@ixo/oracle-runtime-workers 0.13.0 → 0.16.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.
Files changed (205) hide show
  1. package/README.md +32 -10
  2. package/package.json +13 -8
  3. package/src/artifacts/config.ts +158 -0
  4. package/src/artifacts/crypto.ts +94 -0
  5. package/src/artifacts/routes.ts +73 -0
  6. package/src/artifacts/store.ts +238 -0
  7. package/src/artifacts/sweep.ts +200 -0
  8. package/src/artifacts/tool.ts +103 -0
  9. package/src/artifacts/viewer-page.ts +614 -0
  10. package/src/attachments/download.ts +168 -45
  11. package/src/attachments/index.ts +9 -0
  12. package/src/attachments/magic.ts +33 -0
  13. package/src/attachments/pipeline.ts +105 -49
  14. package/src/attachments/sandbox-archive.ts +9 -8
  15. package/src/attachments/view-cache.ts +142 -0
  16. package/src/attachments/view.ts +53 -12
  17. package/src/channels/auth.ts +310 -0
  18. package/src/channels/contract.ts +246 -0
  19. package/src/channels/turns.ts +280 -0
  20. package/src/core/budgeted-llm.ts +223 -0
  21. package/src/core/capability-router.ts +273 -0
  22. package/src/core/context-budget.ts +97 -10
  23. package/src/core/env.ts +111 -0
  24. package/src/core/execution-profile.ts +17 -0
  25. package/src/core/index.ts +267 -9
  26. package/src/core/llm.ts +30 -9
  27. package/src/core/main-agent-types.ts +41 -1
  28. package/src/core/main-agent.ts +367 -65
  29. package/src/core/manifest.ts +34 -0
  30. package/src/core/meta-tools.ts +128 -18
  31. package/src/core/middlewares/capability-gate.ts +130 -12
  32. package/src/core/middlewares/context-guard.ts +55 -24
  33. package/src/core/middlewares/index.ts +20 -2
  34. package/src/core/middlewares/page-context.ts +46 -2
  35. package/src/core/middlewares/return-direct-first.ts +47 -0
  36. package/src/core/middlewares/summarization.ts +152 -10
  37. package/src/core/middlewares/tool-execution.ts +323 -0
  38. package/src/core/middlewares/tool-repetition-guard.ts +202 -35
  39. package/src/core/middlewares/turn-boundary.ts +162 -0
  40. package/src/core/openrouter-pricing.ts +155 -22
  41. package/src/core/prompt-composer.ts +112 -7
  42. package/src/core/registries.ts +253 -48
  43. package/src/core/request-admission.ts +159 -0
  44. package/src/core/runtime-context.ts +107 -8
  45. package/src/core/state.ts +1 -1
  46. package/src/core/sub-agent-fallback.ts +21 -2
  47. package/src/core/subagent-as-tool.ts +78 -43
  48. package/src/core/tool-access.ts +189 -0
  49. package/src/core/tool-scheduler.ts +125 -0
  50. package/src/core/turn-budget.ts +205 -0
  51. package/src/core/turn-time-note.ts +43 -0
  52. package/src/core/user-kv.ts +446 -0
  53. package/src/core/wrap-plugin-tool.ts +20 -0
  54. package/src/delivery/plan.ts +278 -0
  55. package/src/delivery/profile.ts +161 -0
  56. package/src/delivery/prompt.ts +27 -0
  57. package/src/delivery/schema.ts +61 -0
  58. package/src/delivery/shaper.ts +389 -0
  59. package/src/delivery/types.ts +84 -0
  60. package/src/do/ambient.ts +51 -15
  61. package/src/do/contracts.ts +170 -6
  62. package/src/do/idle-eviction.ts +38 -0
  63. package/src/do/matrix-turn-ledger.ts +24 -5
  64. package/src/do/result-store-test-do.ts +137 -3
  65. package/src/do/result-store.ts +239 -58
  66. package/src/do/room-mirror.ts +29 -0
  67. package/src/do/run-buffer.ts +64 -9
  68. package/src/do/run-coordinator.ts +451 -76
  69. package/src/do/run-request.ts +2 -0
  70. package/src/do/run-store-test-do.ts +301 -1
  71. package/src/do/run-store.ts +385 -43
  72. package/src/do/secrets-adapter.ts +22 -3
  73. package/src/do/sse-stream.ts +60 -9
  74. package/src/do/transcript.ts +48 -5
  75. package/src/do/turn-body.ts +105 -5
  76. package/src/do/ucan-service.ts +204 -34
  77. package/src/do/user-oracle-do.ts +2003 -274
  78. package/src/feedback/config.ts +127 -0
  79. package/src/feedback/contract.ts +148 -0
  80. package/src/feedback/linear-sink.ts +285 -0
  81. package/src/feedback/privacy.ts +150 -0
  82. package/src/feedback/reservation.ts +298 -0
  83. package/src/feedback/submit.ts +247 -0
  84. package/src/index.ts +138 -6
  85. package/src/llm/byo-adapter.ts +27 -6
  86. package/src/llm/byo-catalog.ts +13 -0
  87. package/src/llm/byo-model-fallback.ts +248 -0
  88. package/src/llm/byo-service.ts +45 -8
  89. package/src/llm/provider-error.ts +139 -2
  90. package/src/matrix/gateway-do.ts +504 -108
  91. package/src/matrix/group-chat.ts +66 -23
  92. package/src/matrix/inbox-store.ts +16 -1
  93. package/src/matrix/ingest.ts +79 -14
  94. package/src/matrix/media-deadline.ts +130 -0
  95. package/src/matrix/replay-format.ts +5 -3
  96. package/src/matrix/reply-parts.ts +92 -0
  97. package/src/matrix/room-alias.ts +96 -0
  98. package/src/matrix/user-homeserver.ts +166 -7
  99. package/src/owner-store/ixo-vfs-store.ts +170 -43
  100. package/src/owner-store/migrating-store.ts +31 -15
  101. package/src/owner-store/types.ts +18 -3
  102. package/src/plugin-api/index.ts +43 -2
  103. package/src/plugin-api/oracle-plugin.ts +35 -0
  104. package/src/plugin-api/request-admission.ts +41 -0
  105. package/src/plugin-api/tool-helper.ts +25 -1
  106. package/src/plugin-api/tool-plane.ts +92 -0
  107. package/src/plugin-api/types.ts +194 -6
  108. package/src/plugins/agui/agui.plugin.ts +31 -16
  109. package/src/plugins/composio/composio-tools.ts +57 -6
  110. package/src/plugins/composio/composio-ucan.ts +3 -2
  111. package/src/plugins/composio/composio.plugin.ts +2 -0
  112. package/src/plugins/delegated-capabilities.ts +25 -0
  113. package/src/plugins/editor/content-session.ts +173 -83
  114. package/src/plugins/editor/content-tools.ts +76 -17
  115. package/src/plugins/editor/editor-mx.ts +28 -9
  116. package/src/plugins/editor/editor.plugin.ts +3 -1
  117. package/src/plugins/editor/failures.ts +28 -7
  118. package/src/plugins/editor/prompts.ts +2 -1
  119. package/src/plugins/editor/provider.ts +553 -40
  120. package/src/plugins/editor/standalone-editor-tool.ts +61 -18
  121. package/src/plugins/firecrawl/firecrawl-tools.ts +13 -5
  122. package/src/plugins/flows/action-metadata.ts +111 -11
  123. package/src/plugins/flows/actions.ts +18 -0
  124. package/src/plugins/flows/decision-context.ts +31 -0
  125. package/src/plugins/flows/edit.ts +223 -52
  126. package/src/plugins/flows/errors.ts +22 -1
  127. package/src/plugins/flows/flow-doc.ts +92 -9
  128. package/src/plugins/flows/flows.plugin.ts +11 -5
  129. package/src/plugins/flows/forms.ts +34 -0
  130. package/src/plugins/flows/index.ts +2 -0
  131. package/src/plugins/flows/input-policy.ts +140 -0
  132. package/src/plugins/flows/prompts.ts +14 -11
  133. package/src/plugins/flows/read.ts +49 -9
  134. package/src/plugins/flows/ref-syntax.ts +129 -0
  135. package/src/plugins/flows/test-homeserver.ts +245 -0
  136. package/src/plugins/flows/tools/authoring.ts +216 -112
  137. package/src/plugins/flows/tools/discovery.ts +4 -1
  138. package/src/plugins/flows/tools/forms.ts +21 -2
  139. package/src/plugins/flows/tools/settings.ts +34 -13
  140. package/src/plugins/flows/translator.ts +13 -10
  141. package/src/plugins/flows/types.ts +167 -42
  142. package/src/plugins/index.ts +11 -1
  143. package/src/plugins/ixo-transaction/chain-ids.ts +43 -0
  144. package/src/plugins/ixo-transaction/index.ts +2 -0
  145. package/src/plugins/ixo-transaction/ixo-transaction.plugin.ts +119 -0
  146. package/src/plugins/ixo-transaction/receipts.ts +99 -0
  147. package/src/plugins/ixo-transaction/tools.ts +329 -0
  148. package/src/plugins/ixo-transaction/wallet-signing.ts +202 -0
  149. package/src/plugins/mcp-tool-adapter.ts +23 -2
  150. package/src/plugins/memory/memory-tools.ts +7 -2
  151. package/src/plugins/memory/memory-ucan.ts +3 -2
  152. package/src/plugins/memory/memory.plugin.ts +2 -0
  153. package/src/plugins/pod-creator/blueprint-store.ts +163 -0
  154. package/src/plugins/pod-creator/blueprint-types.ts +61 -0
  155. package/src/plugins/pod-creator/bounded-map.ts +87 -0
  156. package/src/plugins/pod-creator/capsule-content-client.ts +285 -0
  157. package/src/plugins/pod-creator/chain-gateway.ts +110 -0
  158. package/src/plugins/pod-creator/config.ts +85 -0
  159. package/src/plugins/pod-creator/create-session-store.ts +180 -0
  160. package/src/plugins/pod-creator/create-tools.ts +538 -0
  161. package/src/plugins/pod-creator/design-pod-roles.ts +111 -0
  162. package/src/plugins/pod-creator/index.ts +65 -0
  163. package/src/plugins/pod-creator/orchestration-tools.ts +172 -0
  164. package/src/plugins/pod-creator/pod-creator.plugin.ts +190 -0
  165. package/src/plugins/pod-creator/stage.ts +201 -0
  166. package/src/plugins/pod-creator/sub-agents.ts +189 -0
  167. package/src/plugins/portal/action-log.ts +21 -1
  168. package/src/plugins/portal/declared-tools.ts +90 -0
  169. package/src/plugins/portal/portal.plugin.ts +42 -16
  170. package/src/plugins/sandbox/sandbox-bridge.ts +79 -10
  171. package/src/plugins/sandbox/sandbox-mcp.ts +3 -2
  172. package/src/plugins/sandbox/sandbox-write-blob.ts +11 -1
  173. package/src/plugins/sandbox/sandbox.plugin.ts +8 -16
  174. package/src/plugins/tasks/manifest.ts +1 -1
  175. package/src/plugins/tasks/middleware.ts +20 -7
  176. package/src/plugins/tasks/tasks-tools.ts +30 -3
  177. package/src/plugins/tasks/tasks.plugin.ts +64 -11
  178. package/src/plugins/user-preferences/schema.ts +12 -1
  179. package/src/plugins/user-preferences/user-preferences-store.ts +38 -13
  180. package/src/plugins/user-preferences/user-preferences-tool.ts +3 -2
  181. package/src/plugins/vfs/vfs-client.ts +250 -71
  182. package/src/plugins/vfs/vfs-content.ts +30 -11
  183. package/src/plugins/vfs/vfs-errors.ts +22 -0
  184. package/src/plugins/vfs/vfs-sandbox-tools.ts +12 -5
  185. package/src/plugins/vfs/vfs-tools.ts +60 -20
  186. package/src/realtime/frontend-call-registry.ts +228 -81
  187. package/src/realtime/realtime-endpoint.ts +215 -44
  188. package/src/realtime/session-socket-hub.ts +47 -2
  189. package/src/secrets/secrets-service.ts +9 -3
  190. package/src/shell/app.ts +562 -82
  191. package/src/shell/auth.ts +131 -37
  192. package/src/shell/turn-body-cap.ts +11 -13
  193. package/src/sqlite/blob-compactor.ts +61 -28
  194. package/src/sqlite/database.ts +156 -90
  195. package/src/sqlite/do-vfs.ts +416 -129
  196. package/src/sqlite/page-tier.ts +133 -40
  197. package/src/sqlite/serialization.ts +40 -0
  198. package/src/sqlite/sessions-store.ts +10 -2
  199. package/src/sqlite/sqlite-saver.ts +139 -19
  200. package/src/sqlite/user-kv-store.ts +317 -0
  201. package/src/tasks/schedule.ts +201 -12
  202. package/src/tasks/scheduler.ts +586 -98
  203. package/src/tasks/spec.ts +67 -3
  204. package/src/tasks/store.ts +292 -27
  205. package/src/tasks/topic-deliverables.ts +70 -0
