memeloop 0.0.1 → 0.1.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 (228) hide show
  1. package/README.md +63 -0
  2. package/dist/browser.cjs +1413 -0
  3. package/dist/browser.cjs.map +1 -0
  4. package/dist/browser.d.cts +3066 -0
  5. package/dist/browser.d.ts +3066 -0
  6. package/dist/browser.js +43 -0
  7. package/dist/chunk-426CJUZP.js +630 -0
  8. package/dist/chunk-426CJUZP.js.map +1 -0
  9. package/dist/chunk-44YHBKDL.js +382 -0
  10. package/dist/chunk-44YHBKDL.js.map +1 -0
  11. package/dist/chunk-7ZDTB4VZ.js +63 -0
  12. package/dist/chunk-7ZDTB4VZ.js.map +1 -0
  13. package/dist/chunk-AZFYDWIN.js +98 -0
  14. package/dist/chunk-AZFYDWIN.js.map +1 -0
  15. package/dist/chunk-BGPU4RR7.js +367 -0
  16. package/dist/chunk-BGPU4RR7.js.map +1 -0
  17. package/dist/chunk-CCEFAOSH.js +496 -0
  18. package/dist/chunk-CCEFAOSH.js.map +1 -0
  19. package/dist/chunk-FWSY5HOA.js +63 -0
  20. package/dist/chunk-FWSY5HOA.js.map +1 -0
  21. package/dist/chunk-GYIOMQMY.js +8726 -0
  22. package/dist/chunk-GYIOMQMY.js.map +1 -0
  23. package/dist/chunk-HVB2BR3H.js +42 -0
  24. package/dist/chunk-HVB2BR3H.js.map +1 -0
  25. package/dist/chunk-K6P63KD4.js +68 -0
  26. package/dist/chunk-K6P63KD4.js.map +1 -0
  27. package/dist/chunk-MRKY4HGF.js +205 -0
  28. package/dist/chunk-MRKY4HGF.js.map +1 -0
  29. package/dist/chunk-QFHAAIIM.js +2657 -0
  30. package/dist/chunk-QFHAAIIM.js.map +1 -0
  31. package/dist/chunk-VZKQX5PP.js +1 -0
  32. package/dist/chunk-VZKQX5PP.js.map +1 -0
  33. package/dist/chunk-WAI6BODI.js +175 -0
  34. package/dist/chunk-WAI6BODI.js.map +1 -0
  35. package/dist/chunk-XHRBV6I3.js +3637 -0
  36. package/dist/chunk-XHRBV6I3.js.map +1 -0
  37. package/dist/chunk-YMNXDNDW.js +798 -0
  38. package/dist/chunk-YMNXDNDW.js.map +1 -0
  39. package/dist/conversation.cjs +208 -0
  40. package/dist/conversation.cjs.map +1 -0
  41. package/dist/conversation.d.cts +100 -0
  42. package/dist/conversation.d.ts +100 -0
  43. package/dist/conversation.js +21 -0
  44. package/dist/conversation.js.map +1 -0
  45. package/dist/device-network-portable.cjs +702 -0
  46. package/dist/device-network-portable.cjs.map +1 -0
  47. package/dist/device-network-portable.d.cts +110 -0
  48. package/dist/device-network-portable.d.ts +110 -0
  49. package/dist/device-network-portable.js +53 -0
  50. package/dist/device-network-portable.js.map +1 -0
  51. package/dist/device-network.cjs +906 -0
  52. package/dist/device-network.cjs.map +1 -0
  53. package/dist/device-network.d.cts +6 -0
  54. package/dist/device-network.d.ts +6 -0
  55. package/dist/device-network.js +59 -0
  56. package/dist/device-network.js.map +1 -0
  57. package/dist/fetchProvider-BpcGVSOG.d.cts +91 -0
  58. package/dist/fetchProvider-Cm0sO4Tl.d.ts +91 -0
  59. package/dist/index.cjs +27957 -5459
  60. package/dist/index.cjs.map +1 -1
  61. package/dist/index.d.cts +94 -1320
  62. package/dist/index.d.ts +94 -1320
  63. package/dist/index.js +10576 -2386
  64. package/dist/index.js.map +1 -1
  65. package/dist/interface-IrKBFtL1.d.cts +493 -0
  66. package/dist/interface-IrKBFtL1.d.ts +493 -0
  67. package/dist/llm-providers.cjs +43 -8
  68. package/dist/llm-providers.cjs.map +1 -1
  69. package/dist/llm-providers.d.cts +2 -1
  70. package/dist/llm-providers.d.ts +2 -1
  71. package/dist/llm-providers.js +4 -2
  72. package/dist/llm-providers.js.map +1 -1
  73. package/dist/loop-api.cjs +5177 -2050
  74. package/dist/loop-api.cjs.map +1 -1
  75. package/dist/loop-api.d.cts +11 -5
  76. package/dist/loop-api.d.ts +11 -5
  77. package/dist/loop-api.js +84 -49
  78. package/dist/mobile.cjs +2625 -0
  79. package/dist/mobile.cjs.map +1 -0
  80. package/dist/mobile.d.cts +6 -0
  81. package/dist/mobile.d.ts +6 -0
  82. package/dist/mobile.js +22 -0
  83. package/dist/mobile.js.map +1 -0
  84. package/dist/orchestration-portable-Bsf8YRfp.d.cts +2192 -0
  85. package/dist/orchestration-portable-Zw0g5tbj.d.ts +2192 -0
  86. package/dist/orchestration-portable.cjs +9553 -0
  87. package/dist/orchestration-portable.cjs.map +1 -0
  88. package/dist/orchestration-portable.d.cts +5 -0
  89. package/dist/orchestration-portable.d.ts +5 -0
  90. package/dist/orchestration-portable.js +290 -0
  91. package/dist/orchestration-portable.js.map +1 -0
  92. package/dist/pairingInvite-BXPWY3aM.d.cts +149 -0
  93. package/dist/pairingInvite-Cuz0wuq9.d.ts +149 -0
  94. package/dist/promptConcat-WTN-uHcz.d.cts +516 -0
  95. package/dist/promptConcat-deDSWZE3.d.ts +516 -0
  96. package/dist/providerRegistry-9trr5aoK.d.ts +86 -0
  97. package/dist/providerRegistry-xk_B1Ekv.d.cts +86 -0
  98. package/dist/registry-8eztoD_r.d.cts +393 -0
  99. package/dist/registry-DV24sI-3.d.ts +393 -0
  100. package/dist/remoteClient-B_spK019.d.ts +87 -0
  101. package/dist/remoteClient-CBggnRy3.d.cts +87 -0
  102. package/dist/runtime-SKSXVYIM.js +18 -0
  103. package/dist/runtime-SKSXVYIM.js.map +1 -0
  104. package/dist/scriptDeploymentPipeline-BAeo1dPb.d.cts +2463 -0
  105. package/dist/scriptDeploymentPipeline-DsnT0AG6.d.ts +2463 -0
  106. package/dist/syncCloudDevices-BEqwgrhD.d.ts +49 -0
  107. package/dist/syncCloudDevices-Ds_Kcgrv.d.cts +49 -0
  108. package/dist/types-7pYti-k9.d.cts +255 -0
  109. package/dist/types-CdFVSntj.d.ts +255 -0
  110. package/package.json +110 -35
  111. package/dist/anthropic.cjs +0 -72
  112. package/dist/anthropic.cjs.map +0 -1
  113. package/dist/anthropic.d.cts +0 -21
  114. package/dist/anthropic.d.ts +0 -21
  115. package/dist/anthropic.js +0 -21
  116. package/dist/anthropic.js.map +0 -1
  117. package/dist/azure.cjs +0 -72
  118. package/dist/azure.cjs.map +0 -1
  119. package/dist/azure.d.cts +0 -21
  120. package/dist/azure.d.ts +0 -21
  121. package/dist/azure.js +0 -21
  122. package/dist/azure.js.map +0 -1
  123. package/dist/chunk-3CN7DFBL.js +0 -4894
  124. package/dist/chunk-3CN7DFBL.js.map +0 -1
  125. package/dist/chunk-4AZ4D7U5.js +0 -32
  126. package/dist/chunk-4AZ4D7U5.js.map +0 -1
  127. package/dist/chunk-6ON4XSOV.js +0 -63
  128. package/dist/chunk-6ON4XSOV.js.map +0 -1
  129. package/dist/chunk-DJQNGIXX.js +0 -4793
  130. package/dist/chunk-DJQNGIXX.js.map +0 -1
  131. package/dist/chunk-FKQP6AOQ.js +0 -32
  132. package/dist/chunk-FKQP6AOQ.js.map +0 -1
  133. package/dist/chunk-OVJ7JJBA.js +0 -35
  134. package/dist/chunk-OVJ7JJBA.js.map +0 -1
  135. package/dist/chunk-P4UZ7IXC.js +0 -42
  136. package/dist/chunk-YHJ2AEFR.js +0 -4933
  137. package/dist/chunk-YHJ2AEFR.js.map +0 -1
  138. package/dist/chunk-YVK7RYRO.js +0 -4973
  139. package/dist/chunk-YVK7RYRO.js.map +0 -1
  140. package/dist/code-assistant.json +0 -114
  141. package/dist/cohere.cjs +0 -72
  142. package/dist/cohere.cjs.map +0 -1
  143. package/dist/cohere.d.cts +0 -21
  144. package/dist/cohere.d.ts +0 -21
  145. package/dist/cohere.js +0 -21
  146. package/dist/cohere.js.map +0 -1
  147. package/dist/deepseek.cjs +0 -72
  148. package/dist/deepseek.cjs.map +0 -1
  149. package/dist/deepseek.d.cts +0 -21
  150. package/dist/deepseek.d.ts +0 -21
  151. package/dist/deepseek.js +0 -21
  152. package/dist/deepseek.js.map +0 -1
  153. package/dist/dist-65U7OYRG.js +0 -1257
  154. package/dist/dist-65U7OYRG.js.map +0 -1
  155. package/dist/fetchProvider-Cu4WkU5O.d.cts +0 -819
  156. package/dist/fetchProvider-Cu4WkU5O.d.ts +0 -819
  157. package/dist/frontend-ui-ux.json +0 -105
  158. package/dist/general-assistant.json +0 -95
  159. package/dist/git-master.json +0 -51
  160. package/dist/google-vertex.cjs +0 -72
  161. package/dist/google-vertex.cjs.map +0 -1
  162. package/dist/google-vertex.d.cts +0 -21
  163. package/dist/google-vertex.d.ts +0 -21
  164. package/dist/google-vertex.js +0 -21
  165. package/dist/google-vertex.js.map +0 -1
  166. package/dist/google.cjs +0 -72
  167. package/dist/google.cjs.map +0 -1
  168. package/dist/google.d.cts +0 -21
  169. package/dist/google.d.ts +0 -21
  170. package/dist/google.js +0 -21
  171. package/dist/google.js.map +0 -1
  172. package/dist/groq.cjs +0 -72
  173. package/dist/groq.cjs.map +0 -1
  174. package/dist/groq.d.cts +0 -21
  175. package/dist/groq.d.ts +0 -21
  176. package/dist/groq.js +0 -21
  177. package/dist/groq.js.map +0 -1
  178. package/dist/index.d.mts +0 -3203
  179. package/dist/index.mjs +0 -7064
  180. package/dist/index.mjs.map +0 -1
  181. package/dist/mistral.cjs +0 -72
  182. package/dist/mistral.cjs.map +0 -1
  183. package/dist/mistral.d.cts +0 -21
  184. package/dist/mistral.d.ts +0 -21
  185. package/dist/mistral.js +0 -21
  186. package/dist/mistral.js.map +0 -1
  187. package/dist/multipart-parser-EJCXIUHC.js +0 -372
  188. package/dist/multipart-parser-EJCXIUHC.js.map +0 -1
  189. package/dist/openai.cjs +0 -72
  190. package/dist/openai.cjs.map +0 -1
  191. package/dist/openai.d.cts +0 -21
  192. package/dist/openai.d.ts +0 -21
  193. package/dist/openai.js +0 -21
  194. package/dist/openai.js.map +0 -1
  195. package/dist/perplexity.cjs +0 -72
  196. package/dist/perplexity.cjs.map +0 -1
  197. package/dist/perplexity.d.cts +0 -21
  198. package/dist/perplexity.d.ts +0 -21
  199. package/dist/perplexity.js +0 -21
  200. package/dist/perplexity.js.map +0 -1
  201. package/dist/playwright.json +0 -52
  202. package/dist/promptConcat-BJdazTg5.d.cts +0 -1832
  203. package/dist/promptConcat-BJdazTg5.d.ts +0 -1832
  204. package/dist/promptConcat-CAkpni_8.d.cts +0 -1834
  205. package/dist/promptConcat-CAkpni_8.d.ts +0 -1834
  206. package/dist/promptConcat-CfH5-GAE.d.cts +0 -1036
  207. package/dist/promptConcat-ChcAZOOL.d.ts +0 -1036
  208. package/dist/promptConcat-G5TnJVRy.d.cts +0 -1800
  209. package/dist/promptConcat-G5TnJVRy.d.ts +0 -1800
  210. package/dist/promptConcat-L72eowzp.d.ts +0 -1090
  211. package/dist/promptConcat-eLHdN7K8.d.cts +0 -1090
  212. package/dist/src-VTSXKG72.js +0 -1409
  213. package/dist/src-VTSXKG72.js.map +0 -1
  214. package/dist/togetherai.cjs +0 -72
  215. package/dist/togetherai.cjs.map +0 -1
  216. package/dist/togetherai.d.cts +0 -21
  217. package/dist/togetherai.d.ts +0 -21
  218. package/dist/togetherai.js +0 -21
  219. package/dist/togetherai.js.map +0 -1
  220. package/dist/types-B0Jm2l38.d.cts +0 -767
  221. package/dist/types-B0Jm2l38.d.ts +0 -767
  222. package/dist/xai.cjs +0 -72
  223. package/dist/xai.cjs.map +0 -1
  224. package/dist/xai.d.cts +0 -21
  225. package/dist/xai.d.ts +0 -21
  226. package/dist/xai.js +0 -21
  227. package/dist/xai.js.map +0 -1
  228. /package/dist/{chunk-P4UZ7IXC.js.map → browser.js.map} +0 -0
