@elizaos/ui 2.0.0-alpha.526 → 2.0.0-alpha.528
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/apps/app-elizamaker/src/index.d.ts +2 -0
- package/apps/app-elizamaker/src/index.d.ts.map +1 -1
- package/apps/app-elizamaker/src/index.js +2 -0
- package/apps/app-elizamaker/src/init-registry-services.d.ts +18 -0
- package/apps/app-elizamaker/src/init-registry-services.d.ts.map +1 -0
- package/apps/app-elizamaker/src/init-registry-services.js +63 -0
- package/apps/app-elizamaker/src/plugin.d.ts.map +1 -1
- package/apps/app-elizamaker/src/plugin.js +7 -0
- package/apps/app-elizamaker/src/registry-service-registry.d.ts +4 -0
- package/apps/app-elizamaker/src/registry-service-registry.d.ts.map +1 -0
- package/apps/app-elizamaker/src/registry-service-registry.js +7 -0
- package/apps/app-lifeops/src/automation-node-contributor.d.ts +2 -0
- package/apps/app-lifeops/src/automation-node-contributor.d.ts.map +1 -0
- package/apps/app-lifeops/src/automation-node-contributor.js +93 -0
- package/apps/app-lifeops/src/public.d.ts.map +1 -1
- package/apps/app-lifeops/src/public.js +2 -0
- package/apps/app-training/src/services/training-service-registry.d.ts +4 -0
- package/apps/app-training/src/services/training-service-registry.d.ts.map +1 -0
- package/apps/app-training/src/services/training-service-registry.js +7 -0
- package/package.json +1 -1
- package/packages/agent/src/api/agent-status-routes.d.ts +3 -23
- package/packages/agent/src/api/agent-status-routes.d.ts.map +1 -1
- package/packages/agent/src/api/agent-status-routes.js +7 -40
- package/packages/agent/src/api/coordinator-wiring.d.ts.map +1 -0
- package/packages/agent/src/api/misc-routes.d.ts.map +1 -1
- package/packages/agent/src/api/misc-routes.js +3 -37
- package/packages/agent/src/api/nfa-routes.d.ts.map +1 -1
- package/packages/agent/src/api/nfa-routes.js +1 -9
- package/packages/agent/src/api/provider-switch-routes.d.ts +8 -7
- package/packages/agent/src/api/provider-switch-routes.d.ts.map +1 -1
- package/packages/agent/src/api/provider-switch-routes.js +41 -26
- package/packages/agent/src/api/server-types.d.ts +0 -6
- package/packages/agent/src/api/server-types.d.ts.map +1 -1
- package/packages/agent/src/api/server.d.ts.map +1 -1
- package/packages/agent/src/api/server.js +31 -138
- package/packages/agent/src/api/stream-routes.d.ts.map +1 -1
- package/packages/agent/src/api/stream-routes.js +6 -8
- package/packages/agent/src/api/wallet-trading-profile.d.ts.map +1 -1
- package/packages/agent/src/api/wallet-trading-profile.js +2 -23
- package/packages/agent/src/auth/account-storage.d.ts.map +1 -1
- package/packages/agent/src/auth/account-storage.js +4 -15
- package/packages/agent/src/runtime/eliza.d.ts.map +1 -1
- package/packages/agent/src/runtime/eliza.js +2 -6
- package/packages/agent/src/runtime/first-time-setup.d.ts.map +1 -1
- package/packages/agent/src/runtime/first-time-setup.js +1 -7
- package/packages/agent/src/runtime/operations/cold-strategy.d.ts +4 -4
- package/packages/agent/src/runtime/operations/cold-strategy.d.ts.map +1 -1
- package/packages/agent/src/runtime/operations/cold-strategy.js +13 -46
- package/packages/agent/src/runtime/operations/health-checks.d.ts +1 -0
- package/packages/agent/src/runtime/operations/health-checks.d.ts.map +1 -1
- package/packages/agent/src/runtime/operations/health-checks.js +1 -1
- package/packages/agent/src/runtime/operations/health.d.ts.map +1 -1
- package/packages/agent/src/runtime/operations/health.js +1 -13
- package/packages/agent/src/runtime/operations/index.d.ts +1 -0
- package/packages/agent/src/runtime/operations/index.d.ts.map +1 -1
- package/packages/agent/src/runtime/operations/index.js +1 -0
- package/packages/agent/src/runtime/operations/manager.d.ts +2 -0
- package/packages/agent/src/runtime/operations/manager.d.ts.map +1 -1
- package/packages/agent/src/runtime/operations/manager.js +27 -7
- package/packages/agent/src/runtime/operations/reload-hot.d.ts +4 -1
- package/packages/agent/src/runtime/operations/reload-hot.d.ts.map +1 -1
- package/packages/agent/src/runtime/operations/reload-hot.js +46 -41
- package/packages/agent/src/runtime/operations/repository.d.ts +30 -8
- package/packages/agent/src/runtime/operations/repository.d.ts.map +1 -1
- package/packages/agent/src/runtime/operations/repository.js +140 -54
- package/packages/agent/src/runtime/operations/types.d.ts +26 -24
- package/packages/agent/src/runtime/operations/types.d.ts.map +1 -1
- package/packages/agent/src/runtime/operations/types.js +8 -20
- package/packages/agent/src/runtime/operations/vault-bridge.d.ts +60 -0
- package/packages/agent/src/runtime/operations/vault-bridge.d.ts.map +1 -0
- package/packages/agent/src/runtime/operations/vault-bridge.js +80 -0
- package/packages/agent/src/runtime/plugin-resolver.d.ts.map +1 -1
- package/packages/agent/src/runtime/plugin-resolver.js +1 -3
- package/packages/agent/src/runtime/plugin-types.d.ts.map +1 -1
- package/packages/agent/src/runtime/plugin-types.js +1 -3
- package/packages/agent/src/services/app-package-modules.d.ts.map +1 -1
- package/packages/agent/src/services/app-package-modules.js +1 -8
- package/packages/agent/src/services/app-run-store.d.ts.map +1 -1
- package/packages/agent/src/services/app-run-store.js +2 -23
- package/packages/agent/src/services/registry-client-local.d.ts.map +1 -1
- package/packages/agent/src/services/registry-client-local.js +1 -9
- package/packages/agent/src/utils/atomic-json.d.ts +37 -0
- package/packages/agent/src/utils/atomic-json.d.ts.map +1 -0
- package/packages/agent/src/utils/atomic-json.js +98 -0
- package/packages/app-core/src/api/automation-node-contributors.d.ts +14 -0
- package/packages/app-core/src/api/automation-node-contributors.d.ts.map +1 -0
- package/packages/app-core/src/api/automation-node-contributors.js +14 -0
- package/packages/app-core/src/api/client-agent.d.ts +627 -0
- package/packages/app-core/src/api/client-agent.d.ts.map +1 -0
- package/packages/app-core/src/api/client-agent.js +1442 -0
- package/packages/app-core/src/api/client-automations.d.ts +8 -0
- package/packages/app-core/src/api/client-automations.d.ts.map +1 -0
- package/packages/app-core/src/api/client-automations.js +7 -0
- package/packages/app-core/src/api/client-base.d.ts +82 -0
- package/packages/app-core/src/api/client-base.d.ts.map +1 -0
- package/packages/app-core/src/api/client-base.js +729 -0
- package/packages/app-core/src/api/client-browser-workspace.d.ts +25 -0
- package/packages/app-core/src/api/client-browser-workspace.d.ts.map +1 -0
- package/packages/app-core/src/api/client-browser-workspace.js +98 -0
- package/packages/app-core/src/api/client-chat.d.ts +355 -0
- package/packages/app-core/src/api/client-chat.d.ts.map +1 -0
- package/packages/app-core/src/api/client-chat.js +582 -0
- package/packages/app-core/src/api/client-cloud.d.ts +286 -0
- package/packages/app-core/src/api/client-cloud.d.ts.map +1 -0
- package/packages/app-core/src/api/client-cloud.js +410 -0
- package/packages/app-core/src/api/client-computeruse.d.ts +32 -0
- package/packages/app-core/src/api/client-computeruse.d.ts.map +1 -0
- package/packages/app-core/src/api/client-computeruse.js +16 -0
- package/packages/app-core/src/api/client-imessage.d.ts +68 -0
- package/packages/app-core/src/api/client-imessage.d.ts.map +1 -0
- package/packages/app-core/src/api/client-imessage.js +74 -0
- package/packages/app-core/src/api/client-local-inference.d.ts +62 -0
- package/packages/app-core/src/api/client-local-inference.d.ts.map +1 -0
- package/packages/app-core/src/api/client-local-inference.js +87 -0
- package/packages/app-core/src/api/client-n8n.d.ts +27 -0
- package/packages/app-core/src/api/client-n8n.d.ts.map +1 -0
- package/packages/app-core/src/api/client-n8n.js +61 -0
- package/packages/app-core/src/api/client-skills.d.ts +475 -0
- package/packages/app-core/src/api/client-skills.d.ts.map +1 -0
- package/packages/app-core/src/api/client-skills.js +608 -0
- package/packages/app-core/src/api/client-types-babylon.d.ts +254 -0
- package/packages/app-core/src/api/client-types-babylon.d.ts.map +1 -0
- package/packages/app-core/src/api/client-types-babylon.js +2 -0
- package/packages/app-core/src/api/client-types-character.d.ts +39 -0
- package/packages/app-core/src/api/client-types-character.d.ts.map +1 -0
- package/packages/app-core/src/api/client-types-character.js +1 -0
- package/packages/app-core/src/api/client-types-chat.d.ts +428 -0
- package/packages/app-core/src/api/client-types-chat.d.ts.map +1 -0
- package/packages/app-core/src/api/client-types-chat.js +9 -0
- package/packages/app-core/src/api/client-types-config.d.ts +587 -0
- package/packages/app-core/src/api/client-types-config.d.ts.map +1 -0
- package/packages/app-core/src/api/client-types-config.js +5 -0
- package/packages/app-core/src/api/client-types-experience.d.ts +97 -0
- package/packages/app-core/src/api/client-types-experience.d.ts.map +1 -0
- package/packages/app-core/src/api/client-types-experience.js +1 -0
- package/packages/app-core/src/api/client-types-relationships.d.ts +181 -0
- package/packages/app-core/src/api/client-types-relationships.d.ts.map +1 -0
- package/packages/app-core/src/api/client-types-relationships.js +1 -0
- package/packages/app-core/src/api/client-types-steward.d.ts +85 -0
- package/packages/app-core/src/api/client-types-steward.d.ts.map +1 -0
- package/packages/app-core/src/api/client-types-steward.js +9 -0
- package/packages/app-core/src/api/client-types.d.ts +9 -0
- package/packages/app-core/src/api/client-types.d.ts.map +1 -0
- package/packages/app-core/src/api/client-types.js +12 -0
- package/packages/app-core/src/api/client-wallet.d.ts +130 -0
- package/packages/app-core/src/api/client-wallet.d.ts.map +1 -0
- package/packages/app-core/src/api/client-wallet.js +228 -0
- package/packages/app-core/src/api/client.d.ts +36 -0
- package/packages/app-core/src/api/client.d.ts.map +1 -0
- package/packages/app-core/src/api/client.js +36 -0
- package/packages/app-core/src/api/index.d.ts +2 -0
- package/packages/app-core/src/api/index.d.ts.map +1 -0
- package/packages/app-core/src/api/index.js +1 -0
- package/packages/app-core/src/bridge/electrobun-rpc.d.ts +57 -0
- package/packages/app-core/src/bridge/electrobun-rpc.d.ts.map +1 -0
- package/packages/app-core/src/bridge/electrobun-rpc.js +87 -0
- package/packages/app-core/src/bridge/electrobun-runtime.d.ts +3 -0
- package/packages/app-core/src/bridge/electrobun-runtime.d.ts.map +1 -0
- package/packages/app-core/src/bridge/electrobun-runtime.js +34 -0
- package/packages/app-core/src/bridge/native-plugins.d.ts +504 -0
- package/packages/app-core/src/bridge/native-plugins.d.ts.map +1 -0
- package/packages/app-core/src/bridge/native-plugins.js +67 -0
- package/packages/app-core/src/chat/coding-agent-session-state.d.ts +16 -0
- package/packages/app-core/src/chat/coding-agent-session-state.d.ts.map +1 -0
- package/packages/app-core/src/chat/coding-agent-session-state.js +27 -0
- package/packages/app-core/src/components/pages/browser-workspace-wallet.d.ts +80 -0
- package/packages/app-core/src/components/pages/browser-workspace-wallet.d.ts.map +1 -0
- package/packages/app-core/src/components/pages/browser-workspace-wallet.js +135 -0
- package/packages/app-core/src/services/account-pool.d.ts +98 -0
- package/packages/app-core/src/services/account-pool.d.ts.map +1 -0
- package/packages/app-core/src/services/account-pool.js +506 -0
- package/packages/app-core/src/services/account-usage.d.ts +75 -0
- package/packages/app-core/src/services/account-usage.d.ts.map +1 -0
- package/packages/app-core/src/services/account-usage.js +179 -0
- package/packages/app-core/src/services/local-inference/active-model.d.ts +59 -0
- package/packages/app-core/src/services/local-inference/active-model.d.ts.map +1 -0
- package/packages/app-core/src/services/local-inference/active-model.js +120 -0
- package/packages/app-core/src/services/local-inference/device-bridge.d.ts +131 -0
- package/packages/app-core/src/services/local-inference/device-bridge.d.ts.map +1 -0
- package/packages/app-core/src/services/local-inference/device-bridge.js +748 -0
- package/packages/app-core/src/services/local-inference/engine.d.ts +52 -0
- package/packages/app-core/src/services/local-inference/engine.d.ts.map +1 -0
- package/packages/app-core/src/services/local-inference/engine.js +138 -0
- package/packages/app-core/src/services/local-inference/external-scanner.d.ts +17 -0
- package/packages/app-core/src/services/local-inference/external-scanner.d.ts.map +1 -0
- package/packages/app-core/src/services/local-inference/external-scanner.js +261 -0
- package/packages/app-core/src/services/local-inference/handler-registry.d.ts +72 -0
- package/packages/app-core/src/services/local-inference/handler-registry.d.ts.map +1 -0
- package/packages/app-core/src/services/local-inference/handler-registry.js +160 -0
- package/packages/app-core/src/services/local-inference/paths.d.ts +24 -0
- package/packages/app-core/src/services/local-inference/paths.d.ts.map +1 -0
- package/packages/app-core/src/services/local-inference/paths.js +41 -0
- package/packages/app-core/src/services/local-inference/providers.d.ts +61 -0
- package/packages/app-core/src/services/local-inference/providers.d.ts.map +1 -0
- package/packages/app-core/src/services/local-inference/providers.js +277 -0
- package/packages/app-core/src/services/local-inference/registry.d.ts +35 -0
- package/packages/app-core/src/services/local-inference/registry.d.ts.map +1 -0
- package/packages/app-core/src/services/local-inference/registry.js +108 -0
- package/packages/app-core/src/services/local-inference/routing-preferences.d.ts +31 -0
- package/packages/app-core/src/services/local-inference/routing-preferences.d.ts.map +1 -0
- package/packages/app-core/src/services/local-inference/routing-preferences.js +72 -0
- package/packages/app-core/src/services/local-inference/types.d.ts +121 -0
- package/packages/app-core/src/services/local-inference/types.d.ts.map +1 -0
- package/packages/app-core/src/services/local-inference/types.js +14 -0
- package/packages/app-core/src/services/local-inference/verify.d.ts +39 -0
- package/packages/app-core/src/services/local-inference/verify.d.ts.map +1 -0
- package/packages/app-core/src/services/local-inference/verify.js +104 -0
- package/packages/app-core/src/types/index.d.ts +658 -0
- package/packages/app-core/src/types/index.d.ts.map +1 -0
- package/packages/app-core/src/types/index.js +4 -0
- package/packages/app-core/src/utils/assistant-text.d.ts +2 -0
- package/packages/app-core/src/utils/assistant-text.d.ts.map +1 -0
- package/packages/app-core/src/utils/assistant-text.js +167 -0
- package/packages/app-core/src/utils/eliza-globals.d.ts +15 -0
- package/packages/app-core/src/utils/eliza-globals.d.ts.map +1 -0
- package/packages/app-core/src/utils/eliza-globals.js +50 -0
- package/packages/app-core/src/utils/streaming-text.d.ts +9 -0
- package/packages/app-core/src/utils/streaming-text.d.ts.map +1 -0
- package/packages/app-core/src/utils/streaming-text.js +112 -0
- package/packages/shared/src/format-error.d.ts +14 -0
- package/packages/shared/src/format-error.d.ts.map +1 -0
- package/packages/shared/src/format-error.js +17 -0
- package/packages/shared/src/index.d.ts +1 -0
- package/packages/shared/src/index.d.ts.map +1 -1
- package/packages/shared/src/index.js +1 -0
- package/packages/typescript/src/runtime.d.ts +14 -0
- package/packages/typescript/src/runtime.d.ts.map +1 -1
- package/packages/typescript/src/runtime.js +42 -0
- package/packages/typescript/src/services/message.d.ts +8 -0
- package/packages/typescript/src/services/message.d.ts.map +1 -1
- package/packages/typescript/src/services/message.js +51 -0
- package/packages/typescript/src/services/task.d.ts +1 -0
- package/packages/typescript/src/services/task.d.ts.map +1 -1
- package/packages/typescript/src/services/task.js +26 -3
- package/apps/app-task-coordinator/src/api/coordinator-wiring.d.ts.map +0 -1
- /package/{apps/app-task-coordinator → packages/agent}/src/api/coordinator-wiring.d.ts +0 -0
- /package/{apps/app-task-coordinator → packages/agent}/src/api/coordinator-wiring.js +0 -0
|
@@ -4,26 +4,48 @@
|
|
|
4
4
|
* Storage layout:
|
|
5
5
|
* <stateDir>/runtime-operations/<id>.json one JSON file per operation
|
|
6
6
|
*
|
|
7
|
-
* Atomic writes: write to <id>.json.tmp.<pid> then rename — same pattern
|
|
8
|
-
* the Eliza config uses (config.ts:saveElizaConfig).
|
|
9
|
-
*
|
|
10
7
|
* In-memory caches are populated lazily at first access from disk and kept
|
|
11
8
|
* in sync on every mutation. They make `findActive` and
|
|
12
9
|
* `findByIdempotencyKey` O(1) on the hot path.
|
|
13
10
|
*
|
|
14
|
-
* Hydration
|
|
15
|
-
* `running` whose `startedAt` is older
|
|
16
|
-
*
|
|
11
|
+
* Hydration:
|
|
12
|
+
* 1. Reap abandoned ops — `pending`/`running` whose `startedAt` is older
|
|
13
|
+
* than `ABANDONED_AFTER_MS` are force-marked `failed` with code
|
|
14
|
+
* `"abandoned"` (the process died mid-flight).
|
|
15
|
+
* 2. Prune terminal ops — `succeeded`/`failed`/`rolled-back` records older
|
|
16
|
+
* than `RETENTION_MS` or beyond the `MAX_RECORDS` cap are deleted from
|
|
17
|
+
* disk and dropped from memory. Active ops are never pruned.
|
|
18
|
+
*
|
|
19
|
+
* Pruning also runs opportunistically after each `create` so a long-running
|
|
20
|
+
* process doesn't accumulate state between hydrations.
|
|
17
21
|
*/
|
|
18
22
|
import type { OperationPhase, RuntimeOperation, RuntimeOperationListOptions, RuntimeOperationRepository } from "./types.js";
|
|
23
|
+
export interface FilesystemRuntimeOperationRepositoryOptions {
|
|
24
|
+
/** Override the retention window for terminal ops. */
|
|
25
|
+
retentionMs?: number;
|
|
26
|
+
/** Override the cap on the number of terminal ops kept. */
|
|
27
|
+
maxRecords?: number;
|
|
28
|
+
}
|
|
19
29
|
export declare class FilesystemRuntimeOperationRepository implements RuntimeOperationRepository {
|
|
20
30
|
private readonly dir;
|
|
21
31
|
private readonly byId;
|
|
22
32
|
private readonly byIdempotencyKey;
|
|
23
33
|
private activeId;
|
|
24
|
-
private
|
|
25
|
-
|
|
34
|
+
private hydration;
|
|
35
|
+
private readonly retentionMs;
|
|
36
|
+
private readonly maxRecords;
|
|
37
|
+
constructor(stateDir?: string, opts?: FilesystemRuntimeOperationRepositoryOptions);
|
|
26
38
|
private hydrate;
|
|
39
|
+
private runHydrate;
|
|
40
|
+
/**
|
|
41
|
+
* Drop terminal ops that exceed the retention window or fall outside the
|
|
42
|
+
* most-recent-N cap. Active (`pending`/`running`) ops are never touched —
|
|
43
|
+
* the abandoned-reaper in {@link runHydrate} is the only path that can
|
|
44
|
+
* transition them to terminal.
|
|
45
|
+
*
|
|
46
|
+
* Returns the number of ops removed.
|
|
47
|
+
*/
|
|
48
|
+
pruneTerminal(now?: number): Promise<number>;
|
|
27
49
|
private pathFor;
|
|
28
50
|
private persist;
|
|
29
51
|
private syncActiveSlot;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repository.d.ts","sourceRoot":"","sources":["../../../../../../../agent/src/runtime/operations/repository.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"repository.d.ts","sourceRoot":"","sources":["../../../../../../../agent/src/runtime/operations/repository.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAQH,OAAO,KAAK,EACV,cAAc,EACd,gBAAgB,EAChB,2BAA2B,EAC3B,0BAA0B,EAC3B,MAAM,YAAY,CAAC;AAepB,MAAM,WAAW,2CAA2C;IAC1D,sDAAsD;IACtD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,2DAA2D;IAC3D,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AA4CD,qBAAa,oCACX,YAAW,0BAA0B;IAErC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA4C;IACjE,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAkC;IACnE,OAAO,CAAC,QAAQ,CAAuB;IACvC,OAAO,CAAC,SAAS,CAA8B;IAC/C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;gBAGlC,QAAQ,GAAE,MAA0B,EACpC,IAAI,GAAE,2CAAgD;IAWxD,OAAO,CAAC,OAAO;YAMD,UAAU;IAiExB;;;;;;;OAOG;IACG,aAAa,CAAC,GAAG,GAAE,MAAmB,GAAG,OAAO,CAAC,MAAM,CAAC;IAkC9D,OAAO,CAAC,OAAO;IAIf,OAAO,CAAC,OAAO;IAOf,OAAO,CAAC,cAAc;IAWhB,MAAM,CAAC,EAAE,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAkB3C,MAAM,CACV,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,gBAAgB,EAAE,IAAI,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC,CAAC,GAC1E,OAAO,CAAC,IAAI,CAAC;IAYV,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAc7D,eAAe,CACnB,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,OAAO,CAAC,cAAc,CAAC,GAC7B,OAAO,CAAC,IAAI,CAAC;IAmBV,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAKjD,IAAI,CAAC,IAAI,CAAC,EAAE,2BAA2B,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAerE,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAYnE,UAAU,IAAI,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;CAcrD;AAID;;;GAGG;AACH,wBAAgB,oBAAoB,IAAI,oCAAoC,CAK3E"}
|
|
@@ -4,73 +4,119 @@
|
|
|
4
4
|
* Storage layout:
|
|
5
5
|
* <stateDir>/runtime-operations/<id>.json one JSON file per operation
|
|
6
6
|
*
|
|
7
|
-
* Atomic writes: write to <id>.json.tmp.<pid> then rename — same pattern
|
|
8
|
-
* the Eliza config uses (config.ts:saveElizaConfig).
|
|
9
|
-
*
|
|
10
7
|
* In-memory caches are populated lazily at first access from disk and kept
|
|
11
8
|
* in sync on every mutation. They make `findActive` and
|
|
12
9
|
* `findByIdempotencyKey` O(1) on the hot path.
|
|
13
10
|
*
|
|
14
|
-
* Hydration
|
|
15
|
-
* `running` whose `startedAt` is older
|
|
16
|
-
*
|
|
11
|
+
* Hydration:
|
|
12
|
+
* 1. Reap abandoned ops — `pending`/`running` whose `startedAt` is older
|
|
13
|
+
* than `ABANDONED_AFTER_MS` are force-marked `failed` with code
|
|
14
|
+
* `"abandoned"` (the process died mid-flight).
|
|
15
|
+
* 2. Prune terminal ops — `succeeded`/`failed`/`rolled-back` records older
|
|
16
|
+
* than `RETENTION_MS` or beyond the `MAX_RECORDS` cap are deleted from
|
|
17
|
+
* disk and dropped from memory. Active ops are never pruned.
|
|
18
|
+
*
|
|
19
|
+
* Pruning also runs opportunistically after each `create` so a long-running
|
|
20
|
+
* process doesn't accumulate state between hydrations.
|
|
17
21
|
*/
|
|
18
|
-
import fs from "node:fs";
|
|
22
|
+
import fs from "node:fs/promises";
|
|
19
23
|
import path from "node:path";
|
|
20
24
|
import { logger } from "@elizaos/core";
|
|
25
|
+
import { formatError } from "@elizaos/shared";
|
|
21
26
|
import { resolveStateDir } from "../../config/paths.js";
|
|
27
|
+
import { readJsonFile, writeJsonAtomic } from "../../utils/atomic-json.js";
|
|
22
28
|
const ABANDONED_AFTER_MS = 24 * 60 * 60 * 1000;
|
|
23
29
|
const IDEMPOTENCY_RETENTION_MS = 24 * 60 * 60 * 1000;
|
|
30
|
+
const DEFAULT_RETENTION_MS = 7 * 24 * 60 * 60 * 1000; // 7 days
|
|
31
|
+
const DEFAULT_MAX_RECORDS = 200;
|
|
32
|
+
function readEnvNumber(name, fallback) {
|
|
33
|
+
const raw = process.env[name];
|
|
34
|
+
if (!raw)
|
|
35
|
+
return fallback;
|
|
36
|
+
const n = Number(raw);
|
|
37
|
+
return Number.isFinite(n) && n >= 0 ? n : fallback;
|
|
38
|
+
}
|
|
39
|
+
function isTerminal(op) {
|
|
40
|
+
return op.status !== "pending" && op.status !== "running";
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Strip the legacy plaintext `apiKey` field that older runtime-ops records
|
|
44
|
+
* carried on `ProviderSwitchIntent` before the vault migration. Returns the
|
|
45
|
+
* sanitized op plus a boolean signalling that the on-disk file needs
|
|
46
|
+
* rewriting. The vault key is preserved (or re-derivable) by the route at
|
|
47
|
+
* the next switch — we never re-emit the plaintext.
|
|
48
|
+
*/
|
|
49
|
+
function stripLegacyApiKey(op) {
|
|
50
|
+
if (op.intent.kind !== "provider-switch")
|
|
51
|
+
return { op, changed: false };
|
|
52
|
+
const intent = op.intent;
|
|
53
|
+
if (!("apiKey" in intent))
|
|
54
|
+
return { op, changed: false };
|
|
55
|
+
const { apiKey: _legacy, ...sanitizedIntent } = intent;
|
|
56
|
+
void _legacy;
|
|
57
|
+
return {
|
|
58
|
+
op: { ...op, intent: sanitizedIntent },
|
|
59
|
+
changed: true,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
24
62
|
function operationsDirFor(stateDir) {
|
|
25
63
|
return path.join(stateDir, "runtime-operations");
|
|
26
64
|
}
|
|
27
|
-
function
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
function readJsonFile(filePath) {
|
|
33
|
-
const raw = fs.readFileSync(filePath, "utf-8");
|
|
34
|
-
if (!raw.trim()) {
|
|
35
|
-
return null;
|
|
36
|
-
}
|
|
37
|
-
const parsed = JSON.parse(raw);
|
|
38
|
-
if (!parsed.id || !parsed.kind || !Array.isArray(parsed.phases)) {
|
|
65
|
+
async function readOperationFile(filePath) {
|
|
66
|
+
const parsed = await readJsonFile(filePath);
|
|
67
|
+
if (!parsed?.id || !parsed.kind || !Array.isArray(parsed.phases)) {
|
|
39
68
|
return null;
|
|
40
69
|
}
|
|
41
70
|
return parsed;
|
|
42
71
|
}
|
|
43
|
-
function writeJsonAtomic(filePath, op) {
|
|
44
|
-
const dir = path.dirname(filePath);
|
|
45
|
-
ensureDir(dir);
|
|
46
|
-
const tmpPath = `${filePath}.tmp.${process.pid}`;
|
|
47
|
-
const content = `${JSON.stringify(op, null, 2)}\n`;
|
|
48
|
-
fs.writeFileSync(tmpPath, content, { encoding: "utf-8", mode: 0o600 });
|
|
49
|
-
fs.renameSync(tmpPath, filePath);
|
|
50
|
-
}
|
|
51
72
|
export class FilesystemRuntimeOperationRepository {
|
|
52
73
|
dir;
|
|
53
74
|
byId = new Map();
|
|
54
75
|
byIdempotencyKey = new Map();
|
|
55
76
|
activeId = null;
|
|
56
|
-
|
|
57
|
-
|
|
77
|
+
hydration = null;
|
|
78
|
+
retentionMs;
|
|
79
|
+
maxRecords;
|
|
80
|
+
constructor(stateDir = resolveStateDir(), opts = {}) {
|
|
58
81
|
this.dir = operationsDirFor(stateDir);
|
|
82
|
+
this.retentionMs =
|
|
83
|
+
opts.retentionMs ??
|
|
84
|
+
readEnvNumber("MILADY_RUNTIME_OPS_RETENTION_MS", DEFAULT_RETENTION_MS);
|
|
85
|
+
this.maxRecords =
|
|
86
|
+
opts.maxRecords ??
|
|
87
|
+
readEnvNumber("MILADY_RUNTIME_OPS_MAX_RECORDS", DEFAULT_MAX_RECORDS);
|
|
59
88
|
}
|
|
60
89
|
hydrate() {
|
|
61
|
-
if (this.
|
|
62
|
-
return;
|
|
63
|
-
this.
|
|
64
|
-
|
|
65
|
-
|
|
90
|
+
if (this.hydration)
|
|
91
|
+
return this.hydration;
|
|
92
|
+
this.hydration = this.runHydrate();
|
|
93
|
+
return this.hydration;
|
|
94
|
+
}
|
|
95
|
+
async runHydrate() {
|
|
96
|
+
// mkdir is idempotent with recursive: true — no existence check needed.
|
|
97
|
+
await fs.mkdir(this.dir, { recursive: true, mode: 0o700 });
|
|
98
|
+
const entries = await fs.readdir(this.dir);
|
|
66
99
|
const now = Date.now();
|
|
67
100
|
for (const entry of entries) {
|
|
68
101
|
if (!entry.endsWith(".json"))
|
|
69
102
|
continue;
|
|
70
103
|
const fullPath = path.join(this.dir, entry);
|
|
71
|
-
const
|
|
72
|
-
if (!
|
|
104
|
+
const raw = await readOperationFile(fullPath);
|
|
105
|
+
if (!raw)
|
|
73
106
|
continue;
|
|
107
|
+
// Migration: strip legacy plaintext `apiKey` from
|
|
108
|
+
// ProviderSwitchIntent records written before the vault integration.
|
|
109
|
+
// Re-persist the sanitized record so the file on disk loses the
|
|
110
|
+
// secret too — pruning + idempotency keep working untouched.
|
|
111
|
+
const stripped = stripLegacyApiKey(raw);
|
|
112
|
+
const op = stripped.op;
|
|
113
|
+
if (stripped.changed) {
|
|
114
|
+
await writeJsonAtomic(fullPath, op, {
|
|
115
|
+
trailingNewline: true,
|
|
116
|
+
skipMkdir: true,
|
|
117
|
+
});
|
|
118
|
+
logger.info(`[runtime-ops] Migrated legacy plaintext apiKey out of ${op.id}`);
|
|
119
|
+
}
|
|
74
120
|
// Reap abandoned operations: a process died with this op still "live".
|
|
75
121
|
const isLive = op.status === "pending" || op.status === "running";
|
|
76
122
|
const isStale = now - op.startedAt > ABANDONED_AFTER_MS;
|
|
@@ -84,7 +130,10 @@ export class FilesystemRuntimeOperationRepository {
|
|
|
84
130
|
code: "abandoned",
|
|
85
131
|
},
|
|
86
132
|
};
|
|
87
|
-
writeJsonAtomic(fullPath, reaped
|
|
133
|
+
await writeJsonAtomic(fullPath, reaped, {
|
|
134
|
+
trailingNewline: true,
|
|
135
|
+
skipMkdir: true,
|
|
136
|
+
});
|
|
88
137
|
this.byId.set(reaped.id, reaped);
|
|
89
138
|
if (reaped.idempotencyKey) {
|
|
90
139
|
this.byIdempotencyKey.set(reaped.idempotencyKey, reaped.id);
|
|
@@ -100,12 +149,49 @@ export class FilesystemRuntimeOperationRepository {
|
|
|
100
149
|
this.activeId = op.id;
|
|
101
150
|
}
|
|
102
151
|
}
|
|
152
|
+
await this.pruneTerminal(now);
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Drop terminal ops that exceed the retention window or fall outside the
|
|
156
|
+
* most-recent-N cap. Active (`pending`/`running`) ops are never touched —
|
|
157
|
+
* the abandoned-reaper in {@link runHydrate} is the only path that can
|
|
158
|
+
* transition them to terminal.
|
|
159
|
+
*
|
|
160
|
+
* Returns the number of ops removed.
|
|
161
|
+
*/
|
|
162
|
+
async pruneTerminal(now = Date.now()) {
|
|
163
|
+
const terminal = Array.from(this.byId.values())
|
|
164
|
+
.filter(isTerminal)
|
|
165
|
+
.sort((a, b) => (b.finishedAt ?? b.startedAt) - (a.finishedAt ?? a.startedAt));
|
|
166
|
+
const toDrop = [];
|
|
167
|
+
for (let i = 0; i < terminal.length; i++) {
|
|
168
|
+
const op = terminal[i];
|
|
169
|
+
const tooOld = now - (op.finishedAt ?? op.startedAt) > this.retentionMs;
|
|
170
|
+
const beyondCap = i >= this.maxRecords;
|
|
171
|
+
if (tooOld || beyondCap)
|
|
172
|
+
toDrop.push(op);
|
|
173
|
+
}
|
|
174
|
+
if (toDrop.length === 0)
|
|
175
|
+
return 0;
|
|
176
|
+
await Promise.all(toDrop.map((op) => fs.rm(this.pathFor(op.id), { force: true }).catch((err) => {
|
|
177
|
+
logger.warn(`[runtime-ops] Failed to unlink ${op.id}: ${formatError(err)}`);
|
|
178
|
+
})));
|
|
179
|
+
for (const op of toDrop) {
|
|
180
|
+
this.byId.delete(op.id);
|
|
181
|
+
if (op.idempotencyKey)
|
|
182
|
+
this.byIdempotencyKey.delete(op.idempotencyKey);
|
|
183
|
+
}
|
|
184
|
+
logger.debug(`[runtime-ops] Pruned ${toDrop.length} terminal op(s)`);
|
|
185
|
+
return toDrop.length;
|
|
103
186
|
}
|
|
104
187
|
pathFor(id) {
|
|
105
188
|
return path.join(this.dir, `${id}.json`);
|
|
106
189
|
}
|
|
107
190
|
persist(op) {
|
|
108
|
-
writeJsonAtomic(this.pathFor(op.id), op
|
|
191
|
+
return writeJsonAtomic(this.pathFor(op.id), op, {
|
|
192
|
+
trailingNewline: true,
|
|
193
|
+
skipMkdir: true,
|
|
194
|
+
});
|
|
109
195
|
}
|
|
110
196
|
syncActiveSlot(op) {
|
|
111
197
|
const isLive = op.status === "pending" || op.status === "running";
|
|
@@ -118,30 +204,33 @@ export class FilesystemRuntimeOperationRepository {
|
|
|
118
204
|
}
|
|
119
205
|
}
|
|
120
206
|
async create(op) {
|
|
121
|
-
this.hydrate();
|
|
207
|
+
await this.hydrate();
|
|
122
208
|
if (this.byId.has(op.id)) {
|
|
123
209
|
throw new Error(`[runtime-ops] Operation already exists: ${op.id}`);
|
|
124
210
|
}
|
|
125
|
-
this.persist(op);
|
|
211
|
+
await this.persist(op);
|
|
126
212
|
this.byId.set(op.id, op);
|
|
127
213
|
if (op.idempotencyKey) {
|
|
128
214
|
this.byIdempotencyKey.set(op.idempotencyKey, op.id);
|
|
129
215
|
}
|
|
130
216
|
this.syncActiveSlot(op);
|
|
217
|
+
void this.pruneTerminal().catch((err) => {
|
|
218
|
+
logger.warn(`[runtime-ops] post-create prune failed: ${formatError(err)}`);
|
|
219
|
+
});
|
|
131
220
|
}
|
|
132
221
|
async update(id, patch) {
|
|
133
|
-
this.hydrate();
|
|
222
|
+
await this.hydrate();
|
|
134
223
|
const current = this.byId.get(id);
|
|
135
224
|
if (!current) {
|
|
136
225
|
throw new Error(`[runtime-ops] Operation not found: ${id}`);
|
|
137
226
|
}
|
|
138
227
|
const next = { ...current, ...patch };
|
|
139
|
-
this.persist(next);
|
|
228
|
+
await this.persist(next);
|
|
140
229
|
this.byId.set(id, next);
|
|
141
230
|
this.syncActiveSlot(next);
|
|
142
231
|
}
|
|
143
232
|
async appendPhase(id, phase) {
|
|
144
|
-
this.hydrate();
|
|
233
|
+
await this.hydrate();
|
|
145
234
|
const current = this.byId.get(id);
|
|
146
235
|
if (!current) {
|
|
147
236
|
throw new Error(`[runtime-ops] Operation not found: ${id}`);
|
|
@@ -150,34 +239,31 @@ export class FilesystemRuntimeOperationRepository {
|
|
|
150
239
|
...current,
|
|
151
240
|
phases: [...current.phases, phase],
|
|
152
241
|
};
|
|
153
|
-
this.persist(next);
|
|
242
|
+
await this.persist(next);
|
|
154
243
|
this.byId.set(id, next);
|
|
155
244
|
}
|
|
156
245
|
async updateLastPhase(id, patch) {
|
|
157
|
-
this.hydrate();
|
|
246
|
+
await this.hydrate();
|
|
158
247
|
const current = this.byId.get(id);
|
|
159
248
|
if (!current) {
|
|
160
249
|
throw new Error(`[runtime-ops] Operation not found: ${id}`);
|
|
161
250
|
}
|
|
162
|
-
if (current.phases.length === 0) {
|
|
163
|
-
throw new Error(`[runtime-ops] Cannot update last phase — no phases on op ${id}`);
|
|
164
|
-
}
|
|
165
251
|
const last = current.phases[current.phases.length - 1];
|
|
166
252
|
if (!last) {
|
|
167
|
-
throw new Error(`[runtime-ops] Cannot update last phase —
|
|
253
|
+
throw new Error(`[runtime-ops] Cannot update last phase — no phases on op ${id}`);
|
|
168
254
|
}
|
|
169
255
|
const merged = { ...last, ...patch };
|
|
170
256
|
const phases = [...current.phases.slice(0, -1), merged];
|
|
171
257
|
const next = { ...current, phases };
|
|
172
|
-
this.persist(next);
|
|
258
|
+
await this.persist(next);
|
|
173
259
|
this.byId.set(id, next);
|
|
174
260
|
}
|
|
175
261
|
async get(id) {
|
|
176
|
-
this.hydrate();
|
|
262
|
+
await this.hydrate();
|
|
177
263
|
return this.byId.get(id) ?? null;
|
|
178
264
|
}
|
|
179
265
|
async list(opts) {
|
|
180
|
-
this.hydrate();
|
|
266
|
+
await this.hydrate();
|
|
181
267
|
let ops = Array.from(this.byId.values());
|
|
182
268
|
if (opts?.status) {
|
|
183
269
|
ops = ops.filter((o) => o.status === opts.status);
|
|
@@ -192,7 +278,7 @@ export class FilesystemRuntimeOperationRepository {
|
|
|
192
278
|
return ops;
|
|
193
279
|
}
|
|
194
280
|
async findByIdempotencyKey(key) {
|
|
195
|
-
this.hydrate();
|
|
281
|
+
await this.hydrate();
|
|
196
282
|
const id = this.byIdempotencyKey.get(key);
|
|
197
283
|
if (!id)
|
|
198
284
|
return null;
|
|
@@ -205,7 +291,7 @@ export class FilesystemRuntimeOperationRepository {
|
|
|
205
291
|
return op;
|
|
206
292
|
}
|
|
207
293
|
async findActive() {
|
|
208
|
-
this.hydrate();
|
|
294
|
+
await this.hydrate();
|
|
209
295
|
if (!this.activeId)
|
|
210
296
|
return null;
|
|
211
297
|
const op = this.byId.get(this.activeId);
|
|
@@ -3,35 +3,30 @@
|
|
|
3
3
|
* lifecycle action against the live runtime (provider switch, plugin
|
|
4
4
|
* enable/disable, config reload, full restart).
|
|
5
5
|
*
|
|
6
|
-
* Design invariants
|
|
6
|
+
* Design invariants:
|
|
7
7
|
*
|
|
8
|
-
* 1. Single queue. One operation runs at a time
|
|
9
|
-
*
|
|
8
|
+
* 1. Single queue. One operation runs at a time. New requests while an op
|
|
9
|
+
* is running return 409 with the active op's id.
|
|
10
10
|
* 2. Tiered execution. The use case classifies an intent into a reload
|
|
11
|
-
* tier (hot / warm / cold).
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* plugin (warm) only "wins" after health checks pass; failure rolls
|
|
15
|
-
* back to the previous configuration.
|
|
11
|
+
* tier (hot / warm / cold).
|
|
12
|
+
* 3. Health-gated promotion. A new/re-initialised runtime only "wins"
|
|
13
|
+
* after health checks pass.
|
|
16
14
|
* 4. Append-only phase log. Each phase mutation is a new entry — never
|
|
17
|
-
* patched in place
|
|
18
|
-
* 5. Idempotency keys de-dupe retries
|
|
19
|
-
* window returns the existing operation record.
|
|
20
|
-
*
|
|
21
|
-
* This module exports types only. Implementations live in sibling files:
|
|
22
|
-
* - manager.ts — RuntimeOperationManager (the use case)
|
|
23
|
-
* - repository.ts — RuntimeOperationRepository (filesystem-backed)
|
|
24
|
-
* - classifier.ts — classifyOperation(intent) → ReloadTier
|
|
25
|
-
* - health.ts — HealthCheck registry + runner
|
|
26
|
-
* - reload-hot.ts — env-var swap + plugin notify
|
|
27
|
-
* - reload-warm.ts — per-plugin reinit (Phase 2)
|
|
28
|
-
* - reload-cold.ts — full runtime swap (delegates to existing handleRestart)
|
|
15
|
+
* patched in place (except `updateLastPhase`, for running→succeeded).
|
|
16
|
+
* 5. Idempotency keys de-dupe retries within the retention window.
|
|
29
17
|
*/
|
|
30
18
|
import type { AgentRuntime } from "@elizaos/core";
|
|
31
19
|
export interface ProviderSwitchIntent {
|
|
32
20
|
kind: "provider-switch";
|
|
33
21
|
provider: string;
|
|
34
|
-
|
|
22
|
+
/**
|
|
23
|
+
* Vault key that resolves to the provider's API key (e.g.
|
|
24
|
+
* `"providers.openai.api-key"`). The actual secret never travels through
|
|
25
|
+
* the intent — only this stable identifier — so persisted operation
|
|
26
|
+
* records cannot leak credentials. Resolved at apply-env time via
|
|
27
|
+
* `SecretsManager.get(apiKeyRef)`.
|
|
28
|
+
*/
|
|
29
|
+
apiKeyRef?: string;
|
|
35
30
|
primaryModel?: string;
|
|
36
31
|
}
|
|
37
32
|
export interface ConfigReloadIntent {
|
|
@@ -71,14 +66,15 @@ export type OperationKind = OperationIntent["kind"];
|
|
|
71
66
|
export type ReloadTier = "hot" | "warm" | "cold";
|
|
72
67
|
export type OperationStatus = "pending" | "running" | "succeeded" | "failed" | "rolled-back";
|
|
73
68
|
export type PhaseStatus = "pending" | "running" | "succeeded" | "failed" | "skipped";
|
|
69
|
+
export type PhaseName = "validate" | "cold-restart" | "apply-env" | "notify-plugins" | "health-check";
|
|
70
|
+
export type OperationErrorCode = "abandoned" | "no-strategy-for-tier" | "no-runtime" | "strategy-failed" | "vault-resolve-failed" | "health-check-failed";
|
|
74
71
|
export interface OperationError {
|
|
75
72
|
message: string;
|
|
76
|
-
code?:
|
|
73
|
+
code?: OperationErrorCode;
|
|
77
74
|
cause?: string;
|
|
78
75
|
}
|
|
79
76
|
export interface OperationPhase {
|
|
80
|
-
|
|
81
|
-
name: string;
|
|
77
|
+
name: PhaseName;
|
|
82
78
|
status: PhaseStatus;
|
|
83
79
|
startedAt?: number;
|
|
84
80
|
finishedAt?: number;
|
|
@@ -175,6 +171,12 @@ export interface ReloadStrategy {
|
|
|
175
171
|
export interface StartOperationRequest {
|
|
176
172
|
intent: OperationIntent;
|
|
177
173
|
idempotencyKey?: string;
|
|
174
|
+
/**
|
|
175
|
+
* Runs after the idempotency and active-operation gates pass, but before
|
|
176
|
+
* the operation is persisted and scheduled. Use for accepted-only side
|
|
177
|
+
* effects that must complete before the strategy can run.
|
|
178
|
+
*/
|
|
179
|
+
prepare?: () => Promise<OperationIntent | undefined>;
|
|
178
180
|
}
|
|
179
181
|
export type StartOperationOutcome =
|
|
180
182
|
/** Newly accepted; will run async. Caller polls /events for status. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../../../agent/src/runtime/operations/types.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../../../agent/src/runtime/operations/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,28 +3,16 @@
|
|
|
3
3
|
* lifecycle action against the live runtime (provider switch, plugin
|
|
4
4
|
* enable/disable, config reload, full restart).
|
|
5
5
|
*
|
|
6
|
-
* Design invariants
|
|
6
|
+
* Design invariants:
|
|
7
7
|
*
|
|
8
|
-
* 1. Single queue. One operation runs at a time
|
|
9
|
-
*
|
|
8
|
+
* 1. Single queue. One operation runs at a time. New requests while an op
|
|
9
|
+
* is running return 409 with the active op's id.
|
|
10
10
|
* 2. Tiered execution. The use case classifies an intent into a reload
|
|
11
|
-
* tier (hot / warm / cold).
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* plugin (warm) only "wins" after health checks pass; failure rolls
|
|
15
|
-
* back to the previous configuration.
|
|
11
|
+
* tier (hot / warm / cold).
|
|
12
|
+
* 3. Health-gated promotion. A new/re-initialised runtime only "wins"
|
|
13
|
+
* after health checks pass.
|
|
16
14
|
* 4. Append-only phase log. Each phase mutation is a new entry — never
|
|
17
|
-
* patched in place
|
|
18
|
-
* 5. Idempotency keys de-dupe retries
|
|
19
|
-
* window returns the existing operation record.
|
|
20
|
-
*
|
|
21
|
-
* This module exports types only. Implementations live in sibling files:
|
|
22
|
-
* - manager.ts — RuntimeOperationManager (the use case)
|
|
23
|
-
* - repository.ts — RuntimeOperationRepository (filesystem-backed)
|
|
24
|
-
* - classifier.ts — classifyOperation(intent) → ReloadTier
|
|
25
|
-
* - health.ts — HealthCheck registry + runner
|
|
26
|
-
* - reload-hot.ts — env-var swap + plugin notify
|
|
27
|
-
* - reload-warm.ts — per-plugin reinit (Phase 2)
|
|
28
|
-
* - reload-cold.ts — full runtime swap (delegates to existing handleRestart)
|
|
15
|
+
* patched in place (except `updateLastPhase`, for running→succeeded).
|
|
16
|
+
* 5. Idempotency keys de-dupe retries within the retention window.
|
|
29
17
|
*/
|
|
30
18
|
export {};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vault bridge — the only place runtime-ops talks to `@elizaos/vault`.
|
|
3
|
+
*
|
|
4
|
+
* Enforces:
|
|
5
|
+
* 1. The naming convention for provider API key vault entries
|
|
6
|
+
* (`providers.<normalizedProvider>.api-key`).
|
|
7
|
+
* 2. Sensitive flag on every write (so the secret is encrypted at rest).
|
|
8
|
+
* 3. Caller tagging for the audit log so a reader of
|
|
9
|
+
* `<stateDir>/audit/vault.jsonl` can attribute every access to a
|
|
10
|
+
* runtime-ops phase.
|
|
11
|
+
*
|
|
12
|
+
* The bridge owns NO mutable state. Either pass an explicit
|
|
13
|
+
* SecretsManager (tests), or call `defaultSecretsManager()` (production)
|
|
14
|
+
* which constructs a fresh manager backed by the OS-keychain vault.
|
|
15
|
+
*/
|
|
16
|
+
import { type SecretsManager } from "@elizaos/vault";
|
|
17
|
+
import type { OperationErrorCode } from "./types.js";
|
|
18
|
+
export declare class VaultResolveError extends Error {
|
|
19
|
+
readonly code: OperationErrorCode;
|
|
20
|
+
constructor(apiKeyRef: string, cause: unknown);
|
|
21
|
+
}
|
|
22
|
+
/** Stable vault key for a provider API key. */
|
|
23
|
+
export declare function vaultKeyForProviderApiKey(normalizedProvider: string): string;
|
|
24
|
+
/**
|
|
25
|
+
* Persist a provider API key in the vault under the canonical key name and
|
|
26
|
+
* return the vault key (the `apiKeyRef`).
|
|
27
|
+
*
|
|
28
|
+
* This is the single write path used by `provider-switch-routes.ts`. The
|
|
29
|
+
* route MUST persist the secret here BEFORE constructing the
|
|
30
|
+
* `ProviderSwitchIntent` so the intent never carries plaintext.
|
|
31
|
+
*/
|
|
32
|
+
export declare function persistProviderApiKey(opts: {
|
|
33
|
+
secrets: SecretsManager;
|
|
34
|
+
normalizedProvider: string;
|
|
35
|
+
apiKey: string;
|
|
36
|
+
caller: string;
|
|
37
|
+
}): Promise<string>;
|
|
38
|
+
/**
|
|
39
|
+
* Resolve a stored API key for the in-memory `process.env` write path.
|
|
40
|
+
*
|
|
41
|
+
* Returns `undefined` only when `apiKeyRef` is absent. If a ref is present,
|
|
42
|
+
* the operation must fail loudly when the vault cannot resolve it; otherwise a
|
|
43
|
+
* provider switch can appear successful while running with no key or a stale
|
|
44
|
+
* key from process.env.
|
|
45
|
+
*
|
|
46
|
+
* The caller is recorded on each successful read.
|
|
47
|
+
*/
|
|
48
|
+
export declare function resolveProviderApiKey(opts: {
|
|
49
|
+
secrets: SecretsManager;
|
|
50
|
+
apiKeyRef: string | undefined;
|
|
51
|
+
caller: string;
|
|
52
|
+
}): Promise<string | undefined>;
|
|
53
|
+
/**
|
|
54
|
+
* Lazy default manager. Production code paths construct a fresh manager
|
|
55
|
+
* the first time runtime-ops needs the vault; tests inject their own.
|
|
56
|
+
*/
|
|
57
|
+
export declare function defaultSecretsManager(): SecretsManager;
|
|
58
|
+
/** Test hook: drop the cached manager. */
|
|
59
|
+
export declare function _resetDefaultSecretsManagerForTesting(): void;
|
|
60
|
+
//# sourceMappingURL=vault-bridge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vault-bridge.d.ts","sourceRoot":"","sources":["../../../../../../../agent/src/runtime/operations/vault-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAiB,KAAK,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACpE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAErD,qBAAa,iBAAkB,SAAQ,KAAK;IAC1C,QAAQ,CAAC,IAAI,EAAE,kBAAkB,CAA0B;gBAE/C,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO;CAQ9C;AAED,+CAA+C;AAC/C,wBAAgB,yBAAyB,CAAC,kBAAkB,EAAE,MAAM,GAAG,MAAM,CAO5E;AAED;;;;;;;GAOG;AACH,wBAAsB,qBAAqB,CAAC,IAAI,EAAE;IAChD,OAAO,EAAE,cAAc,CAAC;IACxB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CAOlB;AAED;;;;;;;;;GASG;AACH,wBAAsB,qBAAqB,CAAC,IAAI,EAAE;IAChD,OAAO,EAAE,cAAc,CAAC;IACxB,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAO9B;AAID;;;GAGG;AACH,wBAAgB,qBAAqB,IAAI,cAAc,CAGtD;AAED,0CAA0C;AAC1C,wBAAgB,qCAAqC,IAAI,IAAI,CAE5D"}
|