@warlock.js/ai 4.14.0 → 4.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 (104) hide show
  1. package/CHANGELOG.md +182 -141
  2. package/cjs/index.cjs +640 -139
  3. package/cjs/index.cjs.map +1 -1
  4. package/esm/contracts/index.d.mts +3 -3
  5. package/esm/contracts/memory/index.d.mts +1 -1
  6. package/esm/contracts/memory/memory-config.type.d.mts +29 -3
  7. package/esm/contracts/memory/memory-config.type.d.mts.map +1 -1
  8. package/esm/contracts/memory/memory-item.type.d.mts +15 -1
  9. package/esm/contracts/memory/memory-item.type.d.mts.map +1 -1
  10. package/esm/contracts/memory/memory.contract.d.mts +15 -2
  11. package/esm/contracts/memory/memory.contract.d.mts.map +1 -1
  12. package/esm/contracts/memory/recall-options.type.d.mts +12 -0
  13. package/esm/contracts/memory/recall-options.type.d.mts.map +1 -1
  14. package/esm/contracts/orchestrator/index.d.mts +1 -1
  15. package/esm/contracts/orchestrator/orchestrator-config.type.d.mts +38 -1
  16. package/esm/contracts/orchestrator/orchestrator-config.type.d.mts.map +1 -1
  17. package/esm/contracts/orchestrator/orchestrator.contract.d.mts +67 -3
  18. package/esm/contracts/orchestrator/orchestrator.contract.d.mts.map +1 -1
  19. package/esm/contracts/supervisor/supervisor-config.type.d.mts +23 -0
  20. package/esm/contracts/supervisor/supervisor-config.type.d.mts.map +1 -1
  21. package/esm/contracts/team/team-config.type.d.mts +9 -6
  22. package/esm/contracts/team/team-config.type.d.mts.map +1 -1
  23. package/esm/contracts/tool.contract.d.mts +35 -3
  24. package/esm/contracts/tool.contract.d.mts.map +1 -1
  25. package/esm/index.d.mts +8 -7
  26. package/esm/index.mjs +3 -2
  27. package/esm/memory/episodic-memory.mjs +14 -6
  28. package/esm/memory/episodic-memory.mjs.map +1 -1
  29. package/esm/memory/index.d.mts +1 -1
  30. package/esm/memory/memory.d.mts +13 -1
  31. package/esm/memory/memory.d.mts.map +1 -1
  32. package/esm/memory/memory.mjs +41 -7
  33. package/esm/memory/memory.mjs.map +1 -1
  34. package/esm/memory/procedural-memory.mjs +20 -7
  35. package/esm/memory/procedural-memory.mjs.map +1 -1
  36. package/esm/memory/semantic-memory.mjs +27 -10
  37. package/esm/memory/semantic-memory.mjs.map +1 -1
  38. package/esm/memory/working-memory.mjs +70 -13
  39. package/esm/memory/working-memory.mjs.map +1 -1
  40. package/esm/middleware/builtins/semantic-cache.d.mts +46 -1
  41. package/esm/middleware/builtins/semantic-cache.d.mts.map +1 -1
  42. package/esm/middleware/builtins/semantic-cache.mjs +60 -15
  43. package/esm/middleware/builtins/semantic-cache.mjs.map +1 -1
  44. package/esm/middleware/index.d.mts +1 -1
  45. package/esm/mock/index.d.mts +1 -1
  46. package/esm/mock/mock-config.type.d.mts +33 -4
  47. package/esm/mock/mock-config.type.d.mts.map +1 -1
  48. package/esm/mock/mock-model.d.mts +2 -1
  49. package/esm/mock/mock-model.d.mts.map +1 -1
  50. package/esm/mock/mock-model.mjs +5 -4
  51. package/esm/mock/mock-model.mjs.map +1 -1
  52. package/esm/mock/mock-sdk.d.mts +11 -3
  53. package/esm/mock/mock-sdk.d.mts.map +1 -1
  54. package/esm/mock/mock-sdk.mjs.map +1 -1
  55. package/esm/orchestrator/as-tool.d.mts +35 -9
  56. package/esm/orchestrator/as-tool.d.mts.map +1 -1
  57. package/esm/orchestrator/as-tool.mjs +67 -19
  58. package/esm/orchestrator/as-tool.mjs.map +1 -1
  59. package/esm/orchestrator/execution.d.mts.map +1 -1
  60. package/esm/orchestrator/execution.mjs +2 -2
  61. package/esm/orchestrator/execution.mjs.map +1 -1
  62. package/esm/orchestrator/index.d.mts +1 -1
  63. package/esm/orchestrator/index.mjs +1 -1
  64. package/esm/orchestrator/memory.d.mts +41 -5
  65. package/esm/orchestrator/memory.d.mts.map +1 -1
  66. package/esm/orchestrator/memory.mjs +53 -5
  67. package/esm/orchestrator/memory.mjs.map +1 -1
  68. package/esm/planner/plan-schema.d.mts +15 -4
  69. package/esm/planner/plan-schema.d.mts.map +1 -1
  70. package/esm/planner/plan-schema.mjs +27 -16
  71. package/esm/planner/plan-schema.mjs.map +1 -1
  72. package/esm/security/index.mjs +1 -0
  73. package/esm/security/outbound-policy.d.mts +9 -0
  74. package/esm/security/outbound-policy.d.mts.map +1 -1
  75. package/esm/security/outbound-policy.mjs +79 -5
  76. package/esm/security/outbound-policy.mjs.map +1 -1
  77. package/esm/security/outbound-policy.type.d.mts +8 -0
  78. package/esm/security/outbound-policy.type.d.mts.map +1 -1
  79. package/esm/security/safe-merge.d.mts +52 -0
  80. package/esm/security/safe-merge.d.mts.map +1 -0
  81. package/esm/security/safe-merge.mjs +68 -0
  82. package/esm/security/safe-merge.mjs.map +1 -0
  83. package/esm/supervisor/decide.mjs +52 -5
  84. package/esm/supervisor/decide.mjs.map +1 -1
  85. package/esm/supervisor/execution.d.mts +22 -12
  86. package/esm/supervisor/execution.d.mts.map +1 -1
  87. package/esm/supervisor/execution.mjs +47 -24
  88. package/esm/supervisor/execution.mjs.map +1 -1
  89. package/esm/supervisor/supervisor.mjs +4 -0
  90. package/esm/supervisor/supervisor.mjs.map +1 -1
  91. package/llms-full.txt +185 -14
  92. package/llms.txt +5 -4
  93. package/package.json +24 -4
  94. package/skills/README.md +6 -2
  95. package/skills/attach-ai-middleware/SKILL.md +17 -1
  96. package/skills/generate-images/SKILL.md +11 -4
  97. package/skills/rag-loaders-and-stores/SKILL.md +3 -0
  98. package/skills/run-ai-agent/SKILL.md +3 -0
  99. package/skills/run-orchestrator/SKILL.md +6 -1
  100. package/skills/run-planner/SKILL.md +7 -3
  101. package/skills/run-supervisor/SKILL.md +11 -1
  102. package/skills/secure-outbound-requests/SKILL.md +85 -0
  103. package/skills/use-ai-memory/SKILL.md +36 -3
  104. package/skills/use-runtime-skills/SKILL.md +2 -1
@@ -25,7 +25,7 @@ import { END, EndSentinel } from "./end.type.mjs";
25
25
  import { SupervisorReport, SupervisorResult, SupervisorTerminatedBy } from "./result/supervisor-result.type.mjs";
26
26
  import { StepSnapshot } from "./result/step-result.type.mjs";
27
27
  import { WorkflowReport, WorkflowResult } from "./result/workflow-result.type.mjs";
28
- import { ToolConfig, ToolContext, ToolMeta, ToolMode } from "./tool.contract.mjs";
28
+ import { ToolActionResolver, ToolConfig, ToolContext, ToolMeta, ToolMode } from "./tool.contract.mjs";
29
29
  import { SupervisorInput } from "./supervisor/supervisor-input.type.mjs";
30
30
  import { SupervisorSnapshot, SupervisorSnapshotStatus } from "./supervisor/supervisor-snapshot.type.mjs";
31
31
  import { PgClientLike, RedisClientLike, SnapshotStore } from "./orchestrator/snapshot-store.contract.mjs";
