@pasko70/pibo 2.2.2 → 2.2.4
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/dist/agent-runtimes/omp/host-tools.js +1 -1
- package/dist/apps/chat/agent-store.js +84 -3
- package/dist/apps/chat/chat-api-routes.js +14 -0
- package/dist/apps/chat/chat-request-normalizers.js +27 -0
- package/dist/apps/chat/web-app.js +58 -2
- package/dist/apps/chat-ui/assets/{dist-ogVF1MMz.js → dist-BFwTuvyi.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-I3spUe7o.js → dist-CImWCF2M.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-DrthHok7.js → dist-ltfz1vFX.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-CbM7-718.js → dist-luJVFsmq.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-CvCbmtlu.js → dist-rf4HYdoa.js} +1 -1
- package/dist/apps/chat-ui/assets/index-D2Maa2v1.js +226 -0
- package/dist/apps/chat-ui/assets/index-nZQXUpxE.css +1 -0
- package/dist/apps/chat-ui/index.html +2 -2
- package/dist/apps/chat-vscode-web/assets/{index-C0sMILFt.js → index-BpurWVnX.js} +1 -1
- package/dist/apps/chat-vscode-web/index.html +1 -1
- package/dist/apps/vscode-artifacts/latest.vsix +0 -0
- package/dist/apps/vscode-artifacts/pibo-vscode-ext-2.2.4.vsix +0 -0
- package/dist/core/session-router.js +1 -1
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
- package/dist/apps/chat-ui/assets/index-CI_vSx9U.js +0 -226
- package/dist/apps/chat-ui/assets/index-QkfBrh9Q.css +0 -1
- package/dist/apps/vscode-artifacts/pibo-vscode-ext-2.2.2.vsix +0 -0
|
@@ -90,7 +90,7 @@ export class OmpHostToolBridge {
|
|
|
90
90
|
wire.push({
|
|
91
91
|
name: def.name,
|
|
92
92
|
description: typeof def.description === "string" ? def.description : "",
|
|
93
|
-
|
|
93
|
+
parameters: toolInputSchema(def),
|
|
94
94
|
});
|
|
95
95
|
}
|
|
96
96
|
const result = await this.client.request({ type: "set_host_tools", tools: wire }, "set_host_tools");
|
|
@@ -15,6 +15,7 @@ export function previewCustomAgentCreate(input, options = {}) {
|
|
|
15
15
|
profileName: input.displayName,
|
|
16
16
|
displayName: input.displayName,
|
|
17
17
|
profileAliases: [],
|
|
18
|
+
folderId: input.folderId,
|
|
18
19
|
description: input.description,
|
|
19
20
|
runtimeInstanceId: sanitizeRuntimeInstanceId(input.runtimeInstanceId),
|
|
20
21
|
runtimeOptions: cloneRuntimeOptions(input.runtimeOptions),
|
|
@@ -48,6 +49,7 @@ export function previewCustomAgentUpdate(existing, input, options = {}) {
|
|
|
48
49
|
...existing,
|
|
49
50
|
profileName,
|
|
50
51
|
displayName: input.displayName ?? existing.displayName,
|
|
52
|
+
folderId: input.folderId === undefined ? existing.folderId : input.folderId ?? undefined,
|
|
51
53
|
description: input.description === undefined ? existing.description : input.description,
|
|
52
54
|
runtimeInstanceId: input.runtimeInstanceId === undefined ? existing.runtimeInstanceId : sanitizeRuntimeInstanceId(input.runtimeInstanceId),
|
|
53
55
|
runtimeOptions: input.runtimeOptions === undefined ? existing.runtimeOptions : cloneRuntimeOptions(input.runtimeOptions),
|
|
@@ -88,11 +90,19 @@ export class CustomAgentStore {
|
|
|
88
90
|
if (resolvedPath !== ":memory:")
|
|
89
91
|
this.db.exec("PRAGMA journal_mode = WAL");
|
|
90
92
|
this.db.exec(`
|
|
93
|
+
CREATE TABLE IF NOT EXISTS chat_agent_folders (
|
|
94
|
+
id TEXT PRIMARY KEY,
|
|
95
|
+
name TEXT NOT NULL COLLATE NOCASE UNIQUE,
|
|
96
|
+
created_at TEXT NOT NULL,
|
|
97
|
+
updated_at TEXT NOT NULL
|
|
98
|
+
);
|
|
99
|
+
|
|
91
100
|
CREATE TABLE IF NOT EXISTS chat_agents (
|
|
92
101
|
id TEXT PRIMARY KEY,
|
|
93
102
|
profile_name TEXT NOT NULL UNIQUE,
|
|
94
103
|
display_name TEXT NOT NULL,
|
|
95
104
|
description TEXT,
|
|
105
|
+
folder_id TEXT REFERENCES chat_agent_folders(id) ON DELETE SET NULL,
|
|
96
106
|
runtime_instance_id TEXT NOT NULL DEFAULT 'pi',
|
|
97
107
|
runtime_options_json TEXT NOT NULL DEFAULT '{}',
|
|
98
108
|
native_subagents INTEGER,
|
|
@@ -121,6 +131,7 @@ export class CustomAgentStore {
|
|
|
121
131
|
);
|
|
122
132
|
|
|
123
133
|
`);
|
|
134
|
+
this.migrateAgentFolderColumn();
|
|
124
135
|
this.migrateProfileAliasTable();
|
|
125
136
|
this.migrateArchivedAtColumn();
|
|
126
137
|
this.migrateAutoContextFilesColumn();
|
|
@@ -137,6 +148,38 @@ export class CustomAgentStore {
|
|
|
137
148
|
this.migrateLegacyProfileNames();
|
|
138
149
|
this.migrateDuplicateProfileNames();
|
|
139
150
|
}
|
|
151
|
+
listFolders() {
|
|
152
|
+
const rows = this.db.prepare("SELECT * FROM chat_agent_folders ORDER BY name COLLATE NOCASE ASC, created_at ASC").all();
|
|
153
|
+
return rows.map(folderFromRow);
|
|
154
|
+
}
|
|
155
|
+
getFolder(id) {
|
|
156
|
+
const row = this.db.prepare("SELECT * FROM chat_agent_folders WHERE id = ?").get(id);
|
|
157
|
+
return row ? folderFromRow(row) : undefined;
|
|
158
|
+
}
|
|
159
|
+
createFolder(name) {
|
|
160
|
+
const normalizedName = normalizeCustomAgentFolderName(name);
|
|
161
|
+
this.requireFolderNameAvailable(normalizedName);
|
|
162
|
+
const now = new Date().toISOString();
|
|
163
|
+
const id = `agent_folder_${randomUUID()}`;
|
|
164
|
+
this.db.prepare("INSERT INTO chat_agent_folders (id, name, created_at, updated_at) VALUES (?, ?, ?, ?)").run(id, normalizedName, now, now);
|
|
165
|
+
return this.getFolder(id);
|
|
166
|
+
}
|
|
167
|
+
renameFolder(id, name) {
|
|
168
|
+
const existing = this.getFolder(id);
|
|
169
|
+
if (!existing)
|
|
170
|
+
return undefined;
|
|
171
|
+
const normalizedName = normalizeCustomAgentFolderName(name);
|
|
172
|
+
this.requireFolderNameAvailable(normalizedName, id);
|
|
173
|
+
this.db.prepare("UPDATE chat_agent_folders SET name = ?, updated_at = ? WHERE id = ?").run(normalizedName, new Date().toISOString(), id);
|
|
174
|
+
return this.getFolder(id);
|
|
175
|
+
}
|
|
176
|
+
deleteFolder(id) {
|
|
177
|
+
const assigned = this.db.prepare("SELECT COUNT(*) AS count FROM chat_agents WHERE folder_id = ?").get(id);
|
|
178
|
+
if (assigned.count > 0)
|
|
179
|
+
throw new Error("Move agents out of this folder before deleting it");
|
|
180
|
+
const result = this.db.prepare("DELETE FROM chat_agent_folders WHERE id = ?").run(id);
|
|
181
|
+
return Number(result.changes ?? 0) > 0;
|
|
182
|
+
}
|
|
140
183
|
list(options = {}) {
|
|
141
184
|
this.migrateLegacyProfileNames();
|
|
142
185
|
this.migrateDuplicateProfileNames();
|
|
@@ -153,6 +196,7 @@ export class CustomAgentStore {
|
|
|
153
196
|
create(input) {
|
|
154
197
|
this.migrateLegacyProfileNames();
|
|
155
198
|
this.requireProfileNameAvailable(input.displayName);
|
|
199
|
+
this.requireFolderExists(input.folderId);
|
|
156
200
|
const agent = previewCustomAgentCreate(input);
|
|
157
201
|
this.insert(agent);
|
|
158
202
|
const created = this.get(agent.id);
|
|
@@ -167,6 +211,7 @@ export class CustomAgentStore {
|
|
|
167
211
|
return undefined;
|
|
168
212
|
const profileName = input.displayName ?? existing.displayName;
|
|
169
213
|
this.requireProfileNameAvailable(profileName, id);
|
|
214
|
+
this.requireFolderExists(input.folderId);
|
|
170
215
|
const updated = previewCustomAgentUpdate(existing, input);
|
|
171
216
|
this.db
|
|
172
217
|
.prepare(`
|
|
@@ -174,6 +219,7 @@ export class CustomAgentStore {
|
|
|
174
219
|
profile_name = ?,
|
|
175
220
|
display_name = ?,
|
|
176
221
|
description = ?,
|
|
222
|
+
folder_id = ?,
|
|
177
223
|
runtime_instance_id = ?,
|
|
178
224
|
runtime_options_json = ?,
|
|
179
225
|
native_subagents = ?,
|
|
@@ -199,7 +245,7 @@ export class CustomAgentStore {
|
|
|
199
245
|
updated_at = ?
|
|
200
246
|
WHERE id = ?
|
|
201
247
|
`)
|
|
202
|
-
.run(updated.profileName, updated.displayName, updated.description ?? null, updated.runtimeInstanceId, JSON.stringify(updated.runtimeOptions), serializeBoolean(updated.nativeSubagents), JSON.stringify(updated.nativeTools), JSON.stringify(updated.skills), JSON.stringify(updated.contextFiles), JSON.stringify(sanitizeSubagents(updated.subagents)), JSON.stringify(updated.mcpServers), JSON.stringify(updated.piPackages), updated.mainModel ? JSON.stringify(updated.mainModel) : null, updated.subagentModel ? JSON.stringify(updated.subagentModel) : null, updated.thinkingLevel ?? null, updated.mainThinkingLevel ?? null, updated.subagentThinkingLevel ?? null, serializeBoolean(updated.fast), serializeBoolean(updated.mainFast), serializeBoolean(updated.subagentFast), updated.builtinTools, JSON.stringify(updated.builtinToolNames), updated.autoContextFiles ? 1 : 0, updated.runControl ? 1 : 0, updated.goalControl ? 1 : 0, updated.updatedAt, id);
|
|
248
|
+
.run(updated.profileName, updated.displayName, updated.description ?? null, updated.folderId ?? null, updated.runtimeInstanceId, JSON.stringify(updated.runtimeOptions), serializeBoolean(updated.nativeSubagents), JSON.stringify(updated.nativeTools), JSON.stringify(updated.skills), JSON.stringify(updated.contextFiles), JSON.stringify(sanitizeSubagents(updated.subagents)), JSON.stringify(updated.mcpServers), JSON.stringify(updated.piPackages), updated.mainModel ? JSON.stringify(updated.mainModel) : null, updated.subagentModel ? JSON.stringify(updated.subagentModel) : null, updated.thinkingLevel ?? null, updated.mainThinkingLevel ?? null, updated.subagentThinkingLevel ?? null, serializeBoolean(updated.fast), serializeBoolean(updated.mainFast), serializeBoolean(updated.subagentFast), updated.builtinTools, JSON.stringify(updated.builtinToolNames), updated.autoContextFiles ? 1 : 0, updated.runControl ? 1 : 0, updated.goalControl ? 1 : 0, updated.updatedAt, id);
|
|
203
249
|
return this.get(id);
|
|
204
250
|
}
|
|
205
251
|
setArchived(id, archived) {
|
|
@@ -229,6 +275,7 @@ export class CustomAgentStore {
|
|
|
229
275
|
profile_name,
|
|
230
276
|
display_name,
|
|
231
277
|
description,
|
|
278
|
+
folder_id,
|
|
232
279
|
runtime_instance_id,
|
|
233
280
|
runtime_options_json,
|
|
234
281
|
native_subagents,
|
|
@@ -254,9 +301,20 @@ export class CustomAgentStore {
|
|
|
254
301
|
created_at,
|
|
255
302
|
updated_at,
|
|
256
303
|
archived_at
|
|
257
|
-
) VALUES (${Array.from({ length:
|
|
304
|
+
) VALUES (${Array.from({ length: 30 }, () => "?").join(", ")})
|
|
258
305
|
`)
|
|
259
|
-
.run(agent.id, agent.profileName, agent.displayName, agent.description ?? null, agent.runtimeInstanceId, JSON.stringify(agent.runtimeOptions), serializeBoolean(agent.nativeSubagents), JSON.stringify(agent.nativeTools), JSON.stringify(agent.skills), JSON.stringify(agent.contextFiles), JSON.stringify(sanitizeSubagents(agent.subagents)), JSON.stringify(agent.mcpServers), JSON.stringify(agent.piPackages), agent.mainModel ? JSON.stringify(agent.mainModel) : null, agent.subagentModel ? JSON.stringify(agent.subagentModel) : null, agent.thinkingLevel ?? null, agent.mainThinkingLevel ?? null, agent.subagentThinkingLevel ?? null, serializeBoolean(agent.fast), serializeBoolean(agent.mainFast), serializeBoolean(agent.subagentFast), agent.builtinTools, JSON.stringify(agent.builtinToolNames), agent.autoContextFiles ? 1 : 0, agent.runControl ? 1 : 0, agent.goalControl ? 1 : 0, agent.createdAt, agent.updatedAt, agent.archivedAt ?? null);
|
|
306
|
+
.run(agent.id, agent.profileName, agent.displayName, agent.description ?? null, agent.folderId ?? null, agent.runtimeInstanceId, JSON.stringify(agent.runtimeOptions), serializeBoolean(agent.nativeSubagents), JSON.stringify(agent.nativeTools), JSON.stringify(agent.skills), JSON.stringify(agent.contextFiles), JSON.stringify(sanitizeSubagents(agent.subagents)), JSON.stringify(agent.mcpServers), JSON.stringify(agent.piPackages), agent.mainModel ? JSON.stringify(agent.mainModel) : null, agent.subagentModel ? JSON.stringify(agent.subagentModel) : null, agent.thinkingLevel ?? null, agent.mainThinkingLevel ?? null, agent.subagentThinkingLevel ?? null, serializeBoolean(agent.fast), serializeBoolean(agent.mainFast), serializeBoolean(agent.subagentFast), agent.builtinTools, JSON.stringify(agent.builtinToolNames), agent.autoContextFiles ? 1 : 0, agent.runControl ? 1 : 0, agent.goalControl ? 1 : 0, agent.createdAt, agent.updatedAt, agent.archivedAt ?? null);
|
|
307
|
+
}
|
|
308
|
+
requireFolderExists(folderId) {
|
|
309
|
+
if (folderId === undefined || folderId === null)
|
|
310
|
+
return;
|
|
311
|
+
if (!this.getFolder(folderId))
|
|
312
|
+
throw new Error(`Agent folder "${folderId}" does not exist`);
|
|
313
|
+
}
|
|
314
|
+
requireFolderNameAvailable(name, currentId) {
|
|
315
|
+
const row = this.db.prepare("SELECT id FROM chat_agent_folders WHERE name = ? COLLATE NOCASE").get(name);
|
|
316
|
+
if (row && row.id !== currentId)
|
|
317
|
+
throw new Error(`Agent folder "${name}" already exists`);
|
|
260
318
|
}
|
|
261
319
|
requireProfileNameAvailable(profileName, currentId) {
|
|
262
320
|
const row = this.db.prepare("SELECT id FROM chat_agents WHERE profile_name = ?").get(profileName);
|
|
@@ -306,6 +364,12 @@ export class CustomAgentStore {
|
|
|
306
364
|
.run(nextName, nextName, row.id);
|
|
307
365
|
}
|
|
308
366
|
}
|
|
367
|
+
migrateAgentFolderColumn() {
|
|
368
|
+
if (!this.tableColumns().has("folder_id")) {
|
|
369
|
+
this.db.prepare("ALTER TABLE chat_agents ADD COLUMN folder_id TEXT REFERENCES chat_agent_folders(id) ON DELETE SET NULL").run();
|
|
370
|
+
}
|
|
371
|
+
this.db.exec("CREATE INDEX IF NOT EXISTS chat_agents_folder_id_idx ON chat_agents(folder_id)");
|
|
372
|
+
}
|
|
309
373
|
migrateProfileAliasTable() {
|
|
310
374
|
this.db.exec(`
|
|
311
375
|
CREATE TABLE IF NOT EXISTS chat_agent_profile_aliases (
|
|
@@ -573,6 +637,7 @@ function agentFromRow(row, profileAliases) {
|
|
|
573
637
|
profileName: row.profile_name,
|
|
574
638
|
displayName: row.display_name,
|
|
575
639
|
profileAliases: profileAliases.filter((alias) => alias !== row.profile_name),
|
|
640
|
+
folderId: row.folder_id ?? undefined,
|
|
576
641
|
description: row.description ?? undefined,
|
|
577
642
|
runtimeInstanceId: sanitizeRuntimeInstanceId(row.runtime_instance_id),
|
|
578
643
|
runtimeOptions: parseRuntimeOptions(row.runtime_options_json),
|
|
@@ -601,6 +666,22 @@ function agentFromRow(row, profileAliases) {
|
|
|
601
666
|
archivedAt: row.archived_at ?? undefined,
|
|
602
667
|
};
|
|
603
668
|
}
|
|
669
|
+
function folderFromRow(row) {
|
|
670
|
+
return {
|
|
671
|
+
id: row.id,
|
|
672
|
+
name: row.name,
|
|
673
|
+
createdAt: row.created_at,
|
|
674
|
+
updatedAt: row.updated_at,
|
|
675
|
+
};
|
|
676
|
+
}
|
|
677
|
+
export function normalizeCustomAgentFolderName(value) {
|
|
678
|
+
const name = value.replace(/\s+/g, " ").trim();
|
|
679
|
+
if (!name)
|
|
680
|
+
throw new Error("Agent folder name is required");
|
|
681
|
+
if (name.length > 80)
|
|
682
|
+
throw new Error("Agent folder name is too long");
|
|
683
|
+
return name;
|
|
684
|
+
}
|
|
604
685
|
function parseStringArray(value) {
|
|
605
686
|
try {
|
|
606
687
|
const parsed = JSON.parse(value);
|
|
@@ -21,6 +21,20 @@ export function roomResourcePath(pathname) {
|
|
|
21
21
|
throw new PiboWebHttpError("Invalid room id", 400);
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
|
+
export function agentFolderResourceId(pathname) {
|
|
25
|
+
const prefix = `${CHAT_WEB_API_PREFIX}/agent-folders/`;
|
|
26
|
+
if (!pathname.startsWith(prefix))
|
|
27
|
+
return undefined;
|
|
28
|
+
const encodedId = pathname.slice(prefix.length);
|
|
29
|
+
if (!encodedId || encodedId.includes("/"))
|
|
30
|
+
return undefined;
|
|
31
|
+
try {
|
|
32
|
+
return decodeURIComponent(encodedId);
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
throw new PiboWebHttpError("Invalid agent folder id", 400);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
24
38
|
export function agentResourceId(pathname) {
|
|
25
39
|
const prefix = `${CHAT_WEB_API_PREFIX}/agents/`;
|
|
26
40
|
if (!pathname.startsWith(prefix))
|
|
@@ -116,6 +116,30 @@ export function normalizeAgentDisplayName(value, fallback = "new-agent") {
|
|
|
116
116
|
}
|
|
117
117
|
return name;
|
|
118
118
|
}
|
|
119
|
+
export function normalizeAgentFolderName(value) {
|
|
120
|
+
if (typeof value !== "string")
|
|
121
|
+
throw new PiboWebHttpError("Agent folder name must be a string", 400);
|
|
122
|
+
const name = value.replace(/\s+/g, " ").trim();
|
|
123
|
+
if (!name)
|
|
124
|
+
throw new PiboWebHttpError("Agent folder name is required", 400);
|
|
125
|
+
if (name.length > 80)
|
|
126
|
+
throw new PiboWebHttpError("Agent folder name is too long", 400);
|
|
127
|
+
return name;
|
|
128
|
+
}
|
|
129
|
+
export function normalizeAgentFolderId(value) {
|
|
130
|
+
if (value === undefined)
|
|
131
|
+
return undefined;
|
|
132
|
+
if (value === null || value === "")
|
|
133
|
+
return null;
|
|
134
|
+
if (typeof value !== "string")
|
|
135
|
+
throw new PiboWebHttpError("Agent folder id must be a string", 400);
|
|
136
|
+
const folderId = value.trim();
|
|
137
|
+
if (!folderId)
|
|
138
|
+
return null;
|
|
139
|
+
if (folderId.length > 160)
|
|
140
|
+
throw new PiboWebHttpError("Agent folder id is too long", 400);
|
|
141
|
+
return folderId;
|
|
142
|
+
}
|
|
119
143
|
export function normalizeAgentDescription(value) {
|
|
120
144
|
if (value === undefined || value === null)
|
|
121
145
|
return undefined;
|
|
@@ -661,6 +685,7 @@ export function createAgentInput(body) {
|
|
|
661
685
|
return {
|
|
662
686
|
displayName: normalizeAgentDisplayName(body.displayName),
|
|
663
687
|
description: normalizeAgentDescription(body.description),
|
|
688
|
+
folderId: normalizeAgentFolderId(body.folderId) ?? undefined,
|
|
664
689
|
runtimeInstanceId: normalizeAgentRuntimeInstanceId(body.runtimeInstanceId),
|
|
665
690
|
runtimeOptions: normalizeAgentRuntimeOptions(body.runtimeOptions),
|
|
666
691
|
nativeSubagents: normalizeNativeSubagents(body.nativeSubagents),
|
|
@@ -691,6 +716,8 @@ export function createAgentUpdate(body) {
|
|
|
691
716
|
update.displayName = normalizeAgentDisplayName(body.displayName);
|
|
692
717
|
if (body.description !== undefined)
|
|
693
718
|
update.description = normalizeAgentDescription(body.description);
|
|
719
|
+
if (body.folderId !== undefined)
|
|
720
|
+
update.folderId = normalizeAgentFolderId(body.folderId);
|
|
694
721
|
if (body.runtimeInstanceId !== undefined)
|
|
695
722
|
update.runtimeInstanceId = normalizeAgentRuntimeInstanceId(body.runtimeInstanceId);
|
|
696
723
|
if (body.runtimeOptions !== undefined)
|
|
@@ -50,8 +50,8 @@ import { ensurePrivateChatUploadDirectory, prepareChatFileAttachments, resolveDo
|
|
|
50
50
|
import { chatSettingsRoute, chatSettingsRouteInvalidatesBootstrapCatalog, chatSettingsRouteRequiresSameOrigin, handleChatSettingsRoute, } from "./chat-settings-routes.js";
|
|
51
51
|
import { chatCapabilityRoute, chatCapabilityRouteRequiresSameOrigin, handleChatCapabilityRoute, } from "./chat-capability-routes.js";
|
|
52
52
|
import { chatUserSkillRoute, chatUserSkillRouteRequiresSameOrigin, handleChatUserSkillRoute, syncChatUserSkills, } from "./chat-user-skill-routes.js";
|
|
53
|
-
import { CHAT_WEB_API_PREFIX, agentResourceId, projectResourcePath, projectSessionResourceId, projectWorkflowHumanActionsResource, projectWorkflowSessionStartResource, roomResourcePath, sessionActionResource, sessionResourceId, signalResource, workflowArchiveResourceId, workflowCatalogResourceId, workflowDraftActionResource, workflowDraftManualTriggerRunResource, workflowDraftResourceId, workflowDuplicateResourceId, workflowNextDraftResourceId, workflowPickerKind, workflowPromptAssetResourceId, workflowVersionResource, } from "./chat-api-routes.js";
|
|
54
|
-
import { assertProjectSessionPatchFields, buildStreamingFixtureSchedule, createAgentInput, createAgentUpdate, createRoomUpdate, createSessionUpdate, normalizeAgentArchived, normalizeClientTxnId, normalizeMessageDelivery, normalizeMessageText, normalizeParentRoomId, normalizeProjectArchived, normalizeProjectDescription, normalizeProjectPath, normalizeProjectSessionArchived, normalizeRoomDeleteConfirmation, normalizeRoomName, normalizeRoomTopic, normalizeRoomType, normalizeRoomWorkspace, normalizeSessionDeleteConfirmation, normalizeSessionTitle, normalizeStreamingFixtureCadenceMs, normalizeStreamingFixtureDeltas, normalizeStreamingFixtureMix, normalizeStreamingFixturePreludeMessages, normalizeStreamingFixturePreludeOnly, normalizeStreamingFixtureProfile, normalizeStreamingFixtureSuppressLiveDeltas, normalizeStreamingFixtureTraceSnapshots, resolveCreateSessionProfile, } from "./chat-request-normalizers.js";
|
|
53
|
+
import { CHAT_WEB_API_PREFIX, agentFolderResourceId, agentResourceId, projectResourcePath, projectSessionResourceId, projectWorkflowHumanActionsResource, projectWorkflowSessionStartResource, roomResourcePath, sessionActionResource, sessionResourceId, signalResource, workflowArchiveResourceId, workflowCatalogResourceId, workflowDraftActionResource, workflowDraftManualTriggerRunResource, workflowDraftResourceId, workflowDuplicateResourceId, workflowNextDraftResourceId, workflowPickerKind, workflowPromptAssetResourceId, workflowVersionResource, } from "./chat-api-routes.js";
|
|
54
|
+
import { assertProjectSessionPatchFields, buildStreamingFixtureSchedule, createAgentInput, createAgentUpdate, createRoomUpdate, createSessionUpdate, normalizeAgentArchived, normalizeAgentFolderName, normalizeClientTxnId, normalizeMessageDelivery, normalizeMessageText, normalizeParentRoomId, normalizeProjectArchived, normalizeProjectDescription, normalizeProjectPath, normalizeProjectSessionArchived, normalizeRoomDeleteConfirmation, normalizeRoomName, normalizeRoomTopic, normalizeRoomType, normalizeRoomWorkspace, normalizeSessionDeleteConfirmation, normalizeSessionTitle, normalizeStreamingFixtureCadenceMs, normalizeStreamingFixtureDeltas, normalizeStreamingFixtureMix, normalizeStreamingFixturePreludeMessages, normalizeStreamingFixturePreludeOnly, normalizeStreamingFixtureProfile, normalizeStreamingFixtureSuppressLiveDeltas, normalizeStreamingFixtureTraceSnapshots, resolveCreateSessionProfile, } from "./chat-request-normalizers.js";
|
|
55
55
|
import { ChatWorkflowArchiveStore, ChatWorkflowDraftStore, ChatWorkflowLifecycleEventStore, ChatWorkflowPromptAssetStore, ChatWorkflowPublishedVersionStore, ChatWorkflowTombstoneStore, hashWorkflowDefinitionJson, normalizeWorkflowPromptAssetLabel, sanitizeWorkflowDiagnostics, } from "./workflow-persistence.js";
|
|
56
56
|
import { normalizeProjectWorkflowHumanActionBody, projectWorkflowHumanActionDiagnosticResponse, projectWorkflowHumanActionLifecyclePayload, projectWorkflowHumanActionRuntimeDiagnostic, projectWorkflowHumanActionSubmittedLifecyclePayload, projectWorkflowPendingHumanActionFromToken, validateProjectWorkflowHumanActionRequest, } from "./project-workflow-human-actions.js";
|
|
57
57
|
import { createProjectWorkflowRunCurrent, createProjectWorkflowSessionSnapshot, normalizeProjectWorkflowSessionConfiguration, workflowVersionFromSnapshot, } from "./project-workflow-sessions.js";
|
|
@@ -81,6 +81,7 @@ function loadBootstrapCatalog(state, context, webSession) {
|
|
|
81
81
|
]).then(([modelCatalog, agentCatalog]) => ({
|
|
82
82
|
agents: context.channelContext.getProfiles?.() ?? [],
|
|
83
83
|
customAgents: serializeCustomAgents(state.agentStore.list({ includeArchived: true }), context),
|
|
84
|
+
agentFolders: state.agentStore.listFolders(),
|
|
84
85
|
modelDefaults: loadChatModelDefaults(process.cwd()),
|
|
85
86
|
modelCatalog,
|
|
86
87
|
agentCatalog,
|
|
@@ -904,6 +905,22 @@ function serializeCustomAgent(agent, context) {
|
|
|
904
905
|
function serializeCustomAgents(agents, context) {
|
|
905
906
|
return agents.map((agent) => serializeCustomAgent(agent, context));
|
|
906
907
|
}
|
|
908
|
+
function requireAgentFolder(state, folderId) {
|
|
909
|
+
const folder = state.agentStore.getFolder(folderId);
|
|
910
|
+
if (!folder)
|
|
911
|
+
throw new PiboWebHttpError("Agent folder not found", 404);
|
|
912
|
+
return folder;
|
|
913
|
+
}
|
|
914
|
+
function requireAgentFolderNameAvailable(state, name, currentId) {
|
|
915
|
+
const conflict = state.agentStore.listFolders().find((folder) => folder.id !== currentId && folder.name.localeCompare(name, undefined, { sensitivity: "accent" }) === 0);
|
|
916
|
+
if (conflict)
|
|
917
|
+
throw new PiboWebHttpError(`Agent folder "${name}" already exists`, 409);
|
|
918
|
+
}
|
|
919
|
+
function requireAgentFolderAssignmentAvailable(state, folderId) {
|
|
920
|
+
if (!folderId)
|
|
921
|
+
return;
|
|
922
|
+
requireAgentFolder(state, folderId);
|
|
923
|
+
}
|
|
907
924
|
const RUNTIME_PROFILE_UPDATE_FIELDS = new Set([
|
|
908
925
|
"runtimeInstanceId",
|
|
909
926
|
"runtimeOptions",
|
|
@@ -4280,6 +4297,43 @@ export function createChatWebApp(options = {}) {
|
|
|
4280
4297
|
invalidateBootstrapCatalogCache: () => invalidateBootstrapCatalogCache(state),
|
|
4281
4298
|
});
|
|
4282
4299
|
}
|
|
4300
|
+
if (url.pathname === `${CHAT_WEB_API_PREFIX}/agent-folders` && request.method === "GET") {
|
|
4301
|
+
await requireSession(request, context);
|
|
4302
|
+
return responseJson({ folders: state.agentStore.listFolders() });
|
|
4303
|
+
}
|
|
4304
|
+
if (url.pathname === `${CHAT_WEB_API_PREFIX}/agent-folders` && request.method === "POST") {
|
|
4305
|
+
requireSameOriginJsonRequest(request);
|
|
4306
|
+
await requireSession(request, context);
|
|
4307
|
+
const body = await readJsonBody(request);
|
|
4308
|
+
const name = normalizeAgentFolderName(body.name);
|
|
4309
|
+
requireAgentFolderNameAvailable(state, name);
|
|
4310
|
+
const folder = state.agentStore.createFolder(name);
|
|
4311
|
+
invalidateBootstrapCatalogCache(state);
|
|
4312
|
+
return responseJson({ folder }, { status: 201 });
|
|
4313
|
+
}
|
|
4314
|
+
const patchAgentFolderId = agentFolderResourceId(url.pathname);
|
|
4315
|
+
if (patchAgentFolderId && request.method === "PATCH") {
|
|
4316
|
+
requireSameOriginJsonRequest(request);
|
|
4317
|
+
await requireSession(request, context);
|
|
4318
|
+
requireAgentFolder(state, patchAgentFolderId);
|
|
4319
|
+
const body = await readJsonBody(request);
|
|
4320
|
+
const name = normalizeAgentFolderName(body.name);
|
|
4321
|
+
requireAgentFolderNameAvailable(state, name, patchAgentFolderId);
|
|
4322
|
+
const folder = state.agentStore.renameFolder(patchAgentFolderId, name);
|
|
4323
|
+
invalidateBootstrapCatalogCache(state);
|
|
4324
|
+
return responseJson({ folder: requireAgentFolder(state, folder?.id ?? patchAgentFolderId) });
|
|
4325
|
+
}
|
|
4326
|
+
if (patchAgentFolderId && request.method === "DELETE") {
|
|
4327
|
+
requireSameOriginJsonRequest(request);
|
|
4328
|
+
await requireSession(request, context);
|
|
4329
|
+
const folder = requireAgentFolder(state, patchAgentFolderId);
|
|
4330
|
+
const assignedAgent = state.agentStore.list({ includeArchived: true }).find((agent) => agent.folderId === folder.id);
|
|
4331
|
+
if (assignedAgent)
|
|
4332
|
+
throw new PiboWebHttpError("Move agents out of this folder before deleting it.", 409);
|
|
4333
|
+
state.agentStore.deleteFolder(folder.id);
|
|
4334
|
+
invalidateBootstrapCatalogCache(state);
|
|
4335
|
+
return responseJson({ deletedFolderId: folder.id });
|
|
4336
|
+
}
|
|
4283
4337
|
if (url.pathname === `${CHAT_WEB_API_PREFIX}/agents` && request.method === "GET") {
|
|
4284
4338
|
const webSession = await requireSession(request, context);
|
|
4285
4339
|
const includeArchived = parseBooleanSearchParam(url, "includeArchived");
|
|
@@ -4291,6 +4345,7 @@ export function createChatWebApp(options = {}) {
|
|
|
4291
4345
|
const body = await readJsonBody(request);
|
|
4292
4346
|
const input = normalizeCreateRuntimeFeatureOverrides(createAgentInput(body), context);
|
|
4293
4347
|
requireAgentProfileNameAvailable(state, context, input.displayName);
|
|
4348
|
+
requireAgentFolderAssignmentAvailable(state, input.folderId);
|
|
4294
4349
|
await requireValidCustomAgentRuntime(previewCustomAgentCreate(input), context);
|
|
4295
4350
|
const agent = state.agentStore.create(input);
|
|
4296
4351
|
context.channelContext.upsertProfile?.(createCustomAgentProfileDefinition(agent));
|
|
@@ -4308,6 +4363,7 @@ export function createChatWebApp(options = {}) {
|
|
|
4308
4363
|
const archived = normalizeAgentArchived(body.archived);
|
|
4309
4364
|
if (update.displayName)
|
|
4310
4365
|
requireAgentProfileNameAvailable(state, context, update.displayName, existing.id);
|
|
4366
|
+
requireAgentFolderAssignmentAvailable(state, update.folderId);
|
|
4311
4367
|
if (customAgentUpdateAffectsRuntime(update)) {
|
|
4312
4368
|
await requireValidCustomAgentRuntime(previewCustomAgentUpdate(existing, update), context);
|
|
4313
4369
|
}
|