@code-yeongyu/senpi 2026.5.14 → 2026.5.15
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/CHANGELOG.md +1071 -1063
- package/dist/core/extensions/builtin/background-task/notification.d.ts +1 -1
- package/dist/core/extensions/builtin/background-task/notification.d.ts.map +1 -1
- package/dist/core/extensions/builtin/background-task/notification.js.map +1 -1
- package/dist/core/extensions/builtin/background-task/types.d.ts +2 -2
- package/dist/core/extensions/builtin/background-task/types.d.ts.map +1 -1
- package/dist/core/extensions/builtin/background-task/types.js +2 -2
- package/dist/core/extensions/builtin/background-task/types.js.map +1 -1
- package/dist/core/extensions/builtin/system-messages.d.ts +6 -6
- package/dist/core/extensions/builtin/system-messages.d.ts.map +1 -1
- package/dist/core/extensions/builtin/system-messages.js +10 -10
- package/dist/core/extensions/builtin/system-messages.js.map +1 -1
- package/dist/core/extensions/builtin/todotools/continuation/prompt.d.ts +1 -1
- package/dist/core/extensions/builtin/todotools/continuation/prompt.d.ts.map +1 -1
- package/dist/core/extensions/builtin/todotools/continuation/prompt.js +1 -1
- package/dist/core/extensions/builtin/todotools/continuation/prompt.js.map +1 -1
- package/dist/core/extensions/builtin/todotools/state.d.ts +1 -1
- package/dist/core/extensions/builtin/todotools/state.d.ts.map +1 -1
- package/dist/core/extensions/builtin/todotools/state.js +1 -1
- package/dist/core/extensions/builtin/todotools/state.js.map +1 -1
- package/dist/core/extensions/builtin/todotools/system-messages.d.ts +3 -3
- package/dist/core/extensions/builtin/todotools/system-messages.d.ts.map +1 -1
- package/dist/core/extensions/builtin/todotools/system-messages.js +6 -6
- package/dist/core/extensions/builtin/todotools/system-messages.js.map +1 -1
- package/docs/agents.md +1 -1
- package/package.json +4 -4
|
@@ -4,7 +4,7 @@ import type { BackgroundTask } from "./types.js";
|
|
|
4
4
|
export type NotificationStatus = "COMPLETED" | "CANCELLED" | "ERROR";
|
|
5
5
|
export interface NotificationTask {
|
|
6
6
|
id: string;
|
|
7
|
-
description
|
|
7
|
+
description?: string | undefined;
|
|
8
8
|
status: BackgroundTask["status"];
|
|
9
9
|
error?: string;
|
|
10
10
|
result?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notification.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/background-task/notification.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,MAAM,MAAM,kBAAkB,GAAG,WAAW,GAAG,WAAW,GAAG,OAAO,CAAC;AAErE,MAAM,WAAW,gBAAgB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"notification.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/background-task/notification.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,MAAM,MAAM,kBAAkB,GAAG,WAAW,GAAG,WAAW,GAAG,OAAO,CAAC;AAErE,MAAM,WAAW,gBAAgB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,MAAM,EAAE,cAAc,CAAC,QAAQ,CAAC,CAAC;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IACjC,IAAI,EAAE,gBAAgB,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,kBAAkB,CAAC;IAC/B,WAAW,EAAE,OAAO,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,gBAAgB,EAAE,CAAC;CACnC;AAMD,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM,CAqB7E;AAsED,wBAAgB,0BAA0B,CAAC,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,iBAAiB,GAAG,IAAI,CAkCnH","sourcesContent":["import type { ExtensionAPI } from \"../../types.js\";\nimport { sendBuiltinCustomMessage } from \"../system-messages.js\";\nimport type { BackgroundManager } from \"./manager.js\";\nimport type { BackgroundTask } from \"./types.js\";\n\nexport type NotificationStatus = \"COMPLETED\" | \"CANCELLED\" | \"ERROR\";\n\nexport interface NotificationTask {\n\tid: string;\n\tdescription?: string | undefined;\n\tstatus: BackgroundTask[\"status\"];\n\terror?: string;\n\tresult?: string;\n}\n\nexport interface NotificationInput {\n\ttask: NotificationTask;\n\tduration: string;\n\tstatusText: NotificationStatus;\n\tallComplete: boolean;\n\tremainingCount: number;\n\tcompletedTasks: NotificationTask[];\n}\n\nfunction safeDescription(task: NotificationTask): string {\n\treturn task.description || task.id;\n}\n\nexport function formatCompletionNotification(input: NotificationInput): string {\n\tconst { task, duration, statusText, allComplete, remainingCount, completedTasks } = input;\n\tconst errorInfo = task.error ? `\\n**Error:** ${task.error}` : \"\";\n\n\tif (allComplete) {\n\t\treturn formatAllCompleteNotification(task, completedTasks);\n\t}\n\n\tconst isFailure = statusText !== \"COMPLETED\";\n\n\treturn `<system-reminder>\n[BACKGROUND TASK ${statusText}]\n**ID:** \\`${task.id}\\`\n**Description:** ${safeDescription(task)}\n**Duration:** ${duration}${errorInfo}\n\n**${remainingCount} task${remainingCount === 1 ? \"\" : \"s\"} still in progress.** You WILL be notified when ALL complete.\n${isFailure ? \"**ACTION REQUIRED:** This task failed. Check the error and decide whether to retry, cancel remaining tasks, or continue.\" : \"Do NOT poll - continue productive work.\"}\n\nUse \\`background_output(task_id=\"${task.id}\")\\` to retrieve this result when ready.\n</system-reminder>`;\n}\n\nfunction formatAllCompleteNotification(task: NotificationTask, completedTasks: NotificationTask[]): string {\n\tconst succeededTasks = completedTasks.filter((t) => t.status === \"completed\");\n\tconst failedTasks = completedTasks.filter((t) => t.status !== \"completed\");\n\n\tconst succeededText =\n\t\tsucceededTasks.length > 0 ? succeededTasks.map((t) => `- \\`${t.id}\\`: ${safeDescription(t)}`).join(\"\\n\") : \"\";\n\tconst failedText =\n\t\tfailedTasks.length > 0\n\t\t\t? failedTasks\n\t\t\t\t\t.map(\n\t\t\t\t\t\t(t) =>\n\t\t\t\t\t\t\t`- \\`${t.id}\\`: ${safeDescription(t)} [${t.status.toUpperCase()}]${t.error ? ` - ${t.error}` : \"\"}`,\n\t\t\t\t\t)\n\t\t\t\t\t.join(\"\\n\")\n\t\t\t: \"\";\n\n\tconst hasFailures = failedTasks.length > 0;\n\tconst header = hasFailures\n\t\t? `[ALL BACKGROUND TASKS FINISHED - ${failedTasks.length} FAILED]`\n\t\t: \"[ALL BACKGROUND TASKS COMPLETE]\";\n\n\tlet body = \"\";\n\tif (succeededText) {\n\t\tbody += `**Completed:**\\n${succeededText}\\n`;\n\t}\n\tif (failedText) {\n\t\tbody += `\\n**Failed:**\\n${failedText}\\n`;\n\t}\n\tif (!body) {\n\t\tbody = `- \\`${task.id}\\`: ${safeDescription(task)} [${task.status.toUpperCase()}]${task.error ? ` - ${task.error}` : \"\"}\\n`;\n\t}\n\n\treturn `<system-reminder>\n${header}\n\n${body.trim()}\n\nUse \\`background_output(task_id=\"<id>\")\\` to retrieve each result.${hasFailures ? `\\n\\n**ACTION REQUIRED:** ${failedTasks.length} task(s) failed. Check errors above and decide whether to retry or proceed.` : \"\"}\n</system-reminder>`;\n}\n\nfunction formatDuration(startedAt: Date, completedAt: Date | undefined): string {\n\tconst end = completedAt ?? new Date();\n\tconst milliseconds = end.getTime() - startedAt.getTime();\n\tif (milliseconds < 1000) {\n\t\treturn `${milliseconds}ms`;\n\t}\n\tif (milliseconds < 60000) {\n\t\treturn `${(milliseconds / 1000).toFixed(1)}s`;\n\t}\n\treturn `${Math.floor(milliseconds / 60000)}m ${Math.floor((milliseconds % 60000) / 1000)}s`;\n}\n\nfunction mapStatus(task: BackgroundTask): NotificationStatus {\n\tswitch (task.status) {\n\t\tcase \"cancelled\":\n\t\t\treturn \"CANCELLED\";\n\t\tcase \"error\":\n\t\t\treturn \"ERROR\";\n\t\tdefault:\n\t\t\treturn \"COMPLETED\";\n\t}\n}\n\nfunction isTerminalStatus(status: BackgroundTask[\"status\"]): boolean {\n\treturn status === \"completed\" || status === \"error\" || status === \"cancelled\";\n}\n\nexport function sendCompletionNotification(pi: ExtensionAPI, task: BackgroundTask, manager: BackgroundManager): void {\n\tconst activeTasks = manager.getActiveTasks();\n\tconst allComplete = activeTasks.length === 0;\n\tconst remainingCount = activeTasks.length;\n\n\tconst completedTasks: NotificationTask[] = allComplete\n\t\t? manager\n\t\t\t\t.getAllTasks()\n\t\t\t\t.filter((t) => isTerminalStatus(t.status))\n\t\t\t\t.map((t) => ({ id: t.id, description: t.description, status: t.status, error: t.error, result: t.result }))\n\t\t: [];\n\n\tconst duration = formatDuration(task.startedAt, task.completedAt);\n\tconst statusText = mapStatus(task);\n\n\tconst message = formatCompletionNotification({\n\t\ttask: { id: task.id, description: task.description, status: task.status, error: task.error, result: task.result },\n\t\tduration,\n\t\tstatusText,\n\t\tallComplete,\n\t\tremainingCount,\n\t\tcompletedTasks,\n\t});\n\n\tsendBuiltinCustomMessage(\n\t\tpi,\n\t\t\"background-task.notification\",\n\t\t{\n\t\t\tcustomType: \"background-task.complete\",\n\t\t\tdisplay: true,\n\t\t\tcontent: [{ type: \"text\", text: message }],\n\t\t},\n\t\t{ triggerTurn: true, deliverAs: \"followUp\", sessionId: task.parentSessionId },\n\t);\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notification.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/background-task/notification.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ExtensionAPI } from \"../../types.js\";\nimport { sendBuiltinCustomMessage } from \"../system-messages.js\";\nimport type { BackgroundManager } from \"./manager.js\";\nimport type { BackgroundTask } from \"./types.js\";\n\nexport type NotificationStatus = \"COMPLETED\" | \"CANCELLED\" | \"ERROR\";\n\nexport interface NotificationTask {\n\tid: string;\n\tdescription
|
|
1
|
+
{"version":3,"file":"notification.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/background-task/notification.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ExtensionAPI } from \"../../types.js\";\nimport { sendBuiltinCustomMessage } from \"../system-messages.js\";\nimport type { BackgroundManager } from \"./manager.js\";\nimport type { BackgroundTask } from \"./types.js\";\n\nexport type NotificationStatus = \"COMPLETED\" | \"CANCELLED\" | \"ERROR\";\n\nexport interface NotificationTask {\n\tid: string;\n\tdescription?: string | undefined;\n\tstatus: BackgroundTask[\"status\"];\n\terror?: string;\n\tresult?: string;\n}\n\nexport interface NotificationInput {\n\ttask: NotificationTask;\n\tduration: string;\n\tstatusText: NotificationStatus;\n\tallComplete: boolean;\n\tremainingCount: number;\n\tcompletedTasks: NotificationTask[];\n}\n\nfunction safeDescription(task: NotificationTask): string {\n\treturn task.description || task.id;\n}\n\nexport function formatCompletionNotification(input: NotificationInput): string {\n\tconst { task, duration, statusText, allComplete, remainingCount, completedTasks } = input;\n\tconst errorInfo = task.error ? `\\n**Error:** ${task.error}` : \"\";\n\n\tif (allComplete) {\n\t\treturn formatAllCompleteNotification(task, completedTasks);\n\t}\n\n\tconst isFailure = statusText !== \"COMPLETED\";\n\n\treturn `<system-reminder>\n[BACKGROUND TASK ${statusText}]\n**ID:** \\`${task.id}\\`\n**Description:** ${safeDescription(task)}\n**Duration:** ${duration}${errorInfo}\n\n**${remainingCount} task${remainingCount === 1 ? \"\" : \"s\"} still in progress.** You WILL be notified when ALL complete.\n${isFailure ? \"**ACTION REQUIRED:** This task failed. Check the error and decide whether to retry, cancel remaining tasks, or continue.\" : \"Do NOT poll - continue productive work.\"}\n\nUse \\`background_output(task_id=\"${task.id}\")\\` to retrieve this result when ready.\n</system-reminder>`;\n}\n\nfunction formatAllCompleteNotification(task: NotificationTask, completedTasks: NotificationTask[]): string {\n\tconst succeededTasks = completedTasks.filter((t) => t.status === \"completed\");\n\tconst failedTasks = completedTasks.filter((t) => t.status !== \"completed\");\n\n\tconst succeededText =\n\t\tsucceededTasks.length > 0 ? succeededTasks.map((t) => `- \\`${t.id}\\`: ${safeDescription(t)}`).join(\"\\n\") : \"\";\n\tconst failedText =\n\t\tfailedTasks.length > 0\n\t\t\t? failedTasks\n\t\t\t\t\t.map(\n\t\t\t\t\t\t(t) =>\n\t\t\t\t\t\t\t`- \\`${t.id}\\`: ${safeDescription(t)} [${t.status.toUpperCase()}]${t.error ? ` - ${t.error}` : \"\"}`,\n\t\t\t\t\t)\n\t\t\t\t\t.join(\"\\n\")\n\t\t\t: \"\";\n\n\tconst hasFailures = failedTasks.length > 0;\n\tconst header = hasFailures\n\t\t? `[ALL BACKGROUND TASKS FINISHED - ${failedTasks.length} FAILED]`\n\t\t: \"[ALL BACKGROUND TASKS COMPLETE]\";\n\n\tlet body = \"\";\n\tif (succeededText) {\n\t\tbody += `**Completed:**\\n${succeededText}\\n`;\n\t}\n\tif (failedText) {\n\t\tbody += `\\n**Failed:**\\n${failedText}\\n`;\n\t}\n\tif (!body) {\n\t\tbody = `- \\`${task.id}\\`: ${safeDescription(task)} [${task.status.toUpperCase()}]${task.error ? ` - ${task.error}` : \"\"}\\n`;\n\t}\n\n\treturn `<system-reminder>\n${header}\n\n${body.trim()}\n\nUse \\`background_output(task_id=\"<id>\")\\` to retrieve each result.${hasFailures ? `\\n\\n**ACTION REQUIRED:** ${failedTasks.length} task(s) failed. Check errors above and decide whether to retry or proceed.` : \"\"}\n</system-reminder>`;\n}\n\nfunction formatDuration(startedAt: Date, completedAt: Date | undefined): string {\n\tconst end = completedAt ?? new Date();\n\tconst milliseconds = end.getTime() - startedAt.getTime();\n\tif (milliseconds < 1000) {\n\t\treturn `${milliseconds}ms`;\n\t}\n\tif (milliseconds < 60000) {\n\t\treturn `${(milliseconds / 1000).toFixed(1)}s`;\n\t}\n\treturn `${Math.floor(milliseconds / 60000)}m ${Math.floor((milliseconds % 60000) / 1000)}s`;\n}\n\nfunction mapStatus(task: BackgroundTask): NotificationStatus {\n\tswitch (task.status) {\n\t\tcase \"cancelled\":\n\t\t\treturn \"CANCELLED\";\n\t\tcase \"error\":\n\t\t\treturn \"ERROR\";\n\t\tdefault:\n\t\t\treturn \"COMPLETED\";\n\t}\n}\n\nfunction isTerminalStatus(status: BackgroundTask[\"status\"]): boolean {\n\treturn status === \"completed\" || status === \"error\" || status === \"cancelled\";\n}\n\nexport function sendCompletionNotification(pi: ExtensionAPI, task: BackgroundTask, manager: BackgroundManager): void {\n\tconst activeTasks = manager.getActiveTasks();\n\tconst allComplete = activeTasks.length === 0;\n\tconst remainingCount = activeTasks.length;\n\n\tconst completedTasks: NotificationTask[] = allComplete\n\t\t? manager\n\t\t\t\t.getAllTasks()\n\t\t\t\t.filter((t) => isTerminalStatus(t.status))\n\t\t\t\t.map((t) => ({ id: t.id, description: t.description, status: t.status, error: t.error, result: t.result }))\n\t\t: [];\n\n\tconst duration = formatDuration(task.startedAt, task.completedAt);\n\tconst statusText = mapStatus(task);\n\n\tconst message = formatCompletionNotification({\n\t\ttask: { id: task.id, description: task.description, status: task.status, error: task.error, result: task.result },\n\t\tduration,\n\t\tstatusText,\n\t\tallComplete,\n\t\tremainingCount,\n\t\tcompletedTasks,\n\t});\n\n\tsendBuiltinCustomMessage(\n\t\tpi,\n\t\t\"background-task.notification\",\n\t\t{\n\t\t\tcustomType: \"background-task.complete\",\n\t\t\tdisplay: true,\n\t\t\tcontent: [{ type: \"text\", text: message }],\n\t\t},\n\t\t{ triggerTurn: true, deliverAs: \"followUp\", sessionId: task.parentSessionId },\n\t);\n}\n"]}
|
|
@@ -64,8 +64,8 @@ export declare const BackgroundCancelParams: Type.TObject<{
|
|
|
64
64
|
export type BackgroundCancelParamsType = Static<typeof BackgroundCancelParams>;
|
|
65
65
|
export declare const MAX_CONCURRENT_TASKS: number;
|
|
66
66
|
export declare const MAX_SUBAGENT_DEPTH = 1;
|
|
67
|
-
export declare const DEPTH_ENV_VAR = "
|
|
68
|
-
export declare const AGENT_TYPE_ENV_VAR = "
|
|
67
|
+
export declare const DEPTH_ENV_VAR = "SENPI_SUBAGENT_DEPTH";
|
|
68
|
+
export declare const AGENT_TYPE_ENV_VAR = "SENPI_AGENT_TYPE";
|
|
69
69
|
export declare const TASK_ENTRY_TYPE = "background-task.state";
|
|
70
70
|
export declare const DEFAULT_BLOCK_TIMEOUT = 60000;
|
|
71
71
|
export declare const MAX_BLOCK_TIMEOUT = 300000;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/background-task/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAE5C,MAAM,MAAM,YAAY,GAAG;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;CACtC,CAAC;AAEF,MAAM,MAAM,UAAU,GACnB;IACA,IAAI,EAAE,sBAAsB,CAAC;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAChB,GACD;IACA,IAAI,EAAE,oBAAoB,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAChB,CAAC;AAEL,MAAM,MAAM,YAAY,GAAG;IAC1B,OAAO,EAAE,OAAO,oBAAoB,EAAE,YAAY,CAAC;IACnD,MAAM,EAAE,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACpD,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,OAAO,GAAG,WAAW,CAAC;IACpE,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;IACxB,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,SAAS,EAAE,IAAI,CAAC;IAChB,WAAW,EAAE,IAAI,GAAG,SAAS,CAAC;IAC9B,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,eAAO,MAAM,cAAc;;;;;;;EAezB,CAAC;AAEH,MAAM,MAAM,kBAAkB,GAAG,MAAM,CAAC,OAAO,cAAc,CAAC,CAAC;AAE/D,eAAO,MAAM,sBAAsB;;;;EAQjC,CAAC;AAEH,MAAM,MAAM,0BAA0B,GAAG,MAAM,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAE/E,eAAO,MAAM,sBAAsB;;;EAGjC,CAAC;AAEH,MAAM,MAAM,0BAA0B,GAAG,MAAM,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAE/E,eAAO,MAAM,oBAAoB,QAAW,CAAC;AAC7C,eAAO,MAAM,kBAAkB,IAAI,CAAC;AACpC,eAAO,MAAM,aAAa,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/background-task/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAE5C,MAAM,MAAM,YAAY,GAAG;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;CACtC,CAAC;AAEF,MAAM,MAAM,UAAU,GACnB;IACA,IAAI,EAAE,sBAAsB,CAAC;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAChB,GACD;IACA,IAAI,EAAE,oBAAoB,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAChB,CAAC;AAEL,MAAM,MAAM,YAAY,GAAG;IAC1B,OAAO,EAAE,OAAO,oBAAoB,EAAE,YAAY,CAAC;IACnD,MAAM,EAAE,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACpD,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,OAAO,GAAG,WAAW,CAAC;IACpE,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;IACxB,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,SAAS,EAAE,IAAI,CAAC;IAChB,WAAW,EAAE,IAAI,GAAG,SAAS,CAAC;IAC9B,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,eAAO,MAAM,cAAc;;;;;;;EAezB,CAAC;AAEH,MAAM,MAAM,kBAAkB,GAAG,MAAM,CAAC,OAAO,cAAc,CAAC,CAAC;AAE/D,eAAO,MAAM,sBAAsB;;;;EAQjC,CAAC;AAEH,MAAM,MAAM,0BAA0B,GAAG,MAAM,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAE/E,eAAO,MAAM,sBAAsB;;;EAGjC,CAAC;AAEH,MAAM,MAAM,0BAA0B,GAAG,MAAM,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAE/E,eAAO,MAAM,oBAAoB,QAAW,CAAC;AAC7C,eAAO,MAAM,kBAAkB,IAAI,CAAC;AACpC,eAAO,MAAM,aAAa,yBAAyB,CAAC;AACpD,eAAO,MAAM,kBAAkB,qBAAqB,CAAC;AACrD,eAAO,MAAM,eAAe,0BAA0B,CAAC;AACvD,eAAO,MAAM,qBAAqB,QAAQ,CAAC;AAC3C,eAAO,MAAM,iBAAiB,SAAS,CAAC","sourcesContent":["import { type Static, Type } from \"typebox\";\n\nexport type SpawnOptions = {\n\tprompt: string;\n\tcwd: string;\n\tmodel?: string;\n\tagentType?: string;\n\tsessionPath?: string;\n\tpermissionFlag?: string;\n\tsignal?: AbortSignal;\n\tenv?: Record<string, string>;\n\tonEvent?: (event: SpawnEvent) => void;\n};\n\nexport type SpawnEvent =\n\t| {\n\t\t\ttype: \"tool_execution_start\";\n\t\t\ttoolCallId: string;\n\t\t\ttoolName: string;\n\t }\n\t| {\n\t\t\ttype: \"tool_execution_end\";\n\t\t\ttoolCallId: string;\n\t\t\ttoolName: string;\n\t };\n\nexport type SpawnedAgent = {\n\tprocess: import(\"node:child_process\").ChildProcess;\n\tresult: Promise<{ text: string; exitCode: number }>;\n};\n\nexport type BackgroundTask = {\n\tid: string;\n\tdescription: string;\n\tprompt: string;\n\tmodel: string | undefined;\n\tagentType: string | undefined;\n\tstatus: \"pending\" | \"running\" | \"completed\" | \"error\" | \"cancelled\";\n\tpid: number | undefined;\n\tsessionPath: string | undefined;\n\tactiveToolNames: string[];\n\tstartedAt: Date;\n\tcompletedAt: Date | undefined;\n\tresult: string | undefined;\n\terror: string | undefined;\n\tparentSessionId: string;\n};\n\nexport const TaskToolParams = Type.Object({\n\tdescription: Type.String({ description: \"A short (3-5 words) description of the task\" }),\n\tprompt: Type.String({ description: \"The task for the agent to perform\" }),\n\trun_in_background: Type.Boolean({\n\t\tdescription:\n\t\t\t\"REQUIRED. true=async (returns task_id, system notifies on completion), false=sync (waits for result).\",\n\t}),\n\tsession_id: Type.Optional(Type.String({ description: \"Existing Task session to continue\" })),\n\tmodel: Type.Optional(Type.String({ description: \"Model to use for this task\" })),\n\tagent_type: Type.Optional(\n\t\tType.String({\n\t\t\tdescription:\n\t\t\t\t\"Agent type to use for this task (e.g. 'explore', 'general'). Determines available tools and permissions.\",\n\t\t}),\n\t),\n});\n\nexport type TaskToolParamsType = Static<typeof TaskToolParams>;\n\nexport const BackgroundOutputParams = Type.Object({\n\ttask_id: Type.String({ description: \"Task ID to get output from\" }),\n\tblock: Type.Optional(\n\t\tType.Boolean({\n\t\t\tdescription: \"Wait for completion (default: false). System notifies when done, so blocking is rarely needed.\",\n\t\t}),\n\t),\n\ttimeout: Type.Optional(Type.Number({ description: \"Max wait time in ms (default: 60000, max: 300000)\" })),\n});\n\nexport type BackgroundOutputParamsType = Static<typeof BackgroundOutputParams>;\n\nexport const BackgroundCancelParams = Type.Object({\n\ttaskId: Type.Optional(Type.String({ description: \"Task ID to cancel (required if all=false)\" })),\n\tall: Type.Optional(Type.Boolean({ description: \"Cancel all running background tasks (default: false)\" })),\n});\n\nexport type BackgroundCancelParamsType = Static<typeof BackgroundCancelParams>;\n\nexport const MAX_CONCURRENT_TASKS = Infinity;\nexport const MAX_SUBAGENT_DEPTH = 1;\nexport const DEPTH_ENV_VAR = \"SENPI_SUBAGENT_DEPTH\";\nexport const AGENT_TYPE_ENV_VAR = \"SENPI_AGENT_TYPE\";\nexport const TASK_ENTRY_TYPE = \"background-task.state\";\nexport const DEFAULT_BLOCK_TIMEOUT = 60000;\nexport const MAX_BLOCK_TIMEOUT = 300000;\n"]}
|
|
@@ -24,8 +24,8 @@ export const BackgroundCancelParams = Type.Object({
|
|
|
24
24
|
});
|
|
25
25
|
export const MAX_CONCURRENT_TASKS = Infinity;
|
|
26
26
|
export const MAX_SUBAGENT_DEPTH = 1;
|
|
27
|
-
export const DEPTH_ENV_VAR = "
|
|
28
|
-
export const AGENT_TYPE_ENV_VAR = "
|
|
27
|
+
export const DEPTH_ENV_VAR = "SENPI_SUBAGENT_DEPTH";
|
|
28
|
+
export const AGENT_TYPE_ENV_VAR = "SENPI_AGENT_TYPE";
|
|
29
29
|
export const TASK_ENTRY_TYPE = "background-task.state";
|
|
30
30
|
export const DEFAULT_BLOCK_TIMEOUT = 60000;
|
|
31
31
|
export const MAX_BLOCK_TIMEOUT = 300000;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/background-task/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,IAAI,EAAE,MAAM,SAAS,CAAC;AAgD5C,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,CAAC,MAAM,CAAC;IACzC,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,6CAA6C,EAAE,CAAC;IACxF,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,mCAAmC,EAAE,CAAC;IACzE,iBAAiB,EAAE,IAAI,CAAC,OAAO,CAAC;QAC/B,WAAW,EACV,uGAAuG;KACxG,CAAC;IACF,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,mCAAmC,EAAE,CAAC,CAAC;IAC5F,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,4BAA4B,EAAE,CAAC,CAAC;IAChF,UAAU,EAAE,IAAI,CAAC,QAAQ,CACxB,IAAI,CAAC,MAAM,CAAC;QACX,WAAW,EACV,0GAA0G;KAC3G,CAAC,CACF;CACD,CAAC,CAAC;AAIH,MAAM,CAAC,MAAM,sBAAsB,GAAG,IAAI,CAAC,MAAM,CAAC;IACjD,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,4BAA4B,EAAE,CAAC;IACnE,KAAK,EAAE,IAAI,CAAC,QAAQ,CACnB,IAAI,CAAC,OAAO,CAAC;QACZ,WAAW,EAAE,gGAAgG;KAC7G,CAAC,CACF;IACD,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,mDAAmD,EAAE,CAAC,CAAC;CACzG,CAAC,CAAC;AAIH,MAAM,CAAC,MAAM,sBAAsB,GAAG,IAAI,CAAC,MAAM,CAAC;IACjD,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,2CAA2C,EAAE,CAAC,CAAC;IAChG,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,WAAW,EAAE,sDAAsD,EAAE,CAAC,CAAC;CACzG,CAAC,CAAC;AAIH,MAAM,CAAC,MAAM,oBAAoB,GAAG,QAAQ,CAAC;AAC7C,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC;AACpC,MAAM,CAAC,MAAM,aAAa,GAAG,
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/background-task/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,IAAI,EAAE,MAAM,SAAS,CAAC;AAgD5C,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,CAAC,MAAM,CAAC;IACzC,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,6CAA6C,EAAE,CAAC;IACxF,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,mCAAmC,EAAE,CAAC;IACzE,iBAAiB,EAAE,IAAI,CAAC,OAAO,CAAC;QAC/B,WAAW,EACV,uGAAuG;KACxG,CAAC;IACF,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,mCAAmC,EAAE,CAAC,CAAC;IAC5F,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,4BAA4B,EAAE,CAAC,CAAC;IAChF,UAAU,EAAE,IAAI,CAAC,QAAQ,CACxB,IAAI,CAAC,MAAM,CAAC;QACX,WAAW,EACV,0GAA0G;KAC3G,CAAC,CACF;CACD,CAAC,CAAC;AAIH,MAAM,CAAC,MAAM,sBAAsB,GAAG,IAAI,CAAC,MAAM,CAAC;IACjD,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,4BAA4B,EAAE,CAAC;IACnE,KAAK,EAAE,IAAI,CAAC,QAAQ,CACnB,IAAI,CAAC,OAAO,CAAC;QACZ,WAAW,EAAE,gGAAgG;KAC7G,CAAC,CACF;IACD,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,mDAAmD,EAAE,CAAC,CAAC;CACzG,CAAC,CAAC;AAIH,MAAM,CAAC,MAAM,sBAAsB,GAAG,IAAI,CAAC,MAAM,CAAC;IACjD,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,2CAA2C,EAAE,CAAC,CAAC;IAChG,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,WAAW,EAAE,sDAAsD,EAAE,CAAC,CAAC;CACzG,CAAC,CAAC;AAIH,MAAM,CAAC,MAAM,oBAAoB,GAAG,QAAQ,CAAC;AAC7C,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC;AACpC,MAAM,CAAC,MAAM,aAAa,GAAG,sBAAsB,CAAC;AACpD,MAAM,CAAC,MAAM,kBAAkB,GAAG,kBAAkB,CAAC;AACrD,MAAM,CAAC,MAAM,eAAe,GAAG,uBAAuB,CAAC;AACvD,MAAM,CAAC,MAAM,qBAAqB,GAAG,KAAK,CAAC;AAC3C,MAAM,CAAC,MAAM,iBAAiB,GAAG,MAAM,CAAC","sourcesContent":["import { type Static, Type } from \"typebox\";\n\nexport type SpawnOptions = {\n\tprompt: string;\n\tcwd: string;\n\tmodel?: string;\n\tagentType?: string;\n\tsessionPath?: string;\n\tpermissionFlag?: string;\n\tsignal?: AbortSignal;\n\tenv?: Record<string, string>;\n\tonEvent?: (event: SpawnEvent) => void;\n};\n\nexport type SpawnEvent =\n\t| {\n\t\t\ttype: \"tool_execution_start\";\n\t\t\ttoolCallId: string;\n\t\t\ttoolName: string;\n\t }\n\t| {\n\t\t\ttype: \"tool_execution_end\";\n\t\t\ttoolCallId: string;\n\t\t\ttoolName: string;\n\t };\n\nexport type SpawnedAgent = {\n\tprocess: import(\"node:child_process\").ChildProcess;\n\tresult: Promise<{ text: string; exitCode: number }>;\n};\n\nexport type BackgroundTask = {\n\tid: string;\n\tdescription: string;\n\tprompt: string;\n\tmodel: string | undefined;\n\tagentType: string | undefined;\n\tstatus: \"pending\" | \"running\" | \"completed\" | \"error\" | \"cancelled\";\n\tpid: number | undefined;\n\tsessionPath: string | undefined;\n\tactiveToolNames: string[];\n\tstartedAt: Date;\n\tcompletedAt: Date | undefined;\n\tresult: string | undefined;\n\terror: string | undefined;\n\tparentSessionId: string;\n};\n\nexport const TaskToolParams = Type.Object({\n\tdescription: Type.String({ description: \"A short (3-5 words) description of the task\" }),\n\tprompt: Type.String({ description: \"The task for the agent to perform\" }),\n\trun_in_background: Type.Boolean({\n\t\tdescription:\n\t\t\t\"REQUIRED. true=async (returns task_id, system notifies on completion), false=sync (waits for result).\",\n\t}),\n\tsession_id: Type.Optional(Type.String({ description: \"Existing Task session to continue\" })),\n\tmodel: Type.Optional(Type.String({ description: \"Model to use for this task\" })),\n\tagent_type: Type.Optional(\n\t\tType.String({\n\t\t\tdescription:\n\t\t\t\t\"Agent type to use for this task (e.g. 'explore', 'general'). Determines available tools and permissions.\",\n\t\t}),\n\t),\n});\n\nexport type TaskToolParamsType = Static<typeof TaskToolParams>;\n\nexport const BackgroundOutputParams = Type.Object({\n\ttask_id: Type.String({ description: \"Task ID to get output from\" }),\n\tblock: Type.Optional(\n\t\tType.Boolean({\n\t\t\tdescription: \"Wait for completion (default: false). System notifies when done, so blocking is rarely needed.\",\n\t\t}),\n\t),\n\ttimeout: Type.Optional(Type.Number({ description: \"Max wait time in ms (default: 60000, max: 300000)\" })),\n});\n\nexport type BackgroundOutputParamsType = Static<typeof BackgroundOutputParams>;\n\nexport const BackgroundCancelParams = Type.Object({\n\ttaskId: Type.Optional(Type.String({ description: \"Task ID to cancel (required if all=false)\" })),\n\tall: Type.Optional(Type.Boolean({ description: \"Cancel all running background tasks (default: false)\" })),\n});\n\nexport type BackgroundCancelParamsType = Static<typeof BackgroundCancelParams>;\n\nexport const MAX_CONCURRENT_TASKS = Infinity;\nexport const MAX_SUBAGENT_DEPTH = 1;\nexport const DEPTH_ENV_VAR = \"SENPI_SUBAGENT_DEPTH\";\nexport const AGENT_TYPE_ENV_VAR = \"SENPI_AGENT_TYPE\";\nexport const TASK_ENTRY_TYPE = \"background-task.state\";\nexport const DEFAULT_BLOCK_TIMEOUT = 60000;\nexport const MAX_BLOCK_TIMEOUT = 300000;\n"]}
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import type { ImageContent, TextContent } from "@earendil-works/pi-ai";
|
|
2
2
|
import type { CustomMessage } from "../../messages.js";
|
|
3
3
|
import type { ExtensionAPI } from "../types.js";
|
|
4
|
-
export declare const
|
|
5
|
-
export declare const
|
|
4
|
+
export declare const SENPI_SYSTEM_PREFIX = "[system:senpi]";
|
|
5
|
+
export declare const SENPI_CONVERSATION_EVENT = "senpi:conversation";
|
|
6
6
|
export type BuiltinSystemMessageRoute = "background-task.notification" | "todotools.continuation";
|
|
7
|
-
export type
|
|
8
|
-
export interface
|
|
7
|
+
export type SenpiConversationAction = "injected" | "failed";
|
|
8
|
+
export interface SenpiConversationEvent {
|
|
9
9
|
version: 1;
|
|
10
10
|
source: "builtin";
|
|
11
|
-
action:
|
|
11
|
+
action: SenpiConversationAction;
|
|
12
12
|
route: BuiltinSystemMessageRoute;
|
|
13
13
|
sessionId?: string;
|
|
14
14
|
timestamp: number;
|
|
15
15
|
conversation: {
|
|
16
|
-
prefix: typeof
|
|
16
|
+
prefix: typeof SENPI_SYSTEM_PREFIX;
|
|
17
17
|
kind: "custom_message" | "user_message";
|
|
18
18
|
customType?: string;
|
|
19
19
|
deliverAs?: "steer" | "followUp";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"system-messages.d.ts","sourceRoot":"","sources":["../../../../src/core/extensions/builtin/system-messages.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACvE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,eAAO,MAAM,
|
|
1
|
+
{"version":3,"file":"system-messages.d.ts","sourceRoot":"","sources":["../../../../src/core/extensions/builtin/system-messages.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACvE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,eAAO,MAAM,mBAAmB,mBAAmB,CAAC;AACpD,eAAO,MAAM,wBAAwB,uBAAuB,CAAC;AAE7D,MAAM,MAAM,yBAAyB,GAAG,8BAA8B,GAAG,wBAAwB,CAAC;AAClG,MAAM,MAAM,uBAAuB,GAAG,UAAU,GAAG,QAAQ,CAAC;AAE5D,MAAM,WAAW,sBAAsB;IACtC,OAAO,EAAE,CAAC,CAAC;IACX,MAAM,EAAE,SAAS,CAAC;IAClB,MAAM,EAAE,uBAAuB,CAAC;IAChC,KAAK,EAAE,yBAAyB,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE;QACb,MAAM,EAAE,OAAO,mBAAmB,CAAC;QACnC,IAAI,EAAE,gBAAgB,GAAG,cAAc,CAAC;QACxC,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,SAAS,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;QACjC,WAAW,CAAC,EAAE,OAAO,CAAC;KACtB,CAAC;IACF,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,KAAK,yBAAyB,GAAG;IAChC,SAAS,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,KAAK,2BAA2B,GAAG;IAClC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE,OAAO,GAAG,UAAU,GAAG,UAAU,CAAC;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAqFF,wBAAgB,sBAAsB,CACrC,EAAE,EAAE,YAAY,EAChB,KAAK,EAAE,yBAAyB,EAChC,OAAO,EAAE,MAAM,GAAG,CAAC,WAAW,GAAG,YAAY,CAAC,EAAE,EAChD,OAAO,CAAC,EAAE,yBAAyB,GACjC,IAAI,CAqBN;AAED,wBAAgB,wBAAwB,CAAC,QAAQ,EAChD,EAAE,EAAE,YAAY,EAChB,KAAK,EAAE,yBAAyB,EAChC,OAAO,EAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,EAAE,SAAS,GAAG,YAAY,GAAG,SAAS,GAAG,SAAS,CAAC,EACxF,OAAO,CAAC,EAAE,2BAA2B,GACnC,IAAI,CAgCN;AAED,wBAAgB,+BAA+B,CAC9C,EAAE,EAAE,YAAY,EAChB,IAAI,EAAE;IACL,KAAK,EAAE,yBAAyB,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,gBAAgB,GAAG,cAAc,CAAC;IACxC,OAAO,EAAE,MAAM,GAAG,CAAC,WAAW,GAAG,YAAY,CAAC,EAAE,CAAC;IACjD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;IACjC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;CACrB,GACC,IAAI,CAiBN","sourcesContent":["import type { ImageContent, TextContent } from \"@earendil-works/pi-ai\";\nimport type { CustomMessage } from \"../../messages.js\";\nimport type { ExtensionAPI } from \"../types.js\";\n\nexport const SENPI_SYSTEM_PREFIX = \"[system:senpi]\";\nexport const SENPI_CONVERSATION_EVENT = \"senpi:conversation\";\n\nexport type BuiltinSystemMessageRoute = \"background-task.notification\" | \"todotools.continuation\";\nexport type SenpiConversationAction = \"injected\" | \"failed\";\n\nexport interface SenpiConversationEvent {\n\tversion: 1;\n\tsource: \"builtin\";\n\taction: SenpiConversationAction;\n\troute: BuiltinSystemMessageRoute;\n\tsessionId?: string;\n\ttimestamp: number;\n\tconversation: {\n\t\tprefix: typeof SENPI_SYSTEM_PREFIX;\n\t\tkind: \"custom_message\" | \"user_message\";\n\t\tcustomType?: string;\n\t\tdeliverAs?: \"steer\" | \"followUp\";\n\t\ttriggerTurn?: boolean;\n\t};\n\ttext: string;\n\terrorMessage?: string;\n}\n\ntype BuiltinUserMessageOptions = {\n\tdeliverAs?: \"steer\" | \"followUp\";\n\tsessionId?: string;\n};\n\ntype BuiltinCustomMessageOptions = {\n\ttriggerTurn?: boolean;\n\tdeliverAs?: \"steer\" | \"followUp\" | \"nextTurn\";\n\tsessionId?: string;\n};\n\nfunction prefixText(text: string): string {\n\treturn text.startsWith(SENPI_SYSTEM_PREFIX) ? text : `${SENPI_SYSTEM_PREFIX}\\n${text}`;\n}\n\nfunction prefixContent(content: string | (TextContent | ImageContent)[]): string | (TextContent | ImageContent)[] {\n\tif (typeof content === \"string\") {\n\t\treturn prefixText(content);\n\t}\n\n\tconst firstTextIndex = content.findIndex((part) => part.type === \"text\");\n\tif (firstTextIndex === -1) {\n\t\treturn [{ type: \"text\", text: SENPI_SYSTEM_PREFIX }, ...content];\n\t}\n\n\treturn content.map((part, index) => {\n\t\tif (part.type !== \"text\" || index !== firstTextIndex) {\n\t\t\treturn part;\n\t\t}\n\n\t\treturn {\n\t\t\t...part,\n\t\t\ttext: prefixText(part.text),\n\t\t};\n\t});\n}\n\nfunction extractText(content: string | (TextContent | ImageContent)[]): string {\n\tif (typeof content === \"string\") {\n\t\treturn content;\n\t}\n\n\treturn content\n\t\t.filter((part): part is TextContent => part.type === \"text\")\n\t\t.map((part) => part.text)\n\t\t.join(\"\\n\");\n}\n\nfunction emitSenpiConversationEvent(pi: ExtensionAPI, event: SenpiConversationEvent): void {\n\tpi.events.emit(SENPI_CONVERSATION_EVENT, event);\n}\n\nfunction createBaseEvent(args: {\n\taction: SenpiConversationAction;\n\troute: BuiltinSystemMessageRoute;\n\tsessionId?: string;\n\tkind: \"custom_message\" | \"user_message\";\n\tcustomType?: string;\n\tdeliverAs?: \"steer\" | \"followUp\";\n\ttriggerTurn?: boolean;\n\ttext: string;\n\terrorMessage?: string;\n}): SenpiConversationEvent {\n\treturn {\n\t\tversion: 1,\n\t\tsource: \"builtin\",\n\t\taction: args.action,\n\t\troute: args.route,\n\t\tsessionId: args.sessionId,\n\t\ttimestamp: Date.now(),\n\t\tconversation: {\n\t\t\tprefix: SENPI_SYSTEM_PREFIX,\n\t\t\tkind: args.kind,\n\t\t\tcustomType: args.customType,\n\t\t\tdeliverAs: args.deliverAs,\n\t\t\ttriggerTurn: args.triggerTurn,\n\t\t},\n\t\ttext: args.text,\n\t\terrorMessage: args.errorMessage,\n\t};\n}\n\nfunction hasUserMessageOptions(\n\toptions: BuiltinUserMessageOptions | undefined,\n): options is BuiltinUserMessageOptions & { deliverAs: \"steer\" | \"followUp\" } {\n\treturn options?.deliverAs !== undefined;\n}\n\nfunction hasCustomMessageOptions(\n\toptions: BuiltinCustomMessageOptions | undefined,\n): options is BuiltinCustomMessageOptions & { triggerTurn?: boolean; deliverAs?: \"steer\" | \"followUp\" | \"nextTurn\" } {\n\treturn options?.triggerTurn === true || options?.deliverAs !== undefined;\n}\n\nexport function sendBuiltinUserMessage(\n\tpi: ExtensionAPI,\n\troute: BuiltinSystemMessageRoute,\n\tcontent: string | (TextContent | ImageContent)[],\n\toptions?: BuiltinUserMessageOptions,\n): void {\n\tconst prefixedContent = prefixContent(content);\n\n\temitSenpiConversationEvent(\n\t\tpi,\n\t\tcreateBaseEvent({\n\t\t\taction: \"injected\",\n\t\t\troute,\n\t\t\tsessionId: options?.sessionId,\n\t\t\tkind: \"user_message\",\n\t\t\ttext: extractText(prefixedContent),\n\t\t\tdeliverAs: options?.deliverAs,\n\t\t}),\n\t);\n\n\tif (hasUserMessageOptions(options)) {\n\t\tpi.sendUserMessage(prefixedContent, { deliverAs: options.deliverAs });\n\t\treturn;\n\t}\n\n\tpi.sendUserMessage(prefixedContent);\n}\n\nexport function sendBuiltinCustomMessage<TDetails>(\n\tpi: ExtensionAPI,\n\troute: BuiltinSystemMessageRoute,\n\tmessage: Pick<CustomMessage<TDetails>, \"content\" | \"customType\" | \"details\" | \"display\">,\n\toptions?: BuiltinCustomMessageOptions,\n): void {\n\tconst prefixedContent = prefixContent(message.content);\n\tconst deliverAs = options?.deliverAs === \"nextTurn\" ? undefined : options?.deliverAs;\n\n\temitSenpiConversationEvent(\n\t\tpi,\n\t\tcreateBaseEvent({\n\t\t\taction: \"injected\",\n\t\t\troute,\n\t\t\tsessionId: options?.sessionId,\n\t\t\tkind: \"custom_message\",\n\t\t\tcustomType: message.customType,\n\t\t\ttext: extractText(prefixedContent),\n\t\t\tdeliverAs,\n\t\t\ttriggerTurn: options?.triggerTurn,\n\t\t}),\n\t);\n\n\tconst prefixedMessage = {\n\t\t...message,\n\t\tcontent: prefixedContent,\n\t};\n\n\tif (hasCustomMessageOptions(options)) {\n\t\tpi.sendMessage(prefixedMessage, {\n\t\t\ttriggerTurn: options.triggerTurn,\n\t\t\tdeliverAs: options.deliverAs,\n\t\t});\n\t\treturn;\n\t}\n\n\tpi.sendMessage(prefixedMessage);\n}\n\nexport function emitBuiltinSystemMessageFailure(\n\tpi: ExtensionAPI,\n\targs: {\n\t\troute: BuiltinSystemMessageRoute;\n\t\tsessionId?: string;\n\t\tkind: \"custom_message\" | \"user_message\";\n\t\tcontent: string | (TextContent | ImageContent)[];\n\t\tcustomType?: string;\n\t\tdeliverAs?: \"steer\" | \"followUp\";\n\t\ttriggerTurn?: boolean;\n\t\terrorMessage: string;\n\t},\n): void {\n\tconst prefixedContent = prefixContent(args.content);\n\n\temitSenpiConversationEvent(\n\t\tpi,\n\t\tcreateBaseEvent({\n\t\t\taction: \"failed\",\n\t\t\troute: args.route,\n\t\t\tsessionId: args.sessionId,\n\t\t\tkind: args.kind,\n\t\t\tcustomType: args.customType,\n\t\t\ttext: extractText(prefixedContent),\n\t\t\tdeliverAs: args.deliverAs,\n\t\t\ttriggerTurn: args.triggerTurn,\n\t\t\terrorMessage: args.errorMessage,\n\t\t}),\n\t);\n}\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export const
|
|
2
|
-
export const
|
|
1
|
+
export const SENPI_SYSTEM_PREFIX = "[system:senpi]";
|
|
2
|
+
export const SENPI_CONVERSATION_EVENT = "senpi:conversation";
|
|
3
3
|
function prefixText(text) {
|
|
4
|
-
return text.startsWith(
|
|
4
|
+
return text.startsWith(SENPI_SYSTEM_PREFIX) ? text : `${SENPI_SYSTEM_PREFIX}\n${text}`;
|
|
5
5
|
}
|
|
6
6
|
function prefixContent(content) {
|
|
7
7
|
if (typeof content === "string") {
|
|
@@ -9,7 +9,7 @@ function prefixContent(content) {
|
|
|
9
9
|
}
|
|
10
10
|
const firstTextIndex = content.findIndex((part) => part.type === "text");
|
|
11
11
|
if (firstTextIndex === -1) {
|
|
12
|
-
return [{ type: "text", text:
|
|
12
|
+
return [{ type: "text", text: SENPI_SYSTEM_PREFIX }, ...content];
|
|
13
13
|
}
|
|
14
14
|
return content.map((part, index) => {
|
|
15
15
|
if (part.type !== "text" || index !== firstTextIndex) {
|
|
@@ -30,8 +30,8 @@ function extractText(content) {
|
|
|
30
30
|
.map((part) => part.text)
|
|
31
31
|
.join("\n");
|
|
32
32
|
}
|
|
33
|
-
function
|
|
34
|
-
pi.events.emit(
|
|
33
|
+
function emitSenpiConversationEvent(pi, event) {
|
|
34
|
+
pi.events.emit(SENPI_CONVERSATION_EVENT, event);
|
|
35
35
|
}
|
|
36
36
|
function createBaseEvent(args) {
|
|
37
37
|
return {
|
|
@@ -42,7 +42,7 @@ function createBaseEvent(args) {
|
|
|
42
42
|
sessionId: args.sessionId,
|
|
43
43
|
timestamp: Date.now(),
|
|
44
44
|
conversation: {
|
|
45
|
-
prefix:
|
|
45
|
+
prefix: SENPI_SYSTEM_PREFIX,
|
|
46
46
|
kind: args.kind,
|
|
47
47
|
customType: args.customType,
|
|
48
48
|
deliverAs: args.deliverAs,
|
|
@@ -60,7 +60,7 @@ function hasCustomMessageOptions(options) {
|
|
|
60
60
|
}
|
|
61
61
|
export function sendBuiltinUserMessage(pi, route, content, options) {
|
|
62
62
|
const prefixedContent = prefixContent(content);
|
|
63
|
-
|
|
63
|
+
emitSenpiConversationEvent(pi, createBaseEvent({
|
|
64
64
|
action: "injected",
|
|
65
65
|
route,
|
|
66
66
|
sessionId: options?.sessionId,
|
|
@@ -77,7 +77,7 @@ export function sendBuiltinUserMessage(pi, route, content, options) {
|
|
|
77
77
|
export function sendBuiltinCustomMessage(pi, route, message, options) {
|
|
78
78
|
const prefixedContent = prefixContent(message.content);
|
|
79
79
|
const deliverAs = options?.deliverAs === "nextTurn" ? undefined : options?.deliverAs;
|
|
80
|
-
|
|
80
|
+
emitSenpiConversationEvent(pi, createBaseEvent({
|
|
81
81
|
action: "injected",
|
|
82
82
|
route,
|
|
83
83
|
sessionId: options?.sessionId,
|
|
@@ -102,7 +102,7 @@ export function sendBuiltinCustomMessage(pi, route, message, options) {
|
|
|
102
102
|
}
|
|
103
103
|
export function emitBuiltinSystemMessageFailure(pi, args) {
|
|
104
104
|
const prefixedContent = prefixContent(args.content);
|
|
105
|
-
|
|
105
|
+
emitSenpiConversationEvent(pi, createBaseEvent({
|
|
106
106
|
action: "failed",
|
|
107
107
|
route: args.route,
|
|
108
108
|
sessionId: args.sessionId,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"system-messages.js","sourceRoot":"","sources":["../../../../src/core/extensions/builtin/system-messages.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ImageContent, TextContent } from \"@earendil-works/pi-ai\";\nimport type { CustomMessage } from \"../../messages.js\";\nimport type { ExtensionAPI } from \"../types.js\";\n\nexport const SANEPI_SYSTEM_PREFIX = \"[system:senpi]\";\nexport const SANEPI_CONVERSATION_EVENT = \"sanepi:conversation\";\n\nexport type BuiltinSystemMessageRoute = \"background-task.notification\" | \"todotools.continuation\";\nexport type SanepiConversationAction = \"injected\" | \"failed\";\n\nexport interface SanepiConversationEvent {\n\tversion: 1;\n\tsource: \"builtin\";\n\taction: SanepiConversationAction;\n\troute: BuiltinSystemMessageRoute;\n\tsessionId?: string;\n\ttimestamp: number;\n\tconversation: {\n\t\tprefix: typeof SANEPI_SYSTEM_PREFIX;\n\t\tkind: \"custom_message\" | \"user_message\";\n\t\tcustomType?: string;\n\t\tdeliverAs?: \"steer\" | \"followUp\";\n\t\ttriggerTurn?: boolean;\n\t};\n\ttext: string;\n\terrorMessage?: string;\n}\n\ntype BuiltinUserMessageOptions = {\n\tdeliverAs?: \"steer\" | \"followUp\";\n\tsessionId?: string;\n};\n\ntype BuiltinCustomMessageOptions = {\n\ttriggerTurn?: boolean;\n\tdeliverAs?: \"steer\" | \"followUp\" | \"nextTurn\";\n\tsessionId?: string;\n};\n\nfunction prefixText(text: string): string {\n\treturn text.startsWith(SANEPI_SYSTEM_PREFIX) ? text : `${SANEPI_SYSTEM_PREFIX}\\n${text}`;\n}\n\nfunction prefixContent(content: string | (TextContent | ImageContent)[]): string | (TextContent | ImageContent)[] {\n\tif (typeof content === \"string\") {\n\t\treturn prefixText(content);\n\t}\n\n\tconst firstTextIndex = content.findIndex((part) => part.type === \"text\");\n\tif (firstTextIndex === -1) {\n\t\treturn [{ type: \"text\", text: SANEPI_SYSTEM_PREFIX }, ...content];\n\t}\n\n\treturn content.map((part, index) => {\n\t\tif (part.type !== \"text\" || index !== firstTextIndex) {\n\t\t\treturn part;\n\t\t}\n\n\t\treturn {\n\t\t\t...part,\n\t\t\ttext: prefixText(part.text),\n\t\t};\n\t});\n}\n\nfunction extractText(content: string | (TextContent | ImageContent)[]): string {\n\tif (typeof content === \"string\") {\n\t\treturn content;\n\t}\n\n\treturn content\n\t\t.filter((part): part is TextContent => part.type === \"text\")\n\t\t.map((part) => part.text)\n\t\t.join(\"\\n\");\n}\n\nfunction emitSanepiConversationEvent(pi: ExtensionAPI, event: SanepiConversationEvent): void {\n\tpi.events.emit(SANEPI_CONVERSATION_EVENT, event);\n}\n\nfunction createBaseEvent(args: {\n\taction: SanepiConversationAction;\n\troute: BuiltinSystemMessageRoute;\n\tsessionId?: string;\n\tkind: \"custom_message\" | \"user_message\";\n\tcustomType?: string;\n\tdeliverAs?: \"steer\" | \"followUp\";\n\ttriggerTurn?: boolean;\n\ttext: string;\n\terrorMessage?: string;\n}): SanepiConversationEvent {\n\treturn {\n\t\tversion: 1,\n\t\tsource: \"builtin\",\n\t\taction: args.action,\n\t\troute: args.route,\n\t\tsessionId: args.sessionId,\n\t\ttimestamp: Date.now(),\n\t\tconversation: {\n\t\t\tprefix: SANEPI_SYSTEM_PREFIX,\n\t\t\tkind: args.kind,\n\t\t\tcustomType: args.customType,\n\t\t\tdeliverAs: args.deliverAs,\n\t\t\ttriggerTurn: args.triggerTurn,\n\t\t},\n\t\ttext: args.text,\n\t\terrorMessage: args.errorMessage,\n\t};\n}\n\nfunction hasUserMessageOptions(\n\toptions: BuiltinUserMessageOptions | undefined,\n): options is BuiltinUserMessageOptions & { deliverAs: \"steer\" | \"followUp\" } {\n\treturn options?.deliverAs !== undefined;\n}\n\nfunction hasCustomMessageOptions(\n\toptions: BuiltinCustomMessageOptions | undefined,\n): options is BuiltinCustomMessageOptions & { triggerTurn?: boolean; deliverAs?: \"steer\" | \"followUp\" | \"nextTurn\" } {\n\treturn options?.triggerTurn === true || options?.deliverAs !== undefined;\n}\n\nexport function sendBuiltinUserMessage(\n\tpi: ExtensionAPI,\n\troute: BuiltinSystemMessageRoute,\n\tcontent: string | (TextContent | ImageContent)[],\n\toptions?: BuiltinUserMessageOptions,\n): void {\n\tconst prefixedContent = prefixContent(content);\n\n\temitSanepiConversationEvent(\n\t\tpi,\n\t\tcreateBaseEvent({\n\t\t\taction: \"injected\",\n\t\t\troute,\n\t\t\tsessionId: options?.sessionId,\n\t\t\tkind: \"user_message\",\n\t\t\ttext: extractText(prefixedContent),\n\t\t\tdeliverAs: options?.deliverAs,\n\t\t}),\n\t);\n\n\tif (hasUserMessageOptions(options)) {\n\t\tpi.sendUserMessage(prefixedContent, { deliverAs: options.deliverAs });\n\t\treturn;\n\t}\n\n\tpi.sendUserMessage(prefixedContent);\n}\n\nexport function sendBuiltinCustomMessage<TDetails>(\n\tpi: ExtensionAPI,\n\troute: BuiltinSystemMessageRoute,\n\tmessage: Pick<CustomMessage<TDetails>, \"content\" | \"customType\" | \"details\" | \"display\">,\n\toptions?: BuiltinCustomMessageOptions,\n): void {\n\tconst prefixedContent = prefixContent(message.content);\n\tconst deliverAs = options?.deliverAs === \"nextTurn\" ? undefined : options?.deliverAs;\n\n\temitSanepiConversationEvent(\n\t\tpi,\n\t\tcreateBaseEvent({\n\t\t\taction: \"injected\",\n\t\t\troute,\n\t\t\tsessionId: options?.sessionId,\n\t\t\tkind: \"custom_message\",\n\t\t\tcustomType: message.customType,\n\t\t\ttext: extractText(prefixedContent),\n\t\t\tdeliverAs,\n\t\t\ttriggerTurn: options?.triggerTurn,\n\t\t}),\n\t);\n\n\tconst prefixedMessage = {\n\t\t...message,\n\t\tcontent: prefixedContent,\n\t};\n\n\tif (hasCustomMessageOptions(options)) {\n\t\tpi.sendMessage(prefixedMessage, {\n\t\t\ttriggerTurn: options.triggerTurn,\n\t\t\tdeliverAs: options.deliverAs,\n\t\t});\n\t\treturn;\n\t}\n\n\tpi.sendMessage(prefixedMessage);\n}\n\nexport function emitBuiltinSystemMessageFailure(\n\tpi: ExtensionAPI,\n\targs: {\n\t\troute: BuiltinSystemMessageRoute;\n\t\tsessionId?: string;\n\t\tkind: \"custom_message\" | \"user_message\";\n\t\tcontent: string | (TextContent | ImageContent)[];\n\t\tcustomType?: string;\n\t\tdeliverAs?: \"steer\" | \"followUp\";\n\t\ttriggerTurn?: boolean;\n\t\terrorMessage: string;\n\t},\n): void {\n\tconst prefixedContent = prefixContent(args.content);\n\n\temitSanepiConversationEvent(\n\t\tpi,\n\t\tcreateBaseEvent({\n\t\t\taction: \"failed\",\n\t\t\troute: args.route,\n\t\t\tsessionId: args.sessionId,\n\t\t\tkind: args.kind,\n\t\t\tcustomType: args.customType,\n\t\t\ttext: extractText(prefixedContent),\n\t\t\tdeliverAs: args.deliverAs,\n\t\t\ttriggerTurn: args.triggerTurn,\n\t\t\terrorMessage: args.errorMessage,\n\t\t}),\n\t);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"system-messages.js","sourceRoot":"","sources":["../../../../src/core/extensions/builtin/system-messages.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ImageContent, TextContent } from \"@earendil-works/pi-ai\";\nimport type { CustomMessage } from \"../../messages.js\";\nimport type { ExtensionAPI } from \"../types.js\";\n\nexport const SENPI_SYSTEM_PREFIX = \"[system:senpi]\";\nexport const SENPI_CONVERSATION_EVENT = \"senpi:conversation\";\n\nexport type BuiltinSystemMessageRoute = \"background-task.notification\" | \"todotools.continuation\";\nexport type SenpiConversationAction = \"injected\" | \"failed\";\n\nexport interface SenpiConversationEvent {\n\tversion: 1;\n\tsource: \"builtin\";\n\taction: SenpiConversationAction;\n\troute: BuiltinSystemMessageRoute;\n\tsessionId?: string;\n\ttimestamp: number;\n\tconversation: {\n\t\tprefix: typeof SENPI_SYSTEM_PREFIX;\n\t\tkind: \"custom_message\" | \"user_message\";\n\t\tcustomType?: string;\n\t\tdeliverAs?: \"steer\" | \"followUp\";\n\t\ttriggerTurn?: boolean;\n\t};\n\ttext: string;\n\terrorMessage?: string;\n}\n\ntype BuiltinUserMessageOptions = {\n\tdeliverAs?: \"steer\" | \"followUp\";\n\tsessionId?: string;\n};\n\ntype BuiltinCustomMessageOptions = {\n\ttriggerTurn?: boolean;\n\tdeliverAs?: \"steer\" | \"followUp\" | \"nextTurn\";\n\tsessionId?: string;\n};\n\nfunction prefixText(text: string): string {\n\treturn text.startsWith(SENPI_SYSTEM_PREFIX) ? text : `${SENPI_SYSTEM_PREFIX}\\n${text}`;\n}\n\nfunction prefixContent(content: string | (TextContent | ImageContent)[]): string | (TextContent | ImageContent)[] {\n\tif (typeof content === \"string\") {\n\t\treturn prefixText(content);\n\t}\n\n\tconst firstTextIndex = content.findIndex((part) => part.type === \"text\");\n\tif (firstTextIndex === -1) {\n\t\treturn [{ type: \"text\", text: SENPI_SYSTEM_PREFIX }, ...content];\n\t}\n\n\treturn content.map((part, index) => {\n\t\tif (part.type !== \"text\" || index !== firstTextIndex) {\n\t\t\treturn part;\n\t\t}\n\n\t\treturn {\n\t\t\t...part,\n\t\t\ttext: prefixText(part.text),\n\t\t};\n\t});\n}\n\nfunction extractText(content: string | (TextContent | ImageContent)[]): string {\n\tif (typeof content === \"string\") {\n\t\treturn content;\n\t}\n\n\treturn content\n\t\t.filter((part): part is TextContent => part.type === \"text\")\n\t\t.map((part) => part.text)\n\t\t.join(\"\\n\");\n}\n\nfunction emitSenpiConversationEvent(pi: ExtensionAPI, event: SenpiConversationEvent): void {\n\tpi.events.emit(SENPI_CONVERSATION_EVENT, event);\n}\n\nfunction createBaseEvent(args: {\n\taction: SenpiConversationAction;\n\troute: BuiltinSystemMessageRoute;\n\tsessionId?: string;\n\tkind: \"custom_message\" | \"user_message\";\n\tcustomType?: string;\n\tdeliverAs?: \"steer\" | \"followUp\";\n\ttriggerTurn?: boolean;\n\ttext: string;\n\terrorMessage?: string;\n}): SenpiConversationEvent {\n\treturn {\n\t\tversion: 1,\n\t\tsource: \"builtin\",\n\t\taction: args.action,\n\t\troute: args.route,\n\t\tsessionId: args.sessionId,\n\t\ttimestamp: Date.now(),\n\t\tconversation: {\n\t\t\tprefix: SENPI_SYSTEM_PREFIX,\n\t\t\tkind: args.kind,\n\t\t\tcustomType: args.customType,\n\t\t\tdeliverAs: args.deliverAs,\n\t\t\ttriggerTurn: args.triggerTurn,\n\t\t},\n\t\ttext: args.text,\n\t\terrorMessage: args.errorMessage,\n\t};\n}\n\nfunction hasUserMessageOptions(\n\toptions: BuiltinUserMessageOptions | undefined,\n): options is BuiltinUserMessageOptions & { deliverAs: \"steer\" | \"followUp\" } {\n\treturn options?.deliverAs !== undefined;\n}\n\nfunction hasCustomMessageOptions(\n\toptions: BuiltinCustomMessageOptions | undefined,\n): options is BuiltinCustomMessageOptions & { triggerTurn?: boolean; deliverAs?: \"steer\" | \"followUp\" | \"nextTurn\" } {\n\treturn options?.triggerTurn === true || options?.deliverAs !== undefined;\n}\n\nexport function sendBuiltinUserMessage(\n\tpi: ExtensionAPI,\n\troute: BuiltinSystemMessageRoute,\n\tcontent: string | (TextContent | ImageContent)[],\n\toptions?: BuiltinUserMessageOptions,\n): void {\n\tconst prefixedContent = prefixContent(content);\n\n\temitSenpiConversationEvent(\n\t\tpi,\n\t\tcreateBaseEvent({\n\t\t\taction: \"injected\",\n\t\t\troute,\n\t\t\tsessionId: options?.sessionId,\n\t\t\tkind: \"user_message\",\n\t\t\ttext: extractText(prefixedContent),\n\t\t\tdeliverAs: options?.deliverAs,\n\t\t}),\n\t);\n\n\tif (hasUserMessageOptions(options)) {\n\t\tpi.sendUserMessage(prefixedContent, { deliverAs: options.deliverAs });\n\t\treturn;\n\t}\n\n\tpi.sendUserMessage(prefixedContent);\n}\n\nexport function sendBuiltinCustomMessage<TDetails>(\n\tpi: ExtensionAPI,\n\troute: BuiltinSystemMessageRoute,\n\tmessage: Pick<CustomMessage<TDetails>, \"content\" | \"customType\" | \"details\" | \"display\">,\n\toptions?: BuiltinCustomMessageOptions,\n): void {\n\tconst prefixedContent = prefixContent(message.content);\n\tconst deliverAs = options?.deliverAs === \"nextTurn\" ? undefined : options?.deliverAs;\n\n\temitSenpiConversationEvent(\n\t\tpi,\n\t\tcreateBaseEvent({\n\t\t\taction: \"injected\",\n\t\t\troute,\n\t\t\tsessionId: options?.sessionId,\n\t\t\tkind: \"custom_message\",\n\t\t\tcustomType: message.customType,\n\t\t\ttext: extractText(prefixedContent),\n\t\t\tdeliverAs,\n\t\t\ttriggerTurn: options?.triggerTurn,\n\t\t}),\n\t);\n\n\tconst prefixedMessage = {\n\t\t...message,\n\t\tcontent: prefixedContent,\n\t};\n\n\tif (hasCustomMessageOptions(options)) {\n\t\tpi.sendMessage(prefixedMessage, {\n\t\t\ttriggerTurn: options.triggerTurn,\n\t\t\tdeliverAs: options.deliverAs,\n\t\t});\n\t\treturn;\n\t}\n\n\tpi.sendMessage(prefixedMessage);\n}\n\nexport function emitBuiltinSystemMessageFailure(\n\tpi: ExtensionAPI,\n\targs: {\n\t\troute: BuiltinSystemMessageRoute;\n\t\tsessionId?: string;\n\t\tkind: \"custom_message\" | \"user_message\";\n\t\tcontent: string | (TextContent | ImageContent)[];\n\t\tcustomType?: string;\n\t\tdeliverAs?: \"steer\" | \"followUp\";\n\t\ttriggerTurn?: boolean;\n\t\terrorMessage: string;\n\t},\n): void {\n\tconst prefixedContent = prefixContent(args.content);\n\n\temitSenpiConversationEvent(\n\t\tpi,\n\t\tcreateBaseEvent({\n\t\t\taction: \"failed\",\n\t\t\troute: args.route,\n\t\t\tsessionId: args.sessionId,\n\t\t\tkind: args.kind,\n\t\t\tcustomType: args.customType,\n\t\t\ttext: extractText(prefixedContent),\n\t\t\tdeliverAs: args.deliverAs,\n\t\t\ttriggerTurn: args.triggerTurn,\n\t\t\terrorMessage: args.errorMessage,\n\t\t}),\n\t);\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type TodoItem } from "../state.js";
|
|
2
|
-
export declare const CONTINUATION_DIRECTIVE = "[SYSTEM DIRECTIVE:
|
|
2
|
+
export declare const CONTINUATION_DIRECTIVE = "[SYSTEM DIRECTIVE: SENPI - TODO CONTINUATION]\n\nIncomplete tasks remain in your todo list. Continue working on the next pending task.\n\n- FIRST: Continue the first actionable remaining task now. If an in-progress task is already done, verify it and mark it completed before moving on\n- Proceed without asking for permission\n- Mark each task complete immediately when finished\n- Do not stop until all tasks are done\n- Do not reply with refusal, deferral, or a summary-only response\n- If a task is already complete, no longer needed, or blocked, verify that and update the todo list to a terminal state instead of leaving it pending\n- If you believe all work is already complete, the system is questioning your completion claim. Critically re-examine each todo item from a skeptical perspective, verify the work was actually done correctly, and update the todo list accordingly.";
|
|
3
3
|
export declare function countIncomplete(todos: TodoItem[]): number;
|
|
4
4
|
export declare function buildContinuationPrompt(todos: TodoItem[]): string;
|
|
5
5
|
//# sourceMappingURL=prompt.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/todotools/continuation/prompt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsC,KAAK,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEhF,eAAO,MAAM,sBAAsB,
|
|
1
|
+
{"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/todotools/continuation/prompt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsC,KAAK,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEhF,eAAO,MAAM,sBAAsB,y3BAUmN,CAAC;AAEvP,wBAAgB,eAAe,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,MAAM,CAEzD;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,MAAM,CAmBjE","sourcesContent":["import { isIncompleteTodo, sanitizeTodoText, type TodoItem } from \"../state.js\";\n\nexport const CONTINUATION_DIRECTIVE = `[SYSTEM DIRECTIVE: SENPI - TODO CONTINUATION]\n\nIncomplete tasks remain in your todo list. Continue working on the next pending task.\n\n- FIRST: Continue the first actionable remaining task now. If an in-progress task is already done, verify it and mark it completed before moving on\n- Proceed without asking for permission\n- Mark each task complete immediately when finished\n- Do not stop until all tasks are done\n- Do not reply with refusal, deferral, or a summary-only response\n- If a task is already complete, no longer needed, or blocked, verify that and update the todo list to a terminal state instead of leaving it pending\n- If you believe all work is already complete, the system is questioning your completion claim. Critically re-examine each todo item from a skeptical perspective, verify the work was actually done correctly, and update the todo list accordingly.`;\n\nexport function countIncomplete(todos: TodoItem[]): number {\n\treturn todos.filter(isIncompleteTodo).length;\n}\n\nexport function buildContinuationPrompt(todos: TodoItem[]): string {\n\tif (todos.length === 0) {\n\t\treturn \"\";\n\t}\n\n\tconst completedCount = todos.filter((todo) => todo.status === \"completed\").length;\n\tconst remainingTodos = todos.filter(isIncompleteTodo);\n\tconst activeTotal = completedCount + remainingTodos.length;\n\tconst remainingLines = remainingTodos\n\t\t.map((todo) => `- [${todo.status}] ${sanitizeTodoText(todo.content)}`)\n\t\t.join(\"\\n\");\n\n\treturn `${CONTINUATION_DIRECTIVE}\n\n[Status: ${completedCount}/${activeTotal} completed, ${remainingTodos.length} remaining]\n\nRemaining tasks:\n${remainingLines}\n`;\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { isIncompleteTodo, sanitizeTodoText } from "../state.js";
|
|
2
|
-
export const CONTINUATION_DIRECTIVE = `[SYSTEM DIRECTIVE:
|
|
2
|
+
export const CONTINUATION_DIRECTIVE = `[SYSTEM DIRECTIVE: SENPI - TODO CONTINUATION]
|
|
3
3
|
|
|
4
4
|
Incomplete tasks remain in your todo list. Continue working on the next pending task.
|
|
5
5
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/todotools/continuation/prompt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAiB,MAAM,aAAa,CAAC;AAEhF,MAAM,CAAC,MAAM,sBAAsB,GAAG;;;;;;;;;;sPAUgN,CAAC;AAEvP,MAAM,UAAU,eAAe,CAAC,KAAiB,EAAU;IAC1D,OAAO,KAAK,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,MAAM,CAAC;AAAA,CAC7C;AAED,MAAM,UAAU,uBAAuB,CAAC,KAAiB,EAAU;IAClE,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,EAAE,CAAC;IACX,CAAC;IAED,MAAM,cAAc,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC,MAAM,CAAC;IAClF,MAAM,cAAc,GAAG,KAAK,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;IACtD,MAAM,WAAW,GAAG,cAAc,GAAG,cAAc,CAAC,MAAM,CAAC;IAC3D,MAAM,cAAc,GAAG,cAAc;SACnC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,IAAI,CAAC,MAAM,KAAK,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;SACrE,IAAI,CAAC,IAAI,CAAC,CAAC;IAEb,OAAO,GAAG,sBAAsB;;WAEtB,cAAc,IAAI,WAAW,eAAe,cAAc,CAAC,MAAM;;;EAG1E,cAAc;CACf,CAAC;AAAA,CACD","sourcesContent":["import { isIncompleteTodo, sanitizeTodoText, type TodoItem } from \"../state.js\";\n\nexport const CONTINUATION_DIRECTIVE = `[SYSTEM DIRECTIVE:
|
|
1
|
+
{"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/todotools/continuation/prompt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAiB,MAAM,aAAa,CAAC;AAEhF,MAAM,CAAC,MAAM,sBAAsB,GAAG;;;;;;;;;;sPAUgN,CAAC;AAEvP,MAAM,UAAU,eAAe,CAAC,KAAiB,EAAU;IAC1D,OAAO,KAAK,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,MAAM,CAAC;AAAA,CAC7C;AAED,MAAM,UAAU,uBAAuB,CAAC,KAAiB,EAAU;IAClE,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,EAAE,CAAC;IACX,CAAC;IAED,MAAM,cAAc,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC,MAAM,CAAC;IAClF,MAAM,cAAc,GAAG,KAAK,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;IACtD,MAAM,WAAW,GAAG,cAAc,GAAG,cAAc,CAAC,MAAM,CAAC;IAC3D,MAAM,cAAc,GAAG,cAAc;SACnC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,IAAI,CAAC,MAAM,KAAK,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;SACrE,IAAI,CAAC,IAAI,CAAC,CAAC;IAEb,OAAO,GAAG,sBAAsB;;WAEtB,cAAc,IAAI,WAAW,eAAe,cAAc,CAAC,MAAM;;;EAG1E,cAAc;CACf,CAAC;AAAA,CACD","sourcesContent":["import { isIncompleteTodo, sanitizeTodoText, type TodoItem } from \"../state.js\";\n\nexport const CONTINUATION_DIRECTIVE = `[SYSTEM DIRECTIVE: SENPI - TODO CONTINUATION]\n\nIncomplete tasks remain in your todo list. Continue working on the next pending task.\n\n- FIRST: Continue the first actionable remaining task now. If an in-progress task is already done, verify it and mark it completed before moving on\n- Proceed without asking for permission\n- Mark each task complete immediately when finished\n- Do not stop until all tasks are done\n- Do not reply with refusal, deferral, or a summary-only response\n- If a task is already complete, no longer needed, or blocked, verify that and update the todo list to a terminal state instead of leaving it pending\n- If you believe all work is already complete, the system is questioning your completion claim. Critically re-examine each todo item from a skeptical perspective, verify the work was actually done correctly, and update the todo list accordingly.`;\n\nexport function countIncomplete(todos: TodoItem[]): number {\n\treturn todos.filter(isIncompleteTodo).length;\n}\n\nexport function buildContinuationPrompt(todos: TodoItem[]): string {\n\tif (todos.length === 0) {\n\t\treturn \"\";\n\t}\n\n\tconst completedCount = todos.filter((todo) => todo.status === \"completed\").length;\n\tconst remainingTodos = todos.filter(isIncompleteTodo);\n\tconst activeTotal = completedCount + remainingTodos.length;\n\tconst remainingLines = remainingTodos\n\t\t.map((todo) => `- [${todo.status}] ${sanitizeTodoText(todo.content)}`)\n\t\t.join(\"\\n\");\n\n\treturn `${CONTINUATION_DIRECTIVE}\n\n[Status: ${completedCount}/${activeTotal} completed, ${remainingTodos.length} remaining]\n\nRemaining tasks:\n${remainingLines}\n`;\n}\n"]}
|
|
@@ -15,7 +15,7 @@ type BranchEntry = {
|
|
|
15
15
|
data?: unknown;
|
|
16
16
|
message?: unknown;
|
|
17
17
|
};
|
|
18
|
-
export declare const TODO_STATE_ENTRY_TYPE = "
|
|
18
|
+
export declare const TODO_STATE_ENTRY_TYPE = "senpi.todo-state";
|
|
19
19
|
export declare function isTerminalTodoStatus(status: string): boolean;
|
|
20
20
|
export declare function isIncompleteTodo(todo: TodoItem): boolean;
|
|
21
21
|
export declare function sanitizeTodoText(text: string): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/todotools/state.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,QAAQ,GAAG;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC9B,KAAK,EAAE,QAAQ,EAAE,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC5B,KAAK,EAAE,QAAQ,EAAE,CAAC;CAClB,CAAC;AAEF,KAAK,WAAW,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAE5F,eAAO,MAAM,qBAAqB,
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/todotools/state.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,QAAQ,GAAG;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC9B,KAAK,EAAE,QAAQ,EAAE,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC5B,KAAK,EAAE,QAAQ,EAAE,CAAC;CAClB,CAAC;AAEF,KAAK,WAAW,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAE5F,eAAO,MAAM,qBAAqB,qBAAqB,CAAC;AAExD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAE5D;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAExD;AAMD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMrD;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAKpD;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,MAAM,EAAE,GAAG,SAAS,CAK1E;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,MAAM,EAAE,CAK9D;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ,CAM5D;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ,EAAE,CAEnE;AAED,wBAAgB,+BAA+B,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,QAAQ,EAAE,CA4BlF","sourcesContent":["import { stripAnsi } from \"../../../../utils/ansi.js\";\n\nexport type TodoItem = {\n\tcontent: string;\n\tstatus: string;\n\tpriority: string;\n};\n\nexport type TodoWriteDetails = {\n\ttodos: TodoItem[];\n};\n\nexport type TodoStateEntry = {\n\ttodos: TodoItem[];\n};\n\ntype BranchEntry = { type: string; customType?: string; data?: unknown; message?: unknown };\n\nexport const TODO_STATE_ENTRY_TYPE = \"senpi.todo-state\";\n\nexport function isTerminalTodoStatus(status: string): boolean {\n\treturn status === \"completed\" || status === \"cancelled\";\n}\n\nexport function isIncompleteTodo(todo: TodoItem): boolean {\n\treturn !isTerminalTodoStatus(todo.status);\n}\n\nfunction countOpenTodos(todos: TodoItem[]): number {\n\treturn todos.filter(isIncompleteTodo).length;\n}\n\nexport function sanitizeTodoText(text: string): string {\n\treturn stripAnsi(text)\n\t\t.replace(/[\\r\\n]+/g, \" \")\n\t\t.replace(/[\\u0000-\\u001F\\u007F-\\u009F]/g, \" \")\n\t\t.replace(/\\s+/g, \" \")\n\t\t.trim();\n}\n\nexport function getTodoMarker(status: string): string {\n\tif (status === \"completed\") return \"[✓]\";\n\tif (status === \"in_progress\") return \"[•]\";\n\tif (status === \"cancelled\") return \"[×]\";\n\treturn \"[ ]\";\n}\n\nexport function getTodoWidgetLines(todos: TodoItem[]): string[] | undefined {\n\tif (todos.length === 0 || !todos.some(isIncompleteTodo)) {\n\t\treturn undefined;\n\t}\n\treturn [\"Todo\", ...todos.map((todo) => `${getTodoMarker(todo.status)} ${sanitizeTodoText(todo.content)}`)];\n}\n\nexport function getTodoResultLines(todos: TodoItem[]): string[] {\n\treturn [\n\t\t`${countOpenTodos(todos)} todos`,\n\t\t...todos.map((todo) => `${getTodoMarker(todo.status)} ${sanitizeTodoText(todo.content)}`),\n\t];\n}\n\nexport function isTodoItem(value: unknown): value is TodoItem {\n\tif (typeof value !== \"object\" || value === null) {\n\t\treturn false;\n\t}\n\tconst item = value as Record<string, unknown>;\n\treturn typeof item.content === \"string\" && typeof item.status === \"string\" && typeof item.priority === \"string\";\n}\n\nexport function isTodoItemArray(value: unknown): value is TodoItem[] {\n\treturn Array.isArray(value) && value.every(isTodoItem);\n}\n\nexport function getLatestTodosFromBranchEntries(entries: BranchEntry[]): TodoItem[] {\n\tlet todos: TodoItem[] = [];\n\n\tfor (const entry of entries) {\n\t\tif (entry.type === \"custom\" && entry.customType === TODO_STATE_ENTRY_TYPE) {\n\t\t\tconst data = entry.data as TodoStateEntry | undefined;\n\t\t\tif (isTodoItemArray(data?.todos)) {\n\t\t\t\ttodos = data.todos.map((todo) => ({ ...todo }));\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (entry.type !== \"message\" || typeof entry.message !== \"object\" || entry.message === null) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst message = entry.message as { role?: string; toolName?: string; details?: unknown };\n\t\tif (message.role !== \"toolResult\" || message.toolName !== \"todowrite\") {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst details = message.details as TodoWriteDetails | undefined;\n\t\tif (isTodoItemArray(details?.todos)) {\n\t\t\ttodos = details.todos.map((todo) => ({ ...todo }));\n\t\t}\n\t}\n\n\treturn todos;\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { stripAnsi } from "../../../../utils/ansi.js";
|
|
2
|
-
export const TODO_STATE_ENTRY_TYPE = "
|
|
2
|
+
export const TODO_STATE_ENTRY_TYPE = "senpi.todo-state";
|
|
3
3
|
export function isTerminalTodoStatus(status) {
|
|
4
4
|
return status === "completed" || status === "cancelled";
|
|
5
5
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/todotools/state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAkBtD,MAAM,CAAC,MAAM,qBAAqB,GAAG,
|
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/todotools/state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAkBtD,MAAM,CAAC,MAAM,qBAAqB,GAAG,kBAAkB,CAAC;AAExD,MAAM,UAAU,oBAAoB,CAAC,MAAc,EAAW;IAC7D,OAAO,MAAM,KAAK,WAAW,IAAI,MAAM,KAAK,WAAW,CAAC;AAAA,CACxD;AAED,MAAM,UAAU,gBAAgB,CAAC,IAAc,EAAW;IACzD,OAAO,CAAC,oBAAoB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAAA,CAC1C;AAED,SAAS,cAAc,CAAC,KAAiB,EAAU;IAClD,OAAO,KAAK,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,MAAM,CAAC;AAAA,CAC7C;AAED,MAAM,UAAU,gBAAgB,CAAC,IAAY,EAAU;IACtD,OAAO,SAAS,CAAC,IAAI,CAAC;SACpB,OAAO,CAAC,UAAU,EAAE,GAAG,CAAC;SACxB,OAAO,CAAC,+BAA+B,EAAE,GAAG,CAAC;SAC7C,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;SACpB,IAAI,EAAE,CAAC;AAAA,CACT;AAED,MAAM,UAAU,aAAa,CAAC,MAAc,EAAU;IACrD,IAAI,MAAM,KAAK,WAAW;QAAE,OAAO,OAAK,CAAC;IACzC,IAAI,MAAM,KAAK,aAAa;QAAE,OAAO,OAAK,CAAC;IAC3C,IAAI,MAAM,KAAK,WAAW;QAAE,OAAO,MAAK,CAAC;IACzC,OAAO,KAAK,CAAC;AAAA,CACb;AAED,MAAM,UAAU,kBAAkB,CAAC,KAAiB,EAAwB;IAC3E,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC;QACzD,OAAO,SAAS,CAAC;IAClB,CAAC;IACD,OAAO,CAAC,MAAM,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;AAAA,CAC3G;AAED,MAAM,UAAU,kBAAkB,CAAC,KAAiB,EAAY;IAC/D,OAAO;QACN,GAAG,cAAc,CAAC,KAAK,CAAC,QAAQ;QAChC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;KACzF,CAAC;AAAA,CACF;AAED,MAAM,UAAU,UAAU,CAAC,KAAc,EAAqB;IAC7D,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QACjD,OAAO,KAAK,CAAC;IACd,CAAC;IACD,MAAM,IAAI,GAAG,KAAgC,CAAC;IAC9C,OAAO,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ,IAAI,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,IAAI,OAAO,IAAI,CAAC,QAAQ,KAAK,QAAQ,CAAC;AAAA,CAChH;AAED,MAAM,UAAU,eAAe,CAAC,KAAc,EAAuB;IACpE,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;AAAA,CACvD;AAED,MAAM,UAAU,+BAA+B,CAAC,OAAsB,EAAc;IACnF,IAAI,KAAK,GAAe,EAAE,CAAC;IAE3B,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC7B,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,UAAU,KAAK,qBAAqB,EAAE,CAAC;YAC3E,MAAM,IAAI,GAAG,KAAK,CAAC,IAAkC,CAAC;YACtD,IAAI,eAAe,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC;gBAClC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC;YACjD,CAAC;YACD,SAAS;QACV,CAAC;QAED,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,IAAI,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;YAC7F,SAAS;QACV,CAAC;QAED,MAAM,OAAO,GAAG,KAAK,CAAC,OAAkE,CAAC;QACzF,IAAI,OAAO,CAAC,IAAI,KAAK,YAAY,IAAI,OAAO,CAAC,QAAQ,KAAK,WAAW,EAAE,CAAC;YACvE,SAAS;QACV,CAAC;QAED,MAAM,OAAO,GAAG,OAAO,CAAC,OAAuC,CAAC;QAChE,IAAI,eAAe,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC;YACrC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC;QACpD,CAAC;IACF,CAAC;IAED,OAAO,KAAK,CAAC;AAAA,CACb","sourcesContent":["import { stripAnsi } from \"../../../../utils/ansi.js\";\n\nexport type TodoItem = {\n\tcontent: string;\n\tstatus: string;\n\tpriority: string;\n};\n\nexport type TodoWriteDetails = {\n\ttodos: TodoItem[];\n};\n\nexport type TodoStateEntry = {\n\ttodos: TodoItem[];\n};\n\ntype BranchEntry = { type: string; customType?: string; data?: unknown; message?: unknown };\n\nexport const TODO_STATE_ENTRY_TYPE = \"senpi.todo-state\";\n\nexport function isTerminalTodoStatus(status: string): boolean {\n\treturn status === \"completed\" || status === \"cancelled\";\n}\n\nexport function isIncompleteTodo(todo: TodoItem): boolean {\n\treturn !isTerminalTodoStatus(todo.status);\n}\n\nfunction countOpenTodos(todos: TodoItem[]): number {\n\treturn todos.filter(isIncompleteTodo).length;\n}\n\nexport function sanitizeTodoText(text: string): string {\n\treturn stripAnsi(text)\n\t\t.replace(/[\\r\\n]+/g, \" \")\n\t\t.replace(/[\\u0000-\\u001F\\u007F-\\u009F]/g, \" \")\n\t\t.replace(/\\s+/g, \" \")\n\t\t.trim();\n}\n\nexport function getTodoMarker(status: string): string {\n\tif (status === \"completed\") return \"[✓]\";\n\tif (status === \"in_progress\") return \"[•]\";\n\tif (status === \"cancelled\") return \"[×]\";\n\treturn \"[ ]\";\n}\n\nexport function getTodoWidgetLines(todos: TodoItem[]): string[] | undefined {\n\tif (todos.length === 0 || !todos.some(isIncompleteTodo)) {\n\t\treturn undefined;\n\t}\n\treturn [\"Todo\", ...todos.map((todo) => `${getTodoMarker(todo.status)} ${sanitizeTodoText(todo.content)}`)];\n}\n\nexport function getTodoResultLines(todos: TodoItem[]): string[] {\n\treturn [\n\t\t`${countOpenTodos(todos)} todos`,\n\t\t...todos.map((todo) => `${getTodoMarker(todo.status)} ${sanitizeTodoText(todo.content)}`),\n\t];\n}\n\nexport function isTodoItem(value: unknown): value is TodoItem {\n\tif (typeof value !== \"object\" || value === null) {\n\t\treturn false;\n\t}\n\tconst item = value as Record<string, unknown>;\n\treturn typeof item.content === \"string\" && typeof item.status === \"string\" && typeof item.priority === \"string\";\n}\n\nexport function isTodoItemArray(value: unknown): value is TodoItem[] {\n\treturn Array.isArray(value) && value.every(isTodoItem);\n}\n\nexport function getLatestTodosFromBranchEntries(entries: BranchEntry[]): TodoItem[] {\n\tlet todos: TodoItem[] = [];\n\n\tfor (const entry of entries) {\n\t\tif (entry.type === \"custom\" && entry.customType === TODO_STATE_ENTRY_TYPE) {\n\t\t\tconst data = entry.data as TodoStateEntry | undefined;\n\t\t\tif (isTodoItemArray(data?.todos)) {\n\t\t\t\ttodos = data.todos.map((todo) => ({ ...todo }));\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (entry.type !== \"message\" || typeof entry.message !== \"object\" || entry.message === null) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst message = entry.message as { role?: string; toolName?: string; details?: unknown };\n\t\tif (message.role !== \"toolResult\" || message.toolName !== \"todowrite\") {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst details = message.details as TodoWriteDetails | undefined;\n\t\tif (isTodoItemArray(details?.todos)) {\n\t\t\ttodos = details.todos.map((todo) => ({ ...todo }));\n\t\t}\n\t}\n\n\treturn todos;\n}\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ImageContent, TextContent } from "@earendil-works/pi-ai";
|
|
2
2
|
import type { ExtensionAPI } from "../../types.js";
|
|
3
|
-
export declare const
|
|
4
|
-
export declare const
|
|
3
|
+
export declare const SENPI_SYSTEM_PREFIX = "[system:senpi]";
|
|
4
|
+
export declare const SENPI_CONVERSATION_EVENT = "senpi:conversation";
|
|
5
5
|
export type TodoSystemMessageRoute = "todotools.continuation";
|
|
6
6
|
export type TodoConversationAction = "injected" | "failed";
|
|
7
7
|
export interface TodoConversationEvent {
|
|
@@ -12,7 +12,7 @@ export interface TodoConversationEvent {
|
|
|
12
12
|
sessionId?: string;
|
|
13
13
|
timestamp: number;
|
|
14
14
|
conversation: {
|
|
15
|
-
prefix: typeof
|
|
15
|
+
prefix: typeof SENPI_SYSTEM_PREFIX;
|
|
16
16
|
kind: "user_message";
|
|
17
17
|
deliverAs?: "steer" | "followUp";
|
|
18
18
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"system-messages.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/todotools/system-messages.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACvE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD,eAAO,MAAM,
|
|
1
|
+
{"version":3,"file":"system-messages.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/todotools/system-messages.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACvE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD,eAAO,MAAM,mBAAmB,mBAAmB,CAAC;AACpD,eAAO,MAAM,wBAAwB,uBAAuB,CAAC;AAE7D,MAAM,MAAM,sBAAsB,GAAG,wBAAwB,CAAC;AAC9D,MAAM,MAAM,sBAAsB,GAAG,UAAU,GAAG,QAAQ,CAAC;AAE3D,MAAM,WAAW,qBAAqB;IACrC,OAAO,EAAE,CAAC,CAAC;IACX,MAAM,EAAE,SAAS,CAAC;IAClB,MAAM,EAAE,sBAAsB,CAAC;IAC/B,KAAK,EAAE,sBAAsB,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE;QACb,MAAM,EAAE,OAAO,mBAAmB,CAAC;QACnC,IAAI,EAAE,cAAc,CAAC;QACrB,SAAS,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;KACjC,CAAC;IACF,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,sBAAsB;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;CACjC;AA0ED,wBAAgB,mBAAmB,CAClC,EAAE,EAAE,YAAY,EAChB,KAAK,EAAE,sBAAsB,EAC7B,OAAO,EAAE,MAAM,GAAG,CAAC,WAAW,GAAG,YAAY,CAAC,EAAE,EAChD,OAAO,CAAC,EAAE,sBAAsB,GAC9B,IAAI,CAoBN;AAED,wBAAgB,4BAA4B,CAC3C,EAAE,EAAE,YAAY,EAChB,IAAI,EAAE;IACL,KAAK,EAAE,sBAAsB,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,GAAG,CAAC,WAAW,GAAG,YAAY,CAAC,EAAE,CAAC;IACjD,SAAS,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;IACjC,YAAY,EAAE,MAAM,CAAC;CACrB,GACC,IAAI,CAcN","sourcesContent":["import type { ImageContent, TextContent } from \"@earendil-works/pi-ai\";\nimport type { ExtensionAPI } from \"../../types.js\";\n\nexport const SENPI_SYSTEM_PREFIX = \"[system:senpi]\";\nexport const SENPI_CONVERSATION_EVENT = \"senpi:conversation\";\n\nexport type TodoSystemMessageRoute = \"todotools.continuation\";\nexport type TodoConversationAction = \"injected\" | \"failed\";\n\nexport interface TodoConversationEvent {\n\tversion: 1;\n\tsource: \"builtin\";\n\taction: TodoConversationAction;\n\troute: TodoSystemMessageRoute;\n\tsessionId?: string;\n\ttimestamp: number;\n\tconversation: {\n\t\tprefix: typeof SENPI_SYSTEM_PREFIX;\n\t\tkind: \"user_message\";\n\t\tdeliverAs?: \"steer\" | \"followUp\";\n\t};\n\ttext: string;\n\terrorMessage?: string;\n}\n\nexport interface TodoUserMessageOptions {\n\tsessionId?: string;\n\tdeliverAs?: \"steer\" | \"followUp\";\n}\n\nfunction prefixText(text: string): string {\n\treturn text.startsWith(SENPI_SYSTEM_PREFIX) ? text : `${SENPI_SYSTEM_PREFIX}\\n${text}`;\n}\n\nfunction prefixContent(content: string | (TextContent | ImageContent)[]): string | (TextContent | ImageContent)[] {\n\tif (typeof content === \"string\") {\n\t\treturn prefixText(content);\n\t}\n\n\tconst firstTextIndex = content.findIndex((part) => part.type === \"text\");\n\tif (firstTextIndex === -1) {\n\t\treturn [{ type: \"text\", text: SENPI_SYSTEM_PREFIX }, ...content];\n\t}\n\n\treturn content.map((part, index) => {\n\t\tif (part.type !== \"text\" || index !== firstTextIndex) {\n\t\t\treturn part;\n\t\t}\n\n\t\treturn {\n\t\t\t...part,\n\t\t\ttext: prefixText(part.text),\n\t\t};\n\t});\n}\n\nfunction extractText(content: string | (TextContent | ImageContent)[]): string {\n\tif (typeof content === \"string\") {\n\t\treturn content;\n\t}\n\n\treturn content\n\t\t.filter((part): part is TextContent => part.type === \"text\")\n\t\t.map((part) => part.text)\n\t\t.join(\"\\n\");\n}\n\nfunction emitTodoConversationEvent(pi: ExtensionAPI, event: TodoConversationEvent): void {\n\tpi.events.emit(SENPI_CONVERSATION_EVENT, event);\n}\n\nfunction createBaseEvent(args: {\n\taction: TodoConversationAction;\n\troute: TodoSystemMessageRoute;\n\tsessionId?: string;\n\tdeliverAs?: \"steer\" | \"followUp\";\n\ttext: string;\n\terrorMessage?: string;\n}): TodoConversationEvent {\n\treturn {\n\t\tversion: 1,\n\t\tsource: \"builtin\",\n\t\taction: args.action,\n\t\troute: args.route,\n\t\tsessionId: args.sessionId,\n\t\ttimestamp: Date.now(),\n\t\tconversation: {\n\t\t\tprefix: SENPI_SYSTEM_PREFIX,\n\t\t\tkind: \"user_message\",\n\t\t\tdeliverAs: args.deliverAs,\n\t\t},\n\t\ttext: args.text,\n\t\terrorMessage: args.errorMessage,\n\t};\n}\n\nfunction hasUserMessageOptions(\n\toptions: TodoUserMessageOptions | undefined,\n): options is TodoUserMessageOptions & { deliverAs: \"steer\" | \"followUp\" } {\n\treturn options?.deliverAs !== undefined;\n}\n\nexport function sendTodoUserMessage(\n\tpi: ExtensionAPI,\n\troute: TodoSystemMessageRoute,\n\tcontent: string | (TextContent | ImageContent)[],\n\toptions?: TodoUserMessageOptions,\n): void {\n\tconst prefixedContent = prefixContent(content);\n\n\temitTodoConversationEvent(\n\t\tpi,\n\t\tcreateBaseEvent({\n\t\t\taction: \"injected\",\n\t\t\troute,\n\t\t\tsessionId: options?.sessionId,\n\t\t\ttext: extractText(prefixedContent),\n\t\t\tdeliverAs: options?.deliverAs,\n\t\t}),\n\t);\n\n\tif (hasUserMessageOptions(options)) {\n\t\tpi.sendUserMessage(prefixedContent, { deliverAs: options.deliverAs });\n\t\treturn;\n\t}\n\n\tpi.sendUserMessage(prefixedContent);\n}\n\nexport function emitTodoSystemMessageFailure(\n\tpi: ExtensionAPI,\n\targs: {\n\t\troute: TodoSystemMessageRoute;\n\t\tsessionId?: string;\n\t\tcontent: string | (TextContent | ImageContent)[];\n\t\tdeliverAs?: \"steer\" | \"followUp\";\n\t\terrorMessage: string;\n\t},\n): void {\n\tconst prefixedContent = prefixContent(args.content);\n\n\temitTodoConversationEvent(\n\t\tpi,\n\t\tcreateBaseEvent({\n\t\t\taction: \"failed\",\n\t\t\troute: args.route,\n\t\t\tsessionId: args.sessionId,\n\t\t\ttext: extractText(prefixedContent),\n\t\t\tdeliverAs: args.deliverAs,\n\t\t\terrorMessage: args.errorMessage,\n\t\t}),\n\t);\n}\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export const
|
|
2
|
-
export const
|
|
1
|
+
export const SENPI_SYSTEM_PREFIX = "[system:senpi]";
|
|
2
|
+
export const SENPI_CONVERSATION_EVENT = "senpi:conversation";
|
|
3
3
|
function prefixText(text) {
|
|
4
|
-
return text.startsWith(
|
|
4
|
+
return text.startsWith(SENPI_SYSTEM_PREFIX) ? text : `${SENPI_SYSTEM_PREFIX}\n${text}`;
|
|
5
5
|
}
|
|
6
6
|
function prefixContent(content) {
|
|
7
7
|
if (typeof content === "string") {
|
|
@@ -9,7 +9,7 @@ function prefixContent(content) {
|
|
|
9
9
|
}
|
|
10
10
|
const firstTextIndex = content.findIndex((part) => part.type === "text");
|
|
11
11
|
if (firstTextIndex === -1) {
|
|
12
|
-
return [{ type: "text", text:
|
|
12
|
+
return [{ type: "text", text: SENPI_SYSTEM_PREFIX }, ...content];
|
|
13
13
|
}
|
|
14
14
|
return content.map((part, index) => {
|
|
15
15
|
if (part.type !== "text" || index !== firstTextIndex) {
|
|
@@ -31,7 +31,7 @@ function extractText(content) {
|
|
|
31
31
|
.join("\n");
|
|
32
32
|
}
|
|
33
33
|
function emitTodoConversationEvent(pi, event) {
|
|
34
|
-
pi.events.emit(
|
|
34
|
+
pi.events.emit(SENPI_CONVERSATION_EVENT, event);
|
|
35
35
|
}
|
|
36
36
|
function createBaseEvent(args) {
|
|
37
37
|
return {
|
|
@@ -42,7 +42,7 @@ function createBaseEvent(args) {
|
|
|
42
42
|
sessionId: args.sessionId,
|
|
43
43
|
timestamp: Date.now(),
|
|
44
44
|
conversation: {
|
|
45
|
-
prefix:
|
|
45
|
+
prefix: SENPI_SYSTEM_PREFIX,
|
|
46
46
|
kind: "user_message",
|
|
47
47
|
deliverAs: args.deliverAs,
|
|
48
48
|
},
|