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.
- package/README.md +63 -0
- package/dist/browser.cjs +1413 -0
- package/dist/browser.cjs.map +1 -0
- package/dist/browser.d.cts +3066 -0
- package/dist/browser.d.ts +3066 -0
- package/dist/browser.js +43 -0
- package/dist/chunk-426CJUZP.js +630 -0
- package/dist/chunk-426CJUZP.js.map +1 -0
- package/dist/chunk-44YHBKDL.js +382 -0
- package/dist/chunk-44YHBKDL.js.map +1 -0
- package/dist/chunk-7ZDTB4VZ.js +63 -0
- package/dist/chunk-7ZDTB4VZ.js.map +1 -0
- package/dist/chunk-AZFYDWIN.js +98 -0
- package/dist/chunk-AZFYDWIN.js.map +1 -0
- package/dist/chunk-BGPU4RR7.js +367 -0
- package/dist/chunk-BGPU4RR7.js.map +1 -0
- package/dist/chunk-CCEFAOSH.js +496 -0
- package/dist/chunk-CCEFAOSH.js.map +1 -0
- package/dist/chunk-FWSY5HOA.js +63 -0
- package/dist/chunk-FWSY5HOA.js.map +1 -0
- package/dist/chunk-GYIOMQMY.js +8726 -0
- package/dist/chunk-GYIOMQMY.js.map +1 -0
- package/dist/chunk-HVB2BR3H.js +42 -0
- package/dist/chunk-HVB2BR3H.js.map +1 -0
- package/dist/chunk-K6P63KD4.js +68 -0
- package/dist/chunk-K6P63KD4.js.map +1 -0
- package/dist/chunk-MRKY4HGF.js +205 -0
- package/dist/chunk-MRKY4HGF.js.map +1 -0
- package/dist/chunk-QFHAAIIM.js +2657 -0
- package/dist/chunk-QFHAAIIM.js.map +1 -0
- package/dist/chunk-VZKQX5PP.js +1 -0
- package/dist/chunk-VZKQX5PP.js.map +1 -0
- package/dist/chunk-WAI6BODI.js +175 -0
- package/dist/chunk-WAI6BODI.js.map +1 -0
- package/dist/chunk-XHRBV6I3.js +3637 -0
- package/dist/chunk-XHRBV6I3.js.map +1 -0
- package/dist/chunk-YMNXDNDW.js +798 -0
- package/dist/chunk-YMNXDNDW.js.map +1 -0
- package/dist/conversation.cjs +208 -0
- package/dist/conversation.cjs.map +1 -0
- package/dist/conversation.d.cts +100 -0
- package/dist/conversation.d.ts +100 -0
- package/dist/conversation.js +21 -0
- package/dist/conversation.js.map +1 -0
- package/dist/device-network-portable.cjs +702 -0
- package/dist/device-network-portable.cjs.map +1 -0
- package/dist/device-network-portable.d.cts +110 -0
- package/dist/device-network-portable.d.ts +110 -0
- package/dist/device-network-portable.js +53 -0
- package/dist/device-network-portable.js.map +1 -0
- package/dist/device-network.cjs +906 -0
- package/dist/device-network.cjs.map +1 -0
- package/dist/device-network.d.cts +6 -0
- package/dist/device-network.d.ts +6 -0
- package/dist/device-network.js +59 -0
- package/dist/device-network.js.map +1 -0
- package/dist/fetchProvider-BpcGVSOG.d.cts +91 -0
- package/dist/fetchProvider-Cm0sO4Tl.d.ts +91 -0
- package/dist/index.cjs +27957 -5459
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +94 -1320
- package/dist/index.d.ts +94 -1320
- package/dist/index.js +10576 -2386
- package/dist/index.js.map +1 -1
- package/dist/interface-IrKBFtL1.d.cts +493 -0
- package/dist/interface-IrKBFtL1.d.ts +493 -0
- package/dist/llm-providers.cjs +43 -8
- package/dist/llm-providers.cjs.map +1 -1
- package/dist/llm-providers.d.cts +2 -1
- package/dist/llm-providers.d.ts +2 -1
- package/dist/llm-providers.js +4 -2
- package/dist/llm-providers.js.map +1 -1
- package/dist/loop-api.cjs +5177 -2050
- package/dist/loop-api.cjs.map +1 -1
- package/dist/loop-api.d.cts +11 -5
- package/dist/loop-api.d.ts +11 -5
- package/dist/loop-api.js +84 -49
- package/dist/mobile.cjs +2625 -0
- package/dist/mobile.cjs.map +1 -0
- package/dist/mobile.d.cts +6 -0
- package/dist/mobile.d.ts +6 -0
- package/dist/mobile.js +22 -0
- package/dist/mobile.js.map +1 -0
- package/dist/orchestration-portable-Bsf8YRfp.d.cts +2192 -0
- package/dist/orchestration-portable-Zw0g5tbj.d.ts +2192 -0
- package/dist/orchestration-portable.cjs +9553 -0
- package/dist/orchestration-portable.cjs.map +1 -0
- package/dist/orchestration-portable.d.cts +5 -0
- package/dist/orchestration-portable.d.ts +5 -0
- package/dist/orchestration-portable.js +290 -0
- package/dist/orchestration-portable.js.map +1 -0
- package/dist/pairingInvite-BXPWY3aM.d.cts +149 -0
- package/dist/pairingInvite-Cuz0wuq9.d.ts +149 -0
- package/dist/promptConcat-WTN-uHcz.d.cts +516 -0
- package/dist/promptConcat-deDSWZE3.d.ts +516 -0
- package/dist/providerRegistry-9trr5aoK.d.ts +86 -0
- package/dist/providerRegistry-xk_B1Ekv.d.cts +86 -0
- package/dist/registry-8eztoD_r.d.cts +393 -0
- package/dist/registry-DV24sI-3.d.ts +393 -0
- package/dist/remoteClient-B_spK019.d.ts +87 -0
- package/dist/remoteClient-CBggnRy3.d.cts +87 -0
- package/dist/runtime-SKSXVYIM.js +18 -0
- package/dist/runtime-SKSXVYIM.js.map +1 -0
- package/dist/scriptDeploymentPipeline-BAeo1dPb.d.cts +2463 -0
- package/dist/scriptDeploymentPipeline-DsnT0AG6.d.ts +2463 -0
- package/dist/syncCloudDevices-BEqwgrhD.d.ts +49 -0
- package/dist/syncCloudDevices-Ds_Kcgrv.d.cts +49 -0
- package/dist/types-7pYti-k9.d.cts +255 -0
- package/dist/types-CdFVSntj.d.ts +255 -0
- package/package.json +110 -35
- package/dist/anthropic.cjs +0 -72
- package/dist/anthropic.cjs.map +0 -1
- package/dist/anthropic.d.cts +0 -21
- package/dist/anthropic.d.ts +0 -21
- package/dist/anthropic.js +0 -21
- package/dist/anthropic.js.map +0 -1
- package/dist/azure.cjs +0 -72
- package/dist/azure.cjs.map +0 -1
- package/dist/azure.d.cts +0 -21
- package/dist/azure.d.ts +0 -21
- package/dist/azure.js +0 -21
- package/dist/azure.js.map +0 -1
- package/dist/chunk-3CN7DFBL.js +0 -4894
- package/dist/chunk-3CN7DFBL.js.map +0 -1
- package/dist/chunk-4AZ4D7U5.js +0 -32
- package/dist/chunk-4AZ4D7U5.js.map +0 -1
- package/dist/chunk-6ON4XSOV.js +0 -63
- package/dist/chunk-6ON4XSOV.js.map +0 -1
- package/dist/chunk-DJQNGIXX.js +0 -4793
- package/dist/chunk-DJQNGIXX.js.map +0 -1
- package/dist/chunk-FKQP6AOQ.js +0 -32
- package/dist/chunk-FKQP6AOQ.js.map +0 -1
- package/dist/chunk-OVJ7JJBA.js +0 -35
- package/dist/chunk-OVJ7JJBA.js.map +0 -1
- package/dist/chunk-P4UZ7IXC.js +0 -42
- package/dist/chunk-YHJ2AEFR.js +0 -4933
- package/dist/chunk-YHJ2AEFR.js.map +0 -1
- package/dist/chunk-YVK7RYRO.js +0 -4973
- package/dist/chunk-YVK7RYRO.js.map +0 -1
- package/dist/code-assistant.json +0 -114
- package/dist/cohere.cjs +0 -72
- package/dist/cohere.cjs.map +0 -1
- package/dist/cohere.d.cts +0 -21
- package/dist/cohere.d.ts +0 -21
- package/dist/cohere.js +0 -21
- package/dist/cohere.js.map +0 -1
- package/dist/deepseek.cjs +0 -72
- package/dist/deepseek.cjs.map +0 -1
- package/dist/deepseek.d.cts +0 -21
- package/dist/deepseek.d.ts +0 -21
- package/dist/deepseek.js +0 -21
- package/dist/deepseek.js.map +0 -1
- package/dist/dist-65U7OYRG.js +0 -1257
- package/dist/dist-65U7OYRG.js.map +0 -1
- package/dist/fetchProvider-Cu4WkU5O.d.cts +0 -819
- package/dist/fetchProvider-Cu4WkU5O.d.ts +0 -819
- package/dist/frontend-ui-ux.json +0 -105
- package/dist/general-assistant.json +0 -95
- package/dist/git-master.json +0 -51
- package/dist/google-vertex.cjs +0 -72
- package/dist/google-vertex.cjs.map +0 -1
- package/dist/google-vertex.d.cts +0 -21
- package/dist/google-vertex.d.ts +0 -21
- package/dist/google-vertex.js +0 -21
- package/dist/google-vertex.js.map +0 -1
- package/dist/google.cjs +0 -72
- package/dist/google.cjs.map +0 -1
- package/dist/google.d.cts +0 -21
- package/dist/google.d.ts +0 -21
- package/dist/google.js +0 -21
- package/dist/google.js.map +0 -1
- package/dist/groq.cjs +0 -72
- package/dist/groq.cjs.map +0 -1
- package/dist/groq.d.cts +0 -21
- package/dist/groq.d.ts +0 -21
- package/dist/groq.js +0 -21
- package/dist/groq.js.map +0 -1
- package/dist/index.d.mts +0 -3203
- package/dist/index.mjs +0 -7064
- package/dist/index.mjs.map +0 -1
- package/dist/mistral.cjs +0 -72
- package/dist/mistral.cjs.map +0 -1
- package/dist/mistral.d.cts +0 -21
- package/dist/mistral.d.ts +0 -21
- package/dist/mistral.js +0 -21
- package/dist/mistral.js.map +0 -1
- package/dist/multipart-parser-EJCXIUHC.js +0 -372
- package/dist/multipart-parser-EJCXIUHC.js.map +0 -1
- package/dist/openai.cjs +0 -72
- package/dist/openai.cjs.map +0 -1
- package/dist/openai.d.cts +0 -21
- package/dist/openai.d.ts +0 -21
- package/dist/openai.js +0 -21
- package/dist/openai.js.map +0 -1
- package/dist/perplexity.cjs +0 -72
- package/dist/perplexity.cjs.map +0 -1
- package/dist/perplexity.d.cts +0 -21
- package/dist/perplexity.d.ts +0 -21
- package/dist/perplexity.js +0 -21
- package/dist/perplexity.js.map +0 -1
- package/dist/playwright.json +0 -52
- package/dist/promptConcat-BJdazTg5.d.cts +0 -1832
- package/dist/promptConcat-BJdazTg5.d.ts +0 -1832
- package/dist/promptConcat-CAkpni_8.d.cts +0 -1834
- package/dist/promptConcat-CAkpni_8.d.ts +0 -1834
- package/dist/promptConcat-CfH5-GAE.d.cts +0 -1036
- package/dist/promptConcat-ChcAZOOL.d.ts +0 -1036
- package/dist/promptConcat-G5TnJVRy.d.cts +0 -1800
- package/dist/promptConcat-G5TnJVRy.d.ts +0 -1800
- package/dist/promptConcat-L72eowzp.d.ts +0 -1090
- package/dist/promptConcat-eLHdN7K8.d.cts +0 -1090
- package/dist/src-VTSXKG72.js +0 -1409
- package/dist/src-VTSXKG72.js.map +0 -1
- package/dist/togetherai.cjs +0 -72
- package/dist/togetherai.cjs.map +0 -1
- package/dist/togetherai.d.cts +0 -21
- package/dist/togetherai.d.ts +0 -21
- package/dist/togetherai.js +0 -21
- package/dist/togetherai.js.map +0 -1
- package/dist/types-B0Jm2l38.d.cts +0 -767
- package/dist/types-B0Jm2l38.d.ts +0 -767
- package/dist/xai.cjs +0 -72
- package/dist/xai.cjs.map +0 -1
- package/dist/xai.d.cts +0 -21
- package/dist/xai.d.ts +0 -21
- package/dist/xai.js +0 -21
- package/dist/xai.js.map +0 -1
- /package/dist/{chunk-P4UZ7IXC.js.map → browser.js.map} +0 -0
|
@@ -0,0 +1,798 @@
|
|
|
1
|
+
import {
|
|
2
|
+
OrchestrationError
|
|
3
|
+
} from "./chunk-FWSY5HOA.js";
|
|
4
|
+
|
|
5
|
+
// src/storage/tiddlyWikiHttpStorage.ts
|
|
6
|
+
var PREFIX = "$:/memeloop";
|
|
7
|
+
var DEFAULT_MAX_INLINE_BLOB = 256 * 1024;
|
|
8
|
+
var DEFAULT_CAS_ATTEMPTS = 3;
|
|
9
|
+
function bytesToBase64(bytes) {
|
|
10
|
+
let binary = "";
|
|
11
|
+
for (const byte of bytes) binary += String.fromCharCode(byte);
|
|
12
|
+
return btoa(binary);
|
|
13
|
+
}
|
|
14
|
+
function base64ToBytes(value) {
|
|
15
|
+
const binary = atob(value);
|
|
16
|
+
const bytes = new Uint8Array(binary.length);
|
|
17
|
+
for (let index = 0; index < binary.length; index += 1) bytes[index] = binary.charCodeAt(index);
|
|
18
|
+
return bytes;
|
|
19
|
+
}
|
|
20
|
+
function escapeFilterValue(value) {
|
|
21
|
+
return value.replace(/["\\[\]]/g, (character) => `\\${character}`);
|
|
22
|
+
}
|
|
23
|
+
var TiddlyWikiHttpStorage = class {
|
|
24
|
+
baseUrl;
|
|
25
|
+
recipe;
|
|
26
|
+
fetchImpl;
|
|
27
|
+
credentialHandle;
|
|
28
|
+
credentialResolver;
|
|
29
|
+
maxInlineBlobBytes;
|
|
30
|
+
maxCasAttempts;
|
|
31
|
+
constructor(options) {
|
|
32
|
+
this.baseUrl = options.baseUrl.replace(/\/+$/, "");
|
|
33
|
+
this.recipe = options.recipe ?? "default";
|
|
34
|
+
this.fetchImpl = options.fetchImpl ?? globalThis.fetch.bind(globalThis);
|
|
35
|
+
this.maxInlineBlobBytes = options.maxInlineBlobBytes ?? DEFAULT_MAX_INLINE_BLOB;
|
|
36
|
+
this.maxCasAttempts = options.maxCasAttempts ?? DEFAULT_CAS_ATTEMPTS;
|
|
37
|
+
if (options.credentialHandle === void 0 !== (options.credentialResolver === void 0)) {
|
|
38
|
+
throw new OrchestrationError({
|
|
39
|
+
code: "INVALID",
|
|
40
|
+
message: "credentialHandle and credentialResolver must be provided together",
|
|
41
|
+
retryable: false
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
this.credentialHandle = options.credentialHandle;
|
|
45
|
+
this.credentialResolver = options.credentialResolver;
|
|
46
|
+
}
|
|
47
|
+
eventTitle(conversationId, messageId) {
|
|
48
|
+
return `${PREFIX}/e/${conversationId}/${messageId}`;
|
|
49
|
+
}
|
|
50
|
+
metaTitle(conversationId) {
|
|
51
|
+
return `${PREFIX}/meta/${conversationId}`;
|
|
52
|
+
}
|
|
53
|
+
blobTitle(contentHash) {
|
|
54
|
+
return `${PREFIX}/blob/${contentHash}`;
|
|
55
|
+
}
|
|
56
|
+
definitionTitle(id) {
|
|
57
|
+
return `${PREFIX}/def/${id}`;
|
|
58
|
+
}
|
|
59
|
+
instanceTitle(id) {
|
|
60
|
+
return `${PREFIX}/inst/${id}`;
|
|
61
|
+
}
|
|
62
|
+
imTitle(channelId, imUserId) {
|
|
63
|
+
return `${PREFIX}/im/${channelId}/${imUserId}`;
|
|
64
|
+
}
|
|
65
|
+
tiddlerUrl(title) {
|
|
66
|
+
return `${this.baseUrl}/recipes/${encodeURIComponent(this.recipe)}/tiddlers/${encodeURIComponent(title)}`;
|
|
67
|
+
}
|
|
68
|
+
filterUrl(filter) {
|
|
69
|
+
return `${this.baseUrl}/recipes/${encodeURIComponent(this.recipe)}/tiddlers.json?filter=${encodeURIComponent(filter)}`;
|
|
70
|
+
}
|
|
71
|
+
async headers(url, method, extra = {}) {
|
|
72
|
+
const credentialHeaders = this.credentialHandle && this.credentialResolver ? await this.credentialResolver.resolveHeaders(this.credentialHandle, { url, method }) : {};
|
|
73
|
+
return {
|
|
74
|
+
"content-type": "application/json",
|
|
75
|
+
"x-requested-with": "TiddlyWiki",
|
|
76
|
+
...credentialHeaders,
|
|
77
|
+
...extra
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
/** GET a tiddler; returns null on 404. Includes the ETag when the server sends one. */
|
|
81
|
+
async readTiddler(title) {
|
|
82
|
+
const url = this.tiddlerUrl(title);
|
|
83
|
+
const response = await this.fetchImpl(url, { headers: await this.headers(url, "GET") });
|
|
84
|
+
if (response.status === 404) return null;
|
|
85
|
+
if (!response.ok) {
|
|
86
|
+
throw new OrchestrationError({ code: "UNAVAILABLE", message: `tiddler read failed: HTTP ${response.status}`, retryable: true });
|
|
87
|
+
}
|
|
88
|
+
const tiddler = await response.json();
|
|
89
|
+
const etag = response.headers.get("etag") ?? void 0;
|
|
90
|
+
return { tiddler, ...etag ? { etag } : {} };
|
|
91
|
+
}
|
|
92
|
+
/** CAS write: If-Match when an ETag is known; bounded retries on 412/409. */
|
|
93
|
+
async writeTiddler(title, build) {
|
|
94
|
+
for (let attempt = 1; attempt <= this.maxCasAttempts; attempt += 1) {
|
|
95
|
+
const current = await this.readTiddler(title);
|
|
96
|
+
if (current && !current.etag) {
|
|
97
|
+
throw new OrchestrationError({ code: "CONFLICT", message: `tiddler '${title}' has no ETag for a safe update`, retryable: false });
|
|
98
|
+
}
|
|
99
|
+
const next = build(current?.tiddler ?? null);
|
|
100
|
+
const url = this.tiddlerUrl(title);
|
|
101
|
+
const precondition = current ? { "if-match": current.etag } : { "if-none-match": "*" };
|
|
102
|
+
const response = await this.fetchImpl(url, {
|
|
103
|
+
method: "PUT",
|
|
104
|
+
headers: await this.headers(url, "PUT", precondition),
|
|
105
|
+
body: JSON.stringify(next)
|
|
106
|
+
});
|
|
107
|
+
if (response.ok) return;
|
|
108
|
+
if (response.status === 412 || response.status === 409) {
|
|
109
|
+
if (attempt === this.maxCasAttempts) {
|
|
110
|
+
throw new OrchestrationError({
|
|
111
|
+
code: "CONFLICT",
|
|
112
|
+
message: `tiddler '${title}' was modified concurrently after ${attempt} CAS attempts`,
|
|
113
|
+
retryable: true
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
throw new OrchestrationError({ code: "UNAVAILABLE", message: `tiddler write failed: HTTP ${response.status}`, retryable: true });
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
async listByPrefix(prefix) {
|
|
122
|
+
const filter = `[prefix["${escapeFilterValue(prefix)}"]]`;
|
|
123
|
+
const url = this.filterUrl(filter);
|
|
124
|
+
const response = await this.fetchImpl(url, { headers: await this.headers(url, "GET") });
|
|
125
|
+
if (!response.ok) {
|
|
126
|
+
throw new OrchestrationError({ code: "UNAVAILABLE", message: `tiddler list failed: HTTP ${response.status}`, retryable: true });
|
|
127
|
+
}
|
|
128
|
+
return await response.json();
|
|
129
|
+
}
|
|
130
|
+
parsePayload(tiddler) {
|
|
131
|
+
return JSON.parse(tiddler.text ?? "{}");
|
|
132
|
+
}
|
|
133
|
+
async listConversations(options = {}) {
|
|
134
|
+
const tiddlers = await this.listByPrefix(`${PREFIX}/meta/`);
|
|
135
|
+
const metas = tiddlers.map((tiddler) => this.parsePayload(tiddler));
|
|
136
|
+
metas.sort((a, b) => (b.lastMessageTimestamp ?? 0) - (a.lastMessageTimestamp ?? 0));
|
|
137
|
+
const offset = options.offset ?? 0;
|
|
138
|
+
const limit = options.limit ?? metas.length;
|
|
139
|
+
return metas.slice(offset, offset + limit);
|
|
140
|
+
}
|
|
141
|
+
async getMessages(conversationId, _options = {}) {
|
|
142
|
+
const tiddlers = await this.listByPrefix(`${PREFIX}/e/${conversationId}/`);
|
|
143
|
+
const messages = tiddlers.map((tiddler) => this.parsePayload(tiddler));
|
|
144
|
+
messages.sort((a, b) => (a.lamportClock ?? 0) - (b.lamportClock ?? 0));
|
|
145
|
+
return messages;
|
|
146
|
+
}
|
|
147
|
+
async appendMessage(message) {
|
|
148
|
+
await this.writeTiddler(this.eventTitle(message.conversationId, message.messageId), () => ({
|
|
149
|
+
title: this.eventTitle(message.conversationId, message.messageId),
|
|
150
|
+
text: JSON.stringify(message)
|
|
151
|
+
}));
|
|
152
|
+
}
|
|
153
|
+
async insertMessagesIfAbsent(messages) {
|
|
154
|
+
for (const message of messages) {
|
|
155
|
+
const title = this.eventTitle(message.conversationId, message.messageId);
|
|
156
|
+
const existing = await this.readTiddler(title);
|
|
157
|
+
if (!existing) {
|
|
158
|
+
await this.writeTiddler(title, () => ({ title, text: JSON.stringify(message) }));
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
async getMaxLamportClockForConversation(conversationId) {
|
|
163
|
+
const messages = await this.getMessages(conversationId);
|
|
164
|
+
return messages.reduce((max, message) => Math.max(max, message.lamportClock ?? 0), 0);
|
|
165
|
+
}
|
|
166
|
+
async upsertConversationMetadata(meta) {
|
|
167
|
+
const title = this.metaTitle(meta.conversationId);
|
|
168
|
+
await this.writeTiddler(title, () => ({ title, text: JSON.stringify(meta) }));
|
|
169
|
+
}
|
|
170
|
+
async getConversationMeta(conversationId) {
|
|
171
|
+
const result = await this.readTiddler(this.metaTitle(conversationId));
|
|
172
|
+
return result ? this.parsePayload(result.tiddler) : null;
|
|
173
|
+
}
|
|
174
|
+
async saveAttachment(reference, data) {
|
|
175
|
+
if (data.byteLength > this.maxInlineBlobBytes) {
|
|
176
|
+
throw new OrchestrationError({
|
|
177
|
+
code: "INVALID",
|
|
178
|
+
message: `blob of ${data.byteLength} bytes exceeds the inline limit ${this.maxInlineBlobBytes}; store it in an external BlobStore and keep the reference`,
|
|
179
|
+
retryable: false,
|
|
180
|
+
details: { maxInlineBlobBytes: this.maxInlineBlobBytes }
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
const title = this.blobTitle(reference.contentHash);
|
|
184
|
+
await this.writeTiddler(title, () => ({
|
|
185
|
+
title,
|
|
186
|
+
text: JSON.stringify({ reference, dataBase64: bytesToBase64(data) })
|
|
187
|
+
}));
|
|
188
|
+
}
|
|
189
|
+
async getAttachment(contentHash) {
|
|
190
|
+
const result = await this.readTiddler(this.blobTitle(contentHash));
|
|
191
|
+
if (!result) return null;
|
|
192
|
+
return this.parsePayload(result.tiddler).reference;
|
|
193
|
+
}
|
|
194
|
+
async readAttachmentData(contentHash) {
|
|
195
|
+
const result = await this.readTiddler(this.blobTitle(contentHash));
|
|
196
|
+
if (!result) return null;
|
|
197
|
+
return base64ToBytes(this.parsePayload(result.tiddler).dataBase64);
|
|
198
|
+
}
|
|
199
|
+
async getAgentDefinition(id) {
|
|
200
|
+
const result = await this.readTiddler(this.definitionTitle(id));
|
|
201
|
+
return result ? this.parsePayload(result.tiddler) : null;
|
|
202
|
+
}
|
|
203
|
+
async saveAgentDefinition(definition) {
|
|
204
|
+
const title = this.definitionTitle(definition.id);
|
|
205
|
+
await this.writeTiddler(title, () => ({ title, text: JSON.stringify(definition) }));
|
|
206
|
+
}
|
|
207
|
+
async saveAgentInstance(meta) {
|
|
208
|
+
const title = this.instanceTitle(meta.instanceId);
|
|
209
|
+
await this.writeTiddler(title, () => ({ title, text: JSON.stringify(meta) }));
|
|
210
|
+
}
|
|
211
|
+
async getImBinding(channelId, imUserId) {
|
|
212
|
+
const result = await this.readTiddler(this.imTitle(channelId, imUserId));
|
|
213
|
+
return result ? this.parsePayload(result.tiddler) : null;
|
|
214
|
+
}
|
|
215
|
+
async setImBinding(record) {
|
|
216
|
+
const title = this.imTitle(record.channelId, record.imUserId);
|
|
217
|
+
await this.writeTiddler(title, () => ({ title, text: JSON.stringify(record) }));
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
// src/agent-management/AgentSessionController.ts
|
|
222
|
+
var AgentSessionController = class {
|
|
223
|
+
options;
|
|
224
|
+
listener = null;
|
|
225
|
+
snapshot = {
|
|
226
|
+
agent: null,
|
|
227
|
+
loading: false,
|
|
228
|
+
error: null,
|
|
229
|
+
messages: [],
|
|
230
|
+
orderedMessageIds: [],
|
|
231
|
+
streamingMessageIds: /* @__PURE__ */ new Set()
|
|
232
|
+
};
|
|
233
|
+
unsubAgentUpdates = null;
|
|
234
|
+
unsubMessages = null;
|
|
235
|
+
pollingTimer = null;
|
|
236
|
+
agentId = null;
|
|
237
|
+
constructor(options) {
|
|
238
|
+
this.options = {
|
|
239
|
+
pollInterval: 500,
|
|
240
|
+
...options
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
// ── Lifecycle ─────────────────────────────────────────────────
|
|
244
|
+
/**
|
|
245
|
+
* Start a session for the given agent ID.
|
|
246
|
+
* Fetches the agent, subscribes to live updates, and loads messages.
|
|
247
|
+
*/
|
|
248
|
+
async start(agentId) {
|
|
249
|
+
this.agentId = agentId;
|
|
250
|
+
this.emitPartial({ loading: true, error: null });
|
|
251
|
+
try {
|
|
252
|
+
const [agent, rawMessages] = await Promise.all([
|
|
253
|
+
this.options.agentInstanceClient.fetchAgent(agentId),
|
|
254
|
+
this.options.conversationClient.getMessages(agentId)
|
|
255
|
+
]);
|
|
256
|
+
const orderedMessageIds = rawMessages.map((m) => m.messageId);
|
|
257
|
+
const messagesMap = /* @__PURE__ */ new Map();
|
|
258
|
+
for (const m of rawMessages) messagesMap.set(m.messageId, m);
|
|
259
|
+
this.emitPartial({
|
|
260
|
+
agent,
|
|
261
|
+
loading: false,
|
|
262
|
+
messages: rawMessages,
|
|
263
|
+
orderedMessageIds,
|
|
264
|
+
streamingMessageIds: /* @__PURE__ */ new Set()
|
|
265
|
+
});
|
|
266
|
+
this.unsubAgentUpdates = this.options.agentInstanceClient.subscribeToUpdates(
|
|
267
|
+
agentId,
|
|
268
|
+
this.handleAgentUpdate
|
|
269
|
+
);
|
|
270
|
+
this.unsubMessages = this.options.conversationClient.subscribeToMessages(
|
|
271
|
+
agentId,
|
|
272
|
+
this.handleNewMessage
|
|
273
|
+
);
|
|
274
|
+
this.startPolling(agentId);
|
|
275
|
+
} catch (error_) {
|
|
276
|
+
this.emitPartial({
|
|
277
|
+
loading: false,
|
|
278
|
+
error: error_ instanceof Error ? error_ : new Error(String(error_))
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
/** Stop the session and clean up subscriptions. */
|
|
283
|
+
stop() {
|
|
284
|
+
this.stopPolling();
|
|
285
|
+
this.unsubAgentUpdates?.();
|
|
286
|
+
this.unsubAgentUpdates = null;
|
|
287
|
+
this.unsubMessages?.();
|
|
288
|
+
this.unsubMessages = null;
|
|
289
|
+
this.agentId = null;
|
|
290
|
+
}
|
|
291
|
+
// ── Actions ───────────────────────────────────────────────────
|
|
292
|
+
/** Send a user message. */
|
|
293
|
+
async sendMessage(content, file, wikiTiddlers) {
|
|
294
|
+
if (!this.agentId) return;
|
|
295
|
+
this.emitPartial({ error: null });
|
|
296
|
+
try {
|
|
297
|
+
await this.options.conversationClient.sendMessage(this.agentId, content, file, wikiTiddlers);
|
|
298
|
+
} catch (error_) {
|
|
299
|
+
this.emitPartial({
|
|
300
|
+
error: error_ instanceof Error ? error_ : new Error(String(error_))
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
/** Cancel the current agent operation. */
|
|
305
|
+
async cancel() {
|
|
306
|
+
if (!this.agentId) return;
|
|
307
|
+
try {
|
|
308
|
+
await this.options.agentInstanceClient.cancelAgent(this.agentId);
|
|
309
|
+
} catch (error_) {
|
|
310
|
+
this.emitPartial({
|
|
311
|
+
error: error_ instanceof Error ? error_ : new Error(String(error_))
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
/** Delete a turn starting at the given user message ID. */
|
|
316
|
+
async deleteTurn(userMessageId) {
|
|
317
|
+
return this.options.conversationClient.deleteTurn(userMessageId);
|
|
318
|
+
}
|
|
319
|
+
/** Retry a turn starting at the given user message ID. */
|
|
320
|
+
async retryTurn(userMessageId) {
|
|
321
|
+
return this.options.conversationClient.retryTurn(userMessageId);
|
|
322
|
+
}
|
|
323
|
+
// ── Subscription ──────────────────────────────────────────────
|
|
324
|
+
/** Subscribe to snapshot changes. Returns unsubscribe function. */
|
|
325
|
+
subscribe(listener) {
|
|
326
|
+
this.listener = listener;
|
|
327
|
+
listener({ ...this.snapshot, streamingMessageIds: new Set(this.snapshot.streamingMessageIds) });
|
|
328
|
+
return () => {
|
|
329
|
+
if (this.listener === listener) this.listener = null;
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
/** Get current snapshot without subscribing. */
|
|
333
|
+
getSnapshot() {
|
|
334
|
+
return this.snapshot;
|
|
335
|
+
}
|
|
336
|
+
// ── Private helpers ───────────────────────────────────────────
|
|
337
|
+
emitPartial(partial) {
|
|
338
|
+
this.snapshot = { ...this.snapshot, ...partial };
|
|
339
|
+
if (this.listener) {
|
|
340
|
+
this.listener({
|
|
341
|
+
...this.snapshot,
|
|
342
|
+
streamingMessageIds: new Set(this.snapshot.streamingMessageIds)
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
handleAgentUpdate = (update) => {
|
|
347
|
+
if (this.snapshot.agent) {
|
|
348
|
+
this.emitPartial({ agent: { ...this.snapshot.agent, ...update } });
|
|
349
|
+
}
|
|
350
|
+
};
|
|
351
|
+
handleNewMessage = (message) => {
|
|
352
|
+
const messages = [...this.snapshot.messages.filter((m) => m.messageId !== message.messageId), message];
|
|
353
|
+
const orderedMessageIds = [.../* @__PURE__ */ new Set([...this.snapshot.orderedMessageIds, message.messageId])];
|
|
354
|
+
this.emitPartial({ messages, orderedMessageIds });
|
|
355
|
+
};
|
|
356
|
+
startPolling(agentId) {
|
|
357
|
+
this.stopPolling();
|
|
358
|
+
this.pollingTimer = setInterval(async () => {
|
|
359
|
+
try {
|
|
360
|
+
const agent = await this.options.agentInstanceClient.fetchAgent(agentId);
|
|
361
|
+
this.emitPartial({ agent });
|
|
362
|
+
} catch {
|
|
363
|
+
}
|
|
364
|
+
}, this.options.pollInterval);
|
|
365
|
+
}
|
|
366
|
+
stopPolling() {
|
|
367
|
+
if (this.pollingTimer !== null) {
|
|
368
|
+
clearInterval(this.pollingTimer);
|
|
369
|
+
this.pollingTimer = null;
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
};
|
|
373
|
+
|
|
374
|
+
// src/agent-management/AgentDefinitionEditorController.ts
|
|
375
|
+
var AgentDefinitionEditorController = class {
|
|
376
|
+
options;
|
|
377
|
+
listener = null;
|
|
378
|
+
state = {
|
|
379
|
+
agentDefinition: null,
|
|
380
|
+
agentName: "",
|
|
381
|
+
previewAgentId: null,
|
|
382
|
+
isLoading: false,
|
|
383
|
+
isSaving: false,
|
|
384
|
+
promptSchema: null
|
|
385
|
+
};
|
|
386
|
+
autosaveTimer = null;
|
|
387
|
+
constructor(options) {
|
|
388
|
+
this.options = {
|
|
389
|
+
autosaveDebounceMs: 1e3,
|
|
390
|
+
...options
|
|
391
|
+
};
|
|
392
|
+
}
|
|
393
|
+
// ── Lifecycle ─────────────────────────────────────────────────
|
|
394
|
+
/** Load an agent definition and its prompt schema. */
|
|
395
|
+
async loadDefinition(definitionId) {
|
|
396
|
+
this.emit({ isLoading: true });
|
|
397
|
+
try {
|
|
398
|
+
const [definition, previewAgentId] = await Promise.all([
|
|
399
|
+
this.options.definitionRepository.getAgentDef(definitionId),
|
|
400
|
+
this.findOrCreatePreviewAgent(definitionId)
|
|
401
|
+
]);
|
|
402
|
+
if (!definition) {
|
|
403
|
+
this.emit({ isLoading: false });
|
|
404
|
+
return;
|
|
405
|
+
}
|
|
406
|
+
let promptSchema = null;
|
|
407
|
+
if (definition.agentFrameworkID) {
|
|
408
|
+
try {
|
|
409
|
+
promptSchema = await this.options.agentInstanceClient.getFrameworkConfigSchema(
|
|
410
|
+
definition.agentFrameworkID
|
|
411
|
+
);
|
|
412
|
+
} catch {
|
|
413
|
+
promptSchema = null;
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
this.state = {
|
|
417
|
+
agentDefinition: definition,
|
|
418
|
+
agentName: definition.name ?? "",
|
|
419
|
+
previewAgentId,
|
|
420
|
+
isLoading: false,
|
|
421
|
+
isSaving: false,
|
|
422
|
+
promptSchema
|
|
423
|
+
};
|
|
424
|
+
this.emit(this.state);
|
|
425
|
+
} catch {
|
|
426
|
+
this.emit({ isLoading: false });
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
/** Update the agent definition field. Triggers debounced autosave. */
|
|
430
|
+
updateDefinition(change) {
|
|
431
|
+
if (!this.state.agentDefinition) return;
|
|
432
|
+
const updated = { ...this.state.agentDefinition, ...change };
|
|
433
|
+
this.state = { ...this.state, agentDefinition: updated, agentName: updated.name ?? "" };
|
|
434
|
+
this.emit({ agentDefinition: updated, agentName: this.state.agentName });
|
|
435
|
+
this.scheduleAutosave(updated);
|
|
436
|
+
}
|
|
437
|
+
/** Force an immediate save to the repository. */
|
|
438
|
+
async saveNow() {
|
|
439
|
+
if (!this.state.agentDefinition) return;
|
|
440
|
+
this.emit({ isSaving: true });
|
|
441
|
+
try {
|
|
442
|
+
await this.options.definitionRepository.updateAgentDef({
|
|
443
|
+
id: this.state.agentDefinition.id,
|
|
444
|
+
name: this.state.agentName,
|
|
445
|
+
description: this.state.agentDefinition.description,
|
|
446
|
+
agentFrameworkConfig: this.state.agentDefinition.agentFrameworkConfig,
|
|
447
|
+
aiApiConfig: this.state.agentDefinition.aiApiConfig,
|
|
448
|
+
agentTools: this.state.agentDefinition.agentTools,
|
|
449
|
+
heartbeat: this.state.agentDefinition.heartbeat
|
|
450
|
+
});
|
|
451
|
+
} catch {
|
|
452
|
+
} finally {
|
|
453
|
+
this.emit({ isSaving: false });
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
/** Reload the prompt schema for a framework ID. */
|
|
457
|
+
async reloadSchema(frameworkId) {
|
|
458
|
+
try {
|
|
459
|
+
const schema = await this.options.agentInstanceClient.getFrameworkConfigSchema(frameworkId);
|
|
460
|
+
this.emit({ promptSchema: schema });
|
|
461
|
+
} catch {
|
|
462
|
+
this.emit({ promptSchema: null });
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
// ── Preview agent lifecycle ───────────────────────────────────
|
|
466
|
+
/** Get or create a preview agent instance tied to this definition. */
|
|
467
|
+
async findOrCreatePreviewAgent(definitionId) {
|
|
468
|
+
try {
|
|
469
|
+
const result = await this.options.agentInstanceClient.createAgent(definitionId, {
|
|
470
|
+
preview: true
|
|
471
|
+
});
|
|
472
|
+
return result.id;
|
|
473
|
+
} catch {
|
|
474
|
+
return null;
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
// ── Scheduled tasks ───────────────────────────────────────────
|
|
478
|
+
async loadScheduledTasks() {
|
|
479
|
+
if (!this.state.previewAgentId) return [];
|
|
480
|
+
return this.options.scheduledTaskClient.listScheduledTasksForAgent(
|
|
481
|
+
this.state.previewAgentId
|
|
482
|
+
);
|
|
483
|
+
}
|
|
484
|
+
async saveScheduledTask(input) {
|
|
485
|
+
return this.options.scheduledTaskClient.createScheduledTask(input);
|
|
486
|
+
}
|
|
487
|
+
async deleteScheduledTask(taskId) {
|
|
488
|
+
return this.options.scheduledTaskClient.deleteScheduledTask(taskId);
|
|
489
|
+
}
|
|
490
|
+
// ── Subscription ──────────────────────────────────────────────
|
|
491
|
+
subscribe(listener) {
|
|
492
|
+
this.listener = listener;
|
|
493
|
+
listener(this.state);
|
|
494
|
+
return () => {
|
|
495
|
+
if (this.listener === listener) this.listener = null;
|
|
496
|
+
};
|
|
497
|
+
}
|
|
498
|
+
getState() {
|
|
499
|
+
return this.state;
|
|
500
|
+
}
|
|
501
|
+
// ── Private ───────────────────────────────────────────────────
|
|
502
|
+
emit(change) {
|
|
503
|
+
this.listener?.(change);
|
|
504
|
+
}
|
|
505
|
+
scheduleAutosave(definition) {
|
|
506
|
+
if (this.autosaveTimer !== null) clearTimeout(this.autosaveTimer);
|
|
507
|
+
this.autosaveTimer = setTimeout(() => {
|
|
508
|
+
this.options.definitionRepository.updateAgentDef({
|
|
509
|
+
id: definition.id,
|
|
510
|
+
name: definition.name,
|
|
511
|
+
description: definition.description,
|
|
512
|
+
agentFrameworkConfig: definition.agentFrameworkConfig,
|
|
513
|
+
aiApiConfig: definition.aiApiConfig,
|
|
514
|
+
agentTools: definition.agentTools,
|
|
515
|
+
heartbeat: definition.heartbeat
|
|
516
|
+
}).catch(() => {
|
|
517
|
+
});
|
|
518
|
+
}, this.options.autosaveDebounceMs);
|
|
519
|
+
}
|
|
520
|
+
};
|
|
521
|
+
|
|
522
|
+
// src/agent-management/AgentCreationController.ts
|
|
523
|
+
var AgentCreationController = class {
|
|
524
|
+
options;
|
|
525
|
+
listener = null;
|
|
526
|
+
state = {
|
|
527
|
+
currentStep: 0,
|
|
528
|
+
agentName: "",
|
|
529
|
+
selectedTemplate: null,
|
|
530
|
+
temporaryAgentDefinition: null,
|
|
531
|
+
previewAgentId: null,
|
|
532
|
+
isLoading: false,
|
|
533
|
+
promptSchema: null
|
|
534
|
+
};
|
|
535
|
+
constructor(options) {
|
|
536
|
+
this.options = {
|
|
537
|
+
defaultFrameworkId: "memeloopAgentToolLoop",
|
|
538
|
+
...options
|
|
539
|
+
};
|
|
540
|
+
}
|
|
541
|
+
/** Initialize the creation wizard, optionally from a saved tab state. */
|
|
542
|
+
async start(definitionId, templateDefinitionId) {
|
|
543
|
+
this.emit({ isLoading: true });
|
|
544
|
+
try {
|
|
545
|
+
if (definitionId) {
|
|
546
|
+
const temporaryDefinition = await this.options.definitionRepository.getAgentDef(definitionId);
|
|
547
|
+
if (temporaryDefinition) {
|
|
548
|
+
this.state = {
|
|
549
|
+
...this.state,
|
|
550
|
+
temporaryAgentDefinition: temporaryDefinition,
|
|
551
|
+
agentName: temporaryDefinition.name ?? "",
|
|
552
|
+
isLoading: false
|
|
553
|
+
};
|
|
554
|
+
this.emit(this.state);
|
|
555
|
+
if (templateDefinitionId) {
|
|
556
|
+
const template = await this.options.definitionRepository.getAgentDef(templateDefinitionId);
|
|
557
|
+
if (template) {
|
|
558
|
+
this.state = { ...this.state, selectedTemplate: template };
|
|
559
|
+
this.emit(this.state);
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
return;
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
this.emit({ isLoading: false });
|
|
566
|
+
} catch {
|
|
567
|
+
this.emit({ isLoading: false });
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
/** Select a template for the new agent. */
|
|
571
|
+
selectTemplate(template) {
|
|
572
|
+
this.state = { ...this.state, selectedTemplate: template };
|
|
573
|
+
this.emit(this.state);
|
|
574
|
+
}
|
|
575
|
+
/** Update the agent name. */
|
|
576
|
+
setAgentName(name) {
|
|
577
|
+
this.state = { ...this.state, agentName: name };
|
|
578
|
+
this.emit(this.state);
|
|
579
|
+
}
|
|
580
|
+
/** Advance to the next wizard step. */
|
|
581
|
+
nextStep() {
|
|
582
|
+
this.state = { ...this.state, currentStep: Math.min(this.state.currentStep + 1, 2) };
|
|
583
|
+
this.emit(this.state);
|
|
584
|
+
}
|
|
585
|
+
/** Go back to the previous wizard step. */
|
|
586
|
+
previousStep() {
|
|
587
|
+
this.state = { ...this.state, currentStep: Math.max(this.state.currentStep - 1, 0) };
|
|
588
|
+
this.emit(this.state);
|
|
589
|
+
}
|
|
590
|
+
/** Set the current wizard step directly. */
|
|
591
|
+
setStep(step) {
|
|
592
|
+
this.state = { ...this.state, currentStep: Math.max(0, Math.min(step, 2)) };
|
|
593
|
+
this.emit(this.state);
|
|
594
|
+
}
|
|
595
|
+
/** Update the temporary agent definition. */
|
|
596
|
+
updateTemporaryDefinition(change) {
|
|
597
|
+
const updated = this.state.temporaryAgentDefinition ? { ...this.state.temporaryAgentDefinition, ...change } : null;
|
|
598
|
+
this.state = { ...this.state, temporaryAgentDefinition: updated };
|
|
599
|
+
this.emit(this.state);
|
|
600
|
+
}
|
|
601
|
+
/** Set the prompt schema for the selected framework. */
|
|
602
|
+
setPromptSchema(schema) {
|
|
603
|
+
this.state = { ...this.state, promptSchema: schema };
|
|
604
|
+
this.emit(this.state);
|
|
605
|
+
}
|
|
606
|
+
/**
|
|
607
|
+
* Create a preview agent instance for the chat-preview step.
|
|
608
|
+
* Should be called when entering step 2 (or the chat preview step).
|
|
609
|
+
*/
|
|
610
|
+
async createPreviewAgent(definitionId) {
|
|
611
|
+
this.emit({ isLoading: true });
|
|
612
|
+
try {
|
|
613
|
+
const result = await this.options.agentInstanceClient.createAgent(definitionId, {
|
|
614
|
+
preview: true
|
|
615
|
+
});
|
|
616
|
+
this.state = { ...this.state, previewAgentId: result.id, isLoading: false };
|
|
617
|
+
this.emit(this.state);
|
|
618
|
+
} catch {
|
|
619
|
+
this.emit({ isLoading: false });
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
/**
|
|
623
|
+
* Finalize creation: persist the temporary definition and create the actual
|
|
624
|
+
* agent instance. Returns the final agent instance ID, or null on failure.
|
|
625
|
+
*/
|
|
626
|
+
async finalize() {
|
|
627
|
+
if (!this.state.temporaryAgentDefinition) return null;
|
|
628
|
+
try {
|
|
629
|
+
const definition = await this.options.definitionRepository.createAgentDef(
|
|
630
|
+
this.state.temporaryAgentDefinition
|
|
631
|
+
);
|
|
632
|
+
const instance = await this.options.agentInstanceClient.createAgent(definition.id);
|
|
633
|
+
return instance.id;
|
|
634
|
+
} catch {
|
|
635
|
+
return null;
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
/** Clean up temporary resources. */
|
|
639
|
+
async cleanup() {
|
|
640
|
+
if (this.state.previewAgentId) {
|
|
641
|
+
try {
|
|
642
|
+
await this.options.agentInstanceClient.deleteAgent(this.state.previewAgentId);
|
|
643
|
+
} catch {
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
// ── Subscription ──────────────────────────────────────────────
|
|
648
|
+
subscribe(listener) {
|
|
649
|
+
this.listener = listener;
|
|
650
|
+
listener({ ...this.state });
|
|
651
|
+
return () => {
|
|
652
|
+
if (this.listener === listener) this.listener = null;
|
|
653
|
+
};
|
|
654
|
+
}
|
|
655
|
+
getState() {
|
|
656
|
+
return this.state;
|
|
657
|
+
}
|
|
658
|
+
// ── Private ───────────────────────────────────────────────────
|
|
659
|
+
emit(change) {
|
|
660
|
+
this.state = { ...this.state, ...change };
|
|
661
|
+
this.listener?.({ ...this.state });
|
|
662
|
+
}
|
|
663
|
+
};
|
|
664
|
+
|
|
665
|
+
// src/agent-management/PromptPreviewController.ts
|
|
666
|
+
var PromptPreviewController = class {
|
|
667
|
+
options;
|
|
668
|
+
listener = null;
|
|
669
|
+
state = {
|
|
670
|
+
open: false,
|
|
671
|
+
baseMode: "preview",
|
|
672
|
+
activeTab: "tree",
|
|
673
|
+
loading: false,
|
|
674
|
+
progress: 0,
|
|
675
|
+
currentStep: "",
|
|
676
|
+
currentPlugin: null,
|
|
677
|
+
result: null,
|
|
678
|
+
lastUpdated: null,
|
|
679
|
+
formFieldsToScrollTo: []
|
|
680
|
+
};
|
|
681
|
+
constructor(options) {
|
|
682
|
+
this.options = options;
|
|
683
|
+
}
|
|
684
|
+
/** Open the dialog with an optional base mode. */
|
|
685
|
+
open(baseMode) {
|
|
686
|
+
this.state = {
|
|
687
|
+
...this.state,
|
|
688
|
+
open: true,
|
|
689
|
+
baseMode: baseMode ?? "preview",
|
|
690
|
+
loading: false,
|
|
691
|
+
progress: 0,
|
|
692
|
+
currentStep: "Starting...",
|
|
693
|
+
currentPlugin: null,
|
|
694
|
+
result: null,
|
|
695
|
+
lastUpdated: null,
|
|
696
|
+
formFieldsToScrollTo: []
|
|
697
|
+
};
|
|
698
|
+
this.emit();
|
|
699
|
+
}
|
|
700
|
+
/** Close the dialog. */
|
|
701
|
+
close() {
|
|
702
|
+
this.state = {
|
|
703
|
+
...this.state,
|
|
704
|
+
open: false,
|
|
705
|
+
baseMode: "preview",
|
|
706
|
+
lastUpdated: null,
|
|
707
|
+
formFieldsToScrollTo: []
|
|
708
|
+
};
|
|
709
|
+
this.emit();
|
|
710
|
+
}
|
|
711
|
+
/** Set the active tab in the dialog. */
|
|
712
|
+
setActiveTab(tab) {
|
|
713
|
+
this.state = { ...this.state, activeTab: tab };
|
|
714
|
+
this.emit();
|
|
715
|
+
}
|
|
716
|
+
/** Set form fields to scroll to (for edit mode navigation). */
|
|
717
|
+
setFormFieldsToScrollTo(fieldPaths) {
|
|
718
|
+
this.state = { ...this.state, formFieldsToScrollTo: fieldPaths };
|
|
719
|
+
this.emit();
|
|
720
|
+
}
|
|
721
|
+
/**
|
|
722
|
+
* Generate a preview of the prompt tree.
|
|
723
|
+
* @param agentFrameworkConfig The agent's framework configuration
|
|
724
|
+
* @param messages Current conversation messages
|
|
725
|
+
* @param inputText Optional input text to include in the preview
|
|
726
|
+
*/
|
|
727
|
+
async generate(agentFrameworkConfig, messages, inputText) {
|
|
728
|
+
this.state = {
|
|
729
|
+
...this.state,
|
|
730
|
+
loading: true,
|
|
731
|
+
progress: 0,
|
|
732
|
+
currentStep: "Preparing..."
|
|
733
|
+
};
|
|
734
|
+
this.emit();
|
|
735
|
+
try {
|
|
736
|
+
const result = await this.options.previewClient.generatePreview(
|
|
737
|
+
agentFrameworkConfig,
|
|
738
|
+
messages,
|
|
739
|
+
inputText,
|
|
740
|
+
(progress) => {
|
|
741
|
+
this.state = {
|
|
742
|
+
...this.state,
|
|
743
|
+
progress: progress.progress,
|
|
744
|
+
currentStep: progress.step,
|
|
745
|
+
currentPlugin: progress.currentPlugin ?? null
|
|
746
|
+
};
|
|
747
|
+
this.emit();
|
|
748
|
+
}
|
|
749
|
+
);
|
|
750
|
+
this.state = {
|
|
751
|
+
...this.state,
|
|
752
|
+
loading: false,
|
|
753
|
+
progress: 1,
|
|
754
|
+
currentStep: "Complete",
|
|
755
|
+
currentPlugin: null,
|
|
756
|
+
result,
|
|
757
|
+
lastUpdated: /* @__PURE__ */ new Date()
|
|
758
|
+
};
|
|
759
|
+
this.emit();
|
|
760
|
+
return result;
|
|
761
|
+
} catch {
|
|
762
|
+
this.state = {
|
|
763
|
+
...this.state,
|
|
764
|
+
loading: false,
|
|
765
|
+
progress: 0,
|
|
766
|
+
currentStep: "Error occurred",
|
|
767
|
+
currentPlugin: null,
|
|
768
|
+
result: null
|
|
769
|
+
};
|
|
770
|
+
this.emit();
|
|
771
|
+
return null;
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
// ── Subscription ──────────────────────────────────────────────
|
|
775
|
+
subscribe(listener) {
|
|
776
|
+
this.listener = listener;
|
|
777
|
+
listener({ ...this.state });
|
|
778
|
+
return () => {
|
|
779
|
+
if (this.listener === listener) this.listener = null;
|
|
780
|
+
};
|
|
781
|
+
}
|
|
782
|
+
getState() {
|
|
783
|
+
return this.state;
|
|
784
|
+
}
|
|
785
|
+
// ── Private ───────────────────────────────────────────────────
|
|
786
|
+
emit() {
|
|
787
|
+
this.listener?.({ ...this.state });
|
|
788
|
+
}
|
|
789
|
+
};
|
|
790
|
+
|
|
791
|
+
export {
|
|
792
|
+
TiddlyWikiHttpStorage,
|
|
793
|
+
AgentSessionController,
|
|
794
|
+
AgentDefinitionEditorController,
|
|
795
|
+
AgentCreationController,
|
|
796
|
+
PromptPreviewController
|
|
797
|
+
};
|
|
798
|
+
//# sourceMappingURL=chunk-YMNXDNDW.js.map
|