@animalabs/agent-framework 0.22.3 → 0.23.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 (234) hide show
  1. package/README.md +105 -3
  2. package/dist/src/agent.d.ts +36 -10
  3. package/dist/src/agent.d.ts.map +1 -1
  4. package/dist/src/agent.js +76 -32
  5. package/dist/src/agent.js.map +1 -1
  6. package/dist/src/code-execution/index.d.ts +1 -1
  7. package/dist/src/code-execution/index.d.ts.map +1 -1
  8. package/dist/src/code-execution/index.js.map +1 -1
  9. package/dist/src/code-execution/py-runner.d.ts +34 -2
  10. package/dist/src/code-execution/py-runner.d.ts.map +1 -1
  11. package/dist/src/code-execution/py-runner.js +72 -16
  12. package/dist/src/code-execution/py-runner.js.map +1 -1
  13. package/dist/src/code-execution/runtime-py.d.ts +3 -2
  14. package/dist/src/code-execution/runtime-py.d.ts.map +1 -1
  15. package/dist/src/code-execution/runtime-py.js +47 -7
  16. package/dist/src/code-execution/runtime-py.js.map +1 -1
  17. package/dist/src/code-execution/tool-definition.d.ts +12 -7
  18. package/dist/src/code-execution/tool-definition.d.ts.map +1 -1
  19. package/dist/src/code-execution/tool-definition.js +59 -11
  20. package/dist/src/code-execution/tool-definition.js.map +1 -1
  21. package/dist/src/config-checks.d.ts +2 -2
  22. package/dist/src/config-checks.d.ts.map +1 -1
  23. package/dist/src/config-checks.js +6 -2
  24. package/dist/src/config-checks.js.map +1 -1
  25. package/dist/src/framework.d.ts +744 -120
  26. package/dist/src/framework.d.ts.map +1 -1
  27. package/dist/src/framework.js +3546 -906
  28. package/dist/src/framework.js.map +1 -1
  29. package/dist/src/gate/event-gate.d.ts.map +1 -1
  30. package/dist/src/gate/event-gate.js +13 -6
  31. package/dist/src/gate/event-gate.js.map +1 -1
  32. package/dist/src/held-writes.d.ts +16 -0
  33. package/dist/src/held-writes.d.ts.map +1 -0
  34. package/dist/src/held-writes.js +56 -0
  35. package/dist/src/held-writes.js.map +1 -0
  36. package/dist/src/index.d.ts +7 -3
  37. package/dist/src/index.d.ts.map +1 -1
  38. package/dist/src/index.js +8 -4
  39. package/dist/src/index.js.map +1 -1
  40. package/dist/src/mcpl/capability-grant.d.ts +4 -0
  41. package/dist/src/mcpl/capability-grant.d.ts.map +1 -1
  42. package/dist/src/mcpl/capability-grant.js +1 -1
  43. package/dist/src/mcpl/capability-grant.js.map +1 -1
  44. package/dist/src/mcpl/channel-registry.d.ts +95 -18
  45. package/dist/src/mcpl/channel-registry.d.ts.map +1 -1
  46. package/dist/src/mcpl/channel-registry.js +578 -150
  47. package/dist/src/mcpl/channel-registry.js.map +1 -1
  48. package/dist/src/mcpl/convert-block.d.ts +2 -2
  49. package/dist/src/mcpl/convert-block.d.ts.map +1 -1
  50. package/dist/src/mcpl/convert-block.js +6 -7
  51. package/dist/src/mcpl/convert-block.js.map +1 -1
  52. package/dist/src/mcpl/index.d.ts +5 -1
  53. package/dist/src/mcpl/index.d.ts.map +1 -1
  54. package/dist/src/mcpl/index.js +3 -1
  55. package/dist/src/mcpl/index.js.map +1 -1
  56. package/dist/src/mcpl/inference-router.d.ts +4 -2
  57. package/dist/src/mcpl/inference-router.d.ts.map +1 -1
  58. package/dist/src/mcpl/inference-router.js +6 -7
  59. package/dist/src/mcpl/inference-router.js.map +1 -1
  60. package/dist/src/mcpl/log-value.d.ts +7 -0
  61. package/dist/src/mcpl/log-value.d.ts.map +1 -1
  62. package/dist/src/mcpl/log-value.js +9 -0
  63. package/dist/src/mcpl/log-value.js.map +1 -1
  64. package/dist/src/mcpl/modern-connection.d.ts +227 -0
  65. package/dist/src/mcpl/modern-connection.d.ts.map +1 -0
  66. package/dist/src/mcpl/modern-connection.js +1088 -0
  67. package/dist/src/mcpl/modern-connection.js.map +1 -0
  68. package/dist/src/mcpl/prefix-rule.d.ts +18 -0
  69. package/dist/src/mcpl/prefix-rule.d.ts.map +1 -0
  70. package/dist/src/mcpl/prefix-rule.js +25 -0
  71. package/dist/src/mcpl/prefix-rule.js.map +1 -0
  72. package/dist/src/mcpl/protocol-family.d.ts +179 -0
  73. package/dist/src/mcpl/protocol-family.d.ts.map +1 -0
  74. package/dist/src/mcpl/protocol-family.js +697 -0
  75. package/dist/src/mcpl/protocol-family.js.map +1 -0
  76. package/dist/src/mcpl/push-coalescer.d.ts +38 -19
  77. package/dist/src/mcpl/push-coalescer.d.ts.map +1 -1
  78. package/dist/src/mcpl/push-coalescer.js +52 -23
  79. package/dist/src/mcpl/push-coalescer.js.map +1 -1
  80. package/dist/src/mcpl/reference-fetcher.d.ts +66 -15
  81. package/dist/src/mcpl/reference-fetcher.d.ts.map +1 -1
  82. package/dist/src/mcpl/reference-fetcher.js +243 -76
  83. package/dist/src/mcpl/reference-fetcher.js.map +1 -1
  84. package/dist/src/mcpl/references.d.ts +63 -18
  85. package/dist/src/mcpl/references.d.ts.map +1 -1
  86. package/dist/src/mcpl/references.js +117 -32
  87. package/dist/src/mcpl/references.js.map +1 -1
  88. package/dist/src/mcpl/server-connection.d.ts +326 -30
  89. package/dist/src/mcpl/server-connection.d.ts.map +1 -1
  90. package/dist/src/mcpl/server-connection.js +995 -212
  91. package/dist/src/mcpl/server-connection.js.map +1 -1
  92. package/dist/src/mcpl/server-registry.d.ts +25 -5
  93. package/dist/src/mcpl/server-registry.d.ts.map +1 -1
  94. package/dist/src/mcpl/server-registry.js +51 -12
  95. package/dist/src/mcpl/server-registry.js.map +1 -1
  96. package/dist/src/mcpl/tool-result-normalize.d.ts +54 -0
  97. package/dist/src/mcpl/tool-result-normalize.d.ts.map +1 -0
  98. package/dist/src/mcpl/tool-result-normalize.js +232 -0
  99. package/dist/src/mcpl/tool-result-normalize.js.map +1 -0
  100. package/dist/src/mcpl/transport.d.ts +56 -13
  101. package/dist/src/mcpl/transport.d.ts.map +1 -1
  102. package/dist/src/mcpl/transport.js +206 -70
  103. package/dist/src/mcpl/transport.js.map +1 -1
  104. package/dist/src/mcpl/types.d.ts +66 -20
  105. package/dist/src/mcpl/types.d.ts.map +1 -1
  106. package/dist/src/mcpl/types.js.map +1 -1
  107. package/dist/src/mcpl/visible-content.d.ts +2 -1
  108. package/dist/src/mcpl/visible-content.d.ts.map +1 -1
  109. package/dist/src/mcpl/visible-content.js +2 -1
  110. package/dist/src/mcpl/visible-content.js.map +1 -1
  111. package/dist/src/module-registry.d.ts +16 -6
  112. package/dist/src/module-registry.d.ts.map +1 -1
  113. package/dist/src/module-registry.js +65 -6
  114. package/dist/src/module-registry.js.map +1 -1
  115. package/dist/src/modules/api/index.d.ts +1 -1
  116. package/dist/src/modules/api/index.d.ts.map +1 -1
  117. package/dist/src/modules/api/index.js +3 -2
  118. package/dist/src/modules/api/index.js.map +1 -1
  119. package/dist/src/modules/discord/discord-js-client.d.ts +42 -2
  120. package/dist/src/modules/discord/discord-js-client.d.ts.map +1 -1
  121. package/dist/src/modules/discord/discord-js-client.js +268 -65
  122. package/dist/src/modules/discord/discord-js-client.js.map +1 -1
  123. package/dist/src/modules/discord/index.d.ts +27 -5
  124. package/dist/src/modules/discord/index.d.ts.map +1 -1
  125. package/dist/src/modules/discord/index.js +366 -76
  126. package/dist/src/modules/discord/index.js.map +1 -1
  127. package/dist/src/modules/discord/refusal.d.ts +14 -0
  128. package/dist/src/modules/discord/refusal.d.ts.map +1 -0
  129. package/dist/src/modules/discord/refusal.js +14 -0
  130. package/dist/src/modules/discord/refusal.js.map +1 -0
  131. package/dist/src/modules/discord/types.d.ts +17 -7
  132. package/dist/src/modules/discord/types.d.ts.map +1 -1
  133. package/dist/src/modules/health/index.d.ts.map +1 -1
  134. package/dist/src/modules/health/index.js +6 -2
  135. package/dist/src/modules/health/index.js.map +1 -1
  136. package/dist/src/modules/index.d.ts +1 -1
  137. package/dist/src/modules/index.d.ts.map +1 -1
  138. package/dist/src/modules/index.js +1 -1
  139. package/dist/src/modules/index.js.map +1 -1
  140. package/dist/src/modules/workspace/disk-agreement.d.ts +25 -2
  141. package/dist/src/modules/workspace/disk-agreement.d.ts.map +1 -1
  142. package/dist/src/modules/workspace/disk-agreement.js +45 -5
  143. package/dist/src/modules/workspace/disk-agreement.js.map +1 -1
  144. package/dist/src/modules/workspace/effects.d.ts +2 -1
  145. package/dist/src/modules/workspace/effects.d.ts.map +1 -1
  146. package/dist/src/modules/workspace/effects.js +19 -9
  147. package/dist/src/modules/workspace/effects.js.map +1 -1
  148. package/dist/src/modules/workspace/index.d.ts +214 -42
  149. package/dist/src/modules/workspace/index.d.ts.map +1 -1
  150. package/dist/src/modules/workspace/index.js +667 -113
  151. package/dist/src/modules/workspace/index.js.map +1 -1
  152. package/dist/src/modules/workspace/observe.d.ts +240 -8
  153. package/dist/src/modules/workspace/observe.d.ts.map +1 -1
  154. package/dist/src/modules/workspace/observe.js +554 -24
  155. package/dist/src/modules/workspace/observe.js.map +1 -1
  156. package/dist/src/modules/workspace/types.d.ts +10 -1
  157. package/dist/src/modules/workspace/types.d.ts.map +1 -1
  158. package/dist/src/modules/workspace/types.js.map +1 -1
  159. package/dist/src/modules/workspace/watcher.d.ts +42 -0
  160. package/dist/src/modules/workspace/watcher.d.ts.map +1 -1
  161. package/dist/src/modules/workspace/watcher.js +130 -25
  162. package/dist/src/modules/workspace/watcher.js.map +1 -1
  163. package/dist/src/silent-heartbeat.d.ts +112 -39
  164. package/dist/src/silent-heartbeat.d.ts.map +1 -1
  165. package/dist/src/silent-heartbeat.js +100 -29
  166. package/dist/src/silent-heartbeat.js.map +1 -1
  167. package/dist/src/tool-args.d.ts +40 -0
  168. package/dist/src/tool-args.d.ts.map +1 -0
  169. package/dist/src/tool-args.js +207 -0
  170. package/dist/src/tool-args.js.map +1 -0
  171. package/dist/src/tool-presentation.d.ts.map +1 -1
  172. package/dist/src/tool-presentation.js +9 -2
  173. package/dist/src/tool-presentation.js.map +1 -1
  174. package/dist/src/types/agent.d.ts +27 -17
  175. package/dist/src/types/agent.d.ts.map +1 -1
  176. package/dist/src/types/events.d.ts +8 -0
  177. package/dist/src/types/events.d.ts.map +1 -1
  178. package/dist/src/types/framework.d.ts +17 -2
  179. package/dist/src/types/framework.d.ts.map +1 -1
  180. package/dist/src/types/module.d.ts +54 -10
  181. package/dist/src/types/module.d.ts.map +1 -1
  182. package/dist/src/types/trace.d.ts +2 -2
  183. package/dist/src/types/trace.d.ts.map +1 -1
  184. package/package.json +3 -1
  185. package/src/agent.ts +99 -36
  186. package/src/code-execution/index.ts +1 -0
  187. package/src/code-execution/py-runner.ts +104 -17
  188. package/src/code-execution/runtime-py.ts +47 -7
  189. package/src/code-execution/tool-definition.ts +65 -11
  190. package/src/config-checks.ts +4 -2
  191. package/src/framework.ts +3633 -956
  192. package/src/gate/event-gate.ts +14 -6
  193. package/src/held-writes.ts +59 -0
  194. package/src/index.ts +19 -4
  195. package/src/mcpl/capability-grant.ts +1 -1
  196. package/src/mcpl/channel-registry.ts +613 -160
  197. package/src/mcpl/convert-block.ts +15 -7
  198. package/src/mcpl/index.ts +14 -1
  199. package/src/mcpl/inference-router.ts +8 -7
  200. package/src/mcpl/log-value.ts +10 -0
  201. package/src/mcpl/modern-connection.ts +1182 -0
  202. package/src/mcpl/prefix-rule.ts +32 -0
  203. package/src/mcpl/protocol-family.ts +691 -0
  204. package/src/mcpl/push-coalescer.ts +67 -29
  205. package/src/mcpl/reference-fetcher.ts +288 -82
  206. package/src/mcpl/references.ts +123 -33
  207. package/src/mcpl/server-connection.ts +1050 -221
  208. package/src/mcpl/server-registry.ts +50 -12
  209. package/src/mcpl/tool-result-normalize.ts +294 -0
  210. package/src/mcpl/transport.ts +204 -62
  211. package/src/mcpl/types.ts +67 -20
  212. package/src/mcpl/visible-content.ts +2 -1
  213. package/src/module-registry.ts +68 -13
  214. package/src/modules/api/index.ts +3 -2
  215. package/src/modules/discord/discord-js-client.ts +288 -72
  216. package/src/modules/discord/index.ts +380 -77
  217. package/src/modules/discord/refusal.ts +13 -0
  218. package/src/modules/discord/types.ts +17 -9
  219. package/src/modules/health/index.ts +6 -2
  220. package/src/modules/index.ts +1 -1
  221. package/src/modules/workspace/disk-agreement.ts +46 -5
  222. package/src/modules/workspace/effects.ts +18 -7
  223. package/src/modules/workspace/index.ts +722 -124
  224. package/src/modules/workspace/observe.ts +591 -22
  225. package/src/modules/workspace/types.ts +10 -1
  226. package/src/modules/workspace/watcher.ts +126 -25
  227. package/src/silent-heartbeat.ts +184 -59
  228. package/src/tool-args.ts +213 -0
  229. package/src/tool-presentation.ts +9 -2
  230. package/src/types/agent.ts +27 -17
  231. package/src/types/events.ts +8 -0
  232. package/src/types/framework.ts +17 -2
  233. package/src/types/module.ts +55 -10
  234. package/src/types/trace.ts +2 -2
