agentfootprint 2.4.0 → 2.5.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 (187) hide show
  1. package/README.md +21 -3
  2. package/dist/adapters/llm/AnthropicProvider.js +2 -2
  3. package/dist/adapters/llm/AnthropicProvider.js.map +1 -1
  4. package/dist/adapters/llm/BedrockProvider.js +2 -2
  5. package/dist/adapters/llm/BedrockProvider.js.map +1 -1
  6. package/dist/adapters/llm/BrowserAnthropicProvider.js +96 -28
  7. package/dist/adapters/llm/BrowserAnthropicProvider.js.map +1 -1
  8. package/dist/adapters/llm/OpenAIProvider.js +2 -2
  9. package/dist/adapters/llm/OpenAIProvider.js.map +1 -1
  10. package/dist/adapters/memory/agentcore.js +9 -3
  11. package/dist/adapters/memory/agentcore.js.map +1 -1
  12. package/dist/adapters/memory/redis.js +9 -3
  13. package/dist/adapters/memory/redis.js.map +1 -1
  14. package/dist/core/Agent.js +477 -79
  15. package/dist/core/Agent.js.map +1 -1
  16. package/dist/core/flowchartAsTool.js +188 -0
  17. package/dist/core/flowchartAsTool.js.map +1 -0
  18. package/dist/core/outputSchema.js +119 -0
  19. package/dist/core/outputSchema.js.map +1 -0
  20. package/dist/core/slots/buildSystemPromptSlot.js +8 -0
  21. package/dist/core/slots/buildSystemPromptSlot.js.map +1 -1
  22. package/dist/core/slots/buildToolsSlot.js +56 -5
  23. package/dist/core/slots/buildToolsSlot.js.map +1 -1
  24. package/dist/esm/adapters/llm/AnthropicProvider.js +2 -2
  25. package/dist/esm/adapters/llm/AnthropicProvider.js.map +1 -1
  26. package/dist/esm/adapters/llm/BedrockProvider.js +2 -2
  27. package/dist/esm/adapters/llm/BedrockProvider.js.map +1 -1
  28. package/dist/esm/adapters/llm/BrowserAnthropicProvider.js +96 -28
  29. package/dist/esm/adapters/llm/BrowserAnthropicProvider.js.map +1 -1
  30. package/dist/esm/adapters/llm/OpenAIProvider.js +2 -2
  31. package/dist/esm/adapters/llm/OpenAIProvider.js.map +1 -1
  32. package/dist/esm/adapters/memory/agentcore.js +9 -3
  33. package/dist/esm/adapters/memory/agentcore.js.map +1 -1
  34. package/dist/esm/adapters/memory/redis.js +9 -3
  35. package/dist/esm/adapters/memory/redis.js.map +1 -1
  36. package/dist/esm/core/Agent.js +476 -78
  37. package/dist/esm/core/Agent.js.map +1 -1
  38. package/dist/esm/core/flowchartAsTool.js +184 -0
  39. package/dist/esm/core/flowchartAsTool.js.map +1 -0
  40. package/dist/esm/core/outputSchema.js +113 -0
  41. package/dist/esm/core/outputSchema.js.map +1 -0
  42. package/dist/esm/core/slots/buildSystemPromptSlot.js +8 -0
  43. package/dist/esm/core/slots/buildSystemPromptSlot.js.map +1 -1
  44. package/dist/esm/core/slots/buildToolsSlot.js +56 -5
  45. package/dist/esm/core/slots/buildToolsSlot.js.map +1 -1
  46. package/dist/esm/index.js +34 -5
  47. package/dist/esm/index.js.map +1 -1
  48. package/dist/esm/lib/injection-engine/SkillRegistry.js +98 -0
  49. package/dist/esm/lib/injection-engine/SkillRegistry.js.map +1 -1
  50. package/dist/esm/lib/injection-engine/factories/defineSkill.js +1 -0
  51. package/dist/esm/lib/injection-engine/factories/defineSkill.js.map +1 -1
  52. package/dist/esm/lib/injection-engine/index.js +7 -0
  53. package/dist/esm/lib/injection-engine/index.js.map +1 -1
  54. package/dist/esm/lib/injection-engine/skillTools.js +125 -0
  55. package/dist/esm/lib/injection-engine/skillTools.js.map +1 -0
  56. package/dist/esm/lib/injection-engine/types.js +8 -0
  57. package/dist/esm/lib/injection-engine/types.js.map +1 -1
  58. package/dist/esm/lib/lazyRequire.js +33 -0
  59. package/dist/esm/lib/lazyRequire.js.map +1 -0
  60. package/dist/esm/lib/mcp/mcpClient.js +4 -6
  61. package/dist/esm/lib/mcp/mcpClient.js.map +1 -1
  62. package/dist/esm/llm-providers.js +31 -0
  63. package/dist/esm/llm-providers.js.map +1 -0
  64. package/dist/esm/locales/index.js +144 -0
  65. package/dist/esm/locales/index.js.map +1 -0
  66. package/dist/esm/memory-providers.js +44 -0
  67. package/dist/esm/memory-providers.js.map +1 -0
  68. package/dist/esm/providers.js +11 -0
  69. package/dist/esm/providers.js.map +1 -1
  70. package/dist/esm/recorders/core/contextEngineering.js +155 -0
  71. package/dist/esm/recorders/core/contextEngineering.js.map +1 -0
  72. package/dist/esm/recorders/observability/commentary/commentaryTemplates.js +6 -1
  73. package/dist/esm/recorders/observability/commentary/commentaryTemplates.js.map +1 -1
  74. package/dist/esm/security/PermissionPolicy.js +135 -0
  75. package/dist/esm/security/PermissionPolicy.js.map +1 -0
  76. package/dist/esm/security/index.js +38 -0
  77. package/dist/esm/security/index.js.map +1 -0
  78. package/dist/esm/tool-providers/gatedTools.js +52 -0
  79. package/dist/esm/tool-providers/gatedTools.js.map +1 -0
  80. package/dist/esm/tool-providers/index.js +43 -0
  81. package/dist/esm/tool-providers/index.js.map +1 -0
  82. package/dist/esm/tool-providers/skillScopedTools.js +63 -0
  83. package/dist/esm/tool-providers/skillScopedTools.js.map +1 -0
  84. package/dist/esm/tool-providers/staticTools.js +33 -0
  85. package/dist/esm/tool-providers/staticTools.js.map +1 -0
  86. package/dist/esm/tool-providers/types.js +53 -0
  87. package/dist/esm/tool-providers/types.js.map +1 -0
  88. package/dist/index.js +55 -12
  89. package/dist/index.js.map +1 -1
  90. package/dist/lib/injection-engine/SkillRegistry.js +98 -0
  91. package/dist/lib/injection-engine/SkillRegistry.js.map +1 -1
  92. package/dist/lib/injection-engine/factories/defineSkill.js +1 -0
  93. package/dist/lib/injection-engine/factories/defineSkill.js.map +1 -1
  94. package/dist/lib/injection-engine/index.js +11 -1
  95. package/dist/lib/injection-engine/index.js.map +1 -1
  96. package/dist/lib/injection-engine/skillTools.js +130 -0
  97. package/dist/lib/injection-engine/skillTools.js.map +1 -0
  98. package/dist/lib/injection-engine/types.js +8 -0
  99. package/dist/lib/injection-engine/types.js.map +1 -1
  100. package/dist/lib/lazyRequire.js +37 -0
  101. package/dist/lib/lazyRequire.js.map +1 -0
  102. package/dist/lib/mcp/mcpClient.js +4 -6
  103. package/dist/lib/mcp/mcpClient.js.map +1 -1
  104. package/dist/llm-providers.js +47 -0
  105. package/dist/llm-providers.js.map +1 -0
  106. package/dist/locales/index.js +149 -0
  107. package/dist/locales/index.js.map +1 -0
  108. package/dist/memory-providers.js +49 -0
  109. package/dist/memory-providers.js.map +1 -0
  110. package/dist/providers.js +11 -0
  111. package/dist/providers.js.map +1 -1
  112. package/dist/recorders/core/contextEngineering.js +161 -0
  113. package/dist/recorders/core/contextEngineering.js.map +1 -0
  114. package/dist/recorders/observability/commentary/commentaryTemplates.js +6 -1
  115. package/dist/recorders/observability/commentary/commentaryTemplates.js.map +1 -1
  116. package/dist/security/PermissionPolicy.js +139 -0
  117. package/dist/security/PermissionPolicy.js.map +1 -0
  118. package/dist/security/index.js +42 -0
  119. package/dist/security/index.js.map +1 -0
  120. package/dist/tool-providers/gatedTools.js +56 -0
  121. package/dist/tool-providers/gatedTools.js.map +1 -0
  122. package/dist/tool-providers/index.js +51 -0
  123. package/dist/tool-providers/index.js.map +1 -0
  124. package/dist/tool-providers/skillScopedTools.js +67 -0
  125. package/dist/tool-providers/skillScopedTools.js.map +1 -0
  126. package/dist/tool-providers/staticTools.js +37 -0
  127. package/dist/tool-providers/staticTools.js.map +1 -0
  128. package/dist/tool-providers/types.js +54 -0
  129. package/dist/tool-providers/types.js.map +1 -0
  130. package/dist/types/adapters/llm/AnthropicProvider.d.ts.map +1 -1
  131. package/dist/types/adapters/llm/BedrockProvider.d.ts.map +1 -1
  132. package/dist/types/adapters/llm/BrowserAnthropicProvider.d.ts.map +1 -1
  133. package/dist/types/adapters/llm/OpenAIProvider.d.ts.map +1 -1
  134. package/dist/types/adapters/memory/agentcore.d.ts +7 -1
  135. package/dist/types/adapters/memory/agentcore.d.ts.map +1 -1
  136. package/dist/types/adapters/memory/redis.d.ts +7 -1
  137. package/dist/types/adapters/memory/redis.d.ts.map +1 -1
  138. package/dist/types/core/Agent.d.ts +202 -2
  139. package/dist/types/core/Agent.d.ts.map +1 -1
  140. package/dist/types/core/flowchartAsTool.d.ts +161 -0
  141. package/dist/types/core/flowchartAsTool.d.ts.map +1 -0
  142. package/dist/types/core/outputSchema.d.ts +128 -0
  143. package/dist/types/core/outputSchema.d.ts.map +1 -0
  144. package/dist/types/core/slots/buildSystemPromptSlot.d.ts.map +1 -1
  145. package/dist/types/core/slots/buildToolsSlot.d.ts +10 -0
  146. package/dist/types/core/slots/buildToolsSlot.d.ts.map +1 -1
  147. package/dist/types/index.d.ts +8 -4
  148. package/dist/types/index.d.ts.map +1 -1
  149. package/dist/types/lib/injection-engine/SkillRegistry.d.ts +98 -0
  150. package/dist/types/lib/injection-engine/SkillRegistry.d.ts.map +1 -1
  151. package/dist/types/lib/injection-engine/factories/defineSkill.d.ts +33 -6
  152. package/dist/types/lib/injection-engine/factories/defineSkill.d.ts.map +1 -1
  153. package/dist/types/lib/injection-engine/index.d.ts +5 -3
  154. package/dist/types/lib/injection-engine/index.d.ts.map +1 -1
  155. package/dist/types/lib/injection-engine/skillTools.d.ts +73 -0
  156. package/dist/types/lib/injection-engine/skillTools.d.ts.map +1 -0
  157. package/dist/types/lib/injection-engine/types.d.ts +18 -0
  158. package/dist/types/lib/injection-engine/types.d.ts.map +1 -1
  159. package/dist/types/lib/lazyRequire.d.ts +30 -0
  160. package/dist/types/lib/lazyRequire.d.ts.map +1 -0
  161. package/dist/types/lib/mcp/mcpClient.d.ts.map +1 -1
  162. package/dist/types/llm-providers.d.ts +31 -0
  163. package/dist/types/llm-providers.d.ts.map +1 -0
  164. package/dist/types/locales/index.d.ts +133 -0
  165. package/dist/types/locales/index.d.ts.map +1 -0
  166. package/dist/types/memory-providers.d.ts +41 -0
  167. package/dist/types/memory-providers.d.ts.map +1 -0
  168. package/dist/types/providers.d.ts +11 -0
  169. package/dist/types/providers.d.ts.map +1 -1
  170. package/dist/types/recorders/core/contextEngineering.d.ts +137 -0
  171. package/dist/types/recorders/core/contextEngineering.d.ts.map +1 -0
  172. package/dist/types/recorders/observability/commentary/commentaryTemplates.d.ts.map +1 -1
  173. package/dist/types/security/PermissionPolicy.d.ts +125 -0
  174. package/dist/types/security/PermissionPolicy.d.ts.map +1 -0
  175. package/dist/types/security/index.d.ts +40 -0
  176. package/dist/types/security/index.d.ts.map +1 -0
  177. package/dist/types/tool-providers/gatedTools.d.ts +37 -0
  178. package/dist/types/tool-providers/gatedTools.d.ts.map +1 -0
  179. package/dist/types/tool-providers/index.d.ts +42 -0
  180. package/dist/types/tool-providers/index.d.ts.map +1 -0
  181. package/dist/types/tool-providers/skillScopedTools.d.ts +46 -0
  182. package/dist/types/tool-providers/skillScopedTools.d.ts.map +1 -0
  183. package/dist/types/tool-providers/staticTools.d.ts +22 -0
  184. package/dist/types/tool-providers/staticTools.d.ts.map +1 -0
  185. package/dist/types/tool-providers/types.d.ts +103 -0
  186. package/dist/types/tool-providers/types.d.ts.map +1 -0
  187. package/package.json +36 -2
