@actalk/inkos-studio 1.6.1-canary.49.1 → 1.6.2
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/api/server.d.ts.map +1 -1
- package/dist/api/server.js +163 -3
- package/dist/api/server.js.map +1 -1
- package/dist/assets/{FilmWizard-DEDrqO5H.js → FilmWizard-C_1W4acq.js} +1 -1
- package/dist/assets/{FlowView-DUBkKiff.js → FlowView-DvrwPvo2.js} +1 -1
- package/dist/assets/{_baseUniq-DYxaUtZI.js → _baseUniq-B-ZYRDWx.js} +1 -1
- package/dist/assets/{arc-CHuRYqSh.js → arc-Ciw3FGtr.js} +1 -1
- package/dist/assets/{architectureDiagram-Q4EWVU46-BRVULDTV.js → architectureDiagram-Q4EWVU46-mC_rz2X6.js} +1 -1
- package/dist/assets/{blockDiagram-DXYQGD6D-DKQr_EU5.js → blockDiagram-DXYQGD6D-D_GMBRzY.js} +1 -1
- package/dist/assets/{c4Diagram-AHTNJAMY-6OA3wnaj.js → c4Diagram-AHTNJAMY-CvmmAOg5.js} +1 -1
- package/dist/assets/channel-F10GB4f_.js +1 -0
- package/dist/assets/{chunk-4BX2VUAB-RPzgJJNb.js → chunk-4BX2VUAB-BPr0k8sP.js} +1 -1
- package/dist/assets/{chunk-4TB4RGXK-C4RNzHuu.js → chunk-4TB4RGXK-D-Y1Qj_T.js} +1 -1
- package/dist/assets/{chunk-55IACEB6-D7M7RO-J.js → chunk-55IACEB6-Bug_ufgD.js} +1 -1
- package/dist/assets/{chunk-EDXVE4YY-DZY9MFLO.js → chunk-EDXVE4YY-C7tD8L3k.js} +1 -1
- package/dist/assets/{chunk-FMBD7UC4-QMoMGo7W.js → chunk-FMBD7UC4-BU7HNA1K.js} +1 -1
- package/dist/assets/{chunk-OYMX7WX6-CQWjKnzn.js → chunk-OYMX7WX6-DQ_CIv08.js} +1 -1
- package/dist/assets/{chunk-QZHKN3VN-D16FUhg8.js → chunk-QZHKN3VN-HODyXosI.js} +1 -1
- package/dist/assets/{chunk-YZCP3GAM-CqRHihc7.js → chunk-YZCP3GAM-7Y8K_8MD.js} +1 -1
- package/dist/assets/classDiagram-6PBFFD2Q-BqBb7BDW.js +1 -0
- package/dist/assets/classDiagram-v2-HSJHXN6E-BqBb7BDW.js +1 -0
- package/dist/assets/clone-DOQmcAsj.js +1 -0
- package/dist/assets/{cose-bilkent-S5V4N54A-bfoOQLsv.js → cose-bilkent-S5V4N54A-D2kYbpZy.js} +1 -1
- package/dist/assets/{dagre-KV5264BT-BCyLituE.js → dagre-KV5264BT-BlyZQ0n0.js} +1 -1
- package/dist/assets/{diagram-5BDNPKRD-CPkN139r.js → diagram-5BDNPKRD-C3lJ6ObZ.js} +1 -1
- package/dist/assets/{diagram-G4DWMVQ6-DFLt39fl.js → diagram-G4DWMVQ6-hx-WGqJX.js} +1 -1
- package/dist/assets/{diagram-MMDJMWI5-DYYmrlVW.js → diagram-MMDJMWI5-CdI5Z_ZJ.js} +1 -1
- package/dist/assets/{diagram-TYMM5635-BZ3Pv-hE.js → diagram-TYMM5635-BmtYRsNe.js} +1 -1
- package/dist/assets/{erDiagram-SMLLAGMA-CAKauIJm.js → erDiagram-SMLLAGMA-DPokxoLy.js} +1 -1
- package/dist/assets/{flowDiagram-DWJPFMVM-KB2eEgGe.js → flowDiagram-DWJPFMVM-DFnf6GAZ.js} +1 -1
- package/dist/assets/{ganttDiagram-T4ZO3ILL-JMol99Z2.js → ganttDiagram-T4ZO3ILL-ymFoiBFD.js} +1 -1
- package/dist/assets/{gitGraphDiagram-UUTBAWPF-Bj2wACW5.js → gitGraphDiagram-UUTBAWPF-BOAZqylM.js} +1 -1
- package/dist/assets/{graph-mzOZJsmK.js → graph-BMumGBmN.js} +1 -1
- package/dist/assets/{highlighted-body-OFNGDK62-C5zsRw66.js → highlighted-body-OFNGDK62-DRX5PypI.js} +1 -1
- package/dist/assets/index-BZMnkfN7.css +1 -0
- package/dist/assets/{index-BXxzots5.js → index-MiIZL4f3.js} +291 -280
- package/dist/assets/{infoDiagram-42DDH7IO-DJiZjg4e.js → infoDiagram-42DDH7IO-D0iCgAlu.js} +1 -1
- package/dist/assets/{ishikawaDiagram-UXIWVN3A-D3C3S2GG.js → ishikawaDiagram-UXIWVN3A-WtqHTEzb.js} +1 -1
- package/dist/assets/{journeyDiagram-VCZTEJTY-oox1ioYZ.js → journeyDiagram-VCZTEJTY-DUlKzcQ-.js} +1 -1
- package/dist/assets/{kanban-definition-6JOO6SKY-DmK_6JO5.js → kanban-definition-6JOO6SKY-COYae0oO.js} +1 -1
- package/dist/assets/{layout-BU0zwXna.js → layout-Et_h2gsr.js} +1 -1
- package/dist/assets/{linear-BTTy9rEg.js → linear-DY_vot7D.js} +1 -1
- package/dist/assets/{min-CxsTU35L.js → min-CImNjYIc.js} +1 -1
- package/dist/assets/{mindmap-definition-QFDTVHPH-B9yvRvsY.js → mindmap-definition-QFDTVHPH-zOJ7uKnl.js} +1 -1
- package/dist/assets/{pieDiagram-DEJITSTG-BRDyhVEN.js → pieDiagram-DEJITSTG-BftexWKs.js} +1 -1
- package/dist/assets/{quadrantDiagram-34T5L4WZ-CHuq8duY.js → quadrantDiagram-34T5L4WZ-CHmM6MYD.js} +1 -1
- package/dist/assets/{requirementDiagram-MS252O5E-CPZMaTta.js → requirementDiagram-MS252O5E-eMzrziUe.js} +1 -1
- package/dist/assets/{sankeyDiagram-XADWPNL6-ukpqhioK.js → sankeyDiagram-XADWPNL6-B-Bgmxmu.js} +1 -1
- package/dist/assets/{sequenceDiagram-FGHM5R23-_HE4wLAQ.js → sequenceDiagram-FGHM5R23-cFT-__W_.js} +1 -1
- package/dist/assets/{stateDiagram-FHFEXIEX-CzvbU_vB.js → stateDiagram-FHFEXIEX-CVnHwqCo.js} +1 -1
- package/dist/assets/stateDiagram-v2-QKLJ7IA2-nhhJvKGq.js +1 -0
- package/dist/assets/{timeline-definition-GMOUNBTQ-CjOUyryC.js → timeline-definition-GMOUNBTQ-CKbNRuf9.js} +1 -1
- package/dist/assets/{value-BRre6T9m.js → value-IOfiG7E7.js} +1 -1
- package/dist/assets/{vennDiagram-DHZGUBPP-ByHmBMvF.js → vennDiagram-DHZGUBPP-BDoxftwQ.js} +1 -1
- package/dist/assets/{wardley-RL74JXVD-BJB7tkWD.js → wardley-RL74JXVD-5TXAieIJ.js} +1 -1
- package/dist/assets/{wardleyDiagram-NUSXRM2D-CPNSDUV6.js → wardleyDiagram-NUSXRM2D-CFpD2tIy.js} +1 -1
- package/dist/assets/{xychartDiagram-5P7HB3ND-BPC25pDH.js → xychartDiagram-5P7HB3ND-cP5C2vcw.js} +1 -1
- package/dist/index.html +2 -2
- package/package.json +18 -15
- package/LICENSE +0 -661
- package/dist/assets/channel-CbescFQS.js +0 -1
- package/dist/assets/classDiagram-6PBFFD2Q-BbJjgfyw.js +0 -1
- package/dist/assets/classDiagram-v2-HSJHXN6E-BbJjgfyw.js +0 -1
- package/dist/assets/clone-D07SvwIC.js +0 -1
- package/dist/assets/index-Pc31QmUJ.css +0 -1
- package/dist/assets/stateDiagram-v2-QKLJ7IA2-Zuwgf5Ss.js +0 -1
package/dist/api/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/api/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAK5B,OAAO,
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/api/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAK5B,OAAO,EAgGL,KAAK,aAAa,EAIlB,KAAK,aAAa,EAMnB,MAAM,oBAAoB,CAAC;AA8jE5B,wBAAgB,kBAAkB,CAAC,aAAa,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,GAAE;IAAE,QAAQ,CAAC,kBAAkB,CAAC,EAAE,aAAa,CAAA;CAAO,8EAq7G7I;AAID,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,MAAM,EACZ,IAAI,SAAO,EACX,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GACxC,OAAO,CAAC,IAAI,CAAC,CA8Cf"}
|
package/dist/api/server.js
CHANGED
|
@@ -3,7 +3,7 @@ import { cors } from "hono/cors";
|
|
|
3
3
|
import { streamSSE } from "hono/streaming";
|
|
4
4
|
import { serve } from "@hono/node-server";
|
|
5
5
|
import { gzipSync } from "node:zlib";
|
|
6
|
-
import { StateManager, PipelineRunner, createLLMClient, createLogger, createInteractionToolsFromDeps, computeAnalytics, loadProjectConfig, loadProjectSession, processProjectInteractionRequest, resolveSessionActiveBook, listBookSessions, loadBookSession, appendManualSessionMessages, createAndPersistBookSession, renameBookSession, deleteBookSession, migrateBookSession, SessionAlreadyMigratedError, runAgentSession, resolveServicePreset, resolveServiceProviderFamily, resolveServiceModelsBaseUrl, guessServiceFromBaseUrl, resolveServiceModel, loadSecrets, saveSecrets, listModelsForService, isApiKeyOptionalForEndpoint, getAllEndpoints, probeModelsFromUpstream, fetchWithProxy, chatCompletion, buildExportArtifact, evaluateBookQuality, ConsolidatorAgent, DetectionConfigSchema, ResearchSearchConfigSchema, InputGovernanceModeSchema, GLOBAL_ENV_PATH, COVER_PROVIDER_PRESETS, createPlayDB, PlayStore, buildPlayEntityImagePrompt, buildPlaySceneImagePrompt, generatePlayImage, readPlayImageManifest, readPlayImageSettings, writePlayImageSettings, Scheduler, coverSecretKey, resolveCoverProviderPreset, SessionKindSchema, isExplicitWriteChapterCommand, isUsablePlayInitialScene, isWriteNextInstruction, normalizeActionSource as normalizeCoreActionSource, normalizeActionPayload as normalizeCoreActionPayload, normalizePlayMode as normalizeCorePlayMode, normalizeRequestedIntent as normalizeCoreRequestedIntent, normalizeSkillIdList as normalizeCoreSkillIdList, inferLanguage, createSkillRegistry, loadConfiguredCapabilitySkills, CapabilitySkillManifestSchema, createGenerateCoverTool, createInteractiveFilmCreationTool, createPlayStartTool, createScriptCreationTool, createShortFictionRunTool, createStoryboardCreationTool, createSubAgentTool, createDraftStructureTool, createConnectChoiceTool, createRemoveNodeTool, filmLLMDepsFromClient, applyGraphDelta, loadStoryGraph, reviewStoryGraph, exportInk, buildPlayableHtml, analyzeEmotionalArcs, analyzePathDistribution, generateNodeImage, defaultNodeImageDeps, } from "@actalk/inkos-core";
|
|
6
|
+
import { StateManager, PipelineRunner, createLLMClient, createLogger, createInteractionToolsFromDeps, computeAnalytics, loadProjectConfig, loadProjectSession, processProjectInteractionRequest, resolveSessionActiveBook, listBookSessions, loadBookSession, appendManualSessionMessages, createAndPersistBookSession, renameBookSession, deleteBookSession, migrateBookSession, SessionAlreadyMigratedError, abortAgentSession, runAgentSession, resolveServicePreset, resolveServiceProviderFamily, resolveServiceModelsBaseUrl, guessServiceFromBaseUrl, resolveServiceModel, loadSecrets, saveSecrets, listModelsForService, isApiKeyOptionalForEndpoint, getAllEndpoints, probeModelsFromUpstream, fetchWithProxy, chatCompletion, buildExportArtifact, evaluateBookQuality, ConsolidatorAgent, DetectionConfigSchema, ResearchSearchConfigSchema, InputGovernanceModeSchema, GLOBAL_ENV_PATH, COVER_PROVIDER_PRESETS, createPlayDB, PlayStore, buildPlayEntityImagePrompt, buildPlaySceneImagePrompt, generatePlayImage, readPlayImageManifest, readPlayImageSettings, writePlayImageSettings, Scheduler, coverSecretKey, resolveCoverProviderPreset, SessionKindSchema, isExplicitWriteChapterCommand, isUsablePlayInitialScene, isWriteNextInstruction, normalizeActionSource as normalizeCoreActionSource, normalizeActionPayload as normalizeCoreActionPayload, normalizePlayMode as normalizeCorePlayMode, normalizeRequestedIntent as normalizeCoreRequestedIntent, normalizeSkillIdList as normalizeCoreSkillIdList, inferLanguage, createSkillRegistry, loadConfiguredCapabilitySkills, CapabilitySkillManifestSchema, getBuiltinPrompt, listBuiltinPromptPacks, listBuiltinPrompts, loadPromptPackPrompt, promptOverridePath, createGenerateCoverTool, createInteractiveFilmCreationTool, createPlayStartTool, createScriptCreationTool, createShortFictionRunTool, createStoryboardCreationTool, createSubAgentTool, createDraftStructureTool, createConnectChoiceTool, createRemoveNodeTool, filmLLMDepsFromClient, applyGraphDelta, loadStoryGraph, reviewStoryGraph, exportInk, buildPlayableHtml, analyzeEmotionalArcs, analyzePathDistribution, generateNodeImage, defaultNodeImageDeps, } from "@actalk/inkos-core";
|
|
7
7
|
import { access, mkdir, readFile, readdir, rm, stat, writeFile } from "node:fs/promises";
|
|
8
8
|
import { dirname, isAbsolute, join, relative, resolve } from "node:path";
|
|
9
9
|
import { isSafeBookId } from "./safety.js";
|
|
@@ -351,6 +351,106 @@ function normalizeStudioSkillId(value, field = "skillId") {
|
|
|
351
351
|
throw new ApiError(400, "INVALID_SKILL_ID", `Invalid ${field}: empty`);
|
|
352
352
|
return id;
|
|
353
353
|
}
|
|
354
|
+
const MAX_AGENT_ATTACHMENTS = 8;
|
|
355
|
+
const MAX_AGENT_ATTACHMENT_BYTES = 4 * 1024 * 1024;
|
|
356
|
+
const MAX_AGENT_ATTACHMENT_TEXT_CHARS = 120_000;
|
|
357
|
+
function safeUploadFileName(value) {
|
|
358
|
+
const trimmed = value.trim().replace(/[/\\\0]/g, "_").replace(/\s+/g, " ");
|
|
359
|
+
const safe = trimmed.replace(/[^\p{L}\p{N}._ -]+/gu, "_").slice(0, 120).trim();
|
|
360
|
+
return safe || "upload";
|
|
361
|
+
}
|
|
362
|
+
function isTextAttachment(filename, mimeType) {
|
|
363
|
+
const lower = filename.toLowerCase();
|
|
364
|
+
return mimeType.startsWith("text/")
|
|
365
|
+
|| [
|
|
366
|
+
".txt",
|
|
367
|
+
".md",
|
|
368
|
+
".markdown",
|
|
369
|
+
".json",
|
|
370
|
+
".csv",
|
|
371
|
+
".tsv",
|
|
372
|
+
".yaml",
|
|
373
|
+
".yml",
|
|
374
|
+
".log",
|
|
375
|
+
].some((suffix) => lower.endsWith(suffix));
|
|
376
|
+
}
|
|
377
|
+
function parseDataUrl(dataUrl) {
|
|
378
|
+
const match = /^data:([^;,]+)?(?:;[^,]*)?;base64,(.*)$/s.exec(dataUrl);
|
|
379
|
+
if (!match) {
|
|
380
|
+
throw new ApiError(400, "INVALID_ATTACHMENT_DATA_URL", "Attachment must be a base64 data URL");
|
|
381
|
+
}
|
|
382
|
+
const mimeType = match[1]?.trim() || "application/octet-stream";
|
|
383
|
+
return { mimeType, buffer: Buffer.from(match[2] ?? "", "base64") };
|
|
384
|
+
}
|
|
385
|
+
async function normalizeAgentAttachments(root, sessionId, value) {
|
|
386
|
+
if (value === undefined || value === null)
|
|
387
|
+
return [];
|
|
388
|
+
if (!Array.isArray(value)) {
|
|
389
|
+
throw new ApiError(400, "INVALID_ATTACHMENTS", "attachments must be an array");
|
|
390
|
+
}
|
|
391
|
+
if (value.length > MAX_AGENT_ATTACHMENTS) {
|
|
392
|
+
throw new ApiError(413, "TOO_MANY_ATTACHMENTS", `At most ${MAX_AGENT_ATTACHMENTS} files can be attached to one message`);
|
|
393
|
+
}
|
|
394
|
+
const uploadDir = join(root, ".inkos", "uploads", safeUploadFileName(sessionId));
|
|
395
|
+
const out = [];
|
|
396
|
+
for (const [index, raw] of value.entries()) {
|
|
397
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
|
|
398
|
+
throw new ApiError(400, "INVALID_ATTACHMENT", "Each attachment must be an object");
|
|
399
|
+
}
|
|
400
|
+
const payload = raw;
|
|
401
|
+
const filename = safeUploadFileName(payload.filename || `upload-${index + 1}`);
|
|
402
|
+
if (!payload.dataUrl) {
|
|
403
|
+
throw new ApiError(400, "INVALID_ATTACHMENT", `Attachment ${filename} is missing dataUrl`);
|
|
404
|
+
}
|
|
405
|
+
const parsed = parseDataUrl(payload.dataUrl);
|
|
406
|
+
const mimeType = payload.mediaType?.trim() || parsed.mimeType;
|
|
407
|
+
if (parsed.buffer.byteLength > MAX_AGENT_ATTACHMENT_BYTES) {
|
|
408
|
+
throw new ApiError(413, "ATTACHMENT_TOO_LARGE", `${filename} exceeds ${MAX_AGENT_ATTACHMENT_BYTES} bytes`);
|
|
409
|
+
}
|
|
410
|
+
await mkdir(uploadDir, { recursive: true });
|
|
411
|
+
const storedName = `${Date.now()}-${index + 1}-${filename}`;
|
|
412
|
+
const storedPath = join(uploadDir, storedName);
|
|
413
|
+
await writeFile(storedPath, parsed.buffer);
|
|
414
|
+
const relPath = relative(root, storedPath);
|
|
415
|
+
if (mimeType.startsWith("image/")) {
|
|
416
|
+
out.push({
|
|
417
|
+
id: payload.id || `${Date.now()}-${index}`,
|
|
418
|
+
filename,
|
|
419
|
+
mimeType,
|
|
420
|
+
size: parsed.buffer.byteLength,
|
|
421
|
+
storedPath: relPath,
|
|
422
|
+
image: {
|
|
423
|
+
data: parsed.buffer.toString("base64"),
|
|
424
|
+
mimeType,
|
|
425
|
+
},
|
|
426
|
+
});
|
|
427
|
+
continue;
|
|
428
|
+
}
|
|
429
|
+
if (isTextAttachment(filename, mimeType)) {
|
|
430
|
+
const text = parsed.buffer.toString("utf-8");
|
|
431
|
+
if (text.length > MAX_AGENT_ATTACHMENT_TEXT_CHARS) {
|
|
432
|
+
throw new ApiError(413, "ATTACHMENT_TEXT_TOO_LARGE", `${filename} is too large to inject without semantic compaction`);
|
|
433
|
+
}
|
|
434
|
+
out.push({
|
|
435
|
+
id: payload.id || `${Date.now()}-${index}`,
|
|
436
|
+
filename,
|
|
437
|
+
mimeType,
|
|
438
|
+
size: parsed.buffer.byteLength,
|
|
439
|
+
storedPath: relPath,
|
|
440
|
+
text,
|
|
441
|
+
});
|
|
442
|
+
continue;
|
|
443
|
+
}
|
|
444
|
+
out.push({
|
|
445
|
+
id: payload.id || `${Date.now()}-${index}`,
|
|
446
|
+
filename,
|
|
447
|
+
mimeType,
|
|
448
|
+
size: parsed.buffer.byteLength,
|
|
449
|
+
storedPath: relPath,
|
|
450
|
+
});
|
|
451
|
+
}
|
|
452
|
+
return out;
|
|
453
|
+
}
|
|
354
454
|
function projectSkillsDir(root) {
|
|
355
455
|
return join(root, ".inkos", "skills");
|
|
356
456
|
}
|
|
@@ -443,6 +543,27 @@ async function loadStudioSkills(root) {
|
|
|
443
543
|
diagnostics: configured.diagnostics,
|
|
444
544
|
};
|
|
445
545
|
}
|
|
546
|
+
async function toStudioPromptPackPrompt(root, prompt) {
|
|
547
|
+
const loaded = await loadPromptPackPrompt({ promptId: prompt.id, projectRoot: root });
|
|
548
|
+
const overridePath = promptOverridePath(root, prompt.id);
|
|
549
|
+
return {
|
|
550
|
+
id: prompt.id,
|
|
551
|
+
packId: prompt.packId,
|
|
552
|
+
title: prompt.title,
|
|
553
|
+
defaultContent: prompt.content,
|
|
554
|
+
content: loaded.content,
|
|
555
|
+
source: loaded.source,
|
|
556
|
+
overridden: loaded.source === "project",
|
|
557
|
+
path: loaded.source === "project" ? relative(root, overridePath) : undefined,
|
|
558
|
+
};
|
|
559
|
+
}
|
|
560
|
+
function normalizeStudioPromptId(value) {
|
|
561
|
+
const promptId = typeof value === "string" ? value.trim().toLowerCase() : "";
|
|
562
|
+
if (!promptId || !getBuiltinPrompt(promptId)) {
|
|
563
|
+
throw new ApiError(404, "PROMPT_PACK_PROMPT_NOT_FOUND", `Prompt pack prompt not found: ${String(value)}`);
|
|
564
|
+
}
|
|
565
|
+
return promptId;
|
|
566
|
+
}
|
|
446
567
|
async function listProjectSkillIds(root) {
|
|
447
568
|
try {
|
|
448
569
|
const entries = await readdir(projectSkillsDir(root), { withFileTypes: true });
|
|
@@ -2613,6 +2734,37 @@ export function createStudioServer(initialConfig, root, overrides = {}) {
|
|
|
2613
2734
|
const result = await loadStudioSkills(root);
|
|
2614
2735
|
return c.json(result);
|
|
2615
2736
|
});
|
|
2737
|
+
app.get("/api/v1/prompt-packs", async (c) => {
|
|
2738
|
+
const prompts = await Promise.all(listBuiltinPrompts().map((prompt) => toStudioPromptPackPrompt(root, prompt)));
|
|
2739
|
+
return c.json({
|
|
2740
|
+
packs: listBuiltinPromptPacks(),
|
|
2741
|
+
prompts,
|
|
2742
|
+
});
|
|
2743
|
+
});
|
|
2744
|
+
app.put("/api/v1/prompt-packs/:promptId", async (c) => {
|
|
2745
|
+
const promptId = normalizeStudioPromptId(c.req.param("promptId"));
|
|
2746
|
+
const payload = await c.req.json().catch(() => {
|
|
2747
|
+
throw new ApiError(400, "INVALID_PROMPT_PACK_PAYLOAD", "Prompt pack payload must be JSON");
|
|
2748
|
+
});
|
|
2749
|
+
const content = payload && typeof payload === "object" && "content" in payload
|
|
2750
|
+
? payload.content
|
|
2751
|
+
: undefined;
|
|
2752
|
+
if (typeof content !== "string") {
|
|
2753
|
+
throw new ApiError(400, "INVALID_PROMPT_PACK_PAYLOAD", "content must be a string");
|
|
2754
|
+
}
|
|
2755
|
+
const file = promptOverridePath(root, promptId);
|
|
2756
|
+
await mkdir(dirname(file), { recursive: true });
|
|
2757
|
+
await writeFile(file, content, "utf-8");
|
|
2758
|
+
const prompt = listBuiltinPrompts().find((item) => item.id === promptId);
|
|
2759
|
+
return c.json({ prompt: await toStudioPromptPackPrompt(root, prompt) });
|
|
2760
|
+
});
|
|
2761
|
+
app.delete("/api/v1/prompt-packs/:promptId", async (c) => {
|
|
2762
|
+
const promptId = normalizeStudioPromptId(c.req.param("promptId"));
|
|
2763
|
+
const file = promptOverridePath(root, promptId);
|
|
2764
|
+
await rm(file, { force: true });
|
|
2765
|
+
const prompt = listBuiltinPrompts().find((item) => item.id === promptId);
|
|
2766
|
+
return c.json({ prompt: await toStudioPromptPackPrompt(root, prompt) });
|
|
2767
|
+
});
|
|
2616
2768
|
app.post("/api/v1/skills", async (c) => {
|
|
2617
2769
|
const payload = await c.req.json().catch(() => {
|
|
2618
2770
|
throw new ApiError(400, "INVALID_SKILL_PAYLOAD", "Skill payload must be JSON");
|
|
@@ -3093,8 +3245,14 @@ export function createStudioServer(initialConfig, root, overrides = {}) {
|
|
|
3093
3245
|
await deleteBookSession(root, c.req.param("sessionId"));
|
|
3094
3246
|
return c.json({ ok: true });
|
|
3095
3247
|
});
|
|
3248
|
+
app.post("/api/v1/sessions/:sessionId/abort", async (c) => {
|
|
3249
|
+
const sessionId = c.req.param("sessionId");
|
|
3250
|
+
const aborted = abortAgentSession(root, sessionId);
|
|
3251
|
+
broadcast("agent:aborted", { sessionId, aborted });
|
|
3252
|
+
return c.json({ ok: true, aborted });
|
|
3253
|
+
});
|
|
3096
3254
|
app.post("/api/v1/agent", async (c) => {
|
|
3097
|
-
const { instruction, activeBookId, sessionId: reqSessionId, sessionKind: reqSessionKind, actionSource: reqActionSource, requestedIntent: reqRequestedIntent, actionPayload: reqActionPayload, requestedSkills: reqRequestedSkills, disabledSkills: reqDisabledSkills, playMode: reqPlayMode, model: reqModel, service: reqService, } = await c.req.json();
|
|
3255
|
+
const { instruction, activeBookId, sessionId: reqSessionId, sessionKind: reqSessionKind, actionSource: reqActionSource, requestedIntent: reqRequestedIntent, actionPayload: reqActionPayload, requestedSkills: reqRequestedSkills, disabledSkills: reqDisabledSkills, attachments: reqAttachments, playMode: reqPlayMode, model: reqModel, service: reqService, } = await c.req.json();
|
|
3098
3256
|
const sessionId = reqSessionId;
|
|
3099
3257
|
if (!instruction?.trim()) {
|
|
3100
3258
|
return c.json({ error: "No instruction provided" }, 400);
|
|
@@ -3111,8 +3269,9 @@ export function createStudioServer(initialConfig, root, overrides = {}) {
|
|
|
3111
3269
|
const actionPayload = normalizeStudioActionPayload(reqActionPayload);
|
|
3112
3270
|
const requestedSkills = normalizeStudioSkillIdList(reqRequestedSkills, "requestedSkills");
|
|
3113
3271
|
const disabledSkills = normalizeStudioSkillIdList(reqDisabledSkills, "disabledSkills");
|
|
3272
|
+
const attachments = await normalizeAgentAttachments(root, sessionId, reqAttachments);
|
|
3114
3273
|
const playMode = normalizeStudioPlayMode(reqPlayMode);
|
|
3115
|
-
broadcast("agent:start", { instruction, activeBookId, sessionId, actionSource, requestedIntent, requestedSkills });
|
|
3274
|
+
broadcast("agent:start", { instruction, activeBookId, sessionId, actionSource, requestedIntent, requestedSkills, attachments: attachments.length });
|
|
3116
3275
|
try {
|
|
3117
3276
|
// Load config + create LLM client (pipeline created after model resolution)
|
|
3118
3277
|
const config = await loadCurrentProjectConfig({ requireApiKey: false });
|
|
@@ -3494,6 +3653,7 @@ export function createStudioServer(initialConfig, root, overrides = {}) {
|
|
|
3494
3653
|
actionPayload,
|
|
3495
3654
|
requestedSkills,
|
|
3496
3655
|
disabledSkills,
|
|
3656
|
+
attachments,
|
|
3497
3657
|
sessionId: bookSession.sessionId,
|
|
3498
3658
|
language: surfaceLanguage,
|
|
3499
3659
|
onContextCompression: (event) => {
|