@@ -0,0 +1,245 @@
1
+ /**
2
+ * Test support: an in-memory Matrix homeserver behind a real `matrix-js-sdk`
3
+ * client. The client's `fetchFn` is routed here, so matrix-crdt and the
4
+ * provider run their real code paths — join, backwards history walk, the
5
+ * `/events` long-poll, document-update sends — against rooms these tests
6
+ * control, and every request is counted. Not a `*.test.ts` file.
7
+ *
8
+ * Only the endpoints the document provider uses are implemented:
9
+ * POST /join/{room} → joins (always succeeds)
10
+ * GET /rooms/{room}/messages → the stored events, newest first
11
+ * GET /events → held open until aborted
12
+ * PUT /rooms/{room}/send/{type}/{txn} → stored, or the scripted failure
13
+ * GET /rooms/{room}/state/… → 404 M_NOT_FOUND
14
+ * Anything else answers 404 `M_UNRECOGNIZED` and is recorded.
15
+ */
16
+ import { createClient, type MatrixClient } from 'matrix-js-sdk';
17
+ import * as Y from 'yjs';
18
+
19
+ export const TEST_HOMESERVER_URL = 'https://hs.test.example';
20
+ export const TEST_ORACLE_USER = '@oracle:test.example';
21
+
22
+ export interface StoredEvent {
23
+ event_id: string;
24
+ type: string;
25
+ room_id: string;
26
+ sender: string;
27
+ user_id: string;
28
+ origin_server_ts: number;
29
+ content: Record<string, unknown>;
30
+ }
31
+
32
+ /**
33
+ * A scripted homeserver answer: `ok` stores the event; `network` fails the
34
+ * request with no HTTP answer; `hang` never answers (until aborted); else an
35
+ * error body.
36
+ */
37
+ export type SendOutcome =
38
+ | 'ok'
39
+ | 'network'
40
+ | 'hang'
41
+ | {
42
+ status: number;
43
+ errcode: string;
44
+ error?: string;
45
+ retry_after_ms?: number;
46
+ };
47
+
48
+ export interface RecordedRequest {
49
+ method: string;
50
+ path: string;
51
+ at: number;
52
+ }
53
+
54
+ function json(status: number, body: unknown): Response {
55
+ return new Response(JSON.stringify(body), {
56
+ status,
57
+ headers: { 'content-type': 'application/json' },
58
+ });
59
+ }
60
+
61
+ function encodeUpdate(update: Uint8Array): string {
62
+ let binary = '';
63
+ for (const byte of update) binary += String.fromCharCode(byte);
64
+ return btoa(binary);
65
+ }
66
+
67
+ export class TestHomeserver {
68
+ readonly requests: RecordedRequest[] = [];
69
+ /** Events per room, oldest first. */
70
+ readonly rooms = new Map<string, StoredEvent[]>();
71
+ /** Answers for document-update sends, consumed in order; then `ok`. */
72
+ sendScript: SendOutcome[] = [];
73
+ /** When set, `/messages` answers this instead of the stored events. */
74
+ messagesFailure: { status: number; errcode: string } | undefined;
75
+ /** When set, `POST /join` answers this error. */
76
+ joinFailure: { status: number; errcode: string } | undefined;
77
+ /** One-off `/messages` failures, consumed in order before `messagesFailure`. */
78
+ messagesScript: Array<{ status: number; errcode: string }> = [];
79
+ /** `/events` long-polls currently held open. */
80
+ openPolls = 0;
81
+ /** Delays (ms) for successive `/messages` answers, consumed in order. */
82
+ messagesDelays: number[] = [];
83
+
84
+ private nextEventId = 1;
85
+
86
+ /** A fresh client bound to this homeserver. */
87
+ client(): MatrixClient {
88
+ return createClient({
89
+ baseUrl: TEST_HOMESERVER_URL,
90
+ accessToken: 'test-token',
91
+ userId: TEST_ORACLE_USER,
92
+ fetchFn: (input, init) => this.handle(input, init),
93
+ });
94
+ }
95
+
96
+ /** Store a Y.Doc's full state as one document-update event in `roomId`. */
97
+ seedDoc(roomId: string, doc: Y.Doc): void {
98
+ this.append(roomId, 'matrix-crdt.doc_update', {
99
+ update: encodeUpdate(Y.encodeStateAsUpdate(doc)),
100
+ });
101
+ }
102
+
103
+ /** Rebuild the room's document from its stored update events. */
104
+ docOf(roomId: string): Y.Doc {
105
+ const doc = new Y.Doc();
106
+ for (const event of this.rooms.get(roomId) ?? []) {
107
+ const update = event.content.update;
108
+ if (typeof update !== 'string') continue;
109
+ const bytes = Uint8Array.from(atob(update), (c) => c.charCodeAt(0));
110
+ Y.applyUpdate(doc, bytes);
111
+ }
112
+ return doc;
113
+ }
114
+
115
+ count(method: string, pathPart: string): number {
116
+ return this.requests.filter(
117
+ (r) => r.method === method && r.path.includes(pathPart),
118
+ ).length;
119
+ }
120
+
121
+ private append(
122
+ roomId: string,
123
+ type: string,
124
+ content: Record<string, unknown>,
125
+ ): StoredEvent {
126
+ const event: StoredEvent = {
127
+ event_id: `$e${this.nextEventId++}`,
128
+ type,
129
+ room_id: roomId,
130
+ sender: TEST_ORACLE_USER,
131
+ user_id: TEST_ORACLE_USER,
132
+ origin_server_ts: Date.now(),
133
+ content,
134
+ };
135
+ const events = this.rooms.get(roomId) ?? [];
136
+ events.push(event);
137
+ this.rooms.set(roomId, events);
138
+ return event;
139
+ }
140
+
141
+ private async handle(
142
+ input: RequestInfo | URL,
143
+ init: RequestInit | undefined,
144
+ ): Promise<Response> {
145
+ const url = new URL(input instanceof Request ? input.url : String(input));
146
+ const method = (
147
+ init?.method ?? (input instanceof Request ? input.method : 'GET')
148
+ ).toUpperCase();
149
+ const path = decodeURIComponent(
150
+ url.pathname.replace(/^\/_matrix\/client\/v3/, ''),
151
+ );
152
+ this.requests.push({ method, path, at: Date.now() });
153
+
154
+ const join = /^\/join\/(.+)$/.exec(path);
155
+ if (method === 'POST' && join)
156
+ return this.joinFailure
157
+ ? json(this.joinFailure.status, {
158
+ errcode: this.joinFailure.errcode,
159
+ error: 'scripted failure',
160
+ })
161
+ : json(200, { room_id: join[1] });
162
+
163
+ const messages = /^\/rooms\/([^/]+)\/messages$/.exec(path);
164
+ if (method === 'GET' && messages) {
165
+ const delay = this.messagesDelays.shift();
166
+ if (delay) await new Promise((resolve) => setTimeout(resolve, delay));
167
+ const failure = this.messagesScript.shift() ?? this.messagesFailure;
168
+ if (failure)
169
+ return json(failure.status, {
170
+ errcode: failure.errcode,
171
+ error: 'scripted failure',
172
+ });
173
+ const chunk = [...(this.rooms.get(messages[1] ?? '') ?? [])].reverse();
174
+ return json(200, { chunk, start: 't0' });
175
+ }
176
+
177
+ if (method === 'GET' && path === '/events') {
178
+ const signal = init?.signal;
179
+ this.openPolls += 1;
180
+ return new Promise<Response>((_resolve, reject) => {
181
+ const finish = () => {
182
+ this.openPolls -= 1;
183
+ const reason: unknown = signal?.reason;
184
+ reject(reason instanceof Error ? reason : new Error('aborted'));
185
+ };
186
+ if (signal?.aborted) finish();
187
+ else signal?.addEventListener('abort', finish, { once: true });
188
+ });
189
+ }
190
+
191
+ const send = /^\/rooms\/([^/]+)\/send\/([^/]+)\/([^/]+)$/.exec(path);
192
+ if (method === 'PUT' && send) {
193
+ const [, roomId = '', type = ''] = send;
194
+ const outcome =
195
+ type === 'matrix-crdt.doc_update' ? this.sendScript.shift() : 'ok';
196
+ if (outcome === 'network') throw new TypeError('Network connection lost');
197
+ if (outcome === 'hang')
198
+ return new Promise<Response>((_resolve, reject) => {
199
+ const signal = init?.signal;
200
+ signal?.addEventListener(
201
+ 'abort',
202
+ () => reject(new Error('aborted')),
203
+ { once: true },
204
+ );
205
+ });
206
+ if (outcome && outcome !== 'ok')
207
+ return json(outcome.status, {
208
+ errcode: outcome.errcode,
209
+ error: outcome.error ?? 'scripted failure',
210
+ ...(outcome.retry_after_ms !== undefined
211
+ ? { retry_after_ms: outcome.retry_after_ms }
212
+ : {}),
213
+ });
214
+ const body: unknown = JSON.parse(String(init?.body ?? '{}'));
215
+ const content = body && typeof body === 'object' ? { ...body } : {};
216
+ return json(200, {
217
+ event_id: this.append(roomId, type, content).event_id,
218
+ });
219
+ }
220
+
221
+ if (method === 'GET' && /^\/rooms\/[^/]+\/state\//.test(path))
222
+ return json(404, { errcode: 'M_NOT_FOUND', error: 'not found' });
223
+
224
+ return json(404, { errcode: 'M_UNRECOGNIZED', error: `no route ${path}` });
225
+ }
226
+ }
227
+
228
+ /**
229
+ * Record every unhandled promise rejection until `stop()` is called. Uses the
230
+ * global `unhandledrejection` event, which workerd dispatches.
231
+ */
232
+ export function watchUnhandledRejections(): {
233
+ reasons: unknown[];
234
+ stop: () => void;
235
+ } {
236
+ const reasons: unknown[] = [];
237
+ const listener = (event: PromiseRejectionEvent) => {
238
+ reasons.push(event.reason);
239
+ };
240
+ globalThis.addEventListener('unhandledrejection', listener);
241
+ return {
242
+ reasons,
243
+ stop: () => globalThis.removeEventListener('unhandledrejection', listener),
244
+ };
245
+ }