@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.
Files changed (215) hide show
  1. package/README.md +110 -0
  2. package/package.json +77 -0
  3. package/src/attachments/classify.ts +114 -0
  4. package/src/attachments/content-blocks.ts +51 -0
  5. package/src/attachments/download.ts +235 -0
  6. package/src/attachments/extract.ts +241 -0
  7. package/src/attachments/index.ts +84 -0
  8. package/src/attachments/magic.ts +133 -0
  9. package/src/attachments/pipeline.ts +409 -0
  10. package/src/attachments/retention.ts +205 -0
  11. package/src/attachments/route.ts +41 -0
  12. package/src/attachments/sandbox-archive.ts +90 -0
  13. package/src/attachments/sanitize.ts +35 -0
  14. package/src/attachments/types.ts +86 -0
  15. package/src/attachments/view.ts +107 -0
  16. package/src/core/env.ts +200 -0
  17. package/src/core/index.ts +513 -0
  18. package/src/core/llm.ts +842 -0
  19. package/src/core/main-agent-types.ts +123 -0
  20. package/src/core/main-agent.ts +399 -0
  21. package/src/core/manifest.ts +365 -0
  22. package/src/core/meta-tools.ts +232 -0
  23. package/src/core/middlewares/byo-history-sanitizer.ts +165 -0
  24. package/src/core/middlewares/capability-gate.ts +76 -0
  25. package/src/core/middlewares/index.ts +18 -0
  26. package/src/core/middlewares/page-context.ts +98 -0
  27. package/src/core/middlewares/safety-guardrail.ts +117 -0
  28. package/src/core/middlewares/summarization.ts +99 -0
  29. package/src/core/middlewares/tool-repetition-guard.ts +125 -0
  30. package/src/core/middlewares/tool-validation.ts +83 -0
  31. package/src/core/middlewares/work-status.ts +57 -0
  32. package/src/core/openrouter-pricing.ts +124 -0
  33. package/src/core/plugin-loader.ts +192 -0
  34. package/src/core/plugins/index.ts +6 -0
  35. package/src/core/plugins/skills/index.ts +8 -0
  36. package/src/core/plugins/skills/skills-tools.ts +356 -0
  37. package/src/core/plugins/skills/skills.plugin.ts +113 -0
  38. package/src/core/plugins/weather/index.ts +8 -0
  39. package/src/core/plugins/weather/weather-client.ts +153 -0
  40. package/src/core/plugins/weather/weather-middleware.ts +27 -0
  41. package/src/core/plugins/weather/weather-sub-agent.ts +65 -0
  42. package/src/core/plugins/weather/weather-tools.ts +103 -0
  43. package/src/core/plugins/weather/weather.plugin.ts +227 -0
  44. package/src/core/prompt-composer.ts +469 -0
  45. package/src/core/registries.ts +642 -0
  46. package/src/core/runtime-context.ts +619 -0
  47. package/src/core/state.ts +108 -0
  48. package/src/core/sub-agent-fallback.ts +187 -0
  49. package/src/core/subagent-as-tool.ts +322 -0
  50. package/src/core/template.ts +245 -0
  51. package/src/core/utils.ts +246 -0
  52. package/src/core/wrap-plugin-tool.ts +100 -0
  53. package/src/do/ambient.ts +266 -0
  54. package/src/do/contracts.ts +562 -0
  55. package/src/do/debug-timers.ts +120 -0
  56. package/src/do/fresh-stub.ts +32 -0
  57. package/src/do/gateway-retry.ts +73 -0
  58. package/src/do/secrets-adapter.ts +32 -0
  59. package/src/do/size-alerts.ts +76 -0
  60. package/src/do/sse-stream.ts +472 -0
  61. package/src/do/transcript.ts +192 -0
  62. package/src/do/turn-body.ts +84 -0
  63. package/src/do/turn-metadata.ts +146 -0
  64. package/src/do/ucan-service.ts +339 -0
  65. package/src/do/user-oracle-do.ts +3035 -0
  66. package/src/gateway-worker.ts +82 -0
  67. package/src/index.ts +237 -0
  68. package/src/llm/byo-adapter.ts +59 -0
  69. package/src/llm/byo-catalog.ts +520 -0
  70. package/src/llm/byo-client.ts +280 -0
  71. package/src/llm/byo-routes.ts +255 -0
  72. package/src/llm/byo-service.ts +836 -0
  73. package/src/llm/chatgpt-oauth.ts +430 -0
  74. package/src/llm/provider-error.ts +283 -0
  75. package/src/matrix/gateway-do.ts +918 -0
  76. package/src/matrix/ingest.ts +209 -0
  77. package/src/matrix/replay-format.ts +34 -0
  78. package/src/matrix/reply-chain.ts +109 -0
  79. package/src/matrix/room-state-codec.ts +115 -0
  80. package/src/matrix/user-homeserver.ts +106 -0
  81. package/src/matrix/work-status.ts +294 -0
  82. package/src/memory/session-history-indexer.ts +328 -0
  83. package/src/owner-store/ixo-vfs-store.ts +570 -0
  84. package/src/owner-store/matrix-media-store.ts +136 -0
  85. package/src/owner-store/migrating-store.ts +185 -0
  86. package/src/owner-store/owner-copy-errors.ts +175 -0
  87. package/src/owner-store/retry.ts +45 -0
  88. package/src/owner-store/tus-upload.ts +333 -0
  89. package/src/owner-store/types.ts +0 -0
  90. package/src/plugin-api/define-plugin.ts +45 -0
  91. package/src/plugin-api/index.ts +56 -0
  92. package/src/plugin-api/oracle-plugin.ts +145 -0
  93. package/src/plugin-api/tool-helper.ts +82 -0
  94. package/src/plugin-api/types.ts +816 -0
  95. package/src/plugin-api/ucan-errors.ts +16 -0
  96. package/src/plugins/agui/agui-agent.ts +115 -0
  97. package/src/plugins/agui/agui.plugin.ts +148 -0
  98. package/src/plugins/agui/index.ts +2 -0
  99. package/src/plugins/attachments/attachments.plugin.ts +54 -0
  100. package/src/plugins/attachments/index.ts +6 -0
  101. package/src/plugins/attachments/view-attachment-tool.ts +91 -0
  102. package/src/plugins/base64.ts +26 -0
  103. package/src/plugins/composio/composio-tools.ts +365 -0
  104. package/src/plugins/composio/composio-ucan.ts +43 -0
  105. package/src/plugins/composio/composio.plugin.ts +214 -0
  106. package/src/plugins/composio/index.ts +15 -0
  107. package/src/plugins/domain-indexer/domain-indexer-agent.ts +57 -0
  108. package/src/plugins/domain-indexer/domain-indexer-tools.ts +253 -0
  109. package/src/plugins/domain-indexer/domain-indexer.plugin.ts +100 -0
  110. package/src/plugins/domain-indexer/index.ts +3 -0
  111. package/src/plugins/editor/blocknote-bridge.ts +120 -0
  112. package/src/plugins/editor/content-session.ts +331 -0
  113. package/src/plugins/editor/content-tools.ts +686 -0
  114. package/src/plugins/editor/document-model.ts +0 -0
  115. package/src/plugins/editor/editor-access-denied-tool.ts +58 -0
  116. package/src/plugins/editor/editor-agent.ts +34 -0
  117. package/src/plugins/editor/editor-config.ts +64 -0
  118. package/src/plugins/editor/editor-mx.ts +128 -0
  119. package/src/plugins/editor/editor.plugin.ts +143 -0
  120. package/src/plugins/editor/failures.ts +154 -0
  121. package/src/plugins/editor/index.ts +31 -0
  122. package/src/plugins/editor/jsdom-shim.ts +55 -0
  123. package/src/plugins/editor/prompts.ts +59 -0
  124. package/src/plugins/editor/prop-policy.ts +147 -0
  125. package/src/plugins/editor/provider.ts +386 -0
  126. package/src/plugins/editor/room-membership.ts +95 -0
  127. package/src/plugins/editor/standalone-editor-tool.ts +200 -0
  128. package/src/plugins/firecrawl/firecrawl-agent.ts +93 -0
  129. package/src/plugins/firecrawl/firecrawl-tools.ts +220 -0
  130. package/src/plugins/firecrawl/firecrawl.plugin.ts +105 -0
  131. package/src/plugins/firecrawl/index.ts +15 -0
  132. package/src/plugins/flows/action-metadata.ts +3505 -0
  133. package/src/plugins/flows/actions.ts +190 -0
  134. package/src/plugins/flows/edit.ts +314 -0
  135. package/src/plugins/flows/errors.ts +38 -0
  136. package/src/plugins/flows/explain.ts +43 -0
  137. package/src/plugins/flows/flow-doc.ts +111 -0
  138. package/src/plugins/flows/flows.plugin.ts +129 -0
  139. package/src/plugins/flows/forms.ts +330 -0
  140. package/src/plugins/flows/index.ts +2 -0
  141. package/src/plugins/flows/linkage.ts +147 -0
  142. package/src/plugins/flows/port-types.ts +53 -0
  143. package/src/plugins/flows/prompts.ts +65 -0
  144. package/src/plugins/flows/read.ts +392 -0
  145. package/src/plugins/flows/references.ts +66 -0
  146. package/src/plugins/flows/test-support.ts +165 -0
  147. package/src/plugins/flows/tools/authoring.ts +516 -0
  148. package/src/plugins/flows/tools/discovery.ts +119 -0
  149. package/src/plugins/flows/tools/forms.ts +142 -0
  150. package/src/plugins/flows/tools/inspect.ts +165 -0
  151. package/src/plugins/flows/tools/linkage.ts +117 -0
  152. package/src/plugins/flows/tools/settings.ts +184 -0
  153. package/src/plugins/flows/translator.ts +328 -0
  154. package/src/plugins/flows/types.ts +210 -0
  155. package/src/plugins/flows/ydoc-helpers.ts +543 -0
  156. package/src/plugins/index.ts +70 -0
  157. package/src/plugins/mcp-call-timeout.ts +38 -0
  158. package/src/plugins/mcp-tool-adapter.ts +87 -0
  159. package/src/plugins/memory/index.ts +17 -0
  160. package/src/plugins/memory/memory-tools.ts +463 -0
  161. package/src/plugins/memory/memory-ucan.ts +51 -0
  162. package/src/plugins/memory/memory.plugin.ts +122 -0
  163. package/src/plugins/memory/types.ts +147 -0
  164. package/src/plugins/portal/action-log.ts +34 -0
  165. package/src/plugins/portal/index.ts +2 -0
  166. package/src/plugins/portal/portal.plugin.ts +203 -0
  167. package/src/plugins/sandbox/index.ts +34 -0
  168. package/src/plugins/sandbox/sandbox-bridge.ts +295 -0
  169. package/src/plugins/sandbox/sandbox-mcp.ts +127 -0
  170. package/src/plugins/sandbox/sandbox-write-blob.ts +103 -0
  171. package/src/plugins/sandbox/sandbox.plugin.ts +599 -0
  172. package/src/plugins/tasks/index.ts +17 -0
  173. package/src/plugins/tasks/manifest.ts +81 -0
  174. package/src/plugins/tasks/middleware.ts +219 -0
  175. package/src/plugins/tasks/tasks-tools.ts +414 -0
  176. package/src/plugins/tasks/tasks.plugin.ts +74 -0
  177. package/src/plugins/ucan-failure.ts +133 -0
  178. package/src/plugins/user-preferences/index.ts +22 -0
  179. package/src/plugins/user-preferences/schema.ts +31 -0
  180. package/src/plugins/user-preferences/user-preferences-store.ts +172 -0
  181. package/src/plugins/user-preferences/user-preferences-tool.ts +131 -0
  182. package/src/plugins/user-preferences/user-preferences.plugin.ts +137 -0
  183. package/src/plugins/vfs/index.ts +40 -0
  184. package/src/plugins/vfs/vfs-auth.ts +56 -0
  185. package/src/plugins/vfs/vfs-client.ts +655 -0
  186. package/src/plugins/vfs/vfs-content.ts +181 -0
  187. package/src/plugins/vfs/vfs-errors.ts +163 -0
  188. package/src/plugins/vfs/vfs-sandbox-tools.ts +272 -0
  189. package/src/plugins/vfs/vfs-tools.ts +635 -0
  190. package/src/plugins/vfs/vfs.plugin.ts +201 -0
  191. package/src/realtime/frontend-call-registry.ts +163 -0
  192. package/src/realtime/realtime-endpoint.ts +619 -0
  193. package/src/realtime/session-socket-hub.ts +249 -0
  194. package/src/realtime/socket-io-codec.ts +187 -0
  195. package/src/secrets/jwe.ts +74 -0
  196. package/src/secrets/pin-cipher.ts +43 -0
  197. package/src/secrets/secrets-service.ts +319 -0
  198. package/src/shell/app.ts +564 -0
  199. package/src/shell/auth.ts +290 -0
  200. package/src/sqlite/blob-codec.ts +100 -0
  201. package/src/sqlite/blob-compactor.ts +146 -0
  202. package/src/sqlite/cache-config.ts +45 -0
  203. package/src/sqlite/database.ts +643 -0
  204. package/src/sqlite/do-vfs.ts +1485 -0
  205. package/src/sqlite/index.ts +61 -0
  206. package/src/sqlite/serialization.ts +370 -0
  207. package/src/sqlite/sessions-store.ts +311 -0
  208. package/src/sqlite/sqlite-saver.ts +919 -0
  209. package/src/sqlite/vacuum-policy.ts +77 -0
  210. package/src/sqlite/wa-sqlite-loader.ts +123 -0
  211. package/src/sqlite/wasm.d.ts +10 -0
  212. package/src/tasks/schedule.ts +174 -0
  213. package/src/tasks/scheduler.ts +753 -0
  214. package/src/tasks/spec.ts +125 -0
  215. package/src/tasks/store.ts +351 -0