@@ -0,0 +1,3637 @@
1
+ import {
2
+ containsSecrets
3
+ } from "./chunk-AZFYDWIN.js";
4
+ import {
5
+ MEMELOOP_STRUCTURED_TOOL_KEY,
6
+ createAgentToolLoopRunner,
7
+ createAgentToolLoopState,
8
+ getActivePluginRegistry,
9
+ getBuiltinLoopProfile,
10
+ getLoopRegistry,
11
+ nextLamportClockForConversation,
12
+ runAgentToolLoopIteration,
13
+ startAgentToolLoopTurn,
14
+ stopAgentToolLoopTurn,
15
+ truncateToolSummary
16
+ } from "./chunk-QFHAAIIM.js";
17
+ import {
18
+ AGENT_WORKLOAD_API_VERSION,
19
+ AGENT_WORKLOAD_KIND,
20
+ agentRunReference,
21
+ agentWorkloadReference,
22
+ createAgentRunManifest,
23
+ createAgentWorkloadManifest,
24
+ createArtifactRecordManifest,
25
+ isAgentRun,
26
+ isAgentWorkload
27
+ } from "./chunk-BGPU4RR7.js";
28
+ import {
29
+ OrchestrationError,
30
+ toOrchestrationErrorData
31
+ } from "./chunk-FWSY5HOA.js";
32
+
33
+ // src/orchestration/agentClient.ts
34
+ function requireName(name, generateName, label) {
35
+ if (name) return name;
36
+ if (generateName) return `${generateName}${Math.random().toString(36).slice(2, 8)}`;
37
+ throw new OrchestrationError({ code: "INVALID", message: `${label} requires name or generateName`, retryable: false });
38
+ }
39
+ var CANCELLATION_POLL_INTERVAL_MS = 50;
40
+ function cancellationError(lastResourceVersion) {
41
+ return new OrchestrationError({
42
+ code: "CANCELLED",
43
+ message: "condition wait cancelled",
44
+ retryable: false,
45
+ details: { lastResourceVersion }
46
+ });
47
+ }
48
+ function throwIfCancelled(options, lastResourceVersion) {
49
+ if (options.signal?.aborted || options.isCancelled?.() === true) {
50
+ throw cancellationError(lastResourceVersion);
51
+ }
52
+ }
53
+ function abortableDelay(ms, signal, lastResourceVersion) {
54
+ if (!signal) {
55
+ return new Promise((resolve) => {
56
+ setTimeout(resolve, ms);
57
+ });
58
+ }
59
+ return new Promise((resolve, reject) => {
60
+ const onAbort = () => {
61
+ clearTimeout(timeout);
62
+ signal.removeEventListener("abort", onAbort);
63
+ reject(cancellationError(lastResourceVersion));
64
+ };
65
+ const timeout = setTimeout(() => {
66
+ signal.removeEventListener("abort", onAbort);
67
+ resolve();
68
+ }, ms);
69
+ signal.addEventListener("abort", onAbort, { once: true });
70
+ if (signal.aborted) onAbort();
71
+ });
72
+ }
73
+ async function waitInterval(ms, options, lastResourceVersion) {
74
+ if (!options.isCancelled) {
75
+ await abortableDelay(ms, options.signal, lastResourceVersion);
76
+ return;
77
+ }
78
+ for (let remaining = ms; remaining > 0; remaining -= CANCELLATION_POLL_INTERVAL_MS) {
79
+ throwIfCancelled(options, lastResourceVersion);
80
+ await abortableDelay(Math.min(remaining, CANCELLATION_POLL_INTERVAL_MS), options.signal, lastResourceVersion);
81
+ }
82
+ throwIfCancelled(options, lastResourceVersion);
83
+ }
84
+ async function waitForCondition(get, condition, options) {
85
+ const intervalMs = Math.max(100, options.interval ?? 1e3);
86
+ const timeoutMs = options.timeout ?? 3e4;
87
+ const deadline = Date.now() + timeoutMs;
88
+ let lastResourceVersion = "0";
89
+ while (true) {
90
+ throwIfCancelled(options, lastResourceVersion);
91
+ const resource = await get();
92
+ throwIfCancelled(options, lastResourceVersion);
93
+ if (resource) {
94
+ lastResourceVersion = resource.metadata?.resourceVersion ?? "0";
95
+ const match = resource.status?.conditions?.find(
96
+ (candidate) => candidate.type === condition.type && candidate.status === condition.status
97
+ );
98
+ if (match) {
99
+ return { observedResourceVersion: lastResourceVersion, matched: true };
100
+ }
101
+ }
102
+ if (Date.now() + intervalMs > deadline) {
103
+ throw new OrchestrationError({
104
+ code: "TIMEOUT",
105
+ message: `condition ${condition.type}=${condition.status} not met within ${timeoutMs}ms`,
106
+ retryable: true,
107
+ details: { lastResourceVersion }
108
+ });
109
+ }
110
+ await waitInterval(intervalMs, options, lastResourceVersion);
111
+ }
112
+ }
113
+ function createAgentClient(client, defaultNamespace) {
114
+ function resolveNamespace(namespace) {
115
+ return namespace ?? defaultNamespace;
116
+ }
117
+ return {
118
+ async createWorkload(options) {
119
+ const name = requireName(options.name, options.generateName, "AgentWorkload");
120
+ const manifest = createAgentWorkloadManifest(name, {
121
+ profileId: options.profileId,
122
+ scriptReference: options.scriptReference,
123
+ promptReference: options.promptReference,
124
+ trust: options.trust,
125
+ placement: options.placement,
126
+ modelPolicy: options.modelPolicy,
127
+ toolPolicy: options.toolPolicy,
128
+ networkPolicy: options.networkPolicy,
129
+ storagePolicy: options.storagePolicy,
130
+ completionPolicy: options.completionPolicy,
131
+ ownerReferences: options.ownerReferences
132
+ });
133
+ const result = await client.apply(manifest, {
134
+ idempotencyKey: options.idempotencyKey,
135
+ fieldManager: "memeloop-agent-client"
136
+ });
137
+ if (!isAgentWorkload(result)) {
138
+ throw new OrchestrationError({ code: "UNKNOWN_EFFECT", message: "apply returned a non-AgentWorkload resource", retryable: false });
139
+ }
140
+ return result;
141
+ },
142
+ async getWorkload(name, namespace) {
143
+ const result = await client.get(agentWorkloadReference(name, resolveNamespace(namespace)));
144
+ return result && isAgentWorkload(result) ? result : null;
145
+ },
146
+ async deleteWorkload(name, namespace) {
147
+ await client.delete(agentWorkloadReference(name, resolveNamespace(namespace)));
148
+ },
149
+ async waitForWorkloadCondition(name, condition, options = {}) {
150
+ return waitForCondition(
151
+ () => this.getWorkload(name, defaultNamespace),
152
+ condition,
153
+ options
154
+ );
155
+ },
156
+ async createRun(options) {
157
+ const name = requireName(options.name, options.generateName, "AgentRun");
158
+ const manifest = createAgentRunManifest(name, {
159
+ workloadRef: agentWorkloadReference(options.workloadName, options.workloadNamespace ?? defaultNamespace),
160
+ promptReference: options.promptReference,
161
+ retry: options.retry,
162
+ timeoutMs: options.timeoutMs
163
+ });
164
+ const result = await client.apply(manifest, {
165
+ idempotencyKey: options.idempotencyKey,
166
+ fieldManager: "memeloop-agent-client"
167
+ });
168
+ if (!isAgentRun(result)) {
169
+ throw new OrchestrationError({ code: "UNKNOWN_EFFECT", message: "apply returned a non-AgentRun resource", retryable: false });
170
+ }
171
+ return result;
172
+ },
173
+ async getRun(name, namespace) {
174
+ const result = await client.get(agentRunReference(name, resolveNamespace(namespace)));
175
+ return result && isAgentRun(result) ? result : null;
176
+ },
177
+ async deleteRun(name, namespace) {
178
+ await client.delete(agentRunReference(name, resolveNamespace(namespace)));
179
+ },
180
+ async waitForRunCondition(name, condition, options = {}) {
181
+ return waitForCondition(
182
+ () => this.getRun(name, defaultNamespace),
183
+ condition,
184
+ options
185
+ );
186
+ }
187
+ };
188
+ }
189
+
190
+ // src/tools/schemaRegistry.ts
191
+ import { zodToJsonSchema } from "zod-to-json-schema";
192
+ var toolSchemas = /* @__PURE__ */ new Map();
193
+ var toolMetadata = /* @__PURE__ */ new Map();
194
+ function toolSchemaToJsonSchema(value) {
195
+ const native = value?.toJSONSchema?.();
196
+ if (native) return structuredClone(native);
197
+ if (value !== null && typeof value === "object" && "_def" in value) {
198
+ const converted = zodToJsonSchema(value, {
199
+ $refStrategy: "none"
200
+ });
201
+ return structuredClone(converted);
202
+ }
203
+ if (value !== null && typeof value === "object" && !Array.isArray(value) && ("type" in value || "properties" in value || "$ref" in value || "oneOf" in value || "anyOf" in value)) {
204
+ return structuredClone(value);
205
+ }
206
+ throw new TypeError(
207
+ "Tool parameter schema must be a Zod schema or a portable JSON Schema"
208
+ );
209
+ }
210
+ function registerToolParameterSchema(toolId, schema, metadata) {
211
+ toolSchemas.set(toolId, schema);
212
+ if (metadata) {
213
+ toolMetadata.set(toolId, metadata);
214
+ }
215
+ }
216
+ function getToolParameterSchema(toolId) {
217
+ return toolSchemas.get(toolId);
218
+ }
219
+ function getToolMetadata(toolId) {
220
+ return toolMetadata.get(toolId);
221
+ }
222
+
223
+ // src/orchestration/scripts/scriptRuntime.ts
224
+ var BUILTIN_RUNTIME_CLASSES = {
225
+ "trusted-process": {
226
+ isolation: "process",
227
+ cpuLimitMillis: 2e3,
228
+ memoryLimitBytes: 512 * 1024 * 1024,
229
+ // 512 MiB
230
+ timeLimitMs: 3e5,
231
+ // 5 min
232
+ supportsCancellation: true,
233
+ supportedTrustClasses: ["trusted"],
234
+ networkAccess: "full"
235
+ },
236
+ "restricted-process": {
237
+ isolation: "process",
238
+ cpuLimitMillis: 1e3,
239
+ memoryLimitBytes: 128 * 1024 * 1024,
240
+ // 128 MiB
241
+ timeLimitMs: 12e4,
242
+ // 2 min
243
+ supportsCancellation: true,
244
+ supportedTrustClasses: ["trusted", "restricted"],
245
+ networkAccess: "outbound-only"
246
+ },
247
+ "quarantine-process": {
248
+ isolation: "process",
249
+ cpuLimitMillis: 500,
250
+ // A Node VM plus the trusted worker bootstrap needs more than 32 MiB RSS;
251
+ // the Linux host enforces this value as cgroup MemoryMax, not only V8 heap.
252
+ memoryLimitBytes: 96 * 1024 * 1024,
253
+ // 96 MiB
254
+ timeLimitMs: 3e4,
255
+ // 30 sec
256
+ supportsCancellation: true,
257
+ supportedTrustClasses: ["quarantine"],
258
+ networkAccess: "none"
259
+ }
260
+ };
261
+ function selectRuntimeClass(trustClass, available = Object.keys(BUILTIN_RUNTIME_CLASSES)) {
262
+ const exact = available.find((name2) => {
263
+ const spec2 = BUILTIN_RUNTIME_CLASSES[name2];
264
+ return spec2?.supportedTrustClasses.includes(trustClass);
265
+ });
266
+ if (!exact) {
267
+ throw new Error("No RuntimeClass available for trust class: " + trustClass);
268
+ }
269
+ const name = exact;
270
+ const spec = BUILTIN_RUNTIME_CLASSES[name];
271
+ return {
272
+ runtimeClass: name,
273
+ isolation: spec.isolation,
274
+ cpuLimitMillis: spec.cpuLimitMillis ?? 500,
275
+ memoryLimitBytes: spec.memoryLimitBytes ?? 32 * 1024 * 1024,
276
+ timeLimitMs: spec.timeLimitMs ?? 3e4,
277
+ networkAccess: spec.networkAccess
278
+ };
279
+ }
280
+
281
+ // src/orchestration/scripts/scriptAdmission.ts
282
+ var TRUST_PROFILES = {
283
+ trusted: {
284
+ maxScriptBytes: 1048576,
285
+ // 1 MiB
286
+ allowedInterfaces: ["resource", "loop-runtime", "tool-execution", "model-provider", "network", "storage", "credential-broker", "artifact"],
287
+ forbiddenImports: [],
288
+ requireDefaultExport: true,
289
+ allowUntrustedInputs: false
290
+ },
291
+ restricted: {
292
+ maxScriptBytes: 256e3,
293
+ // 256 KiB
294
+ allowedInterfaces: ["resource", "loop-runtime", "model-provider"],
295
+ forbiddenImports: ["node:fs", "node:child_process", "node:net", "node:http", "node:https"],
296
+ requireDefaultExport: true,
297
+ allowUntrustedInputs: false
298
+ },
299
+ quarantine: {
300
+ maxScriptBytes: 64e3,
301
+ // 64 KiB
302
+ allowedInterfaces: ["loop-runtime"],
303
+ // No network, no file system, no model provider
304
+ forbiddenImports: ["node:fs", "node:child_process", "node:net", "node:http", "node:https", "node:os", "node:crypto"],
305
+ requireDefaultExport: true,
306
+ allowUntrustedInputs: false
307
+ }
308
+ };
309
+ var COMPATIBLE_CHECKPOINT_VERSIONS = /* @__PURE__ */ new Set(["loops.memeloop.io/v1alpha1"]);
310
+ function defaultRequestedInterfacesForTrustClass(trustClass) {
311
+ return [...TRUST_PROFILES[trustClass].allowedInterfaces];
312
+ }
313
+ function maxScriptBytesForTrustClass(trustClass) {
314
+ return TRUST_PROFILES[trustClass].maxScriptBytes;
315
+ }
316
+ function admitScript(request) {
317
+ const profile = TRUST_PROFILES[request.authorTrust];
318
+ const approvedInterfaces = [];
319
+ if (request.script.sizeBytes > profile.maxScriptBytes) {
320
+ return {
321
+ admitted: false,
322
+ reason: `Script size ${request.script.sizeBytes} exceeds ${request.authorTrust} limit ${profile.maxScriptBytes}`,
323
+ approvedInterfaces: [],
324
+ checkpointCompatible: false,
325
+ retryable: true
326
+ };
327
+ }
328
+ if (!request.script.valid) {
329
+ return {
330
+ admitted: false,
331
+ reason: `Script validation failed: ${request.script.errors.join("; ")}`,
332
+ approvedInterfaces: [],
333
+ checkpointCompatible: false,
334
+ retryable: true
335
+ };
336
+ }
337
+ if (profile.requireDefaultExport && !request.script.hasDefaultExport) {
338
+ return {
339
+ admitted: false,
340
+ reason: "Script must export a default async generator",
341
+ approvedInterfaces: [],
342
+ checkpointCompatible: false,
343
+ retryable: true
344
+ };
345
+ }
346
+ for (const imp of request.script.imports) {
347
+ if (profile.forbiddenImports.includes(imp) || profile.forbiddenImports.includes(imp.replace(/^node:/, ""))) {
348
+ return {
349
+ admitted: false,
350
+ reason: `Import '${imp}' not allowed for ${request.authorTrust} scripts`,
351
+ approvedInterfaces: [],
352
+ checkpointCompatible: false,
353
+ retryable: false
354
+ };
355
+ }
356
+ }
357
+ for (const iface of request.requestedInterfaces) {
358
+ if (!profile.allowedInterfaces.includes(iface)) {
359
+ return {
360
+ admitted: false,
361
+ reason: `Interface '${iface}' not allowed for ${request.authorTrust} scripts`,
362
+ approvedInterfaces: [],
363
+ checkpointCompatible: false,
364
+ retryable: false
365
+ };
366
+ }
367
+ approvedInterfaces.push(iface);
368
+ }
369
+ let checkpointCompatible = true;
370
+ if (request.expectedCheckpointDigest && request.checkpointApiVersion) {
371
+ if (!COMPATIBLE_CHECKPOINT_VERSIONS.has(request.checkpointApiVersion)) {
372
+ checkpointCompatible = false;
373
+ }
374
+ if (request.expectedCheckpointDigest !== request.script.digest) {
375
+ checkpointCompatible = false;
376
+ }
377
+ }
378
+ return {
379
+ admitted: true,
380
+ reason: `Admitted as ${request.authorTrust}`,
381
+ approvedInterfaces,
382
+ checkpointCompatible,
383
+ retryable: false
384
+ };
385
+ }
386
+
387
+ // src/orchestration/scripts/scriptValidation.ts
388
+ import { parse } from "acorn";
389
+ var MAX_SCRIPT_BYTES = 1048576;
390
+ function isAstNode(value) {
391
+ return typeof value === "object" && value !== null && typeof value.type === "string";
392
+ }
393
+ function walkAst(node, visit) {
394
+ visit(node);
395
+ for (const key of Object.keys(node)) {
396
+ const value = node[key];
397
+ if (Array.isArray(value)) {
398
+ for (const child of value) {
399
+ if (isAstNode(child)) walkAst(child, visit);
400
+ }
401
+ } else if (isAstNode(value)) {
402
+ walkAst(value, visit);
403
+ }
404
+ }
405
+ }
406
+ function isAsyncGeneratorFunction(node) {
407
+ if (!node) return false;
408
+ return (node.type === "FunctionDeclaration" || node.type === "FunctionExpression") && node.async === true && node.generator === true;
409
+ }
410
+ function getStaticImportSource(node) {
411
+ const source = node.source;
412
+ if (source && source.type === "Literal" && typeof source.value === "string") {
413
+ return source.value;
414
+ }
415
+ return void 0;
416
+ }
417
+ function isCommonJsExportAssignment(node) {
418
+ if (node.type !== "AssignmentExpression") return false;
419
+ const left = node.left;
420
+ if (!left || left.type !== "MemberExpression" || left.computed === true) return false;
421
+ const object = left.object;
422
+ const property = left.property;
423
+ if (!object || object.type !== "Identifier" || !property || property.type !== "Identifier") {
424
+ return false;
425
+ }
426
+ if (object.name === "exports") return true;
427
+ return object.name === "module" && property.name === "exports";
428
+ }
429
+ async function digestNormalizedScript(normalizedSource) {
430
+ const encoded = new TextEncoder().encode(normalizedSource);
431
+ const hash = await crypto.subtle.digest("SHA-256", encoded);
432
+ return Array.from(new Uint8Array(hash)).map((b) => b.toString(16).padStart(2, "0")).join("");
433
+ }
434
+ async function validateScript(source) {
435
+ const errors = [];
436
+ const imports = [];
437
+ let hasDefaultExport = false;
438
+ let hasNonLiteralDynamicImport = false;
439
+ const normalized = normalizeScript(source);
440
+ const encoded = new TextEncoder().encode(normalized);
441
+ if (encoded.length > MAX_SCRIPT_BYTES) {
442
+ errors.push(`Script exceeds ${MAX_SCRIPT_BYTES} bytes (got ${encoded.length})`);
443
+ }
444
+ if (normalized.trim().length === 0) {
445
+ errors.push("Script is empty");
446
+ }
447
+ const digest = await digestNormalizedScript(normalized);
448
+ let program;
449
+ if (normalized.trim().length > 0) {
450
+ try {
451
+ program = parse(normalized, { ecmaVersion: "latest", sourceType: "module" });
452
+ } catch (error) {
453
+ errors.push(`Syntax error: ${error instanceof Error ? error.message : String(error)}`);
454
+ }
455
+ }
456
+ if (program) {
457
+ const topLevel = Array.isArray(program.body) ? program.body : [];
458
+ for (const statement of topLevel) {
459
+ if (statement.type !== "ExportDefaultDeclaration") continue;
460
+ const declaration = statement.declaration;
461
+ if (isAsyncGeneratorFunction(declaration)) {
462
+ hasDefaultExport = true;
463
+ } else if (declaration?.type === "Identifier") {
464
+ const identifier = declaration;
465
+ hasDefaultExport = topLevel.some((candidate) => {
466
+ if (isAsyncGeneratorFunction(candidate) && candidate.id?.name === identifier.name) {
467
+ return true;
468
+ }
469
+ if (candidate.type === "VariableDeclaration" && Array.isArray(candidate.declarations)) {
470
+ return candidate.declarations.some(
471
+ (declarator) => declarator.id?.name === identifier.name && isAsyncGeneratorFunction(declarator.init)
472
+ );
473
+ }
474
+ return false;
475
+ });
476
+ }
477
+ }
478
+ walkAst(program, (node) => {
479
+ if (node.type === "ImportDeclaration") {
480
+ const specifier = getStaticImportSource(node);
481
+ if (specifier !== void 0) imports.push(specifier);
482
+ } else if (node.type === "ExportNamedDeclaration" || node.type === "ExportAllDeclaration") {
483
+ const specifier = getStaticImportSource(node);
484
+ if (specifier !== void 0) imports.push(specifier);
485
+ } else if (node.type === "ImportExpression") {
486
+ const specifier = getStaticImportSource(node);
487
+ if (specifier !== void 0) {
488
+ imports.push(specifier);
489
+ } else {
490
+ hasNonLiteralDynamicImport = true;
491
+ }
492
+ } else if (isCommonJsExportAssignment(node)) {
493
+ errors.push("CommonJS module.exports not supported (use ESM export)");
494
+ }
495
+ });
496
+ }
497
+ for (const specifier of imports) {
498
+ if (isForbiddenImport(specifier)) {
499
+ errors.push(`Forbidden import: ${specifier}`);
500
+ }
501
+ }
502
+ if (hasNonLiteralDynamicImport) {
503
+ errors.push("Dynamic import() with a non-literal argument is not allowed (defeats admission control)");
504
+ }
505
+ if (!hasDefaultExport) {
506
+ errors.push("Script must export a default async generator function");
507
+ }
508
+ return {
509
+ valid: errors.length === 0,
510
+ digest,
511
+ imports,
512
+ hasDefaultExport,
513
+ hasNonLiteralDynamicImport,
514
+ errors,
515
+ sizeBytes: encoded.length
516
+ };
517
+ }
518
+ function normalizeScript(source) {
519
+ return source.replace(/^\uFEFF/, "").replace(/\r\n/g, "\n").replace(/\r/g, "\n").split("\n").map((line) => line.trimEnd()).join("\n").trim() + "\n";
520
+ }
521
+ function isForbiddenImport(spec) {
522
+ const builtins = /* @__PURE__ */ new Set([
523
+ "fs",
524
+ "path",
525
+ "child_process",
526
+ "net",
527
+ "http",
528
+ "https",
529
+ "os",
530
+ "crypto",
531
+ "tls",
532
+ "dgram",
533
+ "dns",
534
+ "readline",
535
+ "repl",
536
+ "stream",
537
+ "timers",
538
+ "tty",
539
+ "url",
540
+ "util",
541
+ "v8",
542
+ "vm",
543
+ "worker_threads",
544
+ "zlib",
545
+ "assert",
546
+ "buffer",
547
+ "querystring",
548
+ "string_decoder"
549
+ ]);
550
+ const base = spec.replace(/^node:/, "");
551
+ if (builtins.has(base) && spec !== "node:events") return true;
552
+ if (spec.startsWith("@libp2p/") || spec.startsWith("@chainsafe/libp2p") || spec === "libp2p") {
553
+ return true;
554
+ }
555
+ if (spec === "memeloop" || spec.startsWith("memeloop/")) return true;
556
+ return false;
557
+ }
558
+
559
+ // src/orchestration/scripts/scriptDeploymentPipeline.ts
560
+ var LIFECYCLE_TO_COMPLETION_POLICY = {
561
+ "run-once": "complete",
562
+ service: "daemon",
563
+ schedule: "detach"
564
+ };
565
+ function remoteDeploymentToWorkloadManifest(deployment, options = {}) {
566
+ const manifest = createAgentWorkloadManifest(options.name ?? deployment.artifactRef.name, {
567
+ scriptReference: deployment.artifactRef.contentDigest,
568
+ trust: deployment.trustClass,
569
+ runtimeClass: deployment.runtimeClass,
570
+ completionPolicy: LIFECYCLE_TO_COMPLETION_POLICY[deployment.lifecycle],
571
+ ...deployment.nodeSelector ? { placement: { nodeSelector: deployment.nodeSelector } } : {},
572
+ ...deployment.env ? { env: deployment.env } : {},
573
+ ...deployment.networkPolicy ? { networkPolicy: deployment.networkPolicy } : {},
574
+ ...deployment.storagePolicy ? { storagePolicy: deployment.storagePolicy } : {},
575
+ ...options.ownerReferences ? { ownerReferences: options.ownerReferences } : {}
576
+ });
577
+ const namespace = options.namespace ?? deployment.artifactRef.namespace;
578
+ if (namespace !== void 0) {
579
+ manifest.metadata.namespace = namespace;
580
+ }
581
+ return manifest;
582
+ }
583
+ async function deployGeneratedScript(request, options = {}) {
584
+ const validation = await validateScript(request.source);
585
+ if (!validation.valid) {
586
+ return {
587
+ deployed: false,
588
+ reason: `Script validation failed: ${validation.errors.join("; ")}`,
589
+ validation
590
+ };
591
+ }
592
+ const admission = admitScript({
593
+ script: validation,
594
+ authorTrust: request.authorTrust,
595
+ requestedInterfaces: request.requestedInterfaces,
596
+ expectedCheckpointDigest: request.expectedCheckpointDigest,
597
+ checkpointApiVersion: request.checkpointApiVersion
598
+ });
599
+ if (!admission.admitted) {
600
+ return { deployed: false, reason: admission.reason, validation, admission };
601
+ }
602
+ if (request.expectedCheckpointDigest !== void 0 && !admission.checkpointCompatible) {
603
+ return {
604
+ deployed: false,
605
+ reason: "Checkpoint is incompatible with this script digest/API version; an explicit converter or restart policy is required",
606
+ validation,
607
+ admission
608
+ };
609
+ }
610
+ for (const [name, value] of Object.entries(request.env ?? {})) {
611
+ if (containsSecrets(value)) {
612
+ return {
613
+ deployed: false,
614
+ reason: `Environment variable '${name}' carries a secret-shaped value; workload env must never contain credentials (plan 24.35)`,
615
+ validation,
616
+ admission
617
+ };
618
+ }
619
+ }
620
+ const contentDigest = `sha256:${validation.digest}`;
621
+ const artifactName = `script-${validation.digest}`;
622
+ const artifact = createArtifactRecordManifest(artifactName, {
623
+ contentHash: contentDigest,
624
+ sizeBytes: validation.sizeBytes,
625
+ mimeType: "text/javascript",
626
+ producer: { trust: request.authorTrust },
627
+ trust: request.authorTrust
628
+ });
629
+ if (request.namespace !== void 0) {
630
+ artifact.metadata.namespace = request.namespace;
631
+ }
632
+ await options.artifactStore?.putArtifact(artifact, normalizeScript(request.source));
633
+ const runtimeClass = selectRuntimeClass(request.authorTrust, options.availableRuntimeClasses);
634
+ const deployment = {
635
+ artifactRef: {
636
+ apiVersion: artifact.apiVersion,
637
+ kind: "ArtifactRecord",
638
+ name: artifactName,
639
+ namespace: artifact.metadata.namespace,
640
+ contentDigest
641
+ },
642
+ trustClass: request.authorTrust,
643
+ lifecycle: request.lifecycle,
644
+ runtimeClass: runtimeClass.runtimeClass,
645
+ nodeSelector: request.nodeSelector,
646
+ env: request.env,
647
+ networkPolicy: request.networkPolicy,
648
+ storagePolicy: request.storagePolicy
649
+ };
650
+ return {
651
+ deployed: true,
652
+ reason: admission.reason,
653
+ validation,
654
+ admission,
655
+ artifact,
656
+ runtimeClass,
657
+ deployment
658
+ };
659
+ }
660
+ function createScriptLoadGate(config) {
661
+ return {
662
+ async admitScriptLoad(request) {
663
+ const validation = await validateScript(request.normalizedSource);
664
+ if (!validation.valid) {
665
+ return { allowed: false, reason: `Script validation failed: ${validation.errors.join("; ")}` };
666
+ }
667
+ if (validation.digest !== request.digest) {
668
+ return { allowed: false, reason: "Digest mismatch between loader and validated source" };
669
+ }
670
+ const admission = admitScript({
671
+ script: validation,
672
+ authorTrust: config.authorTrust,
673
+ requestedInterfaces: config.requestedInterfaces,
674
+ expectedCheckpointDigest: config.expectedCheckpointDigest,
675
+ checkpointApiVersion: config.checkpointApiVersion
676
+ });
677
+ if (!admission.admitted) {
678
+ return { allowed: false, reason: admission.reason };
679
+ }
680
+ if (config.expectedCheckpointDigest !== void 0 && !admission.checkpointCompatible) {
681
+ return {
682
+ allowed: false,
683
+ reason: "Checkpoint is incompatible with this script digest/API version; an explicit converter or restart policy is required"
684
+ };
685
+ }
686
+ const runtimeClass = selectRuntimeClass(config.authorTrust, config.availableRuntimeClasses);
687
+ return {
688
+ allowed: true,
689
+ trustClass: config.authorTrust,
690
+ runtimeClass: runtimeClass.runtimeClass,
691
+ checkpointCompatible: admission.checkpointCompatible
692
+ };
693
+ }
694
+ };
695
+ }
696
+ function createScriptDeploymentClient(config) {
697
+ const interfaceCeiling = config.requestedInterfaces ?? defaultRequestedInterfacesForTrustClass(config.authorTrust);
698
+ function requireOrchestration() {
699
+ if (!config.orchestration) {
700
+ throw new OrchestrationError({
701
+ code: "UNSUPPORTED",
702
+ message: "script deployment scheduling requires a host-configured orchestration facade",
703
+ retryable: false
704
+ });
705
+ }
706
+ return config.orchestration;
707
+ }
708
+ return {
709
+ async deploy(request) {
710
+ const result = await deployGeneratedScript(
711
+ {
712
+ source: request.source,
713
+ authorTrust: config.authorTrust,
714
+ requestedInterfaces: request.requestedInterfaces ?? interfaceCeiling,
715
+ lifecycle: request.lifecycle,
716
+ nodeSelector: request.nodeSelector,
717
+ env: request.env,
718
+ networkPolicy: request.networkPolicy,
719
+ storagePolicy: request.storagePolicy,
720
+ expectedCheckpointDigest: request.expectedCheckpointDigest,
721
+ checkpointApiVersion: request.checkpointApiVersion,
722
+ namespace: request.namespace ?? config.namespace
723
+ },
724
+ {
725
+ artifactStore: config.artifactStore,
726
+ availableRuntimeClasses: config.availableRuntimeClasses
727
+ }
728
+ );
729
+ if (result.deployed && result.deployment && config.orchestration) {
730
+ const manifest = remoteDeploymentToWorkloadManifest(result.deployment, {
731
+ namespace: request.namespace ?? config.namespace
732
+ });
733
+ const workload = await config.orchestration.apply(manifest, {
734
+ idempotencyKey: result.deployment.artifactRef.contentDigest,
735
+ fieldManager: config.fieldManager ?? "memeloop/script-deployment"
736
+ });
737
+ return { ...result, workload };
738
+ }
739
+ return result;
740
+ },
741
+ async waitForScheduled(name, options = {}) {
742
+ const orchestration = requireOrchestration();
743
+ const { namespace, ...waitOptions2 } = options;
744
+ return waitForCondition(
745
+ () => orchestration.get({
746
+ apiVersion: AGENT_WORKLOAD_API_VERSION,
747
+ kind: AGENT_WORKLOAD_KIND,
748
+ name,
749
+ namespace: namespace ?? config.namespace
750
+ }),
751
+ { type: "Scheduled", status: "True" },
752
+ waitOptions2
753
+ );
754
+ },
755
+ async deleteDeployment(name, namespace) {
756
+ const orchestration = requireOrchestration();
757
+ await orchestration.delete({
758
+ apiVersion: AGENT_WORKLOAD_API_VERSION,
759
+ kind: AGENT_WORKLOAD_KIND,
760
+ name,
761
+ namespace: namespace ?? config.namespace
762
+ });
763
+ }
764
+ };
765
+ }
766
+
767
+ // src/loops/agent-agent-loop/builtinLoopSources.ts
768
+ var AgentAgentLoopArtifactResourceLifecycleScriptId = "builtin:agent-agent-loop/artifact-resource-lifecycle";
769
+ var AgentAgentLoopDeclarativeAgentRunScriptId = "builtin:agent-agent-loop/declarative-agent-run";
770
+ var AgentAgentLoopQualityGateScriptId = "builtin:agent-agent-loop/quality-gate";
771
+ var BUILTIN_AGENT_AGENT_LOOP_ARTIFACT_RESOURCE_LIFECYCLE_SCRIPT_ID = AgentAgentLoopArtifactResourceLifecycleScriptId;
772
+ var BUILTIN_AGENT_AGENT_LOOP_DECLARATIVE_AGENT_RUN_SCRIPT_ID = AgentAgentLoopDeclarativeAgentRunScriptId;
773
+ var BUILTIN_AGENT_AGENT_LOOP_QUALITY_GATE_SCRIPT_ID = AgentAgentLoopQualityGateScriptId;
774
+ var builtinAgentAgentLoopSources = {
775
+ [AgentAgentLoopArtifactResourceLifecycleScriptId]: [
776
+ "// @ts-check",
777
+ "",
778
+ "function resourceName(value) {",
779
+ ' const normalized = value.toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/^-+|-+$/g, "");',
780
+ ' return (normalized || "artifact").slice(0, 56);',
781
+ "}",
782
+ "",
783
+ "/** @param {import('../../loopAPI/agent-agent-loop/loop.js').AgentAgentScriptContext} ctx */",
784
+ "export default async function run(ctx) {",
785
+ " if (!ctx.orchestration) {",
786
+ ' throw new Error("artifact-resource-lifecycle requires the orchestration resource facade");',
787
+ " }",
788
+ "",
789
+ " const metadata = ctx.profile?.metadata ?? {};",
790
+ ' const contentHash = typeof metadata.contentHash === "string"',
791
+ " ? metadata.contentHash",
792
+ ' : "sha256:0000000000000000000000000000000000000000000000000000000000000000";',
793
+ " const artifactName = resourceName(`script-${ctx.input.conversationId}`);",
794
+ " const query = {",
795
+ ' apiVersion: "artifacts.memeloop.io/v1alpha1",',
796
+ ' kind: "ArtifactRecord",',
797
+ ' namespace: "default",',
798
+ " };",
799
+ " const abortController = new AbortController();",
800
+ " const events = ctx.orchestration.watch(query, {",
801
+ ' resourceVersion: "0",',
802
+ " sendInitialEvents: true,",
803
+ " allowBookmarks: true,",
804
+ " timeoutMs: 5_000,",
805
+ " signal: abortController.signal,",
806
+ " })[Symbol.asyncIterator]();",
807
+ " const nextEvent = events.next();",
808
+ "",
809
+ " try {",
810
+ " const artifact = await ctx.orchestration.apply({",
811
+ " apiVersion: query.apiVersion,",
812
+ " kind: query.kind,",
813
+ " metadata: {",
814
+ " name: artifactName,",
815
+ " namespace: query.namespace,",
816
+ ' labels: { "memeloop.io/artifact-purpose": "generated-script" },',
817
+ " },",
818
+ " spec: {",
819
+ " contentHash,",
820
+ ' mimeType: "text/javascript",',
821
+ ' producer: { trust: "restricted" },',
822
+ ' trust: "restricted",',
823
+ " },",
824
+ " }, {",
825
+ ' fieldManager: "agent-agent-script-example",',
826
+ " idempotencyKey: `${ctx.input.conversationId}:artifact`,",
827
+ " });",
828
+ "",
829
+ " const observed = await nextEvent;",
830
+ ' if (observed.done || observed.value.type !== "ADDED") {',
831
+ ' throw new Error("artifact watch ended before observing the created resource");',
832
+ " }",
833
+ "",
834
+ " const reference = {",
835
+ " apiVersion: artifact.apiVersion,",
836
+ " kind: artifact.kind,",
837
+ " name: artifact.metadata.name,",
838
+ " namespace: artifact.metadata.namespace,",
839
+ " uid: artifact.metadata.uid,",
840
+ " };",
841
+ " const fetched = await ctx.orchestration.get(reference, {",
842
+ " resourceVersion: artifact.metadata.resourceVersion,",
843
+ " });",
844
+ " const listed = await ctx.orchestration.list(query, {",
845
+ " resourceVersion: artifact.metadata.resourceVersion,",
846
+ ' resourceVersionMatch: "not-older-than",',
847
+ " limit: 10,",
848
+ " });",
849
+ " if (!fetched || !listed.items.some((item) => item.metadata.uid === artifact.metadata.uid)) {",
850
+ ' throw new Error("created artifact was not readable through the resource facade");',
851
+ " }",
852
+ "",
853
+ " await ctx.orchestration.delete(reference, {",
854
+ " idempotencyKey: `${ctx.input.conversationId}:artifact-delete`,",
855
+ " preconditions: {",
856
+ " uid: artifact.metadata.uid,",
857
+ " resourceVersion: artifact.metadata.resourceVersion,",
858
+ " },",
859
+ " });",
860
+ " ctx.finish(`verified artifact lifecycle ${artifact.metadata.name}@${observed.value.resourceVersion}`);",
861
+ " } finally {",
862
+ " abortController.abort();",
863
+ " await events.return?.();",
864
+ " }",
865
+ "}",
866
+ ""
867
+ ].join("\n"),
868
+ [AgentAgentLoopDeclarativeAgentRunScriptId]: [
869
+ "// @ts-check",
870
+ "",
871
+ "function resourceName(value) {",
872
+ ' const normalized = value.toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/^-+|-+$/g, "");',
873
+ ' return (normalized || "agent-run").slice(0, 48);',
874
+ "}",
875
+ "",
876
+ "/** @param {import('../../loopAPI/agent-agent-loop/loop.js').AgentAgentScriptContext} ctx */",
877
+ "export default async function run(ctx) {",
878
+ " if (!ctx.agentClient) {",
879
+ ' throw new Error("declarative-agent-run requires the orchestration resource facade");',
880
+ " }",
881
+ "",
882
+ " const metadata = ctx.profile?.metadata ?? {};",
883
+ ' const childProfileId = typeof metadata.childProfileId === "string"',
884
+ " ? metadata.childProfileId",
885
+ " : ctx.agents[0]?.profileId;",
886
+ " if (!childProfileId) {",
887
+ ' throw new Error("declarative-agent-run requires metadata.childProfileId or one configured agent");',
888
+ " }",
889
+ "",
890
+ " const baseName = resourceName(`child-${ctx.input.conversationId}`);",
891
+ " const workloadName = `${baseName}-workload`;",
892
+ " const runName = `${baseName}-run`;",
893
+ " const workload = await ctx.agentClient.createWorkload({",
894
+ " name: workloadName,",
895
+ " profileId: childProfileId,",
896
+ " promptReference: `conversation:${ctx.input.conversationId}:input`,",
897
+ ' trust: "restricted",',
898
+ " placement: {",
899
+ ' nodeSelector: { "memeloop.io/worker-pool": "restricted" },',
900
+ " antiAffinity: [ctx.input.conversationId],",
901
+ " },",
902
+ " modelPolicy: {",
903
+ ' modelClass: "local-model",',
904
+ " budget: { maxTokens: 8_192 },",
905
+ " },",
906
+ " toolPolicy: {",
907
+ ' defaultAction: "deny",',
908
+ ' allowedToolClasses: ["read-only"],',
909
+ " },",
910
+ " networkPolicy: {",
911
+ ' networkClass: "restricted-egress",',
912
+ ' egress: "restricted",',
913
+ " },",
914
+ " storagePolicy: {",
915
+ ' storageClass: "ephemeral",',
916
+ " },",
917
+ ' completionPolicy: "complete",',
918
+ " idempotencyKey: `${ctx.input.conversationId}:workload`,",
919
+ " });",
920
+ " const agentRun = await ctx.agentClient.createRun({",
921
+ " name: runName,",
922
+ " workloadName: workload.metadata.name,",
923
+ " workloadNamespace: workload.metadata.namespace,",
924
+ " promptReference: `conversation:${ctx.input.conversationId}:input`,",
925
+ " timeoutMs: 120_000,",
926
+ " idempotencyKey: `${ctx.input.conversationId}:run`,",
927
+ " });",
928
+ "",
929
+ " if (metadata.waitForCompletion === true) {",
930
+ " await ctx.agentClient.waitForRunCondition(",
931
+ " agentRun.metadata.name,",
932
+ ' { type: "Completed", status: "True" },',
933
+ " { timeout: 5_000, interval: 100 },",
934
+ " );",
935
+ " }",
936
+ "",
937
+ " ctx.finish(`scheduled ${workload.metadata.name}/${agentRun.metadata.name}`);",
938
+ "}",
939
+ ""
940
+ ].join("\n"),
941
+ [AgentAgentLoopQualityGateScriptId]: [
942
+ "// @ts-check",
943
+ "",
944
+ "function positiveInteger(value, fallback) {",
945
+ " const number = Number(value);",
946
+ " return Number.isFinite(number) && number > 0 ? Math.floor(number) : fallback;",
947
+ "}",
948
+ "",
949
+ "function asEntries(value, fallback) {",
950
+ " return Array.isArray(value) && value.length > 0 ? value : fallback;",
951
+ "}",
952
+ "",
953
+ "function withConversationIds(ctx, entries, phase, iteration) {",
954
+ " return entries.map((entry, index) => {",
955
+ ' const record = typeof entry === "string" ? { profile: entry } : entry;',
956
+ " return {",
957
+ " ...record,",
958
+ " conversationId:",
959
+ " record.conversationId ?? `${ctx.input.conversationId}:${phase}:${iteration}:${index}`,",
960
+ " };",
961
+ " });",
962
+ "}",
963
+ "",
964
+ "function resultText(ctx, result) {",
965
+ " return result.text || ctx.formatAgentResults(result, { includeFailureSection: true });",
966
+ "}",
967
+ "",
968
+ "function reviewText(ctx, result) {",
969
+ " return ctx.formatAgentResults(result, { includeFailureSection: true });",
970
+ "}",
971
+ "",
972
+ "function approved(result) {",
973
+ " return (",
974
+ " result.failures.length === 0 &&",
975
+ " result.results.length > 0 &&",
976
+ " result.results.every((item) => /^\\s*APPROVED\\b/imu.test(item.text))",
977
+ " );",
978
+ "}",
979
+ "",
980
+ "function feedbackBlock(ctx, history) {",
981
+ ' if (history.length === 0) return "No prior review feedback.";',
982
+ " return history",
983
+ " .map((entry) =>",
984
+ " [",
985
+ " `Iteration ${entry.iteration}`,",
986
+ " `Attempt:\\n${resultText(ctx, entry.attempt)}`,",
987
+ " `Review:\\n${reviewText(ctx, entry.review)}`,",
988
+ ' ].join("\\n\\n"),',
989
+ " )",
990
+ ' .join("\\n\\n---\\n\\n");',
991
+ "}",
992
+ "",
993
+ "function workerPrompt(ctx, goal, iteration, previousAttempt, history) {",
994
+ " if (!previousAttempt) return goal;",
995
+ " return [",
996
+ ' "Continue working on the original goal until the reviewer can approve it.",',
997
+ ' "Do not summarize the review. Produce the corrected deliverable itself.",',
998
+ " `Original goal:\\n${goal}`,",
999
+ " `Previous deliverable:\\n${resultText(ctx, previousAttempt)}`,",
1000
+ " `Review history:\\n${feedbackBlock(ctx, history)}`,",
1001
+ " `This is revision attempt ${iteration}.`,",
1002
+ ' ].join("\\n\\n");',
1003
+ "}",
1004
+ "",
1005
+ "function reviewPrompt(ctx, goal, attempt, history) {",
1006
+ " return [",
1007
+ ' "You are the quality gate for this delegated agent run.",',
1008
+ ' "Return APPROVED on the first line only when the deliverable fully satisfies the original goal and is ready to send to the user.",',
1009
+ ' "Return REVISE on the first line when more work is required, followed by concrete blocking issues and exact changes needed.",',
1010
+ ' "Do not approve partial progress.",',
1011
+ " `Original goal:\\n${goal}`,",
1012
+ " `Candidate deliverable:\\n${resultText(ctx, attempt)}`,",
1013
+ " `Earlier review history:\\n${feedbackBlock(ctx, history)}`,",
1014
+ ' ].join("\\n\\n");',
1015
+ "}",
1016
+ "",
1017
+ "async function runBatch(ctx, mode, input) {",
1018
+ ' return mode === "sequential" ? ctx.runSequential(input) : ctx.runParallel(input);',
1019
+ "}",
1020
+ "",
1021
+ "/** @param {import('../../loopAPI/agent-agent-loop/loop.js').AgentAgentScriptContext} ctx */",
1022
+ "export default async function run(ctx) {",
1023
+ " const metadata = ctx.profile?.metadata ?? {};",
1024
+ " const goal = ctx.input.message;",
1025
+ " const maxIterations = positiveInteger(metadata.maxIterations, 4);",
1026
+ ' const mode = metadata.mode === "sequential" ? "sequential" : "parallel";',
1027
+ ' const reviewMode = metadata.reviewMode === "sequential" ? "sequential" : "parallel";',
1028
+ ' const defaultAgents = ctx.getAgentEntries("agents");',
1029
+ " const workers = asEntries(",
1030
+ ' ctx.getAgentEntries("workers"),',
1031
+ ' asEntries(ctx.getAgentEntries("draftAgents"), defaultAgents),',
1032
+ " );",
1033
+ " const reviewers = asEntries(",
1034
+ ' ctx.getAgentEntries("reviewers"),',
1035
+ ' asEntries(ctx.getAgentEntries("reviewAgents"), defaultAgents),',
1036
+ " );",
1037
+ " const fixers = asEntries(",
1038
+ ' ctx.getAgentEntries("fixers"),',
1039
+ ' asEntries(ctx.getAgentEntries("revisionAgents"), workers),',
1040
+ " );",
1041
+ " const history = [];",
1042
+ " let attempt;",
1043
+ "",
1044
+ " if (workers.length === 0 || reviewers.length === 0) {",
1045
+ " ctx.finish(",
1046
+ ' "AgentAgent quality gate requires worker and reviewer agents. Configure metadata.workers/reviewers or metadata.agents.",',
1047
+ " );",
1048
+ " return;",
1049
+ " }",
1050
+ "",
1051
+ " for (let iteration = 1; iteration <= maxIterations; iteration += 1) {",
1052
+ " if (ctx.isCancelled()) break;",
1053
+ " const activeWorkers = iteration === 1 ? workers : fixers;",
1054
+ " const attemptKey = `quality-gate:${iteration}:attempt`;",
1055
+ " const previousAttempt = attempt;",
1056
+ " const savedAttempt = await ctx.loadCheckpoint(attemptKey);",
1057
+ " if (savedAttempt) {",
1058
+ " attempt = savedAttempt;",
1059
+ " } else {",
1060
+ " ctx.emit({",
1061
+ ' type: "thinking",',
1062
+ ' data: { status: "quality-gate-work", conversationId: ctx.input.conversationId, iteration },',
1063
+ " });",
1064
+ " attempt = await runBatch(ctx, mode, {",
1065
+ ' agents: withConversationIds(ctx, activeWorkers, "work", iteration),',
1066
+ " prompt: workerPrompt(ctx, goal, iteration, previousAttempt, history),",
1067
+ " });",
1068
+ " await ctx.checkpoint(attemptKey, attempt);",
1069
+ " }",
1070
+ "",
1071
+ " if (attempt.failures.length > 0 && attempt.results.length === 0) {",
1072
+ " history.push({",
1073
+ " iteration,",
1074
+ " attempt,",
1075
+ ' review: { results: [], failures: attempt.failures, text: "" },',
1076
+ " });",
1077
+ " continue;",
1078
+ " }",
1079
+ "",
1080
+ " const reviewKey = `quality-gate:${iteration}:review`;",
1081
+ " let review = await ctx.loadCheckpoint(reviewKey);",
1082
+ " if (!review) {",
1083
+ " ctx.emit({",
1084
+ ' type: "thinking",',
1085
+ " data: {",
1086
+ ' status: "quality-gate-review",',
1087
+ " conversationId: ctx.input.conversationId,",
1088
+ " iteration,",
1089
+ " },",
1090
+ " });",
1091
+ " review = await runBatch(ctx, reviewMode, {",
1092
+ ' agents: withConversationIds(ctx, reviewers, "review", iteration),',
1093
+ " prompt: reviewPrompt(ctx, goal, attempt, history),",
1094
+ " });",
1095
+ " await ctx.checkpoint(reviewKey, review);",
1096
+ " }",
1097
+ " history.push({ iteration, attempt, review });",
1098
+ "",
1099
+ " if (approved(review)) {",
1100
+ " ctx.finish(resultText(ctx, attempt));",
1101
+ " return;",
1102
+ " }",
1103
+ " }",
1104
+ "",
1105
+ " ctx.finish(",
1106
+ " [",
1107
+ ' "Quality gate did not approve the delegated work before the iteration limit.",',
1108
+ ' attempt ? resultText(ctx, attempt) : "No deliverable was produced.",',
1109
+ ' "Review trail:",',
1110
+ " feedbackBlock(ctx, history),",
1111
+ " ]",
1112
+ " .filter(Boolean)",
1113
+ ' .join("\\n\\n"),',
1114
+ " );",
1115
+ "}",
1116
+ ""
1117
+ ].join("\n")
1118
+ };
1119
+ function getBuiltinAgentAgentLoopSource(id) {
1120
+ return builtinAgentAgentLoopSources[id];
1121
+ }
1122
+
1123
+ // src/loopAPI/scriptLoader.ts
1124
+ var DEFAULT_POLICY = {
1125
+ allowBuiltin: true,
1126
+ allowFile: false,
1127
+ allowNetwork: false,
1128
+ allowSource: false,
1129
+ allowSpecifier: true
1130
+ };
1131
+ var LOADED_SCRIPT_METADATA = /* @__PURE__ */ Symbol("memeloop.loadedScriptMetadata");
1132
+ function isLoadedScriptFunction(value) {
1133
+ return typeof value === "function";
1134
+ }
1135
+ function getLoadedScriptMetadata(script) {
1136
+ if (!isLoadedScriptFunction(script)) return void 0;
1137
+ return script[LOADED_SCRIPT_METADATA];
1138
+ }
1139
+ function attachLoadedScriptMetadata(script, metadata) {
1140
+ if (getLoadedScriptMetadata(script) !== void 0) return;
1141
+ Object.defineProperty(script, LOADED_SCRIPT_METADATA, {
1142
+ value: metadata,
1143
+ enumerable: false,
1144
+ configurable: false,
1145
+ writable: false
1146
+ });
1147
+ }
1148
+ var builtinScriptDigests = /* @__PURE__ */ new Set();
1149
+ function registerBuiltinScriptDigests(digests) {
1150
+ for (const digest of digests) {
1151
+ builtinScriptDigests.add(digest);
1152
+ }
1153
+ }
1154
+ async function registerBuiltinScriptSources(sources) {
1155
+ const digests = [];
1156
+ for (const source of Object.values(sources)) {
1157
+ digests.push(await digestNormalizedScript(normalizeScript(source)));
1158
+ }
1159
+ registerBuiltinScriptDigests(digests);
1160
+ return digests;
1161
+ }
1162
+ function isRegisteredBuiltinScriptDigest(digest) {
1163
+ return builtinScriptDigests.has(digest);
1164
+ }
1165
+ var ScriptLoadDeniedError = class extends Error {
1166
+ constructor(digest, gateReason) {
1167
+ super(`Agent loop script load denied (sha256:${digest}): ${gateReason}`);
1168
+ this.digest = digest;
1169
+ this.gateReason = gateReason;
1170
+ this.name = "ScriptLoadDeniedError";
1171
+ }
1172
+ code = "SCRIPT_LOAD_DENIED";
1173
+ };
1174
+ var FAIL_CLOSED_SCRIPT_LOAD_GATE = {
1175
+ admitScriptLoad: () => ({
1176
+ allowed: false,
1177
+ reason: "No script load gate configured; non-builtin script sources are denied by default (fail-closed)"
1178
+ })
1179
+ };
1180
+ function getExportedScript(moduleExports) {
1181
+ if (typeof moduleExports === "function") return moduleExports;
1182
+ if (!moduleExports || typeof moduleExports !== "object") return void 0;
1183
+ const record = moduleExports;
1184
+ return record.default ?? record.run;
1185
+ }
1186
+ function sourceToDataSpecifier(source, name = "agent-loop-script.mjs") {
1187
+ return `data:text/javascript;charset=utf-8,${encodeURIComponent(`${source}
1188
+ //# sourceURL=${name}`)}`;
1189
+ }
1190
+ function normalizeScriptReference(scriptReference) {
1191
+ if (typeof scriptReference !== "string") return scriptReference;
1192
+ if (scriptReference.startsWith("builtin:")) return { kind: "builtin", id: scriptReference };
1193
+ return { kind: "specifier", specifier: scriptReference };
1194
+ }
1195
+ function isFileSpecifier(specifier) {
1196
+ return specifier.startsWith("file:") || specifier.startsWith("/") || specifier.startsWith("./") || specifier.startsWith("../");
1197
+ }
1198
+ function isNetworkSpecifier(specifier) {
1199
+ return specifier.startsWith("http:") || specifier.startsWith("https:");
1200
+ }
1201
+ function isSourceSpecifier(specifier) {
1202
+ return specifier.startsWith("data:text/javascript") || specifier.startsWith("data:application/javascript");
1203
+ }
1204
+ function decodeDataScriptSpecifier(specifier) {
1205
+ const commaIndex = specifier.indexOf(",");
1206
+ if (commaIndex < 0) return void 0;
1207
+ const metadata = specifier.slice("data:".length, commaIndex);
1208
+ const payload = specifier.slice(commaIndex + 1);
1209
+ try {
1210
+ if (metadata.split(";").includes("base64")) {
1211
+ return atob(payload);
1212
+ }
1213
+ return decodeURIComponent(payload);
1214
+ } catch {
1215
+ return void 0;
1216
+ }
1217
+ }
1218
+ function assertSpecifierAllowed(specifier, policy) {
1219
+ if (!policy.allowSpecifier) {
1220
+ throw new Error("Agent loop script import specifiers are disabled by policy.");
1221
+ }
1222
+ if (isSourceSpecifier(specifier) && !policy.allowSource) {
1223
+ throw new Error("Agent loop script source/data URLs are disabled by policy.");
1224
+ }
1225
+ if (isFileSpecifier(specifier) && !policy.allowFile) {
1226
+ throw new Error("Agent loop script file imports are disabled by policy.");
1227
+ }
1228
+ if (isNetworkSpecifier(specifier) && !policy.allowNetwork) {
1229
+ throw new Error("Agent loop script network imports are disabled by policy.");
1230
+ }
1231
+ }
1232
+ async function loadAgentLoopScript(scriptReference, options = {}) {
1233
+ const policy = { ...DEFAULT_POLICY, ...options };
1234
+ const importModule = options.importModule ?? ((specifier) => import(specifier));
1235
+ const normalized = normalizeScriptReference(scriptReference);
1236
+ const scriptType = options.scriptType ?? "Agent loop script";
1237
+ let scriptSpecifier;
1238
+ let sourceForAdmission;
1239
+ if (normalized.kind === "builtin") {
1240
+ if (!policy.allowBuiltin) {
1241
+ throw new Error("Built-in agent loop scripts are disabled by policy.");
1242
+ }
1243
+ const source = options.getBuiltinScriptSource?.(normalized.id);
1244
+ if (!source) throw new Error(`Unknown built-in agent loop script: ${normalized.id}`);
1245
+ sourceForAdmission = source;
1246
+ scriptSpecifier = sourceToDataSpecifier(source, normalized.id);
1247
+ } else if (normalized.kind === "source") {
1248
+ if (!policy.allowSource) {
1249
+ throw new Error("Agent loop script source strings are disabled by policy.");
1250
+ }
1251
+ sourceForAdmission = normalized.source;
1252
+ scriptSpecifier = sourceToDataSpecifier(normalized.source, normalized.name);
1253
+ } else {
1254
+ scriptSpecifier = normalized.specifier;
1255
+ assertSpecifierAllowed(scriptSpecifier, policy);
1256
+ if (isSourceSpecifier(scriptSpecifier)) {
1257
+ sourceForAdmission = decodeDataScriptSpecifier(scriptSpecifier);
1258
+ if (sourceForAdmission === void 0) {
1259
+ throw new ScriptLoadDeniedError("undecodable", "data: script specifier payload could not be decoded");
1260
+ }
1261
+ }
1262
+ }
1263
+ let metadata;
1264
+ if (sourceForAdmission !== void 0) {
1265
+ const normalizedSource = normalizeScript(sourceForAdmission);
1266
+ const digest = await digestNormalizedScript(normalizedSource);
1267
+ if (isRegisteredBuiltinScriptDigest(digest)) {
1268
+ metadata = { digest, builtin: true, trustClass: "trusted" };
1269
+ } else {
1270
+ const gate = options.scriptLoadGate ?? FAIL_CLOSED_SCRIPT_LOAD_GATE;
1271
+ const decision = await gate.admitScriptLoad({ normalizedSource, digest, reference: normalized, scriptType });
1272
+ if (!decision.allowed) {
1273
+ throw new ScriptLoadDeniedError(digest, decision.reason ?? "denied by script load gate");
1274
+ }
1275
+ metadata = {
1276
+ digest,
1277
+ builtin: false,
1278
+ trustClass: decision.trustClass,
1279
+ runtimeClass: decision.runtimeClass,
1280
+ checkpointCompatible: decision.checkpointCompatible
1281
+ };
1282
+ }
1283
+ }
1284
+ const moduleExports = await importModule(scriptSpecifier);
1285
+ const exportedScript = getExportedScript(moduleExports);
1286
+ if (!isLoadedScriptFunction(exportedScript)) {
1287
+ throw new TypeError(
1288
+ `${scriptType} "${scriptSpecifier}" must export a default function or named run function.`
1289
+ );
1290
+ }
1291
+ if (metadata) {
1292
+ attachLoadedScriptMetadata(exportedScript, metadata);
1293
+ }
1294
+ return exportedScript;
1295
+ }
1296
+
1297
+ // src/loopAPI/agent-agent-loop/scriptLoader.ts
1298
+ var builtinDigestsRegistered;
1299
+ function ensureBuiltinDigestsRegistered() {
1300
+ builtinDigestsRegistered ??= registerBuiltinScriptSources(builtinAgentAgentLoopSources);
1301
+ return builtinDigestsRegistered;
1302
+ }
1303
+ async function loadAgentAgentLoopScript(scriptReference, options = {}) {
1304
+ await ensureBuiltinDigestsRegistered();
1305
+ return loadAgentLoopScript(scriptReference, {
1306
+ ...options,
1307
+ getBuiltinScriptSource: getBuiltinAgentAgentLoopSource,
1308
+ scriptType: "AgentAgentLoop script"
1309
+ });
1310
+ }
1311
+
1312
+ // src/loopAPI/agent-agent-loop/loop.ts
1313
+ var LOOP_ID = "agent-agent-loop";
1314
+ var LOOP_NAME = "AgentAgent Loop";
1315
+ var LOOP_DESC = "Orchestrates child agents to collaborate on a task. Supports sequential chaining, parallel execution, and feedback loops.";
1316
+ function isAsyncIterable(value) {
1317
+ return Boolean(value && typeof value === "object" && Symbol.asyncIterator in value);
1318
+ }
1319
+ function messageStep(message) {
1320
+ return { type: "message", data: message };
1321
+ }
1322
+ function stepText(step) {
1323
+ if (step.type !== "message") return void 0;
1324
+ if (typeof step.data === "string") return step.data;
1325
+ if (step.data && typeof step.data === "object" && "content" in step.data) {
1326
+ const content = step.data.content;
1327
+ return typeof content === "string" ? content : void 0;
1328
+ }
1329
+ return void 0;
1330
+ }
1331
+ function profileIdFromEntry(entry) {
1332
+ if (typeof entry === "string") return entry;
1333
+ return entry.profileId ?? entry.profile;
1334
+ }
1335
+ function readProfileAgentEntries(profile, key = "agents") {
1336
+ const metadata = profile?.metadata;
1337
+ if (!metadata) return void 0;
1338
+ const entries = metadata[key];
1339
+ if (Array.isArray(entries)) return entries;
1340
+ return void 0;
1341
+ }
1342
+ function normalizeAgentAgents(input, context, entries, prompt) {
1343
+ const configuredEntries = entries ?? context.agents ?? readProfileAgentEntries(context.profile) ?? [];
1344
+ return configuredEntries.flatMap((entry, index) => {
1345
+ const profileId = profileIdFromEntry(entry);
1346
+ if (!profileId) return [];
1347
+ const record = typeof entry === "string" ? {} : entry;
1348
+ return {
1349
+ ...record,
1350
+ profileId,
1351
+ prompt: prompt ?? record.prompt,
1352
+ conversationId: record.conversationId ?? `${input.conversationId}:child:${index}`,
1353
+ label: record.label
1354
+ };
1355
+ });
1356
+ }
1357
+ function formatAgentResults(result, options = {}) {
1358
+ const emptyMessage = options.emptyMessage ?? "No child agent output.";
1359
+ const failureHeader = options.failureHeader ?? "Failed child agents:";
1360
+ const includeFailureSection = options.includeFailureSection !== false;
1361
+ const sections = [result.text || emptyMessage];
1362
+ if (includeFailureSection && result.failures.length > 0) {
1363
+ sections.push(`${failureHeader}
1364
+ ${result.failures.map((failure) => `${failure.profileId}: ${failure.error}`).join("\n")}`);
1365
+ }
1366
+ return sections.filter(Boolean).join("\n\n");
1367
+ }
1368
+ function createScriptArguments(input, context, emittedSteps) {
1369
+ const agentEntries = context.agents ?? readProfileAgentEntries(context.profile) ?? [];
1370
+ const agents = normalizeAgentAgents(input, context, agentEntries);
1371
+ const getAgentEntries = (key = "agents") => {
1372
+ if (key === "agents") return agentEntries;
1373
+ return readProfileAgentEntries(context.profile, key) ?? [];
1374
+ };
1375
+ const emit = (step) => {
1376
+ emittedSteps.push(step);
1377
+ context.runtime?.emit?.(step);
1378
+ };
1379
+ const log = (event, data) => {
1380
+ context.runtime?.log?.(event, data);
1381
+ };
1382
+ const isCancelled = () => context.runtime?.signal?.cancelled === true;
1383
+ let childCounter = 0;
1384
+ const runAgent = async (childInput) => {
1385
+ if (isCancelled()) throw new Error("AgentAgent_Loop cancelled before child agent start");
1386
+ const profileId = childInput.profileId ?? childInput.profile;
1387
+ if (!profileId) throw new Error("ctx.runAgent requires profileId or profile");
1388
+ if (!context.runtime?.runChildAgent) throw new Error("ctx.runAgent requires runtime.runChildAgent");
1389
+ const childConversationId = childInput.conversationId ?? `${input.conversationId}:child:${profileId}:${++childCounter}`;
1390
+ const prompt = childInput.prompt ?? input.message;
1391
+ emit({
1392
+ type: "thinking",
1393
+ data: { status: "child-agent-started", profileId, conversationId: childConversationId }
1394
+ });
1395
+ const steps = [];
1396
+ const chunks = [];
1397
+ try {
1398
+ for await (const step of context.runtime.runChildAgent({
1399
+ profileId,
1400
+ prompt,
1401
+ conversationId: childConversationId
1402
+ })) {
1403
+ if (isCancelled()) throw new Error("AgentAgent_Loop cancelled during child agent run");
1404
+ steps.push(step);
1405
+ const text = stepText(step);
1406
+ if (text) chunks.push(text);
1407
+ emit({
1408
+ type: "thinking",
1409
+ data: { status: "child-agent-step", profileId, conversationId: childConversationId, step }
1410
+ });
1411
+ }
1412
+ } catch (error) {
1413
+ const message = error instanceof Error ? error.message : String(error);
1414
+ emit({
1415
+ type: "thinking",
1416
+ data: { status: "child-agent-failed", profileId, conversationId: childConversationId, error: message }
1417
+ });
1418
+ throw error;
1419
+ }
1420
+ emit({
1421
+ type: "thinking",
1422
+ data: { status: "child-agent-completed", profileId, conversationId: childConversationId }
1423
+ });
1424
+ return { profileId, conversationId: childConversationId, steps, text: chunks.join("").trim() };
1425
+ };
1426
+ const runBatch = async (batchInput, mode) => {
1427
+ const batchAgents = normalizeAgentAgents(input, context, batchInput?.agents, batchInput?.prompt);
1428
+ const continueOnError = batchInput?.continueOnError !== false;
1429
+ const results = [];
1430
+ const failures = [];
1431
+ const runOne = async (agent) => {
1432
+ if (isCancelled()) {
1433
+ emit({
1434
+ type: "thinking",
1435
+ data: { status: "cancelled", conversationId: input.conversationId }
1436
+ });
1437
+ return;
1438
+ }
1439
+ try {
1440
+ const result = await runAgent(agent);
1441
+ results.push(result);
1442
+ } catch (error) {
1443
+ const message = error instanceof Error ? error.message : String(error);
1444
+ failures.push({ profileId: agent.profileId, conversationId: agent.conversationId, error: message });
1445
+ if (!continueOnError) throw error;
1446
+ }
1447
+ };
1448
+ if (mode === "parallel") {
1449
+ await Promise.all(batchAgents.map((agent) => runOne(agent)));
1450
+ } else {
1451
+ for (const agent of batchAgents) {
1452
+ await runOne(agent);
1453
+ if (isCancelled()) break;
1454
+ }
1455
+ }
1456
+ return { results, failures, text: results.map((result) => result.text).filter(Boolean).join("\n\n") };
1457
+ };
1458
+ const agentClient = context.runtime?.orchestration ? createAgentClient(context.runtime.orchestration) : void 0;
1459
+ const scriptClient = context.runtime?.scriptDeployment ? createScriptDeploymentClient(context.runtime.scriptDeployment) : void 0;
1460
+ return {
1461
+ input,
1462
+ context,
1463
+ profile: context.profile,
1464
+ agents,
1465
+ getAgentEntries,
1466
+ runtime: context.runtime,
1467
+ orchestration: context.runtime?.orchestration,
1468
+ agentClient,
1469
+ scriptClient,
1470
+ runAgent,
1471
+ runAgents: (inputs) => Promise.all(inputs.map(runAgent)),
1472
+ runSequential: (batchInput) => runBatch(batchInput, "sequential"),
1473
+ runParallel: (batchInput) => runBatch(batchInput, "parallel"),
1474
+ formatAgentResults,
1475
+ finishAgentResults: (result, options) => {
1476
+ emit(messageStep(formatAgentResults(result, options)));
1477
+ },
1478
+ emit,
1479
+ finish: (message) => {
1480
+ emit(typeof message === "string" ? messageStep(message) : message);
1481
+ },
1482
+ isCancelled,
1483
+ log,
1484
+ state: context.runtime?.state ?? {
1485
+ get: async () => void 0,
1486
+ set: async () => void 0,
1487
+ update: async () => void 0
1488
+ },
1489
+ checkpoint: context.runtime?.checkpoint ?? (async () => void 0),
1490
+ loadCheckpoint: context.runtime?.loadCheckpoint ?? (async () => void 0)
1491
+ };
1492
+ }
1493
+ async function* drainEmittedSteps(steps) {
1494
+ while (steps.length > 0) {
1495
+ const step = steps.shift();
1496
+ if (step) yield step;
1497
+ }
1498
+ }
1499
+ async function* runScript(script, input, context) {
1500
+ const emittedSteps = [];
1501
+ const scriptArguments = createScriptArguments(input, context, emittedSteps);
1502
+ const result = await script(scriptArguments);
1503
+ yield* drainEmittedSteps(emittedSteps);
1504
+ if (isAsyncIterable(result)) {
1505
+ yield* result;
1506
+ yield* drainEmittedSteps(emittedSteps);
1507
+ } else if (typeof result === "string") {
1508
+ yield messageStep(result);
1509
+ } else if (Array.isArray(result)) {
1510
+ yield* result;
1511
+ } else if (result) {
1512
+ yield result;
1513
+ }
1514
+ }
1515
+ function asAgentAgentContext(context) {
1516
+ return context;
1517
+ }
1518
+ async function resolveScript(context) {
1519
+ if (context.script) return context.script;
1520
+ const scriptReference = context.profile?.scriptReference ?? context.profile?.scriptRef ?? context.profile?.script;
1521
+ if (scriptReference) {
1522
+ if (context.loadScript) return context.loadScript(scriptReference, context);
1523
+ return loadAgentAgentLoopScript(scriptReference, context.scriptPolicy);
1524
+ }
1525
+ return void 0;
1526
+ }
1527
+ function createAgentAgentLoopDefinition() {
1528
+ return {
1529
+ id: LOOP_ID,
1530
+ name: LOOP_NAME,
1531
+ description: LOOP_DESC,
1532
+ createRunner: (rawContext) => {
1533
+ return async function* agentAgentLoop(input) {
1534
+ const context = asAgentAgentContext(rawContext);
1535
+ const script = await resolveScript(context);
1536
+ yield {
1537
+ type: "thinking",
1538
+ data: { status: "agent-agent-loop-loop-started", conversationId: input.conversationId }
1539
+ };
1540
+ context.runtime?.log?.("agent-agent-loop-loop-started", {
1541
+ conversationId: input.conversationId,
1542
+ profileId: context.profile?.id
1543
+ });
1544
+ if (script) {
1545
+ yield* runScript(script, input, context);
1546
+ yield {
1547
+ type: "thinking",
1548
+ data: { status: "completed", conversationId: input.conversationId }
1549
+ };
1550
+ return;
1551
+ }
1552
+ yield {
1553
+ type: "thinking",
1554
+ data: { status: "script-missing", conversationId: input.conversationId }
1555
+ };
1556
+ yield {
1557
+ type: "message",
1558
+ data: "AgentAgentLoop requires an explicit loop script. Configure profile.scriptReference or provide context.script."
1559
+ };
1560
+ yield {
1561
+ type: "thinking",
1562
+ data: { status: "completed", conversationId: input.conversationId }
1563
+ };
1564
+ };
1565
+ }
1566
+ };
1567
+ }
1568
+ function getAgentAgentLoopId() {
1569
+ return LOOP_ID;
1570
+ }
1571
+
1572
+ // src/loops/agent-tool-loop/builtinLoopSources.ts
1573
+ var AgentToolLoopDefaultScriptId = "builtin:agent-tool-loop/default";
1574
+ var BUILTIN_AGENT_TOOL_LOOP_DEFAULT_SCRIPT_ID = AgentToolLoopDefaultScriptId;
1575
+ var builtinAgentToolLoopSources = {
1576
+ [AgentToolLoopDefaultScriptId]: [
1577
+ "// @ts-check",
1578
+ "",
1579
+ "/** @param {import('../../loopAPI/agent-tool-loop/loop.js').AgentToolLoopScriptContext} ctx */",
1580
+ "export default async function* run(ctx) {",
1581
+ " const state = ctx.createState();",
1582
+ "",
1583
+ " try {",
1584
+ " const start = await ctx.startTurn(state);",
1585
+ " if (start.step) yield start.step;",
1586
+ " if (start.action === 'stop') return;",
1587
+ "",
1588
+ " while (true) {",
1589
+ " const result = yield* ctx.runIteration(state);",
1590
+ " if (result.action === 'stop') return;",
1591
+ " }",
1592
+ " } catch (error) {",
1593
+ " await ctx.stopTurn(state, 'error');",
1594
+ " throw error;",
1595
+ " } finally {",
1596
+ " await ctx.stopTurn(state);",
1597
+ " }",
1598
+ "}"
1599
+ ].join("\n")
1600
+ };
1601
+ function getBuiltinAgentToolLoopSource(id) {
1602
+ return builtinAgentToolLoopSources[id];
1603
+ }
1604
+
1605
+ // src/loopAPI/agent-tool-loop/scriptLoader.ts
1606
+ var builtinDigestsRegistered2;
1607
+ function ensureBuiltinDigestsRegistered2() {
1608
+ builtinDigestsRegistered2 ??= registerBuiltinScriptSources(builtinAgentToolLoopSources);
1609
+ return builtinDigestsRegistered2;
1610
+ }
1611
+ async function loadAgentToolLoopScript(scriptReference, options = {}) {
1612
+ await ensureBuiltinDigestsRegistered2();
1613
+ return loadAgentLoopScript(scriptReference, {
1614
+ ...options,
1615
+ getBuiltinScriptSource: getBuiltinAgentToolLoopSource,
1616
+ scriptType: "AgentToolLoop script"
1617
+ });
1618
+ }
1619
+
1620
+ // src/loopAPI/agent-tool-loop/scriptRunner.ts
1621
+ function isAsyncIterable2(value) {
1622
+ return Boolean(value && typeof value === "object" && Symbol.asyncIterator in value);
1623
+ }
1624
+ function messageStep2(message) {
1625
+ return { type: "message", data: message };
1626
+ }
1627
+ async function* drainEmittedSteps2(steps) {
1628
+ while (steps.length > 0) {
1629
+ const step = steps.shift();
1630
+ if (step) yield step;
1631
+ }
1632
+ }
1633
+ function asAgentToolLoopContext(rawContext) {
1634
+ return rawContext;
1635
+ }
1636
+ async function resolveAgentToolLoopScript(context) {
1637
+ if (context.script) return context.script;
1638
+ const scriptReference = context.profile?.scriptReference ?? context.profile?.scriptRef ?? context.profile?.script;
1639
+ if (!scriptReference) return void 0;
1640
+ if (context.loadScript) return context.loadScript(scriptReference, context);
1641
+ return loadAgentToolLoopScript(scriptReference, context.scriptPolicy);
1642
+ }
1643
+ function createAgentToolLoopScriptContext(input, context, emittedSteps) {
1644
+ const emit = (step) => {
1645
+ emittedSteps.push(step);
1646
+ context.runtime?.emit?.(step);
1647
+ };
1648
+ return {
1649
+ input,
1650
+ context,
1651
+ profile: context.profile,
1652
+ createState: () => createAgentToolLoopState(context),
1653
+ startTurn: (state) => startAgentToolLoopTurn(context, input, state),
1654
+ runIteration: (state) => runAgentToolLoopIteration(context, input, state),
1655
+ stopTurn: (state, reason) => stopAgentToolLoopTurn(context, input, state, reason),
1656
+ emit,
1657
+ finish: (message) => {
1658
+ emit(typeof message === "string" ? messageStep2(message) : message);
1659
+ },
1660
+ isCancelled: () => context.runtime?.signal?.cancelled === true || context.agentToolLoop?.isCancelled?.(input.conversationId) === true,
1661
+ log: (event, data) => {
1662
+ context.runtime?.log?.(event, data);
1663
+ context.logger?.debug?.(event, data);
1664
+ }
1665
+ };
1666
+ }
1667
+ async function* runAgentToolLoopScript(script, input, context) {
1668
+ const emittedSteps = [];
1669
+ const result = await script(createAgentToolLoopScriptContext(input, context, emittedSteps));
1670
+ yield* drainEmittedSteps2(emittedSteps);
1671
+ if (isAsyncIterable2(result)) {
1672
+ yield* result;
1673
+ yield* drainEmittedSteps2(emittedSteps);
1674
+ } else if (typeof result === "string") {
1675
+ yield messageStep2(result);
1676
+ } else if (Array.isArray(result)) {
1677
+ yield* result;
1678
+ } else if (result) {
1679
+ yield result;
1680
+ }
1681
+ }
1682
+
1683
+ // src/loopAPI/agent-tool-loop/loop.ts
1684
+ function createAgentToolLoopDefinition(name = "AgentToolLoop") {
1685
+ return {
1686
+ id: "agent-tool-loop",
1687
+ name,
1688
+ description: "Agent/tool loop that alternates between LLM output and external tool execution.",
1689
+ createRunner: (rawContext) => {
1690
+ const context = asAgentToolLoopContext(rawContext);
1691
+ return async function* agentToolLoop(input) {
1692
+ const script = await resolveAgentToolLoopScript(context);
1693
+ if (script) {
1694
+ yield* runAgentToolLoopScript(script, input, context);
1695
+ return;
1696
+ }
1697
+ yield* createAgentToolLoopRunner(context)(input);
1698
+ };
1699
+ }
1700
+ };
1701
+ }
1702
+
1703
+ // src/loopAPI/plugins/builtinLoopsPlugin.ts
1704
+ var AGENT_TOOL_LOOP_ID = "agent-tool-loop";
1705
+ var AGENT_AGENT_LOOP_ID = getAgentAgentLoopId();
1706
+ function registerBuiltinLoops() {
1707
+ const registry = getLoopRegistry();
1708
+ if (!registry.getLoop(AGENT_TOOL_LOOP_ID)) {
1709
+ registry.registerLoop(createAgentToolLoopDefinition("AgentToolLoop"));
1710
+ }
1711
+ if (!registry.getLoop(AGENT_AGENT_LOOP_ID)) {
1712
+ registry.registerLoop(createAgentAgentLoopDefinition());
1713
+ }
1714
+ }
1715
+
1716
+ // src/tools/builtins/askQuestion.ts
1717
+ import { z } from "zod";
1718
+
1719
+ // src/tools/builtins/questionWaitRegistry.ts
1720
+ var pending = /* @__PURE__ */ new Map();
1721
+ function resolveQuestionAnswer(questionId, answer) {
1722
+ const p = pending.get(questionId);
1723
+ if (!p) return false;
1724
+ clearTimeout(p.timer);
1725
+ pending.delete(questionId);
1726
+ p.resolve(answer);
1727
+ return true;
1728
+ }
1729
+ function waitForQuestionAnswer(questionId, timeoutMs) {
1730
+ return new Promise((resolve, reject) => {
1731
+ const timer = setTimeout(() => {
1732
+ pending.delete(questionId);
1733
+ reject(new Error("askQuestion_timeout"));
1734
+ }, timeoutMs);
1735
+ pending.set(questionId, { resolve, reject, timer });
1736
+ });
1737
+ }
1738
+
1739
+ // src/tools/builtins/askQuestion.ts
1740
+ var askQuestionConfigSchema = z.object({
1741
+ question: z.string().min(1),
1742
+ /**
1743
+ * Desktop / TidGi 的 LLM 工具参数里通常不会显式携带 conversationId,
1744
+ * 由宿主侧上下文负责关联;这里允许缺省,交给宿主回调侧做路由。
1745
+ */
1746
+ conversationId: z.string().min(1).optional(),
1747
+ timeoutMs: z.number().int().positive().max(36e5).optional(),
1748
+ inputType: z.enum(["single-select", "multi-select", "text"]).optional(),
1749
+ options: z.array(
1750
+ z.object({
1751
+ label: z.string(),
1752
+ description: z.string().optional()
1753
+ })
1754
+ ).optional(),
1755
+ allowFreeform: z.boolean().optional().default(true)
1756
+ });
1757
+ var ASK_QUESTION_TOOL_ID = "ask-question";
1758
+ async function askQuestionImpl(arguments_, context) {
1759
+ const parsed = askQuestionConfigSchema.safeParse(arguments_);
1760
+ if (!parsed.success) {
1761
+ return { error: "invalid_askQuestion_args" };
1762
+ }
1763
+ const { question, conversationId, timeoutMs, inputType, options, allowFreeform } = parsed.data;
1764
+ const questionId = crypto.randomUUID();
1765
+ const timeout = timeoutMs ?? 3e5;
1766
+ context.notifyAskQuestion?.({
1767
+ questionId,
1768
+ question,
1769
+ conversationId,
1770
+ inputType,
1771
+ options,
1772
+ allowFreeform
1773
+ });
1774
+ try {
1775
+ const answer = await waitForQuestionAnswer(questionId, timeout);
1776
+ return { result: answer };
1777
+ } catch (error) {
1778
+ return { error: error instanceof Error ? error.message : "askQuestion_failed" };
1779
+ }
1780
+ }
1781
+
1782
+ // src/tools/builtins/askUserQuestion.ts
1783
+ import { z as z2 } from "zod";
1784
+ var askUserQuestionConfigSchema = z2.object({
1785
+ question: z2.string().min(1).describe("The question to ask the user"),
1786
+ inputType: z2.enum(["text", "single-select", "multi-select"]).optional().default("text").describe("Type of input expected: text, single-select, or multi-select"),
1787
+ options: z2.array(
1788
+ z2.object({
1789
+ label: z2.string().min(1),
1790
+ description: z2.string().optional()
1791
+ })
1792
+ ).optional().describe("Options for single-select or multi-select input types"),
1793
+ allowFreeform: z2.boolean().optional().default(true).describe("Allow free-text input even for select types"),
1794
+ timeoutMs: z2.number().int().positive().max(36e5).optional().default(3e5).describe("Timeout in milliseconds (default 5 minutes)")
1795
+ });
1796
+ var ASK_USER_QUESTION_TOOL_ID = "askUserQuestion";
1797
+ async function askUserQuestionImpl(arguments_, context) {
1798
+ const parsed = askUserQuestionConfigSchema.safeParse(arguments_);
1799
+ if (!parsed.success) {
1800
+ return { error: `invalid_askUserQuestion_args: ${parsed.error.message}` };
1801
+ }
1802
+ const { question, inputType, options, allowFreeform, timeoutMs } = parsed.data;
1803
+ const questionId = crypto.randomUUID();
1804
+ const conversationId = context.agent?.id ?? context.activeToolConversationId;
1805
+ context.notifyAskQuestion?.({
1806
+ questionId,
1807
+ question,
1808
+ conversationId,
1809
+ inputType,
1810
+ options,
1811
+ allowFreeform
1812
+ });
1813
+ try {
1814
+ const answer = await waitForQuestionAnswer(questionId, timeoutMs);
1815
+ return { result: answer };
1816
+ } catch (error) {
1817
+ const message = error instanceof Error ? error.message : "askUserQuestion_failed";
1818
+ return { error: message };
1819
+ }
1820
+ }
1821
+
1822
+ // src/tools/builtins/mcpClient.ts
1823
+ var TOOL_ID = "mcpClient";
1824
+ var mcpClientConfigSchema = {
1825
+ type: "object",
1826
+ properties: {
1827
+ nodeId: { type: "string", description: "Target node ID" },
1828
+ serverName: { type: "string", description: "MCP server name on that node" },
1829
+ toolName: { type: "string", description: "Tool to invoke" },
1830
+ args: { type: "object", description: "Tool arguments" }
1831
+ },
1832
+ required: ["nodeId", "serverName", "toolName"]
1833
+ };
1834
+ var mcpClientImpl = async (arguments_, context) => {
1835
+ const nodeId = arguments_.nodeId;
1836
+ const serverName = arguments_.serverName;
1837
+ const toolName = arguments_.toolName;
1838
+ const toolArguments = arguments_.args ?? {};
1839
+ if (!nodeId || !serverName || !toolName) {
1840
+ return {
1841
+ error: "mcpClient requires nodeId, serverName, and toolName"
1842
+ };
1843
+ }
1844
+ if (!context.mcpCallRemote) {
1845
+ return {
1846
+ error: "MCP proxy not configured (no mcpCallRemote in context). Connect to nodes that expose MCP."
1847
+ };
1848
+ }
1849
+ try {
1850
+ const result = await context.mcpCallRemote(nodeId, serverName, toolName, toolArguments);
1851
+ return { result };
1852
+ } catch (error) {
1853
+ const message = error instanceof Error ? error.message : String(error);
1854
+ return { error: `MCP call failed: ${message}` };
1855
+ }
1856
+ };
1857
+ function getMcpClientToolId() {
1858
+ return TOOL_ID;
1859
+ }
1860
+
1861
+ // src/tools/builtins/mcpForward.ts
1862
+ var TOOL_ID2 = "mcpForward";
1863
+ var mcpForwardConfigSchema = {
1864
+ type: "object",
1865
+ properties: {
1866
+ action: {
1867
+ type: "string",
1868
+ enum: ["list", "listTools"],
1869
+ description: "Action: 'list' returns nodes with MCP servers, 'listTools' returns all available MCP tools across nodes"
1870
+ }
1871
+ }
1872
+ };
1873
+ var mcpForwardImpl = async (arguments_, context) => {
1874
+ const action = arguments_.action ?? "list";
1875
+ if (!context.getPeers) {
1876
+ return { error: "Peer list not configured (no getPeers)." };
1877
+ }
1878
+ if (!context.sendRpcToNode) {
1879
+ return { error: "Remote node RPC not configured (no sendRpcToNode)." };
1880
+ }
1881
+ const peers = await context.getPeers();
1882
+ const online = peers.filter((p) => p.reachability.state === "online");
1883
+ if (action === "list") {
1884
+ const result = [];
1885
+ for (const node of online) {
1886
+ try {
1887
+ const response = await context.sendRpcToNode(
1888
+ node.peerId,
1889
+ "memeloop.mcp.listServers",
1890
+ {}
1891
+ );
1892
+ const servers = Array.isArray(response?.servers) ? response.servers : [];
1893
+ if (servers.length > 0) {
1894
+ result.push({
1895
+ nodeId: node.peerId,
1896
+ name: node.displayName,
1897
+ mcpServers: servers
1898
+ });
1899
+ }
1900
+ } catch {
1901
+ }
1902
+ }
1903
+ return { nodes: result };
1904
+ }
1905
+ if (action === "listTools") {
1906
+ const allTools = [];
1907
+ for (const node of online) {
1908
+ try {
1909
+ const response = await context.sendRpcToNode(
1910
+ node.peerId,
1911
+ "memeloop.mcp.listTools",
1912
+ {}
1913
+ );
1914
+ const tools = Array.isArray(response?.tools) ? response.tools : [];
1915
+ for (const tool of tools) {
1916
+ allTools.push({
1917
+ nodeId: node.peerId,
1918
+ serverName: tool.serverName,
1919
+ name: tool.name,
1920
+ description: tool.description
1921
+ });
1922
+ }
1923
+ } catch {
1924
+ }
1925
+ }
1926
+ return { tools: allTools };
1927
+ }
1928
+ return { error: `Unknown action: ${action}` };
1929
+ };
1930
+ function getMcpForwardToolId() {
1931
+ return TOOL_ID2;
1932
+ }
1933
+
1934
+ // src/tools/builtins/orchestration.ts
1935
+ var ORCHESTRATION_TOOL_ID = "orchestration";
1936
+ var orchestrationConfigSchema = {
1937
+ type: "object",
1938
+ properties: {
1939
+ action: {
1940
+ type: "string",
1941
+ enum: ["capabilities", "apply", "get", "list", "wait", "delete"],
1942
+ description: "Declarative orchestration resource operation."
1943
+ },
1944
+ resource: {
1945
+ type: "object",
1946
+ description: "Resource manifest for apply. status and actor fields are not accepted."
1947
+ },
1948
+ reference: {
1949
+ type: "object",
1950
+ description: "Resource reference for get, wait, or delete."
1951
+ },
1952
+ query: {
1953
+ type: "object",
1954
+ description: "Resource query for list."
1955
+ },
1956
+ condition: {
1957
+ type: "object",
1958
+ description: "Condition to wait for. Required when action is wait."
1959
+ },
1960
+ options: {
1961
+ type: "object",
1962
+ description: "Operation options. Only documented fields are forwarded."
1963
+ }
1964
+ },
1965
+ required: ["action"]
1966
+ };
1967
+ function objectValue(value, field) {
1968
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
1969
+ throw invalidError(`${field} must be an object`);
1970
+ }
1971
+ return value;
1972
+ }
1973
+ function invalidError(message) {
1974
+ return new OrchestrationError({ code: "INVALID", message, retryable: false });
1975
+ }
1976
+ function optionalString(value) {
1977
+ return typeof value === "string" && value.length > 0 ? value : void 0;
1978
+ }
1979
+ function optionalBoolean(value) {
1980
+ return typeof value === "boolean" ? value : void 0;
1981
+ }
1982
+ function stringRecord(value) {
1983
+ if (value === void 0) return void 0;
1984
+ const record = objectValue(value, "record");
1985
+ const entries = Object.entries(record);
1986
+ if (entries.some(([, entry]) => typeof entry !== "string")) {
1987
+ throw invalidError("record values must be strings");
1988
+ }
1989
+ return Object.fromEntries(entries);
1990
+ }
1991
+ function metadataValue(value) {
1992
+ const metadata = objectValue(value, "resource.metadata");
1993
+ return {
1994
+ name: optionalString(metadata.name),
1995
+ generateName: optionalString(metadata.generateName),
1996
+ namespace: optionalString(metadata.namespace),
1997
+ labels: stringRecord(metadata.labels),
1998
+ annotations: stringRecord(metadata.annotations)
1999
+ };
2000
+ }
2001
+ function resourceValue(value) {
2002
+ const resource = objectValue(value, "resource");
2003
+ const apiVersion = optionalString(resource.apiVersion);
2004
+ const kind = optionalString(resource.kind);
2005
+ if (!apiVersion || !kind) throw invalidError("resource requires apiVersion and kind");
2006
+ return {
2007
+ apiVersion,
2008
+ kind,
2009
+ metadata: metadataValue(resource.metadata),
2010
+ spec: objectValue(resource.spec, "resource.spec")
2011
+ };
2012
+ }
2013
+ function referenceValue(value) {
2014
+ const reference = objectValue(value, "reference");
2015
+ const apiVersion = optionalString(reference.apiVersion);
2016
+ const kind = optionalString(reference.kind);
2017
+ const name = optionalString(reference.name);
2018
+ const uid = optionalString(reference.uid);
2019
+ if (!apiVersion || !kind || !name && !uid) {
2020
+ throw invalidError("reference requires apiVersion, kind, and name or uid");
2021
+ }
2022
+ return {
2023
+ apiVersion,
2024
+ kind,
2025
+ name,
2026
+ namespace: optionalString(reference.namespace),
2027
+ uid
2028
+ };
2029
+ }
2030
+ function queryValue(value) {
2031
+ const query = objectValue(value, "query");
2032
+ const kind = optionalString(query.kind);
2033
+ if (!kind) throw invalidError("query requires kind");
2034
+ return {
2035
+ apiVersion: optionalString(query.apiVersion),
2036
+ kind,
2037
+ namespace: optionalString(query.namespace),
2038
+ labels: stringRecord(query.labels)
2039
+ };
2040
+ }
2041
+ function preconditionsValue(value) {
2042
+ if (value === void 0) return void 0;
2043
+ const preconditions = objectValue(value, "options.preconditions");
2044
+ return {
2045
+ uid: optionalString(preconditions.uid),
2046
+ resourceVersion: optionalString(preconditions.resourceVersion),
2047
+ generation: typeof preconditions.generation === "number" ? preconditions.generation : void 0
2048
+ };
2049
+ }
2050
+ function applyOptions(value) {
2051
+ if (value === void 0) return void 0;
2052
+ const options = objectValue(value, "options");
2053
+ return {
2054
+ idempotencyKey: optionalString(options.idempotencyKey),
2055
+ fieldManager: optionalString(options.fieldManager),
2056
+ force: optionalBoolean(options.force),
2057
+ dryRun: optionalBoolean(options.dryRun),
2058
+ preconditions: preconditionsValue(options.preconditions)
2059
+ };
2060
+ }
2061
+ function getOptions(value) {
2062
+ if (value === void 0) return void 0;
2063
+ const options = objectValue(value, "options");
2064
+ return { resourceVersion: optionalString(options.resourceVersion) };
2065
+ }
2066
+ function listOptions(value) {
2067
+ if (value === void 0) return void 0;
2068
+ const options = objectValue(value, "options");
2069
+ return {
2070
+ resourceVersion: optionalString(options.resourceVersion),
2071
+ resourceVersionMatch: options.resourceVersionMatch === "exact" || options.resourceVersionMatch === "not-older-than" ? options.resourceVersionMatch : void 0,
2072
+ limit: typeof options.limit === "number" ? options.limit : void 0,
2073
+ continueToken: optionalString(options.continueToken)
2074
+ };
2075
+ }
2076
+ function deleteOptions(value) {
2077
+ if (value === void 0) return void 0;
2078
+ const options = objectValue(value, "options");
2079
+ const propagationPolicy = options.propagationPolicy;
2080
+ const validPropagationPolicy = propagationPolicy === "orphan" || propagationPolicy === "background" || propagationPolicy === "foreground" ? propagationPolicy : void 0;
2081
+ return {
2082
+ idempotencyKey: optionalString(options.idempotencyKey),
2083
+ preconditions: preconditionsValue(options.preconditions),
2084
+ propagationPolicy: validPropagationPolicy,
2085
+ dryRun: optionalBoolean(options.dryRun)
2086
+ };
2087
+ }
2088
+ function waitConditionValue(value) {
2089
+ const condition = objectValue(value, "condition");
2090
+ const type = optionalString(condition.type);
2091
+ if (!type) throw invalidError("condition requires type");
2092
+ const status = condition.status === "True" || condition.status === "False" || condition.status === "Unknown" ? condition.status : "True";
2093
+ return { type, status };
2094
+ }
2095
+ function waitOptions(value) {
2096
+ if (value === void 0) return {};
2097
+ const options = objectValue(value, "options");
2098
+ const timeout = typeof options.timeout === "number" ? options.timeout : void 0;
2099
+ const interval = typeof options.interval === "number" ? options.interval : void 0;
2100
+ if (timeout !== void 0 && timeout <= 0) throw invalidError("timeout must be positive");
2101
+ if (interval !== void 0 && interval <= 0) throw invalidError("interval must be positive");
2102
+ return { timeout, interval };
2103
+ }
2104
+ async function waitForResourceCondition(context, client, reference, condition, options) {
2105
+ return waitForCondition(
2106
+ () => client.get(reference, { resourceVersion: void 0 }),
2107
+ condition,
2108
+ {
2109
+ ...options,
2110
+ isCancelled: () => context.isCancelled?.() === true || context.activeToolConversationId !== void 0 && context.conversationCancellation?.has(context.activeToolConversationId) === true
2111
+ }
2112
+ );
2113
+ }
2114
+ var orchestrationImpl = async (arguments_, context) => {
2115
+ const client = context.orchestration;
2116
+ if (!client) {
2117
+ return {
2118
+ error: {
2119
+ code: "UNSUPPORTED",
2120
+ message: "Orchestration manager not configured.",
2121
+ retryable: false
2122
+ }
2123
+ };
2124
+ }
2125
+ try {
2126
+ switch (arguments_.action) {
2127
+ case "capabilities":
2128
+ return await client.getCapabilities();
2129
+ case "apply":
2130
+ return await client.apply(resourceValue(arguments_.resource), applyOptions(arguments_.options));
2131
+ case "get":
2132
+ return await client.get(referenceValue(arguments_.reference), getOptions(arguments_.options));
2133
+ case "list":
2134
+ return await client.list(queryValue(arguments_.query), listOptions(arguments_.options));
2135
+ case "wait":
2136
+ return await waitForResourceCondition(
2137
+ context,
2138
+ client,
2139
+ referenceValue(arguments_.reference),
2140
+ waitConditionValue(arguments_.condition),
2141
+ waitOptions(arguments_.options)
2142
+ );
2143
+ case "delete":
2144
+ return await client.delete(referenceValue(arguments_.reference), deleteOptions(arguments_.options));
2145
+ default:
2146
+ throw invalidError("orchestration requires a supported action");
2147
+ }
2148
+ } catch (error) {
2149
+ return { error: toOrchestrationErrorData(error) };
2150
+ }
2151
+ };
2152
+
2153
+ // src/tools/builtins/remoteAgent.ts
2154
+ var TOOL_ID3 = "remoteAgent";
2155
+ var REMOTE_LOG_POLL_INTERVAL_MS = 500;
2156
+ var REMOTE_LOG_IDLE_POLLS = 2;
2157
+ function messageContentToText(content) {
2158
+ if (typeof content === "string") return content;
2159
+ if (content == null) return "";
2160
+ try {
2161
+ return JSON.stringify(content);
2162
+ } catch {
2163
+ return Object.prototype.toString.call(content);
2164
+ }
2165
+ }
2166
+ function getRemoteStreamChunkContent(chunk) {
2167
+ if (chunk != null && typeof chunk === "object" && "content" in chunk) {
2168
+ return Reflect.get(chunk, "content");
2169
+ }
2170
+ return void 0;
2171
+ }
2172
+ function summarizeRemoteMessages(messages) {
2173
+ const relevant = messages.filter((message) => message.role && message.role !== "user");
2174
+ if (relevant.length === 0) {
2175
+ return "(task dispatched; waiting for remote output)";
2176
+ }
2177
+ const joined = relevant.map((message) => {
2178
+ const role = typeof message.role === "string" ? message.role : "message";
2179
+ const content = messageContentToText(message.content).trim();
2180
+ return content.length > 0 ? `[${role}] ${content}` : "";
2181
+ }).filter((line) => line.length > 0).join("\n");
2182
+ return joined.trim() || "(task dispatched; remote messages had no readable content)";
2183
+ }
2184
+ async function collectRemoteConversationSummary(sendRpc, nodeId, conversationId, timeoutMs) {
2185
+ const startedAt = Date.now();
2186
+ const knownMessageIds = /* @__PURE__ */ new Set();
2187
+ const collectedMessages = [];
2188
+ let idlePolls = 0;
2189
+ while (Date.now() - startedAt < timeoutMs) {
2190
+ const response = await sendRpc(nodeId, "memeloop.chat.pullAgentRunLog", {
2191
+ conversationId,
2192
+ knownMessageIds: [...knownMessageIds]
2193
+ });
2194
+ const newMessages = Array.isArray(response?.messages) ? response.messages : [];
2195
+ if (newMessages.length > 0) {
2196
+ idlePolls = 0;
2197
+ for (const message of newMessages) {
2198
+ if (typeof message.messageId === "string" && message.messageId.length > 0) {
2199
+ knownMessageIds.add(message.messageId);
2200
+ }
2201
+ collectedMessages.push(message);
2202
+ }
2203
+ } else if (collectedMessages.some((message) => message.role && message.role !== "user")) {
2204
+ idlePolls += 1;
2205
+ if (idlePolls >= REMOTE_LOG_IDLE_POLLS) {
2206
+ break;
2207
+ }
2208
+ }
2209
+ await new Promise((resolve) => setTimeout(resolve, REMOTE_LOG_POLL_INTERVAL_MS));
2210
+ }
2211
+ return summarizeRemoteMessages(collectedMessages);
2212
+ }
2213
+ async function supportsAgentWorkload(client) {
2214
+ try {
2215
+ const caps = await client.getCapabilities();
2216
+ return caps.operations.includes("apply") && caps.resourceKinds.includes("AgentWorkload");
2217
+ } catch {
2218
+ return false;
2219
+ }
2220
+ }
2221
+ async function runRemoteAgentViaOrchestration(client, nodeId, definitionId, message, localNodeId) {
2222
+ const timestamp = Date.now().toString(36);
2223
+ const conversationId = `remote:${nodeId}:${definitionId}:${timestamp}`;
2224
+ const agents = createAgentClient(client);
2225
+ const workload = await agents.createWorkload({
2226
+ name: conversationId,
2227
+ profileId: definitionId,
2228
+ promptReference: message,
2229
+ completionPolicy: "complete",
2230
+ placement: { requiredNode: nodeId }
2231
+ });
2232
+ const run = await agents.createRun({
2233
+ name: `${conversationId}-run`,
2234
+ workloadName: workload.metadata.name,
2235
+ promptReference: message
2236
+ });
2237
+ const result = await agents.waitForRunCondition(
2238
+ run.metadata.name,
2239
+ { type: "Completed", status: "True" },
2240
+ { timeout: 3e4, interval: 1e3 }
2241
+ );
2242
+ const finalRun = await agents.getRun(run.metadata.name);
2243
+ const summary = finalRun?.status?.summary ?? "(no summary)";
2244
+ const shortSummary = truncateToolSummary(summary);
2245
+ const resolvedNodeId = localNodeId?.trim() || "local";
2246
+ return {
2247
+ summary,
2248
+ remoteNodeId: nodeId,
2249
+ remoteConversationId: conversationId,
2250
+ definitionId,
2251
+ [MEMELOOP_STRUCTURED_TOOL_KEY]: {
2252
+ summary: shortSummary,
2253
+ detailRef: {
2254
+ type: "agent-run",
2255
+ conversationId,
2256
+ nodeId: resolvedNodeId,
2257
+ resourceVersion: result.observedResourceVersion
2258
+ }
2259
+ }
2260
+ };
2261
+ }
2262
+ var remoteAgentConfigSchema = {
2263
+ type: "object",
2264
+ properties: {
2265
+ nodeId: { type: "string", description: "Target node ID to run the agent-run on" },
2266
+ definitionId: { type: "string", description: "Agent definition ID on that node" },
2267
+ message: { type: "string", description: "Task message for the remote agent" }
2268
+ },
2269
+ required: ["nodeId", "definitionId", "message"]
2270
+ };
2271
+ var remoteAgentListImpl = async (_arguments, context) => {
2272
+ if (context.orchestration) {
2273
+ try {
2274
+ const caps = await context.orchestration.getCapabilities();
2275
+ const targets = caps.resourceKinds.map((kind) => ({
2276
+ kind,
2277
+ interfaces: caps.interfaces,
2278
+ operations: caps.operations
2279
+ }));
2280
+ return {
2281
+ targets,
2282
+ capabilities: caps.interfaces
2283
+ };
2284
+ } catch (error) {
2285
+ const message = error instanceof Error ? error.message : String(error);
2286
+ return {
2287
+ targets: [],
2288
+ error: `Orchestration target discovery failed: ${message}`
2289
+ };
2290
+ }
2291
+ }
2292
+ return {
2293
+ targets: [],
2294
+ error: "Direct peer enumeration is disabled. Configure an orchestration manager to discover execution targets."
2295
+ };
2296
+ };
2297
+ var remoteAgentImpl = async (arguments_, context) => {
2298
+ const nodeId = arguments_.nodeId;
2299
+ const definitionId = arguments_.definitionId;
2300
+ const message = arguments_.message;
2301
+ if (!nodeId || !definitionId || typeof message !== "string") {
2302
+ return remoteAgentListImpl(arguments_, context);
2303
+ }
2304
+ try {
2305
+ if (context.orchestration && await supportsAgentWorkload(context.orchestration)) {
2306
+ return await runRemoteAgentViaOrchestration(context.orchestration, nodeId, definitionId, message, context.localNodeId);
2307
+ }
2308
+ } catch (error) {
2309
+ const errorMessage = error instanceof Error ? error.message : messageContentToText(error);
2310
+ return { error: `remoteAgent failed: ${errorMessage}` };
2311
+ }
2312
+ const sendRpc = context.sendRpcToNode ? async (nodeId2, method, parameters) => context.sendRpcToNode?.(nodeId2, method, parameters) : void 0;
2313
+ if (!sendRpc) {
2314
+ return {
2315
+ error: "Remote node RPC not configured (no sendRpcToNode). Connect to peer nodes first."
2316
+ };
2317
+ }
2318
+ try {
2319
+ const createResult = await sendRpc(nodeId, "memeloop.agent.create", {
2320
+ definitionId
2321
+ });
2322
+ const conversationId = createResult?.conversationId;
2323
+ if (!conversationId) {
2324
+ return { error: "Remote agent.create did not return conversationId", raw: createResult };
2325
+ }
2326
+ await sendRpc(nodeId, "memeloop.agent.send", {
2327
+ conversationId,
2328
+ message
2329
+ });
2330
+ const subscribeStream = context.subscribeRemoteStream;
2331
+ const streamWaitMs = context.remoteAgentStreamTimeoutMs ?? 3e4;
2332
+ const chunks = [];
2333
+ if (subscribeStream) {
2334
+ await new Promise((resolve) => {
2335
+ const unsub = subscribeStream(nodeId, conversationId, (chunk) => {
2336
+ if (typeof chunk === "string") chunks.push(chunk);
2337
+ else {
2338
+ const chunkContent = getRemoteStreamChunkContent(chunk);
2339
+ if (chunkContent !== void 0) {
2340
+ chunks.push(messageContentToText(chunkContent));
2341
+ }
2342
+ }
2343
+ });
2344
+ setTimeout(() => {
2345
+ unsub();
2346
+ resolve();
2347
+ }, streamWaitMs);
2348
+ });
2349
+ }
2350
+ const fullSummary = chunks.length > 0 ? chunks.join("").trim() : await collectRemoteConversationSummary(sendRpc, nodeId, conversationId, streamWaitMs);
2351
+ const shortSummary = truncateToolSummary(fullSummary);
2352
+ return {
2353
+ summary: fullSummary,
2354
+ remoteNodeId: nodeId,
2355
+ remoteConversationId: conversationId,
2356
+ definitionId,
2357
+ [MEMELOOP_STRUCTURED_TOOL_KEY]: {
2358
+ summary: shortSummary,
2359
+ detailRef: {
2360
+ type: "agent-run",
2361
+ conversationId,
2362
+ nodeId
2363
+ }
2364
+ }
2365
+ };
2366
+ } catch (error) {
2367
+ const message2 = error instanceof Error ? error.message : messageContentToText(error);
2368
+ return { error: `remoteAgent failed: ${message2}` };
2369
+ }
2370
+ };
2371
+ function getRemoteAgentToolId() {
2372
+ return TOOL_ID3;
2373
+ }
2374
+
2375
+ // src/tools/builtins/spawnAgent.ts
2376
+ var TOOL_ID4 = "spawnAgent";
2377
+ async function supportsAgentWorkload2(client) {
2378
+ try {
2379
+ const caps = await client.getCapabilities();
2380
+ return caps.operations.includes("apply") && caps.resourceKinds.includes("AgentWorkload");
2381
+ } catch {
2382
+ return false;
2383
+ }
2384
+ }
2385
+ async function runSpawnAgentViaOrchestration(client, definitionId, message, conversationId, localNodeId) {
2386
+ const agents = createAgentClient(client);
2387
+ const workload = await agents.createWorkload({
2388
+ name: conversationId,
2389
+ profileId: definitionId,
2390
+ completionPolicy: "complete"
2391
+ });
2392
+ const run = await agents.createRun({
2393
+ name: `${conversationId}-run`,
2394
+ workloadName: workload.metadata.name,
2395
+ promptReference: message
2396
+ });
2397
+ const result = await agents.waitForRunCondition(
2398
+ run.metadata.name,
2399
+ { type: "Completed", status: "True" },
2400
+ { timeout: 3e4, interval: 1e3 }
2401
+ );
2402
+ const finalRun = await agents.getRun(run.metadata.name);
2403
+ const summary = finalRun?.status?.summary ?? "(no summary)";
2404
+ const shortSummary = truncateToolSummary(summary);
2405
+ const nodeId = localNodeId?.trim() || "local";
2406
+ return {
2407
+ summary,
2408
+ conversationId,
2409
+ definitionId,
2410
+ [MEMELOOP_STRUCTURED_TOOL_KEY]: {
2411
+ summary: shortSummary,
2412
+ detailRef: {
2413
+ type: "agent-run",
2414
+ conversationId,
2415
+ nodeId,
2416
+ resourceVersion: result.observedResourceVersion
2417
+ }
2418
+ }
2419
+ };
2420
+ }
2421
+ async function runSpawnAgentLocally(runLocalAgent, definitionId, message, conversationId, localNodeId) {
2422
+ const chunks = [];
2423
+ for await (const step of runLocalAgent({ conversationId, message })) {
2424
+ if (step.type === "message" && typeof step.data === "string") {
2425
+ chunks.push(step.data);
2426
+ }
2427
+ if (step.type === "message" && step.data != null && typeof step.data === "object" && "content" in step.data) {
2428
+ const c = step.data.content;
2429
+ if (typeof c === "string") chunks.push(c);
2430
+ }
2431
+ }
2432
+ const fullSummary = chunks.join("").trim() || "(no text output)";
2433
+ const shortSummary = truncateToolSummary(fullSummary);
2434
+ const nodeId = localNodeId?.trim() || "local";
2435
+ return {
2436
+ summary: fullSummary,
2437
+ conversationId,
2438
+ definitionId,
2439
+ [MEMELOOP_STRUCTURED_TOOL_KEY]: {
2440
+ summary: shortSummary,
2441
+ detailRef: {
2442
+ type: "agent-run",
2443
+ conversationId,
2444
+ nodeId
2445
+ }
2446
+ }
2447
+ };
2448
+ }
2449
+ var spawnAgentConfigSchema = {
2450
+ type: "object",
2451
+ properties: {
2452
+ definitionId: { type: "string", description: "Agent definition ID to use for the agent-run" },
2453
+ message: { type: "string", description: "User message / task for the agent-run" }
2454
+ },
2455
+ required: ["definitionId", "message"]
2456
+ };
2457
+ var spawnAgentImpl = async (arguments_, context) => {
2458
+ const definitionId = arguments_.definitionId;
2459
+ const message = arguments_.message;
2460
+ if (!definitionId || typeof message !== "string") {
2461
+ return { error: "spawnAgent requires definitionId and message" };
2462
+ }
2463
+ const conversationId = `spawn:${definitionId}:${Date.now().toString(36)}`;
2464
+ try {
2465
+ if (context.orchestration && await supportsAgentWorkload2(context.orchestration)) {
2466
+ return await runSpawnAgentViaOrchestration(context.orchestration, definitionId, message, conversationId, context.localNodeId);
2467
+ }
2468
+ if (!context.runLocalAgent) {
2469
+ return {
2470
+ error: "Local agent runner not configured (no runLocalAgent in context)."
2471
+ };
2472
+ }
2473
+ return await runSpawnAgentLocally(
2474
+ (input) => context.runLocalAgent(input),
2475
+ definitionId,
2476
+ message,
2477
+ conversationId,
2478
+ context.localNodeId
2479
+ );
2480
+ } catch (error) {
2481
+ const errorMessage = error instanceof Error ? error.message : String(error);
2482
+ return { error: `spawnAgent failed: ${errorMessage}`, conversationId };
2483
+ }
2484
+ };
2485
+ function getSpawnAgentToolId() {
2486
+ return TOOL_ID4;
2487
+ }
2488
+
2489
+ // src/agent/agentProfiles.ts
2490
+ function makeBuiltinDefinition(id, name, type, prompt, permissions, model) {
2491
+ const systemPrompt = prompt;
2492
+ const tools = [];
2493
+ return {
2494
+ id,
2495
+ name,
2496
+ type,
2497
+ prompt,
2498
+ permissions,
2499
+ model,
2500
+ protocolDef: {
2501
+ id,
2502
+ name,
2503
+ description: prompt.slice(0, 200),
2504
+ systemPrompt,
2505
+ tools,
2506
+ version: "1.0.0",
2507
+ modelConfig: model ? {
2508
+ provider: model.split("/")[0] ?? "memeloop",
2509
+ model: model.split("/").slice(1).join("/") || model
2510
+ } : void 0
2511
+ }
2512
+ };
2513
+ }
2514
+ var buildAgent = makeBuiltinDefinition(
2515
+ "memeloop:build",
2516
+ "Build Agent",
2517
+ "build",
2518
+ "You are a build agent capable of executing tasks, writing and editing files, running commands, and making changes. Use tools to accomplish the user's goals efficiently.",
2519
+ { default: "allow", rules: [] }
2520
+ );
2521
+ var planAgent = makeBuiltinDefinition(
2522
+ "memeloop:plan",
2523
+ "Plan Agent",
2524
+ "plan",
2525
+ "You are a planning agent. Your role is to analyze requirements, decompose tasks, and create structured plans. You CANNOT write files or execute terminal commands. Only use read and search tools.",
2526
+ {
2527
+ default: "deny",
2528
+ rules: [
2529
+ { pattern: "file.read", action: "allow" },
2530
+ { pattern: "file.search", action: "allow" },
2531
+ { pattern: "file.list", action: "allow" },
2532
+ { pattern: "grep.search", action: "allow" },
2533
+ { pattern: "glob.*", action: "allow" }
2534
+ ]
2535
+ }
2536
+ );
2537
+ var exploreAgent = makeBuiltinDefinition(
2538
+ "memeloop:explore",
2539
+ "Explore Agent",
2540
+ "explore",
2541
+ "You are an exploration agent specialized in fast codebase search and discovery. You have read and search tools. Do NOT modify files or run terminal commands. Focus on finding relevant code, files, and patterns.",
2542
+ {
2543
+ default: "deny",
2544
+ rules: [
2545
+ { pattern: "file.read", action: "allow" },
2546
+ { pattern: "file.search", action: "allow" },
2547
+ { pattern: "file.list", action: "allow" },
2548
+ { pattern: "grep.search", action: "allow" },
2549
+ { pattern: "glob.*", action: "allow" },
2550
+ { pattern: "lsp.*", action: "allow" }
2551
+ ]
2552
+ }
2553
+ );
2554
+ var oracleAgent = makeBuiltinDefinition(
2555
+ "memeloop:oracle",
2556
+ "Oracle Agent",
2557
+ "oracle",
2558
+ "You are an oracle agent specialized in architecture analysis, code review, and constraint verification. You have read access only. Review code, identify issues, and provide expert architectural guidance.",
2559
+ {
2560
+ default: "deny",
2561
+ rules: [
2562
+ { pattern: "file.read", action: "allow" },
2563
+ { pattern: "file.search", action: "allow" },
2564
+ { pattern: "file.list", action: "allow" },
2565
+ { pattern: "grep.search", action: "allow" },
2566
+ { pattern: "glob.*", action: "allow" },
2567
+ { pattern: "lsp.*", action: "allow" }
2568
+ ]
2569
+ }
2570
+ );
2571
+ var librarianAgent = makeBuiltinDefinition(
2572
+ "memeloop:librarian",
2573
+ "Librarian Agent",
2574
+ "librarian",
2575
+ "You are a librarian agent specialized in external documentation lookup, web search, and context gathering. Use web search tools to find relevant documentation, APIs, and examples. Do NOT modify files or run terminal commands.",
2576
+ {
2577
+ default: "deny",
2578
+ rules: [
2579
+ { pattern: "file.read", action: "allow" },
2580
+ { pattern: "file.search", action: "allow" },
2581
+ { pattern: "file.list", action: "allow" },
2582
+ { pattern: "web.*", action: "allow" },
2583
+ { pattern: "grep.search", action: "allow" },
2584
+ { pattern: "glob.*", action: "allow" }
2585
+ ]
2586
+ }
2587
+ );
2588
+ var BUILTIN_AGENT_PROFILES = [
2589
+ buildAgent,
2590
+ planAgent,
2591
+ exploreAgent,
2592
+ oracleAgent,
2593
+ librarianAgent
2594
+ ];
2595
+
2596
+ // src/agent/agentProfileRegistry.ts
2597
+ var AgentProfileRegistry = class {
2598
+ profiles = /* @__PURE__ */ new Map();
2599
+ constructor() {
2600
+ this.seedDefaults();
2601
+ }
2602
+ /** Seed the registry with built-in agent profiles. */
2603
+ seedDefaults() {
2604
+ for (const profile of BUILTIN_AGENT_PROFILES) {
2605
+ this.profiles.set(profile.id, profile);
2606
+ }
2607
+ }
2608
+ /**
2609
+ * Register a new agent profile or override an existing one.
2610
+ * Throws if the profile is invalid.
2611
+ */
2612
+ registerAgentProfile(profile) {
2613
+ if (!profile.id || typeof profile.id !== "string" || profile.id.trim().length === 0) {
2614
+ throw new Error("Agent profile must have a non-empty id");
2615
+ }
2616
+ if (!profile.name || typeof profile.name !== "string") {
2617
+ throw new Error("Agent profile must have a name");
2618
+ }
2619
+ if (!profile.type || typeof profile.type !== "string") {
2620
+ throw new Error("Agent profile must have a type");
2621
+ }
2622
+ if (!profile.prompt || typeof profile.prompt !== "string") {
2623
+ throw new Error("Agent profile must have a prompt");
2624
+ }
2625
+ if (!profile.permissions || typeof profile.permissions.default !== "string") {
2626
+ throw new Error("Agent profile must have valid permissions");
2627
+ }
2628
+ this.profiles.set(profile.id, profile);
2629
+ }
2630
+ /**
2631
+ * Get an agent profile by ID.
2632
+ * Returns undefined if not found.
2633
+ */
2634
+ getAgentProfile(id) {
2635
+ return this.profiles.get(id);
2636
+ }
2637
+ /**
2638
+ * List all registered agent profiles.
2639
+ */
2640
+ listAgentProfiles() {
2641
+ return Array.from(this.profiles.values());
2642
+ }
2643
+ /**
2644
+ * List agent profiles filtered by type.
2645
+ */
2646
+ listAgentProfilesByType(type) {
2647
+ return this.listAgentProfiles().filter((profile) => profile.type === type);
2648
+ }
2649
+ /**
2650
+ * Remove an agent profile by ID.
2651
+ */
2652
+ unregisterAgentProfile(id) {
2653
+ return this.profiles.delete(id);
2654
+ }
2655
+ /**
2656
+ * Reset the registry to only built-in defaults.
2657
+ */
2658
+ reset() {
2659
+ this.profiles.clear();
2660
+ this.seedDefaults();
2661
+ }
2662
+ };
2663
+ var defaultRegistry = null;
2664
+ function getAgentProfileRegistry() {
2665
+ if (!defaultRegistry) {
2666
+ defaultRegistry = new AgentProfileRegistry();
2667
+ }
2668
+ return defaultRegistry;
2669
+ }
2670
+ function resetAgentProfileRegistry() {
2671
+ if (defaultRegistry) {
2672
+ defaultRegistry.reset();
2673
+ }
2674
+ defaultRegistry = null;
2675
+ }
2676
+
2677
+ // src/tools/builtins/task.ts
2678
+ var TOOL_ID5 = "task";
2679
+ async function supportsAgentWorkload3(client) {
2680
+ try {
2681
+ const caps = await client.getCapabilities();
2682
+ return caps.operations.includes("apply") && caps.resourceKinds.includes("AgentWorkload");
2683
+ } catch {
2684
+ return false;
2685
+ }
2686
+ }
2687
+ async function runTaskViaOrchestration(client, agentId, prompt, background, localNodeId, conversationId, permissions) {
2688
+ const agents = createAgentClient(client);
2689
+ const workload = await agents.createWorkload({
2690
+ name: conversationId,
2691
+ profileId: agentId,
2692
+ promptReference: prompt,
2693
+ completionPolicy: background ? "detach" : "complete",
2694
+ toolPolicy: {
2695
+ defaultAction: permissions.default,
2696
+ rules: permissions.rules
2697
+ }
2698
+ });
2699
+ const run = await agents.createRun({
2700
+ name: `${conversationId}-run`,
2701
+ workloadName: workload.metadata.name,
2702
+ promptReference: prompt
2703
+ });
2704
+ const nodeId = localNodeId?.trim() || "local";
2705
+ if (background) {
2706
+ return {
2707
+ summary: `Background task "${agentId}" launched. Task ID: ${conversationId}`,
2708
+ conversationId,
2709
+ agentId,
2710
+ taskId: conversationId,
2711
+ background: true,
2712
+ [MEMELOOP_STRUCTURED_TOOL_KEY]: {
2713
+ summary: `[bg-task] ${agentId}: ${conversationId}`,
2714
+ detailRef: {
2715
+ type: "agent-run",
2716
+ conversationId,
2717
+ nodeId,
2718
+ resourceVersion: run.metadata.resourceVersion
2719
+ }
2720
+ }
2721
+ };
2722
+ }
2723
+ const result = await agents.waitForRunCondition(
2724
+ run.metadata.name,
2725
+ { type: "Completed", status: "True" },
2726
+ { timeout: 3e4, interval: 1e3 }
2727
+ );
2728
+ const finalRun = await agents.getRun(run.metadata.name);
2729
+ const text = finalRun?.status?.summary ?? "(no summary)";
2730
+ const shortSummary = truncateToolSummary(text);
2731
+ return {
2732
+ result: text,
2733
+ conversationId,
2734
+ agentId,
2735
+ [MEMELOOP_STRUCTURED_TOOL_KEY]: {
2736
+ summary: shortSummary,
2737
+ detailRef: {
2738
+ type: "agent-run",
2739
+ conversationId,
2740
+ nodeId,
2741
+ resourceVersion: result.observedResourceVersion
2742
+ }
2743
+ }
2744
+ };
2745
+ }
2746
+ async function runTaskLocally(runLocalAgent, context, agentId, prompt, background, conversationId) {
2747
+ async function collectOutput(gen2) {
2748
+ const chunks = [];
2749
+ for await (const step of gen2) {
2750
+ if (step.type === "message") {
2751
+ if (typeof step.data === "string") {
2752
+ chunks.push(step.data);
2753
+ } else if (step.data != null && typeof step.data === "object" && "content" in step.data) {
2754
+ const c = step.data.content;
2755
+ if (typeof c === "string") chunks.push(c);
2756
+ }
2757
+ }
2758
+ }
2759
+ return { text: chunks.join("").trim() || "(no text output)", conversationId };
2760
+ }
2761
+ if (background) {
2762
+ const gen2 = runLocalAgent({ conversationId, message: prompt });
2763
+ void collectOutput(gen2).catch(() => {
2764
+ });
2765
+ const nodeId2 = context.localNodeId?.trim() || "local";
2766
+ return {
2767
+ summary: `Background task "${agentId}" launched. Task ID: ${conversationId}`,
2768
+ conversationId,
2769
+ agentId,
2770
+ taskId: conversationId,
2771
+ background: true,
2772
+ [MEMELOOP_STRUCTURED_TOOL_KEY]: {
2773
+ summary: `[bg-task] ${agentId}: ${conversationId}`,
2774
+ detailRef: {
2775
+ type: "agent-run",
2776
+ conversationId,
2777
+ nodeId: nodeId2
2778
+ }
2779
+ }
2780
+ };
2781
+ }
2782
+ const gen = runLocalAgent({ conversationId, message: prompt });
2783
+ const { text, conversationId: cid } = await collectOutput(gen);
2784
+ const shortSummary = truncateToolSummary(text);
2785
+ const nodeId = context.localNodeId?.trim() || "local";
2786
+ return {
2787
+ result: text,
2788
+ conversationId: cid,
2789
+ agentId,
2790
+ [MEMELOOP_STRUCTURED_TOOL_KEY]: {
2791
+ summary: shortSummary,
2792
+ detailRef: {
2793
+ type: "agent-run",
2794
+ conversationId: cid,
2795
+ nodeId
2796
+ }
2797
+ }
2798
+ };
2799
+ }
2800
+ var taskToolConfigSchema = {
2801
+ type: "object",
2802
+ properties: {
2803
+ agent: {
2804
+ type: "string",
2805
+ description: "Agent ID to delegate to (e.g. 'memeloop:build', 'memeloop:explore')"
2806
+ },
2807
+ prompt: {
2808
+ type: "string",
2809
+ description: "Task prompt / instructions for the delegated agent"
2810
+ },
2811
+ background: {
2812
+ type: "boolean",
2813
+ description: "If true, runs asynchronously and returns a task ID immediately"
2814
+ }
2815
+ },
2816
+ required: ["agent", "prompt"]
2817
+ };
2818
+ function isTooDeeplyNested(context) {
2819
+ const cid = context.activeToolConversationId;
2820
+ if (!cid) return false;
2821
+ const depth = cid.split(":").length - 1;
2822
+ return depth > 2;
2823
+ }
2824
+ function applyAgentPermissions(context, agentId, defaultAction, rules) {
2825
+ const tp = context.agentToolLoop ?? (context.agentToolLoop = {});
2826
+ const tperm = tp.toolPermissions ?? (tp.toolPermissions = {});
2827
+ const perAgent = tperm.perAgent ?? (tperm.perAgent = {});
2828
+ perAgent[agentId] = { default: defaultAction, rules };
2829
+ }
2830
+ var taskToolImpl = async (arguments_, context) => {
2831
+ const agentId = arguments_.agent;
2832
+ const prompt = arguments_.prompt;
2833
+ const background = arguments_.background;
2834
+ if (!agentId || typeof prompt !== "string" || prompt.trim().length === 0) {
2835
+ return { error: "task requires 'agent' (string) and 'prompt' (non-empty string)" };
2836
+ }
2837
+ if (isTooDeeplyNested(context)) {
2838
+ return {
2839
+ error: "Maximum agent nesting depth exceeded. Cannot delegate further."
2840
+ };
2841
+ }
2842
+ const registry = getAgentProfileRegistry();
2843
+ const agentProfile = registry.getAgentProfile(agentId);
2844
+ if (!agentProfile) {
2845
+ const available = registry.listAgentProfiles().map((a) => a.id).join(", ");
2846
+ return {
2847
+ error: `Agent "${agentId}" not found in registry. Available: [${available}]`
2848
+ };
2849
+ }
2850
+ const permissions = {
2851
+ default: agentProfile.permissions.default,
2852
+ rules: agentProfile.permissions.rules
2853
+ };
2854
+ const timestamp = Date.now().toString(36);
2855
+ const conversationId = `${agentProfile.id}:${timestamp}`;
2856
+ try {
2857
+ if (context.orchestration && await supportsAgentWorkload3(context.orchestration)) {
2858
+ return await runTaskViaOrchestration(
2859
+ context.orchestration,
2860
+ agentProfile.id,
2861
+ prompt,
2862
+ background,
2863
+ context.localNodeId,
2864
+ conversationId,
2865
+ permissions
2866
+ );
2867
+ }
2868
+ if (!context.runLocalAgent) {
2869
+ return {
2870
+ error: "Local agent runner not configured (no runLocalAgent in context)."
2871
+ };
2872
+ }
2873
+ applyAgentPermissions(
2874
+ context,
2875
+ agentProfile.id,
2876
+ permissions.default,
2877
+ permissions.rules
2878
+ );
2879
+ return await runTaskLocally(
2880
+ (input) => context.runLocalAgent(input),
2881
+ context,
2882
+ agentProfile.id,
2883
+ prompt,
2884
+ background,
2885
+ conversationId
2886
+ );
2887
+ } catch (error) {
2888
+ const message = error instanceof Error ? error.message : String(error);
2889
+ return {
2890
+ error: `Task execution failed: ${message}`,
2891
+ conversationId,
2892
+ agentId: agentProfile.id
2893
+ };
2894
+ }
2895
+ };
2896
+ function getTaskToolId() {
2897
+ return TOOL_ID5;
2898
+ }
2899
+
2900
+ // src/tools/builtins/todoWrite.ts
2901
+ import { z as z3 } from "zod";
2902
+ var todoWriteConfigSchema = z3.object({
2903
+ action: z3.enum(["create", "update", "complete", "list", "remove"]).describe("Action: create, update, complete, list, or remove"),
2904
+ id: z3.string().min(1).optional().describe("Todo item ID (required for update/complete/remove)"),
2905
+ content: z3.string().min(1).optional().describe("Todo item content (required for create/update)"),
2906
+ status: z3.enum(["pending", "in_progress", "completed", "cancelled"]).optional().describe("Status (defaults to 'pending' for create)"),
2907
+ priority: z3.enum(["high", "medium", "low"]).optional().default("medium").describe("Priority level")
2908
+ });
2909
+ var TODO_WRITE_TOOL_ID = "todoWrite";
2910
+ var conversationTodos = /* @__PURE__ */ new Map();
2911
+ function __clearTodoStore() {
2912
+ conversationTodos.clear();
2913
+ }
2914
+ function getConversationTodos(conversationId) {
2915
+ let todos = conversationTodos.get(conversationId);
2916
+ if (!todos) {
2917
+ todos = /* @__PURE__ */ new Map();
2918
+ conversationTodos.set(conversationId, todos);
2919
+ }
2920
+ return todos;
2921
+ }
2922
+ function formatTodoList(todos) {
2923
+ if (todos.size === 0) {
2924
+ return "(No todos)";
2925
+ }
2926
+ const statusOrder = {
2927
+ in_progress: 0,
2928
+ pending: 1,
2929
+ completed: 2,
2930
+ cancelled: 3
2931
+ };
2932
+ const sorted = [...todos.values()].sort(
2933
+ (a, b) => (statusOrder[a.status] ?? 99) - (statusOrder[b.status] ?? 99) || b.updatedAt - a.updatedAt
2934
+ );
2935
+ const statusIcons = {
2936
+ pending: "\u25CB",
2937
+ in_progress: "\u25C9",
2938
+ completed: "\u2713",
2939
+ cancelled: "\u2717"
2940
+ };
2941
+ return sorted.map(
2942
+ (t) => `${statusIcons[t.status] ?? "?"} [${t.priority}] ${t.content} (id: ${t.id})`
2943
+ ).join("\n");
2944
+ }
2945
+ function getConversationId(context) {
2946
+ return context.agent?.id ?? context.activeToolConversationId ?? "default";
2947
+ }
2948
+ async function todoWriteImpl(arguments_, context) {
2949
+ const parsed = todoWriteConfigSchema.safeParse(arguments_);
2950
+ if (!parsed.success) {
2951
+ return { error: `invalid_todoWrite_args: ${parsed.error.message}` };
2952
+ }
2953
+ const { action, id, content, status, priority } = parsed.data;
2954
+ const conversationId = getConversationId(context);
2955
+ const todos = getConversationTodos(conversationId);
2956
+ const now = Date.now();
2957
+ switch (action) {
2958
+ case "create": {
2959
+ if (!content) {
2960
+ return { error: "content is required for create action" };
2961
+ }
2962
+ const newId = id ?? crypto.randomUUID();
2963
+ if (todos.has(newId)) {
2964
+ return { error: `Todo with id '${newId}' already exists. Use update action.` };
2965
+ }
2966
+ const item = {
2967
+ id: newId,
2968
+ content,
2969
+ status: status ?? "pending",
2970
+ priority,
2971
+ createdAt: now,
2972
+ updatedAt: now
2973
+ };
2974
+ todos.set(newId, item);
2975
+ return {
2976
+ result: `Todo created: [${item.priority}] ${item.content} (id: ${item.id})
2977
+
2978
+ ${formatTodoList(todos)}`
2979
+ };
2980
+ }
2981
+ case "update": {
2982
+ if (!id) {
2983
+ return { error: "id is required for update action" };
2984
+ }
2985
+ const existing = todos.get(id);
2986
+ if (!existing) {
2987
+ return { error: `Todo with id '${id}' not found` };
2988
+ }
2989
+ if (content !== void 0) existing.content = content;
2990
+ if (status !== void 0) existing.status = status;
2991
+ existing.priority = priority ?? existing.priority;
2992
+ existing.updatedAt = now;
2993
+ return {
2994
+ result: `Todo updated: [${existing.priority}] ${existing.content} (id: ${existing.id}, status: ${existing.status})
2995
+
2996
+ ${formatTodoList(todos)}`
2997
+ };
2998
+ }
2999
+ case "complete": {
3000
+ if (!id) {
3001
+ return { error: "id is required for complete action" };
3002
+ }
3003
+ const existing = todos.get(id);
3004
+ if (!existing) {
3005
+ return { error: `Todo with id '${id}' not found` };
3006
+ }
3007
+ existing.status = "completed";
3008
+ existing.updatedAt = now;
3009
+ return {
3010
+ result: `Todo completed: [${existing.priority}] ${existing.content} (id: ${existing.id})
3011
+
3012
+ ${formatTodoList(todos)}`
3013
+ };
3014
+ }
3015
+ case "remove": {
3016
+ if (!id) {
3017
+ let removed2 = 0;
3018
+ for (const [key, item] of todos) {
3019
+ if (item.status === "completed" || item.status === "cancelled") {
3020
+ todos.delete(key);
3021
+ removed2++;
3022
+ }
3023
+ }
3024
+ return {
3025
+ result: `Removed ${removed2} completed/cancelled todo(s)
3026
+
3027
+ ${formatTodoList(todos)}`
3028
+ };
3029
+ }
3030
+ const removed = todos.delete(id);
3031
+ return {
3032
+ result: removed ? `Todo removed: ${id}
3033
+
3034
+ ${formatTodoList(todos)}` : `Todo with id '${id}' not found
3035
+
3036
+ ${formatTodoList(todos)}`
3037
+ };
3038
+ }
3039
+ case "list":
3040
+ default: {
3041
+ return {
3042
+ result: `Todo list (${todos.size} items):
3043
+
3044
+ ${formatTodoList(todos)}`
3045
+ };
3046
+ }
3047
+ }
3048
+ }
3049
+
3050
+ // src/loopAPI/plugins/builtinToolsPlugin.ts
3051
+ var PLUGIN_MCP_CLIENT = "builtin:mcp-client";
3052
+ var PLUGIN_MCP_FORWARD = "builtin:mcp-forward";
3053
+ var PLUGIN_ORCHESTRATION = "builtin:orchestration";
3054
+ var PLUGIN_SPAWN_AGENT = "builtin:spawn-agent";
3055
+ var PLUGIN_REMOTE_AGENT = "builtin:remote-agent";
3056
+ var PLUGIN_ASK_QUESTION = "builtin:ask-question";
3057
+ var PLUGIN_TODO_WRITE = "builtin:todo-write";
3058
+ var PLUGIN_ASK_USER_QUESTION = "builtin:ask-user-question";
3059
+ var PLUGIN_TASK = "builtin:task";
3060
+ var BUILTIN_TOOL_PLUGIN_IDS = [
3061
+ PLUGIN_MCP_CLIENT,
3062
+ PLUGIN_MCP_FORWARD,
3063
+ PLUGIN_ORCHESTRATION,
3064
+ PLUGIN_SPAWN_AGENT,
3065
+ PLUGIN_REMOTE_AGENT,
3066
+ PLUGIN_ASK_QUESTION,
3067
+ PLUGIN_TODO_WRITE,
3068
+ PLUGIN_ASK_USER_QUESTION,
3069
+ PLUGIN_TASK
3070
+ ];
3071
+ function getToolRegistry(context) {
3072
+ return context.toolRegistry;
3073
+ }
3074
+ function createBuiltinToolPlugin(options) {
3075
+ return {
3076
+ id: options.id,
3077
+ targetLoopId: "*",
3078
+ install: (context) => {
3079
+ const registry = getToolRegistry(context);
3080
+ if (!registry) return;
3081
+ const builtinContext = context;
3082
+ const implementation = (arguments_) => options.implementation(arguments_, builtinContext);
3083
+ if (options.effect === void 0) {
3084
+ registry.registerTool(options.toolId, implementation, options.schema);
3085
+ } else {
3086
+ registry.registerTool(
3087
+ options.toolId,
3088
+ implementation,
3089
+ options.schema,
3090
+ options.effect
3091
+ );
3092
+ }
3093
+ registerToolParameterSchema(options.toolId, options.schema, options.metadata);
3094
+ }
3095
+ };
3096
+ }
3097
+ var builtinToolPlugins = [
3098
+ createBuiltinToolPlugin({
3099
+ id: PLUGIN_MCP_CLIENT,
3100
+ toolId: getMcpClientToolId(),
3101
+ schema: mcpClientConfigSchema,
3102
+ metadata: {
3103
+ displayName: "MCP Client",
3104
+ description: "Call a tool on a remote MCP server (transparent proxy). Requires nodeId, serverName, toolName, and optional args."
3105
+ },
3106
+ implementation: mcpClientImpl
3107
+ }),
3108
+ createBuiltinToolPlugin({
3109
+ id: PLUGIN_MCP_FORWARD,
3110
+ toolId: getMcpForwardToolId(),
3111
+ schema: mcpForwardConfigSchema,
3112
+ metadata: {
3113
+ displayName: "MCP Forward",
3114
+ description: "Discover MCP servers and tools on connected nodes. Use action='list' for nodes with servers, action='listTools' for all available tools."
3115
+ },
3116
+ implementation: mcpForwardImpl
3117
+ }),
3118
+ createBuiltinToolPlugin({
3119
+ id: PLUGIN_ORCHESTRATION,
3120
+ toolId: ORCHESTRATION_TOOL_ID,
3121
+ schema: orchestrationConfigSchema,
3122
+ metadata: {
3123
+ displayName: "Orchestration",
3124
+ description: "Discover and manage declarative resources through the policy-scoped orchestration manager."
3125
+ },
3126
+ implementation: orchestrationImpl
3127
+ }),
3128
+ createBuiltinToolPlugin({
3129
+ id: PLUGIN_SPAWN_AGENT,
3130
+ toolId: getSpawnAgentToolId(),
3131
+ schema: spawnAgentConfigSchema,
3132
+ metadata: {
3133
+ displayName: "Spawn Agent",
3134
+ description: "Run a local agent-agent-loop with the given definition and message. Returns summary."
3135
+ },
3136
+ implementation: spawnAgentImpl
3137
+ }),
3138
+ createBuiltinToolPlugin({
3139
+ id: PLUGIN_REMOTE_AGENT,
3140
+ toolId: getRemoteAgentToolId(),
3141
+ schema: remoteAgentConfigSchema,
3142
+ metadata: {
3143
+ displayName: "Remote Agent",
3144
+ description: "Create and run a agent-agent-loop on a remote node. Requires nodeId, definitionId, message. List nodes with no args."
3145
+ },
3146
+ implementation: remoteAgentImpl
3147
+ }),
3148
+ createBuiltinToolPlugin({
3149
+ id: PLUGIN_ASK_QUESTION,
3150
+ toolId: ASK_QUESTION_TOOL_ID,
3151
+ schema: askQuestionConfigSchema,
3152
+ metadata: {
3153
+ displayName: "Ask Question",
3154
+ description: "Block until the user answers (via memeloop.agent.resolveQuestion RPC). Args: question, conversationId, optional timeoutMs."
3155
+ },
3156
+ implementation: askQuestionImpl
3157
+ }),
3158
+ createBuiltinToolPlugin({
3159
+ id: PLUGIN_TODO_WRITE,
3160
+ toolId: TODO_WRITE_TOOL_ID,
3161
+ effect: "update",
3162
+ schema: todoWriteConfigSchema,
3163
+ metadata: {
3164
+ displayName: "Todo Write",
3165
+ description: "Manage structured todo lists: create, update, complete, list, remove. Todos scoped per conversation."
3166
+ },
3167
+ implementation: todoWriteImpl
3168
+ }),
3169
+ createBuiltinToolPlugin({
3170
+ id: PLUGIN_ASK_USER_QUESTION,
3171
+ toolId: ASK_USER_QUESTION_TOOL_ID,
3172
+ schema: askUserQuestionConfigSchema,
3173
+ metadata: {
3174
+ displayName: "Ask User Question",
3175
+ description: "Pause agent and ask user a question. Supports text, single-select, and multi-select input types. Blocks until answered."
3176
+ },
3177
+ implementation: askUserQuestionImpl
3178
+ }),
3179
+ createBuiltinToolPlugin({
3180
+ id: PLUGIN_TASK,
3181
+ toolId: getTaskToolId(),
3182
+ schema: taskToolConfigSchema,
3183
+ metadata: {
3184
+ displayName: "Task Delegation",
3185
+ description: "Delegate a task to a specialized agent-agent-loop (build, plan, explore, oracle, librarian). Supports sync (default) and background modes."
3186
+ },
3187
+ implementation: taskToolImpl
3188
+ })
3189
+ ];
3190
+ function getBuiltinToolPlugins() {
3191
+ return builtinToolPlugins;
3192
+ }
3193
+ function registerBuiltinToolPlugins() {
3194
+ const loopRegistry = getLoopRegistry();
3195
+ for (const plugin of builtinToolPlugins) {
3196
+ if (loopRegistry.getPlugin(plugin.id)) continue;
3197
+ loopRegistry.registerPlugin(plugin);
3198
+ }
3199
+ }
3200
+
3201
+ // src/promptUtilities/builtinPromptPlugins.ts
3202
+ var FULL_REPLACEMENT_PLUGIN_TOOL_ID = "fullReplacement";
3203
+ var DYNAMIC_POSITION_PLUGIN_TOOL_ID = "dynamicPosition";
3204
+ function registerFullReplacement(reg) {
3205
+ if (reg.has(FULL_REPLACEMENT_PLUGIN_TOOL_ID)) return;
3206
+ reg.set(FULL_REPLACEMENT_PLUGIN_TOOL_ID, (hooks) => {
3207
+ hooks.processPrompts.tapAsync(
3208
+ "fullReplacementLite",
3209
+ (context, callback) => {
3210
+ const msgs = context.messages;
3211
+ if (!Array.isArray(msgs)) {
3212
+ callback();
3213
+ return;
3214
+ }
3215
+ const maxChars = context?.maxReplacementChars ?? 48e3;
3216
+ if (!Number.isFinite(maxChars) || maxChars <= 0) {
3217
+ callback();
3218
+ return;
3219
+ }
3220
+ let total = 0;
3221
+ const kept = [];
3222
+ for (let index = msgs.length - 1; index >= 0; index--) {
3223
+ const m = msgs[index];
3224
+ const c = typeof m?.content === "string" ? m.content : m?.content != null ? JSON.stringify(m.content) : "";
3225
+ total += c.length;
3226
+ if (total > maxChars) break;
3227
+ kept.push(m);
3228
+ }
3229
+ kept.reverse();
3230
+ context.messages = kept;
3231
+ callback();
3232
+ }
3233
+ );
3234
+ });
3235
+ }
3236
+ function registerDynamicPosition(reg) {
3237
+ if (reg.has(DYNAMIC_POSITION_PLUGIN_TOOL_ID)) return;
3238
+ reg.set(DYNAMIC_POSITION_PLUGIN_TOOL_ID, (hooks) => {
3239
+ hooks.processPrompts.tapAsync(
3240
+ "dynamicPositionLite",
3241
+ (context, callback) => {
3242
+ const prompts = context.prompts;
3243
+ const messages = context.messages;
3244
+ if (!Array.isArray(prompts) || prompts.length < 2 || !Array.isArray(messages)) {
3245
+ callback();
3246
+ return;
3247
+ }
3248
+ const userTurns = messages.filter((m) => m?.role === "user").length;
3249
+ if (userTurns < 2) {
3250
+ callback();
3251
+ return;
3252
+ }
3253
+ const deferred = [];
3254
+ const rest = [];
3255
+ for (const n of prompts) {
3256
+ if (n?.dynamicPosition === "deferToEnd") deferred.push(n);
3257
+ else rest.push(n);
3258
+ }
3259
+ if (deferred.length === 0) {
3260
+ callback();
3261
+ return;
3262
+ }
3263
+ context.prompts = [...rest, ...deferred];
3264
+ callback();
3265
+ }
3266
+ );
3267
+ });
3268
+ }
3269
+ function registerBuiltinPromptPlugins(target) {
3270
+ const reg = target ?? getActivePluginRegistry();
3271
+ registerFullReplacement(reg);
3272
+ registerDynamicPosition(reg);
3273
+ }
3274
+
3275
+ // src/runtime.ts
3276
+ async function drainAgentLoop(gen, conversationId, notify) {
3277
+ try {
3278
+ for await (const step of gen) {
3279
+ notify(conversationId, { type: "agent-step", step });
3280
+ }
3281
+ notify(conversationId, { type: "agent-done" });
3282
+ } catch (error) {
3283
+ notify(conversationId, {
3284
+ type: "agent-error",
3285
+ error: error instanceof Error ? error.message : String(error)
3286
+ });
3287
+ }
3288
+ }
3289
+ function inferDefinitionIdFromConversationId(conversationId) {
3290
+ const parts = conversationId.split(":");
3291
+ if (parts.length >= 2) return parts.slice(0, -1).join(":");
3292
+ return conversationId;
3293
+ }
3294
+ async function resolveDefinitionId(context, conversationId) {
3295
+ try {
3296
+ const meta = await context.storage.getConversationMeta(conversationId);
3297
+ if (meta?.definitionId) return meta.definitionId;
3298
+ } catch {
3299
+ }
3300
+ return inferDefinitionIdFromConversationId(conversationId);
3301
+ }
3302
+ async function resolveLoopProfile(context, definitionId) {
3303
+ const definition = (context.resolveAgentDefinition ? await context.resolveAgentDefinition(definitionId) : null) ?? await context.storage.getAgentDefinition(definitionId) ?? getBuiltinLoopProfile(definitionId) ?? null;
3304
+ if (!definition) return null;
3305
+ return definition;
3306
+ }
3307
+ async function createProfileRunner(context, definitionId, runtime) {
3308
+ const profile = await resolveLoopProfile(context, definitionId);
3309
+ if (!profile) return null;
3310
+ return createAgentProfileRunner(context, profile, runtime);
3311
+ }
3312
+ async function createAgentProfileRunner(context, profile, runtime) {
3313
+ registerBuiltinLoops();
3314
+ registerBuiltinToolPlugins();
3315
+ registerBuiltinPromptPlugins(context.tools.getPromptPlugins?.());
3316
+ const runnerContext = {
3317
+ ...context,
3318
+ runtime,
3319
+ scriptPolicy: context.loopScriptPolicy,
3320
+ toolRegistry: context.tools
3321
+ };
3322
+ return getLoopRegistry().createRunnerForProfile(profile, runnerContext);
3323
+ }
3324
+ async function createAgentLoopScriptRunner(context, profile, conversationId) {
3325
+ const cancellation = context.conversationCancellation ?? /* @__PURE__ */ new Set();
3326
+ context.conversationCancellation ??= cancellation;
3327
+ const scriptState = /* @__PURE__ */ new Map();
3328
+ return createAgentProfileRunner(
3329
+ context,
3330
+ profile,
3331
+ createScriptRuntime(context, cancellation, scriptState, conversationId)
3332
+ );
3333
+ }
3334
+ function createScriptRuntime(context, cancellation, scriptState, conversationId, parentConversationId) {
3335
+ const stateKey = (key) => `${conversationId}:${key}`;
3336
+ return {
3337
+ orchestration: context.orchestration,
3338
+ scriptDeployment: context.scriptDeployment,
3339
+ runChildAgent: async function* (input) {
3340
+ const childRuntime = createScriptRuntime(
3341
+ context,
3342
+ cancellation,
3343
+ scriptState,
3344
+ input.conversationId,
3345
+ conversationId
3346
+ );
3347
+ const run = await createProfileRunner(context, input.profileId, childRuntime);
3348
+ if (!run) {
3349
+ yield {
3350
+ type: "message",
3351
+ data: `Child agent profile not found: ${input.profileId}`
3352
+ };
3353
+ return;
3354
+ }
3355
+ yield* run({ conversationId: input.conversationId, message: input.prompt });
3356
+ },
3357
+ log: (event, data) => context.logger?.debug?.(event, data),
3358
+ emit: () => void 0,
3359
+ signal: {
3360
+ get cancelled() {
3361
+ return cancellation.has(conversationId) || (parentConversationId ? cancellation.has(parentConversationId) : false);
3362
+ }
3363
+ },
3364
+ state: {
3365
+ get: async (key) => {
3366
+ const local = scriptState.get(stateKey(key));
3367
+ if (local !== void 0) return local;
3368
+ const persisted = await context.loopCheckpoints?.loadCheckpoint(conversationId, `state:${key}`);
3369
+ if (persisted !== void 0) scriptState.set(stateKey(key), persisted);
3370
+ return persisted;
3371
+ },
3372
+ set: async (key, value) => {
3373
+ scriptState.set(stateKey(key), value);
3374
+ await context.loopCheckpoints?.saveCheckpoint(conversationId, `state:${key}`, value);
3375
+ },
3376
+ update: async (key, updater) => {
3377
+ const fullKey = stateKey(key);
3378
+ const previous = scriptState.get(fullKey);
3379
+ const next = updater(previous);
3380
+ scriptState.set(fullKey, next);
3381
+ await context.loopCheckpoints?.saveCheckpoint(conversationId, `state:${key}`, next);
3382
+ }
3383
+ },
3384
+ checkpoint: async (key, result) => {
3385
+ scriptState.set(stateKey(`checkpoint:${key}`), result);
3386
+ await context.loopCheckpoints?.saveCheckpoint(conversationId, key, result);
3387
+ },
3388
+ loadCheckpoint: async (key) => {
3389
+ const memoryKey = stateKey(`checkpoint:${key}`);
3390
+ if (scriptState.has(memoryKey)) return scriptState.get(memoryKey);
3391
+ const result = await context.loopCheckpoints?.loadCheckpoint(conversationId, key);
3392
+ if (result !== void 0) scriptState.set(memoryKey, result);
3393
+ return result;
3394
+ }
3395
+ };
3396
+ }
3397
+ async function createAgentLoopRunner(context, options) {
3398
+ const cancellation = context.conversationCancellation ?? /* @__PURE__ */ new Set();
3399
+ context.conversationCancellation ??= cancellation;
3400
+ const scriptState = /* @__PURE__ */ new Map();
3401
+ const conversationId = options.conversationId ?? options.definitionId;
3402
+ return createProfileRunner(
3403
+ context,
3404
+ options.definitionId,
3405
+ createScriptRuntime(context, cancellation, scriptState, conversationId)
3406
+ );
3407
+ }
3408
+ function createMemeLoopRuntime(context) {
3409
+ const listeners = /* @__PURE__ */ new Map();
3410
+ const cancellation = context.conversationCancellation ?? /* @__PURE__ */ new Set();
3411
+ const scriptState = /* @__PURE__ */ new Map();
3412
+ context.conversationCancellation ??= cancellation;
3413
+ function notify(conversationId, update) {
3414
+ const set = listeners.get(conversationId);
3415
+ if (!set) return;
3416
+ for (const listener of set) {
3417
+ listener(update);
3418
+ }
3419
+ }
3420
+ async function runAgentLoop(input, definitionId) {
3421
+ const run = context.runAgentToolLoop ?? await createProfileRunner(
3422
+ context,
3423
+ definitionId,
3424
+ createScriptRuntime(context, cancellation, scriptState, input.conversationId)
3425
+ );
3426
+ if (!run) return false;
3427
+ void drainAgentLoop(run(input), input.conversationId, notify);
3428
+ return true;
3429
+ }
3430
+ async function* runChildAgent(input) {
3431
+ const run = await createProfileRunner(
3432
+ context,
3433
+ input.profileId,
3434
+ createScriptRuntime(context, cancellation, scriptState, input.conversationId)
3435
+ );
3436
+ if (!run) {
3437
+ yield {
3438
+ type: "message",
3439
+ data: `Child agent profile not found: ${input.profileId}`
3440
+ };
3441
+ return;
3442
+ }
3443
+ yield* run({ conversationId: input.conversationId, message: input.prompt });
3444
+ }
3445
+ context.runChildAgent ??= runChildAgent;
3446
+ return {
3447
+ async createAgent(options) {
3448
+ const now = Date.now();
3449
+ const conversationId = `${options.definitionId}:${now.toString(36)}`;
3450
+ cancellation?.delete(conversationId);
3451
+ const meta = {
3452
+ conversationId,
3453
+ title: options.definitionId,
3454
+ lastMessagePreview: context.runAgentToolLoop ? "" : options.initialMessage ?? "",
3455
+ lastMessageTimestamp: now,
3456
+ messageCount: context.runAgentToolLoop || !options.initialMessage ? 0 : 1,
3457
+ originNodeId: "local",
3458
+ definitionId: options.definitionId,
3459
+ isUserInitiated: true
3460
+ };
3461
+ await context.storage.upsertConversationMetadata(meta);
3462
+ if (options.initialMessage) {
3463
+ const started = await runAgentLoop(
3464
+ { conversationId, message: options.initialMessage },
3465
+ options.definitionId
3466
+ );
3467
+ if (started) {
3468
+ notify(conversationId, { type: "created", conversationId });
3469
+ return { conversationId };
3470
+ }
3471
+ }
3472
+ if (options.initialMessage) {
3473
+ const message = {
3474
+ messageId: `${conversationId}:m1`,
3475
+ conversationId,
3476
+ originNodeId: meta.originNodeId,
3477
+ timestamp: now,
3478
+ lamportClock: 1,
3479
+ role: "user",
3480
+ content: options.initialMessage
3481
+ };
3482
+ await context.storage.appendMessage(message);
3483
+ }
3484
+ notify(conversationId, { type: "created", conversationId });
3485
+ return { conversationId };
3486
+ },
3487
+ async sendMessage(options) {
3488
+ cancellation?.delete(options.conversationId);
3489
+ const definitionId = options.definitionId ?? await resolveDefinitionId(context, options.conversationId);
3490
+ const started = await runAgentLoop(
3491
+ {
3492
+ conversationId: options.conversationId,
3493
+ message: options.message,
3494
+ userMessage: options.userMessage,
3495
+ resumeSession: options.resumeSession
3496
+ },
3497
+ definitionId
3498
+ );
3499
+ if (started) {
3500
+ notify(options.conversationId, { type: "message-queued" });
3501
+ return;
3502
+ }
3503
+ if (options.resumeSession && options.resumeSession.length > 0) {
3504
+ await context.storage.insertMessagesIfAbsent(options.resumeSession);
3505
+ }
3506
+ const now = Date.now();
3507
+ const lamportClock = await nextLamportClockForConversation(
3508
+ context.storage,
3509
+ options.conversationId
3510
+ );
3511
+ const hostUserMessage = options.userMessage;
3512
+ const message = {
3513
+ ...hostUserMessage,
3514
+ messageId: hostUserMessage?.messageId ?? `${options.conversationId}:${now.toString(36)}`,
3515
+ conversationId: options.conversationId,
3516
+ originNodeId: hostUserMessage?.originNodeId ?? "local",
3517
+ timestamp: hostUserMessage?.timestamp ?? now,
3518
+ lamportClock: hostUserMessage?.lamportClock ?? lamportClock,
3519
+ role: "user",
3520
+ content: hostUserMessage?.content ?? options.message
3521
+ };
3522
+ await context.storage.appendMessage(message);
3523
+ notify(options.conversationId, { type: "message-queued" });
3524
+ },
3525
+ async cancelAgent(conversationId) {
3526
+ cancellation?.add(conversationId);
3527
+ notify(conversationId, { type: "cancelled" });
3528
+ },
3529
+ subscribeToUpdates(conversationId, listener) {
3530
+ const set = listeners.get(conversationId) ?? /* @__PURE__ */ new Set();
3531
+ set.add(listener);
3532
+ listeners.set(conversationId, set);
3533
+ return () => {
3534
+ const current = listeners.get(conversationId);
3535
+ if (!current) return;
3536
+ current.delete(listener);
3537
+ if (current.size === 0) {
3538
+ listeners.delete(conversationId);
3539
+ }
3540
+ };
3541
+ }
3542
+ };
3543
+ }
3544
+
3545
+ export {
3546
+ BUILTIN_AGENT_AGENT_LOOP_ARTIFACT_RESOURCE_LIFECYCLE_SCRIPT_ID,
3547
+ BUILTIN_AGENT_AGENT_LOOP_DECLARATIVE_AGENT_RUN_SCRIPT_ID,
3548
+ BUILTIN_AGENT_AGENT_LOOP_QUALITY_GATE_SCRIPT_ID,
3549
+ builtinAgentAgentLoopSources,
3550
+ getBuiltinAgentAgentLoopSource,
3551
+ waitForCondition,
3552
+ createAgentClient,
3553
+ toolSchemaToJsonSchema,
3554
+ registerToolParameterSchema,
3555
+ getToolParameterSchema,
3556
+ getToolMetadata,
3557
+ BUILTIN_RUNTIME_CLASSES,
3558
+ selectRuntimeClass,
3559
+ BUILTIN_AGENT_TOOL_LOOP_DEFAULT_SCRIPT_ID,
3560
+ builtinAgentToolLoopSources,
3561
+ getBuiltinAgentToolLoopSource,
3562
+ digestNormalizedScript,
3563
+ validateScript,
3564
+ normalizeScript,
3565
+ loadAgentToolLoopScript,
3566
+ createAgentToolLoopDefinition,
3567
+ AGENT_TOOL_LOOP_ID,
3568
+ AGENT_AGENT_LOOP_ID,
3569
+ registerBuiltinLoops,
3570
+ resolveQuestionAnswer,
3571
+ askQuestionConfigSchema,
3572
+ ASK_QUESTION_TOOL_ID,
3573
+ askQuestionImpl,
3574
+ askUserQuestionConfigSchema,
3575
+ ASK_USER_QUESTION_TOOL_ID,
3576
+ askUserQuestionImpl,
3577
+ mcpClientConfigSchema,
3578
+ mcpClientImpl,
3579
+ getMcpClientToolId,
3580
+ mcpForwardConfigSchema,
3581
+ mcpForwardImpl,
3582
+ getMcpForwardToolId,
3583
+ ORCHESTRATION_TOOL_ID,
3584
+ orchestrationConfigSchema,
3585
+ orchestrationImpl,
3586
+ remoteAgentConfigSchema,
3587
+ remoteAgentListImpl,
3588
+ remoteAgentImpl,
3589
+ getRemoteAgentToolId,
3590
+ spawnAgentConfigSchema,
3591
+ spawnAgentImpl,
3592
+ getSpawnAgentToolId,
3593
+ buildAgent,
3594
+ planAgent,
3595
+ exploreAgent,
3596
+ oracleAgent,
3597
+ librarianAgent,
3598
+ BUILTIN_AGENT_PROFILES,
3599
+ AgentProfileRegistry,
3600
+ getAgentProfileRegistry,
3601
+ resetAgentProfileRegistry,
3602
+ taskToolConfigSchema,
3603
+ taskToolImpl,
3604
+ getTaskToolId,
3605
+ todoWriteConfigSchema,
3606
+ TODO_WRITE_TOOL_ID,
3607
+ __clearTodoStore,
3608
+ todoWriteImpl,
3609
+ PLUGIN_MCP_CLIENT,
3610
+ PLUGIN_MCP_FORWARD,
3611
+ PLUGIN_ORCHESTRATION,
3612
+ PLUGIN_SPAWN_AGENT,
3613
+ PLUGIN_REMOTE_AGENT,
3614
+ PLUGIN_ASK_QUESTION,
3615
+ PLUGIN_TODO_WRITE,
3616
+ PLUGIN_ASK_USER_QUESTION,
3617
+ PLUGIN_TASK,
3618
+ BUILTIN_TOOL_PLUGIN_IDS,
3619
+ getBuiltinToolPlugins,
3620
+ registerBuiltinToolPlugins,
3621
+ registerBuiltinPromptPlugins,
3622
+ createAgentProfileRunner,
3623
+ createAgentLoopScriptRunner,
3624
+ createAgentLoopRunner,
3625
+ createMemeLoopRuntime,
3626
+ defaultRequestedInterfacesForTrustClass,
3627
+ maxScriptBytesForTrustClass,
3628
+ admitScript,
3629
+ remoteDeploymentToWorkloadManifest,
3630
+ deployGeneratedScript,
3631
+ createScriptLoadGate,
3632
+ createScriptDeploymentClient,
3633
+ loadAgentAgentLoopScript,
3634
+ createAgentAgentLoopDefinition,
3635
+ getAgentAgentLoopId
3636
+ };
3637
+ //# sourceMappingURL=chunk-XHRBV6I3.js.map