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,1413 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/browser.ts
21
+ var browser_exports = {};
22
+ __export(browser_exports, {
23
+ ALL_CATEGORIES: () => ALL_CATEGORIES,
24
+ AgentCreationController: () => AgentCreationController,
25
+ AgentDefinitionEditorController: () => AgentDefinitionEditorController,
26
+ AgentSessionController: () => AgentSessionController,
27
+ OrchestrationError: () => OrchestrationError,
28
+ PromptPreviewController: () => PromptPreviewController,
29
+ REMOTE_ORCHESTRATION_PROTOCOL: () => REMOTE_ORCHESTRATION_PROTOCOL,
30
+ TiddlyWikiHttpStorage: () => TiddlyWikiHttpStorage,
31
+ createFetchOrchestrationTransport: () => createFetchOrchestrationTransport,
32
+ createNamespacedOrchestrationClient: () => createNamespacedOrchestrationClient,
33
+ createReadOnlyOrchestrationClient: () => createReadOnlyOrchestrationClient,
34
+ createRemoteOrchestrationClient: () => createRemoteOrchestrationClient,
35
+ createRemoteOrchestrationHandler: () => createRemoteOrchestrationHandler,
36
+ getCategoryConfig: () => getCategoryConfig,
37
+ isTaskCategory: () => isTaskCategory,
38
+ resolveCategory: () => resolveCategory
39
+ });
40
+ module.exports = __toCommonJS(browser_exports);
41
+
42
+ // src/orchestration/errors.ts
43
+ var OrchestrationError = class extends Error {
44
+ code;
45
+ retryable;
46
+ retryAfterMs;
47
+ reason;
48
+ details;
49
+ constructor(data) {
50
+ super(data.message);
51
+ this.name = "OrchestrationError";
52
+ this.code = data.code;
53
+ this.retryable = data.retryable;
54
+ this.retryAfterMs = data.retryAfterMs;
55
+ this.reason = data.reason;
56
+ this.details = data.details;
57
+ }
58
+ toJSON() {
59
+ return {
60
+ code: this.code,
61
+ message: this.message,
62
+ retryable: this.retryable,
63
+ retryAfterMs: this.retryAfterMs,
64
+ reason: this.reason,
65
+ details: this.details
66
+ };
67
+ }
68
+ };
69
+
70
+ // src/storage/tiddlyWikiHttpStorage.ts
71
+ var PREFIX = "$:/memeloop";
72
+ var DEFAULT_MAX_INLINE_BLOB = 256 * 1024;
73
+ var DEFAULT_CAS_ATTEMPTS = 3;
74
+ function bytesToBase64(bytes) {
75
+ let binary = "";
76
+ for (const byte of bytes) binary += String.fromCharCode(byte);
77
+ return btoa(binary);
78
+ }
79
+ function base64ToBytes(value) {
80
+ const binary = atob(value);
81
+ const bytes = new Uint8Array(binary.length);
82
+ for (let index = 0; index < binary.length; index += 1) bytes[index] = binary.charCodeAt(index);
83
+ return bytes;
84
+ }
85
+ function escapeFilterValue(value) {
86
+ return value.replace(/["\\[\]]/g, (character) => `\\${character}`);
87
+ }
88
+ var TiddlyWikiHttpStorage = class {
89
+ baseUrl;
90
+ recipe;
91
+ fetchImpl;
92
+ credentialHandle;
93
+ credentialResolver;
94
+ maxInlineBlobBytes;
95
+ maxCasAttempts;
96
+ constructor(options) {
97
+ this.baseUrl = options.baseUrl.replace(/\/+$/, "");
98
+ this.recipe = options.recipe ?? "default";
99
+ this.fetchImpl = options.fetchImpl ?? globalThis.fetch.bind(globalThis);
100
+ this.maxInlineBlobBytes = options.maxInlineBlobBytes ?? DEFAULT_MAX_INLINE_BLOB;
101
+ this.maxCasAttempts = options.maxCasAttempts ?? DEFAULT_CAS_ATTEMPTS;
102
+ if (options.credentialHandle === void 0 !== (options.credentialResolver === void 0)) {
103
+ throw new OrchestrationError({
104
+ code: "INVALID",
105
+ message: "credentialHandle and credentialResolver must be provided together",
106
+ retryable: false
107
+ });
108
+ }
109
+ this.credentialHandle = options.credentialHandle;
110
+ this.credentialResolver = options.credentialResolver;
111
+ }
112
+ eventTitle(conversationId, messageId) {
113
+ return `${PREFIX}/e/${conversationId}/${messageId}`;
114
+ }
115
+ metaTitle(conversationId) {
116
+ return `${PREFIX}/meta/${conversationId}`;
117
+ }
118
+ blobTitle(contentHash) {
119
+ return `${PREFIX}/blob/${contentHash}`;
120
+ }
121
+ definitionTitle(id) {
122
+ return `${PREFIX}/def/${id}`;
123
+ }
124
+ instanceTitle(id) {
125
+ return `${PREFIX}/inst/${id}`;
126
+ }
127
+ imTitle(channelId, imUserId) {
128
+ return `${PREFIX}/im/${channelId}/${imUserId}`;
129
+ }
130
+ tiddlerUrl(title) {
131
+ return `${this.baseUrl}/recipes/${encodeURIComponent(this.recipe)}/tiddlers/${encodeURIComponent(title)}`;
132
+ }
133
+ filterUrl(filter) {
134
+ return `${this.baseUrl}/recipes/${encodeURIComponent(this.recipe)}/tiddlers.json?filter=${encodeURIComponent(filter)}`;
135
+ }
136
+ async headers(url, method, extra = {}) {
137
+ const credentialHeaders = this.credentialHandle && this.credentialResolver ? await this.credentialResolver.resolveHeaders(this.credentialHandle, { url, method }) : {};
138
+ return {
139
+ "content-type": "application/json",
140
+ "x-requested-with": "TiddlyWiki",
141
+ ...credentialHeaders,
142
+ ...extra
143
+ };
144
+ }
145
+ /** GET a tiddler; returns null on 404. Includes the ETag when the server sends one. */
146
+ async readTiddler(title) {
147
+ const url = this.tiddlerUrl(title);
148
+ const response = await this.fetchImpl(url, { headers: await this.headers(url, "GET") });
149
+ if (response.status === 404) return null;
150
+ if (!response.ok) {
151
+ throw new OrchestrationError({ code: "UNAVAILABLE", message: `tiddler read failed: HTTP ${response.status}`, retryable: true });
152
+ }
153
+ const tiddler = await response.json();
154
+ const etag = response.headers.get("etag") ?? void 0;
155
+ return { tiddler, ...etag ? { etag } : {} };
156
+ }
157
+ /** CAS write: If-Match when an ETag is known; bounded retries on 412/409. */
158
+ async writeTiddler(title, build) {
159
+ for (let attempt = 1; attempt <= this.maxCasAttempts; attempt += 1) {
160
+ const current = await this.readTiddler(title);
161
+ if (current && !current.etag) {
162
+ throw new OrchestrationError({ code: "CONFLICT", message: `tiddler '${title}' has no ETag for a safe update`, retryable: false });
163
+ }
164
+ const next = build(current?.tiddler ?? null);
165
+ const url = this.tiddlerUrl(title);
166
+ const precondition = current ? { "if-match": current.etag } : { "if-none-match": "*" };
167
+ const response = await this.fetchImpl(url, {
168
+ method: "PUT",
169
+ headers: await this.headers(url, "PUT", precondition),
170
+ body: JSON.stringify(next)
171
+ });
172
+ if (response.ok) return;
173
+ if (response.status === 412 || response.status === 409) {
174
+ if (attempt === this.maxCasAttempts) {
175
+ throw new OrchestrationError({
176
+ code: "CONFLICT",
177
+ message: `tiddler '${title}' was modified concurrently after ${attempt} CAS attempts`,
178
+ retryable: true
179
+ });
180
+ }
181
+ continue;
182
+ }
183
+ throw new OrchestrationError({ code: "UNAVAILABLE", message: `tiddler write failed: HTTP ${response.status}`, retryable: true });
184
+ }
185
+ }
186
+ async listByPrefix(prefix) {
187
+ const filter = `[prefix["${escapeFilterValue(prefix)}"]]`;
188
+ const url = this.filterUrl(filter);
189
+ const response = await this.fetchImpl(url, { headers: await this.headers(url, "GET") });
190
+ if (!response.ok) {
191
+ throw new OrchestrationError({ code: "UNAVAILABLE", message: `tiddler list failed: HTTP ${response.status}`, retryable: true });
192
+ }
193
+ return await response.json();
194
+ }
195
+ parsePayload(tiddler) {
196
+ return JSON.parse(tiddler.text ?? "{}");
197
+ }
198
+ async listConversations(options = {}) {
199
+ const tiddlers = await this.listByPrefix(`${PREFIX}/meta/`);
200
+ const metas = tiddlers.map((tiddler) => this.parsePayload(tiddler));
201
+ metas.sort((a, b) => (b.lastMessageTimestamp ?? 0) - (a.lastMessageTimestamp ?? 0));
202
+ const offset = options.offset ?? 0;
203
+ const limit = options.limit ?? metas.length;
204
+ return metas.slice(offset, offset + limit);
205
+ }
206
+ async getMessages(conversationId, _options = {}) {
207
+ const tiddlers = await this.listByPrefix(`${PREFIX}/e/${conversationId}/`);
208
+ const messages = tiddlers.map((tiddler) => this.parsePayload(tiddler));
209
+ messages.sort((a, b) => (a.lamportClock ?? 0) - (b.lamportClock ?? 0));
210
+ return messages;
211
+ }
212
+ async appendMessage(message) {
213
+ await this.writeTiddler(this.eventTitle(message.conversationId, message.messageId), () => ({
214
+ title: this.eventTitle(message.conversationId, message.messageId),
215
+ text: JSON.stringify(message)
216
+ }));
217
+ }
218
+ async insertMessagesIfAbsent(messages) {
219
+ for (const message of messages) {
220
+ const title = this.eventTitle(message.conversationId, message.messageId);
221
+ const existing = await this.readTiddler(title);
222
+ if (!existing) {
223
+ await this.writeTiddler(title, () => ({ title, text: JSON.stringify(message) }));
224
+ }
225
+ }
226
+ }
227
+ async getMaxLamportClockForConversation(conversationId) {
228
+ const messages = await this.getMessages(conversationId);
229
+ return messages.reduce((max, message) => Math.max(max, message.lamportClock ?? 0), 0);
230
+ }
231
+ async upsertConversationMetadata(meta) {
232
+ const title = this.metaTitle(meta.conversationId);
233
+ await this.writeTiddler(title, () => ({ title, text: JSON.stringify(meta) }));
234
+ }
235
+ async getConversationMeta(conversationId) {
236
+ const result = await this.readTiddler(this.metaTitle(conversationId));
237
+ return result ? this.parsePayload(result.tiddler) : null;
238
+ }
239
+ async saveAttachment(reference, data) {
240
+ if (data.byteLength > this.maxInlineBlobBytes) {
241
+ throw new OrchestrationError({
242
+ code: "INVALID",
243
+ message: `blob of ${data.byteLength} bytes exceeds the inline limit ${this.maxInlineBlobBytes}; store it in an external BlobStore and keep the reference`,
244
+ retryable: false,
245
+ details: { maxInlineBlobBytes: this.maxInlineBlobBytes }
246
+ });
247
+ }
248
+ const title = this.blobTitle(reference.contentHash);
249
+ await this.writeTiddler(title, () => ({
250
+ title,
251
+ text: JSON.stringify({ reference, dataBase64: bytesToBase64(data) })
252
+ }));
253
+ }
254
+ async getAttachment(contentHash) {
255
+ const result = await this.readTiddler(this.blobTitle(contentHash));
256
+ if (!result) return null;
257
+ return this.parsePayload(result.tiddler).reference;
258
+ }
259
+ async readAttachmentData(contentHash) {
260
+ const result = await this.readTiddler(this.blobTitle(contentHash));
261
+ if (!result) return null;
262
+ return base64ToBytes(this.parsePayload(result.tiddler).dataBase64);
263
+ }
264
+ async getAgentDefinition(id) {
265
+ const result = await this.readTiddler(this.definitionTitle(id));
266
+ return result ? this.parsePayload(result.tiddler) : null;
267
+ }
268
+ async saveAgentDefinition(definition) {
269
+ const title = this.definitionTitle(definition.id);
270
+ await this.writeTiddler(title, () => ({ title, text: JSON.stringify(definition) }));
271
+ }
272
+ async saveAgentInstance(meta) {
273
+ const title = this.instanceTitle(meta.instanceId);
274
+ await this.writeTiddler(title, () => ({ title, text: JSON.stringify(meta) }));
275
+ }
276
+ async getImBinding(channelId, imUserId) {
277
+ const result = await this.readTiddler(this.imTitle(channelId, imUserId));
278
+ return result ? this.parsePayload(result.tiddler) : null;
279
+ }
280
+ async setImBinding(record) {
281
+ const title = this.imTitle(record.channelId, record.imUserId);
282
+ await this.writeTiddler(title, () => ({ title, text: JSON.stringify(record) }));
283
+ }
284
+ };
285
+
286
+ // src/agent/categories.ts
287
+ var CATEGORY_CONFIGS = {
288
+ "visual-engineering": {
289
+ model: "default",
290
+ temperature: 0.3,
291
+ description: "UI/UX visual engineering tasks requiring precise rendering and layout"
292
+ },
293
+ ultrabrain: {
294
+ model: "default",
295
+ temperature: 0.1,
296
+ description: "Deep logical reasoning, architecture decisions, and complex problem-solving"
297
+ },
298
+ artistry: {
299
+ model: "default",
300
+ temperature: 0.8,
301
+ description: "Creative writing, design, and artistic generation tasks"
302
+ },
303
+ quick: {
304
+ model: "default",
305
+ temperature: 0.2,
306
+ description: "Fast, straightforward tasks with minimal deliberation needed"
307
+ },
308
+ "unspecified-low": {
309
+ model: "default",
310
+ temperature: 0.5,
311
+ description: "Unclassified tasks of moderate complexity and effort"
312
+ },
313
+ "unspecified-high": {
314
+ model: "default",
315
+ temperature: 0.4,
316
+ description: "Unclassified tasks requiring substantial effort across multiple systems"
317
+ },
318
+ writing: {
319
+ model: "default",
320
+ temperature: 0.7,
321
+ description: "Documentation, prose, technical writing, and content generation"
322
+ }
323
+ };
324
+ function getCategoryConfig(category) {
325
+ const config = CATEGORY_CONFIGS[category];
326
+ if (!config) {
327
+ throw new Error(`Unknown task category: ${category}`);
328
+ }
329
+ return { ...config };
330
+ }
331
+ function isTaskCategory(value) {
332
+ return value in CATEGORY_CONFIGS;
333
+ }
334
+ var ALL_CATEGORIES = Object.keys(CATEGORY_CONFIGS);
335
+ function resolveCategory(category) {
336
+ if (isTaskCategory(category)) {
337
+ return getCategoryConfig(category);
338
+ }
339
+ return getCategoryConfig("unspecified-low");
340
+ }
341
+
342
+ // src/agent-management/AgentSessionController.ts
343
+ var AgentSessionController = class {
344
+ options;
345
+ listener = null;
346
+ snapshot = {
347
+ agent: null,
348
+ loading: false,
349
+ error: null,
350
+ messages: [],
351
+ orderedMessageIds: [],
352
+ streamingMessageIds: /* @__PURE__ */ new Set()
353
+ };
354
+ unsubAgentUpdates = null;
355
+ unsubMessages = null;
356
+ pollingTimer = null;
357
+ agentId = null;
358
+ constructor(options) {
359
+ this.options = {
360
+ pollInterval: 500,
361
+ ...options
362
+ };
363
+ }
364
+ // ── Lifecycle ─────────────────────────────────────────────────
365
+ /**
366
+ * Start a session for the given agent ID.
367
+ * Fetches the agent, subscribes to live updates, and loads messages.
368
+ */
369
+ async start(agentId) {
370
+ this.agentId = agentId;
371
+ this.emitPartial({ loading: true, error: null });
372
+ try {
373
+ const [agent, rawMessages] = await Promise.all([
374
+ this.options.agentInstanceClient.fetchAgent(agentId),
375
+ this.options.conversationClient.getMessages(agentId)
376
+ ]);
377
+ const orderedMessageIds = rawMessages.map((m) => m.messageId);
378
+ const messagesMap = /* @__PURE__ */ new Map();
379
+ for (const m of rawMessages) messagesMap.set(m.messageId, m);
380
+ this.emitPartial({
381
+ agent,
382
+ loading: false,
383
+ messages: rawMessages,
384
+ orderedMessageIds,
385
+ streamingMessageIds: /* @__PURE__ */ new Set()
386
+ });
387
+ this.unsubAgentUpdates = this.options.agentInstanceClient.subscribeToUpdates(
388
+ agentId,
389
+ this.handleAgentUpdate
390
+ );
391
+ this.unsubMessages = this.options.conversationClient.subscribeToMessages(
392
+ agentId,
393
+ this.handleNewMessage
394
+ );
395
+ this.startPolling(agentId);
396
+ } catch (error_) {
397
+ this.emitPartial({
398
+ loading: false,
399
+ error: error_ instanceof Error ? error_ : new Error(String(error_))
400
+ });
401
+ }
402
+ }
403
+ /** Stop the session and clean up subscriptions. */
404
+ stop() {
405
+ this.stopPolling();
406
+ this.unsubAgentUpdates?.();
407
+ this.unsubAgentUpdates = null;
408
+ this.unsubMessages?.();
409
+ this.unsubMessages = null;
410
+ this.agentId = null;
411
+ }
412
+ // ── Actions ───────────────────────────────────────────────────
413
+ /** Send a user message. */
414
+ async sendMessage(content, file, wikiTiddlers) {
415
+ if (!this.agentId) return;
416
+ this.emitPartial({ error: null });
417
+ try {
418
+ await this.options.conversationClient.sendMessage(this.agentId, content, file, wikiTiddlers);
419
+ } catch (error_) {
420
+ this.emitPartial({
421
+ error: error_ instanceof Error ? error_ : new Error(String(error_))
422
+ });
423
+ }
424
+ }
425
+ /** Cancel the current agent operation. */
426
+ async cancel() {
427
+ if (!this.agentId) return;
428
+ try {
429
+ await this.options.agentInstanceClient.cancelAgent(this.agentId);
430
+ } catch (error_) {
431
+ this.emitPartial({
432
+ error: error_ instanceof Error ? error_ : new Error(String(error_))
433
+ });
434
+ }
435
+ }
436
+ /** Delete a turn starting at the given user message ID. */
437
+ async deleteTurn(userMessageId) {
438
+ return this.options.conversationClient.deleteTurn(userMessageId);
439
+ }
440
+ /** Retry a turn starting at the given user message ID. */
441
+ async retryTurn(userMessageId) {
442
+ return this.options.conversationClient.retryTurn(userMessageId);
443
+ }
444
+ // ── Subscription ──────────────────────────────────────────────
445
+ /** Subscribe to snapshot changes. Returns unsubscribe function. */
446
+ subscribe(listener) {
447
+ this.listener = listener;
448
+ listener({ ...this.snapshot, streamingMessageIds: new Set(this.snapshot.streamingMessageIds) });
449
+ return () => {
450
+ if (this.listener === listener) this.listener = null;
451
+ };
452
+ }
453
+ /** Get current snapshot without subscribing. */
454
+ getSnapshot() {
455
+ return this.snapshot;
456
+ }
457
+ // ── Private helpers ───────────────────────────────────────────
458
+ emitPartial(partial) {
459
+ this.snapshot = { ...this.snapshot, ...partial };
460
+ if (this.listener) {
461
+ this.listener({
462
+ ...this.snapshot,
463
+ streamingMessageIds: new Set(this.snapshot.streamingMessageIds)
464
+ });
465
+ }
466
+ }
467
+ handleAgentUpdate = (update) => {
468
+ if (this.snapshot.agent) {
469
+ this.emitPartial({ agent: { ...this.snapshot.agent, ...update } });
470
+ }
471
+ };
472
+ handleNewMessage = (message) => {
473
+ const messages = [...this.snapshot.messages.filter((m) => m.messageId !== message.messageId), message];
474
+ const orderedMessageIds = [.../* @__PURE__ */ new Set([...this.snapshot.orderedMessageIds, message.messageId])];
475
+ this.emitPartial({ messages, orderedMessageIds });
476
+ };
477
+ startPolling(agentId) {
478
+ this.stopPolling();
479
+ this.pollingTimer = setInterval(async () => {
480
+ try {
481
+ const agent = await this.options.agentInstanceClient.fetchAgent(agentId);
482
+ this.emitPartial({ agent });
483
+ } catch {
484
+ }
485
+ }, this.options.pollInterval);
486
+ }
487
+ stopPolling() {
488
+ if (this.pollingTimer !== null) {
489
+ clearInterval(this.pollingTimer);
490
+ this.pollingTimer = null;
491
+ }
492
+ }
493
+ };
494
+
495
+ // src/agent-management/AgentDefinitionEditorController.ts
496
+ var AgentDefinitionEditorController = class {
497
+ options;
498
+ listener = null;
499
+ state = {
500
+ agentDefinition: null,
501
+ agentName: "",
502
+ previewAgentId: null,
503
+ isLoading: false,
504
+ isSaving: false,
505
+ promptSchema: null
506
+ };
507
+ autosaveTimer = null;
508
+ constructor(options) {
509
+ this.options = {
510
+ autosaveDebounceMs: 1e3,
511
+ ...options
512
+ };
513
+ }
514
+ // ── Lifecycle ─────────────────────────────────────────────────
515
+ /** Load an agent definition and its prompt schema. */
516
+ async loadDefinition(definitionId) {
517
+ this.emit({ isLoading: true });
518
+ try {
519
+ const [definition, previewAgentId] = await Promise.all([
520
+ this.options.definitionRepository.getAgentDef(definitionId),
521
+ this.findOrCreatePreviewAgent(definitionId)
522
+ ]);
523
+ if (!definition) {
524
+ this.emit({ isLoading: false });
525
+ return;
526
+ }
527
+ let promptSchema = null;
528
+ if (definition.agentFrameworkID) {
529
+ try {
530
+ promptSchema = await this.options.agentInstanceClient.getFrameworkConfigSchema(
531
+ definition.agentFrameworkID
532
+ );
533
+ } catch {
534
+ promptSchema = null;
535
+ }
536
+ }
537
+ this.state = {
538
+ agentDefinition: definition,
539
+ agentName: definition.name ?? "",
540
+ previewAgentId,
541
+ isLoading: false,
542
+ isSaving: false,
543
+ promptSchema
544
+ };
545
+ this.emit(this.state);
546
+ } catch {
547
+ this.emit({ isLoading: false });
548
+ }
549
+ }
550
+ /** Update the agent definition field. Triggers debounced autosave. */
551
+ updateDefinition(change) {
552
+ if (!this.state.agentDefinition) return;
553
+ const updated = { ...this.state.agentDefinition, ...change };
554
+ this.state = { ...this.state, agentDefinition: updated, agentName: updated.name ?? "" };
555
+ this.emit({ agentDefinition: updated, agentName: this.state.agentName });
556
+ this.scheduleAutosave(updated);
557
+ }
558
+ /** Force an immediate save to the repository. */
559
+ async saveNow() {
560
+ if (!this.state.agentDefinition) return;
561
+ this.emit({ isSaving: true });
562
+ try {
563
+ await this.options.definitionRepository.updateAgentDef({
564
+ id: this.state.agentDefinition.id,
565
+ name: this.state.agentName,
566
+ description: this.state.agentDefinition.description,
567
+ agentFrameworkConfig: this.state.agentDefinition.agentFrameworkConfig,
568
+ aiApiConfig: this.state.agentDefinition.aiApiConfig,
569
+ agentTools: this.state.agentDefinition.agentTools,
570
+ heartbeat: this.state.agentDefinition.heartbeat
571
+ });
572
+ } catch {
573
+ } finally {
574
+ this.emit({ isSaving: false });
575
+ }
576
+ }
577
+ /** Reload the prompt schema for a framework ID. */
578
+ async reloadSchema(frameworkId) {
579
+ try {
580
+ const schema = await this.options.agentInstanceClient.getFrameworkConfigSchema(frameworkId);
581
+ this.emit({ promptSchema: schema });
582
+ } catch {
583
+ this.emit({ promptSchema: null });
584
+ }
585
+ }
586
+ // ── Preview agent lifecycle ───────────────────────────────────
587
+ /** Get or create a preview agent instance tied to this definition. */
588
+ async findOrCreatePreviewAgent(definitionId) {
589
+ try {
590
+ const result = await this.options.agentInstanceClient.createAgent(definitionId, {
591
+ preview: true
592
+ });
593
+ return result.id;
594
+ } catch {
595
+ return null;
596
+ }
597
+ }
598
+ // ── Scheduled tasks ───────────────────────────────────────────
599
+ async loadScheduledTasks() {
600
+ if (!this.state.previewAgentId) return [];
601
+ return this.options.scheduledTaskClient.listScheduledTasksForAgent(
602
+ this.state.previewAgentId
603
+ );
604
+ }
605
+ async saveScheduledTask(input) {
606
+ return this.options.scheduledTaskClient.createScheduledTask(input);
607
+ }
608
+ async deleteScheduledTask(taskId) {
609
+ return this.options.scheduledTaskClient.deleteScheduledTask(taskId);
610
+ }
611
+ // ── Subscription ──────────────────────────────────────────────
612
+ subscribe(listener) {
613
+ this.listener = listener;
614
+ listener(this.state);
615
+ return () => {
616
+ if (this.listener === listener) this.listener = null;
617
+ };
618
+ }
619
+ getState() {
620
+ return this.state;
621
+ }
622
+ // ── Private ───────────────────────────────────────────────────
623
+ emit(change) {
624
+ this.listener?.(change);
625
+ }
626
+ scheduleAutosave(definition) {
627
+ if (this.autosaveTimer !== null) clearTimeout(this.autosaveTimer);
628
+ this.autosaveTimer = setTimeout(() => {
629
+ this.options.definitionRepository.updateAgentDef({
630
+ id: definition.id,
631
+ name: definition.name,
632
+ description: definition.description,
633
+ agentFrameworkConfig: definition.agentFrameworkConfig,
634
+ aiApiConfig: definition.aiApiConfig,
635
+ agentTools: definition.agentTools,
636
+ heartbeat: definition.heartbeat
637
+ }).catch(() => {
638
+ });
639
+ }, this.options.autosaveDebounceMs);
640
+ }
641
+ };
642
+
643
+ // src/agent-management/AgentCreationController.ts
644
+ var AgentCreationController = class {
645
+ options;
646
+ listener = null;
647
+ state = {
648
+ currentStep: 0,
649
+ agentName: "",
650
+ selectedTemplate: null,
651
+ temporaryAgentDefinition: null,
652
+ previewAgentId: null,
653
+ isLoading: false,
654
+ promptSchema: null
655
+ };
656
+ constructor(options) {
657
+ this.options = {
658
+ defaultFrameworkId: "memeloopAgentToolLoop",
659
+ ...options
660
+ };
661
+ }
662
+ /** Initialize the creation wizard, optionally from a saved tab state. */
663
+ async start(definitionId, templateDefinitionId) {
664
+ this.emit({ isLoading: true });
665
+ try {
666
+ if (definitionId) {
667
+ const temporaryDefinition = await this.options.definitionRepository.getAgentDef(definitionId);
668
+ if (temporaryDefinition) {
669
+ this.state = {
670
+ ...this.state,
671
+ temporaryAgentDefinition: temporaryDefinition,
672
+ agentName: temporaryDefinition.name ?? "",
673
+ isLoading: false
674
+ };
675
+ this.emit(this.state);
676
+ if (templateDefinitionId) {
677
+ const template = await this.options.definitionRepository.getAgentDef(templateDefinitionId);
678
+ if (template) {
679
+ this.state = { ...this.state, selectedTemplate: template };
680
+ this.emit(this.state);
681
+ }
682
+ }
683
+ return;
684
+ }
685
+ }
686
+ this.emit({ isLoading: false });
687
+ } catch {
688
+ this.emit({ isLoading: false });
689
+ }
690
+ }
691
+ /** Select a template for the new agent. */
692
+ selectTemplate(template) {
693
+ this.state = { ...this.state, selectedTemplate: template };
694
+ this.emit(this.state);
695
+ }
696
+ /** Update the agent name. */
697
+ setAgentName(name) {
698
+ this.state = { ...this.state, agentName: name };
699
+ this.emit(this.state);
700
+ }
701
+ /** Advance to the next wizard step. */
702
+ nextStep() {
703
+ this.state = { ...this.state, currentStep: Math.min(this.state.currentStep + 1, 2) };
704
+ this.emit(this.state);
705
+ }
706
+ /** Go back to the previous wizard step. */
707
+ previousStep() {
708
+ this.state = { ...this.state, currentStep: Math.max(this.state.currentStep - 1, 0) };
709
+ this.emit(this.state);
710
+ }
711
+ /** Set the current wizard step directly. */
712
+ setStep(step) {
713
+ this.state = { ...this.state, currentStep: Math.max(0, Math.min(step, 2)) };
714
+ this.emit(this.state);
715
+ }
716
+ /** Update the temporary agent definition. */
717
+ updateTemporaryDefinition(change) {
718
+ const updated = this.state.temporaryAgentDefinition ? { ...this.state.temporaryAgentDefinition, ...change } : null;
719
+ this.state = { ...this.state, temporaryAgentDefinition: updated };
720
+ this.emit(this.state);
721
+ }
722
+ /** Set the prompt schema for the selected framework. */
723
+ setPromptSchema(schema) {
724
+ this.state = { ...this.state, promptSchema: schema };
725
+ this.emit(this.state);
726
+ }
727
+ /**
728
+ * Create a preview agent instance for the chat-preview step.
729
+ * Should be called when entering step 2 (or the chat preview step).
730
+ */
731
+ async createPreviewAgent(definitionId) {
732
+ this.emit({ isLoading: true });
733
+ try {
734
+ const result = await this.options.agentInstanceClient.createAgent(definitionId, {
735
+ preview: true
736
+ });
737
+ this.state = { ...this.state, previewAgentId: result.id, isLoading: false };
738
+ this.emit(this.state);
739
+ } catch {
740
+ this.emit({ isLoading: false });
741
+ }
742
+ }
743
+ /**
744
+ * Finalize creation: persist the temporary definition and create the actual
745
+ * agent instance. Returns the final agent instance ID, or null on failure.
746
+ */
747
+ async finalize() {
748
+ if (!this.state.temporaryAgentDefinition) return null;
749
+ try {
750
+ const definition = await this.options.definitionRepository.createAgentDef(
751
+ this.state.temporaryAgentDefinition
752
+ );
753
+ const instance = await this.options.agentInstanceClient.createAgent(definition.id);
754
+ return instance.id;
755
+ } catch {
756
+ return null;
757
+ }
758
+ }
759
+ /** Clean up temporary resources. */
760
+ async cleanup() {
761
+ if (this.state.previewAgentId) {
762
+ try {
763
+ await this.options.agentInstanceClient.deleteAgent(this.state.previewAgentId);
764
+ } catch {
765
+ }
766
+ }
767
+ }
768
+ // ── Subscription ──────────────────────────────────────────────
769
+ subscribe(listener) {
770
+ this.listener = listener;
771
+ listener({ ...this.state });
772
+ return () => {
773
+ if (this.listener === listener) this.listener = null;
774
+ };
775
+ }
776
+ getState() {
777
+ return this.state;
778
+ }
779
+ // ── Private ───────────────────────────────────────────────────
780
+ emit(change) {
781
+ this.state = { ...this.state, ...change };
782
+ this.listener?.({ ...this.state });
783
+ }
784
+ };
785
+
786
+ // src/agent-management/PromptPreviewController.ts
787
+ var PromptPreviewController = class {
788
+ options;
789
+ listener = null;
790
+ state = {
791
+ open: false,
792
+ baseMode: "preview",
793
+ activeTab: "tree",
794
+ loading: false,
795
+ progress: 0,
796
+ currentStep: "",
797
+ currentPlugin: null,
798
+ result: null,
799
+ lastUpdated: null,
800
+ formFieldsToScrollTo: []
801
+ };
802
+ constructor(options) {
803
+ this.options = options;
804
+ }
805
+ /** Open the dialog with an optional base mode. */
806
+ open(baseMode) {
807
+ this.state = {
808
+ ...this.state,
809
+ open: true,
810
+ baseMode: baseMode ?? "preview",
811
+ loading: false,
812
+ progress: 0,
813
+ currentStep: "Starting...",
814
+ currentPlugin: null,
815
+ result: null,
816
+ lastUpdated: null,
817
+ formFieldsToScrollTo: []
818
+ };
819
+ this.emit();
820
+ }
821
+ /** Close the dialog. */
822
+ close() {
823
+ this.state = {
824
+ ...this.state,
825
+ open: false,
826
+ baseMode: "preview",
827
+ lastUpdated: null,
828
+ formFieldsToScrollTo: []
829
+ };
830
+ this.emit();
831
+ }
832
+ /** Set the active tab in the dialog. */
833
+ setActiveTab(tab) {
834
+ this.state = { ...this.state, activeTab: tab };
835
+ this.emit();
836
+ }
837
+ /** Set form fields to scroll to (for edit mode navigation). */
838
+ setFormFieldsToScrollTo(fieldPaths) {
839
+ this.state = { ...this.state, formFieldsToScrollTo: fieldPaths };
840
+ this.emit();
841
+ }
842
+ /**
843
+ * Generate a preview of the prompt tree.
844
+ * @param agentFrameworkConfig The agent's framework configuration
845
+ * @param messages Current conversation messages
846
+ * @param inputText Optional input text to include in the preview
847
+ */
848
+ async generate(agentFrameworkConfig, messages, inputText) {
849
+ this.state = {
850
+ ...this.state,
851
+ loading: true,
852
+ progress: 0,
853
+ currentStep: "Preparing..."
854
+ };
855
+ this.emit();
856
+ try {
857
+ const result = await this.options.previewClient.generatePreview(
858
+ agentFrameworkConfig,
859
+ messages,
860
+ inputText,
861
+ (progress) => {
862
+ this.state = {
863
+ ...this.state,
864
+ progress: progress.progress,
865
+ currentStep: progress.step,
866
+ currentPlugin: progress.currentPlugin ?? null
867
+ };
868
+ this.emit();
869
+ }
870
+ );
871
+ this.state = {
872
+ ...this.state,
873
+ loading: false,
874
+ progress: 1,
875
+ currentStep: "Complete",
876
+ currentPlugin: null,
877
+ result,
878
+ lastUpdated: /* @__PURE__ */ new Date()
879
+ };
880
+ this.emit();
881
+ return result;
882
+ } catch {
883
+ this.state = {
884
+ ...this.state,
885
+ loading: false,
886
+ progress: 0,
887
+ currentStep: "Error occurred",
888
+ currentPlugin: null,
889
+ result: null
890
+ };
891
+ this.emit();
892
+ return null;
893
+ }
894
+ }
895
+ // ── Subscription ──────────────────────────────────────────────
896
+ subscribe(listener) {
897
+ this.listener = listener;
898
+ listener({ ...this.state });
899
+ return () => {
900
+ if (this.listener === listener) this.listener = null;
901
+ };
902
+ }
903
+ getState() {
904
+ return this.state;
905
+ }
906
+ // ── Private ───────────────────────────────────────────────────
907
+ emit() {
908
+ this.listener?.({ ...this.state });
909
+ }
910
+ };
911
+
912
+ // src/orchestration/remoteClient.ts
913
+ var REMOTE_ORCHESTRATION_PROTOCOL = "memeloop.resource.v1";
914
+ var REMOTE_OPERATIONS = /* @__PURE__ */ new Set([
915
+ "capabilities",
916
+ "apply",
917
+ "get",
918
+ "list",
919
+ "watch",
920
+ "delete"
921
+ ]);
922
+ function isRecord(value) {
923
+ return value !== null && typeof value === "object" && !Array.isArray(value);
924
+ }
925
+ function errorData(error) {
926
+ if (error instanceof OrchestrationError) {
927
+ return {
928
+ code: error.code,
929
+ message: error.message,
930
+ retryable: error.retryable,
931
+ ...error.retryAfterMs !== void 0 ? { retryAfterMs: error.retryAfterMs } : {},
932
+ ...error.reason !== void 0 ? { reason: error.reason } : {},
933
+ ...error.details !== void 0 ? { details: error.details } : {}
934
+ };
935
+ }
936
+ return {
937
+ code: "INTERNAL",
938
+ message: error instanceof Error ? error.message : String(error),
939
+ retryable: false
940
+ };
941
+ }
942
+ function throwResponseError(response) {
943
+ throw new OrchestrationError(response.error);
944
+ }
945
+ function assertResponse(request, response) {
946
+ if (!isRecord(response) || response.protocol !== REMOTE_ORCHESTRATION_PROTOCOL || response.requestId !== request.requestId || typeof response.ok !== "boolean" || response.ok && !("result" in response) || !response.ok && (!isRecord(response.error) || typeof response.error.code !== "string" || typeof response.error.message !== "string" || typeof response.error.retryable !== "boolean")) {
947
+ throw new OrchestrationError({
948
+ code: "INVALID",
949
+ message: "remote orchestration response correlation or protocol mismatch",
950
+ retryable: false
951
+ });
952
+ }
953
+ }
954
+ var requestSequence = 0;
955
+ function createRemoteOrchestrationClient(transport, options = {}) {
956
+ const createRequestId = options.createRequestId ?? (() => `resource-${Date.now().toString(36)}-${(++requestSequence).toString(36)}`);
957
+ function makeRequest(operation, payload) {
958
+ return {
959
+ protocol: REMOTE_ORCHESTRATION_PROTOCOL,
960
+ requestId: createRequestId(),
961
+ operation,
962
+ payload
963
+ };
964
+ }
965
+ async function request(operation, payload, signal) {
966
+ const envelope = makeRequest(operation, payload);
967
+ const response = await transport.request(envelope, { signal });
968
+ assertResponse(envelope, response);
969
+ if (!response.ok) throwResponseError(response);
970
+ return response.result;
971
+ }
972
+ return {
973
+ getCapabilities() {
974
+ return request("capabilities", {});
975
+ },
976
+ apply(resource, applyOptions) {
977
+ return request("apply", {
978
+ resource,
979
+ ...applyOptions ? { options: applyOptions } : {}
980
+ });
981
+ },
982
+ get(reference, getOptions) {
983
+ return request("get", {
984
+ reference,
985
+ ...getOptions ? { options: getOptions } : {}
986
+ });
987
+ },
988
+ list(query, listOptions) {
989
+ return request("list", {
990
+ query,
991
+ ...listOptions ? { options: listOptions } : {}
992
+ });
993
+ },
994
+ async *watch(query, watchOptions) {
995
+ const envelope = makeRequest("watch", {
996
+ query,
997
+ ...watchOptions ? {
998
+ options: {
999
+ ...watchOptions,
1000
+ signal: void 0
1001
+ }
1002
+ } : {}
1003
+ });
1004
+ for await (const response of transport.watch(envelope, {
1005
+ signal: watchOptions?.signal
1006
+ })) {
1007
+ assertResponse(envelope, response);
1008
+ if (!response.ok) throwResponseError(response);
1009
+ yield response.result;
1010
+ }
1011
+ },
1012
+ delete(reference, deleteOptions) {
1013
+ return request("delete", {
1014
+ reference,
1015
+ ...deleteOptions ? { options: deleteOptions } : {}
1016
+ });
1017
+ }
1018
+ };
1019
+ }
1020
+ function createReadOnlyOrchestrationClient(client, options = {}) {
1021
+ const allowedKinds = options.allowedResourceKinds ? new Set(options.allowedResourceKinds) : void 0;
1022
+ function assertAllowedKind(kind) {
1023
+ if (!allowedKinds || allowedKinds.has(kind)) return;
1024
+ throw new OrchestrationError({
1025
+ code: "FORBIDDEN",
1026
+ message: `remote orchestration access to resource kind '${kind}' is forbidden`,
1027
+ retryable: false
1028
+ });
1029
+ }
1030
+ function forbidden(operation) {
1031
+ throw new OrchestrationError({
1032
+ code: "FORBIDDEN",
1033
+ message: `remote orchestration operation '${operation}' is read-only`,
1034
+ retryable: false
1035
+ });
1036
+ }
1037
+ return {
1038
+ async getCapabilities() {
1039
+ const capabilities = await client.getCapabilities();
1040
+ return {
1041
+ operations: ["get", "list", "watch"],
1042
+ resourceKinds: capabilities.resourceKinds.filter((kind) => allowedKinds ? allowedKinds.has(kind) : true),
1043
+ interfaces: capabilities.interfaces.includes("resource") ? ["resource"] : []
1044
+ };
1045
+ },
1046
+ async apply() {
1047
+ forbidden("apply");
1048
+ },
1049
+ async get(reference, getOptions) {
1050
+ assertAllowedKind(reference.kind);
1051
+ return await client.get(reference, getOptions);
1052
+ },
1053
+ async list(query, listOptions) {
1054
+ assertAllowedKind(query.kind);
1055
+ return await client.list(query, listOptions);
1056
+ },
1057
+ async *watch(query, watchOptions) {
1058
+ assertAllowedKind(query.kind);
1059
+ yield* client.watch(query, watchOptions);
1060
+ },
1061
+ async delete() {
1062
+ forbidden("delete");
1063
+ }
1064
+ };
1065
+ }
1066
+ function createNamespacedOrchestrationClient(client, options) {
1067
+ const namespace = options.namespace.trim();
1068
+ if (!namespace || namespace.length > 253) {
1069
+ throw new TypeError("namespace must contain between 1 and 253 characters");
1070
+ }
1071
+ const allowedKinds = new Set(options.allowedResourceKinds);
1072
+ const mutableKinds = new Set(options.mutableResourceKinds ?? options.allowedResourceKinds);
1073
+ for (const kind of mutableKinds) {
1074
+ if (!allowedKinds.has(kind)) {
1075
+ throw new TypeError(`mutable resource kind '${kind}' must also be allowed`);
1076
+ }
1077
+ }
1078
+ function assertAllowedKind(kind) {
1079
+ if (allowedKinds.has(kind)) return;
1080
+ throw new OrchestrationError({
1081
+ code: "FORBIDDEN",
1082
+ message: `remote orchestration access to resource kind '${kind}' is forbidden`,
1083
+ retryable: false
1084
+ });
1085
+ }
1086
+ function bindNamespace(metadata) {
1087
+ if (metadata.namespace !== void 0 && metadata.namespace !== namespace) {
1088
+ throw new OrchestrationError({
1089
+ code: "FORBIDDEN",
1090
+ message: `remote orchestration access outside namespace '${namespace}' is forbidden`,
1091
+ retryable: false
1092
+ });
1093
+ }
1094
+ return { ...metadata, namespace };
1095
+ }
1096
+ function assertMutableKind(kind) {
1097
+ assertAllowedKind(kind);
1098
+ if (mutableKinds.has(kind)) return;
1099
+ throw new OrchestrationError({
1100
+ code: "FORBIDDEN",
1101
+ message: `remote orchestration mutation of resource kind '${kind}' is forbidden`,
1102
+ retryable: false
1103
+ });
1104
+ }
1105
+ return {
1106
+ async getCapabilities() {
1107
+ const capabilities = await client.getCapabilities();
1108
+ const resourceKinds = capabilities.resourceKinds.filter((kind) => allowedKinds.has(kind));
1109
+ const resourceOperations = Object.fromEntries(
1110
+ resourceKinds.map((kind) => {
1111
+ const sourceOperations = capabilities.resourceOperations?.[kind] ?? capabilities.operations;
1112
+ return [
1113
+ kind,
1114
+ sourceOperations.filter((operation) => mutableKinds.has(kind) || operation !== "apply" && operation !== "delete")
1115
+ ];
1116
+ })
1117
+ );
1118
+ return {
1119
+ operations: capabilities.operations,
1120
+ resourceKinds,
1121
+ resourceOperations,
1122
+ interfaces: capabilities.interfaces.includes("resource") ? ["resource"] : []
1123
+ };
1124
+ },
1125
+ async apply(resource, applyOptions) {
1126
+ assertMutableKind(resource.kind);
1127
+ return await client.apply(
1128
+ {
1129
+ ...resource,
1130
+ metadata: bindNamespace(resource.metadata)
1131
+ },
1132
+ applyOptions
1133
+ );
1134
+ },
1135
+ async get(reference, getOptions) {
1136
+ assertAllowedKind(reference.kind);
1137
+ return await client.get(bindNamespace(reference), getOptions);
1138
+ },
1139
+ async list(query, listOptions) {
1140
+ assertAllowedKind(query.kind);
1141
+ return await client.list(bindNamespace(query), listOptions);
1142
+ },
1143
+ watch(query, watchOptions) {
1144
+ assertAllowedKind(query.kind);
1145
+ return client.watch(bindNamespace(query), watchOptions);
1146
+ },
1147
+ async delete(reference, deleteOptions) {
1148
+ assertMutableKind(reference.kind);
1149
+ return await client.delete(bindNamespace(reference), deleteOptions);
1150
+ }
1151
+ };
1152
+ }
1153
+ function requirePayload(payload, key) {
1154
+ if (!(key in payload)) {
1155
+ throw new OrchestrationError({
1156
+ code: "INVALID",
1157
+ message: `remote orchestration request is missing payload.${key}`,
1158
+ retryable: false
1159
+ });
1160
+ }
1161
+ return payload[key];
1162
+ }
1163
+ function success(request, result) {
1164
+ return {
1165
+ protocol: REMOTE_ORCHESTRATION_PROTOCOL,
1166
+ requestId: request.requestId,
1167
+ ok: true,
1168
+ result
1169
+ };
1170
+ }
1171
+ function failure(request, error) {
1172
+ const requestRecord = isRecord(request) ? request : void 0;
1173
+ return {
1174
+ protocol: REMOTE_ORCHESTRATION_PROTOCOL,
1175
+ requestId: typeof requestRecord?.requestId === "string" ? requestRecord.requestId : "invalid",
1176
+ ok: false,
1177
+ error: errorData(error)
1178
+ };
1179
+ }
1180
+ function createRemoteOrchestrationHandler(client) {
1181
+ function validate(request) {
1182
+ if (!isRecord(request) || request.protocol !== REMOTE_ORCHESTRATION_PROTOCOL || typeof request.requestId !== "string" || !request.requestId || request.requestId.length > 256 || !REMOTE_OPERATIONS.has(request.operation) || !isRecord(request.payload)) {
1183
+ throw new OrchestrationError({
1184
+ code: "INVALID",
1185
+ message: "invalid remote orchestration request envelope",
1186
+ retryable: false
1187
+ });
1188
+ }
1189
+ }
1190
+ return {
1191
+ async request(request) {
1192
+ try {
1193
+ validate(request);
1194
+ const payload = request.payload;
1195
+ switch (request.operation) {
1196
+ case "capabilities":
1197
+ return success(request, await client.getCapabilities());
1198
+ case "apply":
1199
+ return success(
1200
+ request,
1201
+ await client.apply(
1202
+ requirePayload(payload, "resource"),
1203
+ payload.options
1204
+ )
1205
+ );
1206
+ case "get":
1207
+ return success(
1208
+ request,
1209
+ await client.get(
1210
+ requirePayload(payload, "reference"),
1211
+ payload.options
1212
+ )
1213
+ );
1214
+ case "list":
1215
+ return success(
1216
+ request,
1217
+ await client.list(
1218
+ requirePayload(payload, "query"),
1219
+ payload.options
1220
+ )
1221
+ );
1222
+ case "delete":
1223
+ return success(
1224
+ request,
1225
+ await client.delete(
1226
+ requirePayload(payload, "reference"),
1227
+ payload.options
1228
+ )
1229
+ );
1230
+ case "watch":
1231
+ throw new OrchestrationError({
1232
+ code: "INVALID",
1233
+ message: "watch requests require the streaming protocol method",
1234
+ retryable: false
1235
+ });
1236
+ default:
1237
+ throw new OrchestrationError({
1238
+ code: "UNSUPPORTED",
1239
+ message: `unsupported remote orchestration operation '${String(request.operation)}'`,
1240
+ retryable: false
1241
+ });
1242
+ }
1243
+ } catch (error) {
1244
+ return failure(request, error);
1245
+ }
1246
+ },
1247
+ async *watch(request, options = {}) {
1248
+ try {
1249
+ validate(request);
1250
+ if (request.operation !== "watch") {
1251
+ throw new OrchestrationError({
1252
+ code: "INVALID",
1253
+ message: "streaming protocol accepts only watch operations",
1254
+ retryable: false
1255
+ });
1256
+ }
1257
+ const watchOptions = request.payload.options;
1258
+ for await (const event of client.watch(
1259
+ requirePayload(request.payload, "query"),
1260
+ {
1261
+ ...watchOptions,
1262
+ signal: options.signal
1263
+ }
1264
+ )) {
1265
+ yield success(request, event);
1266
+ }
1267
+ } catch (error) {
1268
+ yield failure(request, error);
1269
+ }
1270
+ }
1271
+ };
1272
+ }
1273
+ function createFetchOrchestrationTransport(options) {
1274
+ const fetch_ = options.fetch ?? globalThis.fetch;
1275
+ const maxResponseBytes = options.maxResponseBytes ?? 1024 * 1024;
1276
+ const maxWatchLineBytes = options.maxWatchLineBytes ?? 1024 * 1024;
1277
+ function assertWatchLineSize(line) {
1278
+ if (new TextEncoder().encode(line).byteLength > maxWatchLineBytes) {
1279
+ throw new OrchestrationError({
1280
+ code: "EXHAUSTED",
1281
+ message: `remote orchestration watch line exceeds ${maxWatchLineBytes} bytes`,
1282
+ retryable: false
1283
+ });
1284
+ }
1285
+ }
1286
+ async function headers(accept) {
1287
+ const additional = typeof options.headers === "function" ? await options.headers() : options.headers ?? {};
1288
+ return {
1289
+ Accept: accept,
1290
+ "Content-Type": "application/json",
1291
+ ...additional
1292
+ };
1293
+ }
1294
+ async function post(request, accept, signal) {
1295
+ const response = await fetch_(options.endpoint, {
1296
+ method: "POST",
1297
+ headers: await headers(accept),
1298
+ body: JSON.stringify(request),
1299
+ signal,
1300
+ ...options.credentials ? { credentials: options.credentials } : {}
1301
+ });
1302
+ if (!response.ok) {
1303
+ throw new OrchestrationError({
1304
+ code: response.status === 401 || response.status === 403 ? "FORBIDDEN" : "UNAVAILABLE",
1305
+ message: `remote orchestration endpoint returned HTTP ${response.status}`,
1306
+ retryable: response.status >= 500
1307
+ });
1308
+ }
1309
+ return response;
1310
+ }
1311
+ async function readBoundedText(response, limit) {
1312
+ if (!response.body) return "";
1313
+ const reader = response.body.getReader();
1314
+ const decoder = new TextDecoder();
1315
+ let size = 0;
1316
+ let text = "";
1317
+ try {
1318
+ for (; ; ) {
1319
+ const { done, value } = await reader.read();
1320
+ if (done) break;
1321
+ size += value.byteLength;
1322
+ if (size > limit) {
1323
+ await reader.cancel();
1324
+ throw new OrchestrationError({
1325
+ code: "EXHAUSTED",
1326
+ message: `remote orchestration response exceeds ${limit} bytes`,
1327
+ retryable: false
1328
+ });
1329
+ }
1330
+ text += decoder.decode(value, { stream: true });
1331
+ }
1332
+ return text + decoder.decode();
1333
+ } finally {
1334
+ reader.releaseLock();
1335
+ }
1336
+ }
1337
+ return {
1338
+ async request(request, transportOptions = {}) {
1339
+ const response = await post(request, "application/json", transportOptions.signal);
1340
+ const text = await readBoundedText(response, maxResponseBytes);
1341
+ return JSON.parse(text);
1342
+ },
1343
+ async *watch(request, transportOptions = {}) {
1344
+ const response = await post(request, "application/x-ndjson", transportOptions.signal);
1345
+ if (!response.body) {
1346
+ throw new OrchestrationError({
1347
+ code: "UNAVAILABLE",
1348
+ message: "remote orchestration watch response has no body",
1349
+ retryable: true
1350
+ });
1351
+ }
1352
+ const reader = response.body.getReader();
1353
+ const decoder = new TextDecoder();
1354
+ let pending = "";
1355
+ let streamCompleted = false;
1356
+ try {
1357
+ for (; ; ) {
1358
+ const { done, value } = await reader.read();
1359
+ if (done) {
1360
+ streamCompleted = true;
1361
+ break;
1362
+ }
1363
+ pending += decoder.decode(value, { stream: true });
1364
+ let newline = pending.indexOf("\n");
1365
+ while (newline >= 0) {
1366
+ const line = pending.slice(0, newline).trim();
1367
+ pending = pending.slice(newline + 1);
1368
+ assertWatchLineSize(line);
1369
+ if (line) yield JSON.parse(line);
1370
+ newline = pending.indexOf("\n");
1371
+ }
1372
+ if (pending.length > maxWatchLineBytes) {
1373
+ throw new OrchestrationError({
1374
+ code: "EXHAUSTED",
1375
+ message: `remote orchestration watch line exceeds ${maxWatchLineBytes} bytes`,
1376
+ retryable: false
1377
+ });
1378
+ }
1379
+ }
1380
+ pending += decoder.decode();
1381
+ if (pending.trim()) {
1382
+ assertWatchLineSize(pending.trim());
1383
+ yield JSON.parse(pending);
1384
+ }
1385
+ } finally {
1386
+ if (!streamCompleted) {
1387
+ await reader.cancel().catch(() => void 0);
1388
+ }
1389
+ reader.releaseLock();
1390
+ }
1391
+ }
1392
+ };
1393
+ }
1394
+ // Annotate the CommonJS export names for ESM import in node:
1395
+ 0 && (module.exports = {
1396
+ ALL_CATEGORIES,
1397
+ AgentCreationController,
1398
+ AgentDefinitionEditorController,
1399
+ AgentSessionController,
1400
+ OrchestrationError,
1401
+ PromptPreviewController,
1402
+ REMOTE_ORCHESTRATION_PROTOCOL,
1403
+ TiddlyWikiHttpStorage,
1404
+ createFetchOrchestrationTransport,
1405
+ createNamespacedOrchestrationClient,
1406
+ createReadOnlyOrchestrationClient,
1407
+ createRemoteOrchestrationClient,
1408
+ createRemoteOrchestrationHandler,
1409
+ getCategoryConfig,
1410
+ isTaskCategory,
1411
+ resolveCategory
1412
+ });
1413
+ //# sourceMappingURL=browser.cjs.map