@@ -67,14 +67,14 @@ import { GeneratedImage, ImageGenerationOptions, ImageGenerationResponse, ImageM
67
67
  import { MemoryItem, MemoryTier, RecalledMemory } from "./memory/memory-item.type.mjs";
68
68
  import { RecallOptions } from "./memory/recall-options.type.mjs";
69
69
  import { MemoryContract } from "./memory/memory.contract.mjs";
70
- import { MemoryConfig, SemanticMemoryConfig } from "./memory/memory-config.type.mjs";
70
+ import { MemoryConfig, SemanticMemoryConfig, WorkingMemoryConfig } from "./memory/memory-config.type.mjs";
71
71
  import { CheckpointRecord, CheckpointStore } from "./orchestrator/checkpoint-store.contract.mjs";
72
72
  import { SessionLock } from "./orchestrator/session-lock.contract.mjs";
73
73
  import { OrchestratorCommands } from "./orchestrator/orchestrator-commands.type.mjs";
74
74
  import { OrchestratorEvent, OrchestratorEventHandler, OrchestratorEventHandlers, OrchestratorEventMap, OrchestratorEventName } from "./orchestrator/orchestrator-event.type.mjs";
75
75
  import { OrchestratorExecuteOptions, OrchestratorResumeOptions } from "./orchestrator/orchestrator-execute-options.type.mjs";
76
76
  import { OrchestratorAsToolOptions, OrchestratorContract, OrchestratorSessionScope, SessionContextOverrides } from "./orchestrator/orchestrator.contract.mjs";
77
- import { OrchestratorConfig, OrchestratorMemoryConfig, SummarizeCallback, SummarizeConfig } from "./orchestrator/orchestrator-config.type.mjs";
77
+ import { OrchestratorConfig, OrchestratorMemoryConfig, OrchestratorMemoryScope, SummarizeCallback, SummarizeConfig } from "./orchestrator/orchestrator-config.type.mjs";
78
78
  import { SessionContract } from "./orchestrator/session.contract.mjs";
79
79
  import { PlannerCapability } from "./planner/planner-capability.type.mjs";
80
80
  import { PlannerPlan, PlannerStep } from "./planner/planner-plan.type.mjs";
@@ -1,4 +1,4 @@
1
1
  import { MemoryItem, MemoryTier, RecalledMemory } from "./memory-item.type.mjs";
2
2
  import { RecallOptions } from "./recall-options.type.mjs";
3
3
  import { MemoryContract } from "./memory.contract.mjs";
4
- import { MemoryConfig, SemanticMemoryConfig } from "./memory-config.type.mjs";
4
+ import { MemoryConfig, SemanticMemoryConfig, WorkingMemoryConfig } from "./memory-config.type.mjs";
@@ -3,6 +3,31 @@ import { MemoryTier } from "./memory-item.type.mjs";
3
3
  import { CacheDriver } from "@warlock.js/cache";
4
4
 
5
5
  //#region ../ai/src/contracts/memory/memory-config.type.d.ts
6
+ /**
7
+ * Working-tier wiring for `memory(config)`.
8
+ *
9
+ * The working tier is a plain in-process buffer with no durability and
10
+ * no vector index — it lives for the lifetime of the `memory()` instance,
11
+ * which composite primitives (`ai.orchestrator({ memory })`) resolve once
12
+ * and reuse across every session. Its only knob is the size bound that
13
+ * keeps that lifetime from turning into unbounded process-memory growth.
14
+ */
15
+ type WorkingMemoryConfig = {
16
+ /**
17
+ * Maximum number of entries the working buffer holds, across every
18
+ * `scope`. On overflow the oldest-written entry is evicted (FIFO —
19
+ * recall returns newest-first, so the evicted end is the one a bounded
20
+ * recall would never reach). Default `1000`.
21
+ *
22
+ * Must be an integer `>= 1`; there is no unbounded setting. Raise it
23
+ * deliberately for a long-running single-tenant process that recalls
24
+ * deep history from the working tier, and remember every entry is
25
+ * retained in process memory until evicted or `clear()`ed. Durable
26
+ * recall belongs in the semantic / episodic tiers, which delegate
27
+ * storage to a `CacheDriver`.
28
+ */
29
+ maxItems?: number;
30
+ };
6
31
  /**
7
32
  * Semantic-tier wiring for `memory(config)`.
8
33
  *
@@ -111,9 +136,10 @@ type MemoryConfig = {
111
136
  /** Stable identifier — used in logs and as the working-tier scope key. */name?: string;
112
137
  /**
113
138
  * Enable the in-run working tier. Default `true`. Set `false` to build
114
- * a semantic-only memory.
139
+ * a semantic-only memory, or pass a {@link WorkingMemoryConfig} to tune
140
+ * its size bound (`{ maxItems }`, default `1000`).
115
141
  */
116
- working?: boolean;
142
+ working?: boolean | WorkingMemoryConfig;
117
143
  /**
118
144
  * Enable + wire the semantic recall tier. Omit for a working-only
119
145
  * memory.
@@ -146,5 +172,5 @@ type MemoryConfig = {
146
172
  threshold?: number;
147
173
  };
148
174
  //#endregion
149
- export { EpisodicMemoryConfig, MemoryConfig, ProceduralMemoryConfig, SemanticMemoryConfig };
175
+ export { EpisodicMemoryConfig, MemoryConfig, ProceduralMemoryConfig, SemanticMemoryConfig, WorkingMemoryConfig };
150
176
  //# sourceMappingURL=memory-config.type.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"memory-config.type.d.mts","names":[],"sources":["../../../../../../../../ai/src/contracts/memory/memory-config.type.ts"],"mappings":";;;;;;;AAmBA;;;;;;;;;;AAcW;AAWX;;KAzBY,oBAAA;EAgCS,qEA9BnB,QAAA,EAAU,gBAAA;EAyBA;;;;;EAnBV,KAAA,GAAQ,WAAW;EA8CnB;;AAAG;AAUL;;EAlDE,SAAA;AAAA;;;;;;;;AAqEmB;KA1DT,oBAAA;EAsEY,yEApEtB,QAAA,EAAU,gBAAA;EAgFC;;;;EA3EX,KAAA,GAAQ,WAAW;EA0FK;;;;;EApFxB,SAAA;EA0EW;;;;;EApEX,aAAA;EAwFA;;AAAS;;EAnFT,UAAA;;;;;EAKA,GAAA;AAAA;;;;;;;;KAUU,sBAAA;6EAEV,QAAA,EAAU,gBAAA;;;;;EAKV,KAAA,GAAQ,WAAW;;;;;;EAMnB,SAAA;;;;;;EAMA,mBAAA;AAAA;;;;;;;;;;KAYU,YAAA;4EAEV,IAAA;;;;;EAKA,OAAA;;;;;EAKA,QAAA,GAAW,oBAAA;;;;;EAKX,QAAA,GAAW,oBAAA;;;;;EAKX,UAAA,GAAa,sBAAA;;;;;EAKb,WAAA,GAAc,UAAA;;;;;EAKd,CAAA;;;;;EAKA,SAAA;AAAA"}
1
+ {"version":3,"file":"memory-config.type.d.mts","names":[],"sources":["../../../../../../../../ai/src/contracts/memory/memory-config.type.ts"],"mappings":";;;;;;;AAaA;;;;AAcU;AAkBV;;KAhCY,mBAAA;EAwCS;;;;;;;AAMV;AAWX;;;;;EA3CE,QAAQ;AAAA;;;;;;;AAwEL;AAUL;;;;;;;;KAhEY,oBAAA;EAmFV,qEAjFA,QAAA,EAAU,gBAAA;EAiFS;AAYrB;;;;EAvFE,KAAA,GAAQ,WAAW;EAyGR;;;;;EAnGX,SAAA;AAAA;;;;;;;;;KAWU,oBAAA;EAuGV,yEArGA,QAAA,EAAU,gBAAA;EA0GD;AAAA;;;EArGT,KAAA,GAAQ,WAAW;;;;;;EAMnB,SAAA;;;;;;EAMA,aAAA;;;;;EAKA,UAAA;;;;;EAKA,GAAA;AAAA;;;;;;;;KAUU,sBAAA;6EAEV,QAAA,EAAU,gBAAA;;;;;EAKV,KAAA,GAAQ,WAAW;;;;;;EAMnB,SAAA;;;;;;EAMA,mBAAA;AAAA;;;;;;;;;;KAYU,YAAA;4EAEV,IAAA;;;;;;EAMA,OAAA,aAAoB,mBAAA;;;;;EAKpB,QAAA,GAAW,oBAAA;;;;;EAKX,QAAA,GAAW,oBAAA;;;;;EAKX,UAAA,GAAa,sBAAA;;;;;EAKb,WAAA,GAAc,UAAA;;;;;EAKd,CAAA;;;;;EAKA,SAAA;AAAA"}
@@ -35,11 +35,25 @@ type MemoryTier = "working" | "semantic" | "episodic" | "procedural";
35
35
  * `metadata` is an opaque bag round-tripped verbatim onto the recalled
36
36
  * memory — use it for source ids, timestamps, tags, or anything the
37
37
  * consumer wants back alongside the text.
38
+ *
39
+ * `scope` is the ISOLATION key (4.15.0). It is not metadata: every tier
40
+ * enforces an exact-equality match between an item's `scope` and the
41
+ * `scope` on the `recall()` call BEFORE hits are scored and merged, so
42
+ * an item written under one scope can never surface in another scope's
43
+ * recall. Omit it for the shared/global pool.
38
44
  */
39
45
  type MemoryItem = {
40
46
  /** Natural-language content. Embedded for semantic recall; surfaced verbatim on retrieval. */text: string; /** Destination tier. Defaults to the factory's `defaultTier` when omitted. */
41
47
  tier?: MemoryTier; /** Caller-owned identifier for overwrite / dedup. Derived from `text` when omitted. */
42
- id?: string; /** Opaque metadata round-tripped onto the recalled memory unchanged. */
48
+ id?: string;
49
+ /**
50
+ * Isolation key — an opaque tenant / session / user boundary. Enforced
51
+ * by every tier as an exact-equality filter at recall time, and folded
52
+ * into the stored key so two scopes writing identical text never
53
+ * overwrite each other. Omit for the shared/global pool (which only an
54
+ * equally unscoped `recall()` can read).
55
+ */
56
+ scope?: string; /** Opaque metadata round-tripped onto the recalled memory unchanged. */
43
57
  metadata?: Record<string, unknown>;
44
58
  };
45
59
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"memory-item.type.d.mts","names":[],"sources":["../../../../../../../../ai/src/contracts/memory/memory-item.type.ts"],"mappings":";;AAqBA;;;;AAAsB;AAiBtB;;;;;;;;;;;AAQmB;AAanB;;;KAtCY,UAAA;;;;;;;;;AAgDO;;;;;;;KA/BP,UAAA;gGAEV,IAAA;EAEA,IAAA,GAAO,UAAA;EAEP,EAAA;EAEA,QAAA,GAAW,MAAM;AAAA;;;;;;;;;;;KAaP,cAAA;wCAEV,EAAA;EAEA,IAAA;EAEA,IAAA,EAAM,UAAA;EAEN,KAAA;EAEA,QAAA,GAAW,MAAM;AAAA"}
1
+ {"version":3,"file":"memory-item.type.d.mts","names":[],"sources":["../../../../../../../../ai/src/contracts/memory/memory-item.type.ts"],"mappings":";;AAqBA;;;;AAAsB;AAuBtB;;;;;;;;;;;;AAgBmB;AAanB;;KApDY,UAAA;;;;;;;;;;AA8DO;;;;;;;;;;;;KAvCP,UAAA;gGAEV,IAAA;EAEA,IAAA,GAAO,UAAA;EAEP,EAAA;;;;;;;;EAQA,KAAA;EAEA,QAAA,GAAW,MAAM;AAAA;;;;;;;;;;;KAaP,cAAA;wCAEV,EAAA;EAEA,IAAA;EAEA,IAAA,EAAM,UAAA;EAEN,KAAA;EAEA,QAAA,GAAW,MAAM;AAAA"}
@@ -27,6 +27,15 @@ import { RecallOptions } from "./recall-options.type.mjs";
27
27
  * itself; surfacing the recalled text is the consumer's call so the
