Analysis runtime
api.runtime.analysis lets a plugin run focused LLM analysis through the same provider, model, auth-profile, and timeout plumbing WednesdayAI uses for agent turns — without importing core internals. Use it for memory recall, fact extraction, topic detection, or background-classification style plugins.
run(...) — await the result
Use run(...) when the current turn should wait for the analysis result:
enqueue(...) — fire and forget
Use enqueue(...) when the current turn should not wait — for example memory extraction or background indexing. An optional completion callback runs after the analysis lane is released:
Parameters
AnalysisRunParams — purpose and input are required:
| Field | Type | Notes |
|---|---|---|
purpose | string | Required. Short label for the analysis. |
input | string | Required. The text to analyse. |
systemPrompt | string | Optional system prompt. |
responseFormat | "text" | "json" | Output format. |
provider / model | string | Override the provider/model — both must be set together. |
authProfileId | string | Auth profile to use. |
sessionKey | string | Pass when using memory tools, so memory scope rules evaluate against the source chat. |
timeoutMs | number | Per-run timeout. |
toolsAllow | string[] | Tool allow-list (see below). |
maxOutputTokens / temperature | number | Generation controls. |
Result
AnalysisResult carries a status you should branch on first:
status | Meaning |
|---|---|
ok | Success. Read text or json. |
empty | The model returned nothing usable. |
timeout | The run exceeded timeoutMs. |
error | A system-level failure — read error. For a JSON-parse failure, text still holds the raw model output. |
rejected | The request was rejected before running (invalid params). |
result.error only and leave result.text undefined. The text field is reserved for actual model output (including the case where the model returned text that failed JSON parsing). Branch on status first; read text only for ok and JSON-parse error outcomes.
Memory tools in analysis
By default, analysis runs are LLM-only. To grant read-only memory access, pass an explicit allow-list:memory_search and memory_get are accepted in analysis allow-lists. Pass the originating sessionKey so memory scope rules evaluate against the source channel or direct chat.
Lanes, admission, and bounds
- Analysis runs use a dedicated command lane, so awaited hook-time analysis does not queue behind the active user turn. The lane runs one analysis at a time.
- Background (
enqueue) analysis is queued behind a small per-plugin cap. It yields to awaited work, and returnsaccepted: falsewithreason: "queue-full"when that plugin is saturated. - If background analysis is already running, a new awaited
run(...)is rejected immediately rather than waiting behind the job. - Both
run(...)andenqueue(...)validate params synchronously before claiming the lane or a quota. Invalid requests (emptypurpose, emptyinput, aproviderwithout amodel, or a tool outside the allow-list) are rejected immediately —run(...)returnsstatus: "rejected";enqueue(...)returnsaccepted: falsewithreason: "invalid".
Constraints to keep in mind
- Analysis runs do not rewrite the raw user message. To affect the active turn, contribute context through normal hook returns (for example a
PromptContributionfromcontext.collect). - Analysis is text-only in v1: prompt text that looks like a local image path is not auto-loaded.
- Provider overrides must include both
providerandmodel— a provider-only override is rejected so a plugin cannot accidentally pair one provider with another’s default model id. - Transient analysis runs skip workspace cwd changes, skill environment overrides, sandbox startup, bootstrap context loading, and global hook dispatch. The transcript uses a transient internal session key and is not synced back to session storage.
- Keep prompts narrow, set a timeout, and prefer
enqueue(...)for work that updates plugin-owned state for future turns. Completion callbacks still run inside the plugin host process — keep them bounded.
What’s next
- Plugin SDK reference
- Hooks — where
context.collectand the other lifecycle hooks live - Agent signals