@@ -45,6 +45,15 @@ const MAX_TRACE_SNIPPET = 80;
45
45
  const MAX_INFERENCE_BUFFER = 100;
46
46
  /** Minimum interval between filesystem checks for config changes (ms). */
47
47
  const RELOAD_THROTTLE_MS = 1000;
48
+
49
+ /**
50
+ * Parse a gate file's text as JSON. Some Windows editors save UTF-8 with a
51
+ * leading U+FEFF (BOM), which `readFileSync(…, 'utf-8')` keeps and
52
+ * `JSON.parse` rejects; drop exactly one before parsing (#395).
53
+ */
54
+ function parseGateJson(text: string): unknown {
55
+ return JSON.parse(text.charCodeAt(0) === 0xfeff ? text.slice(1) : text);
56
+ }
48
57
  /** Minimum debounce value (ms). */
49
58
  const MIN_DEBOUNCE_MS = 100;
50
59
  /** Maximum debounce value (ms). */
@@ -723,7 +732,7 @@ export class EventGate {
723
732
  const raw = readFileSync(this.configPath, 'utf-8');
724
733
  const stat = statSync(this.configPath);
725
734
  this.configMtime = stat.mtimeMs;
726
- const config = validateConfig(JSON.parse(raw));
735
+ const config = validateConfig(parseGateJson(raw));
727
736
  this.configSource = 'file';
728
737
  this.configErrors = [];
729
738
  return config;
@@ -1870,7 +1879,7 @@ export class EventGate {
1870
1879
  return;
1871
1880
  }
1872
1881
  this.privilegedMtime = statSync(this.privilegedUsersPath).mtimeMs;
1873
- const raw = JSON.parse(readFileSync(this.privilegedUsersPath, 'utf8'));
1882
+ const raw: any = parseGateJson(readFileSync(this.privilegedUsersPath, 'utf8'));
1874
1883
  const ids = Array.isArray(raw) ? raw : Array.isArray(raw?.userIds) ? raw.userIds : [];
1875
1884
  this.privilegedUserIds = new Set(ids.map((x: unknown) => String(x)));
1876
1885
  } catch (err) {
@@ -2003,10 +2012,9 @@ export class EventGate {
2003
2012
  // a turn whose exit didn't end it (a retry stop() cancelled, a successor
2004
2013
  // stop() refused) would make every debounced batch buffer until that
2005
2014
  // agent's next turn ended. A turn that continues after the start() takes
2006
- // its entry again (onInferenceResumed). A turn that a start() during the
2007
- // stop() began before this ran loses its entry too, and runs on without
2008
- // it, so debounced batches are delivered while it runs: nothing refuses
2009
- // a start() during a stop() yet.
2015
+ // its entry again (onInferenceResumed). A start() made during the stop()
2016
+ // is refused, so no turn of a new lifecycle can have begun before this
2017
+ // runs.
2010
2018
  this.inferring.clear();
2011
2019
  }
2012
2020
  }