28
28
  * injection point stays explicit.
29
29
  *
30
+ * **Isolation (4.15.0).** Every item may carry a `scope` — an opaque
31
+ * tenant / session / user key — and every `recall()` may name one. The
32
+ * match is exact equality, enforced *inside* each tier before hits are
33
+ * scored and merged, so one scope's memories can never surface in
34
+ * another's recall. Unscoped items form a shared pool readable only by an
35
+ * equally unscoped `recall()`; there is no "read every scope" query.
36
+ * `ai.orchestrator({ memory })` sets this automatically from the turn's
37
+ * `sessionId` (see `OrchestratorMemoryConfig.scope`).
38
+ *
30
39
  * **Still deferred.** Decay / forgetting (TTL-based relevance falloff,
31
40
  * eviction policies) is not yet implemented; the four tiers above are the
32
41
  * full 4.3.0 surface. The `episodic` and `procedural` tiers were added in
@@ -62,14 +71,18 @@ interface MemoryContract {
62
71
  * appended to the in-run buffer.
63
72
  *
64
73
  * Re-remembering an item whose id (explicit or text-derived) already
65
- * exists overwrites it in place rather than duplicating.
74
+ * exists overwrites it in place rather than duplicating — within the
75
+ * item's `scope`. Identical text under two different scopes stays two
76
+ * independent entries.
66
77
  */
67
78
  remember(items: MemoryItem | MemoryItem[]): Promise<void>;
68
79
  /**
69
80
  * Retrieve the memories most relevant to `query`, scored and ordered
70
81
  * by descending relevance. Queries every enabled tier by default;
71
82
  * `options.tier` narrows to one. `options.k` caps the result count,
72
- * `options.threshold` raises the semantic-similarity floor.
83
+ * `options.threshold` raises the semantic-similarity floor, and
84
+ * `options.scope` restricts the eligible set to the memories written
85
+ * under that exact scope (omit it to read the unscoped pool only).
73
86
  *
74
87
  * Returns an empty array when nothing clears the threshold — never
75
88
  * throws on "no hits".
@@ -1 +1 @@
1
- {"version":3,"file":"memory.contract.d.mts","names":[],"sources":["../../../../../../../../ai/src/contracts/memory/memory.contract.ts"],"mappings":";;;;;;AAqDA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+BmC;;;;;;;;;;;;;;;;;;UA/BlB,cAAA;;WAEN,IAAA;;;;;;;;;;EAWT,QAAA,CAAS,KAAA,EAAO,UAAA,GAAa,UAAA,KAAe,OAAA;;;;;;;;;;EAW5C,MAAA,CAAO,KAAA,UAAe,OAAA,GAAU,aAAA,GAAgB,OAAA,CAAQ,cAAA;;;;;;EAOxD,KAAA,CAAM,IAAA,GAAO,UAAA,GAAa,OAAA;AAAA"}
1
+ {"version":3,"file":"memory.contract.d.mts","names":[],"sources":["../../../../../../../../ai/src/contracts/memory/memory.contract.ts"],"mappings":";;;;;;AA8DA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmCmC;;;;;;;;;;;;;;;;;;;;;;;;;;;UAnClB,cAAA;;WAEN,IAAA;;;;;;;;;;;;EAaT,QAAA,CAAS,KAAA,EAAO,UAAA,GAAa,UAAA,KAAe,OAAA;;;;;;;;;;;;EAa5C,MAAA,CAAO,KAAA,UAAe,OAAA,GAAU,aAAA,GAAgB,OAAA,CAAQ,cAAA;;;;;;EAOxD,KAAA,CAAM,IAAA,GAAO,UAAA,GAAa,OAAA;AAAA"}
@@ -27,6 +27,18 @@ type RecallOptions = {
27
27
  * which has no vector index.
28
28
  */
29
29
  threshold?: number;
30
+ /**
31
+ * Isolation key (4.15.0) — only memories remembered under the SAME
32
+ * `scope` are eligible. The match is exact equality, enforced inside
33
+ * every tier before hits are scored and merged, never bolted on by the
34
+ * caller afterward.
35
+ *
36
+ * Omitting `scope` does NOT mean "every scope": an unscoped recall
37
+ * reads only the unscoped (shared/global) pool. That is the fail-closed
38
+ * default — reading another tenant's memories always requires naming
39
+ * their scope explicitly.
40
+ */
41
+ scope?: string;
30
42
  };
31
43
  //#endregion
32
44
  export { RecallOptions };
@@ -1 +1 @@
1
- {"version":3,"file":"recall-options.type.d.mts","names":[],"sources":["../../../../../../../../ai/src/contracts/memory/recall-options.type.ts"],"mappings":";;;;;AASA;;;;;KAAY,aAAA;EAYH;;;AAME;;EAZT,CAAA;;;;;;EAMA,IAAA,GAAO,UAAU;;;;;;EAMjB,SAAA;AAAA"}
1
+ {"version":3,"file":"recall-options.type.d.mts","names":[],"sources":["../../../../../../../../ai/src/contracts/memory/recall-options.type.ts"],"mappings":";;;;;AASA;;;;;KAAY,aAAA;EAYH;;;;AAkBF;EAxBL,CAAA;;;;;;EAMA,IAAA,GAAO,UAAU;;;;;;EAMjB,SAAA;;;;;;;;;;;;EAYA,KAAA;AAAA"}
@@ -5,5 +5,5 @@ import { OrchestratorCommands } from "./orchestrator-commands.type.mjs";
5
5
  import { OrchestratorEvent, OrchestratorEventHandler, OrchestratorEventHandlers, OrchestratorEventMap, OrchestratorEventName } from "./orchestrator-event.type.mjs";
6
6
  import { OrchestratorExecuteOptions, OrchestratorResumeOptions } from "./orchestrator-execute-options.type.mjs";
7
7
  import { OrchestratorAsToolOptions, OrchestratorContract, OrchestratorSessionScope, SessionContextOverrides } from "./orchestrator.contract.mjs";
