@ixo/oracle-runtime-workers 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +110 -0
- package/package.json +77 -0
- package/src/attachments/classify.ts +114 -0
- package/src/attachments/content-blocks.ts +51 -0
- package/src/attachments/download.ts +235 -0
- package/src/attachments/extract.ts +241 -0
- package/src/attachments/index.ts +84 -0
- package/src/attachments/magic.ts +133 -0
- package/src/attachments/pipeline.ts +409 -0
- package/src/attachments/retention.ts +205 -0
- package/src/attachments/route.ts +41 -0
- package/src/attachments/sandbox-archive.ts +90 -0
- package/src/attachments/sanitize.ts +35 -0
- package/src/attachments/types.ts +86 -0
- package/src/attachments/view.ts +107 -0
- package/src/core/env.ts +200 -0
- package/src/core/index.ts +513 -0
- package/src/core/llm.ts +842 -0
- package/src/core/main-agent-types.ts +123 -0
- package/src/core/main-agent.ts +399 -0
- package/src/core/manifest.ts +365 -0
- package/src/core/meta-tools.ts +232 -0
- package/src/core/middlewares/byo-history-sanitizer.ts +165 -0
- package/src/core/middlewares/capability-gate.ts +76 -0
- package/src/core/middlewares/index.ts +18 -0
- package/src/core/middlewares/page-context.ts +98 -0
- package/src/core/middlewares/safety-guardrail.ts +117 -0
- package/src/core/middlewares/summarization.ts +99 -0
- package/src/core/middlewares/tool-repetition-guard.ts +125 -0
- package/src/core/middlewares/tool-validation.ts +83 -0
- package/src/core/middlewares/work-status.ts +57 -0
- package/src/core/openrouter-pricing.ts +124 -0
- package/src/core/plugin-loader.ts +192 -0
- package/src/core/plugins/index.ts +6 -0
- package/src/core/plugins/skills/index.ts +8 -0
- package/src/core/plugins/skills/skills-tools.ts +356 -0
- package/src/core/plugins/skills/skills.plugin.ts +113 -0
- package/src/core/plugins/weather/index.ts +8 -0
- package/src/core/plugins/weather/weather-client.ts +153 -0
- package/src/core/plugins/weather/weather-middleware.ts +27 -0
- package/src/core/plugins/weather/weather-sub-agent.ts +65 -0
- package/src/core/plugins/weather/weather-tools.ts +103 -0
- package/src/core/plugins/weather/weather.plugin.ts +227 -0
- package/src/core/prompt-composer.ts +469 -0
- package/src/core/registries.ts +642 -0
- package/src/core/runtime-context.ts +619 -0
- package/src/core/state.ts +108 -0
- package/src/core/sub-agent-fallback.ts +187 -0
- package/src/core/subagent-as-tool.ts +322 -0
- package/src/core/template.ts +245 -0
- package/src/core/utils.ts +246 -0
- package/src/core/wrap-plugin-tool.ts +100 -0
- package/src/do/ambient.ts +266 -0
- package/src/do/contracts.ts +562 -0
- package/src/do/debug-timers.ts +120 -0
- package/src/do/fresh-stub.ts +32 -0
- package/src/do/gateway-retry.ts +73 -0
- package/src/do/secrets-adapter.ts +32 -0
- package/src/do/size-alerts.ts +76 -0
- package/src/do/sse-stream.ts +472 -0
- package/src/do/transcript.ts +192 -0
- package/src/do/turn-body.ts +84 -0
- package/src/do/turn-metadata.ts +146 -0
- package/src/do/ucan-service.ts +339 -0
- package/src/do/user-oracle-do.ts +3035 -0
- package/src/gateway-worker.ts +82 -0
- package/src/index.ts +237 -0
- package/src/llm/byo-adapter.ts +59 -0
- package/src/llm/byo-catalog.ts +520 -0
- package/src/llm/byo-client.ts +280 -0
- package/src/llm/byo-routes.ts +255 -0
- package/src/llm/byo-service.ts +836 -0
- package/src/llm/chatgpt-oauth.ts +430 -0
- package/src/llm/provider-error.ts +283 -0
- package/src/matrix/gateway-do.ts +918 -0
- package/src/matrix/ingest.ts +209 -0
- package/src/matrix/replay-format.ts +34 -0
- package/src/matrix/reply-chain.ts +109 -0
- package/src/matrix/room-state-codec.ts +115 -0
- package/src/matrix/user-homeserver.ts +106 -0
- package/src/matrix/work-status.ts +294 -0
- package/src/memory/session-history-indexer.ts +328 -0
- package/src/owner-store/ixo-vfs-store.ts +570 -0
- package/src/owner-store/matrix-media-store.ts +136 -0
- package/src/owner-store/migrating-store.ts +185 -0
- package/src/owner-store/owner-copy-errors.ts +175 -0
- package/src/owner-store/retry.ts +45 -0
- package/src/owner-store/tus-upload.ts +333 -0
- package/src/owner-store/types.ts +0 -0
- package/src/plugin-api/define-plugin.ts +45 -0
- package/src/plugin-api/index.ts +56 -0
- package/src/plugin-api/oracle-plugin.ts +145 -0
- package/src/plugin-api/tool-helper.ts +82 -0
- package/src/plugin-api/types.ts +816 -0
- package/src/plugin-api/ucan-errors.ts +16 -0
- package/src/plugins/agui/agui-agent.ts +115 -0
- package/src/plugins/agui/agui.plugin.ts +148 -0
- package/src/plugins/agui/index.ts +2 -0
- package/src/plugins/attachments/attachments.plugin.ts +54 -0
- package/src/plugins/attachments/index.ts +6 -0
- package/src/plugins/attachments/view-attachment-tool.ts +91 -0
- package/src/plugins/base64.ts +26 -0
- package/src/plugins/composio/composio-tools.ts +365 -0
- package/src/plugins/composio/composio-ucan.ts +43 -0
- package/src/plugins/composio/composio.plugin.ts +214 -0
- package/src/plugins/composio/index.ts +15 -0
- package/src/plugins/domain-indexer/domain-indexer-agent.ts +57 -0
- package/src/plugins/domain-indexer/domain-indexer-tools.ts +253 -0
- package/src/plugins/domain-indexer/domain-indexer.plugin.ts +100 -0
- package/src/plugins/domain-indexer/index.ts +3 -0
- package/src/plugins/editor/blocknote-bridge.ts +120 -0
- package/src/plugins/editor/content-session.ts +331 -0
- package/src/plugins/editor/content-tools.ts +686 -0
- package/src/plugins/editor/document-model.ts +0 -0
- package/src/plugins/editor/editor-access-denied-tool.ts +58 -0
- package/src/plugins/editor/editor-agent.ts +34 -0
- package/src/plugins/editor/editor-config.ts +64 -0
- package/src/plugins/editor/editor-mx.ts +128 -0
- package/src/plugins/editor/editor.plugin.ts +143 -0
- package/src/plugins/editor/failures.ts +154 -0
- package/src/plugins/editor/index.ts +31 -0
- package/src/plugins/editor/jsdom-shim.ts +55 -0
- package/src/plugins/editor/prompts.ts +59 -0
- package/src/plugins/editor/prop-policy.ts +147 -0
- package/src/plugins/editor/provider.ts +386 -0
- package/src/plugins/editor/room-membership.ts +95 -0
- package/src/plugins/editor/standalone-editor-tool.ts +200 -0
- package/src/plugins/firecrawl/firecrawl-agent.ts +93 -0
- package/src/plugins/firecrawl/firecrawl-tools.ts +220 -0
- package/src/plugins/firecrawl/firecrawl.plugin.ts +105 -0
- package/src/plugins/firecrawl/index.ts +15 -0
- package/src/plugins/flows/action-metadata.ts +3505 -0
- package/src/plugins/flows/actions.ts +190 -0
- package/src/plugins/flows/edit.ts +314 -0
- package/src/plugins/flows/errors.ts +38 -0
- package/src/plugins/flows/explain.ts +43 -0
- package/src/plugins/flows/flow-doc.ts +111 -0
- package/src/plugins/flows/flows.plugin.ts +129 -0
- package/src/plugins/flows/forms.ts +330 -0
- package/src/plugins/flows/index.ts +2 -0
- package/src/plugins/flows/linkage.ts +147 -0
- package/src/plugins/flows/port-types.ts +53 -0
- package/src/plugins/flows/prompts.ts +65 -0
- package/src/plugins/flows/read.ts +392 -0
- package/src/plugins/flows/references.ts +66 -0
- package/src/plugins/flows/test-support.ts +165 -0
- package/src/plugins/flows/tools/authoring.ts +516 -0
- package/src/plugins/flows/tools/discovery.ts +119 -0
- package/src/plugins/flows/tools/forms.ts +142 -0
- package/src/plugins/flows/tools/inspect.ts +165 -0
- package/src/plugins/flows/tools/linkage.ts +117 -0
- package/src/plugins/flows/tools/settings.ts +184 -0
- package/src/plugins/flows/translator.ts +328 -0
- package/src/plugins/flows/types.ts +210 -0
- package/src/plugins/flows/ydoc-helpers.ts +543 -0
- package/src/plugins/index.ts +70 -0
- package/src/plugins/mcp-call-timeout.ts +38 -0
- package/src/plugins/mcp-tool-adapter.ts +87 -0
- package/src/plugins/memory/index.ts +17 -0
- package/src/plugins/memory/memory-tools.ts +463 -0
- package/src/plugins/memory/memory-ucan.ts +51 -0
- package/src/plugins/memory/memory.plugin.ts +122 -0
- package/src/plugins/memory/types.ts +147 -0
- package/src/plugins/portal/action-log.ts +34 -0
- package/src/plugins/portal/index.ts +2 -0
- package/src/plugins/portal/portal.plugin.ts +203 -0
- package/src/plugins/sandbox/index.ts +34 -0
- package/src/plugins/sandbox/sandbox-bridge.ts +295 -0
- package/src/plugins/sandbox/sandbox-mcp.ts +127 -0
- package/src/plugins/sandbox/sandbox-write-blob.ts +103 -0
- package/src/plugins/sandbox/sandbox.plugin.ts +599 -0
- package/src/plugins/tasks/index.ts +17 -0
- package/src/plugins/tasks/manifest.ts +81 -0
- package/src/plugins/tasks/middleware.ts +219 -0
- package/src/plugins/tasks/tasks-tools.ts +414 -0
- package/src/plugins/tasks/tasks.plugin.ts +74 -0
- package/src/plugins/ucan-failure.ts +133 -0
- package/src/plugins/user-preferences/index.ts +22 -0
- package/src/plugins/user-preferences/schema.ts +31 -0
- package/src/plugins/user-preferences/user-preferences-store.ts +172 -0
- package/src/plugins/user-preferences/user-preferences-tool.ts +131 -0
- package/src/plugins/user-preferences/user-preferences.plugin.ts +137 -0
- package/src/plugins/vfs/index.ts +40 -0
- package/src/plugins/vfs/vfs-auth.ts +56 -0
- package/src/plugins/vfs/vfs-client.ts +655 -0
- package/src/plugins/vfs/vfs-content.ts +181 -0
- package/src/plugins/vfs/vfs-errors.ts +163 -0
- package/src/plugins/vfs/vfs-sandbox-tools.ts +272 -0
- package/src/plugins/vfs/vfs-tools.ts +635 -0
- package/src/plugins/vfs/vfs.plugin.ts +201 -0
- package/src/realtime/frontend-call-registry.ts +163 -0
- package/src/realtime/realtime-endpoint.ts +619 -0
- package/src/realtime/session-socket-hub.ts +249 -0
- package/src/realtime/socket-io-codec.ts +187 -0
- package/src/secrets/jwe.ts +74 -0
- package/src/secrets/pin-cipher.ts +43 -0
- package/src/secrets/secrets-service.ts +319 -0
- package/src/shell/app.ts +564 -0
- package/src/shell/auth.ts +290 -0
- package/src/sqlite/blob-codec.ts +100 -0
- package/src/sqlite/blob-compactor.ts +146 -0
- package/src/sqlite/cache-config.ts +45 -0
- package/src/sqlite/database.ts +643 -0
- package/src/sqlite/do-vfs.ts +1485 -0
- package/src/sqlite/index.ts +61 -0
- package/src/sqlite/serialization.ts +370 -0
- package/src/sqlite/sessions-store.ts +311 -0
- package/src/sqlite/sqlite-saver.ts +919 -0
- package/src/sqlite/vacuum-policy.ts +77 -0
- package/src/sqlite/wa-sqlite-loader.ts +123 -0
- package/src/sqlite/wasm.d.ts +10 -0
- package/src/tasks/schedule.ts +174 -0
- package/src/tasks/scheduler.ts +753 -0
- package/src/tasks/spec.ts +125 -0
- package/src/tasks/store.ts +351 -0
|
@@ -0,0 +1,816 @@
|
|
|
1
|
+
import type { z } from 'zod';
|
|
2
|
+
import type { BaseMessage } from '@langchain/core/messages';
|
|
3
|
+
import type { BaseChatModel } from '@langchain/core/language_models/chat_models';
|
|
4
|
+
import type { UserPreferences } from '../core/state';
|
|
5
|
+
import type { AttachmentViewSurface } from '../attachments/view';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Route shape returned by `OraclePlugin.getAuthExcludedRoutes()`. Paths are
|
|
9
|
+
* matched against the Hono router's request path (leading slash optional).
|
|
10
|
+
* This file is a verbatim port of `@ixo/oracle-runtime`'s plugin-api types —
|
|
11
|
+
* the plugin contract is identical across the Node and Workers runtimes; only
|
|
12
|
+
* the NestJS-specific `RequestMethod` type was replaced.
|
|
13
|
+
*/
|
|
14
|
+
export interface AuthExcludedRoute {
|
|
15
|
+
/** Path under the plugin's controller, e.g. `weather/now`. Leading slash optional. */
|
|
16
|
+
path: string;
|
|
17
|
+
/** HTTP method (`GET`, `POST`, ...). Defaults to all methods when omitted. */
|
|
18
|
+
method?:
|
|
19
|
+
| 'GET'
|
|
20
|
+
| 'POST'
|
|
21
|
+
| 'PUT'
|
|
22
|
+
| 'PATCH'
|
|
23
|
+
| 'DELETE'
|
|
24
|
+
| 'OPTIONS'
|
|
25
|
+
| 'HEAD'
|
|
26
|
+
| 'ALL';
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** Merged Zod-validated env vars (core schema + every loaded plugin's `configSchema`). */
|
|
30
|
+
export type MergedConfig = Record<string, unknown>;
|
|
31
|
+
|
|
32
|
+
/** Plugin-scoped logger. */
|
|
33
|
+
export interface Logger {
|
|
34
|
+
log(message: unknown, ...optional: unknown[]): void;
|
|
35
|
+
error(message: unknown, ...optional: unknown[]): void;
|
|
36
|
+
warn(message: unknown, ...optional: unknown[]): void;
|
|
37
|
+
debug?(message: unknown, ...optional: unknown[]): void;
|
|
38
|
+
verbose?(message: unknown, ...optional: unknown[]): void;
|
|
39
|
+
/**
|
|
40
|
+
* Returns a new logger that auto-prefixes records with the given context.
|
|
41
|
+
* Optional — when absent, the same logger is returned unchanged.
|
|
42
|
+
*/
|
|
43
|
+
child?(bindings: Record<string, unknown>): Logger;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** LLM role tag used by `ctx.llm.get(role)`. Aligned with current `ModelRole`. */
|
|
47
|
+
export type ModelRole = 'main' | 'subagent' | 'utility' | (string & {});
|
|
48
|
+
|
|
49
|
+
/** Optional fields forwarded to ChatOpenAI when materialising an LLM. */
|
|
50
|
+
export type ChatOpenAIFields = Record<string, unknown>;
|
|
51
|
+
|
|
52
|
+
/** UCAN delegation envelope. */
|
|
53
|
+
export interface UcanDelegation {
|
|
54
|
+
readonly raw: string;
|
|
55
|
+
readonly issuer?: string;
|
|
56
|
+
readonly audience?: string;
|
|
57
|
+
readonly capabilities?: ReadonlyArray<{ resource: string; action: string }>;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** Per-room secret index. */
|
|
61
|
+
export type SecretIndex = Record<
|
|
62
|
+
string,
|
|
63
|
+
{ readonly key: string; readonly version?: number }
|
|
64
|
+
>;
|
|
65
|
+
|
|
66
|
+
/** Snapshot of a Matrix room's state events. */
|
|
67
|
+
export interface RoomStateSnapshot {
|
|
68
|
+
readonly roomId: string;
|
|
69
|
+
readonly state: ReadonlyArray<unknown>;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** A single Matrix room event. */
|
|
73
|
+
export interface MatrixEvent {
|
|
74
|
+
readonly eventId: string;
|
|
75
|
+
readonly type: string;
|
|
76
|
+
readonly content: unknown;
|
|
77
|
+
readonly senderId?: string;
|
|
78
|
+
readonly originServerTs?: number;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/** Memory-enriched user context (mirrors `state.userContext`). */
|
|
82
|
+
export type UserContextData = Record<string, unknown>;
|
|
83
|
+
|
|
84
|
+
/** Read-only view over the LangGraph annotation state. */
|
|
85
|
+
export interface ReadonlyState {
|
|
86
|
+
readonly messages: readonly BaseMessage[];
|
|
87
|
+
readonly userContext?: UserContextData;
|
|
88
|
+
readonly loadedPlugins?: ReadonlySet<string>;
|
|
89
|
+
readonly [key: string]: unknown;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Read accessors registered by other plugins via `getSharedState()`.
|
|
94
|
+
* Forks can extend this via declaration merging (e.g. `userProfile`).
|
|
95
|
+
*/
|
|
96
|
+
export interface SharedAccessors {
|
|
97
|
+
readonly [key: string]: unknown;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/** Which commerce persona a Matrix turn runs as. */
|
|
101
|
+
export type CommerceMode = 'support' | 'work';
|
|
102
|
+
|
|
103
|
+
/** Lifecycle of a thread-scoped work engagement. */
|
|
104
|
+
export type CommerceEngagementStatus = 'active' | 'delivered' | 'closed';
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* A thread-scoped work engagement: one per Matrix thread, keyed by the thread
|
|
108
|
+
* root event id (= session id). Stored in the room's state by the
|
|
109
|
+
* oracle-payments plugin; surfaced read-only on `ctx.commerce.engagement`.
|
|
110
|
+
*/
|
|
111
|
+
export interface CommerceEngagement {
|
|
112
|
+
status: CommerceEngagementStatus;
|
|
113
|
+
serviceId: string;
|
|
114
|
+
serviceName: string;
|
|
115
|
+
priceUsd: number;
|
|
116
|
+
collectionId: string;
|
|
117
|
+
adminAddress: string;
|
|
118
|
+
/**
|
|
119
|
+
* DID of the user this job belongs to. The chain accepts one active claim
|
|
120
|
+
* intent per (agent, user claim collection), so "is there live work?" is a
|
|
121
|
+
* question about a USER, not a room — this is what lets the same engagement
|
|
122
|
+
* be found again from another room or another thread. Optional because
|
|
123
|
+
* engagements written before it existed are still readable.
|
|
124
|
+
*/
|
|
125
|
+
userDid?: string;
|
|
126
|
+
/** ISO timestamp of engagement start. */
|
|
127
|
+
startedAt: string;
|
|
128
|
+
/**
|
|
129
|
+
* ISO timestamp of a user cancellation (`cancel_work`). Stamped when the
|
|
130
|
+
* cancellation is requested, before its release claim reaches the chain — an
|
|
131
|
+
* engagement that still reads `active` while carrying this timestamp is one
|
|
132
|
+
* whose release failed and needs another `cancel_work`.
|
|
133
|
+
*/
|
|
134
|
+
cancelledAt?: string;
|
|
135
|
+
/** Free-text reason the user gave `cancel_work`, when any. */
|
|
136
|
+
cancelReason?: string;
|
|
137
|
+
/**
|
|
138
|
+
* Escrow intent locked on-chain at engagement start. `expiresAt` is the
|
|
139
|
+
* derived deadline (start + the grant's `intentDurationNs`) after which the
|
|
140
|
+
* reserved amount auto-releases. Expiry is the passive cleanup; the active
|
|
141
|
+
* one is a claim — submitting any claim against the intent (a delivery, or
|
|
142
|
+
* the release claim `cancel_work` files) settles it immediately.
|
|
143
|
+
*/
|
|
144
|
+
intent?: { txHash: string; submittedAt: string; expiresAt?: string };
|
|
145
|
+
/** Work claim recorded by `deliver_work` (set by a later lane). */
|
|
146
|
+
claim?: { cid: string; txHash?: string; submittedAt: string };
|
|
147
|
+
/**
|
|
148
|
+
* The evaluation outcome already reported to the user in chat, stamped by
|
|
149
|
+
* the claim-status watcher. Its `status` is the raw on-chain
|
|
150
|
+
* `EvaluationStatus`, so a re-evaluation (a flagged claim later resolved)
|
|
151
|
+
* posts a second card while an unchanged status never re-posts.
|
|
152
|
+
*/
|
|
153
|
+
paymentOutcome?: {
|
|
154
|
+
status: number;
|
|
155
|
+
outcome: CommercePaymentOutcome;
|
|
156
|
+
reportedAt: string;
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* How a submitted claim was settled, as rendered on the `payment_update` card.
|
|
162
|
+
* `under_review` is the chain's non-terminal FLAGGED status; `rejected` covers
|
|
163
|
+
* both a rejected and an invalidated claim — either way the escrow goes back.
|
|
164
|
+
*/
|
|
165
|
+
export type CommercePaymentOutcome =
|
|
166
|
+
| 'approved'
|
|
167
|
+
| 'rejected'
|
|
168
|
+
| 'under_review'
|
|
169
|
+
| 'disputed';
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Why a work-classified turn did not start an engagement. The first four are
|
|
173
|
+
* contract-gate failures (the user needs to contract or fix their contract);
|
|
174
|
+
* the last four are different in kind — the contract is fine, but the user
|
|
175
|
+
* already has a job running (`engagement_in_progress`), their account holds too
|
|
176
|
+
* few credits to reserve the payment (`insufficient_funds`, which they fix by
|
|
177
|
+
* topping up and nothing else), the on-chain payment reservation failed for
|
|
178
|
+
* some other reason (`intent_failed`), or the contract could not be checked at
|
|
179
|
+
* all (`contract_check_failed`, which is NOT evidence of an absent contract and
|
|
180
|
+
* must never be reported as one).
|
|
181
|
+
*/
|
|
182
|
+
export type CommerceGateFailureReason =
|
|
183
|
+
| 'not_contracted'
|
|
184
|
+
| 'quota_exhausted'
|
|
185
|
+
| 'max_amount_too_low'
|
|
186
|
+
| 'service_not_contracted'
|
|
187
|
+
| 'engagement_in_progress'
|
|
188
|
+
| 'contract_check_failed'
|
|
189
|
+
| 'insufficient_funds'
|
|
190
|
+
| 'intent_failed';
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* The job already running when a new one is refused with
|
|
194
|
+
* `engagement_in_progress`. The chain accepts one active claim intent per
|
|
195
|
+
* (agent, user claim collection), so a user can have exactly one paid job with
|
|
196
|
+
* an oracle at a time — a second reservation could never be locked.
|
|
197
|
+
*/
|
|
198
|
+
export interface CommerceInProgressEngagement {
|
|
199
|
+
serviceId: string;
|
|
200
|
+
serviceName: string;
|
|
201
|
+
/**
|
|
202
|
+
* Thread root event id the running job lives in — the only thread its
|
|
203
|
+
* `cancel_work` can be called from.
|
|
204
|
+
*/
|
|
205
|
+
threadId: string;
|
|
206
|
+
/**
|
|
207
|
+
* The user already cancelled this job but its on-chain release did not land,
|
|
208
|
+
* so the reservation is still held. Retrying `cancel_work` in that thread
|
|
209
|
+
* completes the release; nothing else frees it before expiry.
|
|
210
|
+
*/
|
|
211
|
+
releaseFailed?: boolean;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/** Gate-failure context attached when a work request lacked a usable contract. */
|
|
215
|
+
export interface CommerceGateFailure {
|
|
216
|
+
reason: CommerceGateFailureReason;
|
|
217
|
+
serviceId: string;
|
|
218
|
+
/** Display name of the requested service, when the agent card provides one. */
|
|
219
|
+
serviceName?: string;
|
|
220
|
+
/**
|
|
221
|
+
* What actually went wrong, in plain words — the chain's rejection text, the
|
|
222
|
+
* engine's status, the numbers that did not add up. The reason alone is a
|
|
223
|
+
* code; this is what lets the agent tell the user something true instead of
|
|
224
|
+
* "it failed". Absent only when the reason already is the whole story.
|
|
225
|
+
*/
|
|
226
|
+
detail?: string;
|
|
227
|
+
/** The blocking job — present only for `engagement_in_progress`. */
|
|
228
|
+
inProgress?: CommerceInProgressEngagement;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Per-turn commerce routing outcome, produced by the Matrix message router
|
|
233
|
+
* and threaded into `RuntimeContext.commerce`. Absent entirely on HTTP turns
|
|
234
|
+
* and on Matrix turns where the commerce router is inert (no oracle-payments
|
|
235
|
+
* plugin registered).
|
|
236
|
+
*/
|
|
237
|
+
export interface CommerceContext {
|
|
238
|
+
mode: CommerceMode;
|
|
239
|
+
/** The user's active engagement — present in work mode. */
|
|
240
|
+
engagement?: CommerceEngagement;
|
|
241
|
+
/**
|
|
242
|
+
* Room the active engagement's durable record lives in. Usually the room the
|
|
243
|
+
* turn arrived in, but NOT when the user continued live work from somewhere
|
|
244
|
+
* else — the engagement record stays where it started, so everything that
|
|
245
|
+
* settles it (`deliver_work`, `cancel_work`) must address it here rather
|
|
246
|
+
* than at `ctx.session.roomId`.
|
|
247
|
+
*/
|
|
248
|
+
engagementRoomId?: string;
|
|
249
|
+
/** Thread root the active engagement's record is keyed by. Same rule. */
|
|
250
|
+
engagementThreadId?: string;
|
|
251
|
+
/** Present when the user asked for work but the contract gate failed. */
|
|
252
|
+
gate?: CommerceGateFailure;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
export type ToolCallEventPayload = Record<string, unknown>;
|
|
256
|
+
export type ActionCallEventPayload = Record<string, unknown>;
|
|
257
|
+
export type RenderComponentEventPayload = Record<string, unknown>;
|
|
258
|
+
export type ReasoningEventPayload = Record<string, unknown>;
|
|
259
|
+
export type BrowserToolCallEventPayload = Record<string, unknown>;
|
|
260
|
+
export type RouterEventPayload = Record<string, unknown>;
|
|
261
|
+
export type MessageCacheInvalidationPayload = Record<string, unknown>;
|
|
262
|
+
|
|
263
|
+
import type { AgentMiddleware } from 'langchain';
|
|
264
|
+
export type { AgentMiddleware };
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* The agent's structured interface to a plugin. Drives Tier-1 prompt
|
|
268
|
+
* composition and powers `list_capabilities` discovery.
|
|
269
|
+
*/
|
|
270
|
+
export interface PluginManifest {
|
|
271
|
+
/** Human-readable name. */
|
|
272
|
+
title: string;
|
|
273
|
+
|
|
274
|
+
/** One-line description shown in the Tier-1 prompt for `always` plugins. */
|
|
275
|
+
summary: string;
|
|
276
|
+
|
|
277
|
+
/** Triggers — when the agent should consider this plugin. */
|
|
278
|
+
whenToUse: string[];
|
|
279
|
+
|
|
280
|
+
/** Anti-patterns — when the agent should NOT use this plugin. */
|
|
281
|
+
whenNotToUse?: string[];
|
|
282
|
+
|
|
283
|
+
/** Few-shot examples teaching the agent how to invoke the plugin. */
|
|
284
|
+
examples?: ManifestExample[];
|
|
285
|
+
|
|
286
|
+
/** Categorization for grouping and filtering. */
|
|
287
|
+
tags?: string[];
|
|
288
|
+
category?:
|
|
289
|
+
| 'data'
|
|
290
|
+
| 'communication'
|
|
291
|
+
| 'automation'
|
|
292
|
+
| 'memory'
|
|
293
|
+
| 'integration'
|
|
294
|
+
| 'ui'
|
|
295
|
+
| 'auth'
|
|
296
|
+
| 'observability'
|
|
297
|
+
| 'core';
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* Discovery and loading mode:
|
|
301
|
+
* - `always` — tools bound to agent at boot; listed in Tier-1 prompt.
|
|
302
|
+
* - `on-demand` — tools NOT bound; manifest discoverable via
|
|
303
|
+
* `list_capabilities`; agent calls `load_capability(name)`
|
|
304
|
+
* to load.
|
|
305
|
+
* - `silent` — invisible to agent; runs as middleware-only.
|
|
306
|
+
*
|
|
307
|
+
* Default: `on-demand`.
|
|
308
|
+
*/
|
|
309
|
+
visibility?: 'always' | 'on-demand' | 'silent';
|
|
310
|
+
|
|
311
|
+
/** Stability hint surfaced to the agent (`experimental` → warning footnote). */
|
|
312
|
+
stability?: 'stable' | 'beta' | 'experimental';
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
export interface ManifestExample {
|
|
316
|
+
/** Representative user message. */
|
|
317
|
+
user: string;
|
|
318
|
+
/** Optional reasoning. */
|
|
319
|
+
thought?: string;
|
|
320
|
+
/** Tool the agent should call. */
|
|
321
|
+
tool: string;
|
|
322
|
+
/** Tool args. */
|
|
323
|
+
args?: Record<string, unknown>;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* Author-provided prompt customization. Every field is optional — when absent
|
|
328
|
+
* the runtime falls back to its built-in defaults. Authored once, baked into
|
|
329
|
+
* the system prompt at build time.
|
|
330
|
+
*/
|
|
331
|
+
export interface OraclePromptConfig {
|
|
332
|
+
/**
|
|
333
|
+
* Full replacement of the identity preamble. When set, used verbatim as the
|
|
334
|
+
* opening paragraph. When unset, the composer generates one from
|
|
335
|
+
* `name`/`org`/`description`.
|
|
336
|
+
*/
|
|
337
|
+
opening?: string;
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* Appended to the runtime's operating-principles section. Use for tone,
|
|
341
|
+
* voice, formality, or oracle-specific behavioral hints.
|
|
342
|
+
*/
|
|
343
|
+
communicationStyle?: string;
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* Author-written elevator pitch for what this oracle does. Rendered above
|
|
347
|
+
* the plugin-derived capability list — additive, not a replacement.
|
|
348
|
+
*/
|
|
349
|
+
capabilities?: string;
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* Free-form standing guidance injected verbatim into the system prompt under
|
|
353
|
+
* a dedicated `## Custom Instructions` section. Use for house style, domain
|
|
354
|
+
* rules, guardrails, or anything that doesn't fit `communicationStyle` (tone)
|
|
355
|
+
* or `capabilities` (the elevator pitch). The runtime renders the section
|
|
356
|
+
* only when there is content; it also routes operating guides contributed by
|
|
357
|
+
* loaded on-demand capabilities (e.g. the Flow Builder guide) through the
|
|
358
|
+
* same section, appended after the author's text.
|
|
359
|
+
*/
|
|
360
|
+
customInstructions?: string;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
/**
|
|
364
|
+
* Developer-facing oracle config. Passed inline to `createOracleApp`. The
|
|
365
|
+
* runtime fills in `entityDid` from the `ORACLE_ENTITY_DID` env var and
|
|
366
|
+
* combines this with bundled defaults to build the internal `OracleIdentity`.
|
|
367
|
+
*/
|
|
368
|
+
export interface OracleConfig {
|
|
369
|
+
/** Oracle display name. Required. */
|
|
370
|
+
name: string;
|
|
371
|
+
/** Sponsoring organization. Optional — composer falls back gracefully. */
|
|
372
|
+
org?: string;
|
|
373
|
+
/** One-line description of what this oracle is for. */
|
|
374
|
+
description?: string;
|
|
375
|
+
/** Optional prompt customization (opening, communicationStyle, capabilities). */
|
|
376
|
+
prompt?: OraclePromptConfig;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
/**
|
|
380
|
+
* Identity of the oracle running this plugin. Built by the runtime from
|
|
381
|
+
* `OracleConfig` + `ORACLE_ENTITY_DID` env var. Plugins read it via
|
|
382
|
+
* `PluginContext.identity` / `RuntimeContext` and should treat it as
|
|
383
|
+
* read-only.
|
|
384
|
+
*/
|
|
385
|
+
export interface OracleIdentity {
|
|
386
|
+
name: string;
|
|
387
|
+
org: string;
|
|
388
|
+
description: string;
|
|
389
|
+
entityDid: string;
|
|
390
|
+
/** Author-provided prompt customization. Undefined when not configured. */
|
|
391
|
+
prompt?: OraclePromptConfig;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
/**
|
|
395
|
+
* Passed to plugin methods called at request build time
|
|
396
|
+
* (`getTools`, `getSubAgents`, `getMiddlewares`). Lives once per request build.
|
|
397
|
+
*
|
|
398
|
+
* Holds no user, no session, no live socket, no request data.
|
|
399
|
+
*/
|
|
400
|
+
export interface PluginContext<TConfig = MergedConfig> {
|
|
401
|
+
/** Merged Zod-validated env vars (core + all loaded plugins' configSchemas). */
|
|
402
|
+
config: TConfig;
|
|
403
|
+
|
|
404
|
+
/** Identity of this oracle. */
|
|
405
|
+
identity: OracleIdentity;
|
|
406
|
+
|
|
407
|
+
/** Set of plugin names currently loaded — drives soft-dep branching. */
|
|
408
|
+
availablePlugins: ReadonlySet<string>;
|
|
409
|
+
|
|
410
|
+
/** Plugin-scoped logger (auto-prefixed with the plugin's name). */
|
|
411
|
+
logger: Logger;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
/**
|
|
415
|
+
* Passed to tool handlers, sub-agent handlers, and to plugin middlewares' hook
|
|
416
|
+
* functions. Built fresh per graph invocation.
|
|
417
|
+
*/
|
|
418
|
+
export interface RuntimeContext<TConfig = MergedConfig> {
|
|
419
|
+
/** Authenticated user identity (validated by core auth middleware). */
|
|
420
|
+
user: {
|
|
421
|
+
did: string;
|
|
422
|
+
/** e.g. `@did-ixo-ixo1abc:ixo.world`. */
|
|
423
|
+
matrixUserId: string;
|
|
424
|
+
ucanDelegation: UcanDelegation;
|
|
425
|
+
timezone?: string;
|
|
426
|
+
currentTime?: string;
|
|
427
|
+
};
|
|
428
|
+
|
|
429
|
+
/** Session info from `SessionsService`. */
|
|
430
|
+
session: {
|
|
431
|
+
/** = `thread_id`; thread root `eventId`. */
|
|
432
|
+
id: string;
|
|
433
|
+
client: 'portal' | 'matrix' | 'slack';
|
|
434
|
+
wsId?: string;
|
|
435
|
+
requestId: string;
|
|
436
|
+
roomId?: string;
|
|
437
|
+
};
|
|
438
|
+
|
|
439
|
+
/** Read-only view over the graph state's history. */
|
|
440
|
+
history: {
|
|
441
|
+
messages: readonly BaseMessage[];
|
|
442
|
+
recent: (n: number) => BaseMessage[];
|
|
443
|
+
/** Memory enrichment from existing `state.userContext`. */
|
|
444
|
+
userContext: UserContextData;
|
|
445
|
+
/** Typed view over `Annotation.Root`. */
|
|
446
|
+
state: ReadonlyState;
|
|
447
|
+
};
|
|
448
|
+
|
|
449
|
+
/** Same merged Zod-validated env. */
|
|
450
|
+
config: TConfig;
|
|
451
|
+
|
|
452
|
+
/** Set of plugin names currently loaded (boot-fixed). */
|
|
453
|
+
availablePlugins: ReadonlySet<string>;
|
|
454
|
+
|
|
455
|
+
/** Plugins the agent has loaded for THIS thread via `load_capability`. */
|
|
456
|
+
loadedPlugins: ReadonlySet<string>;
|
|
457
|
+
|
|
458
|
+
/** Per-room secrets (JWE-encrypted, 24h cache; today's `SecretsService`). */
|
|
459
|
+
secrets: {
|
|
460
|
+
getIndex: () => Promise<SecretIndex>;
|
|
461
|
+
getValues: (keys: string[]) => Promise<Record<string, string>>;
|
|
462
|
+
};
|
|
463
|
+
|
|
464
|
+
/**
|
|
465
|
+
* Short-TTL keyed value store for content the LLM should never relay
|
|
466
|
+
* verbatim (UCAN invocation CARs, JWTs, signed envelopes, etc.). A
|
|
467
|
+
* producing tool stores the value and returns a short hex blobId; a
|
|
468
|
+
* consuming tool looks the value up server-side and forwards it on. Blobs
|
|
469
|
+
* are namespaced by issuing user DID — cross-user reads always miss.
|
|
470
|
+
*/
|
|
471
|
+
blobStore: {
|
|
472
|
+
/** Store a value and return a fresh `blob_<16 hex>` id. TTL clamped to
|
|
473
|
+
* the service's `MAX_TTL_SECONDS` (24h); defaults to `DEFAULT_TTL_SECONDS`
|
|
474
|
+
* (1h) when omitted. Pass `userDid` from a trusted source — never from
|
|
475
|
+
* LLM-supplied arguments. */
|
|
476
|
+
put: (params: {
|
|
477
|
+
userDid: string;
|
|
478
|
+
name: string;
|
|
479
|
+
value: string;
|
|
480
|
+
ttlSeconds?: number;
|
|
481
|
+
}) => Promise<string>;
|
|
482
|
+
/** Retrieve a blob by id, scoped to the requesting user. Returns `null`
|
|
483
|
+
* if the blob doesn't exist, has expired, or belongs to a different user. */
|
|
484
|
+
get: (params: {
|
|
485
|
+
userDid: string;
|
|
486
|
+
blobId: string;
|
|
487
|
+
}) => Promise<{ name: string; value: string } | null>;
|
|
488
|
+
/** Lightweight format check (`blob_<16 hex>`). Use in tool input handlers
|
|
489
|
+
* to reject malformed IDs before paying for a cache lookup. */
|
|
490
|
+
isValidBlobId: (value: unknown) => value is string;
|
|
491
|
+
};
|
|
492
|
+
|
|
493
|
+
/** Matrix client, scoped operations only. */
|
|
494
|
+
matrix: {
|
|
495
|
+
postToRoom: (roomId: string, content: unknown) => Promise<string>;
|
|
496
|
+
/**
|
|
497
|
+
* Post a timeline event with a caller-chosen event type (e.g. the
|
|
498
|
+
* `ixo.oracle.*` protocol events). `postToRoom` is the `m.room.message`
|
|
499
|
+
* shorthand; this is the general form. Returns the new event id.
|
|
500
|
+
*/
|
|
501
|
+
postEvent: (
|
|
502
|
+
roomId: string,
|
|
503
|
+
eventType: string,
|
|
504
|
+
content: object,
|
|
505
|
+
) => Promise<string>;
|
|
506
|
+
getRoomState: (roomId: string) => Promise<RoomStateSnapshot>;
|
|
507
|
+
getEventById: (roomId: string, eventId: string) => Promise<MatrixEvent>;
|
|
508
|
+
/**
|
|
509
|
+
* Credentials of the oracle's own crypto-less device for plugins that run
|
|
510
|
+
* their own Matrix client (editor, flows). Minted and kept by the gateway.
|
|
511
|
+
*/
|
|
512
|
+
botCredentials: () => Promise<{
|
|
513
|
+
baseUrl: string;
|
|
514
|
+
userId: string;
|
|
515
|
+
accessToken: string;
|
|
516
|
+
deviceId: string;
|
|
517
|
+
}>;
|
|
518
|
+
};
|
|
519
|
+
|
|
520
|
+
/** UCAN authorization helpers. */
|
|
521
|
+
ucan: {
|
|
522
|
+
requireCapability: (resource: string, action: string) => void;
|
|
523
|
+
hasCapability: (resource: string, action: string) => boolean;
|
|
524
|
+
mintInvocation: (
|
|
525
|
+
target: { did: string; capability: string },
|
|
526
|
+
opts?: { skipCache?: boolean; can?: string },
|
|
527
|
+
) => Promise<string>;
|
|
528
|
+
/**
|
|
529
|
+
* Resolve a downstream service URL to its did:web identifier. Returns
|
|
530
|
+
* `null` when the document is missing or has no `id` — used by plugins
|
|
531
|
+
* minting service-targeted UCAN invocations.
|
|
532
|
+
*/
|
|
533
|
+
resolveServiceDid: (serviceUrl: string) => Promise<string | null>;
|
|
534
|
+
/**
|
|
535
|
+
* `true` once the oracle has loaded its Ed25519 signing mnemonic. Plugins
|
|
536
|
+
* gate registration of mint-capable tools on this — without a key, minting
|
|
537
|
+
* is a no-op and the tool should surface an error rather than pretend.
|
|
538
|
+
*/
|
|
539
|
+
hasSigningKey: () => boolean;
|
|
540
|
+
/**
|
|
541
|
+
* Mint a UCAN invocation from a directly-supplied delegation CAR (rather
|
|
542
|
+
* than a per-user cached one), targeted at a specific service route. For
|
|
543
|
+
* callers that already hold the delegation and need a fresh single-use
|
|
544
|
+
* invocation.
|
|
545
|
+
*/
|
|
546
|
+
createInvocationFromDelegation: (
|
|
547
|
+
delegationCar: string,
|
|
548
|
+
serviceUrl: string,
|
|
549
|
+
capability: { can: string; with: string; nb?: Record<string, unknown> },
|
|
550
|
+
options?: { maxTtlSeconds?: number },
|
|
551
|
+
) => Promise<{ invocation: string } | { error: string }>;
|
|
552
|
+
/**
|
|
553
|
+
* Mint a SELF-SIGNED invocation — issued by this oracle with NO proof
|
|
554
|
+
* chain — for calling a downstream service AS THE ORACLE ITSELF (not on a
|
|
555
|
+
* user's behalf). Returns `{ invocation }` on success or `{ error }` with a
|
|
556
|
+
* surfaced-verbatim reason (signing key missing, did:web unreachable, etc.).
|
|
557
|
+
*/
|
|
558
|
+
mintSelfSignedInvocation: (
|
|
559
|
+
serviceUrl: string,
|
|
560
|
+
capability: { can: string; with: string },
|
|
561
|
+
options?: { maxTtlSeconds?: number },
|
|
562
|
+
) => Promise<{ invocation: string } | { error: string }>;
|
|
563
|
+
/**
|
|
564
|
+
* Fetch, from the UCAN Store Worker, a delegation the user deposited for
|
|
565
|
+
* this oracle over `opts.resource`. Selects the newest active delegation
|
|
566
|
+
* whose capability covers `opts.requiredAbility`. Returns `{ token, with }`
|
|
567
|
+
* on success or `{ error }` — `'no-delegation'` when none satisfies the
|
|
568
|
+
* request, `'store-error'` (with `detail`) for auth / network / store
|
|
569
|
+
* failures.
|
|
570
|
+
*/
|
|
571
|
+
getServiceDelegation: (
|
|
572
|
+
userDid: string,
|
|
573
|
+
opts: { storeUrl: string; resource: string; requiredAbility: string },
|
|
574
|
+
) => Promise<
|
|
575
|
+
| { token: string; with: string }
|
|
576
|
+
| { error: 'no-delegation' | 'store-error'; detail?: string }
|
|
577
|
+
>;
|
|
578
|
+
};
|
|
579
|
+
|
|
580
|
+
/** LLM provider. */
|
|
581
|
+
llm: {
|
|
582
|
+
get: (role: ModelRole, params?: ChatOpenAIFields) => BaseChatModel;
|
|
583
|
+
};
|
|
584
|
+
|
|
585
|
+
/** Typed event emitter (today's `@ixo/oracles-events` 7 event types). */
|
|
586
|
+
emit: {
|
|
587
|
+
toolCall: (payload: ToolCallEventPayload) => void;
|
|
588
|
+
actionCall: (payload: ActionCallEventPayload) => void;
|
|
589
|
+
renderComponent: (payload: RenderComponentEventPayload) => void;
|
|
590
|
+
reasoning: (payload: ReasoningEventPayload) => void;
|
|
591
|
+
browserToolCall: (payload: BrowserToolCallEventPayload) => void;
|
|
592
|
+
router: (payload: RouterEventPayload) => void;
|
|
593
|
+
messageCacheInvalidation: (
|
|
594
|
+
payload: MessageCacheInvalidationPayload,
|
|
595
|
+
) => void;
|
|
596
|
+
};
|
|
597
|
+
|
|
598
|
+
/** Plugin-scoped logger. */
|
|
599
|
+
logger: Logger;
|
|
600
|
+
|
|
601
|
+
/**
|
|
602
|
+
* Host task scheduler for this user, when the runtime provides one (the
|
|
603
|
+
* Workers runtime does; absent elsewhere). Used by the tasks plugin.
|
|
604
|
+
*/
|
|
605
|
+
tasks?: OracleTasksSurface;
|
|
606
|
+
|
|
607
|
+
/**
|
|
608
|
+
* Host store for the user's per-room behavioural preferences (tone,
|
|
609
|
+
* language, names). Present when the host persists room state; the
|
|
610
|
+
* `set_user_preferences` tool writes through it and the turn preparer
|
|
611
|
+
* hydrates `state.userPreferences` from it before the agent is built.
|
|
612
|
+
*/
|
|
613
|
+
preferences?: UserPreferencesSurface;
|
|
614
|
+
|
|
615
|
+
/**
|
|
616
|
+
* Host bridge to the user's browser over the realtime (socket.io) channel:
|
|
617
|
+
* browser tools declared by the client (`state.browserTools`) and AG-UI
|
|
618
|
+
* actions (`state.agActions`) are invoked through it and awaited until the
|
|
619
|
+
* browser answers. Present when the runtime terminates client sockets
|
|
620
|
+
* (the Workers runtime does); absent on hosts without a realtime channel.
|
|
621
|
+
*/
|
|
622
|
+
frontend?: FrontendCallSurface;
|
|
623
|
+
|
|
624
|
+
/**
|
|
625
|
+
* Host access to the session's attachments for the `view_attachment`
|
|
626
|
+
* tool: present on hosts that offload old inline payloads (the Workers
|
|
627
|
+
* runtime), absent elsewhere.
|
|
628
|
+
*/
|
|
629
|
+
attachments?: AttachmentViewSurface;
|
|
630
|
+
/**
|
|
631
|
+
* Register a cleanup that runs when THIS turn ends — completed, failed or
|
|
632
|
+
* aborted. For anything a tool keeps open across calls within a turn (an
|
|
633
|
+
* MCP client session, a pooled connection): close it here rather than on
|
|
634
|
+
* an idle timer. On Workers a pending timer keeps the user's Durable
|
|
635
|
+
* Object resident (and billed) and blocks WebSocket hibernation, whereas a
|
|
636
|
+
* turn-end close costs nothing.
|
|
637
|
+
*/
|
|
638
|
+
onTurnEnd?: (dispose: () => void | Promise<void>) => void;
|
|
639
|
+
|
|
640
|
+
/** Propagates from the HTTP request / graph invocation. */
|
|
641
|
+
abortSignal: AbortSignal;
|
|
642
|
+
|
|
643
|
+
/**
|
|
644
|
+
* Commerce routing outcome for this Matrix turn (support vs work persona,
|
|
645
|
+
* active engagement, gate failure, cancellation). Absent on HTTP turns and
|
|
646
|
+
* whenever the commerce router is inert.
|
|
647
|
+
*/
|
|
648
|
+
commerce?: CommerceContext;
|
|
649
|
+
|
|
650
|
+
/** Read accessors for state owned by other plugins. */
|
|
651
|
+
shared: SharedAccessors;
|
|
652
|
+
|
|
653
|
+
/**
|
|
654
|
+
* Identifier of the inbound tool call that triggered this handler, when
|
|
655
|
+
* available. Undefined for direct/test invocations. Used by tools that
|
|
656
|
+
* return a LangGraph `Command` and need to append a matching `ToolMessage`
|
|
657
|
+
* to the state update.
|
|
658
|
+
*/
|
|
659
|
+
toolCallId?: string;
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
/** Lifecycle of a scheduled task. */
|
|
663
|
+
export type OracleTaskStatus =
|
|
664
|
+
| 'active'
|
|
665
|
+
| 'paused'
|
|
666
|
+
| 'completed'
|
|
667
|
+
| 'cancelled'
|
|
668
|
+
| 'failed';
|
|
669
|
+
|
|
670
|
+
/** How a task run is triggered. */
|
|
671
|
+
export type OracleTaskSchedule =
|
|
672
|
+
| { kind: 'cron'; cron: string; timezone?: string }
|
|
673
|
+
| { kind: 'once'; at: string }
|
|
674
|
+
| { kind: 'interval'; everySeconds: number };
|
|
675
|
+
|
|
676
|
+
/** Stored task record (persisted in the user's own database → owner file). */
|
|
677
|
+
export interface OracleTaskRecord {
|
|
678
|
+
id: string;
|
|
679
|
+
title: string;
|
|
680
|
+
/** Markdown intent body — what the agent should do each run. */
|
|
681
|
+
intent: string;
|
|
682
|
+
schedule: OracleTaskSchedule;
|
|
683
|
+
status: OracleTaskStatus;
|
|
684
|
+
/** `before-action` pauses each run for user approval; `never` runs freely. */
|
|
685
|
+
approval: 'never' | 'before-action';
|
|
686
|
+
createdAt: string;
|
|
687
|
+
updatedAt: string;
|
|
688
|
+
nextRunAt?: string;
|
|
689
|
+
lastRunAt?: string;
|
|
690
|
+
lastResult?: { ok: boolean; summary: string; at: string };
|
|
691
|
+
consecutiveFailures: number;
|
|
692
|
+
/**
|
|
693
|
+
* Dedicated `[Task] <title>` room this task delivers into. Absent → the
|
|
694
|
+
* user's main oracle room (the Node runtime's `delivery.roomId: 'main'`).
|
|
695
|
+
*/
|
|
696
|
+
deliveryRoomId?: string;
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
export interface OracleTaskInput {
|
|
700
|
+
title: string;
|
|
701
|
+
intent: string;
|
|
702
|
+
schedule: OracleTaskSchedule;
|
|
703
|
+
approval?: 'never' | 'before-action';
|
|
704
|
+
/**
|
|
705
|
+
* Whether the task gets its own `[Task] <title>` room. `auto` (default)
|
|
706
|
+
* applies the Node heuristic: sub-daily cron, long intent, or a
|
|
707
|
+
* monitor/watch/track intent; `before-action` tasks always get one.
|
|
708
|
+
*/
|
|
709
|
+
dedicatedRoom?: 'auto' | 'yes' | 'no';
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
/**
|
|
713
|
+
* Bridge to the user's browser over the realtime channel. Both calls emit the
|
|
714
|
+
* corresponding event (`browser_tool_call` / `action_call`) to the sockets
|
|
715
|
+
* subscribed to `sessionId` and resolve with the browser's answer, rejecting
|
|
716
|
+
* on the browser's `error`, an AG-UI `success: false`, or the timeout —
|
|
717
|
+
* exactly the Node runtime's `callBrowserTool` / `callAgAction` contract.
|
|
718
|
+
*/
|
|
719
|
+
export interface FrontendCallSurface {
|
|
720
|
+
callBrowserTool(params: FrontendCallParams): Promise<unknown>;
|
|
721
|
+
callAgAction(params: FrontendCallParams): Promise<unknown>;
|
|
722
|
+
/** Whether at least one authenticated realtime client is attached to the session. */
|
|
723
|
+
hasClient(sessionId: string): boolean;
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
export interface FrontendCallParams {
|
|
727
|
+
sessionId: string;
|
|
728
|
+
toolCallId: string;
|
|
729
|
+
toolName: string;
|
|
730
|
+
args: Record<string, unknown>;
|
|
731
|
+
/** Default 15 s (browser tools) / 10 s (AG-UI actions), as on Node. */
|
|
732
|
+
timeoutMs?: number;
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
/**
|
|
736
|
+
* Per-user task scheduling surface, implemented by the host runtime (on
|
|
737
|
+
* Workers: a Durable-Object-alarm scheduler whose records live inside the
|
|
738
|
+
* user's own SQLite file). Optional — absent when the host has no scheduler.
|
|
739
|
+
*/
|
|
740
|
+
export interface OracleTasksSurface {
|
|
741
|
+
preview(
|
|
742
|
+
input: OracleTaskInput,
|
|
743
|
+
): Promise<{ ok: boolean; nextRuns: string[]; problems: string[] }>;
|
|
744
|
+
create(input: OracleTaskInput): Promise<OracleTaskRecord>;
|
|
745
|
+
list(): Promise<OracleTaskRecord[]>;
|
|
746
|
+
get(id: string): Promise<OracleTaskRecord | null>;
|
|
747
|
+
update(
|
|
748
|
+
id: string,
|
|
749
|
+
patch: Partial<OracleTaskInput>,
|
|
750
|
+
): Promise<OracleTaskRecord>;
|
|
751
|
+
pause(id: string): Promise<OracleTaskRecord>;
|
|
752
|
+
resume(id: string): Promise<OracleTaskRecord>;
|
|
753
|
+
cancel(id: string): Promise<OracleTaskRecord>;
|
|
754
|
+
/** Resolve a pending before-action approval for the given run. */
|
|
755
|
+
resolveApproval(
|
|
756
|
+
taskId: string,
|
|
757
|
+
decision: 'approve' | 'reject',
|
|
758
|
+
note?: string,
|
|
759
|
+
): Promise<{ resolved: boolean }>;
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
export interface PluginTool {
|
|
763
|
+
name: string;
|
|
764
|
+
description: string;
|
|
765
|
+
schema: z.ZodType;
|
|
766
|
+
handler: (args: unknown, ctx: RuntimeContext) => Promise<unknown>;
|
|
767
|
+
/** Override visibility — by default inherits from the plugin's `manifest.visibility`. */
|
|
768
|
+
visibility?: 'always' | 'on-demand' | 'silent';
|
|
769
|
+
/**
|
|
770
|
+
* Billing gate. `'contracted'` marks a tool that performs paid contracted
|
|
771
|
+
* work: the runtime binds it only while the turn runs inside an active work
|
|
772
|
+
* engagement (`ctx.commerce.mode === 'work'`) and hides it from the model
|
|
773
|
+
* otherwise — a hard code gate on top of the prompt overlay.
|
|
774
|
+
*/
|
|
775
|
+
billing?: 'contracted';
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
export interface PluginSubAgent {
|
|
779
|
+
/** Tool name the agent will see (e.g. `call_memory_agent`). */
|
|
780
|
+
name: string;
|
|
781
|
+
description: string;
|
|
782
|
+
systemPrompt: string | ((ctx: PluginContext) => string);
|
|
783
|
+
tools: PluginTool[] | ((ctx: PluginContext) => PluginTool[]);
|
|
784
|
+
/** LLM role; default `subagent`. */
|
|
785
|
+
model?: ModelRole;
|
|
786
|
+
/** Sub-agent-scoped middleware (e.g. summarization for long conversations). */
|
|
787
|
+
middlewares?: AgentMiddleware[];
|
|
788
|
+
/**
|
|
789
|
+
* Forward this sub-agent's internal tool calls + results into the parent
|
|
790
|
+
* graph's message history so the UI renders them in the main chat.
|
|
791
|
+
*
|
|
792
|
+
* - `true` → forward ALL of this sub-agent's own tools
|
|
793
|
+
* - `false` / omitted → forward nothing
|
|
794
|
+
* - `string[]` → forward only the listed tool names
|
|
795
|
+
*
|
|
796
|
+
* Runtime-injected passthrough tools (e.g. memory CRUD) are never
|
|
797
|
+
* forwarded — they're already on the main agent.
|
|
798
|
+
*/
|
|
799
|
+
forwardTools?: boolean | string[];
|
|
800
|
+
/** Called after sub-agent completes; can emit follow-up events. */
|
|
801
|
+
onComplete?: (result: string, ctx: RuntimeContext) => Promise<void>;
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
/**
|
|
805
|
+
* Per-room user preferences as the host stores them — the same record the
|
|
806
|
+
* Node runtime's `UserPreferencesService` keeps in the room's
|
|
807
|
+
* `ixo.room.state`/`user_prefs` event. `set` merges: only the provided
|
|
808
|
+
* fields change, and the host stamps `updatedAt`.
|
|
809
|
+
*/
|
|
810
|
+
export interface UserPreferencesSurface {
|
|
811
|
+
get(roomId: string): Promise<UserPreferences | undefined>;
|
|
812
|
+
set(
|
|
813
|
+
roomId: string,
|
|
814
|
+
partial: Partial<UserPreferences>,
|
|
815
|
+
): Promise<UserPreferences>;
|
|
816
|
+
}
|