@@ -0,0 +1,59 @@
1
+ import type { MessageId, MessageQuery, StoredMessage } from '@animalabs/context-manager';
2
+
3
+ /**
4
+ * The id a module holds for a write the framework holds. addMessage holds a
5
+ * write while its agent's turn is alive or the host is quiesced, and stores
6
+ * it at a later boundary. Until then, a module's context answers its id as a
7
+ * handle: `held:` and the write's id in the deferred queue. The context's
8
+ * getMessage, editMessage and removeMessage take the handle as they take a
9
+ * stored id, as a process answer's edits and removals do, and once the write
10
+ * lands, the handle names the stored row, which carries the write's id as
11
+ * `metadata.deferredWriteId`.
12
+ */
13
+ const HELD = 'held:';
14
+
15
+ export function heldHandle(writeId: string): MessageId {
16
+ return `${HELD}${writeId}`;
17
+ }
18
+
19
+ /** The deferred write a handle names, or undefined for any other id. A value
20
+ * that isn't a string, which only an untyped caller passes, is no handle,
21
+ * and goes on to the store as it did before handles. */
22
+ export function heldWriteId(id: MessageId): string | undefined {
23
+ return typeof id === 'string' && id.startsWith(HELD) ? id.slice(HELD.length) : undefined;
24
+ }
25
+
26
+ /**
27
+ * Whether a row matches `filter` as context-manager's queryMessages matches a
28
+ * stored one. That's its MessageStore's private matchesFilter at 0.14.1, which
29
+ * the package doesn't export, so the rule is copied here, and a test compares
30
+ * the two on the same rows. A row matches the external source, one of the
31
+ * external ids (an empty list filters nothing), the participant, and each
32
+ * metadata path, dot-separated, by strict equality.
33
+ */
34
+ export function matchesMessageQuery(row: Pick<StoredMessage, 'participant' | 'metadata'>, filter: MessageQuery): boolean {
35
+ const external = row.metadata?.external as { source?: unknown; id?: unknown } | undefined;
36
+ if (filter.source !== undefined && external?.source !== filter.source) return false;
37
+ if (
38
+ filter.externalIds !== undefined &&
39
+ filter.externalIds.length > 0 &&
40
+ (!external?.id || !filter.externalIds.includes(external.id as string))
41
+ ) {
42
+ return false;
43
+ }
44
+ if (filter.participant !== undefined && row.participant !== filter.participant) return false;
45
+ if (filter.metadata !== undefined) {
46
+ for (const [path, value] of Object.entries(filter.metadata)) {
47
+ if (valueAt(row.metadata, path) !== value) return false;
48
+ }
49
+ }
50
+ return true;
51
+ }
52
+
53
+ function valueAt(value: unknown, path: string): unknown {
54
+ for (const part of path.split('.')) {
55
+ if (value === undefined || value === null || typeof value !== 'object') return undefined;
56
+ value = (value as Record<string, unknown>)[part];
57
+ }
58
+ return value;
59
+ }
package/src/index.ts CHANGED
@@ -74,6 +74,7 @@ export type {
74
74
  ExecResult,
75
75
  PyRunnerOptions,
76
76
  ScriptToolCallHandler,
77
+ ScriptToolResult,
77
78
  } from './code-execution/index.js';