8
- import { OrchestratorConfig, OrchestratorMemoryConfig, SummarizeCallback, SummarizeConfig } from "./orchestrator-config.type.mjs";
8
+ import { OrchestratorConfig, OrchestratorMemoryConfig, OrchestratorMemoryScope, SummarizeCallback, SummarizeConfig } from "./orchestrator-config.type.mjs";
9
9
  import { SessionContract } from "./session.contract.mjs";
@@ -49,6 +49,14 @@ type SummarizeConfig = {
49
49
  * coarse.
50
50
  */
51
51
  type SummarizeCallback = (history: Message[]) => Promise<CompactionResult> | CompactionResult;
52
+ /**
53
+ * Isolation boundary for the orchestrator's memory recall / write-back
54
+ * (4.15.0). `"session"` (the default) confines a turn to the memories
55
+ * remembered under the same `sessionId`; `"shared"` opts every session of
56
+ * this orchestrator into one common pool; a function derives a custom key
57
+ * (a tenant id, a user id) from the executing session.
58
+ */
59
+ type OrchestratorMemoryScope = "session" | "shared" | ((sessionId: string) => string);
52
60
  /**
53
61
  * Per-turn memory wiring for `OrchestratorConfig.memory` (memory core
54
62
  * M2). The `store` is the {@link MemoryContract} the orchestrator
@@ -65,9 +73,33 @@ type SummarizeCallback = (history: Message[]) => Promise<CompactionResult> | Com
65
73
  * `ctx.context[injectKey]` — memory never mutates the prompt itself, the
66
74
  * surfacing point stays explicit (the same contract `MemoryContract`
67
75
  * documents).
76
+ *
77
+ * **Isolation (4.15.0).** The store is resolved ONCE per orchestrator
78
+ * instance and reused by every session, so `scope` decides what a turn
79
+ * may read: it defaults to `"session"`, which confines both recall and
80
+ * write-back to the executing `sessionId`. Cross-session pooling is
81
+ * available but must be asked for (`scope: "shared"`).
68
82
  */
69
83
  type OrchestratorMemoryConfig = {
70
84
  /** The memory store recalled-from before dispatch and remembered-into after. */store: MemoryContract;
85
+ /**
86
+ * Isolation boundary applied to every recall and write-back
87
+ * (4.15.0 — security fix).
88
+ *
89
+ * - `"session"` (DEFAULT) — memories are keyed to the turn's
90
+ * `sessionId`. One session can never recall another's remembered
91
+ * turns, even though the store instance is shared by the whole
92
+ * orchestrator.
93
+ * - `"shared"` — every session reads and writes ONE pool. This is the
94
+ * pre-4.15.0 behavior and is only safe when every session of this
95
+ * orchestrator is trusted to see every other session's memories
96
+ * (e.g. a single-tenant assistant, or a curated knowledge base).
97
+ * - `(sessionId) => string` — derive the key yourself, e.g. map a
98
+ * session to its tenant (`(id) => tenantOf(id)`) so a tenant's users
99
+ * share memory but tenants stay isolated. The returned string is
100
+ * opaque; equal strings share memories.
101
+ */
102
+ scope?: OrchestratorMemoryScope;
71
103
  /**
72
104
  * Pre-dispatch recall tuning. `k` caps the injected count (0 disables
73
105
  * recall — write-only memory); `threshold` raises the semantic
@@ -190,10 +222,15 @@ type OrchestratorConfig<TOutput, TState = TOutput, TIntents extends Record<strin
190
222
  * the existing behavior — orchestrators without memory are unchanged.
191
223
  * Accepts a bare {@link MemoryContract} (recall + remember with
192
224
  * defaults) or an {@link OrchestratorMemoryConfig} for finer control.
225
+ *
226
+ * Either form is SESSION-SCOPED by default (4.15.0): the store is
227
+ * shared by the whole orchestrator instance, but each turn only recalls
228
+ * what its own `sessionId` remembered. Opt into cross-session pooling
229
+ * explicitly with `{ store, scope: "shared" }`.
193
230
  */
194
231
  memory?: MemoryContract | OrchestratorMemoryConfig; /** Definition-level event handlers — tier 1 of the 3-tier model. */
195
232
  on?: OrchestratorEventHandlers;
196
233
  };
197
234
  //#endregion
198
- export { OrchestratorConfig, OrchestratorMemoryConfig, SummarizeCallback, SummarizeConfig };
235
+ export { OrchestratorConfig, OrchestratorMemoryConfig, OrchestratorMemoryScope, SummarizeCallback, SummarizeConfig };
199
236
  //# sourceMappingURL=orchestrator-config.type.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"orchestrator-config.type.d.mts","names":[],"sources":["../../../../../../../../ai/src/contracts/orchestrator/orchestrator-config.type.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AA2BA;;;;;;KAAY,eAAA;EAeE,qEAbZ,UAAA,WAEA;EAAA,IAAA,WAEa;EAAb,UAAA,GAAa,aAAA;EAOC;;;;;EADd,SAAA,IACE,UAAA,EAAY,gBAAA,EACZ,GAAA;IAAO,SAAA;EAAA,MACJ,OAAA,eAEW;EAAhB,IAAA;IAAS,OAAA;EAAA;AAAA;;;;;;;KASC,iBAAA,IACV,OAAA,EAAS,OAAA,OACN,OAAA,CAAQ,gBAAA,IAAoB,gBAAA;;;;;AAAgB;AAmBjD;;;;;;;;;;;;KAAY,wBAAA;EAYR,gFAVF,KAAA,EAAO,cAAA;EAkBP;;;;;AAYS;EAvBT,MAAA;IACE,CAAA;IACA,SAAA;IACA,IAAA,GAAO,UAAA;EAAA;EAmDQ;;;;;;EA3CjB,QAAA;EAkEc;;;;;EA5Dd,YAAA,GAAe,UAAA;EA8DmB;;;;;EAxDlC,SAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;KA4BU,kBAAA,mBAED,OAAA,mBACQ,MAAA,SAAe,qBAAA,IAAyB,MAAA,SAEvD,qBAAA;EAcF,wEAVA,IAAA,UAYA;EAVA,OAAA;EAaA;;;;;;;EALA,OAAA,GAAU,iBAAA,EAO4C;EALtD,YAAA,GAAe,oBAAA,WAON;EAJT,OAAA,EAAS,QAAA,EAIqC;EAF9C,KAAA,IAAS,GAAA,EAAK,YAAA,CAAa,MAAA,MAAY,IAAA,GAAO,OAAA,CAAQ,IAAA,GAK/C;EAHP,MAAA,GAAS,aAAA,YAAyB,WAAA,CAAY,MAAA,GAG5C;EADF,QAAA,IACE,GAAA,EAAK,eAAA,CAAgB,MAAA,MAClB,cAAA,GAAiB,OAAA,CAAQ,cAAA,GAAR;EAEtB,KAAA,GAAQ,MAAA,EAAR;EAEA,MAAA,GAAS,gBAAA,CAAiB,OAAA,GAA1B;EAEA,YAAA,WAF0B;EAI1B,aAAA;EAAA;;;;;EAOA,OAAA;EAO8C;;;;;EAD9C,aAAA;IACE,MAAA,cAAoB,QAAA,EAAU,OAAA,OAAc,OAAA;IAC5C,MAAA,cAAoB,QAAA,EAAU,OAAA,OAAc,OAAA;EAAA,GAQ9C;EALA,SAAA,GAAY,eAAA,GAAkB,iBAAA,EAwB9B;EAtBA,aAAA,mBAwBA;EArBA,eAAA,GAAkB,eAAA;EA+BlB;;;;;;AAG8B;;;;;;;;;;;;EAf9B,WAAA,GAAc,WAAA;EAEd,aAAA,GAAgB,aAAA;;;;;;;;;;EAUhB,MAAA,GAAS,cAAA,GAAiB,wBAAA;EAG1B,EAAA,GAAK,yBAAA;AAAA"}
1
+ {"version":3,"file":"orchestrator-config.type.d.mts","names":[],"sources":["../../../../../../../../ai/src/contracts/orchestrator/orchestrator-config.type.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AA2BA;;;;;;KAAY,eAAA;EAeE,qEAbZ,UAAA,WAEA;EAAA,IAAA,WAEa;EAAb,UAAA,GAAa,aAAA;EAOC;;;;;EADd,SAAA,IACE,UAAA,EAAY,gBAAA,EACZ,GAAA;IAAO,SAAA;EAAA,MACJ,OAAA,eAEW;EAAhB,IAAA;IAAS,OAAA;EAAA;AAAA;;;;;;;KASC,iBAAA,IACV,OAAA,EAAS,OAAA,OACN,OAAA,CAAQ,gBAAA,IAAoB,gBAAA;;;;;AAAgB;AASjD;;KAAY,uBAAA,4BAGN,SAAiB;;AAAA;AAyBvB;;;;;;;;;;;;;;;;;;;;;KAAY,wBAAA;EAkDD,gFAhDT,KAAA,EAAO,cAAA;EA4EG;;;;;;;;;;;;;;;;;EA1DV,KAAA,GAAQ,uBAAA;EAsF0B;;;;;;EA/ElC,MAAA;IACE,CAAA;IACA,SAAA;IACA,IAAA,GAAO,UAAA;EAAA;EAuGuB;;;;;;EA/FhC,QAAA;EA2IS;;;;;EArIT,YAAA,GAAe,UAAA;EAoCf;;;;;EA9BA,SAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;KA4BU,kBAAA,mBAED,OAAA,mBACQ,MAAA,SAAe,qBAAA,IAAyB,MAAA,SAEvD,qBAAA;EA6BF,wEAzBA,IAAA,UA2BA;EAzBA,OAAA;EAyB0B;;;;;;;EAjB1B,OAAA,GAAU,iBAAA,EAmCoC;EAjC9C,YAAA,GAAe,oBAAA,WAkCiB;EA/BhC,OAAA,EAAS,QAAA,EA+BqC;EA7B9C,KAAA,IAAS,GAAA,EAAK,YAAA,CAAa,MAAA,MAAY,IAAA,GAAO,OAAA,CAAQ,IAAA,GAgC1C;EA9BZ,MAAA,GAAS,aAAA,YAAyB,WAAA,CAAY,MAAA,GAgC9C;EA9BA,QAAA,IACE,GAAA,EAAK,eAAA,CAAgB,MAAA,MAClB,cAAA,GAAiB,OAAA,CAAQ,cAAA,GA+BZ;EA7BlB,KAAA,GAAQ,MAAA,EAgDM;EA9Cd,MAAA,GAAS,gBAAA,CAAiB,OAAA,GAgDV;EA9ChB,YAAA,WA6DS;EA3DT,aAAA;EA8DA;;;AAA8B;;EAvD9B,OAAA;;;;;;EAMA,aAAA;IACE,MAAA,cAAoB,QAAA,EAAU,OAAA,OAAc,OAAA;IAC5C,MAAA,cAAoB,QAAA,EAAU,OAAA,OAAc,OAAA;EAAA;EAG9C,SAAA,GAAY,eAAA,GAAkB,iBAAA;EAE9B,aAAA;EAGA,eAAA,GAAkB,eAAA;;;;;;;;;;;;;;;;;;;EAmBlB,WAAA,GAAc,WAAA;EAEd,aAAA,GAAgB,aAAA;;;;;;;;;;;;;;;EAehB,MAAA,GAAS,cAAA,GAAiB,wBAAA;EAG1B,EAAA,GAAK,yBAAA;AAAA"}
@@ -1,4 +1,6 @@
1
+ import { Message } from "../conversation-message.type.mjs";
1
2
  import { StreamContract } from "../stream/stream.contract.mjs";
3
+ import { ToolContext } from "../tool.contract.mjs";
2
4
  import { ToolContract } from "../../tool/tool.mjs";
3
5
  import { SupervisorInput } from "../supervisor/supervisor-input.type.mjs";
4
6
  import { OrchestratorResult } from "../result/orchestrator-result.type.mjs";
@@ -14,11 +16,42 @@ import { StandardSchemaV1 } from "@standard-schema/spec";
14
16
  *
15
17
  * - `"fresh"` (default) — every tool invocation gets a brand-new
16
18
  * `sessionId`; no continuity across calls. Safe default.
17
- * - `"shared"` — the wrapped orchestrator participates in the parent's
18
- * session; the `sessionId` is supplied via the tool's `inputSchema`
19
- * payload. Expert escape hatch for nested-conversation use cases.
19
+ * - `"shared"` — the wrapped orchestrator participates in an existing
20
+ * session. The target `sessionId` comes from the DEVELOPER, via
21
+ * `OrchestratorAsToolOptions.session` (a fixed id bound at
22
+ * construction, or a resolver reading the out-of-band
23
+ * {@link ToolContext}) — never from the model's tool-call arguments.
24
+ * Expert escape hatch for nested-conversation use cases.
20
25
  */
21
26
  type OrchestratorSessionScope = "fresh" | "shared";
27
+ /**
28
+ * Where a `sessionScope: "shared"` tool call gets its session from
29
+ * (4.15.0 — security fix).
30
+ *
31
+ * A `sessionId` is bearer-equivalent: whoever names one gets read/write
32
+ * access to that session's persisted state and history. It must
33
+ * therefore be bound OUTSIDE the model-visible `inputSchema` — either as
34
+ * a literal string fixed at `asTool()` construction, or as a resolver
35
+ * that reads the invocation's {@link ToolContext} (the same out-of-band
36
+ * channel `signal` and `artifacts` travel on, which an LLM cannot write
37
+ * to). Returning `history` lets the developer thread prior turns the
38
+ * same way.
39
+ *
40
+ * @example
41
+ * // Bound per request: the app puts the authenticated user's session on
42
+ * // the tool-call artifacts bag; the model never sees or picks it.
43
+ * const tool = support.asTool({
44
+ * inputSchema: v.object({ message: v.string() }),
45
+ * sessionScope: "shared",
46
+ * session: (ctx) => String(ctx?.artifacts?.supportSessionId ?? ""),
47
+ * });
48
+ */
49
+ type OrchestratorToolSession = string | ((ctx: ToolContext | undefined) => string | OrchestratorToolSessionBinding | undefined | Promise<string | OrchestratorToolSessionBinding | undefined>);
50
+ /** Resolved session binding for a shared-scope tool call. */
51
+ type OrchestratorToolSessionBinding = {
52
+ /** Session the nested orchestrator joins. Must be non-empty. */sessionId: string; /** Prior turns to seed the nested run with. Defaults to `[]`. */
53
+ history?: Message[];
54
+ };
22
55
  /**
23
56
  * Context overrides for a specific session.
24
57
  *
@@ -46,6 +79,37 @@ type OrchestratorAsToolOptions<TToolInput = string> = {
46
79
  description?: string;
47
80
  inputSchema: StandardSchemaV1<TToolInput>; /** Session continuity for tool calls. Default `"fresh"`. */
48
81
  sessionScope?: OrchestratorSessionScope;
82
+ /**
83
+ * Which session a `sessionScope: "shared"` call joins — REQUIRED for
84
+ * that scope (4.15.0), and ignored for `"fresh"`.
85
+ *
86
+ * Bind it at construction (a literal id) or per call from the
87
+ * {@link ToolContext} (a resolver). Both channels are invisible to the
88
+ * model, which is the point: the previous release read `sessionId`
89
+ * straight off the validated tool payload, so a prompt-injected outer
90
+ * agent could name a VICTIM's session and have the nested orchestrator
91
+ * load, mutate, and echo back their conversation.
92
+ *
93
+ * Constructing a `"shared"` tool with neither this nor
94
+ * {@link unsafeAllowModelSessionId} throws.
95
+ */
96
+ session?: OrchestratorToolSession;
97
+ /**
98
+ * DANGEROUS opt-in: restore the pre-4.15.0 behavior of reading
99
+ * `sessionId` / `history` out of the model-generated tool payload.
100
+ *
101
+ * The value is a **bearer token for that session** — anything that can
102
+ * influence the calling model's output (an injected document, a web
103
+ * page it summarized, a poisoned tool result) can name any session id
104
+ * it can guess or has seen, and the nested orchestrator will load that
105
+ * session's state, run a turn against it, and return its content to
106
+ * the outer transcript.
107
+ *
108
+ * Only set this when the outer agent's context is fully trusted AND
109
+ * your `execute` path independently verifies the model-chosen
110
+ * `sessionId` belongs to the current caller. Prefer {@link session}.
111
+ */
112
+ unsafeAllowModelSessionId?: boolean;
49
113
  };
50
114
  /**
51
115
  * Runtime handle returned by `ai.orchestrator(config)` (design §15.3) —
@@ -1 +1 @@
1
- {"version":3,"file":"orchestrator.contract.d.mts","names":[],"sources":["../../../../../../../../ai/src/contracts/orchestrator/orchestrator.contract.ts"],"mappings":";;;;;;;;;;;;AA0BA;;;;AAAoC;AAapC;;;KAbY,wBAAA;AAcE;AAWd;;;;;;;;;;AAXc,KADF,uBAAA;EAAA,CACT,GAAW;AAAA;;;;;AAgB2B;AAgCzC;;;KArCY,yBAAA;EACV,IAAA;EACA,WAAA;EACA,WAAA,EAAa,gBAAA,CAAiB,UAAA,GAkDA;EAhD9B,YAAA,GAAe,wBAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAgCA,oBAAA,6BAAiD,OAAA;EAwErD;EAAA,SAtEF,IAAA;EAsE0B;EAAA,SApE1B,SAAA;EAJ8C;EAAA,SAM9C,OAAA;EAJA;;;;;EAWT,OAAA,CACE,KAAA,EAAO,eAAA,EACP,OAAA,EAAS,0BAAA,CAA2B,MAAA,IACnC,OAAA,CAAQ,kBAAA,CAAmB,OAAA;EADnB;;;;;EAQX,MAAA,CACE,KAAA,EAAO,eAAA,EACP,OAAA,EAAS,0BAAA,CAA2B,MAAA,IACnC,cAAA,CAAe,kBAAA,CAAmB,OAAA,GAAU,iBAAA;EAH/C;;;;;EAUA,MAAA,CACE,SAAA,UACA,OAAA,GAAU,yBAAA,GACT,OAAA,CAAQ,kBAAA,CAAmB,OAAA;EAV3B;;;;;EAiBH,OAAA,iBAAwB,oBAAA,EACtB,IAAA,EAAM,CAAA,EACN,IAAA,EAAM,oBAAA,CAAqB,CAAA,YAC1B,OAAA,CAAQ,oBAAA,CAAqB,CAAA;EAXpB;;;;;EAkBZ,MAAA,sBACE,OAAA,EAAS,yBAAA,CAA0B,UAAA,IAClC,YAAA,CAAa,UAAA,EAAY,OAAA;EAZpB;;;;EAkBR,EAAA,WAAa,qBAAA,EACX,KAAA,EAAO,CAAA,EACP,OAAA,EAAS,wBAAA,CAAyB,CAAA;EAlBP;;;;EAyB7B,GAAA,WAAc,qBAAA,EACZ,KAAA,EAAO,CAAA,EACP,OAAA,EAAS,wBAAA,CAAyB,CAAA;AAAA"}
1
+ {"version":3,"file":"orchestrator.contract.d.mts","names":[],"sources":["../../../../../../../../ai/src/contracts/orchestrator/orchestrator.contract.ts"],"mappings":";;;;;;;;;;;;;;AA+BA;;;;AAAoC;AAwBpC;;;;;;KAxBY,wBAAA;;;;;;;;;AA8B2C;AAGvD;;;;;;;;AAImB;AAcnB;;;;KA3BY,uBAAA,cAEN,GAAA,EAAK,WAAA,0BAEH,8BAAA,eAEA,OAAA,UAAiB,8BAAA;AAiCzB;AAAA,KA9BY,8BAAA;EA8ByB,gEA5BnC,SAAA,UA+Ba;EA7Bb,OAAA,GAAU,OAAO;AAAA;;;;;;;;;;;;KAcP,uBAAA;EAAA,CACT,GAAW;AAAA;AA+Ca;AAgC3B;;;;;;;AAhC2B,KApCf,yBAAA;EACV,IAAA;EACA,WAAA;EACA,WAAA,EAAa,gBAAA,CAAiB,UAAA,GA0FQ;EAxFtC,YAAA,GAAe,wBAAA;EAyFsB;;;;;;;;;;;;;;EA1ErC,OAAA,GAAU,uBAAA;EAsG2B;;;;;;;;;;;;;;;EAtFrC,yBAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAgCe,oBAAA,6BAAiD,OAAA;EA2ChE;EAAA,SAzCS,IAAA;EAyCe;EAAA,SAvCf,SAAA;EAwCP;EAAA,SAtCO,OAAA;EAuCoB;;;;;EAhC7B,OAAA,CACE,KAAA,EAAO,eAAA,EACP,OAAA,EAAS,0BAAA,CAA2B,MAAA,IACnC,OAAA,CAAQ,kBAAA,CAAmB,OAAA;EAqCvB;;;;;EA9BP,MAAA,CACE,KAAA,EAAO,eAAA,EACP,OAAA,EAAS,0BAAA,CAA2B,MAAA,IACnC,cAAA,CAAe,kBAAA,CAAmB,OAAA,GAAU,iBAAA;EA6BnB;;;;;EAtB5B,MAAA,CACE,SAAA,UACA,OAAA,GAAU,yBAAA,GACT,OAAA,CAAQ,kBAAA,CAAmB,OAAA;EA2BnB;;;;;EApBX,OAAA,iBAAwB,oBAAA,EACtB,IAAA,EAAM,CAAA,EACN,IAAA,EAAM,oBAAA,CAAqB,CAAA,YAC1B,OAAA,CAAQ,oBAAA,CAAqB,CAAA;EAyBvB;;;;;EAlBT,MAAA,sBACE,OAAA,EAAS,yBAAA,CAA0B,UAAA,IAClC,YAAA,CAAa,UAAA,EAAY,OAAA;EAiBU;;;;EAXtC,EAAA,WAAa,qBAAA,EACX,KAAA,EAAO,CAAA,EACP,OAAA,EAAS,wBAAA,CAAyB,CAAA;;;;;EAOpC,GAAA,WAAc,qBAAA,EACZ,KAAA,EAAO,CAAA,EACP,OAAA,EAAS,wBAAA,CAAyB,CAAA;AAAA"}
@@ -212,6 +212,29 @@ type SupervisorConfig<TOutput = unknown, TState = TOutput, TIntents extends Reco
212
212
  * with `MaxIterationsError` on `result.error`. Default: `10`.
213
213
  */
214
214
  maxIterations?: number;
215
+ /**
216
+ * Hard cap on fan-out WIDTH — how many intents a single dispatch
217
+ * decision may run in parallel. Default: `10`.
218
+ *
219
+ * Routing decisions arrive as `string[]` from an LLM `router`, a
220
+ * `route` callback, `evaluate.reassignTo`, or per-intent `next`
221
+ * directives. Duplicate names in that array are collapsed before
222
+ * dispatch (they were pure wasted spend — `indexByIntent` already
223
+ * kept only one result per intent); if the DEDUPED list is still
224
+ * longer than this cap, the decision is rejected with
225
+ * `SupervisorRoutingError` (`SUPERVISOR_INVALID_ROUTE`), the same
226
+ * way an unknown intent key is.
227
+ *
228
+ * Security note: the router's per-turn prompt embeds supervisor
229
+ * `state` and prior branch outputs, so a prompt injection carried
230
+ * in tool output can coax the router into emitting a very wide
231
+ * `next` array — one iteration then launches that many real
232
+ * agent/workflow runs (cost + compute amplification). This cap is
233
+ * the width bound that `maxIterations` (a depth bound) doesn't
234
+ * provide. Raise it deliberately when a supervisor legitimately
235
+ * fans out wide (e.g. `ai.fanOut(writer, 20)`).
236
+ */
237
+ maxFanOut?: number;
215
238
  /**
216
239
  * When set, turn 0 dispatches this intent directly and skips the
217
240
  * first router/route call. Must be a key in `intents`.
@@ -1 +1 @@
1
- {"version":3,"file":"supervisor-config.type.d.mts","names":[],"sources":["../../../../../../../../ai/src/contracts/supervisor/supervisor-config.type.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;AAqBA;;KAAY,sBAAA,iBAAuC,kBAAA,KACjD,OAAA,EAAS,kBAAA,CAAmB,CAAA;AAAA,KAGlB,uBAAA,GAA0B,OAAA,eACxB,kBAAA,GAAqB,sBAAA,CAAuB,CAAA;;;;;;;;;AAJ1B;AAGhC;;;;;;;;;;;;;;;AAC2D;AAyC3D;;;;;;;;;;;;;KAAY,gBAAA,6BAED,OAAA,mBACQ,MAAA,SAAe,qBAAA,IAAyB,MAAA,SAAe,qBAAA,gBAC3D,MAAA;EAiHJ,sEA9GT,IAAA;EA8GkC;;;;;;;;EApGlC,OAAA;EAiI6C;;;;;;;;EAvH7C,UAAA;EAuMM;;;;;;;;;;;EA1LN,WAAA,GAAc,gBAAA,CAAiB,eAAA;EAvC/B;;;;;EA8CA,YAAA,GAAe,oBAAA;EA5C0C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmFzD,IAAA,YAAgB,oBAAA;EAmFhB;;;;;;;;;;;;;;;;;;;EA9DA,OAAA,GAAU,OAAA;EAiNQ;;;;;;;;EAvMlB,MAAA,GAAS,aAAA,YAAyB,WAAA,CAAY,MAAA;EA2PgB;;;;EArP9D,KAAA,IAAS,GAAA,EAAK,YAAA,CAAa,MAAA,MAAY,IAAA,GAAO,OAAA,CAAQ,IAAA;;;;;;;;;;;EAYtD,OAAA,EAAS,QAAA;;;;;;;;;;EAWT,QAAA,IAAY,GAAA,EAAK,eAAA,CAAgB,MAAA,MAAY,cAAA,GAAiB,OAAA,CAAQ,cAAA;;;;;;;;;;;;;;;;EAiBtE,KAAA,GAAQ,MAAA;;;;;EAMR,aAAA;;;;;EAMA,YAAA;;;;;;;;;;;EAYA,MAAA,GAAS,gBAAA,CAAiB,OAAA;;;;;;;;;;;;;EAc1B,aAAA,GAAgB,aAAA;;;;;;EAOhB,EAAA,GAAK,uBAAA;;;;;;;;;;;;;;;;;EAkBL,GAAA,GAAM,SAAA,CAAU,MAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwChB,UAAA,GAAa,gBAAA,CAAiB,MAAA;;;;;;;;;;;;;;;;;;;;;;EAsB9B,aAAA;IACE,MAAA;IACA,MAAA;IACA,GAAA;EAAA;;;;;;;;;;;;;;;;;;;;;;;EAyBF,eAAA,GAAkB,gBAAA,CAAiB,UAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4BnC,UAAA,GAAa,eAAA;;;;;;;;;;;;;;;;;;;;;;;EAwBb,iBAAA,IAAqB,KAAA,EAAO,MAAA,EAAQ,SAAA,EAAW,UAAA,KAAe,MAAA;;;;;;;;;;;;;;;;;;;EAoB9D,OAAA,GAAU,iBAAA;AAAA"}
1
+ {"version":3,"file":"supervisor-config.type.d.mts","names":[],"sources":["../../../../../../../../ai/src/contracts/supervisor/supervisor-config.type.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;AAqBA;;KAAY,sBAAA,iBAAuC,kBAAA,KACjD,OAAA,EAAS,kBAAA,CAAmB,CAAA;AAAA,KAGlB,uBAAA,GAA0B,OAAA,eACxB,kBAAA,GAAqB,sBAAA,CAAuB,CAAA;;;;;;;;;AAJ1B;AAGhC;;;;;;;;;;;;;;;AAC2D;AAyC3D;;;;;;;;;;;;;KAAY,gBAAA,6BAED,OAAA,mBACQ,MAAA,SAAe,qBAAA,IAAyB,MAAA,SAAe,qBAAA,gBAC3D,MAAA;EAiHJ,sEA9GT,IAAA;EA8GkC;;;;;;;;EApGlC,OAAA;EAiI6C;;;;;;;;EAvH7C,UAAA;EA+NM;;;;;;;;;;;EAlNN,WAAA,GAAc,gBAAA,CAAiB,eAAA;EAvC/B;;;;;EA8CA,YAAA,GAAe,oBAAA;EA5C0C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmFzD,IAAA,YAAgB,oBAAA;EAmFhB;;;;;;;;;;;;;;;;;;;EA9DA,OAAA,GAAU,OAAA;EAyOV;;;;;;;;EA/NA,MAAA,GAAS,aAAA,YAAyB,WAAA,CAAY,MAAA;EAmRV;;;;EA7QpC,KAAA,IAAS,GAAA,EAAK,YAAA,CAAa,MAAA,MAAY,IAAA,GAAO,OAAA,CAAQ,IAAA;EAiS3B;;;;;;;;;;EArR3B,OAAA,EAAS,QAAA;;;;;;;;;;EAWT,QAAA,IAAY,GAAA,EAAK,eAAA,CAAgB,MAAA,MAAY,cAAA,GAAiB,OAAA,CAAQ,cAAA;;;;;;;;;;;;;;;;EAiBtE,KAAA,GAAQ,MAAA;;;;;EAMR,aAAA;;;;;;;;;;;;;;;;;;;;;;;EAwBA,SAAA;;;;;EAMA,YAAA;;;;;;;;;;;EAYA,MAAA,GAAS,gBAAA,CAAiB,OAAA;;;;;;;;;;;;;EAc1B,aAAA,GAAgB,aAAA;;;;;;EAOhB,EAAA,GAAK,uBAAA;;;;;;;;;;;;;;;;;EAkBL,GAAA,GAAM,SAAA,CAAU,MAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwChB,UAAA,GAAa,gBAAA,CAAiB,MAAA;;;;;;;;;;;;;;;;;;;;;;EAsB9B,aAAA;IACE,MAAA;IACA,MAAA;IACA,GAAA;EAAA;;;;;;;;;;;;;;;;;;;;;;;EAyBF,eAAA,GAAkB,gBAAA,CAAiB,UAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4BnC,UAAA,GAAa,eAAA;;;;;;;;;;;;;;;;;;;;;;;EAwBb,iBAAA,IAAqB,KAAA,EAAO,MAAA,EAAQ,SAAA,EAAW,UAAA,KAAe,MAAA;;;;;;;;;;;;;;;;;;;EAoB9D,OAAA,GAAU,iBAAA;AAAA"}
@@ -3,6 +3,7 @@ import { FlowObserveOption } from "../../observe/resolve-observers.mjs";
3
3
  import { SnapshotStore } from "../orchestrator/snapshot-store.contract.mjs";
4
4
  import { WorkflowInstance } from "../workflow/workflow.contract.mjs";
5
5
  import { SystemPromptContract } from "../system-prompt.contract.mjs";
6
+ import { IntentCallback } from "../supervisor/intent-entry.type.mjs";
6
7
  import { RouterEntry } from "../supervisor/router-entry.type.mjs";
7
8
  import { SupervisorConfig, SupervisorEventHandlers } from "../supervisor/supervisor-config.type.mjs";
8
9
  import { EvaluateContext, EvaluateResult } from "../supervisor/evaluate-context.type.mjs";
@@ -10,13 +11,15 @@ import { StandardSchemaV1 } from "@standard-schema/spec";
10
11
 
11
12
  //#region ../ai/src/contracts/team/team-config.type.d.ts
12
13
  /**
13
- * A role member — an agent or a workflow. The same shorthand the
14
- * supervisor accepts on each `intents` value, narrowed to the two
15
- * dispatchable unit shapes `team()` forwards verbatim. (Callback /
16
- * full-entry intent shapes still work when forwarded this alias is
17
- * the documented, autocomplete-friendly subset for the common case.)
14
+ * A role member — an agent, a workflow, or an inline callback. Every
15
+ * `members` value is forwarded verbatim as a supervisor `intents`
16
+ * value, so the callback form dispatches exactly like a callback
17
+ * intent; it is listed here because the runtime has always accepted
18
+ * it. The richer `IntentEntry` / `IntentRunEntry` object forms are
19
+ * deliberately left out — `team()` names its roles by key, and the
20
+ * per-entry overrides belong to `supervisor()`.
18
21
  */
19
- type TeamMemberValue = AgentContract<unknown> | WorkflowInstance<unknown, unknown>;
22
+ type TeamMemberValue = AgentContract<unknown> | WorkflowInstance<unknown, unknown> | IntentCallback;
20
23
  /**
21
24
  * The built-in quality-gate strategies. Each desugars to a concrete
22
25
  * {@link SupervisorConfig.evaluate} callback — no new loop or
@@ -1 +1 @@
1
- {"version":3,"file":"team-config.type.d.mts","names":[],"sources":["../../../../../../../../ai/src/contracts/team/team-config.type.ts"],"mappings":";;;;;;;;;;;;;AAiBA;;;;AAEoB;KAFR,eAAA,GACR,aAAA,YACA,gBAAgB;;;;AAiBA;AASpB;;;;;;;;;;;KATY,QAAA;;;;;;;AAWgC;KAFhC,UAAA,YACV,GAAA,EAAK,eAAA,CAAgB,MAAA,MAClB,cAAA,GAAiB,OAAA,CAAQ,cAAA;;;;;;;;;;;;;;;;;;;;KAqBlB,UAAA,6BAED,OAAA,mBACQ,MAAA,SAAe,eAAA,IAAmB,MAAA,SAAe,eAAA;EA+CjD,yEA5CjB,IAAA,UA6D0B;EA1D1B,OAAA;EA6DQ;;;;;;;;EAnDR,OAAA,EACI,aAAA,YACA,WAAA,CAAY,MAAA;IACV,KAAA,EAAO,WAAA,CAAY,gBAAA,CAAiB,OAAA,EAAS,MAAA;EAAA;EAnBnB;;;;;;EA2BhC,OAAA,EAAS,QAAA;EATL;;;;;;EAiBJ,IAAA,EAAM,QAAA,GAAW,UAAA,CAAW,MAAA;EAR5B;;;;;;;EAiBA,KAAA;IACE,QAAA,SAAiB,QAAA;IACjB,KAAA,SAAc,QAAA;IACd,MAAA,SAAe,QAAA;EAAA;EAAA;;;;;;EASjB,OAAA,WAWA;EANA,IAAA,YAAgB,oBAAA,EAShB;EANA,MAAA,GAAS,gBAAA,CAAiB,OAAA,GASV;EANhB,KAAA,GAAQ,MAAA,EASH;EANL,aAAA,WAeU;EAZV,aAAA,GAAgB,aAAA,EAYW;EAT3B,EAAA,GAAK,uBAAA;;;;;;;;EASL,OAAA,GAAU,iBAAA;AAAA"}
1
+ {"version":3,"file":"team-config.type.d.mts","names":[],"sources":["../../../../../../../../ai/src/contracts/team/team-config.type.ts"],"mappings":";;;;;;;;;;;;;;AAoBA;;;;;;;KAAY,eAAA,GACR,aAAA,YACA,gBAAA,qBACA,cAAA;;;;;AAAc;AAiBlB;;;;AAAoB;AASpB;;;;;KATY,QAAA;;;;;;;;KASA,UAAA,YACV,GAAA,EAAK,eAAA,CAAgB,MAAA,MAClB,cAAA,GAAiB,OAAA,CAAQ,cAAA;;;;;AAAc;AAqB5C;;;;;;;;;;;;;;KAAY,UAAA,6BAED,OAAA,mBACQ,MAAA,SAAe,eAAA,IAAmB,MAAA,SAAe,eAAA;EA2BzD,yEAxBT,IAAA,UAgC4B;EA7B5B,OAAA;EAuCmB;;;;;;;;EA7BnB,OAAA,EACI,aAAA,YACA,WAAA,CAAY,MAAA;IACV,KAAA,EAAO,WAAA,CAAY,gBAAA,CAAiB,OAAA,EAAS,MAAA;EAAA;EAkExB;;;;;;EA1D3B,OAAA,EAAS,QAAA;EA3B0C;;;;;;EAmCnD,IAAA,EAAM,QAAA,GAAW,UAAA,CAAW,MAAA;EAjBZ;;;;;;;EA0BhB,KAAA;IACE,QAAA,SAAiB,QAAA;IACjB,KAAA,SAAc,QAAA;IACd,MAAA,SAAe,QAAA;EAAA;EAHjB;;;;;;EAYA,OAAA;EAKA,IAAA,YAAgB,oBAAA,EAAA;EAGhB,MAAA,GAAS,gBAAA,CAAiB,OAAA,GAAjB;EAGT,KAAA,GAAQ,MAAA,EAAR;EAGA,aAAA;EAGA,aAAA,GAAgB,aAAA,EAAA;EAGhB,EAAA,GAAK,uBAAA;EAAA;;;;AASsB;;;EAA3B,OAAA,GAAU,iBAAA;AAAA"}
@@ -4,10 +4,18 @@ import { StandardSchemaV1 } from "@standard-schema/spec";
4
4
  /**
5
5
  * Optional metadata attached to a tool for documentation and tooling.
6
6
  *
7
+ * Free-form: any key is accepted. `label` and `actionLabel` are named
8
+ * explicitly only so editors suggest them — both are optional, like
9
+ * every other key.
10
+ *
7
11
  * @example
8
12
  * const meta: ToolMeta = { category: "search", version: "1.0" };
9
13
  */
10
- type ToolMeta = Record<"label" | "actionLabel" | (string & {}), unknown>;
14
+ type ToolMeta = {
15
+ /** Human-readable name for the tool in documentation and tooling UIs. */label?: unknown; /** Human-readable name for the action the tool performs. */
16
+ actionLabel?: unknown;
17
+ [key: string]: unknown;
18
+ };
11
19
  /**
12
20
  * Discriminated mode controlling whether the tool's result feeds back
13
21
  * to the model.
@@ -43,6 +51,30 @@ type ToolMeta = Record<"label" | "actionLabel" | (string & {}), unknown>;
43
51
  * → terminate" rule only kicks in when EVERY tool call is silent.
44
52
  */
45
53
  type ToolMode = "feedback" | "silent";
54
+ /**
55
+ * Callback form of {@link ToolConfig.action} — turns the model's
56
+ * arguments into a present-progressive UI string.
57
+ *
58
+ * Written as a method inside a wrapper object (then indexed back out)
59
+ * so TypeScript checks `input` **bivariantly** instead of
60
+ * contravariantly. That is deliberate, and it is what the runtime
61
+ * actually does: the dispatch boundary resolves the label from the
62
+ * model's *raw, pre-validation* arguments, so it hands the callback an
63
+ * `unknown` while the author declares the shape they expect. Under the
64
+ * default strict (contravariant) function check a
65
+ * `ToolContract<{ query: string }, …>` would not be assignable to
66
+ * `ToolContract<unknown, unknown>`, which is the type every
67
+ * heterogeneous tool list — `AgentConfig.tools`, supervisor tool
68
+ * registries — has to use.
69
+ *
70
+ * The bivariance is not free: `input` is whatever the model emitted,
71
+ * not a validated `TInput`. Resolution is wrapped in a try/catch at
72
+ * the boundary precisely because this callback can throw on malformed
73
+ * arguments; a throw costs the label, never the dispatch.
74
+ */
75
+ type ToolActionResolver<TInput> = {
76
+ resolveAction(input: TInput): string;
77
+ }["resolveAction"];
46
78
  /**
47
79
  * Per-call context threaded into a tool handler as the optional second
48
80
  * argument (Phase 5 / decisions §35).
@@ -130,7 +162,7 @@ interface ToolConfig<TInput = unknown, TOutput = unknown> {
130
162
  * Resolved at the framework boundary; consumers receive a
131
163
  * pre-resolved string in `ToolEventMeta.action`.
132
164
  */
133
- action?: string | ((input: TInput) => string);
165
+ action?: string | ToolActionResolver<TInput>;
134
166
  /** Optional metadata for documentation or tooling */
135
167
  meta?: ToolMeta;
136
168
  /**
@@ -159,5 +191,5 @@ interface ToolConfig<TInput = unknown, TOutput = unknown> {
159
191
  execute(input: TInput, ctx?: ToolContext): Promise<TOutput>;
160
192
  }
161
193
  //#endregion
162
- export { ToolConfig, ToolContext, ToolMeta, ToolMode };
194
+ export { ToolActionResolver, ToolConfig, ToolContext, ToolMeta, ToolMode };
163
195
  //# sourceMappingURL=tool.contract.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tool.contract.d.mts","names":[],"sources":["../../../../../../../ai/src/contracts/tool.contract.ts"],"mappings":";;;;;AAQA;;;;KAAY,QAAA,GAAW,MAAM;AAoC7B;;;;AAAoB;AAmCpB;;;;;;;;;;;;;;;AASsB;AAiBtB;;;;;;;;;;;;;AA7DA,KAAY,QAAA;;;;;;;;;;;;;;;;;;;;;;;;AAqHgD;;;;;;;;;;KAlFhD,WAAA,cAAyB,MAAA;;;;;;;EAOnC,SAAA,EAAW,UAAA;EAEX,MAAA,GAAS,WAAA;AAAA;;;;;;;;;;;;;;;UAiBM,UAAA;;EAEf,IAAA;;EAEA,WAAA;;;;;;;;EAQA,OAAA;;;;;;;;;;;;;;;;;;EAkBA,MAAA,cAAoB,KAAA,EAAO,MAAA;;EAE3B,IAAA,GAAO,QAAA;;;;;;;EAOP,IAAA,GAAO,QAAA;;;;;;EAMP,KAAA,GAAQ,gBAAA,CAAiB,MAAA;;;;;;;;;;;EAWzB,OAAA,CAAQ,KAAA,EAAO,MAAA,EAAQ,GAAA,GAAM,WAAA,GAAc,OAAA,CAAQ,OAAA;AAAA"}
1
+ {"version":3,"file":"tool.contract.d.mts","names":[],"sources":["../../../../../../../ai/src/contracts/tool.contract.ts"],"mappings":";;;;;AAYA;;;;;;;;KAAY,QAAA;EA0CA,yEAxCV,KAAA;EAEA,WAAA;EAAA,CACC,GAAA;AAAA;;;;;;;;;AA6D0B;AAoC7B;;;;;;;;;;;;;;;AASsB;AAiBtB;;;;;;;;;KAtFY,QAAA;;;;;;;;;;;;;;;;;;;;;;KAuBA,kBAAA;EACV,aAAA,CAAc,KAAA,EAAO,MAAM;AAAA;;;;;AAsH+B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAlFhD,WAAA,cAAyB,MAAA;;;;;;;EAOnC,SAAA,EAAW,UAAA;EAEX,MAAA,GAAS,WAAA;AAAA;;;;;;;;;;;;;;;UAiBM,UAAA;;EAEf,IAAA;;EAEA,WAAA;;;;;;;;EAQA,OAAA;;;;;;;;;;;;;;;;;;EAkBA,MAAA,YAAkB,kBAAA,CAAmB,MAAA;;EAErC,IAAA,GAAO,QAAA;;;;;;;EAOP,IAAA,GAAO,QAAA;;;;;;EAMP,KAAA,GAAQ,gBAAA,CAAiB,MAAA;;;;;;;;;;;EAWzB,OAAA,CAAQ,KAAA,EAAO,MAAA,EAAQ,GAAA,GAAM,WAAA,GAAc,OAAA,CAAQ,OAAA;AAAA"}