@@ -0,0 +1,513 @@
1
+ /**
2
+ * The runtime core — everything between "a list of plugins + the Worker env"
3
+ * and "a compiled LangChain agent for one turn". Nothing in here touches
4
+ * Durable Objects, Matrix, or Hono; the host (`src/do`, `src/shell`) supplies
5
+ * those through the `AmbientServices` adapters and mounts `pluginRoutes`.
6
+ */
7
+ import { z } from 'zod';
8
+ import type { OraclePlugin, PluginRoute } from '../plugin-api/oracle-plugin';
9
+ import type {
10
+ AuthExcludedRoute,
11
+ Logger,
12
+ OracleConfig,
13
+ OracleIdentity,
14
+ PluginContext,
15
+ } from '../plugin-api/types';
16
+ import { baseEnvSchema, composeEnvSchema, validateEnv } from './env';
17
+ import { createLlmAdapter, type OpenRouterLlmAdapter } from './llm';
18
+ import { validateManifest, type PluginManifestOverride } from './manifest';
19
+ import {
20
+ resolvePlugins,
21
+ type ExcludedPlugin,
22
+ type FeatureToggle,
23
+ type SoftDepGap,
24
+ } from './plugin-loader';
25
+ import { createRegistries, type Registries } from './registries';
26
+ import { buildPluginContext } from './runtime-context';
27
+ import { NOOP_LOGGER } from './utils';
28
+
29
+ // ── Public surface ──────────────────────────────────────────────────────────
30
+
31
+ export { z };
32
+
33
+ export { baseEnvSchema, composeEnvSchema, validateEnv } from './env';
34
+ export type {
35
+ BaseEnv,
36
+ ComposeEnvSchemaResult,
37
+ ValidateEnvError,
38
+ ValidateEnvResult,
39
+ } from './env';
40
+
41
+ export { resolvePlugins, topoSort } from './plugin-loader';
42
+ export type {
43
+ ExcludedPlugin,
44
+ ExclusionCause,
45
+ FeatureToggle,
46
+ ResolvePluginsInput,
47
+ ResolvePluginsResult,
48
+ SoftDepGap,
49
+ } from './plugin-loader';
50
+
51
+ export {
52
+ ConfigSchemaRegistry,
53
+ ManifestRegistry,
54
+ MiddlewareRegistry,
55
+ SharedStateRegistry,
56
+ SubAgentRegistry,
57
+ ToolRegistry,
58
+ createRegistries,
59
+ formatByPlugin,
60
+ } from './registries';
61
+ export type {
62
+ ManifestCrossCheckResult,
63
+ RegisteredConfigSchema,
64
+ RegisteredManifest,
65
+ RegisteredMiddleware,
66
+ RegisteredSharedAccessor,
67
+ RegisteredSubAgent,
68
+ RegisteredTool,
69
+ Registries,
70
+ ToolSummary,
71
+ } from './registries';
72
+
73
+ export {
74
+ estimateTokensApprox,
75
+ manifestCategorySchema,
76
+ manifestExampleSchema,
77
+ manifestStabilitySchema,
78
+ manifestVisibilitySchema,
79
+ mergeManifestOverride,
80
+ pluginManifestSchema,
81
+ renderTier1,
82
+ validateExamplesAgainstTools,
83
+ validateManifest,
84
+ } from './manifest';
85
+ export type {
86
+ ManifestValidationResult,
87
+ PluginManifestOverride,
88
+ Tier1Entry,
89
+ Tier1Input,
90
+ Tier1Output,
91
+ } from './manifest';
92
+
93
+ export {
94
+ buildListCapabilitiesTool,
95
+ buildLoadCapabilityTool,
96
+ buildMetaTools,
97
+ } from './meta-tools';
98
+ export type { BuildMetaToolsOptions } from './meta-tools';
99
+
100
+ export {
101
+ DEFAULT_MODEL_ID,
102
+ MODEL_CATALOG,
103
+ OPENROUTER_BASE_URL,
104
+ OPENROUTER_MAIN_FALLBACKS,
105
+ OPENROUTER_MODEL_MAP,
106
+ TIER_DISPLAY,
107
+ DEFAULT_MODEL_PRICE_MARKUP,
108
+ buildModelListing,
109
+ createLlmAdapter,
110
+ getCatalogEntry,
111
+ getDefaultModelId,
112
+ getModelCapabilities,
113
+ getModelPriceMarkup,
114
+ isAllowedModel,
115
+ listModelCatalog,
116
+ listModels,
117
+ } from './llm';
118
+ export {
119
+ OPENROUTER_MODELS_URL,
120
+ OPENROUTER_PRICE_CACHE_TTL_MS,
121
+ fetchOpenRouterPrices,
122
+ resetOpenRouterPriceCache,
123
+ type FetchOpenRouterPricesOptions,
124
+ } from './openrouter-pricing';
125
+ export type {
126
+ LlmEnv,
127
+ ModelCatalogEntry,
128
+ ModelFamily,
129
+ ModelInputCapabilities,
130
+ ModelListItem,
131
+ ModelListing,
132
+ ModelPrice,
133
+ ModelTier,
134
+ OpenRouterLlmAdapter,
135
+ ProviderModelRole,
136
+ } from './llm';
137
+
138
+ export { MainAgentGraphState } from './state';
139
+ export type {
140
+ AgAction,
141
+ BrowserToolCall,
142
+ TMainAgentGraphState,
143
+ UserPreferences,
144
+ } from './state';
145
+
146
+ export {
147
+ buildOracleSection,
148
+ composePrompt,
149
+ formatTimeContext,
150
+ formatUserPreferences,
151
+ } from './prompt-composer';
152
+ export type {
153
+ ComposePromptInput,
154
+ MemoryCommunity,
155
+ MemoryContextSection,
156
+ MemoryEntity,
157
+ MemoryEpisode,
158
+ MemoryFact,
159
+ TypedUserContext,
160
+ } from './prompt-composer';
161
+ export { compileTemplate, renderTemplate } from './template';
162
+ export type { CompiledTemplate, TemplateValues } from './template';
163
+
164
+ export * from './middlewares';
165
+
166
+ export {
167
+ EMPTY_SHARED,
168
+ EVENT_NAMES,
169
+ buildPluginContext,
170
+ buildRuntimeContext,
171
+ createMemoryBlobStore,
172
+ createNoopAmbient,
173
+ createScopedEmitter,
174
+ createUnavailableLlmAdapter,
175
+ createUnavailableMatrixAdapter,
176
+ createUnsignedUcanAdapter,
177
+ delegationHasCapability,
178
+ } from './runtime-context';
179
+ export type {
180
+ AmbientServices,
181
+ BlobStoreAdapter,
182
+ BuildPluginContextInput,
183
+ DelegationLike,
184
+ EmitAdapter,
185
+ LlmAdapter,
186
+ MatrixAdapter,
187
+ NoopAmbientOverrides,
188
+ RawEventPayload,
189
+ RunConfig,
190
+ RunConfigContext,
191
+ RuntimeSessionContext,
192
+ RuntimeStateInput,
193
+ RuntimeUserContext,
194
+ ScopeKeys,
195
+ ScopedEmitter,
196
+ SecretsAdapter,
197
+ UcanAdapter,
198
+ } from './runtime-context';
199
+
200
+ export { wrapPluginTool } from './wrap-plugin-tool';
201
+ export type { WrapPluginToolOptions } from './wrap-plugin-tool';
202
+ export {
203
+ computeSubAgentToolName,
204
+ createSubagentAsTool,
205
+ filterForwardedMessages,
206
+ } from './subagent-as-tool';
207
+ export type { AgentSpec, SubagentToolOptions } from './subagent-as-tool';
208
+ export { collectSubAgentsWithFallback } from './sub-agent-fallback';
209
+ export type { CollectSubAgentsInput } from './sub-agent-fallback';
210
+
211
+ export { createMainAgent } from './main-agent';
212
+ export { mainAgentRequestContextSchema } from './main-agent-types';
213
+ export type {
214
+ CompiledMainAgent,
215
+ MainAgentArgs,
216
+ MainAgentBuildResult,
217
+ MainAgentHooks,
218
+ MainAgentRegistries,
219
+ MainAgentRequestContext,
220
+ } from './main-agent-types';
221
+
222
+ export {
223
+ NOOP_LOGGER,
224
+ acquireToolLock,
225
+ clientSchemaToZod,
226
+ createConsoleLogger,
227
+ inlineLocalJsonPointerRefs,
228
+ lruInsert,
229
+ sweepExpired,
230
+ } from './utils';
231
+
232
+ export * from './plugins';
233
+
234
+ // ── Boot ────────────────────────────────────────────────────────────────────
235
+
236
+ export interface RuntimeCoreOptions {
237
+ /** Inline oracle config. `entityDid` comes from env — do not put it here. */
238
+ config: OracleConfig;
239
+ /**
240
+ * Every plugin the oracle may load. Each goes through `features` and its
241
+ * own `autoDetect`; plugins with neither load unconditionally.
242
+ */
243
+ plugins: OraclePlugin[];
244
+ features?: Partial<Record<string, FeatureToggle>>;
245
+ /**
246
+ * Per-plugin manifest overrides, merged shallowly over each plugin's own
247
+ * `manifest`. Keys that match no loaded plugin are logged and ignored.
248
+ */
249
+ manifestOverrides?: Partial<Record<string, PluginManifestOverride>>;
250
+ /**
251
+ * The Worker `env` bindings object. Validated against the base schema plus
252
+ * every loaded plugin's `configSchema`; unknown keys (Durable Object
253
+ * namespaces, …) are stripped from `validatedEnv`.
254
+ */
255
+ env: Record<string, unknown>;
256
+ /** Boot + runtime logger. Defaults to a silent logger. */
257
+ logger?: Logger;
258
+ }
259
+
260
+ /**
261
+ * The boot-time snapshot the host builds once per isolate (memoised per
262
+ * `env` object) and hands to every Durable Object turn.
263
+ */
264
+ export interface RuntimeCore {
265
+ identity: OracleIdentity;
266
+ registries: Registries;
267
+ /** Names of the plugins that loaded, in dependency order. */
268
+ availablePlugins: ReadonlySet<string>;
269
+ /** The loaded plugin instances, in dependency order. */
270
+ plugins: OraclePlugin[];
271
+ excluded: ExcludedPlugin[];
272
+ softDepGaps: SoftDepGap[];
273
+ /** Zod-validated env (base + plugin keys) — the `config` every context sees. */
274
+ validatedEnv: Record<string, unknown>;
275
+ /** Routes contributed by `getRoutes()`, for the shell to mount. */
276
+ pluginRoutes: PluginRoute[];
277
+ /** Auth exclusions contributed by `getAuthExcludedRoutes()`. */
278
+ authExcludedRoutes: AuthExcludedRoute[];
279
+ /** OpenRouter-backed LLM adapter (`get(role, params?)`). */
280
+ llm: OpenRouterLlmAdapter;
281
+ logger: Logger;
282
+ /** A boot-time `PluginContext` scoped to `pluginName` (default `__runtime__`). */
283
+ buildCtx(pluginName?: string): PluginContext;
284
+ /**
285
+ * Warm the registries' boot caches (`getTools` / `getSubAgents` /
286
+ * `getMiddlewares`) and run the cross-plugin checks that need them: tool,
287
+ * sub-agent and shared-state name collisions (fatal), and every manifest's
288
+ * `examples[].tool` references (advisory — logged). Memoised — safe to
289
+ * await on every turn; the first agent build would otherwise perform the
290
+ * collection lazily without the checks. Rejects with the boot error.
291
+ */
292
+ warm(): Promise<void>;
293
+ }
294
+
295
+ function reportBootError(logger: Logger, message: string, hint?: string): void {
296
+ const body = hint ? `${message}\n ${hint}` : message;
297
+ logger.error(`[boot-error] ${body}`);
298
+ }
299
+
300
+ function validateConfig(config: OracleConfig): void {
301
+ if (!config || typeof config !== 'object') {
302
+ throw new Error('createRuntimeCore: `config` is required.');
303
+ }
304
+ if (typeof config.name !== 'string' || config.name.trim().length === 0) {
305
+ throw new Error(
306
+ 'createRuntimeCore: `config.name` is required and must be a non-empty string.',
307
+ );
308
+ }
309
+ }
310
+
311
+ /**
312
+ * Resolve plugins, validate manifests and env, populate the registries and
313
+ * collect routes — the Node runtime's `createOracleApp` boot minus NestJS
314
+ * and Matrix (the Matrix gateway Durable Object owns its own init).
315
+ * Synchronous so the host can memoise it per isolate without an await;
316
+ * `warm()` does the async part.
317
+ */
318
+ export function createRuntimeCore(opts: RuntimeCoreOptions): RuntimeCore {
319
+ validateConfig(opts.config);
320
+ const logger = opts.logger ?? NOOP_LOGGER;
321
+
322
+ // 1. Plugin resolution — toggles, auto-detect, cascade, topo order.
323
+ let resolved;
324
+ try {
325
+ resolved = resolvePlugins({
326
+ bundled: opts.plugins,
327
+ features: opts.features,
328
+ env: opts.env,
329
+ logger,
330
+ });
331
+ } catch (err) {
332
+ reportBootError(logger, err instanceof Error ? err.message : String(err));
333
+ throw err;
334
+ }
335
+
336
+ // 2. Manifest overrides + validation.
337
+ const manifestOverrides = opts.manifestOverrides ?? {};
338
+ const loadedNames = new Set(resolved.loaded.map((p) => p.name));
339
+ for (const key of Object.keys(manifestOverrides)) {
340
+ if (!loadedNames.has(key)) {
341
+ logger.warn(
342
+ `[boot] manifestOverrides references '${key}', which is not a loaded plugin — ignored (event: boot.plugin.manifest_override_unknown)`,
343
+ );
344
+ }
345
+ }
346
+
347
+ const registries = createRegistries();
348
+ for (const plugin of resolved.loaded) {
349
+ registries.manifests.register(plugin, manifestOverrides[plugin.name]);
350
+ }
351
+ const manifestErrors: string[] = [];
352
+ for (const { pluginName, manifest } of registries.manifests.collect()) {
353
+ const result = validateManifest(manifest, pluginName);
354
+ for (const warning of result.warnings) logger.warn(`[boot] ${warning}`);
355
+ if (!result.valid) manifestErrors.push(...result.errors);
356
+ }
357
+ if (manifestErrors.length > 0) {
358
+ for (const err of manifestErrors) reportBootError(logger, err);
359
+ throw new Error(
360
+ `Plugin manifest validation failed (${manifestErrors.length} issues):\n - ${manifestErrors.join('\n - ')}`,
361
+ );
362
+ }
363
+
364
+ // 3. Env — base schema + plugin schemas, attributed errors.
365
+ const composed = composeEnvSchema(resolved.loaded, baseEnvSchema, logger);
366
+ const validated = validateEnv(
367
+ composed.schema,
368
+ opts.env,
369
+ composed.pluginOwnership,
370
+ );
371
+ if (!validated.valid) {
372
+ const lines: string[] = [];
373
+ for (const issue of validated.errors) {
374
+ const message = `Plugin '${issue.plugin}' env validation failed for '${issue.field}': ${issue.message}`;
375
+ reportBootError(
376
+ logger,
377
+ message,
378
+ issue.plugin === 'core'
379
+ ? `Set '${issue.field}' on the Worker (wrangler secret / vars).`
380
+ : `Set '${issue.field}' or disable: features: { ${issue.plugin}: false }`,
381
+ );
382
+ lines.push(message);
383
+ }
384
+ throw new Error(
385
+ `Env validation failed (${validated.errors.length} issues):\n - ${lines.join('\n - ')}`,
386
+ );
387
+ }
388
+
389
+ // 4. Identity.
390
+ const oracleDid = String(validated.config.ORACLE_DID);
391
+ const entityDid =
392
+ typeof validated.config.ORACLE_ENTITY_DID === 'string' &&
393
+ validated.config.ORACLE_ENTITY_DID.length > 0
394
+ ? validated.config.ORACLE_ENTITY_DID
395
+ : oracleDid;
396
+ const identity: OracleIdentity = {
397
+ name: opts.config.name,
398
+ org: opts.config.org ?? '',
399
+ description: opts.config.description ?? '',
400
+ entityDid,
401
+ prompt: opts.config.prompt ?? {},
402
+ };
403
+
404
+ // 5. Registries.
405
+ for (const plugin of resolved.loaded) {
406
+ registries.tools.register(plugin);
407
+ registries.subAgents.register(plugin);
408
+ registries.middlewares.register(plugin);
409
+ registries.configSchema.register(plugin);
410
+ registries.sharedState.register(plugin);
411
+ }
412
+
413
+ const availablePlugins: ReadonlySet<string> = loadedNames;
414
+ const buildCtx = (pluginName = '__runtime__'): PluginContext =>
415
+ buildPluginContext({
416
+ config: validated.config,
417
+ identity,
418
+ availablePlugins,
419
+ logger,
420
+ pluginName,
421
+ });
422
+
423
+ // 6. Routes + auth exclusions (sync — plugins close over config here).
424
+ const pluginRoutes: PluginRoute[] = resolved.loaded.flatMap(
425
+ (p) => p.getRoutes?.(buildCtx(p.name)) ?? [],
426
+ );
427
+ const authExcludedRoutes: AuthExcludedRoute[] = resolved.loaded.flatMap(
428
+ (p) => p.getAuthExcludedRoutes?.() ?? [],
429
+ );
430
+
431
+ // 7. LLM.
432
+ const llm = createLlmAdapter(
433
+ {
434
+ OPEN_ROUTER_API_KEY: String(validated.config.OPEN_ROUTER_API_KEY),
435
+ DEFAULT_MODEL:
436
+ typeof validated.config.DEFAULT_MODEL === 'string'
437
+ ? validated.config.DEFAULT_MODEL
438
+ : undefined,
439
+ MAIN_REASONING_EFFORT: validated.config.MAIN_REASONING_EFFORT as
440
+ | 'low'
441
+ | 'medium'
442
+ | 'high'
443
+ | undefined,
444
+ ORACLE_NAME: String(validated.config.ORACLE_NAME),
445
+ },
446
+ logger,
447
+ );
448
+
449
+ // 8. Warm-up (memoised). Collision + manifest cross-checks need the boot
450
+ // caches, which may involve async `getTools`, so they cannot run here.
451
+ let warmed: Promise<void> | null = null;
452
+ const warm = (): Promise<void> => {
453
+ warmed ??= (async () => {
454
+ const ctx = buildCtx();
455
+ await registries.tools.collectBoot(ctx);
456
+ registries.subAgents.collectBoot(ctx);
457
+ registries.middlewares.collect(ctx);
458
+ try {
459
+ registries.tools.assertNoCollisions();
460
+ registries.subAgents.assertNoCollisions();
461
+ registries.sharedState.assertNoCollisions();
462
+ // Advisory only: request-time tools (`getRequestTools`) are invisible
463
+ // at boot, so an example that names one reads as "unknown" here. The
464
+ // Node runtime does not run this check at boot at all; surfacing it
465
+ // as a warning keeps stale references visible without blocking.
466
+ const cross = registries.manifests.validateAgainstTools(
467
+ registries.tools,
468
+ registries.subAgents,
469
+ );
470
+ for (const issue of cross.errors) {
471
+ logger.warn(
472
+ `[boot] ${issue} (boot-time tools only — ignore if the tool comes from getRequestTools)`,
473
+ );
474
+ }
475
+ } catch (err) {
476
+ reportBootError(
477
+ logger,
478
+ err instanceof Error ? err.message : String(err),
479
+ );
480
+ throw err;
481
+ }
482
+ })().catch((err: unknown) => {
483
+ // Let the next caller retry rather than caching a rejection forever
484
+ // (a transient `getTools` failure should not brick the isolate).
485
+ warmed = null;
486
+ throw err;
487
+ });
488
+ return warmed;
489
+ };
490
+
491
+ logger.log(
492
+ `[boot] oracle '${identity.name}' loaded plugins: [${[...availablePlugins].join(', ')}]` +
493
+ (resolved.excluded.length > 0
494
+ ? ` excluded: [${resolved.excluded.map((e) => `${e.plugin} (${e.reason})`).join(', ')}]`
495
+ : ''),
496
+ );
497
+
498
+ return {
499
+ identity,
500
+ registries,
501
+ availablePlugins,
502
+ plugins: resolved.loaded,
503
+ excluded: resolved.excluded,
504
+ softDepGaps: resolved.softDepGaps,
505
+ validatedEnv: validated.config,
506
+ pluginRoutes,
507
+ authExcludedRoutes,
508
+ llm,
509
+ logger,
510
+ buildCtx,
511
+ warm,
512
+ };
513
+ }