78
79
  export type { SessionUsage, AgentUsage, SessionUsageSnapshot, UsageUpdatedEvent } from './usage/index.js';
79
80
 
@@ -97,10 +98,23 @@ export type {
97
98
  // connectMcplServer / disconnectMcplServer / restartMcplServer)
98
99
  export type { McplServerConfig } from './mcpl/index.js';
99
100
 
100
- // MCPL client connection (exposed so external tooling — server playtests,
101
- // health probes, protocol harnesses — can dial an MCPL server exactly the
102
- // way the framework host does, over stdio or WebSocket)
103
- export { McplServerConnection, McplRequestError } from './mcpl/index.js';
101
+ // Both engines' client connections, and the configuration helpers and
102
+ // protocol revisions they share (exposed so external tooling, such as server
103
+ // playtests, health probes and protocol harnesses, can reach a server
104
+ // exactly the way the framework host does: MCPL over stdio or WebSocket, and
105
+ // modern MCP over stdio or Streamable HTTP)
106
+ export { McplServerConnection, McplRequestError, McplProtocolVersionError, McplUnreapedLaunchError } from './mcpl/index.js';
107
+ export { ModernMcpConnection } from './mcpl/index.js';
108
+ export type { ModernToolCallResult } from './mcpl/index.js';
109
+ export {
110
+ LEGACY_MCP_PROTOCOL_VERSION,
111
+ MODERN_MCP_PROTOCOL_VERSION,
112
+ resolveServerBinding,
113
+ serverConfigProblems,
114
+ serverConfigWarnings,
115
+ checkServerConfig,
116
+ } from './mcpl/index.js';
117
+ export type { McpProtocolFamily, McpTransportKind, ServerBinding } from './mcpl/index.js';
104
118
  export type { McplHostCapabilities, McplConnectionCloseInfo } from './mcpl/index.js';
105
119
 
106
120
  // MCPL tool lifecycle (RFC-007) and tool classes (RFC-008): the types a host
@@ -168,6 +182,7 @@ export * from "./tool-presentation.js";
168
182
  export {
169
183
  SILENT_HEARTBEAT_SEPARATOR,
170
184
  silentHeartbeatOf,
185
+ type RequestOnlyPrompt,
171
186
  type SilentHeartbeatStamp,
172
187
  type SilentHeartbeatTick,
173
188
  } from './silent-heartbeat.js';
@@ -223,7 +223,7 @@ export function capabilityPatternMatches(pattern: string, path: string): boolean
223
223
  /** §13.4: denied unless explicitly enabled by host config. RFC-007 adds both
224
224
  * tool-lifecycle leaves: observing other servers' tool use (and, above all,
225
225
  * their arguments) is an operator decision, never a default. */
226
- const DENY_BY_DEFAULT: readonly string[] = [
226
+ export const DENY_BY_DEFAULT: readonly string[] = [
227
227
  'contextHooks.beforeInference.inject.system',
228
228
  'toolLifecycle.observe',
229
229
  'toolLifecycle.inputs',