@@ -0,0 +1,161 @@
1
+ "use strict";
2
+ /**
3
+ * contextEngineering(agent) — first-class handle on the engineered
4
+ * subset of `context.injected` events.
5
+ *
6
+ * The Block A8 piece. agentfootprint already emits `context.injected`
7
+ * for EVERY piece of content that lands in a slot — including the
8
+ * baseline flow (the user message, every tool result, the static
9
+ * system prompt). For a developer who wants to inspect what their
10
+ * RAG / Skills / Memory / Instructions / Steering / Facts ARE
11
+ * INJECTING (the actual context-engineering work), the baseline flow
12
+ * is noise.
13
+ *
14
+ * `contextEngineering(agent)` filters the stream to ONLY the
15
+ * engineered injections and gives consumers two cleaner subscriptions:
16
+ *
17
+ * - `onEngineered(cb)` — fires for `source` ∈ {rag, skill, memory,
18
+ * instructions, steering, fact, custom}. The actual
19
+ * context-engineering work.
20
+ * - `onBaseline(cb)` — fires for `source` ∈ {user, tool-result,
21
+ * assistant, base, registry}. The baseline message-history flow.
22
+ *
23
+ * Use cases:
24
+ * - **Lens UI**: render only engineered injections in the "context
25
+ * bin"; show the baseline flow as edges between iterations.
26
+ * - **Eval pipelines**: count how many RAG chunks vs Memory entries
27
+ * vs Skill bodies entered the prompt for an eval-set query.
28
+ * - **Cost attribution**: sum tokens by `source` to know what
29
+ * fraction of spend is RAG vs Skills vs baseline.
30
+ * - **Debug logging**: tail just the engineered signals to spot
31
+ * surprising activations during dev.
32
+ *
33
+ * Pattern: Strategy + Filter (GoF) — pure classifier function over
34
+ * the existing `context.injected` event payload, paired with
35
+ * a thin subscription helper.
36
+ *
37
+ * Role: Layer-2 (event taxonomy) consumer-side helper. Doesn't
38
+ * emit new events; doesn't change the agent's flowchart.
39
+ * Pure observation.
40
+ *
41
+ * @example
42
+ * import { contextEngineering } from 'agentfootprint';
43
+ *
44
+ * const ce = contextEngineering(agent);
45
+ * ce.onEngineered((e) => {
46
+ * console.log(`[${e.payload.source}] ${e.payload.contentSummary}`);
47
+ * });
48
+ * ce.onBaseline((e) => {
49
+ * console.log(`[baseline:${e.payload.source}]`);
50
+ * });
51
+ *
52
+ * await agent.run({ message: 'help me' });
53
+ * // ... runs; engineered + baseline streams fire separately
54
+ *
55
+ * ce.detach(); // stops both subscriptions; the agent itself is fine
56
+ */
57
+ Object.defineProperty(exports, "__esModule", { value: true });
58
+ exports.contextEngineering = exports.isBaselineSource = exports.isEngineeredSource = exports.BASELINE_SOURCES = exports.ENGINEERED_SOURCES = void 0;
59
+ /**
60
+ * Public set of "engineered" sources — the context-engineering
61
+ * primitives that consumers configure (RAG, Skills, Memory,
62
+ * Instructions, Steering, Facts) plus user-defined `custom`.
63
+ *
64
+ * Frozen so consumers can `.has(value)` directly without copy.
65
+ */
66
+ exports.ENGINEERED_SOURCES = new Set([
67
+ 'rag',
68
+ 'skill',
69
+ 'memory',
70
+ 'instructions',
71
+ 'steering',
72
+ 'fact',
73
+ 'custom',
74
+ ]);
75
+ /**
76
+ * Public set of "baseline" sources — the message-history flow that
77
+ * exists regardless of context engineering: user input, tool results,
78
+ * assistant outputs, the always-on system prompt anchor (`base`), and
79
+ * the agent's static tool registry advertisement (`registry`).
80
+ */
81
+ exports.BASELINE_SOURCES = new Set([
82
+ 'user',
83
+ 'tool-result',
84
+ 'assistant',
85
+ 'base',
86
+ 'registry',
87
+ ]);
88
+ /**
89
+ * Pure classifier: given a `ContextSource`, is it engineered?
90
+ *
91
+ * Useful for ad-hoc filtering on a raw `agent.on('agentfootprint.context.injected', ...)`
92
+ * subscription when you don't need the wrapper helper.
93
+ */
94
+ function isEngineeredSource(source) {
95
+ return exports.ENGINEERED_SOURCES.has(source);
96
+ }
97
+ exports.isEngineeredSource = isEngineeredSource;
98
+ /**
99
+ * Pure classifier: given a `ContextSource`, is it baseline?
100
+ */
101
+ function isBaselineSource(source) {
102
+ return exports.BASELINE_SOURCES.has(source);
103
+ }
104
+ exports.isBaselineSource = isBaselineSource;
105
+ /**
106
+ * Wrap a runner's `agentfootprint.context.injected` stream into two
107
+ * filtered subscriptions: engineered + baseline. Multiple listeners
108
+ * per stream are allowed; `detach()` removes all of them.
109
+ *
110
+ * The classifier inspects `event.payload.source`. Unknown sources
111
+ * (forward-compat: `ContextSource` is open-extensible) are routed
112
+ * to NEITHER stream — preferring under-firing over miscategorizing.
113
+ * Use `agent.on('agentfootprint.context.injected', ...)` directly
114
+ * if you need to observe sources that aren't (yet) classified.
115
+ */
116
+ function contextEngineering(agent) {
117
+ const unsubscribers = [];
118
+ function onEngineered(listener) {
119
+ const wrapped = (e) => {
120
+ if (isEngineeredSource(e.payload.source))
121
+ listener(e);
122
+ };
123
+ const unsub = agent.on('agentfootprint.context.injected', wrapped);
124
+ unsubscribers.push(unsub);
125
+ return () => {
126
+ unsub();
127
+ const idx = unsubscribers.indexOf(unsub);
128
+ if (idx >= 0)
129
+ unsubscribers.splice(idx, 1);
130
+ };
131
+ }
132
+ function onBaseline(listener) {
133
+ const wrapped = (e) => {
134
+ if (isBaselineSource(e.payload.source))
135
+ listener(e);
136
+ };
137
+ const unsub = agent.on('agentfootprint.context.injected', wrapped);
138
+ unsubscribers.push(unsub);
139
+ return () => {
140
+ unsub();
141
+ const idx = unsubscribers.indexOf(unsub);
142
+ if (idx >= 0)
143
+ unsubscribers.splice(idx, 1);
144
+ };
145
+ }
146
+ function detach() {
147
+ for (const unsub of unsubscribers) {
148
+ try {
149
+ unsub();
150
+ }
151
+ catch {
152
+ // Defensive: a misbehaving subscription's throw should not
153
+ // prevent detaching the rest.
154
+ }
155
+ }
156
+ unsubscribers.length = 0;
157
+ }
158
+ return { onEngineered, onBaseline, detach };
159
+ }
160
+ exports.contextEngineering = contextEngineering;
161
+ //# sourceMappingURL=contextEngineering.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contextEngineering.js","sourceRoot":"","sources":["../../../src/recorders/core/contextEngineering.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;;;AAKH;;;;;;GAMG;AACU,QAAA,kBAAkB,GAA+B,IAAI,GAAG,CAAgB;IACnF,KAAK;IACL,OAAO;IACP,QAAQ;IACR,cAAc;IACd,UAAU;IACV,MAAM;IACN,QAAQ;CACT,CAAC,CAAC;AAEH;;;;;GAKG;AACU,QAAA,gBAAgB,GAA+B,IAAI,GAAG,CAAgB;IACjF,MAAM;IACN,aAAa;IACb,WAAW;IACX,MAAM;IACN,UAAU;CACX,CAAC,CAAC;AAEH;;;;;GAKG;AACH,SAAgB,kBAAkB,CAAC,MAAqB;IACtD,OAAO,0BAAkB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AACxC,CAAC;AAFD,gDAEC;AAED;;GAEG;AACH,SAAgB,gBAAgB,CAAC,MAAqB;IACpD,OAAO,wBAAgB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AACtC,CAAC;AAFD,4CAEC;AAkDD;;;;;;;;;;GAUG;AACH,SAAgB,kBAAkB,CAAC,KAAuB;IACxD,MAAM,aAAa,GAAoC,EAAE,CAAC;IAE1D,SAAS,YAAY,CAAC,QAAiC;QACrD,MAAM,OAAO,GAA4B,CAAC,CAAC,EAAE,EAAE;YAC7C,IAAI,kBAAkB,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;gBAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;QACxD,CAAC,CAAC;QACF,MAAM,KAAK,GAAG,KAAK,CAAC,EAAE,CAAC,iCAAiC,EAAE,OAAO,CAAC,CAAC;QACnE,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC1B,OAAO,GAAG,EAAE;YACV,KAAK,EAAE,CAAC;YACR,MAAM,GAAG,GAAG,aAAa,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YACzC,IAAI,GAAG,IAAI,CAAC;gBAAE,aAAa,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QAC7C,CAAC,CAAC;IACJ,CAAC;IAED,SAAS,UAAU,CAAC,QAAiC;QACnD,MAAM,OAAO,GAA4B,CAAC,CAAC,EAAE,EAAE;YAC7C,IAAI,gBAAgB,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;gBAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;QACtD,CAAC,CAAC;QACF,MAAM,KAAK,GAAG,KAAK,CAAC,EAAE,CAAC,iCAAiC,EAAE,OAAO,CAAC,CAAC;QACnE,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC1B,OAAO,GAAG,EAAE;YACV,KAAK,EAAE,CAAC;YACR,MAAM,GAAG,GAAG,aAAa,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YACzC,IAAI,GAAG,IAAI,CAAC;gBAAE,aAAa,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QAC7C,CAAC,CAAC;IACJ,CAAC;IAED,SAAS,MAAM;QACb,KAAK,MAAM,KAAK,IAAI,aAAa,EAAE,CAAC;YAClC,IAAI,CAAC;gBACH,KAAK,EAAE,CAAC;YACV,CAAC;YAAC,MAAM,CAAC;gBACP,2DAA2D;gBAC3D,8BAA8B;YAChC,CAAC;QACH,CAAC;QACD,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC;IAC3B,CAAC;IAED,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC;AAC9C,CAAC;AA1CD,gDA0CC"}
@@ -73,7 +73,12 @@ exports.defaultCommentaryTemplates = {
73
73
  'context.injected.rag': '{{appName}} retrieved relevant content and added it to the conversation.',
74
74
  'context.injected.skill': '{{appName}} activated a skill — its body went into the system prompt, and its tools became available to the LLM.',
75
75
  'context.injected.memory': '{{appName}} pulled prior content from memory and added it to the conversation.',
76
- 'context.injected.instructions': '{{appName}} added a tool-specific instruction to the system prompt after that tool returned.',
76
+ // Generic fits always-on rules + on-tool-return predicates uniformly.
77
+ // Specialized variants below disambiguate when the trigger metadata
78
+ // is available on the event.
79
+ 'context.injected.instructions': '{{appName}} added a rule to the system prompt: {{descClause}}.',
80
+ 'context.injected.instructions.onToolReturn': '{{appName}} added a tool-specific reminder after `{{lastToolName}}` returned: {{descClause}}.',
81
+ 'context.injected.instructions.alwaysOn': '{{appName}} added an always-on rule to the system prompt: {{descClause}}.',
77
82
  'context.injected.custom': '{{appName}} injected a custom piece of context.',
78
83
  'skill.activated': '{{appName}} turned on a skill — its tools and instructions are now available.',
79
84
  'skill.deactivated': '{{appName}} turned off a skill.',
@@ -1 +1 @@
1
- {"version":3,"file":"commentaryTemplates.js","sourceRoot":"","sources":["../../../../src/recorders/observability/commentary/commentaryTemplates.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"commentaryTemplates.js","sourceRoot":"","sources":["../../../../src/recorders/observability/commentary/commentaryTemplates.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;;;AAUH;;;;GAIG;AACU,QAAA,0BAA0B,GAAwB;IAC7D,kBAAkB,EAAE,2CAA2C;IAE/D,wBAAwB,EAAE,2CAA2C;IACrE,wBAAwB,EAAE,8DAA8D;IAExF,sBAAsB,EAAE,qEAAqE;IAC7F,yBAAyB,EAAE,qEAAqE;IAEhG,mEAAmE;IACnE,iEAAiE;IACjE,iEAAiE;IACjE,8DAA8D;IAC9D,gDAAgD;IAChD,mEAAmE;IACnE,iDAAiD;IACjD,6DAA6D;IAC7D,6CAA6C;IAC7C,iEAAiE;IACjE,iEAAiE;IACjE,iBAAiB,EAAE,0BAA0B;IAC7C,sBAAsB,EAAE,wCAAwC;IAEhE,mBAAmB,EACjB,+IAA+I;IACjJ,wBAAwB,EAAE,6BAA6B;IACvD,0BAA0B,EAAE,EAAE;IAE9B,iBAAiB,EAAE,4EAA4E;IAE/F,sBAAsB,EACpB,0EAA0E;IAC5E,wBAAwB,EACtB,kHAAkH;IACpH,yBAAyB,EACvB,gFAAgF;IAClF,wEAAwE;IACxE,oEAAoE;IACpE,6BAA6B;IAC7B,+BAA+B,EAAE,gEAAgE;IACjG,4CAA4C,EAC1C,+FAA+F;IACjG,wCAAwC,EACtC,2EAA2E;IAC7E,yBAAyB,EAAE,iDAAiD;IAE5E,iBAAiB,EACf,+EAA+E;IACjF,mBAAmB,EAAE,iCAAiC;IAEtD,wBAAwB,EAAE,gDAAgD;IAC1E,uBAAuB,EAAE,yDAAyD;IAElF,eAAe,EAAE,yEAAyE;IAC1F,cAAc,EAAE,sBAAsB;IAEtC,gBAAgB,EAAE,2CAA2C;CAC9D,CAAC;AAgBF;;;;;;;GAOG;AACH,SAAgB,mBAAmB,CAAC,KAA0B;IAC5D,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,KAAK,iCAAiC;YACpC,OAAO,kBAAkB,CAAC;QAC5B,KAAK,+BAA+B;YAClC,OAAO,IAAI,CAAC;QAEd,KAAK,iCAAiC;YACpC,OAAO,KAAK,CAAC,OAAO,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,wBAAwB,CAAC;QAE7F,KAAK,+BAA+B;YAClC,OAAO,KAAK,CAAC,OAAO,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,yBAAyB,CAAC;QAE9F,KAAK,kCAAkC;YACrC,OAAO,mBAAmB,CAAC;QAC7B,KAAK,gCAAgC;YACnC,OAAO,iBAAiB,CAAC;QAE3B,KAAK,iCAAiC;YACpC,QAAQ,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;gBAC7B,KAAK,KAAK;oBACR,OAAO,sBAAsB,CAAC;gBAChC,KAAK,OAAO;oBACV,OAAO,wBAAwB,CAAC;gBAClC,KAAK,QAAQ;oBACX,OAAO,yBAAyB,CAAC;gBACnC,KAAK,cAAc;oBACjB,OAAO,+BAA+B,CAAC;gBACzC,KAAK,QAAQ;oBACX,OAAO,yBAAyB,CAAC;gBACnC,wDAAwD;gBACxD,+BAA+B;gBAC/B,KAAK,MAAM,CAAC;gBACZ,KAAK,aAAa,CAAC;gBACnB,KAAK,WAAW,CAAC;gBACjB,KAAK,MAAM,CAAC;gBACZ,KAAK,UAAU;oBACb,OAAO,IAAI,CAAC;gBACd;oBACE,OAAO,yBAAyB,CAAC;YACrC,CAAC;QAEH,KAAK,gCAAgC;YACnC,OAAO,iBAAiB,CAAC;QAC3B,KAAK,kCAAkC;YACrC,OAAO,mBAAmB,CAAC;QAE7B,KAAK,sCAAsC,CAAC;QAC5C,KAAK,oCAAoC,CAAC;QAC1C,KAAK,oCAAoC;YACvC,OAAO,IAAI,CAAC,CAAC,kDAAkD;QAEjE,KAAK,uCAAuC;YAC1C,OAAO,wBAAwB,CAAC;QAClC,KAAK,sCAAsC;YACzC,OAAO,uBAAuB,CAAC;QAEjC,KAAK,8BAA8B;YACjC,OAAO,eAAe,CAAC;QACzB,KAAK,6BAA6B;YAChC,OAAO,cAAc,CAAC;QAExB,KAAK,+BAA+B;YAClC,OAAO,gBAAgB,CAAC;QAE1B,0DAA0D;QAC1D,mEAAmE;QACnE,kEAAkE;QAClE,gEAAgE;QAChE,YAAY;QACZ,KAAK,sCAAsC,CAAC;QAC5C,KAAK,gCAAgC,CAAC;QACtC,KAAK,wCAAwC;YAC3C,OAAO,IAAI,CAAC;QAEd;YACE,OAAO,SAAS,CAAC,CAAC,eAAe;IACrC,CAAC;AACH,CAAC;AA9ED,kDA8EC;AAED;;;;;;;;GAQG;AACH,SAAgB,qBAAqB,CACnC,KAA0B,EAC1B,GAAsB,EACtB,YAAiC,kCAA0B;IAE3D,MAAM,IAAI,GAAG,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC;IAEtC,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,KAAK,iCAAiC;YACpC,OAAO,EAAE,GAAG,IAAI,EAAE,UAAU,EAAE,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;QAE3D,KAAK,kCAAkC,CAAC,CAAC,CAAC;YACxC,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC;YACxC,MAAM,IAAI,GAAG,GAAG,CAAC,kBAAkB,EAAE,CAAC,QAAQ,CAAC,CAAC;YAChD,MAAM,OAAO,GAAG,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;YACnE,+DAA+D;YAC/D,gEAAgE;YAChE,MAAM,UAAU,GAAG,OAAO;gBACxB,CAAC,CAAC,gBAAgB,CAAC,SAAS,CAAC,wBAAwB,CAAC,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,IAAK,EAAE,CAAC;gBAC9E,CAAC,CAAC,SAAS,CAAC,0BAA0B,CAAC,IAAI,EAAE,CAAC;YAChD,OAAO,EAAE,GAAG,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC;QAC3C,CAAC;QAED,kEAAkE;QAClE,0DAA0D;QAC1D;YACE,OAAO,IAAI,CAAC;IAChB,CAAC;AACH,CAAC;AA5BD,sDA4BC;AAED;;;;;;;;GAQG;AACH,SAAgB,gBAAgB,CAAC,QAAgB,EAAE,IAA4B;IAC7E,OAAO,QAAQ,CAAC,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;AAC3E,CAAC;AAFD,4CAEC"}
@@ -0,0 +1,139 @@
1
+ "use strict";
2
+ /**
3
+ * PermissionPolicy — data-driven role-based authorization for tool dispatch.
4
+ *
5
+ * Closes Neo gap #2 (of 8). Permissions are CROSS-CUTTING — they're not
6
+ * context engineering, they're a guard ON context-engineering operations
7
+ * (tool dispatch, skill activation, memory writes, output emission).
8
+ * That's why this lives in `agentfootprint/security`, parallel to the
9
+ * provider subpaths.
10
+ *
11
+ * Two surfaces, one primitive:
12
+ * 1. `PermissionPolicy.fromRoles({...}, activeRole)` — declarative,
13
+ * data-driven, auditable. Production governance.
14
+ * 2. The PermissionPolicy instance satisfies BOTH:
15
+ * - `PermissionChecker` interface (async check; consumed by Agent
16
+ * constructor's `permissionChecker` field)
17
+ * - sync `isAllowed(toolId)` method (consumed by `gatedTools(...)`
18
+ * from `agentfootprint/tool-providers`)
19
+ *
20
+ * Pattern: Strategy (GoF) for the role-allowlist policy + Adapter
21
+ * (matches `PermissionChecker` interface so it composes with
22
+ * existing v2.4 Agent constructor).
23
+ *
24
+ * Role: Layer-3 cross-cutting guard. Not Injection. Not provider.
25
+ * Lives in its own subpath (`agentfootprint/security`).
26
+ *
27
+ * @example Read-only role for a support agent
28
+ * const policy = PermissionPolicy.fromRoles(
29
+ * {
30
+ * readonly: ['lookup_order', 'get_status', 'list_skills', 'read_skill'],
31
+ * support: ['lookup_order', 'get_status', 'process_refund', 'list_skills', 'read_skill'],
32
+ * },
33
+ * 'readonly',
34
+ * );
35
+ *
36
+ * policy.isAllowed('lookup_order'); // → true
37
+ * policy.isAllowed('process_refund'); // → false (not in readonly role)
38
+ *
39
+ * // As a tool-dispatch gate (composes with gatedTools)
40
+ * const provider = gatedTools(staticTools(allTools), (name) => policy.isAllowed(name));
41
+ *
42
+ * // As an Agent permissionChecker (the v2.4 surface)
43
+ * const agent = Agent.create({ provider, model, permissionChecker: policy }).build();
44
+ *
45
+ * @example Per-identity role switching at runtime
46
+ * const policy = PermissionPolicy.fromRoles({
47
+ * readonly: [...],
48
+ * admin: [...],
49
+ * }, 'readonly');
50
+ *
51
+ * const adminPolicy = policy.withActiveRole('admin');
52
+ * // Same allowlist data; different active role.
53
+ */
54
+ Object.defineProperty(exports, "__esModule", { value: true });
55
+ exports.PermissionPolicy = void 0;
56
+ /**
57
+ * Data-driven role-based permission policy. Satisfies the v2.4
58
+ * `PermissionChecker` interface AND exposes a sync `isAllowed` method
59
+ * for use with `gatedTools` from `agentfootprint/tool-providers`.
60
+ */
61
+ class PermissionPolicy {
62
+ opts;
63
+ name = 'PermissionPolicy';
64
+ constructor(opts) {
65
+ this.opts = opts;
66
+ if (!opts.roles[opts.activeRole]) {
67
+ throw new Error(`PermissionPolicy: activeRole '${opts.activeRole}' is not defined in roles. Available: ${Object.keys(opts.roles).join(', ') || '(none)'}`);
68
+ }
69
+ }
70
+ /**
71
+ * Factory: build a role-based policy from a role → tool-ids map and
72
+ * the role active for this instance.
73
+ *
74
+ * Throws if `activeRole` isn't a key in `roles` — fail loud at
75
+ * config time, not at first denied call.
76
+ */
77
+ static fromRoles(roles, activeRole) {
78
+ return new PermissionPolicy({ roles, activeRole });
79
+ }
80
+ /**
81
+ * Sync allowlist check. Use as a predicate with `gatedTools`:
82
+ *
83
+ * gatedTools(staticTools(allTools), (toolId) => policy.isAllowed(toolId))
84
+ *
85
+ * Returns true iff `toolId` is in the active role's allowlist.
86
+ * Closes-fail by design: missing role membership = denied.
87
+ */
88
+ isAllowed(toolId) {
89
+ return (this.opts.roles[this.opts.activeRole] ?? []).includes(toolId);
90
+ }
91
+ /**
92
+ * Async check matching the `PermissionChecker` interface — consumed
93
+ * by `Agent.create({ permissionChecker })`. Wraps `isAllowed` with
94
+ * the structured `PermissionDecision` envelope (allow / deny + a
95
+ * `policyRuleId` so observability can trace which role decided).
96
+ *
97
+ * Today the policy only checks the tool name (request.target).
98
+ * Future work: also gate by capability ('memory_write', etc.) when
99
+ * the role allowlist is widened to capability-by-id.
100
+ */
101
+ async check(request) {
102
+ const toolId = request.target ?? request.capability;
103
+ if (this.isAllowed(toolId)) {
104
+ return {
105
+ result: 'allow',
106
+ policyRuleId: `${this.opts.activeRole}.allowlist`,
107
+ };
108
+ }
109
+ return {
110
+ result: 'deny',
111
+ policyRuleId: `${this.opts.activeRole}.allowlist.miss`,
112
+ rationale: `Tool '${toolId}' is not in the '${this.opts.activeRole}' role allowlist.`,
113
+ };
114
+ }
115
+ /**
116
+ * Derive a sibling policy with a different active role. Same role
117
+ * map; different active role. Useful for per-identity routing
118
+ * (one policy instance per request, varying active role per caller).
119
+ *
120
+ * Returns a NEW PermissionPolicy — original is unchanged.
121
+ */
122
+ withActiveRole(activeRole) {
123
+ return new PermissionPolicy({ roles: this.opts.roles, activeRole });
124
+ }
125
+ /** The role name currently active. Useful for observability. */
126
+ get activeRole() {
127
+ return this.opts.activeRole;
128
+ }
129
+ /** All defined role names. Stable order = registration order. */
130
+ get roles() {
131
+ return Object.keys(this.opts.roles);
132
+ }
133
+ /** All tool ids allowed under the current active role. */
134
+ allowedToolIds() {
135
+ return [...(this.opts.roles[this.opts.activeRole] ?? [])];
136
+ }
137
+ }
138
+ exports.PermissionPolicy = PermissionPolicy;
139
+ //# sourceMappingURL=PermissionPolicy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PermissionPolicy.js","sourceRoot":"","sources":["../../src/security/PermissionPolicy.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;;;AA6BH;;;;GAIG;AACH,MAAa,gBAAgB;IAGU;IAF5B,IAAI,GAAG,kBAAkB,CAAC;IAEnC,YAAqC,IAA6B;QAA7B,SAAI,GAAJ,IAAI,CAAyB;QAChE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;YACjC,MAAM,IAAI,KAAK,CACb,iCAAiC,IAAI,CAAC,UAAU,yCAC9C,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,QACxC,EAAE,CACH,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;;;;;OAMG;IACH,MAAM,CAAC,SAAS,CAAC,KAAoB,EAAE,UAAkB;QACvD,OAAO,IAAI,gBAAgB,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC;IACrD,CAAC;IAED;;;;;;;OAOG;IACH,SAAS,CAAC,MAAc;QACtB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACxE,CAAC;IAED;;;;;;;;;OASG;IACH,KAAK,CAAC,KAAK,CAAC,OAA0B;QACpC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,UAAU,CAAC;QACpD,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3B,OAAO;gBACL,MAAM,EAAE,OAAO;gBACf,YAAY,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,YAAY;aAClD,CAAC;QACJ,CAAC;QACD,OAAO;YACL,MAAM,EAAE,MAAM;YACd,YAAY,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,iBAAiB;YACtD,SAAS,EAAE,SAAS,MAAM,oBAAoB,IAAI,CAAC,IAAI,CAAC,UAAU,mBAAmB;SACtF,CAAC;IACJ,CAAC;IAED;;;;;;OAMG;IACH,cAAc,CAAC,UAAkB;QAC/B,OAAO,IAAI,gBAAgB,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC;IACtE,CAAC;IAED,gEAAgE;IAChE,IAAI,UAAU;QACZ,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC;IAC9B,CAAC;IAED,iEAAiE;IACjE,IAAI,KAAK;QACP,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACtC,CAAC;IAED,0DAA0D;IAC1D,cAAc;QACZ,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAC5D,CAAC;CACF;AAtFD,4CAsFC"}
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ /**
3
+ * agentfootprint/security — cross-cutting authorization + governance.
4
+ *
5
+ * Permissions are NOT context engineering — they're a guard ON
6
+ * context-engineering operations (tool dispatch, skill activation,
7
+ * memory writes, output emission). That's why this lives in its own
8
+ * subpath, parallel to `agentfootprint/tool-providers` and the
9
+ * `agentfootprint/memory-*` and `agentfootprint/providers` subpaths.
10
+ *
11
+ * Today's surface is small and data-driven on purpose: one role
12
+ * allowlist primitive that satisfies BOTH the v2.4 `PermissionChecker`
13
+ * interface AND a sync `isAllowed(toolId)` predicate for use with
14
+ * `gatedTools` from `agentfootprint/tool-providers`.
15
+ *
16
+ * Future additions (capability gating, gate_open flows, audit logs)
17
+ * land here without expanding the public root barrel.
18
+ *
19
+ * @example
20
+ * import { PermissionPolicy } from 'agentfootprint/security';
21
+ * import { gatedTools, staticTools } from 'agentfootprint/tool-providers';
22
+ *
23
+ * const policy = PermissionPolicy.fromRoles(
24
+ * {
25
+ * readonly: ['lookup', 'list_skills', 'read_skill'],
26
+ * admin: ['lookup', 'list_skills', 'read_skill', 'write', 'delete'],
27
+ * },
28
+ * 'readonly',
29
+ * );
30
+ *
31
+ * const provider = gatedTools(
32
+ * staticTools(allTools),
33
+ * (name) => policy.isAllowed(name),
34
+ * );
35
+ *
36
+ * const agent = Agent.create({ provider, model, permissionChecker: policy }).build();
37
+ */
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.PermissionPolicy = void 0;
40
+ var PermissionPolicy_js_1 = require("./PermissionPolicy.js");
41
+ Object.defineProperty(exports, "PermissionPolicy", { enumerable: true, get: function () { return PermissionPolicy_js_1.PermissionPolicy; } });
42
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/security/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;;;AAEH,6DAAyD;AAAhD,uHAAA,gBAAgB,OAAA"}
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ /**
3
+ * gatedTools — wrap any ToolProvider with a per-tool gating predicate.
4
+ *
5
+ * The DECORATOR for tool providers. Filters the inner provider's
6
+ * output by running the predicate against each tool name. Composes
7
+ * freely:
8
+ *
9
+ * gatedTools(
10
+ * gatedTools(staticTools(allTools), readOnlyPredicate),
11
+ * skillGatePredicate,
12
+ * )
13
+ *
14
+ * Reads as: "static list of all tools, filtered by readonly policy,
15
+ * then further filtered by the active skill's tool set." Each gate
16
+ * is one concern; composition handles the rest.
17
+ *
18
+ * Pattern: Decorator (GoF) — wraps any ToolProvider with an additional
19
+ * filter. Mirrors `withRetry` / `withFallback` over LLMProvider.
20
+ *
21
+ * @example Read-only enforcement
22
+ * const readOnly = gatedTools(
23
+ * staticTools([read, write]),
24
+ * (toolName) => toolName.startsWith('read_'),
25
+ * );
26
+ * readOnly.list(ctx); // → [read]
27
+ *
28
+ * @example Skill-gated dispatch (autoActivate use case)
29
+ * const skillGated = gatedTools(
30
+ * staticTools(allTools),
31
+ * (toolName, ctx) => ctx.activeSkillId
32
+ * ? skillToolMap[ctx.activeSkillId].includes(toolName)
33
+ * : alwaysVisible.includes(toolName),
34
+ * );
35
+ */
36
+ Object.defineProperty(exports, "__esModule", { value: true });
37
+ exports.gatedTools = void 0;
38
+ // #region gatedTools
39
+ function gatedTools(inner, predicate) {
40
+ return {
41
+ id: 'gated',
42
+ list(ctx) {
43
+ // Pull from the inner provider first; each recomputation sees
44
+ // the freshest state from any nested gates.
45
+ const innerTools = inner.list(ctx);
46
+ // Filter by predicate — tool name from `tool.schema.name`.
47
+ // Predicates throwing escape: a buggy predicate should crash
48
+ // loudly, not silently allow tools through. Per the
49
+ // permission-as-defense-in-depth principle.
50
+ return innerTools.filter((t) => predicate(t.schema.name, ctx));
51
+ },
52
+ };
53
+ }
54
+ exports.gatedTools = gatedTools;
55
+ // #endregion gatedTools
56
+ //# sourceMappingURL=gatedTools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gatedTools.js","sourceRoot":"","sources":["../../src/tool-providers/gatedTools.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;;;AAIH,qBAAqB;AACrB,SAAgB,UAAU,CAAC,KAAmB,EAAE,SAA4B;IAC1E,OAAO;QACL,EAAE,EAAE,OAAO;QACX,IAAI,CAAC,GAAwB;YAC3B,8DAA8D;YAC9D,4CAA4C;YAC5C,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACnC,2DAA2D;YAC3D,6DAA6D;YAC7D,oDAAoD;YACpD,4CAA4C;YAC5C,OAAO,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC;QACjE,CAAC;KACF,CAAC;AACJ,CAAC;AAdD,gCAcC;AACD,wBAAwB"}
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ /**
3
+ * agentfootprint/tool-providers — chainable tool dispatch + tool sources.
4
+ *
5
+ * Two layers under one subpath:
6
+ *
7
+ * 1. Tool dispatch (this folder)
8
+ * - `staticTools(arr)` — wrap a flat tool list
9
+ * - `gatedTools(inner, predicate)` — decorator that filters
10
+ * - `ToolProvider` interface — the contract
11
+ * - `ToolDispatchContext` — read-only context per iteration
12
+ *
13
+ * 2. Tool sources (re-exported from existing modules)
14
+ * - `mcpClient(opts)` — connect to an MCP server (real)
15
+ * - `mockMcpClient({ tools })` — in-memory MCP source for dev / tests
16
+ *
17
+ * Compose freely. The dispatch layer is decorator-shaped (mirroring
18
+ * `withRetry` / `withFallback` over LLMProvider). Tool sources produce
19
+ * `Tool[]` that flow into a `staticTools(arr)` provider, which can
20
+ * then be wrapped by `gatedTools(...)` for permission gating or
21
+ * per-skill filtering.
22
+ *
23
+ * @example Static (90% case — what `agent.tools(arr)` does today)
24
+ * const provider = staticTools([weatherTool, lookupTool]);
25
+ *
26
+ * @example Read-only enforcement
27
+ * const readOnly = gatedTools(
28
+ * staticTools(allTools),
29
+ * (name) => policy.isAllowed(name),
30
+ * );
31
+ *
32
+ * @example MCP source + permission gate
33
+ * const slack = await mcpClient({ transport: ... });
34
+ * const slackTools = await slack.tools();
35
+ * const provider = gatedTools(staticTools(slackTools), (name) => allowed(name));
36
+ */
37
+ Object.defineProperty(exports, "__esModule", { value: true });
38
+ exports.mockMcpClient = exports.mcpClient = exports.skillScopedTools = exports.gatedTools = exports.staticTools = void 0;
39
+ var staticTools_js_1 = require("./staticTools.js");
40
+ Object.defineProperty(exports, "staticTools", { enumerable: true, get: function () { return staticTools_js_1.staticTools; } });
41
+ var gatedTools_js_1 = require("./gatedTools.js");
42
+ Object.defineProperty(exports, "gatedTools", { enumerable: true, get: function () { return gatedTools_js_1.gatedTools; } });
43
+ var skillScopedTools_js_1 = require("./skillScopedTools.js");
44
+ Object.defineProperty(exports, "skillScopedTools", { enumerable: true, get: function () { return skillScopedTools_js_1.skillScopedTools; } });
45
+ // Re-export tool sources from the MCP module so consumers find them in
46
+ // one place. The top-level barrel still exports `mcpClient` for v2.2
47
+ // back-compat.
48
+ var index_js_1 = require("../lib/mcp/index.js");
49
+ Object.defineProperty(exports, "mcpClient", { enumerable: true, get: function () { return index_js_1.mcpClient; } });
50
+ Object.defineProperty(exports, "mockMcpClient", { enumerable: true, get: function () { return index_js_1.mockMcpClient; } });
51
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tool-providers/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;;;AAEH,mDAA+C;AAAtC,6GAAA,WAAW,OAAA;AACpB,iDAA6C;AAApC,2GAAA,UAAU,OAAA;AACnB,6DAAyD;AAAhD,uHAAA,gBAAgB,OAAA;AAGzB,uEAAuE;AACvE,qEAAqE;AACrE,eAAe;AACf,gDAA+D;AAAtD,qGAAA,SAAS,OAAA;AAAE,yGAAA,aAAa,OAAA"}
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ /**
3
+ * skillScopedTools — ToolProvider that exposes a tool subset only when
4
+ * a specific Skill is active in the current iteration's context.
5
+ *
6
+ * The Block A5 piece. Pairs with `defineSkill({ autoActivate: 'currentSkill' })`
7
+ * to give the LLM a sharper choice space: when `billing` activates, the
8
+ * tool list flips from "all 25 agent tools" to "the 7 billing tools" +
9
+ * any baseline (always-on) tools the consumer composes alongside.
10
+ *
11
+ * Pattern: gated ToolProvider keyed by `ctx.activeSkillId`. Pure compute;
12
+ * no Agent-runtime dependency. Composes freely with `staticTools`
13
+ * for the always-on baseline.
14
+ *
15
+ * @example One skill's tools, scoped by activation
16
+ * const billingTools = skillScopedTools('billing', [refundTool, chargeTool]);
17
+ * billingTools.list({ iteration: 1, activeSkillId: 'billing', identity: ... });
18
+ * // → [refundTool, chargeTool]
19
+ * billingTools.list({ iteration: 1, activeSkillId: 'refund', identity: ... });
20
+ * // → [] (different skill active)
21
+ * billingTools.list({ iteration: 1, identity: ... });
22
+ * // → [] (no skill active)
23
+ *
24
+ * @example Compose with baseline + multiple skills
25
+ * const baseline = staticTools([lookupOrderTool, listSkills, readSkill]);
26
+ * const billingTbx = skillScopedTools('billing', [refundTool, chargeTool]);
27
+ * const refundTbx = skillScopedTools('refund', [reverseTool]);
28
+ *
29
+ * // Wrap each scope-provider in a gatedTools for downstream composition,
30
+ * // OR build a small wrapper that concatenates list(ctx) outputs:
31
+ * const provider: ToolProvider = {
32
+ * id: 'composite',
33
+ * list: (ctx) => [
34
+ * ...baseline.list(ctx),
35
+ * ...billingTbx.list(ctx),
36
+ * ...refundTbx.list(ctx),
37
+ * ],
38
+ * };
39
+ *
40
+ * Note: the runtime that POPULATES `ctx.activeSkillId` from
41
+ * `scope.activatedInjectionIds` lands in Block C / v2.5+. Today,
42
+ * consumers can drive it manually for tests + design-time inspection.
43
+ */
44
+ Object.defineProperty(exports, "__esModule", { value: true });
45
+ exports.skillScopedTools = void 0;
46
+ // #region skillScopedTools
47
+ function skillScopedTools(skillId, tools) {
48
+ if (!skillId || skillId.trim().length === 0) {
49
+ throw new Error('skillScopedTools: `skillId` is required and must be non-empty.');
50
+ }
51
+ // Capture the tool list once. `list()` returns a fresh array each
52
+ // call (matches the staticTools / gatedTools convention so the
53
+ // agent's reference-equality check always sees an update).
54
+ const captured = [...tools];
55
+ return {
56
+ id: `skill-scoped:${skillId}`,
57
+ list(ctx) {
58
+ // Empty list when the skill is not active.
59
+ if (ctx.activeSkillId !== skillId)
60
+ return [];
61
+ return [...captured];
62
+ },
63
+ };
64
+ }
65
+ exports.skillScopedTools = skillScopedTools;
66
+ // #endregion skillScopedTools
67
+ //# sourceMappingURL=skillScopedTools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skillScopedTools.js","sourceRoot":"","sources":["../../src/tool-providers/skillScopedTools.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;;;AAKH,2BAA2B;AAC3B,SAAgB,gBAAgB,CAAC,OAAe,EAAE,KAAsB;IACtE,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5C,MAAM,IAAI,KAAK,CAAC,gEAAgE,CAAC,CAAC;IACpF,CAAC;IACD,kEAAkE;IAClE,+DAA+D;IAC/D,2DAA2D;IAC3D,MAAM,QAAQ,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC;IAC5B,OAAO;QACL,EAAE,EAAE,gBAAgB,OAAO,EAAE;QAC7B,IAAI,CAAC,GAAwB;YAC3B,2CAA2C;YAC3C,IAAI,GAAG,CAAC,aAAa,KAAK,OAAO;gBAAE,OAAO,EAAE,CAAC;YAC7C,OAAO,CAAC,GAAG,QAAQ,CAAC,CAAC;QACvB,CAAC;KACF,CAAC;AACJ,CAAC;AAhBD,4CAgBC;AACD,8BAA8B"}
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ /**
3
+ * staticTools — the simplest ToolProvider. Wraps a fixed Tool[] list.
4
+ *
5
+ * 90% case. What `agent.tools(arr)` does today, made composable.
6
+ * Equivalent to passing `arr` directly EXCEPT that `staticTools(arr)`
7
+ * is now a `ToolProvider` you can wrap with `gatedTools(...)` for
8
+ * permission filtering or per-skill gating.
9
+ *
10
+ * Pattern: identity ToolProvider — no filtering, just exposes the
11
+ * underlying list verbatim.
12
+ *
13
+ * @example
14
+ * const provider = staticTools([weatherTool, lookupTool]);
15
+ * // Materialize the visible list and register via .tools(...).
16
+ * // Direct .toolProvider(...) wiring on the builder lands in Block A5 / v2.5+.
17
+ * const visible = provider.list({ iteration: 0, identity: { conversationId: '_' } });
18
+ * const agent = Agent.create({ provider: llm, model }).tools(visible).build();
19
+ */
20
+ Object.defineProperty(exports, "__esModule", { value: true });
21
+ exports.staticTools = void 0;
22
+ // #region staticTools
23
+ function staticTools(tools) {
24
+ // Capture the input list once. `list()` returns a fresh array each
25
+ // call so the agent's reference-equality check always sees an update
26
+ // (matches the `gatedTools` decorator's per-call recomputation).
27
+ const captured = [...tools];
28
+ return {
29
+ id: 'static',
30
+ list(_ctx) {
31
+ return [...captured];
32
+ },
33
+ };
34
+ }
35
+ exports.staticTools = staticTools;
36
+ // #endregion staticTools
37
+ //# sourceMappingURL=staticTools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"staticTools.js","sourceRoot":"","sources":["../../src/tool-providers/staticTools.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;GAiBG;;;AAKH,sBAAsB;AACtB,SAAgB,WAAW,CAAC,KAAsB;IAChD,mEAAmE;IACnE,qEAAqE;IACrE,iEAAiE;IACjE,MAAM,QAAQ,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC;IAC5B,OAAO;QACL,EAAE,EAAE,QAAQ;QACZ,IAAI,CAAC,IAAyB;YAC5B,OAAO,CAAC,GAAG,QAAQ,CAAC,CAAC;QACvB,CAAC;KACF,CAAC;AACJ,CAAC;AAXD,kCAWC;AACD,yBAAyB"}