@epoch-agent/core 3.0.0 → 3.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -29
- package/dist/index.d.ts +707 -6
- package/dist/index.js +2236 -582
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { REASONING_EFFORTS, MODEL_ENTRY_PROTOCOLS, PROVIDER_TYPES, isModelEntryId, parseModelRef, OPERATION_TYPES as OPERATION_TYPES$1, COMPLIANCE_CATEGORIES, COMPLIANCE_ACTIONS, SEARCH_PROVIDER_TYPES, CURRENCIES, LANGS, isSettingsPaneId, SETTINGS_PANE_IDS, BRAND_WHEN_SIDEBAR_COLLAPSED, DEFAULT_PERMISSION_LEVEL, resolvePermissionLevel, PERMISSION_LEVELS, SHELL_KINDS, cronTimes, SCHEDULE_MAX_TIMES_PER_DAY, SCHEDULE_INTERVAL_MIN_MINUTES, SCHEDULE_INTERVAL_MAX_MINUTES, ToolExposure, MIN_OPTIONS, MAX_OPTIONS, MAX_HEADER_CHARS, MAX_QUESTIONS, SCHEDULE_DEFAULT_PERMISSION, approvalPolicyForLevel, SCHEDULE_DRAFT_TOOL, isValidAgentRoleName, DEFAULT_AGENT_ROLE, isValidCommandName, RESERVED_COMMAND_NAMES, isWirePluginArchiveName,
|
|
1
|
+
import { REASONING_EFFORTS, MODEL_ENTRY_PROTOCOLS, PROVIDER_TYPES, isModelEntryId, parseModelRef, OPERATION_TYPES as OPERATION_TYPES$1, COMPLIANCE_CATEGORIES, COMPLIANCE_ACTIONS, SEARCH_PROVIDER_TYPES, CURRENCIES, LANGS, isSettingsPaneId, SETTINGS_PANE_IDS, BRAND_WHEN_SIDEBAR_COLLAPSED, DEFAULT_PERMISSION_LEVEL, resolvePermissionLevel, PERMISSION_LEVELS, SHELL_KINDS, cronTimes, SCHEDULE_MAX_TIMES_PER_DAY, SCHEDULE_INTERVAL_MIN_MINUTES, SCHEDULE_INTERVAL_MAX_MINUTES, ToolExposure, MIN_OPTIONS, MAX_OPTIONS, MAX_HEADER_CHARS, MAX_QUESTIONS, SCHEDULE_DEFAULT_PERMISSION, approvalPolicyForLevel, SCHEDULE_DRAFT_TOOL, agentMessageLine, systemNote, LEAD_AGENT_ID, isValidAgentRoleName, DEFAULT_AGENT_ROLE, isValidCommandName, RESERVED_COMMAND_NAMES, isWirePluginArchiveName, contentToText, AGENT_MESSAGE_NOTE_TITLE, formatMoney, totalUsageTokens, OFFLOADED_IMAGE_NOTE, NOOP_TELEMETRY, METRIC, GEN_AI, isPromptOversize, promptTokens, entrySecretName, isEntrySecretName, entryRef, KEY_ACTIONS, tableOf, perAction, isKeyAction, parseSequence, RESERVED_CHORDS, chordId, sequenceId, ACTION_CONTEXTS, SEQUENCE_CONTEXTS, assertNeverPart, normalizeAppearanceTranslucent, MAX_ATTACH_FILES, MAX_ATTACH_TOTAL_BYTES, MAX_SESSION_REFS, utf8ByteLength, truncateToBudget, attachSessionSurface, isContextNearlyFull, isOperationType, normalizeApproval, SCHEDULE_DRAFT_SAVED_MARK, imagePartOmittedSummary, ENTRY_REF_PREFIX, placeholdersOf, SCHEDULE_CONFIRM_PLACEHOLDER, MAX_ATTACH_BYTES, SIMULTANEOUS_CONTEXTS, SESSION_REFERENCE_ERROR_CODES, filePartSummary, sessionPartSummary } from '@epoch-agent/protocol';
|
|
2
2
|
export { API_KEY_ENV_VARS, COMPLIANCE_ACTIONS, COMPLIANCE_CATEGORIES, LEGACY_LEVEL_ALIASES, MAX_ATTACH_BYTES, MAX_ATTACH_FILES, MAX_ATTACH_TOTAL_BYTES, MAX_SESSION_ATTACH_BYTES, MAX_SESSION_REFS, OPERATION_TYPES, PERMISSION_LEVELS, PLAN_OUTCOMES, PROVIDER_INFOS, PROVIDER_TYPES, ToolExposure, apiKeyEnvVar, approvalPolicyForLevel, extractAllMentions, extractMentions, extractSessionMentions, getProviderInfo, isOperationType, isPermissionLevel, isPlanOutcome, isProviderType, normalizeApproval, resolvePermissionLevel } from '@epoch-agent/protocol';
|
|
3
3
|
import { existsSync, mkdirSync, rmSync, writeFileSync, statSync, readdirSync, readFileSync, renameSync, realpathSync, symlinkSync, cpSync, lstatSync, unlinkSync, rmdirSync, mkdtempSync, copyFileSync, openSync, writeSync, closeSync, readSync } from 'fs';
|
|
4
4
|
import { platform, tmpdir, homedir, hostname } from 'os';
|
|
@@ -230,15 +230,15 @@ function createSchtasksBackend(opts = {}) {
|
|
|
230
230
|
let dir;
|
|
231
231
|
try {
|
|
232
232
|
dir = mkdtempSync(join(tmpdir(), "epoch-schtasks-"));
|
|
233
|
-
} catch (
|
|
234
|
-
return { ok: false, detail: `task-xml-write-failed: ${describe10(
|
|
233
|
+
} catch (err3) {
|
|
234
|
+
return { ok: false, detail: `task-xml-write-failed: ${describe10(err3)}` };
|
|
235
235
|
}
|
|
236
236
|
try {
|
|
237
237
|
const file = join(dir, "task.xml");
|
|
238
238
|
try {
|
|
239
239
|
writeFileSync(file, encodeTaskXml(renderTaskXml(input)));
|
|
240
|
-
} catch (
|
|
241
|
-
return { ok: false, detail: `task-xml-write-failed: ${describe10(
|
|
240
|
+
} catch (err3) {
|
|
241
|
+
return { ok: false, detail: `task-xml-write-failed: ${describe10(err3)}` };
|
|
242
242
|
}
|
|
243
243
|
const res = await run("schtasks", ["/Create", "/F", "/TN", input.osTaskId, "/XML", file]);
|
|
244
244
|
if (res.code !== 0) return { ok: false, detail: detailOf("schtasks /Create", res) };
|
|
@@ -471,8 +471,8 @@ function detailOf(what, res) {
|
|
|
471
471
|
const msg = (res.stderr || res.stdout).trim();
|
|
472
472
|
return `${what} exit ${res.code}${msg ? `: ${msg}` : ""}`;
|
|
473
473
|
}
|
|
474
|
-
function describe10(
|
|
475
|
-
return
|
|
474
|
+
function describe10(err3) {
|
|
475
|
+
return err3 instanceof Error ? err3.message : String(err3);
|
|
476
476
|
}
|
|
477
477
|
var SCHTASKS_FOLDER, WEEKDAY_CODES, WEEKDAY_NAMES, MONTH_NAMES;
|
|
478
478
|
var init_schtasks = __esm({
|
|
@@ -545,8 +545,8 @@ function createLaunchdBackend(opts = {}) {
|
|
|
545
545
|
mkdirSync(agentsDir(), { recursive: true });
|
|
546
546
|
mkdirSync(input.logDir, { recursive: true });
|
|
547
547
|
writeFileSync(path, renderPlist(label, input), "utf-8");
|
|
548
|
-
} catch (
|
|
549
|
-
return { ok: false, detail: `plist-write-failed: ${describe11(
|
|
548
|
+
} catch (err3) {
|
|
549
|
+
return { ok: false, detail: `plist-write-failed: ${describe11(err3)}` };
|
|
550
550
|
}
|
|
551
551
|
await run("launchctl", ["bootout", `${guiDomain()}/${label}`]);
|
|
552
552
|
const toggle = await backend.setEnabled(label, input.enabled);
|
|
@@ -561,8 +561,8 @@ function createLaunchdBackend(opts = {}) {
|
|
|
561
561
|
}
|
|
562
562
|
try {
|
|
563
563
|
rmSync(plistPath(label), { force: true });
|
|
564
|
-
} catch (
|
|
565
|
-
return { ok: false, detail: `plist-remove-failed: ${describe11(
|
|
564
|
+
} catch (err3) {
|
|
565
|
+
return { ok: false, detail: `plist-remove-failed: ${describe11(err3)}` };
|
|
566
566
|
}
|
|
567
567
|
return { ok: true };
|
|
568
568
|
},
|
|
@@ -723,8 +723,8 @@ function detailOf2(what, res) {
|
|
|
723
723
|
const msg = (res.stderr || res.stdout).trim();
|
|
724
724
|
return `${what} exit ${res.code}${msg ? `: ${msg}` : ""}`;
|
|
725
725
|
}
|
|
726
|
-
function describe11(
|
|
727
|
-
return
|
|
726
|
+
function describe11(err3) {
|
|
727
|
+
return err3 instanceof Error ? err3.message : String(err3);
|
|
728
728
|
}
|
|
729
729
|
var LAUNCHD_LABEL_PREFIX;
|
|
730
730
|
var init_launchd = __esm({
|
|
@@ -775,12 +775,12 @@ var init_backend = __esm({
|
|
|
775
775
|
file,
|
|
776
776
|
[...args],
|
|
777
777
|
{ encoding: "buffer", windowsHide: true },
|
|
778
|
-
(
|
|
779
|
-
const code =
|
|
778
|
+
(err3, stdout, stderr) => {
|
|
779
|
+
const code = err3 && typeof err3.code === "number" ? err3.code ?? 1 : err3 ? 1 : 0;
|
|
780
780
|
resolve17({ code, stdout: decodeOutput(stdout), stderr: decodeOutput(stderr) });
|
|
781
781
|
}
|
|
782
782
|
),
|
|
783
|
-
(
|
|
783
|
+
(err3) => resolve17({ code: 1, stdout: "", stderr: `${file}: ${err3.message}` })
|
|
784
784
|
);
|
|
785
785
|
});
|
|
786
786
|
}
|
|
@@ -818,12 +818,21 @@ var COMMAND_TOOLS = /* @__PURE__ */ new Set([
|
|
|
818
818
|
"shell_open",
|
|
819
819
|
"shell_send",
|
|
820
820
|
"delegate_task",
|
|
821
|
+
"spawn_teammate",
|
|
822
|
+
"interrupt_agent",
|
|
823
|
+
"followup_task",
|
|
821
824
|
"run_code",
|
|
822
825
|
"mcp_add",
|
|
823
826
|
"mcp_update",
|
|
824
827
|
"mcp_remove"
|
|
825
828
|
]);
|
|
826
|
-
var NON_SHELL_COMMAND_TOOLS = /* @__PURE__ */ new Set([
|
|
829
|
+
var NON_SHELL_COMMAND_TOOLS = /* @__PURE__ */ new Set([
|
|
830
|
+
"run_code",
|
|
831
|
+
"delegate_task",
|
|
832
|
+
"spawn_teammate",
|
|
833
|
+
"interrupt_agent",
|
|
834
|
+
"followup_task"
|
|
835
|
+
]);
|
|
827
836
|
var CODE_EXEC_TOOLS = /* @__PURE__ */ new Set(["code_exec", "sandbox"]);
|
|
828
837
|
var NETWORK_TOOLS = /* @__PURE__ */ new Set(["web_fetch", "web_search"]);
|
|
829
838
|
var INTERNAL_TOOLS = /* @__PURE__ */ new Set([
|
|
@@ -840,7 +849,25 @@ var INTERNAL_TOOLS = /* @__PURE__ */ new Set([
|
|
|
840
849
|
"goal",
|
|
841
850
|
"skill_view",
|
|
842
851
|
"tool_search",
|
|
843
|
-
"schedule_draft"
|
|
852
|
+
"schedule_draft",
|
|
853
|
+
"send_message",
|
|
854
|
+
"list_agents",
|
|
855
|
+
"wait_agent",
|
|
856
|
+
"team_task_create",
|
|
857
|
+
"team_task_list",
|
|
858
|
+
"team_task_get",
|
|
859
|
+
"team_task_update",
|
|
860
|
+
"create_channel",
|
|
861
|
+
"upsert_channel",
|
|
862
|
+
"get_channels",
|
|
863
|
+
"list_threads",
|
|
864
|
+
"search_posts",
|
|
865
|
+
"read_thread",
|
|
866
|
+
"read_post",
|
|
867
|
+
"subscribe",
|
|
868
|
+
"unsubscribe",
|
|
869
|
+
"post",
|
|
870
|
+
"append"
|
|
844
871
|
]);
|
|
845
872
|
function mapOperationType(toolName) {
|
|
846
873
|
if (COMMAND_TOOLS.has(toolName)) return "command";
|
|
@@ -1035,10 +1062,10 @@ var ToolRegistry = class {
|
|
|
1035
1062
|
if (!plugin.onInit) continue;
|
|
1036
1063
|
try {
|
|
1037
1064
|
await plugin.onInit(ctx);
|
|
1038
|
-
} catch (
|
|
1065
|
+
} catch (err3) {
|
|
1039
1066
|
failures.push({
|
|
1040
1067
|
plugin: plugin.name,
|
|
1041
|
-
error:
|
|
1068
|
+
error: err3 instanceof Error ? err3.message : String(err3)
|
|
1042
1069
|
});
|
|
1043
1070
|
}
|
|
1044
1071
|
}
|
|
@@ -1087,12 +1114,12 @@ function encoderFor(encoding) {
|
|
|
1087
1114
|
throw new Error(`${encoding} \u7684\u6A21\u5757\u91CC\u6CA1\u6709 countTokens`);
|
|
1088
1115
|
}
|
|
1089
1116
|
entry.counter = { countTokens: mod.countTokens };
|
|
1090
|
-
} catch (
|
|
1117
|
+
} catch (err3) {
|
|
1091
1118
|
if (!warned) {
|
|
1092
1119
|
warned = true;
|
|
1093
1120
|
log.debug("\u5206\u8BCD\u5668\u52A0\u8F7D\u5931\u8D25\uFF0C\u672C\u8FDB\u7A0B\u56DE\u843D\u5230 chars/4 \u4F30\u7B97", {
|
|
1094
1121
|
encoding,
|
|
1095
|
-
error:
|
|
1122
|
+
error: err3 instanceof Error ? err3.message : String(err3)
|
|
1096
1123
|
});
|
|
1097
1124
|
}
|
|
1098
1125
|
}
|
|
@@ -1461,8 +1488,8 @@ var CodeSandbox = class {
|
|
|
1461
1488
|
...req.signal ? { signal: req.signal } : {}
|
|
1462
1489
|
});
|
|
1463
1490
|
return { ...result, isolation };
|
|
1464
|
-
} catch (
|
|
1465
|
-
const msg =
|
|
1491
|
+
} catch (err3) {
|
|
1492
|
+
const msg = err3 instanceof Error ? err3.message : String(err3);
|
|
1466
1493
|
if (msg.includes("timed out") || msg.includes("killed")) {
|
|
1467
1494
|
return {
|
|
1468
1495
|
success: false,
|
|
@@ -1548,9 +1575,9 @@ var CodeSandbox = class {
|
|
|
1548
1575
|
const onAbort = () => {
|
|
1549
1576
|
child?.kill("SIGKILL");
|
|
1550
1577
|
};
|
|
1551
|
-
const failToStart = (
|
|
1578
|
+
const failToStart = (err3) => {
|
|
1552
1579
|
opts.signal?.removeEventListener("abort", onAbort);
|
|
1553
|
-
if (
|
|
1580
|
+
if (err3.code === "ENOENT") {
|
|
1554
1581
|
resolve17({
|
|
1555
1582
|
success: false,
|
|
1556
1583
|
output: "",
|
|
@@ -1563,7 +1590,7 @@ var CodeSandbox = class {
|
|
|
1563
1590
|
resolve17({
|
|
1564
1591
|
success: false,
|
|
1565
1592
|
output: "",
|
|
1566
|
-
error: `[\u9519\u8BEF] ${
|
|
1593
|
+
error: `[\u9519\u8BEF] ${err3.message}\uFF08command=${command}\uFF0Ccwd=${spawnOpts.cwd ?? ""}\uFF09`,
|
|
1567
1594
|
errorType: "runtime",
|
|
1568
1595
|
duration: Date.now() - start
|
|
1569
1596
|
});
|
|
@@ -1978,7 +2005,8 @@ var BLOCKED_TOOLS = Object.freeze([
|
|
|
1978
2005
|
"delegate_task",
|
|
1979
2006
|
"clarify",
|
|
1980
2007
|
"memory",
|
|
1981
|
-
"
|
|
2008
|
+
"spawn_teammate",
|
|
2009
|
+
"followup_task",
|
|
1982
2010
|
"cronjob",
|
|
1983
2011
|
"enter_plan_mode",
|
|
1984
2012
|
"exit_plan_mode",
|
|
@@ -2037,13 +2065,13 @@ var DelegateManager = class {
|
|
|
2037
2065
|
).then((results) => {
|
|
2038
2066
|
const total = Date.now() - start;
|
|
2039
2067
|
const summary = this.buildSummary(results, total);
|
|
2040
|
-
const
|
|
2068
|
+
const ok4 = results.every((r) => r.success);
|
|
2041
2069
|
if (job) {
|
|
2042
2070
|
job.append(`
|
|
2043
2071
|
${summary}`);
|
|
2044
|
-
job.finish(
|
|
2072
|
+
job.finish(ok4 ? "exited" : "failed");
|
|
2045
2073
|
}
|
|
2046
|
-
return { results, summary, total, ok:
|
|
2074
|
+
return { results, summary, total, ok: ok4 };
|
|
2047
2075
|
});
|
|
2048
2076
|
if (background && job) {
|
|
2049
2077
|
void run.catch(() => void 0);
|
|
@@ -2120,7 +2148,19 @@ ${summary}`);
|
|
|
2120
2148
|
}
|
|
2121
2149
|
async runSingleTask(task, parentSessionId, signal, onProgress) {
|
|
2122
2150
|
const start = Date.now();
|
|
2123
|
-
const
|
|
2151
|
+
const resuming = task.resumeSessionId !== void 0;
|
|
2152
|
+
const sessionId = task.resumeSessionId ?? `delegate-${randomUUID().slice(0, 8)}`;
|
|
2153
|
+
const memberId = task.agentId ?? sessionId;
|
|
2154
|
+
if (resuming) {
|
|
2155
|
+
this.config.team?.markRunning(memberId);
|
|
2156
|
+
} else {
|
|
2157
|
+
this.config.team?.createMember({
|
|
2158
|
+
sessionId,
|
|
2159
|
+
parentSessionId,
|
|
2160
|
+
...task.agentId ? { agentId: task.agentId } : {},
|
|
2161
|
+
...task.role ? { role: task.role } : {}
|
|
2162
|
+
});
|
|
2163
|
+
}
|
|
2124
2164
|
const failed = (error, summary = "") => ({
|
|
2125
2165
|
goal: task.goal,
|
|
2126
2166
|
success: false,
|
|
@@ -2131,9 +2171,11 @@ ${summary}`);
|
|
|
2131
2171
|
});
|
|
2132
2172
|
if (signal?.aborted) return failed(ABORTED);
|
|
2133
2173
|
const controller = new AbortController();
|
|
2174
|
+
this.config.team?.setAbort(memberId, () => controller.abort());
|
|
2134
2175
|
const unlink = linkAbort(isAbortSignal(signal) ? signal : void 0, controller);
|
|
2135
2176
|
const ms = this.config.task_timeout;
|
|
2136
2177
|
let timer;
|
|
2178
|
+
let outcome = "failed";
|
|
2137
2179
|
try {
|
|
2138
2180
|
const work = this.runner(
|
|
2139
2181
|
task.goal,
|
|
@@ -2142,7 +2184,11 @@ ${summary}`);
|
|
|
2142
2184
|
task.role,
|
|
2143
2185
|
parentSessionId,
|
|
2144
2186
|
controller.signal,
|
|
2145
|
-
|
|
2187
|
+
(line) => {
|
|
2188
|
+
this.config.team?.setActivity(memberId, line);
|
|
2189
|
+
onProgress?.(line);
|
|
2190
|
+
},
|
|
2191
|
+
resuming ? { resume: true } : void 0
|
|
2146
2192
|
);
|
|
2147
2193
|
const result = await (ms > 0 ? Promise.race([
|
|
2148
2194
|
work,
|
|
@@ -2154,6 +2200,7 @@ ${summary}`);
|
|
|
2154
2200
|
})
|
|
2155
2201
|
]) : work);
|
|
2156
2202
|
if (controller.signal.aborted) return failed(ABORTED, result.text);
|
|
2203
|
+
outcome = result.error ? "failed" : "finalized";
|
|
2157
2204
|
return {
|
|
2158
2205
|
goal: task.goal,
|
|
2159
2206
|
success: !result.error,
|
|
@@ -2162,11 +2209,12 @@ ${summary}`);
|
|
|
2162
2209
|
duration: Date.now() - start,
|
|
2163
2210
|
...task.role ? { role: task.role } : {}
|
|
2164
2211
|
};
|
|
2165
|
-
} catch (
|
|
2166
|
-
const msg =
|
|
2212
|
+
} catch (err3) {
|
|
2213
|
+
const msg = err3 instanceof Error ? err3.message : String(err3);
|
|
2167
2214
|
if (signal?.aborted) return failed(ABORTED);
|
|
2168
2215
|
return failed(msg.includes("\u8D85\u65F6") ? `[\u8D85\u65F6] ${msg}` : msg);
|
|
2169
2216
|
} finally {
|
|
2217
|
+
this.config.team?.markFinished(memberId, outcome);
|
|
2170
2218
|
clearTimeout(timer);
|
|
2171
2219
|
unlink();
|
|
2172
2220
|
}
|
|
@@ -2211,8 +2259,9 @@ function renderRoles(roles) {
|
|
|
2211
2259
|
...roles.map((r) => `- ${r.name}: ${r.description}`)
|
|
2212
2260
|
];
|
|
2213
2261
|
}
|
|
2214
|
-
function createDelegateTool(runner, config, roles) {
|
|
2262
|
+
function createDelegateTool(runner, config, roles, onManager) {
|
|
2215
2263
|
const manager = new DelegateManager(runner, config);
|
|
2264
|
+
onManager?.(manager);
|
|
2216
2265
|
const listRoles = roles ?? (() => []);
|
|
2217
2266
|
return {
|
|
2218
2267
|
name: "delegate_task",
|
|
@@ -2413,9 +2462,9 @@ function goalBlockBody(view) {
|
|
|
2413
2462
|
return lines;
|
|
2414
2463
|
}
|
|
2415
2464
|
// src/tools/builtin/goal.ts
|
|
2416
|
-
function say2(text,
|
|
2465
|
+
function say2(text, ok4, startedAt) {
|
|
2417
2466
|
const duration = Date.now() - startedAt;
|
|
2418
|
-
return
|
|
2467
|
+
return ok4 ? { success: true, output: text, duration } : { success: false, output: "", error: { code: 7101, message: text }, duration };
|
|
2419
2468
|
}
|
|
2420
2469
|
function createGoalTool(deps) {
|
|
2421
2470
|
return {
|
|
@@ -2629,8 +2678,8 @@ ${f.content}`);
|
|
|
2629
2678
|
);
|
|
2630
2679
|
}
|
|
2631
2680
|
return ok(`\u5DF2\u5220\u9664 ${target} \u8BB0\u5FC6\u6761\u76EE`, start);
|
|
2632
|
-
} catch (
|
|
2633
|
-
return fail(
|
|
2681
|
+
} catch (err3) {
|
|
2682
|
+
return fail(err3 instanceof Error ? err3.message : String(err3), start, 4002);
|
|
2634
2683
|
}
|
|
2635
2684
|
}
|
|
2636
2685
|
};
|
|
@@ -2837,9 +2886,9 @@ async function runCode(input) {
|
|
|
2837
2886
|
}
|
|
2838
2887
|
void relay(msg);
|
|
2839
2888
|
});
|
|
2840
|
-
worker.on("error", (
|
|
2889
|
+
worker.on("error", (err3) => {
|
|
2841
2890
|
if (settled) return;
|
|
2842
|
-
ending =
|
|
2891
|
+
ending = err3.code === "ERR_WORKER_OUT_OF_MEMORY" ? { kind: "oom", message: oomNotice(limits.maxMemoryMb) } : err3.code === "ERR_ACCESS_DENIED" ? { kind: "policy", message: policyNotice() } : { kind: "failed", message: err3.message };
|
|
2843
2892
|
finish();
|
|
2844
2893
|
});
|
|
2845
2894
|
worker.on("exit", () => {
|
|
@@ -2862,11 +2911,11 @@ async function runCode(input) {
|
|
|
2862
2911
|
const result = await input.callTool(msg.name, msg.args);
|
|
2863
2912
|
if (result.success) reply(msg.id, { ok: true, output: result.output });
|
|
2864
2913
|
else reply(msg.id, { ok: false, fatal: false, message: result.output });
|
|
2865
|
-
} catch (
|
|
2914
|
+
} catch (err3) {
|
|
2866
2915
|
reply(msg.id, {
|
|
2867
2916
|
ok: false,
|
|
2868
2917
|
fatal: false,
|
|
2869
|
-
message:
|
|
2918
|
+
message: err3 instanceof Error ? err3.message : String(err3)
|
|
2870
2919
|
});
|
|
2871
2920
|
}
|
|
2872
2921
|
};
|
|
@@ -3959,9 +4008,9 @@ function needsAllowlist(permission2) {
|
|
|
3959
4008
|
return permission2 !== "plan" && approvalPolicyForLevel(permission2) !== "never";
|
|
3960
4009
|
}
|
|
3961
4010
|
// src/tools/builtin/schedule-draft.ts
|
|
3962
|
-
function say4(text,
|
|
4011
|
+
function say4(text, ok4, startedAt) {
|
|
3963
4012
|
const duration = Date.now() - startedAt;
|
|
3964
|
-
return
|
|
4013
|
+
return ok4 ? { success: true, output: text, duration } : { success: false, output: "", error: { code: 7201, message: text }, duration };
|
|
3965
4014
|
}
|
|
3966
4015
|
function describeRow(def) {
|
|
3967
4016
|
const state = def.enabled ? "\u542F\u7528" : "\u505C\u7528";
|
|
@@ -4125,146 +4174,1416 @@ async function persist(save, draft, current) {
|
|
|
4125
4174
|
}
|
|
4126
4175
|
function createScheduleDraftTool(deps) {
|
|
4127
4176
|
return {
|
|
4128
|
-
name: SCHEDULE_DRAFT_TOOL,
|
|
4129
|
-
description: "\u5EFA\u4E00\u6761\u5B9A\u65F6\u4EFB\u52A1\uFF0C\u6216\u8005\u6539\u4E00\u6761\u5DF2\u6709\u7684\u3002\u5B9A\u65F6\u4EFB\u52A1\u662F\u300C\u5230\u70B9\u4E86\u81EA\u5DF1\u8DD1\u4E00\u6B21\u300D\u2014\u2014\u7528\u6237\u8BF4\u300C\u4EE5\u540E\u6BCF\u5929/\u6BCF\u5468\u5E2E\u6211\u505A\u67D0\u4EF6\u4E8B\u300D\u300C\u5B9A\u671F\u68C0\u67E5\u67D0\u67D0\u300D\uFF0C\u6216\u8005\u4F60\u53D1\u73B0\u67D0\u4EF6\u4E8B\u4ED6\u6BCF\u6B21\u90FD\u8981\u624B\u52A8\u505A\u4E00\u904D\u65F6\uFF0C\u7528\u5B83\u3002action=list \u770B\u73B0\u6709\u4EFB\u52A1\uFF08\u8981\u6539\u67D0\u6761\u5FC5\u987B\u5148 list \u62FF\u5230 id\uFF09\uFF1Baction=create \u76F4\u63A5\u5EFA\u4E00\u6761\uFF1Baction=update \u76F4\u63A5\u6539\u4E00\u6761\u3002\u26A0\uFE0F **\u5B83\u4EA4\u4E0A\u53BB\u5C31\u751F\u6548**\uFF08plan \u53EA\u8BFB\u6863\u4E0B\u9664\u5916\uFF0C\u90A3\u4E00\u6863\u53EA\u4EA4\u63D0\u6848\uFF09\u2014\u2014 \u5EFA\u5B8C\u5728\u4F60\u7684\u56DE\u590D\u91CC\u4EA4\u4EE3\u4E00\u53E5\u5C31\u884C\uFF0C\u522B\u95EE\u300C\u8981\u4E0D\u8981\u6211\u5EFA\u300D\u3002\u6743\u9650\u6863\u4E0D\u7ED9\u5C31\u662F auto\uFF08\u65B0\u5EFA\u4EFB\u52A1\u7684\u7F3A\u7701\uFF09\u2014\u2014 \u5B9A\u65F6\u4EFB\u52A1\u6CA1\u4EBA\u53EF\u95EE\uFF0C\u4F4E\u6863\u5728\u8FD9\u91CC\u7B49\u4E8E\u300C\u5230\u70B9\u5FC5\u7136\u5931\u8D25\u300D\u3002\u53EA\u6709\u7528\u6237\u660E\u786E\u8981\u6C42\u300C\u53EA\u8BFB / \u522B\u52A8\u4E1C\u897F\u300D\u65F6\u624D\u7528 plan\uFF0C\u90A3\u7C7B\u4EFB\u52A1\u5929\u7136\u96F6\u6388\u6743\u9762\u3002",
|
|
4177
|
+
name: SCHEDULE_DRAFT_TOOL,
|
|
4178
|
+
description: "\u5EFA\u4E00\u6761\u5B9A\u65F6\u4EFB\u52A1\uFF0C\u6216\u8005\u6539\u4E00\u6761\u5DF2\u6709\u7684\u3002\u5B9A\u65F6\u4EFB\u52A1\u662F\u300C\u5230\u70B9\u4E86\u81EA\u5DF1\u8DD1\u4E00\u6B21\u300D\u2014\u2014\u7528\u6237\u8BF4\u300C\u4EE5\u540E\u6BCF\u5929/\u6BCF\u5468\u5E2E\u6211\u505A\u67D0\u4EF6\u4E8B\u300D\u300C\u5B9A\u671F\u68C0\u67E5\u67D0\u67D0\u300D\uFF0C\u6216\u8005\u4F60\u53D1\u73B0\u67D0\u4EF6\u4E8B\u4ED6\u6BCF\u6B21\u90FD\u8981\u624B\u52A8\u505A\u4E00\u904D\u65F6\uFF0C\u7528\u5B83\u3002action=list \u770B\u73B0\u6709\u4EFB\u52A1\uFF08\u8981\u6539\u67D0\u6761\u5FC5\u987B\u5148 list \u62FF\u5230 id\uFF09\uFF1Baction=create \u76F4\u63A5\u5EFA\u4E00\u6761\uFF1Baction=update \u76F4\u63A5\u6539\u4E00\u6761\u3002\u26A0\uFE0F **\u5B83\u4EA4\u4E0A\u53BB\u5C31\u751F\u6548**\uFF08plan \u53EA\u8BFB\u6863\u4E0B\u9664\u5916\uFF0C\u90A3\u4E00\u6863\u53EA\u4EA4\u63D0\u6848\uFF09\u2014\u2014 \u5EFA\u5B8C\u5728\u4F60\u7684\u56DE\u590D\u91CC\u4EA4\u4EE3\u4E00\u53E5\u5C31\u884C\uFF0C\u522B\u95EE\u300C\u8981\u4E0D\u8981\u6211\u5EFA\u300D\u3002\u6743\u9650\u6863\u4E0D\u7ED9\u5C31\u662F auto\uFF08\u65B0\u5EFA\u4EFB\u52A1\u7684\u7F3A\u7701\uFF09\u2014\u2014 \u5B9A\u65F6\u4EFB\u52A1\u6CA1\u4EBA\u53EF\u95EE\uFF0C\u4F4E\u6863\u5728\u8FD9\u91CC\u7B49\u4E8E\u300C\u5230\u70B9\u5FC5\u7136\u5931\u8D25\u300D\u3002\u53EA\u6709\u7528\u6237\u660E\u786E\u8981\u6C42\u300C\u53EA\u8BFB / \u522B\u52A8\u4E1C\u897F\u300D\u65F6\u624D\u7528 plan\uFF0C\u90A3\u7C7B\u4EFB\u52A1\u5929\u7136\u96F6\u6388\u6743\u9762\u3002",
|
|
4179
|
+
parameters: {
|
|
4180
|
+
type: "object",
|
|
4181
|
+
properties: {
|
|
4182
|
+
action: {
|
|
4183
|
+
type: "string",
|
|
4184
|
+
description: "\u505A\u54EA\u4E00\u4EF6",
|
|
4185
|
+
enum: ["list", "create", "update"]
|
|
4186
|
+
},
|
|
4187
|
+
note: {
|
|
4188
|
+
type: "string",
|
|
4189
|
+
description: "\u4E3A\u4EC0\u4E48\u5EFA\u8FD9\u6761\uFF0C\u4E00\u53E5\u8BDD\u3002create / update \u5FC5\u586B\uFF0C\u4F1A\u5370\u5728\u7528\u6237\u770B\u5230\u7684\u5361\u7247\u4E0A\uFF1B\u8BF4\u4E0D\u51FA\u771F\u5B9E\u7406\u7531\u5C31\u522B\u63D0\u8FD9\u4E2A\u5EFA\u8BAE"
|
|
4190
|
+
},
|
|
4191
|
+
id: { type: "string", description: "\u6539\u54EA\u4E00\u6761\u3002update \u5FC5\u586B\uFF0C\u4ECE action=list \u91CC\u62FF" },
|
|
4192
|
+
name: { type: "string", description: "\u4EFB\u52A1\u540D\uFF0C\u7528\u6237\u5728\u5217\u8868\u91CC\u770B\u5230\u7684\u5C31\u662F\u5B83" },
|
|
4193
|
+
prompt: {
|
|
4194
|
+
type: "string",
|
|
4195
|
+
description: "\u5230\u70B9\u4E86\u53D1\u7ED9 agent \u7684\u63D0\u793A\u8BCD\u3002\u65E0\u4EBA\u503C\u5B88\uFF0C\u6240\u4EE5\u8981\u5199\u6210\u4E00\u53E5\u81EA\u8DB3\u7684\u6307\u4EE4\uFF1B\u8BA9\u5B83\u628A\u7ED3\u679C\u8FFD\u52A0\u5230\u4E00\u4EFD markdown \u6587\u4EF6\u91CC\u901A\u5E38\u6BD4\u4EC0\u4E48\u90FD\u4E0D\u843D\u5730\u6709\u7528"
|
|
4196
|
+
},
|
|
4197
|
+
trigger: {
|
|
4198
|
+
type: "object",
|
|
4199
|
+
description: '\u4EC0\u4E48\u65F6\u5019\u8DD1\u3002\u4E09\u6863\uFF1A{kind:"cron",cycle:"daily",at:"09:00"} / {kind:"cron",cycle:"weekly",at:"09:00",weekdays:[1,3,5]} / {kind:"cron",cycle:"monthly",at:"09:00",days:[1,15]} / {kind:"interval",everyMinutes:30} / {kind:"once",date:"2026-12-31",at:"23:00"}\u3002cron \u6863\u4E00\u5929\u8DD1\u51E0\u6B21\u5C31\u628A\u5176\u4F59\u65F6\u523B\u653E\u8FDB alsoAt\uFF1A{kind:"cron",cycle:"daily",at:"09:00",alsoAt:["14:00","18:00"]}\u3002everyMinutes \u662F 5\u20131440 \u7684\u6574\u6570\uFF0C\u6BCF\u5929\u4ECE 0 \u70B9\u8D77\u7B97\u3002\u6CA1\u6709\u5B8C\u6574 cron \u8868\u8FBE\u5F0F',
|
|
4200
|
+
properties: {
|
|
4201
|
+
kind: { type: "string", enum: ["cron", "interval", "once"] },
|
|
4202
|
+
cycle: { type: "string", enum: ["daily", "weekly", "monthly"] },
|
|
4203
|
+
at: { type: "string", description: "HH:mm\uFF0C24 \u5C0F\u65F6\u5236\uFF0C\u672C\u673A\u65F6\u533A" },
|
|
4204
|
+
alsoAt: {
|
|
4205
|
+
type: "array",
|
|
4206
|
+
items: { type: "string" },
|
|
4207
|
+
description: "cron \u6863\u5728 at \u4E4B\u5916\u7684\u5176\u4F59\u65F6\u523B\uFF08HH:mm\uFF09"
|
|
4208
|
+
},
|
|
4209
|
+
weekdays: { type: "array", items: { type: "number" }, description: "0=\u5468\u65E5 \u2026 6=\u5468\u516D" },
|
|
4210
|
+
days: { type: "array", items: { type: "number" }, description: "\u51E0\u53F7\uFF0C1\u201331" },
|
|
4211
|
+
everyMinutes: { type: "number" },
|
|
4212
|
+
date: { type: "string", description: "YYYY-MM-DD" }
|
|
4213
|
+
},
|
|
4214
|
+
required: ["kind"]
|
|
4215
|
+
},
|
|
4216
|
+
workDir: {
|
|
4217
|
+
type: "string",
|
|
4218
|
+
description: "\u5728\u54EA\u4E2A\u76EE\u5F55\u91CC\u8DD1\u3002\u7EDD\u5BF9\u8DEF\u5F84\u3002\u4E0D\u7ED9\u5C31\u843D\u5728 ~/.epoch/automation/<id>/"
|
|
4219
|
+
},
|
|
4220
|
+
permission: {
|
|
4221
|
+
type: "string",
|
|
4222
|
+
description: "\u6743\u9650\u6863\u3002\u4E0D\u7ED9\u5C31\u662F auto\uFF08**\u65B0\u5EFA\u4EFB\u52A1\u7684\u7F3A\u7701**\uFF0C2026-10-27 \u8D77\uFF1A\u5B9A\u65F6\u4EFB\u52A1\u6CA1\u4EBA\u53EF\u95EE\uFF0C\u4F4E\u6863\u5728\u8FD9\u91CC\u7B49\u4E8E\u300C\u5230\u70B9\u5FC5\u7136\u5931\u8D25\u300D\uFF09\u3002auto=\u5B8C\u5168\u8BBF\u95EE\uFF08\u4E0D\u518D\u786E\u8BA4\uFF0C\u53EA\u5269\u707E\u96BE\u7EA7\u4F1A\u88AB\u62E6\u4E0B\uFF09\uFF1BacceptEdits=\u8BF7\u6C42\u6279\u51C6\uFF1Bdefault=\u9010\u6761\u786E\u8BA4\uFF1Bplan=\u53EA\u8BFB\uFF08\u8BFB\u4E00\u904D\u5199\u4EFD\u62A5\u544A\u7684\u4EFB\u52A1\u7528\u5B83\uFF0C\u5929\u7136\u96F6\u6388\u6743\u9762\uFF09\u3002**\u53EA\u6709\u5728\u7528\u6237\u660E\u786E\u8BF4\u4E86\u8981\u7A84\u4E00\u6863\u65F6\u624D\u964D**",
|
|
4223
|
+
enum: ["plan", "default", "acceptEdits", "auto"]
|
|
4224
|
+
},
|
|
4225
|
+
allowTools: {
|
|
4226
|
+
type: "array",
|
|
4227
|
+
items: { type: "string" },
|
|
4228
|
+
description: "\u6574\u4E2A\u5DE5\u5177\u90FD\u4E0D\u7528\u95EE\u3002\u8303\u56F4\u6700\u7C97\uFF0C\u80FD\u7528 allowRules \u5C31\u522B\u7528\u5B83"
|
|
4229
|
+
},
|
|
4230
|
+
allowOperations: {
|
|
4231
|
+
type: "array",
|
|
4232
|
+
items: { type: "string" },
|
|
4233
|
+
description: "\u6574\u7C7B\u64CD\u4F5C\u90FD\u4E0D\u7528\u95EE\uFF1Afile_read / file_write / command / network / code_exec"
|
|
4234
|
+
},
|
|
4235
|
+
allowRules: {
|
|
4236
|
+
type: "array",
|
|
4237
|
+
items: { type: "string" },
|
|
4238
|
+
description: "\u9010\u6761\u653E\u884C\uFF0C\u6700\u63A8\u8350\u7684\u4E00\u683C\u3002\u5199\u6CD5\uFF1Aterminal(git status) / terminal(git log:*) / file_write(~/reports/**)\u3002\u65E0\u4EBA\u503C\u5B88\u4E0B\u649E\u5230\u8981\u786E\u8BA4\u7684\u64CD\u4F5C\u4E0D\u4F1A\u7B49\u4EBA\uFF0C\u4F1A\u76F4\u63A5\u6536\u5C3E\u5E76\u8BB0\u4E00\u6761\u6B20\u6761 \u2014\u2014 \u6240\u4EE5\u4EFB\u52A1\u8981\u8DD1\u4EC0\u4E48\u547D\u4EE4\uFF0C\u8FD9\u91CC\u5C31\u5F97\u9010\u6761\u5217\u51FA\u6765"
|
|
4239
|
+
},
|
|
4240
|
+
enabled: { type: "boolean", description: "\u53EA\u6709 update \u7528\u3002\u542F\u7528 / \u505C\u7528\u90A3\u4E00\u6761" },
|
|
4241
|
+
maxTurns: { type: "number", description: "\u53EA\u6709 update \u7528\u3002\u8F6E\u6B21\u4E0A\u9650\uFF0C\u6B63\u6574\u6570" },
|
|
4242
|
+
timeoutMs: { type: "number", description: "\u53EA\u6709 update \u7528\u3002\u5899\u949F\u8D85\u65F6\uFF0C\u6BEB\u79D2" }
|
|
4243
|
+
},
|
|
4244
|
+
required: ["action"]
|
|
4245
|
+
},
|
|
4246
|
+
exposure: ToolExposure.Direct,
|
|
4247
|
+
supportsParallel: false,
|
|
4248
|
+
annotations: {
|
|
4249
|
+
readOnlyHint: false,
|
|
4250
|
+
destructiveHint: true,
|
|
4251
|
+
idempotentHint: false,
|
|
4252
|
+
openWorldHint: false
|
|
4253
|
+
},
|
|
4254
|
+
operation: "file_read",
|
|
4255
|
+
describeTarget: (args) => `schedule_draft:${String(args["action"] ?? "list")}`,
|
|
4256
|
+
async execute(rawArgs, ctx) {
|
|
4257
|
+
const startedAt = Date.now();
|
|
4258
|
+
const action = rawArgs["action"];
|
|
4259
|
+
if (action === "list") {
|
|
4260
|
+
const rows = deps.list();
|
|
4261
|
+
return say4(
|
|
4262
|
+
rows.length === 0 ? "\u4E00\u6761\u5B9A\u65F6\u4EFB\u52A1\u90FD\u8FD8\u6CA1\u6709\u3002\u8981\u65B0\u5EFA\u5C31\u7528 action=create\u3002" : `\u73B0\u6709 ${rows.length} \u6761\uFF1A
|
|
4263
|
+
${rows.map(describeRow).join("\n")}`,
|
|
4264
|
+
true,
|
|
4265
|
+
startedAt
|
|
4266
|
+
);
|
|
4267
|
+
}
|
|
4268
|
+
const parsed = parseScheduleDraft(rawArgs);
|
|
4269
|
+
if (!parsed.ok) return say4(parsed.message, false, startedAt);
|
|
4270
|
+
const draft = parsed.value;
|
|
4271
|
+
const current = draft.action === "update" ? deps.get(draft.id) : void 0;
|
|
4272
|
+
if (draft.action === "update" && current === void 0) {
|
|
4273
|
+
return say4(
|
|
4274
|
+
`\u6CA1\u6709 id \u4E3A ${draft.id} \u7684\u4EFB\u52A1\u3002\u5148\u7528 action=list \u770B\u4E00\u773C\u73B0\u6709\u7684\u3002`,
|
|
4275
|
+
false,
|
|
4276
|
+
startedAt
|
|
4277
|
+
);
|
|
4278
|
+
}
|
|
4279
|
+
const issues = validateDraft(draft, deps.homeDir, current);
|
|
4280
|
+
if (issues.length > 0) {
|
|
4281
|
+
return say4(
|
|
4282
|
+
`\u8FD9\u4EFD\u63D0\u6848\u5B58\u4E0D\u4E0B\u6765\uFF0C\u5148\u6539\u8FD9\u51E0\u5904\u518D\u8BF4\uFF1A${issues.join("\u3001")}\u3002\uFF08\u8FD9\u4E9B\u662F\u6821\u9A8C\u7801\uFF0C\u542B\u4E49\u770B\u5B57\u9762\uFF1Bdetail \u62EC\u5728\u540E\u9762\uFF09`,
|
|
4283
|
+
false,
|
|
4284
|
+
startedAt
|
|
4285
|
+
);
|
|
4286
|
+
}
|
|
4287
|
+
const unattended = unattendedIssues(draft);
|
|
4288
|
+
if (unattended.length > 0) {
|
|
4289
|
+
return say4(
|
|
4290
|
+
`\u8FD9\u4EFD\u63D0\u6848\u5B58\u5F97\u4E0B\u6765\uFF0C\u4F46\u5B83\u5230\u70B9\u4E86**\u8DD1\u4E0D\u51FA\u7ED3\u679C** \u2014\u2014 \u5B9A\u65F6\u4EFB\u52A1\u662F\u65E0\u4EBA\u503C\u5B88\u7684\uFF0C\u6CA1\u4EBA\u5728\u65C1\u8FB9\u56DE\u8BDD\u3002\u6539\u5B8C\u518D\u4EA4\uFF1A
|
|
4291
|
+
${unattended.map((x) => `\xB7 ${x}`).join("\n")}`,
|
|
4292
|
+
false,
|
|
4293
|
+
startedAt
|
|
4294
|
+
);
|
|
4295
|
+
}
|
|
4296
|
+
const readOnly = ctx.permissionLevel === "plan";
|
|
4297
|
+
if (readOnly || deps.save === void 0) {
|
|
4298
|
+
return say4(summarizeProposal(draft, current, readOnly), true, startedAt);
|
|
4299
|
+
}
|
|
4300
|
+
const saved = await persist(deps.save, draft, current);
|
|
4301
|
+
if (saved.issues.length > 0) {
|
|
4302
|
+
const codes = saved.issues.map((x) => x.detail ? `${x.code}\uFF08${x.detail}\uFF09` : x.code);
|
|
4303
|
+
return say4(`\u5F15\u64CE\u62D2\u7EDD\u4E86\u8FD9\u4EFD\u63D0\u6848\uFF0C\u4E00\u4E2A\u5B57\u90FD\u6CA1\u5199\uFF1A${codes.join("\u3001")}\u3002`, false, startedAt);
|
|
4304
|
+
}
|
|
4305
|
+
const def = saved.schedule;
|
|
4306
|
+
if (def === void 0) {
|
|
4307
|
+
return say4(
|
|
4308
|
+
"\u5F15\u64CE\u8BF4\u5B58\u4E0B\u6765\u4E86\uFF0C\u4F46\u6CA1\u56DE\u90A3\u6761\u4EFB\u52A1 \u2014\u2014 \u53BB\u81EA\u52A8\u5316\u9762\u677F\u770B\u4E00\u773C\u5B83\u5230\u5E95\u5728\u4E0D\u5728\u3002",
|
|
4309
|
+
false,
|
|
4310
|
+
startedAt
|
|
4311
|
+
);
|
|
4312
|
+
}
|
|
4313
|
+
return say4(summarizeSaved(draft, def, saved.registration, current), true, startedAt);
|
|
4314
|
+
}
|
|
4315
|
+
};
|
|
4316
|
+
}
|
|
4317
|
+
var DEFAULT_INBOX_CAPACITY = 20;
|
|
4318
|
+
var AgentInbox = class {
|
|
4319
|
+
constructor(capacity = DEFAULT_INBOX_CAPACITY) {
|
|
4320
|
+
this.capacity = capacity;
|
|
4321
|
+
}
|
|
4322
|
+
capacity;
|
|
4323
|
+
queue = [];
|
|
4324
|
+
dropped = 0;
|
|
4325
|
+
push(msg) {
|
|
4326
|
+
let evicted = false;
|
|
4327
|
+
while (this.queue.length >= this.capacity) {
|
|
4328
|
+
this.queue.shift();
|
|
4329
|
+
this.dropped += 1;
|
|
4330
|
+
evicted = true;
|
|
4331
|
+
}
|
|
4332
|
+
this.queue.push(msg);
|
|
4333
|
+
return !evicted;
|
|
4334
|
+
}
|
|
4335
|
+
pending() {
|
|
4336
|
+
return this.queue.length > 0;
|
|
4337
|
+
}
|
|
4338
|
+
take() {
|
|
4339
|
+
if (this.queue.length === 0) return [];
|
|
4340
|
+
const lines = this.queue.map((m) => agentMessageLine(m));
|
|
4341
|
+
this.queue = [];
|
|
4342
|
+
if (this.dropped > 0) {
|
|
4343
|
+
lines.unshift(systemNote(`\u6536\u4EF6\u7BB1\u6EE1\u4E86\uFF0C\u6709 ${this.dropped} \u6761\u66F4\u65E9\u7684\u6D88\u606F\u88AB\u4E22\u5F03`));
|
|
4344
|
+
this.dropped = 0;
|
|
4345
|
+
}
|
|
4346
|
+
return [lines.join("\n")];
|
|
4347
|
+
}
|
|
4348
|
+
get size() {
|
|
4349
|
+
return this.queue.length;
|
|
4350
|
+
}
|
|
4351
|
+
};
|
|
4352
|
+
var DEFAULT_TASK_CAPACITY = 200;
|
|
4353
|
+
var TeamTaskBoard = class {
|
|
4354
|
+
constructor(capacity = DEFAULT_TASK_CAPACITY) {
|
|
4355
|
+
this.capacity = capacity;
|
|
4356
|
+
}
|
|
4357
|
+
capacity;
|
|
4358
|
+
tasks = /* @__PURE__ */ new Map();
|
|
4359
|
+
listeners = /* @__PURE__ */ new Set();
|
|
4360
|
+
onChange(cb) {
|
|
4361
|
+
this.listeners.add(cb);
|
|
4362
|
+
return () => {
|
|
4363
|
+
this.listeners.delete(cb);
|
|
4364
|
+
};
|
|
4365
|
+
}
|
|
4366
|
+
notify() {
|
|
4367
|
+
for (const cb of this.listeners) {
|
|
4368
|
+
try {
|
|
4369
|
+
cb();
|
|
4370
|
+
} catch {
|
|
4371
|
+
}
|
|
4372
|
+
}
|
|
4373
|
+
}
|
|
4374
|
+
create(input) {
|
|
4375
|
+
if (this.tasks.size >= this.capacity) {
|
|
4376
|
+
return { ok: false, reason: `\u4EFB\u52A1\u677F\u6EE1\u4E86\uFF08${this.capacity} \u6761\uFF09\uFF0C\u5148\u505A\u5B8C\u518D\u5EFA` };
|
|
4377
|
+
}
|
|
4378
|
+
const dependsOn = input.dependsOn ?? [];
|
|
4379
|
+
const missing = dependsOn.filter((id) => !this.tasks.has(id));
|
|
4380
|
+
if (missing.length > 0) {
|
|
4381
|
+
return { ok: false, reason: `\u4F9D\u8D56\u7684\u4EFB\u52A1\u4E0D\u5B58\u5728\uFF1A${missing.join(", ")}` };
|
|
4382
|
+
}
|
|
4383
|
+
const now = Date.now();
|
|
4384
|
+
const task = {
|
|
4385
|
+
id: `task-${randomUUID().slice(0, 8)}`,
|
|
4386
|
+
title: input.title,
|
|
4387
|
+
...input.description ? { description: input.description } : {},
|
|
4388
|
+
...input.owner ? { owner: input.owner } : {},
|
|
4389
|
+
status: "pending",
|
|
4390
|
+
dependsOn,
|
|
4391
|
+
revision: 1,
|
|
4392
|
+
createdAt: now,
|
|
4393
|
+
updatedAt: now
|
|
4394
|
+
};
|
|
4395
|
+
this.tasks.set(task.id, task);
|
|
4396
|
+
this.notify();
|
|
4397
|
+
return { ok: true, task: { ...task } };
|
|
4398
|
+
}
|
|
4399
|
+
get(id) {
|
|
4400
|
+
const t83 = this.tasks.get(id);
|
|
4401
|
+
return t83 ? { ...t83 } : void 0;
|
|
4402
|
+
}
|
|
4403
|
+
list(filter) {
|
|
4404
|
+
return [...this.tasks.values()].filter((t83) => filter?.status ? t83.status === filter.status : true).filter((t83) => filter?.owner ? t83.owner === filter.owner : true).sort((a, b) => a.createdAt - b.createdAt).map((t83) => ({ ...t83 }));
|
|
4405
|
+
}
|
|
4406
|
+
update(id, patch, expectedRevision) {
|
|
4407
|
+
const current = this.tasks.get(id);
|
|
4408
|
+
if (!current) return { ok: false, reason: `\u6CA1\u6709\u8FD9\u4E2A\u4EFB\u52A1\uFF1A${id}` };
|
|
4409
|
+
if (expectedRevision !== void 0 && current.revision !== expectedRevision) {
|
|
4410
|
+
return {
|
|
4411
|
+
ok: false,
|
|
4412
|
+
reason: `\u4EFB\u52A1 ${id} \u5DF2\u7ECF\u53D8\u8FC7\u4E86\uFF1A\u4F60\u624B\u4E0A\u662F revision ${expectedRevision}\uFF0C\u73B0\u5728\u662F ${current.revision}\u3002\u91CD\u65B0 team_task_get \u8BFB\u4E00\u904D\u518D\u6539`
|
|
4413
|
+
};
|
|
4414
|
+
}
|
|
4415
|
+
const next = {
|
|
4416
|
+
...current,
|
|
4417
|
+
...patch.title !== void 0 ? { title: patch.title } : {},
|
|
4418
|
+
...patch.description !== void 0 ? { description: patch.description } : {},
|
|
4419
|
+
...patch.status !== void 0 ? { status: patch.status } : {},
|
|
4420
|
+
...patch.owner !== void 0 ? { owner: patch.owner } : {},
|
|
4421
|
+
revision: current.revision + 1,
|
|
4422
|
+
updatedAt: Date.now()
|
|
4423
|
+
};
|
|
4424
|
+
this.tasks.set(id, next);
|
|
4425
|
+
this.notify();
|
|
4426
|
+
return { ok: true, task: { ...next } };
|
|
4427
|
+
}
|
|
4428
|
+
};
|
|
4429
|
+
// src/team/registry.ts
|
|
4430
|
+
var TeamRegistry = class {
|
|
4431
|
+
constructor(inboxCapacity = DEFAULT_INBOX_CAPACITY) {
|
|
4432
|
+
this.inboxCapacity = inboxCapacity;
|
|
4433
|
+
this.tasks = new TeamTaskBoard();
|
|
4434
|
+
this.tasks.onChange(() => this.notify());
|
|
4435
|
+
}
|
|
4436
|
+
inboxCapacity;
|
|
4437
|
+
members = /* @__PURE__ */ new Map();
|
|
4438
|
+
bySessionId = /* @__PURE__ */ new Map();
|
|
4439
|
+
mainInboxes = /* @__PURE__ */ new Map();
|
|
4440
|
+
sessions = /* @__PURE__ */ new Set();
|
|
4441
|
+
aborters = /* @__PURE__ */ new Map();
|
|
4442
|
+
listeners = /* @__PURE__ */ new Set();
|
|
4443
|
+
tasks;
|
|
4444
|
+
onChange(cb) {
|
|
4445
|
+
this.listeners.add(cb);
|
|
4446
|
+
return () => {
|
|
4447
|
+
this.listeners.delete(cb);
|
|
4448
|
+
};
|
|
4449
|
+
}
|
|
4450
|
+
notify() {
|
|
4451
|
+
for (const cb of this.listeners) {
|
|
4452
|
+
try {
|
|
4453
|
+
cb();
|
|
4454
|
+
} catch {
|
|
4455
|
+
}
|
|
4456
|
+
}
|
|
4457
|
+
}
|
|
4458
|
+
waitForChange(ms, signal) {
|
|
4459
|
+
return new Promise((resolve17) => {
|
|
4460
|
+
let done2 = false;
|
|
4461
|
+
const onAbort = () => finish(false);
|
|
4462
|
+
const cleanup = () => {
|
|
4463
|
+
off();
|
|
4464
|
+
clearTimeout(timer);
|
|
4465
|
+
signal?.removeEventListener?.("abort", onAbort);
|
|
4466
|
+
};
|
|
4467
|
+
const finish = (v) => {
|
|
4468
|
+
if (done2) return;
|
|
4469
|
+
done2 = true;
|
|
4470
|
+
cleanup();
|
|
4471
|
+
resolve17(v);
|
|
4472
|
+
};
|
|
4473
|
+
const off = this.onChange(() => finish(true));
|
|
4474
|
+
const timer = setTimeout(() => finish(false), ms);
|
|
4475
|
+
signal?.addEventListener?.("abort", onAbort);
|
|
4476
|
+
});
|
|
4477
|
+
}
|
|
4478
|
+
createMember(args) {
|
|
4479
|
+
const agentId = args.agentId ?? args.sessionId;
|
|
4480
|
+
if (this.members.has(agentId)) {
|
|
4481
|
+
throw new Error(`\u6210\u5458\u540D\u5DF2\u88AB\u5360\u7528\uFF1A${agentId}`);
|
|
4482
|
+
}
|
|
4483
|
+
const info = {
|
|
4484
|
+
agentId,
|
|
4485
|
+
sessionId: args.sessionId,
|
|
4486
|
+
parentSessionId: args.parentSessionId,
|
|
4487
|
+
status: "running",
|
|
4488
|
+
...args.role ? { role: args.role } : {},
|
|
4489
|
+
startedAt: Date.now()
|
|
4490
|
+
};
|
|
4491
|
+
this.members.set(agentId, {
|
|
4492
|
+
info,
|
|
4493
|
+
inbox: new AgentInbox(this.inboxCapacity)
|
|
4494
|
+
});
|
|
4495
|
+
this.bySessionId.set(args.sessionId, agentId);
|
|
4496
|
+
this.notify();
|
|
4497
|
+
return { ...info };
|
|
4498
|
+
}
|
|
4499
|
+
setAbort(agentId, fn) {
|
|
4500
|
+
if (!this.members.has(agentId)) return;
|
|
4501
|
+
this.aborters.set(agentId, fn);
|
|
4502
|
+
}
|
|
4503
|
+
interrupt(agentId) {
|
|
4504
|
+
const fn = this.aborters.get(agentId);
|
|
4505
|
+
if (!fn) return false;
|
|
4506
|
+
fn();
|
|
4507
|
+
this.notify();
|
|
4508
|
+
return true;
|
|
4509
|
+
}
|
|
4510
|
+
get(agentId) {
|
|
4511
|
+
const entry = this.members.get(agentId);
|
|
4512
|
+
return entry ? { ...entry.info } : void 0;
|
|
4513
|
+
}
|
|
4514
|
+
bySession(sessionId) {
|
|
4515
|
+
const agentId = this.bySessionId.get(sessionId);
|
|
4516
|
+
return agentId ? this.get(agentId) : void 0;
|
|
4517
|
+
}
|
|
4518
|
+
list() {
|
|
4519
|
+
return [...this.members.values()].map((e) => e.info).sort((a, b) => a.startedAt - b.startedAt);
|
|
4520
|
+
}
|
|
4521
|
+
inboxOf(agentId) {
|
|
4522
|
+
return this.members.get(agentId)?.inbox;
|
|
4523
|
+
}
|
|
4524
|
+
inboxBySession(sessionId) {
|
|
4525
|
+
const agentId = this.bySessionId.get(sessionId);
|
|
4526
|
+
return agentId ? this.inboxOf(agentId) : void 0;
|
|
4527
|
+
}
|
|
4528
|
+
registerSession(sessionId) {
|
|
4529
|
+
if (this.sessions.has(sessionId)) return;
|
|
4530
|
+
this.sessions.add(sessionId);
|
|
4531
|
+
this.notify();
|
|
4532
|
+
}
|
|
4533
|
+
hasSession(sessionId) {
|
|
4534
|
+
return this.sessions.has(sessionId);
|
|
4535
|
+
}
|
|
4536
|
+
sessionIds() {
|
|
4537
|
+
return [...this.sessions];
|
|
4538
|
+
}
|
|
4539
|
+
mainInbox(sessionId) {
|
|
4540
|
+
let inbox = this.mainInboxes.get(sessionId);
|
|
4541
|
+
if (!inbox) {
|
|
4542
|
+
inbox = new AgentInbox(this.inboxCapacity);
|
|
4543
|
+
this.mainInboxes.set(sessionId, inbox);
|
|
4544
|
+
}
|
|
4545
|
+
return inbox;
|
|
4546
|
+
}
|
|
4547
|
+
setActivity(agentId, line) {
|
|
4548
|
+
const entry = this.members.get(agentId);
|
|
4549
|
+
if (!entry) return;
|
|
4550
|
+
entry.info.activity = line;
|
|
4551
|
+
}
|
|
4552
|
+
markRunning(agentId) {
|
|
4553
|
+
const entry = this.members.get(agentId);
|
|
4554
|
+
if (!entry) return;
|
|
4555
|
+
entry.info.status = "running";
|
|
4556
|
+
delete entry.info.finishedAt;
|
|
4557
|
+
delete entry.info.activity;
|
|
4558
|
+
this.notify();
|
|
4559
|
+
}
|
|
4560
|
+
markFinished(agentId, status) {
|
|
4561
|
+
const entry = this.members.get(agentId);
|
|
4562
|
+
if (!entry) return;
|
|
4563
|
+
if (entry.info.finishedAt !== void 0) return;
|
|
4564
|
+
entry.info.status = status;
|
|
4565
|
+
entry.info.finishedAt = Date.now();
|
|
4566
|
+
this.aborters.delete(agentId);
|
|
4567
|
+
this.notify();
|
|
4568
|
+
}
|
|
4569
|
+
deliver(msg) {
|
|
4570
|
+
if (msg.to === LEAD_AGENT_ID) {
|
|
4571
|
+
const sender = this.members.get(msg.from);
|
|
4572
|
+
if (sender) {
|
|
4573
|
+
this.mainInbox(sender.info.parentSessionId).push(msg);
|
|
4574
|
+
this.notify();
|
|
4575
|
+
return { ok: true, to: msg.to, status: "running" };
|
|
4576
|
+
}
|
|
4577
|
+
return { ok: false, to: msg.to, reason: `\u4E3B\u4F1A\u8BDD\u4E0D\u80FD\u53D1\u7ED9 ${LEAD_AGENT_ID}` };
|
|
4578
|
+
}
|
|
4579
|
+
const entry = this.members.get(msg.to);
|
|
4580
|
+
if (entry) {
|
|
4581
|
+
if (entry.info.status === "finalized" || entry.info.status === "failed") {
|
|
4582
|
+
return {
|
|
4583
|
+
ok: false,
|
|
4584
|
+
to: msg.to,
|
|
4585
|
+
reason: `${msg.to} \u5DF2\u7ECF\u6536\u5DE5\u4E86\uFF08${entry.info.status}\uFF09\uFF0C\u6D88\u606F\u6CA1\u9001\u51FA\u53BB \u2014\u2014 \u5B83\u4E0D\u4F1A\u6709\u4E0B\u4E00\u8F6E\u6765\u8BFB`
|
|
4586
|
+
};
|
|
4587
|
+
}
|
|
4588
|
+
entry.inbox.push(msg);
|
|
4589
|
+
this.notify();
|
|
4590
|
+
return { ok: true, to: msg.to, status: entry.info.status };
|
|
4591
|
+
}
|
|
4592
|
+
if (this.sessions.has(msg.to)) {
|
|
4593
|
+
this.mainInbox(msg.to).push(msg);
|
|
4594
|
+
this.notify();
|
|
4595
|
+
return { ok: true, to: msg.to, status: "running" };
|
|
4596
|
+
}
|
|
4597
|
+
return {
|
|
4598
|
+
ok: false,
|
|
4599
|
+
to: msg.to,
|
|
4600
|
+
reason: `\u6CA1\u6709\u8FD9\u4E2A\u6210\u5458\u6216\u4F1A\u8BDD\uFF1A${msg.to}\u3002\u7528 list_agents --all \u770B\u73B0\u5728\u6709\u8C01`
|
|
4601
|
+
};
|
|
4602
|
+
}
|
|
4603
|
+
static message(args) {
|
|
4604
|
+
return {
|
|
4605
|
+
id: randomUUID(),
|
|
4606
|
+
from: args.from,
|
|
4607
|
+
to: args.to,
|
|
4608
|
+
text: args.text,
|
|
4609
|
+
sentAt: Date.now()
|
|
4610
|
+
};
|
|
4611
|
+
}
|
|
4612
|
+
};
|
|
4613
|
+
// src/tools/builtin/send-message.ts
|
|
4614
|
+
var SEND_MESSAGE_TOOL = "send_message";
|
|
4615
|
+
function createSendMessageTool(team) {
|
|
4616
|
+
return {
|
|
4617
|
+
name: SEND_MESSAGE_TOOL,
|
|
4618
|
+
description: [
|
|
4619
|
+
"\u7ED9\u53E6\u4E00\u4E2A agent \u6216**\u53E6\u4E00\u6BB5\u4F1A\u8BDD**\u53D1\u4E00\u6761\u6D88\u606F\u3002**\u4E0D\u662F\u6D3E\u6D3B** \u2014\u2014 \u4E0D\u4F1A\u65B0\u5F00\u6210\u5458\u3001\u4E0D\u4F1A\u7B49\u5B83\u4EA4\u7ED3\u8BBA\u3002",
|
|
4620
|
+
"\u53D1\u7ED9\u6B63\u5728\u8DD1\u7684\u6210\u5458\uFF08\u5B50 agent\uFF09\uFF1A\u5B83\u5728\u4E0B\u4E00\u6B65\u5C31\u6536\u5230\uFF0C\u5F53\u8F6E\u5C31\u80FD\u636E\u6B64\u6539\u53D8\u884C\u4E3A\u3002",
|
|
4621
|
+
`\u53D1\u7ED9 \`${LEAD_AGENT_ID}\`\uFF08\u6D3E\u4F60\u51FA\u6765\u7684\u90A3\u4E2A\u4F1A\u8BDD\uFF09\uFF1A\u5B83\u4E0B\u4E00\u8F6E\u5F00\u5934\u4F1A\u770B\u5230\u3002`,
|
|
4622
|
+
"\u53D1\u7ED9**\u53E6\u4E00\u6BB5\u4E3B\u4F1A\u8BDD**\uFF08\u7528 list_agents --all \u770B\u5230\u7684\u90A3\u4E2A sessionId\uFF09\uFF1A\u5B83\u4E0B\u4E00\u8F6E\u5F00\u5934\u4F1A\u770B\u5230\u3002",
|
|
4623
|
+
"\u53D1\u7ED9\u5DF2\u7ECF\u6536\u5DE5\u7684\u6210\u5458\u4F1A\u5931\u8D25 \u2014\u2014 \u90A3\u4E9B\u8981\u9760 delegate_task \u91CD\u65B0\u6D3E\u3002",
|
|
4624
|
+
"\u7528 list_agents \u770B\u672C\u4F1A\u8BDD\u7684\u6210\u5458\uFF1B\u52A0 --all \u770B\u6240\u6709\u4F1A\u8BDD\u548C\u6210\u5458\u3002"
|
|
4625
|
+
].join("\n"),
|
|
4626
|
+
parameters: {
|
|
4627
|
+
type: "object",
|
|
4628
|
+
properties: {
|
|
4629
|
+
to: {
|
|
4630
|
+
type: "string",
|
|
4631
|
+
description: `\u6536\u4EF6\u4EBA\uFF1A\u67D0\u4E2A\u6210\u5458\u7684 id\uFF0C\u6216 \`${LEAD_AGENT_ID}\``
|
|
4632
|
+
},
|
|
4633
|
+
text: {
|
|
4634
|
+
type: "string",
|
|
4635
|
+
description: "\u8981\u8BF4\u4EC0\u4E48\u3002\u5199\u6E05\u695A\u4F60\u8981\u5BF9\u65B9\u505A\u4EC0\u4E48\u3001\u4E3A\u4EC0\u4E48 \u2014\u2014 \u5B83\u770B\u4E0D\u5230\u4F60\u8FD9\u8FB9\u53D1\u751F\u4E86\u4EC0\u4E48"
|
|
4636
|
+
}
|
|
4637
|
+
},
|
|
4638
|
+
required: ["to", "text"]
|
|
4639
|
+
},
|
|
4640
|
+
exposure: ToolExposure.Direct,
|
|
4641
|
+
supportsParallel: false,
|
|
4642
|
+
operation: "file_read",
|
|
4643
|
+
annotations: {
|
|
4644
|
+
readOnlyHint: true,
|
|
4645
|
+
destructiveHint: false,
|
|
4646
|
+
idempotentHint: false,
|
|
4647
|
+
openWorldHint: false
|
|
4648
|
+
},
|
|
4649
|
+
describeTarget: (args) => String(args["to"] ?? ""),
|
|
4650
|
+
async execute(args, ctx) {
|
|
4651
|
+
const start = Date.now();
|
|
4652
|
+
const to = typeof args["to"] === "string" ? args["to"].trim() : "";
|
|
4653
|
+
const text = typeof args["text"] === "string" ? args["text"].trim() : "";
|
|
4654
|
+
if (!to) {
|
|
4655
|
+
return {
|
|
4656
|
+
success: false,
|
|
4657
|
+
output: "",
|
|
4658
|
+
error: {
|
|
4659
|
+
code: 7101,
|
|
4660
|
+
message: "\u7F3A\u5C11\u6536\u4EF6\u4EBA\uFF08to\uFF09",
|
|
4661
|
+
suggestion: `\u586B\u4E00\u4E2A\u6210\u5458 id\uFF0C\u6216 \`${LEAD_AGENT_ID}\``
|
|
4662
|
+
},
|
|
4663
|
+
duration: Date.now() - start
|
|
4664
|
+
};
|
|
4665
|
+
}
|
|
4666
|
+
if (!text) {
|
|
4667
|
+
return {
|
|
4668
|
+
success: false,
|
|
4669
|
+
output: "",
|
|
4670
|
+
error: { code: 7102, message: "\u6D88\u606F\u5185\u5BB9\uFF08text\uFF09\u662F\u7A7A\u7684" },
|
|
4671
|
+
duration: Date.now() - start
|
|
4672
|
+
};
|
|
4673
|
+
}
|
|
4674
|
+
const memberInfo = team.bySession(ctx.sessionId);
|
|
4675
|
+
const target = team.get(to);
|
|
4676
|
+
const ownMember = target !== void 0 && target.parentSessionId === ctx.sessionId;
|
|
4677
|
+
const from = memberInfo ? memberInfo.agentId : ownMember ? LEAD_AGENT_ID : ctx.sessionId;
|
|
4678
|
+
const result = team.deliver(TeamRegistry.message({ from, to, text }));
|
|
4679
|
+
if (!result.ok) {
|
|
4680
|
+
return {
|
|
4681
|
+
success: false,
|
|
4682
|
+
output: "",
|
|
4683
|
+
error: { code: 7103, message: result.reason },
|
|
4684
|
+
duration: Date.now() - start
|
|
4685
|
+
};
|
|
4686
|
+
}
|
|
4687
|
+
return {
|
|
4688
|
+
success: true,
|
|
4689
|
+
output: result.to === LEAD_AGENT_ID ? `\u5DF2\u9001\u5230 lead\uFF0C\u5B83\u4E0B\u4E00\u8F6E\u5F00\u5934\u4F1A\u770B\u5230\u3002` : `\u5DF2\u9001\u5230 ${result.to}\uFF08${result.status}\uFF09\uFF0C\u5B83\u4E0B\u4E00\u8F6E\u5F00\u5934\u4F1A\u770B\u5230\u3002`,
|
|
4690
|
+
duration: Date.now() - start
|
|
4691
|
+
};
|
|
4692
|
+
}
|
|
4693
|
+
};
|
|
4694
|
+
}
|
|
4695
|
+
function err(code, message, suggestion) {
|
|
4696
|
+
return {
|
|
4697
|
+
success: false,
|
|
4698
|
+
output: "",
|
|
4699
|
+
error: { code, message, ...{} },
|
|
4700
|
+
duration: 0
|
|
4701
|
+
};
|
|
4702
|
+
}
|
|
4703
|
+
function ok2(output) {
|
|
4704
|
+
return { success: true, output, duration: 0 };
|
|
4705
|
+
}
|
|
4706
|
+
function str2(args, key) {
|
|
4707
|
+
const v = args[key];
|
|
4708
|
+
return typeof v === "string" ? v.trim() : "";
|
|
4709
|
+
}
|
|
4710
|
+
function parseTarget(raw) {
|
|
4711
|
+
const t83 = raw.trim();
|
|
4712
|
+
if (!t83) return null;
|
|
4713
|
+
return t83.startsWith("th-") ? { kind: "thread", id: t83 } : { kind: "channel", name: t83 };
|
|
4714
|
+
}
|
|
4715
|
+
function authorOf(deps, ctx) {
|
|
4716
|
+
return deps.agentOf(ctx.sessionId) ?? LEAD_AGENT_ID;
|
|
4717
|
+
}
|
|
4718
|
+
function renderPost(p) {
|
|
4719
|
+
const who = p.author;
|
|
4720
|
+
const when = new Date(p.createdAt).toISOString().slice(0, 16).replace("T", " ");
|
|
4721
|
+
const body2 = p.text.length > 2e3 ? `${p.text.slice(0, 2e3)}\u2026` : p.text;
|
|
4722
|
+
return `#${p.seq} [${p.id}] ${who} \xB7 ${when}
|
|
4723
|
+
${body2}`;
|
|
4724
|
+
}
|
|
4725
|
+
function renderThread(t83) {
|
|
4726
|
+
return `- ${t83.id} ${t83.title} (${t83.postCount} \u5E16\uFF0C\u6700\u540E ${new Date(t83.lastPostAt).toISOString().slice(0, 16).replace("T", " ")})`;
|
|
4727
|
+
}
|
|
4728
|
+
function createBoardTools(store, deps) {
|
|
4729
|
+
const targetParam = {
|
|
4730
|
+
type: "string",
|
|
4731
|
+
description: "\u9891\u9053\u540D\uFF08\u5F00\u65B0\u7EBF\u7A0B\uFF09\uFF0C\u6216 `th-xxxxxxxx` \u8FD9\u6837\u7684\u7EBF\u7A0B id\uFF08\u56DE\u590D\u8FDB\u53BB\uFF09"
|
|
4732
|
+
};
|
|
4733
|
+
const tools = [
|
|
4734
|
+
{
|
|
4735
|
+
name: "get_channels",
|
|
4736
|
+
description: "\u5217\u51FA\u8BA8\u8BBA\u677F\u4E0A\u7684\u9891\u9053\u3002**\u8FD9\u5757\u677F\u662F\u8DE8\u8FDB\u7A0B\u5171\u4EAB\u7684** \u2014\u2014 \u4F60\u53E6\u4E00\u4E2A\u7A97\u53E3\u5EFA\u7684\u9891\u9053\u8FD9\u91CC\u4E5F\u770B\u5F97\u5230\u3002",
|
|
4737
|
+
parameters: { type: "object", properties: {}, required: [] },
|
|
4738
|
+
exposure: ToolExposure.Direct,
|
|
4739
|
+
supportsParallel: true,
|
|
4740
|
+
operation: "file_read",
|
|
4741
|
+
annotations: {
|
|
4742
|
+
readOnlyHint: true,
|
|
4743
|
+
destructiveHint: false,
|
|
4744
|
+
idempotentHint: true,
|
|
4745
|
+
openWorldHint: false
|
|
4746
|
+
},
|
|
4747
|
+
describeTarget: () => "\u9891\u9053\u5217\u8868",
|
|
4748
|
+
async execute() {
|
|
4749
|
+
const channels = store.listChannels();
|
|
4750
|
+
if (channels.length === 0) return ok2("\u8FD8\u6CA1\u6709\u9891\u9053\u3002\u7528 create_channel \u5EFA\u4E00\u4E2A\u3002");
|
|
4751
|
+
return ok2(
|
|
4752
|
+
channels.map((c) => `- ${c.name}${c.description ? `\uFF1A${c.description}` : ""}`).join("\n")
|
|
4753
|
+
);
|
|
4754
|
+
}
|
|
4755
|
+
},
|
|
4756
|
+
{
|
|
4757
|
+
name: "create_channel",
|
|
4758
|
+
description: "\u5EFA\u4E00\u4E2A\u9891\u9053\u3002\u5DF2\u5B58\u5728\u7684\u8BDD\u539F\u6837\u8FD4\u56DE\u5B83\uFF08\u4E0D\u62A5\u9519\u3001\u4E0D\u6539\u63CF\u8FF0\uFF09\u3002",
|
|
4759
|
+
parameters: {
|
|
4760
|
+
type: "object",
|
|
4761
|
+
properties: {
|
|
4762
|
+
name: { type: "string", description: "\u9891\u9053\u540D\uFF0C\u5B57\u6BCD\u6570\u5B57 _ . -" },
|
|
4763
|
+
description: { type: "string", description: "\u8FD9\u4E2A\u9891\u9053\u662F\u5E72\u4EC0\u4E48\u7684" }
|
|
4764
|
+
},
|
|
4765
|
+
required: ["name"]
|
|
4766
|
+
},
|
|
4767
|
+
exposure: ToolExposure.Deferred,
|
|
4768
|
+
supportsParallel: false,
|
|
4769
|
+
operation: "file_read",
|
|
4770
|
+
annotations: {
|
|
4771
|
+
readOnlyHint: false,
|
|
4772
|
+
destructiveHint: false,
|
|
4773
|
+
idempotentHint: true,
|
|
4774
|
+
openWorldHint: false
|
|
4775
|
+
},
|
|
4776
|
+
describeTarget: (args) => String(args["name"] ?? ""),
|
|
4777
|
+
async execute(args, ctx) {
|
|
4778
|
+
const name = str2(args, "name");
|
|
4779
|
+
if (!name) return err(7401, "\u7F3A\u5C11 name");
|
|
4780
|
+
try {
|
|
4781
|
+
const description = str2(args, "description");
|
|
4782
|
+
const ch = store.createChannel({
|
|
4783
|
+
name,
|
|
4784
|
+
...description ? { description } : {},
|
|
4785
|
+
by: authorOf(deps, ctx)
|
|
4786
|
+
});
|
|
4787
|
+
return ok2(`\u9891\u9053 ${ch.name} \u5C31\u7EEA${ch.description ? `\uFF1A${ch.description}` : ""}`);
|
|
4788
|
+
} catch (cause) {
|
|
4789
|
+
return err(7402, cause instanceof Error ? cause.message : String(cause));
|
|
4790
|
+
}
|
|
4791
|
+
}
|
|
4792
|
+
},
|
|
4793
|
+
{
|
|
4794
|
+
name: "upsert_channel",
|
|
4795
|
+
description: "\u6539\u4E00\u4E2A\u9891\u9053\u7684\u63CF\u8FF0\uFF08\u5E16\u5B50\u3001\u8BA2\u9605\u90FD\u4E0D\u52A8\uFF09\u3002\u4E0D\u5B58\u5728\u5C31\u5EFA\u51FA\u6765\u3002",
|
|
4796
|
+
parameters: {
|
|
4797
|
+
type: "object",
|
|
4798
|
+
properties: {
|
|
4799
|
+
name: { type: "string", description: "\u9891\u9053\u540D" },
|
|
4800
|
+
description: { type: "string", description: "\u65B0\u7684\u63CF\u8FF0" }
|
|
4801
|
+
},
|
|
4802
|
+
required: ["name", "description"]
|
|
4803
|
+
},
|
|
4804
|
+
exposure: ToolExposure.Deferred,
|
|
4805
|
+
supportsParallel: false,
|
|
4806
|
+
operation: "file_read",
|
|
4807
|
+
annotations: {
|
|
4808
|
+
readOnlyHint: false,
|
|
4809
|
+
destructiveHint: false,
|
|
4810
|
+
idempotentHint: true,
|
|
4811
|
+
openWorldHint: false
|
|
4812
|
+
},
|
|
4813
|
+
describeTarget: (args) => String(args["name"] ?? ""),
|
|
4814
|
+
async execute(args, ctx) {
|
|
4815
|
+
const name = str2(args, "name");
|
|
4816
|
+
const description = str2(args, "description");
|
|
4817
|
+
if (!name) return err(7403, "\u7F3A\u5C11 name");
|
|
4818
|
+
if (!description) return err(7404, "\u7F3A\u5C11 description");
|
|
4819
|
+
try {
|
|
4820
|
+
store.upsertChannel({ name, description, by: authorOf(deps, ctx) });
|
|
4821
|
+
return ok2(`\u9891\u9053 ${name} \u7684\u63CF\u8FF0\u5DF2\u66F4\u65B0\u3002`);
|
|
4822
|
+
} catch (cause) {
|
|
4823
|
+
return err(7405, cause instanceof Error ? cause.message : String(cause));
|
|
4824
|
+
}
|
|
4825
|
+
}
|
|
4826
|
+
},
|
|
4827
|
+
{
|
|
4828
|
+
name: "list_threads",
|
|
4829
|
+
description: "\u5217\u51FA\u67D0\u4E2A\u9891\u9053\u91CC\u7684\u7EBF\u7A0B\uFF0C\u6309\u6700\u540E\u6D3B\u52A8\u6392\u5E8F\u3002",
|
|
4830
|
+
parameters: {
|
|
4831
|
+
type: "object",
|
|
4832
|
+
properties: {
|
|
4833
|
+
channel: { type: "string", description: "\u9891\u9053\u540D" },
|
|
4834
|
+
limit: { type: "number", description: "\u6700\u591A\u51E0\u6761\uFF0C\u9ED8\u8BA4 20" }
|
|
4835
|
+
},
|
|
4836
|
+
required: ["channel"]
|
|
4837
|
+
},
|
|
4838
|
+
exposure: ToolExposure.Deferred,
|
|
4839
|
+
supportsParallel: true,
|
|
4840
|
+
operation: "file_read",
|
|
4841
|
+
annotations: {
|
|
4842
|
+
readOnlyHint: true,
|
|
4843
|
+
destructiveHint: false,
|
|
4844
|
+
idempotentHint: true,
|
|
4845
|
+
openWorldHint: false
|
|
4846
|
+
},
|
|
4847
|
+
describeTarget: (args) => String(args["channel"] ?? ""),
|
|
4848
|
+
async execute(args) {
|
|
4849
|
+
const channel = str2(args, "channel");
|
|
4850
|
+
if (!channel) return err(7406, "\u7F3A\u5C11 channel");
|
|
4851
|
+
if (!store.channel(channel)) return err(7407, `\u6CA1\u6709\u8FD9\u4E2A\u9891\u9053\uFF1A${channel}`);
|
|
4852
|
+
const limit = typeof args["limit"] === "number" ? Math.min(Math.max(1, args["limit"]), 200) : 20;
|
|
4853
|
+
const threads = store.listThreads(channel, limit);
|
|
4854
|
+
if (threads.length === 0) return ok2(`\u9891\u9053 ${channel} \u91CC\u8FD8\u6CA1\u6709\u7EBF\u7A0B\u3002`);
|
|
4855
|
+
return ok2(threads.map(renderThread).join("\n"));
|
|
4856
|
+
}
|
|
4857
|
+
},
|
|
4858
|
+
{
|
|
4859
|
+
name: "read_thread",
|
|
4860
|
+
description: "\u8BFB\u4E00\u4E2A\u7EBF\u7A0B\u91CC\u7684\u5E16\u5B50\uFF08\u6309\u65F6\u95F4\u6B63\u5E8F\uFF09\u3002**\u8BFB\u5B8C\u4F1A\u7528 markRead \u628A\u8BA2\u9605\u6E38\u6807\u63A8\u5230\u73B0\u5728** \u2014\u2014 \u4E0B\u6B21\u5C31\u4E0D\u4F1A\u518D\u62A5\u8FD9\u4E9B\u3002",
|
|
4861
|
+
parameters: {
|
|
4862
|
+
type: "object",
|
|
4863
|
+
properties: {
|
|
4864
|
+
threadId: { type: "string", description: "\u7EBF\u7A0B id\uFF08th- \u5F00\u5934\uFF09" },
|
|
4865
|
+
limit: { type: "number", description: "\u6700\u591A\u51E0\u6761\uFF0C\u9ED8\u8BA4 50" }
|
|
4866
|
+
},
|
|
4867
|
+
required: ["threadId"]
|
|
4868
|
+
},
|
|
4869
|
+
exposure: ToolExposure.Direct,
|
|
4870
|
+
supportsParallel: true,
|
|
4871
|
+
operation: "file_read",
|
|
4872
|
+
annotations: {
|
|
4873
|
+
readOnlyHint: false,
|
|
4874
|
+
destructiveHint: false,
|
|
4875
|
+
idempotentHint: false,
|
|
4876
|
+
openWorldHint: false
|
|
4877
|
+
},
|
|
4878
|
+
describeTarget: (args) => String(args["threadId"] ?? ""),
|
|
4879
|
+
async execute(args, ctx) {
|
|
4880
|
+
const threadId = str2(args, "threadId");
|
|
4881
|
+
if (!threadId) return err(7408, "\u7F3A\u5C11 threadId");
|
|
4882
|
+
const limit = typeof args["limit"] === "number" ? Math.min(Math.max(1, args["limit"]), 500) : 50;
|
|
4883
|
+
const posts = store.readThread(threadId, limit);
|
|
4884
|
+
if (posts.length === 0) {
|
|
4885
|
+
return ok2(`\u7EBF\u7A0B ${threadId} \u91CC\u6CA1\u6709\u5E16\u5B50\uFF08\u6216\u8005\u8FD9\u4E2A\u7EBF\u7A0B\u4E0D\u5B58\u5728\uFF09\u3002`);
|
|
4886
|
+
}
|
|
4887
|
+
store.markRead(authorOf(deps, ctx), { kind: "thread", id: threadId });
|
|
4888
|
+
return ok2(posts.map(renderPost).join("\n\n"));
|
|
4889
|
+
}
|
|
4890
|
+
},
|
|
4891
|
+
{
|
|
4892
|
+
name: "read_post",
|
|
4893
|
+
description: "\u8BFB\u4E00\u6761\u5E16\u5B50\u7684\u5168\u6587\uFF08`read_thread` \u4F1A\u622A\u65AD\u957F\u5E16\uFF09\u3002",
|
|
4894
|
+
parameters: {
|
|
4895
|
+
type: "object",
|
|
4896
|
+
properties: { postId: { type: "string", description: "\u5E16\u5B50 id\uFF08po- \u5F00\u5934\uFF09" } },
|
|
4897
|
+
required: ["postId"]
|
|
4898
|
+
},
|
|
4899
|
+
exposure: ToolExposure.Deferred,
|
|
4900
|
+
supportsParallel: true,
|
|
4901
|
+
operation: "file_read",
|
|
4902
|
+
annotations: {
|
|
4903
|
+
readOnlyHint: true,
|
|
4904
|
+
destructiveHint: false,
|
|
4905
|
+
idempotentHint: true,
|
|
4906
|
+
openWorldHint: false
|
|
4907
|
+
},
|
|
4908
|
+
describeTarget: (args) => String(args["postId"] ?? ""),
|
|
4909
|
+
async execute(args) {
|
|
4910
|
+
const id = str2(args, "postId");
|
|
4911
|
+
const p = store.readPost(id);
|
|
4912
|
+
if (!p) return err(7409, `\u6CA1\u6709\u8FD9\u6761\u5E16\u5B50\uFF1A${id}`);
|
|
4913
|
+
return ok2(renderPost(p));
|
|
4914
|
+
}
|
|
4915
|
+
},
|
|
4916
|
+
{
|
|
4917
|
+
name: "search_posts",
|
|
4918
|
+
description: "\u5728\u677F\u5B50\u7684\u5E16\u5B50\u91CC\u5168\u6587\u641C\u7D22\uFF08\u5B50\u4E32\u5339\u914D\uFF09\u3002\u53EF\u4EE5\u9650\u5B9A\u9891\u9053\u3002",
|
|
4919
|
+
parameters: {
|
|
4920
|
+
type: "object",
|
|
4921
|
+
properties: {
|
|
4922
|
+
query: { type: "string", description: "\u8981\u627E\u7684\u8BCD" },
|
|
4923
|
+
channel: { type: "string", description: "\u53EA\u5728\u8FD9\u4E2A\u9891\u9053\u91CC\u627E" },
|
|
4924
|
+
limit: { type: "number", description: "\u6700\u591A\u51E0\u6761\uFF0C\u9ED8\u8BA4 20" }
|
|
4925
|
+
},
|
|
4926
|
+
required: ["query"]
|
|
4927
|
+
},
|
|
4928
|
+
exposure: ToolExposure.Deferred,
|
|
4929
|
+
supportsParallel: true,
|
|
4930
|
+
operation: "file_read",
|
|
4931
|
+
annotations: {
|
|
4932
|
+
readOnlyHint: true,
|
|
4933
|
+
destructiveHint: false,
|
|
4934
|
+
idempotentHint: true,
|
|
4935
|
+
openWorldHint: false
|
|
4936
|
+
},
|
|
4937
|
+
describeTarget: (args) => String(args["query"] ?? ""),
|
|
4938
|
+
async execute(args) {
|
|
4939
|
+
const query = str2(args, "query");
|
|
4940
|
+
if (!query) return err(7410, "\u7F3A\u5C11 query");
|
|
4941
|
+
const channel = str2(args, "channel");
|
|
4942
|
+
const limit = typeof args["limit"] === "number" ? Math.min(Math.max(1, args["limit"]), 100) : 20;
|
|
4943
|
+
const posts = store.searchPosts(query, channel || void 0, limit);
|
|
4944
|
+
if (posts.length === 0) return ok2(`\u6CA1\u6709\u627E\u5230\u5305\u542B\u300C${query}\u300D\u7684\u5E16\u5B50\u3002`);
|
|
4945
|
+
return ok2(posts.map(renderPost).join("\n\n"));
|
|
4946
|
+
}
|
|
4947
|
+
},
|
|
4948
|
+
{
|
|
4949
|
+
name: "post",
|
|
4950
|
+
description: [
|
|
4951
|
+
"\u53D1\u4E00\u6761\u5E16\u5B50\u3002target \u662F\u9891\u9053\u540D\u5C31**\u5F00\u4E00\u4E2A\u65B0\u7EBF\u7A0B**\uFF0C\u662F th- \u5F00\u5934\u7684\u7EBF\u7A0B id \u5C31\u56DE\u590D\u8FDB\u53BB\u3002",
|
|
4952
|
+
"**\u4F1A\u81EA\u52A8\u8BA2\u9605\u4F60\u90A3\u6761**\uFF08\u6240\u4EE5\u4E4B\u540E\u522B\u4EBA\u7684\u56DE\u590D\u4F60\u4F1A\u6536\u5230\u63D0\u9192\uFF09\u3002",
|
|
4953
|
+
"\u60F3\u9759\u9ED8\u8BB0\u4E2A\u6D41\u6C34\uFF08\u4E0D\u901A\u77E5\u4EFB\u4F55\u4EBA\uFF09\u7528 append\u3002"
|
|
4954
|
+
].join("\n"),
|
|
4955
|
+
parameters: {
|
|
4956
|
+
type: "object",
|
|
4957
|
+
properties: { target: targetParam, text: { type: "string", description: "\u5E16\u5B50\u6B63\u6587" } },
|
|
4958
|
+
required: ["target", "text"]
|
|
4959
|
+
},
|
|
4960
|
+
exposure: ToolExposure.Deferred,
|
|
4961
|
+
supportsParallel: false,
|
|
4962
|
+
operation: "file_read",
|
|
4963
|
+
annotations: {
|
|
4964
|
+
readOnlyHint: false,
|
|
4965
|
+
destructiveHint: false,
|
|
4966
|
+
idempotentHint: false,
|
|
4967
|
+
openWorldHint: false
|
|
4968
|
+
},
|
|
4969
|
+
describeTarget: (args) => String(args["target"] ?? ""),
|
|
4970
|
+
async execute(args, ctx) {
|
|
4971
|
+
const target = parseTarget(str2(args, "target"));
|
|
4972
|
+
const text = str2(args, "text");
|
|
4973
|
+
if (!target) return err(7411, "\u7F3A\u5C11 target");
|
|
4974
|
+
if (!text) return err(7412, "\u7F3A\u5C11 text");
|
|
4975
|
+
try {
|
|
4976
|
+
const r = store.post({ target, author: authorOf(deps, ctx), text });
|
|
4977
|
+
return ok2(`\u5DF2\u53D1\u5E16 ${r.post.id}\uFF08\u7EBF\u7A0B ${r.threadId}\uFF0C#${r.post.seq}\uFF09\u3002`);
|
|
4978
|
+
} catch (cause) {
|
|
4979
|
+
return err(7413, cause instanceof Error ? cause.message : String(cause));
|
|
4980
|
+
}
|
|
4981
|
+
}
|
|
4982
|
+
},
|
|
4983
|
+
{
|
|
4984
|
+
name: "append",
|
|
4985
|
+
description: [
|
|
4986
|
+
"**\u9759\u9ED8**\u8FFD\u52A0\u4E00\u6761\u5E16\u5B50\uFF1A\u4E0D\u4E3A\u4F5C\u8005\u5EFA\u8BA2\u9605\u3001\u4E5F\u4E0D\u63A8\u9001\u4EFB\u4F55\u901A\u77E5\u3002",
|
|
4987
|
+
"\u8D34\u8BC1\u636E\u3001\u8BB0\u6D41\u6C34\u7528\u5B83\u3002**\u8981\u5728\u8BA8\u8BBA\u91CC\u8BF4\u4E00\u53E5\u8BDD\u8BA9\u8BA2\u9605\u7684\u4EBA\u77E5\u9053\uFF0C\u7528 post\u3002**",
|
|
4988
|
+
"\u6CE8\u610F\uFF1A\u5DF2\u7ECF\u4E3B\u52A8 subscribe \u8FC7\u8FD9\u4E2A\u7EBF\u7A0B\u7684\u4EBA\u62C9\u53D6\u65F6**\u4ECD\u7136\u770B\u5F97\u5230**\u5B83 \u2014\u2014 \u8BA2\u9605\u5173\u7CFB\u662F\u8BFB\u8005\u81EA\u5DF1\u5B9A\u7684\uFF0C\u4E0D\u53D7\u53D1\u5E16\u5DE5\u5177\u5F71\u54CD\u3002"
|
|
4989
|
+
].join("\n"),
|
|
4990
|
+
parameters: {
|
|
4991
|
+
type: "object",
|
|
4992
|
+
properties: { target: targetParam, text: { type: "string", description: "\u6B63\u6587" } },
|
|
4993
|
+
required: ["target", "text"]
|
|
4994
|
+
},
|
|
4995
|
+
exposure: ToolExposure.Deferred,
|
|
4996
|
+
supportsParallel: false,
|
|
4997
|
+
operation: "file_read",
|
|
4998
|
+
annotations: {
|
|
4999
|
+
readOnlyHint: false,
|
|
5000
|
+
destructiveHint: false,
|
|
5001
|
+
idempotentHint: false,
|
|
5002
|
+
openWorldHint: false
|
|
5003
|
+
},
|
|
5004
|
+
describeTarget: (args) => String(args["target"] ?? ""),
|
|
5005
|
+
async execute(args, ctx) {
|
|
5006
|
+
const target = parseTarget(str2(args, "target"));
|
|
5007
|
+
const text = str2(args, "text");
|
|
5008
|
+
if (!target) return err(7414, "\u7F3A\u5C11 target");
|
|
5009
|
+
if (!text) return err(7415, "\u7F3A\u5C11 text");
|
|
5010
|
+
try {
|
|
5011
|
+
const r = store.append({ target, author: authorOf(deps, ctx), text });
|
|
5012
|
+
return ok2(`\u5DF2\u8FFD\u52A0 ${r.post.id}\uFF08\u7EBF\u7A0B ${r.threadId}\uFF0C#${r.post.seq}\uFF09\u3002\u6CA1\u6709\u901A\u77E5\u4EFB\u4F55\u4EBA\u3002`);
|
|
5013
|
+
} catch (cause) {
|
|
5014
|
+
return err(7416, cause instanceof Error ? cause.message : String(cause));
|
|
5015
|
+
}
|
|
5016
|
+
}
|
|
5017
|
+
},
|
|
5018
|
+
{
|
|
5019
|
+
name: "subscribe",
|
|
5020
|
+
description: "\u8BA2\u9605\u4E00\u4E2A\u9891\u9053\u6216\u7EBF\u7A0B\u3002\u4E4B\u540E\u5B83\u6709\u4E86\u65B0\u5E16\uFF0C\u4F60\u4E0B\u4E00\u8F6E\u5F00\u5934\u4F1A\u6536\u5230\u4E00\u6761\u63D0\u9192\uFF08**\u4E0D\u4F1A\u5524\u9192\u4F60**\uFF09\u3002",
|
|
5021
|
+
parameters: {
|
|
5022
|
+
type: "object",
|
|
5023
|
+
properties: { target: { ...targetParam, description: "\u9891\u9053\u540D\u6216\u7EBF\u7A0B id" } },
|
|
5024
|
+
required: ["target"]
|
|
5025
|
+
},
|
|
5026
|
+
exposure: ToolExposure.Deferred,
|
|
5027
|
+
supportsParallel: false,
|
|
5028
|
+
operation: "file_read",
|
|
5029
|
+
annotations: {
|
|
5030
|
+
readOnlyHint: false,
|
|
5031
|
+
destructiveHint: false,
|
|
5032
|
+
idempotentHint: true,
|
|
5033
|
+
openWorldHint: false
|
|
5034
|
+
},
|
|
5035
|
+
describeTarget: (args) => String(args["target"] ?? ""),
|
|
5036
|
+
async execute(args, ctx) {
|
|
5037
|
+
const target = parseTarget(str2(args, "target"));
|
|
5038
|
+
if (!target) return err(7417, "\u7F3A\u5C11 target");
|
|
5039
|
+
store.subscribe(authorOf(deps, ctx), target);
|
|
5040
|
+
return ok2(`\u5DF2\u8BA2\u9605 ${str2(args, "target")}\u3002`);
|
|
5041
|
+
}
|
|
5042
|
+
},
|
|
5043
|
+
{
|
|
5044
|
+
name: "unsubscribe",
|
|
5045
|
+
description: "\u53D6\u6D88\u8BA2\u9605\u3002",
|
|
5046
|
+
parameters: {
|
|
5047
|
+
type: "object",
|
|
5048
|
+
properties: { target: { ...targetParam, description: "\u9891\u9053\u540D\u6216\u7EBF\u7A0B id" } },
|
|
5049
|
+
required: ["target"]
|
|
5050
|
+
},
|
|
5051
|
+
exposure: ToolExposure.Deferred,
|
|
5052
|
+
supportsParallel: false,
|
|
5053
|
+
operation: "file_read",
|
|
5054
|
+
annotations: {
|
|
5055
|
+
readOnlyHint: false,
|
|
5056
|
+
destructiveHint: false,
|
|
5057
|
+
idempotentHint: true,
|
|
5058
|
+
openWorldHint: false
|
|
5059
|
+
},
|
|
5060
|
+
describeTarget: (args) => String(args["target"] ?? ""),
|
|
5061
|
+
async execute(args, ctx) {
|
|
5062
|
+
const target = parseTarget(str2(args, "target"));
|
|
5063
|
+
if (!target) return err(7418, "\u7F3A\u5C11 target");
|
|
5064
|
+
const removed = store.unsubscribe(authorOf(deps, ctx), target);
|
|
5065
|
+
return ok2(
|
|
5066
|
+
removed ? `\u5DF2\u53D6\u6D88\u8BA2\u9605 ${str2(args, "target")}\u3002` : `\u672C\u6765\u5C31\u6CA1\u8BA2\u9605 ${str2(args, "target")}\u3002`
|
|
5067
|
+
);
|
|
5068
|
+
}
|
|
5069
|
+
}
|
|
5070
|
+
];
|
|
5071
|
+
return tools;
|
|
5072
|
+
}
|
|
5073
|
+
var BOARD_TOOL_NAMES = Object.freeze([
|
|
5074
|
+
"create_channel",
|
|
5075
|
+
"upsert_channel",
|
|
5076
|
+
"get_channels",
|
|
5077
|
+
"list_threads",
|
|
5078
|
+
"search_posts",
|
|
5079
|
+
"read_thread",
|
|
5080
|
+
"read_post",
|
|
5081
|
+
"subscribe",
|
|
5082
|
+
"unsubscribe",
|
|
5083
|
+
"post",
|
|
5084
|
+
"append"
|
|
5085
|
+
]);
|
|
5086
|
+
var TASK_STATUSES = ["pending", "in_progress", "done", "blocked"];
|
|
5087
|
+
var AGENT_ID_PATTERN = /^[A-Za-z0-9_-]{1,64}$/;
|
|
5088
|
+
function err2(code, message, suggestion) {
|
|
5089
|
+
return {
|
|
5090
|
+
success: false,
|
|
5091
|
+
output: "",
|
|
5092
|
+
error: { code, message, ...suggestion ? { suggestion } : {} },
|
|
5093
|
+
duration: 0
|
|
5094
|
+
};
|
|
5095
|
+
}
|
|
5096
|
+
function ok3(output, start = Date.now()) {
|
|
5097
|
+
return { success: true, output, duration: Date.now() - start };
|
|
5098
|
+
}
|
|
5099
|
+
function str3(args, key) {
|
|
5100
|
+
const v = args[key];
|
|
5101
|
+
return typeof v === "string" ? v.trim() : "";
|
|
5102
|
+
}
|
|
5103
|
+
function spawnTeammate(team, manager) {
|
|
5104
|
+
return {
|
|
5105
|
+
name: "spawn_teammate",
|
|
5106
|
+
description: [
|
|
5107
|
+
"\u6D3E\u4E00\u4E2A**\u5177\u540D**\u7684\u6210\u5458\u5230\u540E\u53F0\u53BB\u5E72\u4E00\u4EF6\u6D3B\u3002\u5B83\u8DD1\u7740\u7684\u65F6\u5019\u4F60\u80FD\u7528 send_message \u8DDF\u5B83\u8BF4\u8BDD\u3002",
|
|
5108
|
+
"\u548C delegate_task \u7684\u533A\u522B\uFF1Adelegate_task \u662F\u4E00\u6B21\u6027\u7684\uFF08\u6D3E\u5B8C\u7B49\u7ED3\u8BBA\uFF0C\u4E2D\u9014\u8BF4\u4E0D\u4E0A\u8BDD\uFF09\uFF1B",
|
|
5109
|
+
"\u8FD9\u4E2A\u6D3E\u51FA\u53BB\u7684\u6210\u5458\u6709\u540D\u5B57\u3001\u5728\u540E\u53F0\u8DD1\u3001**\u4E2D\u9014\u6536\u5F97\u5230\u4F60\u7684\u6D88\u606F**\uFF0C\u4E5F\u80FD\u88AB interrupt_agent \u6253\u65AD\u3002",
|
|
5110
|
+
"\u7528 list_agents \u770B\u73B0\u5728\u6709\u8C01\u3001\u5404\u81EA\u5728\u5E72\u4EC0\u4E48\uFF1Bteam_task_* \u90A3\u56DB\u4E2A\u5DE5\u5177\u7ED9\u5B83\u4EEC\u5206\u6D3B\u3002"
|
|
5111
|
+
].join("\n"),
|
|
5112
|
+
parameters: {
|
|
5113
|
+
type: "object",
|
|
5114
|
+
properties: {
|
|
5115
|
+
agentId: {
|
|
5116
|
+
type: "string",
|
|
5117
|
+
description: "\u6210\u5458\u540D\uFF0C\u5B57\u6BCD\u6570\u5B57\u4E0B\u5212\u7EBF\u8FDE\u5B57\u7B26\u3002**\u4E0D\u80FD\u91CD\u540D**\uFF0C\u4E4B\u540E send_message \u7528\u5B83\u5BFB\u5740"
|
|
5118
|
+
},
|
|
5119
|
+
goal: { type: "string", description: "\u8981\u5B83\u5B8C\u6210\u4EC0\u4E48\uFF0C\u5199\u5177\u4F53" },
|
|
5120
|
+
context: {
|
|
5121
|
+
type: "string",
|
|
5122
|
+
description: "\u5B8C\u6210\u8FD9\u4E2A\u4EFB\u52A1\u9700\u8981\u77E5\u9053\u7684\u80CC\u666F\uFF08\u5B83\u770B\u4E0D\u5230\u5F53\u524D\u5BF9\u8BDD\uFF09"
|
|
5123
|
+
}
|
|
5124
|
+
},
|
|
5125
|
+
required: ["agentId", "goal"]
|
|
5126
|
+
},
|
|
5127
|
+
exposure: ToolExposure.Deferred,
|
|
5128
|
+
supportsParallel: false,
|
|
5129
|
+
operation: "command",
|
|
5130
|
+
annotations: {
|
|
5131
|
+
readOnlyHint: false,
|
|
5132
|
+
destructiveHint: true,
|
|
5133
|
+
idempotentHint: false,
|
|
5134
|
+
openWorldHint: true
|
|
5135
|
+
},
|
|
5136
|
+
describeTarget: (args) => `${String(args["agentId"] ?? "")}: ${String(args["goal"] ?? "")}`,
|
|
5137
|
+
async execute(args, ctx) {
|
|
5138
|
+
const start = Date.now();
|
|
5139
|
+
const agentId = str3(args, "agentId");
|
|
5140
|
+
const goal = str3(args, "goal");
|
|
5141
|
+
const context = str3(args, "context");
|
|
5142
|
+
if (!AGENT_ID_PATTERN.test(agentId)) {
|
|
5143
|
+
return err2(
|
|
5144
|
+
7201,
|
|
5145
|
+
`\u6210\u5458\u540D\u4E0D\u5408\u6CD5\uFF1A${agentId || "(\u7A7A)"}`,
|
|
5146
|
+
"\u53EA\u8BB8\u5B57\u6BCD\u3001\u6570\u5B57\u3001\u4E0B\u5212\u7EBF\u3001\u8FDE\u5B57\u7B26\uFF0C\u6700\u957F 64"
|
|
5147
|
+
);
|
|
5148
|
+
}
|
|
5149
|
+
if (!goal) return err2(7202, "\u7F3A\u5C11 goal");
|
|
5150
|
+
if (team.get(agentId)) {
|
|
5151
|
+
return err2(
|
|
5152
|
+
7203,
|
|
5153
|
+
`\u5DF2\u7ECF\u6709\u4E00\u4E2A\u6210\u5458\u53EB ${agentId} \u4E86`,
|
|
5154
|
+
"\u6362\u4E00\u4E2A\u540D\u5B57\uFF0C\u6216\u8005\u76F4\u63A5 send_message \u7ED9\u5B83"
|
|
5155
|
+
);
|
|
5156
|
+
}
|
|
5157
|
+
const r = await manager.delegate(
|
|
5158
|
+
{
|
|
5159
|
+
tasks: [{ goal, ...context ? { context } : {}, agentId }],
|
|
5160
|
+
background: true,
|
|
5161
|
+
max_concurrent: 1
|
|
5162
|
+
},
|
|
5163
|
+
ctx.sessionId,
|
|
5164
|
+
ctx.signal
|
|
5165
|
+
);
|
|
5166
|
+
if (!r.success) return { ...err2(7204, r.output), duration: Date.now() - start };
|
|
5167
|
+
return ok3(
|
|
5168
|
+
[
|
|
5169
|
+
`\u5DF2\u6D3E\u51FA\u6210\u5458 ${agentId}\uFF08\u540E\u53F0\u4F5C\u4E1A ${r.jobId ?? "(\u65E0)"}\uFF09\u3002`,
|
|
5170
|
+
`\u8DDF\u5B83\u8BF4\u8BDD\uFF1Asend_message({ to: "${agentId}", text: "\u2026" })`,
|
|
5171
|
+
`\u770B\u5B83\u5728\u5E72\u4EC0\u4E48\uFF1Alist_agents\u3002\u6536\u6389\u5B83\uFF1Ainterrupt_agent({ agentId: "${agentId}" })`
|
|
5172
|
+
].join("\n"),
|
|
5173
|
+
start
|
|
5174
|
+
);
|
|
5175
|
+
}
|
|
5176
|
+
};
|
|
5177
|
+
}
|
|
5178
|
+
function listAgents(team) {
|
|
5179
|
+
return {
|
|
5180
|
+
name: "list_agents",
|
|
5181
|
+
description: [
|
|
5182
|
+
"\u5217\u51FA\u56E2\u961F\u6210\u5458\u548C\u5B83\u4EEC\u7684\u72B6\u6001\u3002",
|
|
5183
|
+
"status \u662F running\uFF08\u6B63\u5728\u8DD1\uFF09/ finalized\uFF08\u8DD1\u5B8C\u4E86\uFF09/ failed\uFF08\u6302\u4E86\uFF09\u3002",
|
|
5184
|
+
"running \u7684\u6210\u5458\u80FD\u88AB send_message \u5F53\u8F6E\u6536\u5230\uFF1B\u6536\u5DE5\u7684\u6536\u4E0D\u5230\u3002",
|
|
5185
|
+
"",
|
|
5186
|
+
"\u9ED8\u8BA4\u53EA\u5217\u672C\u4F1A\u8BDD\u6D3E\u51FA\u7684\u6210\u5458\uFF08\u4F60\u81EA\u5DF1\u662F\u6210\u5458\u65F6\uFF1A\u540C\u4E00\u961F\u7684\u5176\u4ED6\u6210\u5458\uFF09\u3002",
|
|
5187
|
+
"\u52A0 --all \u53EF\u4EE5\u770B\u5230\u6240\u6709\u6D3B\u8DC3\u4F1A\u8BDD\u548C\u6210\u5458\u3002"
|
|
5188
|
+
].join("\n"),
|
|
5189
|
+
parameters: {
|
|
5190
|
+
type: "object",
|
|
5191
|
+
properties: {
|
|
5192
|
+
all: {
|
|
5193
|
+
type: "boolean",
|
|
5194
|
+
description: "\u662F\u5426\u5217\u51FA\u6240\u6709\u6D3B\u8DC3\u4F1A\u8BDD\u548C\u6210\u5458\uFF08\u9ED8\u8BA4 false\uFF0C\u53EA\u5217\u672C\u4F1A\u8BDD\u6D3E\u51FA\u7684\uFF09"
|
|
5195
|
+
}
|
|
5196
|
+
},
|
|
5197
|
+
required: []
|
|
5198
|
+
},
|
|
5199
|
+
exposure: ToolExposure.Direct,
|
|
5200
|
+
supportsParallel: true,
|
|
5201
|
+
operation: "file_read",
|
|
5202
|
+
annotations: {
|
|
5203
|
+
readOnlyHint: true,
|
|
5204
|
+
destructiveHint: false,
|
|
5205
|
+
idempotentHint: true,
|
|
5206
|
+
openWorldHint: false
|
|
5207
|
+
},
|
|
5208
|
+
describeTarget: () => "\u56E2\u961F\u6210\u5458",
|
|
5209
|
+
async execute(args, ctx) {
|
|
5210
|
+
const showAll = args["all"] === true;
|
|
5211
|
+
const self = team.bySession(ctx.sessionId);
|
|
5212
|
+
const scopeParent = self?.parentSessionId ?? ctx.sessionId;
|
|
5213
|
+
const members = showAll ? team.list() : team.list().filter((m) => m.parentSessionId === scopeParent);
|
|
5214
|
+
const others = showAll ? team.sessionIds().filter((id) => id !== ctx.sessionId).map((id) => `- ${id} [\u4F1A\u8BDD] running \u2014 \u53E6\u4E00\u6BB5\u4E3B\u4F1A\u8BDD`) : [];
|
|
5215
|
+
if (members.length === 0 && others.length === 0) {
|
|
5216
|
+
return ok3(
|
|
5217
|
+
showAll ? `\u8FD8\u6CA1\u6709\u4EFB\u4F55\u6210\u5458\u6216\u522B\u7684\u4F1A\u8BDD\u3002\u7528 spawn_teammate \u6216 delegate_task \u6D3E\u4E00\u4E2A\u3002` : `\u672C\u4F1A\u8BDD\u8FD8\u6CA1\u6D3E\u51FA\u4EFB\u4F55\u6210\u5458\u3002\u7528 spawn_teammate \u6216 delegate_task \u6D3E\u4E00\u4E2A\uFF0C\u6216\u52A0 --all \u770B\u6240\u6709\u4F1A\u8BDD\u3002`
|
|
5218
|
+
);
|
|
5219
|
+
}
|
|
5220
|
+
const lines = members.map((m) => {
|
|
5221
|
+
const bits = [`- ${m.agentId}`, m.status];
|
|
5222
|
+
if (m.role) bits.push(`[${m.role}]`);
|
|
5223
|
+
if (m.activity) bits.push(`\u2014 ${m.activity}`);
|
|
5224
|
+
return bits.join(" ");
|
|
5225
|
+
});
|
|
5226
|
+
const head = showAll ? `\u4F60\u662F ${ctx.sessionId}\u3002\u6210\u5458 ${members.length} \u4E2A\u3001\u522B\u7684\u4E3B\u4F1A\u8BDD ${others.length} \u4E2A\uFF1A` : `\u672C\u4F1A\u8BDD\u7684\u6210\u5458 ${members.length} \u4E2A\uFF08\u4F60\u662F ${ctx.sessionId}\uFF09\uFF1A`;
|
|
5227
|
+
return ok3([head, ...lines, ...others].join("\n"));
|
|
5228
|
+
}
|
|
5229
|
+
};
|
|
5230
|
+
}
|
|
5231
|
+
function waitAgent(team) {
|
|
5232
|
+
return {
|
|
5233
|
+
name: "wait_agent",
|
|
5234
|
+
description: [
|
|
5235
|
+
"\u7B49\u5230\u56E2\u961F\u91CC\u51FA\u73B0**\u4E0B\u4E00\u6B21\u53D8\u5316**\uFF08\u6709\u4EBA\u88AB\u6D3E\u51FA\u6765\u3001\u6709\u4EBA\u7ED9\u4F60\u53D1\u6D88\u606F\u3001\u4EFB\u52A1\u677F\u53D8\u4E86\uFF09\uFF0C\u6216\u8005\u7B49\u5230\u8D85\u65F6\u3002",
|
|
5236
|
+
"\u53EA\u544A\u8BC9\u4F60\u300C\u6709\u6CA1\u6709\u53D8\u300D\uFF0C**\u4E0D\u544A\u8BC9\u4F60\u53D8\u4E86\u4EC0\u4E48** \u2014\u2014 \u9192\u6765\u4E4B\u540E\u81EA\u5DF1 list_agents / team_task_list \u8BFB\u4E00\u904D\u3002",
|
|
5237
|
+
"\u9002\u5408\uFF1A\u6D3E\u5B8C\u6D3B\u4E4B\u540E\u7B49\u5B83\u4EEC\u5E72\u6D3B\uFF0C\u800C\u4E0D\u662F\u53CD\u590D\u8F6E\u8BE2\u3002"
|
|
5238
|
+
].join("\n"),
|
|
5239
|
+
parameters: {
|
|
5240
|
+
type: "object",
|
|
5241
|
+
properties: {
|
|
5242
|
+
timeoutSec: {
|
|
5243
|
+
type: "number",
|
|
5244
|
+
description: "\u6700\u591A\u7B49\u591A\u4E45\uFF08\u79D2\uFF09\uFF0C1\u20133600\uFF0C\u9ED8\u8BA4 30"
|
|
5245
|
+
}
|
|
5246
|
+
},
|
|
5247
|
+
required: []
|
|
5248
|
+
},
|
|
5249
|
+
exposure: ToolExposure.Deferred,
|
|
5250
|
+
supportsParallel: false,
|
|
5251
|
+
operation: "file_read",
|
|
5252
|
+
annotations: {
|
|
5253
|
+
readOnlyHint: true,
|
|
5254
|
+
destructiveHint: false,
|
|
5255
|
+
idempotentHint: false,
|
|
5256
|
+
openWorldHint: false
|
|
5257
|
+
},
|
|
5258
|
+
describeTarget: () => "\u7B49\u5F85\u56E2\u961F\u53D8\u5316",
|
|
5259
|
+
async execute(args, ctx) {
|
|
5260
|
+
const raw = typeof args["timeoutSec"] === "number" ? args["timeoutSec"] : 30;
|
|
5261
|
+
const sec = Math.min(Math.max(Math.floor(raw), 1), 3600);
|
|
5262
|
+
const changed = await team.waitForChange(sec * 1e3, ctx.signal);
|
|
5263
|
+
if (ctx.signal?.aborted) return err2(7205, "\u7B49\u5F85\u88AB\u4E2D\u6B62\u4E86");
|
|
5264
|
+
return changed ? ok3("\u56E2\u961F\u6709\u53D8\u5316\u3002\u7528 list_agents \u6216 team_task_list \u770B\u73B0\u5728\u662F\u4EC0\u4E48\u60C5\u51B5\u3002") : ok3(`\u7B49\u4E86 ${sec} \u79D2\uFF0C\u6CA1\u6709\u53D8\u5316\u3002`);
|
|
5265
|
+
}
|
|
5266
|
+
};
|
|
5267
|
+
}
|
|
5268
|
+
function interruptAgent(team) {
|
|
5269
|
+
return {
|
|
5270
|
+
name: "interrupt_agent",
|
|
5271
|
+
description: [
|
|
5272
|
+
"\u6253\u65AD\u4E00\u4E2A\u6B63\u5728\u8DD1\u7684\u6210\u5458\uFF08\u5B83\u4F1A\u88AB\u4E2D\u6B62\uFF0C\u5DF2\u7ECF\u4EA7\u751F\u7684\u534A\u622A\u7ED3\u679C\u7559\u7740\uFF09\u3002",
|
|
5273
|
+
"\u6536\u5DE5\u4E86\u7684\u6210\u5458\u6253\u4E0D\u65AD \u2014\u2014 \u90A3\u79CD\u60C5\u51B5\u4F1A\u8FD4\u56DE false\uFF0C\u7528 list_agents \u786E\u8BA4\u3002"
|
|
5274
|
+
].join("\n"),
|
|
5275
|
+
parameters: {
|
|
5276
|
+
type: "object",
|
|
5277
|
+
properties: {
|
|
5278
|
+
agentId: { type: "string", description: "\u8981\u6253\u65AD\u7684\u6210\u5458\u540D" }
|
|
5279
|
+
},
|
|
5280
|
+
required: ["agentId"]
|
|
5281
|
+
},
|
|
5282
|
+
exposure: ToolExposure.Deferred,
|
|
5283
|
+
supportsParallel: false,
|
|
5284
|
+
operation: "command",
|
|
5285
|
+
annotations: {
|
|
5286
|
+
readOnlyHint: false,
|
|
5287
|
+
destructiveHint: true,
|
|
5288
|
+
idempotentHint: false,
|
|
5289
|
+
openWorldHint: false
|
|
5290
|
+
},
|
|
5291
|
+
describeTarget: (args) => String(args["agentId"] ?? ""),
|
|
5292
|
+
async execute(args) {
|
|
5293
|
+
const agentId = str3(args, "agentId");
|
|
5294
|
+
if (!agentId) return err2(7206, "\u7F3A\u5C11 agentId");
|
|
5295
|
+
const member = team.get(agentId);
|
|
5296
|
+
if (!member) return err2(7207, `\u6CA1\u6709\u8FD9\u4E2A\u6210\u5458\uFF1A${agentId}`, "\u7528 list_agents \u770B\u5F53\u524D\u6709\u8C01");
|
|
5297
|
+
if (!team.interrupt(agentId)) {
|
|
5298
|
+
return err2(
|
|
5299
|
+
7208,
|
|
5300
|
+
`${agentId} \u73B0\u5728\u6253\u4E0D\u65AD\uFF08${member.status}\uFF09`,
|
|
5301
|
+
member.status === "running" ? "\u5B83\u53EF\u80FD\u521A\u8DD1\u5B8C\uFF0C\u6216\u8005\u63A7\u5236\u5668\u8FD8\u6CA1\u63A5\u4E0A \u2014\u2014 \u518D list_agents \u770B\u4E00\u773C" : "\u5B83\u5DF2\u7ECF\u6536\u5DE5\u4E86"
|
|
5302
|
+
);
|
|
5303
|
+
}
|
|
5304
|
+
return ok3(`\u5DF2\u6253\u65AD ${agentId}\u3002`);
|
|
5305
|
+
}
|
|
5306
|
+
};
|
|
5307
|
+
}
|
|
5308
|
+
function taskCreate(team) {
|
|
5309
|
+
return {
|
|
5310
|
+
name: "team_task_create",
|
|
5311
|
+
description: [
|
|
5312
|
+
"\u5728\u5171\u4EAB\u4EFB\u52A1\u677F\u4E0A\u5EFA\u4E00\u6761\u4EFB\u52A1\u3002\u5168\u961F\u90FD\u770B\u5F97\u5230\u540C\u4E00\u4EFD\u3002",
|
|
5313
|
+
"dependsOn \u586B\u522B\u7684\u4EFB\u52A1 id\uFF08\u53EA\u80FD\u662F\u5DF2\u7ECF\u5B58\u5728\u7684\uFF09\u3002",
|
|
5314
|
+
"owner \u586B\u67D0\u4E2A\u6210\u5458\u540D\uFF0C\u8868\u793A\u8FD9\u6761\u5F52\u5B83\u3002"
|
|
5315
|
+
].join("\n"),
|
|
5316
|
+
parameters: {
|
|
5317
|
+
type: "object",
|
|
5318
|
+
properties: {
|
|
5319
|
+
title: { type: "string", description: "\u4E00\u53E5\u8BDD\u8BF4\u660E\u8981\u505A\u4EC0\u4E48" },
|
|
5320
|
+
description: { type: "string", description: "\u7EC6\u8282" },
|
|
5321
|
+
owner: { type: "string", description: "\u5F52\u8C01\uFF08\u6210\u5458\u540D\uFF09" },
|
|
5322
|
+
dependsOn: {
|
|
5323
|
+
type: "array",
|
|
5324
|
+
items: { type: "string" },
|
|
5325
|
+
description: "\u4F9D\u8D56\u54EA\u4E9B\u4EFB\u52A1\u7684 id"
|
|
5326
|
+
}
|
|
5327
|
+
},
|
|
5328
|
+
required: ["title"]
|
|
5329
|
+
},
|
|
5330
|
+
exposure: ToolExposure.Deferred,
|
|
5331
|
+
supportsParallel: true,
|
|
5332
|
+
operation: "file_read",
|
|
5333
|
+
annotations: {
|
|
5334
|
+
readOnlyHint: false,
|
|
5335
|
+
destructiveHint: false,
|
|
5336
|
+
idempotentHint: false,
|
|
5337
|
+
openWorldHint: false
|
|
5338
|
+
},
|
|
5339
|
+
describeTarget: (args) => String(args["title"] ?? ""),
|
|
5340
|
+
async execute(args) {
|
|
5341
|
+
const title = str3(args, "title");
|
|
5342
|
+
if (!title) return err2(7301, "\u7F3A\u5C11 title");
|
|
5343
|
+
const dependsOn = Array.isArray(args["dependsOn"]) ? args["dependsOn"].map(String).filter(Boolean) : [];
|
|
5344
|
+
const description = str3(args, "description");
|
|
5345
|
+
const owner = str3(args, "owner");
|
|
5346
|
+
const r = team.tasks.create({
|
|
5347
|
+
title,
|
|
5348
|
+
...description ? { description } : {},
|
|
5349
|
+
...owner ? { owner } : {},
|
|
5350
|
+
...dependsOn.length > 0 ? { dependsOn } : {}
|
|
5351
|
+
});
|
|
5352
|
+
if (!r.ok) return err2(7302, r.reason);
|
|
5353
|
+
return ok3(`\u5DF2\u5EFA\u4EFB\u52A1 ${r.task.id}\uFF08revision ${r.task.revision}\uFF09\uFF1A${r.task.title}`);
|
|
5354
|
+
}
|
|
5355
|
+
};
|
|
5356
|
+
}
|
|
5357
|
+
function taskList(team) {
|
|
5358
|
+
return {
|
|
5359
|
+
name: "team_task_list",
|
|
5360
|
+
description: "\u5217\u51FA\u5171\u4EAB\u4EFB\u52A1\u677F\u4E0A\u7684\u4EFB\u52A1\uFF0C\u53EF\u6309\u72B6\u6001\u6216 owner \u8FC7\u6EE4\u3002",
|
|
5361
|
+
parameters: {
|
|
5362
|
+
type: "object",
|
|
5363
|
+
properties: {
|
|
5364
|
+
status: { type: "string", enum: [...TASK_STATUSES], description: "\u53EA\u770B\u8FD9\u4E2A\u72B6\u6001" },
|
|
5365
|
+
owner: { type: "string", description: "\u53EA\u770B\u5F52\u8FD9\u4E2A\u6210\u5458\u7684" }
|
|
5366
|
+
},
|
|
5367
|
+
required: []
|
|
5368
|
+
},
|
|
5369
|
+
exposure: ToolExposure.Deferred,
|
|
5370
|
+
supportsParallel: true,
|
|
5371
|
+
operation: "file_read",
|
|
5372
|
+
annotations: {
|
|
5373
|
+
readOnlyHint: true,
|
|
5374
|
+
destructiveHint: false,
|
|
5375
|
+
idempotentHint: true,
|
|
5376
|
+
openWorldHint: false
|
|
5377
|
+
},
|
|
5378
|
+
describeTarget: () => "\u56E2\u961F\u4EFB\u52A1\u677F",
|
|
5379
|
+
async execute(args) {
|
|
5380
|
+
const status = str3(args, "status");
|
|
5381
|
+
if (status && !TASK_STATUSES.includes(status)) {
|
|
5382
|
+
return err2(7303, `\u4E0D\u8BA4\u8BC6\u7684\u72B6\u6001\uFF1A${status}`, `\u53EF\u7528\uFF1A${TASK_STATUSES.join(" / ")}`);
|
|
5383
|
+
}
|
|
5384
|
+
const owner = str3(args, "owner");
|
|
5385
|
+
const tasks = team.tasks.list({
|
|
5386
|
+
...status ? { status } : {},
|
|
5387
|
+
...owner ? { owner } : {}
|
|
5388
|
+
});
|
|
5389
|
+
if (tasks.length === 0) return ok3("\u677F\u5B50\u4E0A\u6CA1\u6709\u7B26\u5408\u6761\u4EF6\u7684\u4EFB\u52A1\u3002");
|
|
5390
|
+
const lines = tasks.map((t83) => {
|
|
5391
|
+
const bits = [`- ${t83.id}`, `[${t83.status}]`, t83.title, `rev ${t83.revision}`];
|
|
5392
|
+
if (t83.owner) bits.push(`\u2192 ${t83.owner}`);
|
|
5393
|
+
if (t83.dependsOn.length > 0) bits.push(`(\u7B49 ${t83.dependsOn.join(", ")})`);
|
|
5394
|
+
return bits.join(" ");
|
|
5395
|
+
});
|
|
5396
|
+
return ok3(`\u5171 ${tasks.length} \u6761\uFF1A
|
|
5397
|
+
${lines.join("\n")}`);
|
|
5398
|
+
}
|
|
5399
|
+
};
|
|
5400
|
+
}
|
|
5401
|
+
function taskGet(team) {
|
|
5402
|
+
return {
|
|
5403
|
+
name: "team_task_get",
|
|
5404
|
+
description: "\u8BFB\u4E00\u6761\u4EFB\u52A1\u7684\u5B8C\u6574\u5185\u5BB9\uFF08\u542B revision \u2014\u2014 \u6539\u4E4B\u524D\u5148\u8BFB\u5B83\uFF09\u3002",
|
|
5405
|
+
parameters: {
|
|
5406
|
+
type: "object",
|
|
5407
|
+
properties: { id: { type: "string", description: "\u4EFB\u52A1 id" } },
|
|
5408
|
+
required: ["id"]
|
|
5409
|
+
},
|
|
5410
|
+
exposure: ToolExposure.Deferred,
|
|
5411
|
+
supportsParallel: true,
|
|
5412
|
+
operation: "file_read",
|
|
5413
|
+
annotations: {
|
|
5414
|
+
readOnlyHint: true,
|
|
5415
|
+
destructiveHint: false,
|
|
5416
|
+
idempotentHint: true,
|
|
5417
|
+
openWorldHint: false
|
|
5418
|
+
},
|
|
5419
|
+
describeTarget: (args) => String(args["id"] ?? ""),
|
|
5420
|
+
async execute(args) {
|
|
5421
|
+
const id = str3(args, "id");
|
|
5422
|
+
const t83 = team.tasks.get(id);
|
|
5423
|
+
if (!t83) return err2(7304, `\u6CA1\u6709\u8FD9\u4E2A\u4EFB\u52A1\uFF1A${id}`, "\u7528 team_task_list \u770B\u6709\u54EA\u4E9B");
|
|
5424
|
+
return ok3(
|
|
5425
|
+
[
|
|
5426
|
+
`${t83.id} [${t83.status}] revision ${t83.revision}`,
|
|
5427
|
+
`\u6807\u9898\uFF1A${t83.title}`,
|
|
5428
|
+
t83.description ? `\u7EC6\u8282\uFF1A${t83.description}` : "",
|
|
5429
|
+
t83.owner ? `\u5F52\u5C5E\uFF1A${t83.owner}` : "\u5F52\u5C5E\uFF1A\uFF08\u65E0\uFF09",
|
|
5430
|
+
t83.dependsOn.length > 0 ? `\u4F9D\u8D56\uFF1A${t83.dependsOn.join(", ")}` : "\u4F9D\u8D56\uFF1A\u65E0"
|
|
5431
|
+
].filter(Boolean).join("\n")
|
|
5432
|
+
);
|
|
5433
|
+
}
|
|
5434
|
+
};
|
|
5435
|
+
}
|
|
5436
|
+
function taskUpdate(team) {
|
|
5437
|
+
return {
|
|
5438
|
+
name: "team_task_update",
|
|
5439
|
+
description: [
|
|
5440
|
+
"\u6539\u4E00\u6761\u4EFB\u52A1\u3002**\u6539\u4E4B\u524D\u5148 team_task_get \u62FF\u5230 revision\uFF0C\u539F\u6837\u586B\u8FDB expectedRevision**\u3002",
|
|
5441
|
+
"\u522B\u4EBA\u5728\u8FD9\u671F\u95F4\u52A8\u8FC7\u5B83\u7684\u8BDD\uFF0C\u8FD9\u6B21\u5199\u5165\u4F1A\u88AB**\u6574\u7B14\u62D2\u7EDD**\u5E76\u544A\u8BC9\u4F60\u73B0\u5728\u662F\u51E0 \u2014\u2014",
|
|
5442
|
+
"\u91CD\u8BFB\u4E00\u904D\u518D\u51B3\u5B9A\uFF0C\u522B\u731C\u3002\u4E0D\u586B expectedRevision \u5C31\u662F\u4E0D\u68C0\u67E5\uFF08\u53EA\u5728\u4F60\u786E\u5B9A\u81EA\u5DF1\u662F\u552F\u4E00\u5199\u8005\u65F6\u7528\uFF09\u3002"
|
|
5443
|
+
].join("\n"),
|
|
5444
|
+
parameters: {
|
|
5445
|
+
type: "object",
|
|
5446
|
+
properties: {
|
|
5447
|
+
id: { type: "string", description: "\u4EFB\u52A1 id" },
|
|
5448
|
+
expectedRevision: {
|
|
5449
|
+
type: "number",
|
|
5450
|
+
description: "\u4F60\u4E0A\u6B21\u8BFB\u5230\u7684 revision\u3002\u5BF9\u4E0D\u4E0A\u5C31\u62D2\u7EDD\u6574\u7B14\u5199\u5165"
|
|
5451
|
+
},
|
|
5452
|
+
title: { type: "string" },
|
|
5453
|
+
description: { type: "string" },
|
|
5454
|
+
status: { type: "string", enum: [...TASK_STATUSES] },
|
|
5455
|
+
owner: { type: "string", description: "\u6539\u6210\u5F52\u8C01" }
|
|
5456
|
+
},
|
|
5457
|
+
required: ["id"]
|
|
5458
|
+
},
|
|
5459
|
+
exposure: ToolExposure.Deferred,
|
|
5460
|
+
supportsParallel: false,
|
|
5461
|
+
operation: "file_read",
|
|
5462
|
+
annotations: {
|
|
5463
|
+
readOnlyHint: false,
|
|
5464
|
+
destructiveHint: false,
|
|
5465
|
+
idempotentHint: false,
|
|
5466
|
+
openWorldHint: false
|
|
5467
|
+
},
|
|
5468
|
+
describeTarget: (args) => String(args["id"] ?? ""),
|
|
5469
|
+
async execute(args) {
|
|
5470
|
+
const id = str3(args, "id");
|
|
5471
|
+
if (!id) return err2(7305, "\u7F3A\u5C11 id");
|
|
5472
|
+
const status = str3(args, "status");
|
|
5473
|
+
if (status && !TASK_STATUSES.includes(status)) {
|
|
5474
|
+
return err2(7306, `\u4E0D\u8BA4\u8BC6\u7684\u72B6\u6001\uFF1A${status}`, `\u53EF\u7528\uFF1A${TASK_STATUSES.join(" / ")}`);
|
|
5475
|
+
}
|
|
5476
|
+
const patch = {};
|
|
5477
|
+
const title = str3(args, "title");
|
|
5478
|
+
const description = str3(args, "description");
|
|
5479
|
+
const owner = str3(args, "owner");
|
|
5480
|
+
if (title) patch.title = title;
|
|
5481
|
+
if (description) patch.description = description;
|
|
5482
|
+
if (status) patch.status = status;
|
|
5483
|
+
if (owner) patch.owner = owner;
|
|
5484
|
+
if (Object.keys(patch).length === 0) return err2(7307, "\u4E00\u4E2A\u5B57\u6BB5\u90FD\u6CA1\u7ED9\uFF0C\u6CA1\u4EC0\u4E48\u53EF\u6539\u7684");
|
|
5485
|
+
const expected = typeof args["expectedRevision"] === "number" ? args["expectedRevision"] : void 0;
|
|
5486
|
+
const r = team.tasks.update(id, patch, expected);
|
|
5487
|
+
if (!r.ok) return err2(7308, r.reason);
|
|
5488
|
+
return ok3(`\u5DF2\u66F4\u65B0 ${r.task.id}\uFF08revision ${r.task.revision}\uFF0C\u72B6\u6001 ${r.task.status}\uFF09\u3002`);
|
|
5489
|
+
}
|
|
5490
|
+
};
|
|
5491
|
+
}
|
|
5492
|
+
function followupTask(team, manager) {
|
|
5493
|
+
return {
|
|
5494
|
+
name: "followup_task",
|
|
5495
|
+
description: [
|
|
5496
|
+
"\u7ED9\u4E00\u4E2A**\u5DF2\u7ECF\u6536\u5DE5**\u7684\u6210\u5458\u518D\u6D3E\u4E00\u53E5\u8BDD\uFF0C\u8BA9\u5B83\u5E26\u7740\u4E0A\u4E00\u6B21\u7684\u5168\u90E8\u4E0A\u4E0B\u6587\u518D\u8DD1\u4E00\u8F6E\u3002",
|
|
5497
|
+
"\u548C send_message \u7684\u5206\u5DE5\uFF1Asend_message \u53EA\u5728\u5BF9\u65B9**\u6B63\u5728\u8DD1**\u7684\u65F6\u5019\u6709\u7528\uFF08\u5F53\u8F6E\u751F\u6548\uFF09\uFF1B",
|
|
5498
|
+
"\u5BF9\u65B9\u5DF2\u7ECF\u6536\u5DE5\u4E86\u5C31\u7528\u8FD9\u4E2A \u2014\u2014 \u5B83\u63A5\u7740\u81EA\u5DF1\u90A3\u6BB5\u4F1A\u8BDD\u7EE7\u7EED\uFF0C\u4E0D\u662F\u4ECE\u96F6\u5F00\u59CB\u3002",
|
|
5499
|
+
"\u4E00\u6B21\u5524\u9192 = \u4E00\u6B21\u5B8C\u6574\u7684\u6A21\u578B\u8C03\u7528\uFF08\u5168\u91CF\u5386\u53F2\u91CD\u53D1\uFF09\uFF0C\u80FD\u4E00\u6B21\u8BF4\u5B8C\u5C31\u522B\u62C6\u6210\u4E09\u6B21\u3002"
|
|
5500
|
+
].join("\n"),
|
|
4130
5501
|
parameters: {
|
|
4131
5502
|
type: "object",
|
|
4132
5503
|
properties: {
|
|
4133
|
-
|
|
4134
|
-
|
|
4135
|
-
description: "\u505A\u54EA\u4E00\u4EF6",
|
|
4136
|
-
enum: ["list", "create", "update"]
|
|
4137
|
-
},
|
|
4138
|
-
note: {
|
|
4139
|
-
type: "string",
|
|
4140
|
-
description: "\u4E3A\u4EC0\u4E48\u5EFA\u8FD9\u6761\uFF0C\u4E00\u53E5\u8BDD\u3002create / update \u5FC5\u586B\uFF0C\u4F1A\u5370\u5728\u7528\u6237\u770B\u5230\u7684\u5361\u7247\u4E0A\uFF1B\u8BF4\u4E0D\u51FA\u771F\u5B9E\u7406\u7531\u5C31\u522B\u63D0\u8FD9\u4E2A\u5EFA\u8BAE"
|
|
4141
|
-
},
|
|
4142
|
-
id: { type: "string", description: "\u6539\u54EA\u4E00\u6761\u3002update \u5FC5\u586B\uFF0C\u4ECE action=list \u91CC\u62FF" },
|
|
4143
|
-
name: { type: "string", description: "\u4EFB\u52A1\u540D\uFF0C\u7528\u6237\u5728\u5217\u8868\u91CC\u770B\u5230\u7684\u5C31\u662F\u5B83" },
|
|
4144
|
-
prompt: {
|
|
4145
|
-
type: "string",
|
|
4146
|
-
description: "\u5230\u70B9\u4E86\u53D1\u7ED9 agent \u7684\u63D0\u793A\u8BCD\u3002\u65E0\u4EBA\u503C\u5B88\uFF0C\u6240\u4EE5\u8981\u5199\u6210\u4E00\u53E5\u81EA\u8DB3\u7684\u6307\u4EE4\uFF1B\u8BA9\u5B83\u628A\u7ED3\u679C\u8FFD\u52A0\u5230\u4E00\u4EFD markdown \u6587\u4EF6\u91CC\u901A\u5E38\u6BD4\u4EC0\u4E48\u90FD\u4E0D\u843D\u5730\u6709\u7528"
|
|
4147
|
-
},
|
|
4148
|
-
trigger: {
|
|
4149
|
-
type: "object",
|
|
4150
|
-
description: '\u4EC0\u4E48\u65F6\u5019\u8DD1\u3002\u4E09\u6863\uFF1A{kind:"cron",cycle:"daily",at:"09:00"} / {kind:"cron",cycle:"weekly",at:"09:00",weekdays:[1,3,5]} / {kind:"cron",cycle:"monthly",at:"09:00",days:[1,15]} / {kind:"interval",everyMinutes:30} / {kind:"once",date:"2026-12-31",at:"23:00"}\u3002cron \u6863\u4E00\u5929\u8DD1\u51E0\u6B21\u5C31\u628A\u5176\u4F59\u65F6\u523B\u653E\u8FDB alsoAt\uFF1A{kind:"cron",cycle:"daily",at:"09:00",alsoAt:["14:00","18:00"]}\u3002everyMinutes \u662F 5\u20131440 \u7684\u6574\u6570\uFF0C\u6BCF\u5929\u4ECE 0 \u70B9\u8D77\u7B97\u3002\u6CA1\u6709\u5B8C\u6574 cron \u8868\u8FBE\u5F0F',
|
|
4151
|
-
properties: {
|
|
4152
|
-
kind: { type: "string", enum: ["cron", "interval", "once"] },
|
|
4153
|
-
cycle: { type: "string", enum: ["daily", "weekly", "monthly"] },
|
|
4154
|
-
at: { type: "string", description: "HH:mm\uFF0C24 \u5C0F\u65F6\u5236\uFF0C\u672C\u673A\u65F6\u533A" },
|
|
4155
|
-
alsoAt: {
|
|
4156
|
-
type: "array",
|
|
4157
|
-
items: { type: "string" },
|
|
4158
|
-
description: "cron \u6863\u5728 at \u4E4B\u5916\u7684\u5176\u4F59\u65F6\u523B\uFF08HH:mm\uFF09"
|
|
4159
|
-
},
|
|
4160
|
-
weekdays: { type: "array", items: { type: "number" }, description: "0=\u5468\u65E5 \u2026 6=\u5468\u516D" },
|
|
4161
|
-
days: { type: "array", items: { type: "number" }, description: "\u51E0\u53F7\uFF0C1\u201331" },
|
|
4162
|
-
everyMinutes: { type: "number" },
|
|
4163
|
-
date: { type: "string", description: "YYYY-MM-DD" }
|
|
4164
|
-
},
|
|
4165
|
-
required: ["kind"]
|
|
4166
|
-
},
|
|
4167
|
-
workDir: {
|
|
4168
|
-
type: "string",
|
|
4169
|
-
description: "\u5728\u54EA\u4E2A\u76EE\u5F55\u91CC\u8DD1\u3002\u7EDD\u5BF9\u8DEF\u5F84\u3002\u4E0D\u7ED9\u5C31\u843D\u5728 ~/.epoch/automation/<id>/"
|
|
4170
|
-
},
|
|
4171
|
-
permission: {
|
|
4172
|
-
type: "string",
|
|
4173
|
-
description: "\u6743\u9650\u6863\u3002\u4E0D\u7ED9\u5C31\u662F auto\uFF08**\u65B0\u5EFA\u4EFB\u52A1\u7684\u7F3A\u7701**\uFF0C2026-10-27 \u8D77\uFF1A\u5B9A\u65F6\u4EFB\u52A1\u6CA1\u4EBA\u53EF\u95EE\uFF0C\u4F4E\u6863\u5728\u8FD9\u91CC\u7B49\u4E8E\u300C\u5230\u70B9\u5FC5\u7136\u5931\u8D25\u300D\uFF09\u3002auto=\u5B8C\u5168\u8BBF\u95EE\uFF08\u4E0D\u518D\u786E\u8BA4\uFF0C\u53EA\u5269\u707E\u96BE\u7EA7\u4F1A\u88AB\u62E6\u4E0B\uFF09\uFF1BacceptEdits=\u8BF7\u6C42\u6279\u51C6\uFF1Bdefault=\u9010\u6761\u786E\u8BA4\uFF1Bplan=\u53EA\u8BFB\uFF08\u8BFB\u4E00\u904D\u5199\u4EFD\u62A5\u544A\u7684\u4EFB\u52A1\u7528\u5B83\uFF0C\u5929\u7136\u96F6\u6388\u6743\u9762\uFF09\u3002**\u53EA\u6709\u5728\u7528\u6237\u660E\u786E\u8BF4\u4E86\u8981\u7A84\u4E00\u6863\u65F6\u624D\u964D**",
|
|
4174
|
-
enum: ["plan", "default", "acceptEdits", "auto"]
|
|
4175
|
-
},
|
|
4176
|
-
allowTools: {
|
|
4177
|
-
type: "array",
|
|
4178
|
-
items: { type: "string" },
|
|
4179
|
-
description: "\u6574\u4E2A\u5DE5\u5177\u90FD\u4E0D\u7528\u95EE\u3002\u8303\u56F4\u6700\u7C97\uFF0C\u80FD\u7528 allowRules \u5C31\u522B\u7528\u5B83"
|
|
4180
|
-
},
|
|
4181
|
-
allowOperations: {
|
|
4182
|
-
type: "array",
|
|
4183
|
-
items: { type: "string" },
|
|
4184
|
-
description: "\u6574\u7C7B\u64CD\u4F5C\u90FD\u4E0D\u7528\u95EE\uFF1Afile_read / file_write / command / network / code_exec"
|
|
4185
|
-
},
|
|
4186
|
-
allowRules: {
|
|
4187
|
-
type: "array",
|
|
4188
|
-
items: { type: "string" },
|
|
4189
|
-
description: "\u9010\u6761\u653E\u884C\uFF0C\u6700\u63A8\u8350\u7684\u4E00\u683C\u3002\u5199\u6CD5\uFF1Aterminal(git status) / terminal(git log:*) / file_write(~/reports/**)\u3002\u65E0\u4EBA\u503C\u5B88\u4E0B\u649E\u5230\u8981\u786E\u8BA4\u7684\u64CD\u4F5C\u4E0D\u4F1A\u7B49\u4EBA\uFF0C\u4F1A\u76F4\u63A5\u6536\u5C3E\u5E76\u8BB0\u4E00\u6761\u6B20\u6761 \u2014\u2014 \u6240\u4EE5\u4EFB\u52A1\u8981\u8DD1\u4EC0\u4E48\u547D\u4EE4\uFF0C\u8FD9\u91CC\u5C31\u5F97\u9010\u6761\u5217\u51FA\u6765"
|
|
4190
|
-
},
|
|
4191
|
-
enabled: { type: "boolean", description: "\u53EA\u6709 update \u7528\u3002\u542F\u7528 / \u505C\u7528\u90A3\u4E00\u6761" },
|
|
4192
|
-
maxTurns: { type: "number", description: "\u53EA\u6709 update \u7528\u3002\u8F6E\u6B21\u4E0A\u9650\uFF0C\u6B63\u6574\u6570" },
|
|
4193
|
-
timeoutMs: { type: "number", description: "\u53EA\u6709 update \u7528\u3002\u5899\u949F\u8D85\u65F6\uFF0C\u6BEB\u79D2" }
|
|
5504
|
+
agentId: { type: "string", description: "\u6210\u5458\u540D\uFF08list_agents \u91CC\u6709\uFF09" },
|
|
5505
|
+
message: { type: "string", description: "\u8FD9\u4E00\u8F6E\u8981\u5B83\u505A\u4EC0\u4E48" }
|
|
4194
5506
|
},
|
|
4195
|
-
required: ["
|
|
5507
|
+
required: ["agentId", "message"]
|
|
4196
5508
|
},
|
|
4197
|
-
exposure: ToolExposure.
|
|
5509
|
+
exposure: ToolExposure.Deferred,
|
|
4198
5510
|
supportsParallel: false,
|
|
5511
|
+
operation: "command",
|
|
4199
5512
|
annotations: {
|
|
4200
5513
|
readOnlyHint: false,
|
|
4201
5514
|
destructiveHint: true,
|
|
4202
5515
|
idempotentHint: false,
|
|
4203
|
-
openWorldHint:
|
|
5516
|
+
openWorldHint: true
|
|
4204
5517
|
},
|
|
4205
|
-
|
|
4206
|
-
|
|
4207
|
-
|
|
4208
|
-
const
|
|
4209
|
-
const
|
|
4210
|
-
if (
|
|
4211
|
-
|
|
4212
|
-
|
|
4213
|
-
|
|
4214
|
-
${
|
|
4215
|
-
true,
|
|
4216
|
-
startedAt
|
|
4217
|
-
);
|
|
4218
|
-
}
|
|
4219
|
-
const parsed = parseScheduleDraft(rawArgs);
|
|
4220
|
-
if (!parsed.ok) return say4(parsed.message, false, startedAt);
|
|
4221
|
-
const draft = parsed.value;
|
|
4222
|
-
const current = draft.action === "update" ? deps.get(draft.id) : void 0;
|
|
4223
|
-
if (draft.action === "update" && current === void 0) {
|
|
4224
|
-
return say4(
|
|
4225
|
-
`\u6CA1\u6709 id \u4E3A ${draft.id} \u7684\u4EFB\u52A1\u3002\u5148\u7528 action=list \u770B\u4E00\u773C\u73B0\u6709\u7684\u3002`,
|
|
4226
|
-
false,
|
|
4227
|
-
startedAt
|
|
4228
|
-
);
|
|
4229
|
-
}
|
|
4230
|
-
const issues = validateDraft(draft, deps.homeDir, current);
|
|
4231
|
-
if (issues.length > 0) {
|
|
4232
|
-
return say4(
|
|
4233
|
-
`\u8FD9\u4EFD\u63D0\u6848\u5B58\u4E0D\u4E0B\u6765\uFF0C\u5148\u6539\u8FD9\u51E0\u5904\u518D\u8BF4\uFF1A${issues.join("\u3001")}\u3002\uFF08\u8FD9\u4E9B\u662F\u6821\u9A8C\u7801\uFF0C\u542B\u4E49\u770B\u5B57\u9762\uFF1Bdetail \u62EC\u5728\u540E\u9762\uFF09`,
|
|
4234
|
-
false,
|
|
4235
|
-
startedAt
|
|
4236
|
-
);
|
|
4237
|
-
}
|
|
4238
|
-
const unattended = unattendedIssues(draft);
|
|
4239
|
-
if (unattended.length > 0) {
|
|
4240
|
-
return say4(
|
|
4241
|
-
`\u8FD9\u4EFD\u63D0\u6848\u5B58\u5F97\u4E0B\u6765\uFF0C\u4F46\u5B83\u5230\u70B9\u4E86**\u8DD1\u4E0D\u51FA\u7ED3\u679C** \u2014\u2014 \u5B9A\u65F6\u4EFB\u52A1\u662F\u65E0\u4EBA\u503C\u5B88\u7684\uFF0C\u6CA1\u4EBA\u5728\u65C1\u8FB9\u56DE\u8BDD\u3002\u6539\u5B8C\u518D\u4EA4\uFF1A
|
|
4242
|
-
${unattended.map((x) => `\xB7 ${x}`).join("\n")}`,
|
|
4243
|
-
false,
|
|
4244
|
-
startedAt
|
|
4245
|
-
);
|
|
4246
|
-
}
|
|
4247
|
-
const readOnly = ctx.permissionLevel === "plan";
|
|
4248
|
-
if (readOnly || deps.save === void 0) {
|
|
4249
|
-
return say4(summarizeProposal(draft, current, readOnly), true, startedAt);
|
|
4250
|
-
}
|
|
4251
|
-
const saved = await persist(deps.save, draft, current);
|
|
4252
|
-
if (saved.issues.length > 0) {
|
|
4253
|
-
const codes = saved.issues.map((x) => x.detail ? `${x.code}\uFF08${x.detail}\uFF09` : x.code);
|
|
4254
|
-
return say4(`\u5F15\u64CE\u62D2\u7EDD\u4E86\u8FD9\u4EFD\u63D0\u6848\uFF0C\u4E00\u4E2A\u5B57\u90FD\u6CA1\u5199\uFF1A${codes.join("\u3001")}\u3002`, false, startedAt);
|
|
5518
|
+
describeTarget: (args) => `${String(args["agentId"] ?? "")}: ${String(args["message"] ?? "")}`,
|
|
5519
|
+
async execute(args, ctx) {
|
|
5520
|
+
const start = Date.now();
|
|
5521
|
+
const agentId = str3(args, "agentId");
|
|
5522
|
+
const message = str3(args, "message");
|
|
5523
|
+
if (!agentId) return err2(7205, "\u7F3A\u5C11 agentId");
|
|
5524
|
+
if (!message) return err2(7206, "\u7F3A\u5C11 message");
|
|
5525
|
+
const member = team.get(agentId);
|
|
5526
|
+
if (!member) {
|
|
5527
|
+
return err2(7207, `\u6CA1\u6709\u8FD9\u4E2A\u6210\u5458\uFF1A${agentId}`, "\u7528 list_agents \u770B\u5F53\u524D\u6709\u8C01");
|
|
4255
5528
|
}
|
|
4256
|
-
|
|
4257
|
-
|
|
4258
|
-
|
|
4259
|
-
|
|
4260
|
-
|
|
4261
|
-
startedAt
|
|
5529
|
+
if (member.status === "running") {
|
|
5530
|
+
return err2(
|
|
5531
|
+
7208,
|
|
5532
|
+
`${agentId} \u6B63\u5728\u8DD1\uFF0C\u4E0D\u9700\u8981\u5524\u9192`,
|
|
5533
|
+
"\u73B0\u5728\u7ED9\u5B83\u8BF4\u8BDD\u7528 send_message \u2014\u2014 \u90A3\u6761\u4F1A\u63D2\u5230\u5B83\u4E0B\u4E00\u4E2A\u6B65\u9AA4\u8FB9\u754C\uFF0C\u5F53\u8F6E\u5C31\u751F\u6548"
|
|
4262
5534
|
);
|
|
4263
5535
|
}
|
|
4264
|
-
|
|
5536
|
+
const r = await manager.delegate(
|
|
5537
|
+
{
|
|
5538
|
+
tasks: [
|
|
5539
|
+
{
|
|
5540
|
+
goal: message,
|
|
5541
|
+
agentId,
|
|
5542
|
+
resumeSessionId: member.sessionId,
|
|
5543
|
+
...member.role ? { role: member.role } : {}
|
|
5544
|
+
}
|
|
5545
|
+
],
|
|
5546
|
+
background: true,
|
|
5547
|
+
max_concurrent: 1
|
|
5548
|
+
},
|
|
5549
|
+
ctx.sessionId,
|
|
5550
|
+
ctx.signal
|
|
5551
|
+
);
|
|
5552
|
+
if (!r.success) return { ...err2(7209, r.output), duration: Date.now() - start };
|
|
5553
|
+
return ok3(
|
|
5554
|
+
[
|
|
5555
|
+
`\u5DF2\u5524\u9192 ${agentId}\uFF08\u540E\u53F0\u4F5C\u4E1A ${r.jobId ?? "(\u65E0)"}\uFF09\uFF0C\u5B83\u5E26\u7740\u4E0A\u4E00\u6B21\u7684\u4E0A\u4E0B\u6587\u63A5\u7740\u5E72\u3002`,
|
|
5556
|
+
`\u770B\u5B83\u5E72\u5230\u54EA\u513F\u4E86\uFF1Atask_output ${r.jobId ?? ""} \u6216 list_agents`
|
|
5557
|
+
].join("\n"),
|
|
5558
|
+
start
|
|
5559
|
+
);
|
|
4265
5560
|
}
|
|
4266
5561
|
};
|
|
4267
5562
|
}
|
|
5563
|
+
function createTeamTools(team, manager) {
|
|
5564
|
+
return [
|
|
5565
|
+
listAgents(team),
|
|
5566
|
+
spawnTeammate(team, manager),
|
|
5567
|
+
waitAgent(team),
|
|
5568
|
+
interruptAgent(team),
|
|
5569
|
+
followupTask(team, manager),
|
|
5570
|
+
taskCreate(team),
|
|
5571
|
+
taskList(team),
|
|
5572
|
+
taskGet(team),
|
|
5573
|
+
taskUpdate(team)
|
|
5574
|
+
];
|
|
5575
|
+
}
|
|
5576
|
+
var TEAM_TOOL_NAMES = Object.freeze([
|
|
5577
|
+
"spawn_teammate",
|
|
5578
|
+
"list_agents",
|
|
5579
|
+
"wait_agent",
|
|
5580
|
+
"interrupt_agent",
|
|
5581
|
+
"followup_task",
|
|
5582
|
+
"team_task_create",
|
|
5583
|
+
"team_task_list",
|
|
5584
|
+
"team_task_get",
|
|
5585
|
+
"team_task_update"
|
|
5586
|
+
]);
|
|
4268
5587
|
// src/session/authorization.ts
|
|
4269
5588
|
function lineageOf(db, sessionId) {
|
|
4270
5589
|
const rows = db.prepare(
|
|
@@ -4749,8 +6068,8 @@ function createSessionListTool(deps) {
|
|
|
4749
6068
|
output: render(out, scopeNote(allWorkspaces, archived)),
|
|
4750
6069
|
duration: Date.now() - start
|
|
4751
6070
|
});
|
|
4752
|
-
} catch (
|
|
4753
|
-
return Promise.resolve(fail3(
|
|
6071
|
+
} catch (err3) {
|
|
6072
|
+
return Promise.resolve(fail3(err3 instanceof Error ? err3.message : String(err3), start, 8014));
|
|
4754
6073
|
}
|
|
4755
6074
|
}
|
|
4756
6075
|
};
|
|
@@ -4912,8 +6231,8 @@ before / after \u5404\u9ED8\u8BA4 ${DEFAULT_WINDOW}\u3001\u4E0A\u9650 ${MAX_WIND
|
|
|
4912
6231
|
output: renderWindow(out, sessionId, sessionId === ctx.sessionId),
|
|
4913
6232
|
duration: Date.now() - start
|
|
4914
6233
|
});
|
|
4915
|
-
} catch (
|
|
4916
|
-
return Promise.resolve(fail4(
|
|
6234
|
+
} catch (err3) {
|
|
6235
|
+
return Promise.resolve(fail4(err3 instanceof Error ? err3.message : String(err3), start, 8011));
|
|
4917
6236
|
}
|
|
4918
6237
|
}
|
|
4919
6238
|
};
|
|
@@ -5019,8 +6338,8 @@ function createSessionTraceTool(deps) {
|
|
|
5019
6338
|
output: renderTrace(trace, ctx.sessionId),
|
|
5020
6339
|
duration: Date.now() - start
|
|
5021
6340
|
});
|
|
5022
|
-
} catch (
|
|
5023
|
-
return Promise.resolve(fail4(
|
|
6341
|
+
} catch (err3) {
|
|
6342
|
+
return Promise.resolve(fail4(err3 instanceof Error ? err3.message : String(err3), start, 8013));
|
|
5024
6343
|
}
|
|
5025
6344
|
}
|
|
5026
6345
|
};
|
|
@@ -5143,10 +6462,10 @@ function createSessionSearchTool(deps) {
|
|
|
5143
6462
|
].join("\n"),
|
|
5144
6463
|
duration: Date.now() - start
|
|
5145
6464
|
});
|
|
5146
|
-
} catch (
|
|
6465
|
+
} catch (err3) {
|
|
5147
6466
|
return Promise.resolve(
|
|
5148
6467
|
fail5(
|
|
5149
|
-
|
|
6468
|
+
err3 instanceof Error ? err3.message : String(err3),
|
|
5150
6469
|
start,
|
|
5151
6470
|
8002,
|
|
5152
6471
|
"Retry with different words"
|
|
@@ -5239,10 +6558,10 @@ function createSessionMessagesSearchTool(deps) {
|
|
|
5239
6558
|
].join("\n"),
|
|
5240
6559
|
duration: Date.now() - start
|
|
5241
6560
|
});
|
|
5242
|
-
} catch (
|
|
6561
|
+
} catch (err3) {
|
|
5243
6562
|
return Promise.resolve(
|
|
5244
6563
|
fail5(
|
|
5245
|
-
|
|
6564
|
+
err3 instanceof Error ? err3.message : String(err3),
|
|
5246
6565
|
start,
|
|
5247
6566
|
8006,
|
|
5248
6567
|
"Retry with different words"
|
|
@@ -5341,10 +6660,10 @@ function parseFrontmatter(raw) {
|
|
|
5341
6660
|
if (!split) return { error: t("frontmatter.missing") };
|
|
5342
6661
|
try {
|
|
5343
6662
|
return { data: load(split.frontmatter), body: split.body };
|
|
5344
|
-
} catch (
|
|
6663
|
+
} catch (err3) {
|
|
5345
6664
|
return {
|
|
5346
6665
|
error: t("frontmatter.bad_yaml", {
|
|
5347
|
-
reason:
|
|
6666
|
+
reason: err3 instanceof Error ? err3.message : String(err3)
|
|
5348
6667
|
})
|
|
5349
6668
|
};
|
|
5350
6669
|
}
|
|
@@ -5457,10 +6776,10 @@ function fail7(message, start, code, suggestion) {
|
|
|
5457
6776
|
function done(output, start) {
|
|
5458
6777
|
return { success: true, output, duration: Date.now() - start };
|
|
5459
6778
|
}
|
|
5460
|
-
function fromThrow(
|
|
5461
|
-
return fail7(
|
|
6779
|
+
function fromThrow(err3, start, suggestion) {
|
|
6780
|
+
return fail7(err3 instanceof Error ? err3.message : String(err3), start, 3102, suggestion);
|
|
5462
6781
|
}
|
|
5463
|
-
function
|
|
6782
|
+
function str4(args, key) {
|
|
5464
6783
|
const raw = args[key];
|
|
5465
6784
|
return typeof raw === "string" ? raw : "";
|
|
5466
6785
|
}
|
|
@@ -5510,9 +6829,9 @@ function createTool(deps) {
|
|
|
5510
6829
|
describeTarget: (args) => `${SKILL_CREATE_TOOL}:${String(args["name"] ?? "")}`,
|
|
5511
6830
|
async execute(args) {
|
|
5512
6831
|
const start = Date.now();
|
|
5513
|
-
const name =
|
|
5514
|
-
const content =
|
|
5515
|
-
const category =
|
|
6832
|
+
const name = str4(args, "name").trim();
|
|
6833
|
+
const content = str4(args, "content");
|
|
6834
|
+
const category = str4(args, "category").trim() || "general";
|
|
5516
6835
|
if (!WRITABLE_SKILL_NAME.test(name)) {
|
|
5517
6836
|
return fail7(`invalid skill name: ${JSON.stringify(name)}`, start, 3101, WRITABLE_HINT);
|
|
5518
6837
|
}
|
|
@@ -5524,8 +6843,8 @@ function createTool(deps) {
|
|
|
5524
6843
|
try {
|
|
5525
6844
|
const path = await deps.skills.create(name, content, category);
|
|
5526
6845
|
return done(`created skill "${name}" at ${path}`, start);
|
|
5527
|
-
} catch (
|
|
5528
|
-
return fromThrow(
|
|
6846
|
+
} catch (err3) {
|
|
6847
|
+
return fromThrow(err3, start);
|
|
5529
6848
|
}
|
|
5530
6849
|
}
|
|
5531
6850
|
};
|
|
@@ -5549,8 +6868,8 @@ function editTool(deps) {
|
|
|
5549
6868
|
describeTarget: (args) => `${SKILL_EDIT_TOOL}:${String(args["name"] ?? "")}`,
|
|
5550
6869
|
async execute(args) {
|
|
5551
6870
|
const start = Date.now();
|
|
5552
|
-
const name =
|
|
5553
|
-
const content =
|
|
6871
|
+
const name = str4(args, "name").trim();
|
|
6872
|
+
const content = str4(args, "content");
|
|
5554
6873
|
if (!name) {
|
|
5555
6874
|
return fail7("name must not be empty", start, 3101, describeAvailableSkills(deps.skills));
|
|
5556
6875
|
}
|
|
@@ -5559,8 +6878,8 @@ function editTool(deps) {
|
|
|
5559
6878
|
try {
|
|
5560
6879
|
await deps.skills.edit(name, content);
|
|
5561
6880
|
return done(`rewrote SKILL.md of skill "${name}"`, start);
|
|
5562
|
-
} catch (
|
|
5563
|
-
return fromThrow(
|
|
6881
|
+
} catch (err3) {
|
|
6882
|
+
return fromThrow(err3, start, describeAvailableSkills(deps.skills));
|
|
5564
6883
|
}
|
|
5565
6884
|
}
|
|
5566
6885
|
};
|
|
@@ -5589,9 +6908,9 @@ function patchTool(deps) {
|
|
|
5589
6908
|
describeTarget: (args) => `${SKILL_PATCH_TOOL}:${String(args["name"] ?? "")}/${String(args["file_path"] ?? "SKILL.md")}`,
|
|
5590
6909
|
async execute(args) {
|
|
5591
6910
|
const start = Date.now();
|
|
5592
|
-
const name =
|
|
5593
|
-
const oldString =
|
|
5594
|
-
const filePath =
|
|
6911
|
+
const name = str4(args, "name").trim();
|
|
6912
|
+
const oldString = str4(args, "old_string");
|
|
6913
|
+
const filePath = str4(args, "file_path").trim();
|
|
5595
6914
|
if (!name) {
|
|
5596
6915
|
return fail7("name must not be empty", start, 3101, describeAvailableSkills(deps.skills));
|
|
5597
6916
|
}
|
|
@@ -5602,12 +6921,12 @@ function patchTool(deps) {
|
|
|
5602
6921
|
await deps.skills.patch(
|
|
5603
6922
|
name,
|
|
5604
6923
|
oldString,
|
|
5605
|
-
|
|
6924
|
+
str4(args, "new_string"),
|
|
5606
6925
|
filePath === "" ? void 0 : filePath
|
|
5607
6926
|
);
|
|
5608
6927
|
return done(`patched ${filePath || "SKILL.md"} of skill "${name}"`, start);
|
|
5609
|
-
} catch (
|
|
5610
|
-
return fromThrow(
|
|
6928
|
+
} catch (err3) {
|
|
6929
|
+
return fromThrow(err3, start, describeAvailableSkills(deps.skills));
|
|
5611
6930
|
}
|
|
5612
6931
|
}
|
|
5613
6932
|
};
|
|
@@ -5635,17 +6954,17 @@ function writeFileTool(deps) {
|
|
|
5635
6954
|
describeTarget: (args) => `${SKILL_WRITE_FILE_TOOL}:${String(args["name"] ?? "")}/${String(args["file_path"] ?? "")}`,
|
|
5636
6955
|
async execute(args) {
|
|
5637
6956
|
const start = Date.now();
|
|
5638
|
-
const name =
|
|
5639
|
-
const filePath =
|
|
6957
|
+
const name = str4(args, "name").trim();
|
|
6958
|
+
const filePath = str4(args, "file_path").trim();
|
|
5640
6959
|
if (!name) {
|
|
5641
6960
|
return fail7("name must not be empty", start, 3101, describeAvailableSkills(deps.skills));
|
|
5642
6961
|
}
|
|
5643
6962
|
if (!filePath) return fail7("file_path must not be empty", start, 3101);
|
|
5644
6963
|
try {
|
|
5645
|
-
await deps.skills.writeFile(name, filePath,
|
|
6964
|
+
await deps.skills.writeFile(name, filePath, str4(args, "content"));
|
|
5646
6965
|
return done(`wrote ${filePath} into skill "${name}"`, start);
|
|
5647
|
-
} catch (
|
|
5648
|
-
return fromThrow(
|
|
6966
|
+
} catch (err3) {
|
|
6967
|
+
return fromThrow(err3, start, describeAvailableSkills(deps.skills));
|
|
5649
6968
|
}
|
|
5650
6969
|
}
|
|
5651
6970
|
};
|
|
@@ -5765,8 +7084,8 @@ var MIGRATIONS = [
|
|
|
5765
7084
|
var TrackerDB = class {
|
|
5766
7085
|
db;
|
|
5767
7086
|
path;
|
|
5768
|
-
constructor(
|
|
5769
|
-
this.path =
|
|
7087
|
+
constructor(dbPath2) {
|
|
7088
|
+
this.path = dbPath2;
|
|
5770
7089
|
this.db = openDatabase(this.path);
|
|
5771
7090
|
migrate(this.db, NS, MIGRATIONS);
|
|
5772
7091
|
}
|
|
@@ -5918,13 +7237,13 @@ function createTodoTool(db) {
|
|
|
5918
7237
|
output: formatTodoList(todos, pendingCount),
|
|
5919
7238
|
duration: Date.now() - startTime
|
|
5920
7239
|
};
|
|
5921
|
-
} catch (
|
|
7240
|
+
} catch (err3) {
|
|
5922
7241
|
return {
|
|
5923
7242
|
success: false,
|
|
5924
7243
|
output: "TODO \u5217\u8868\u5199\u5165\u5931\u8D25",
|
|
5925
7244
|
error: {
|
|
5926
7245
|
code: 1,
|
|
5927
|
-
message:
|
|
7246
|
+
message: err3 instanceof Error ? err3.message : String(err3)
|
|
5928
7247
|
},
|
|
5929
7248
|
duration: Date.now() - startTime
|
|
5930
7249
|
};
|
|
@@ -5932,6 +7251,260 @@ function createTodoTool(db) {
|
|
|
5932
7251
|
}
|
|
5933
7252
|
};
|
|
5934
7253
|
}
|
|
7254
|
+
var MAX_POST_CHARS = 2e4;
|
|
7255
|
+
var CHANNEL_PATTERN = /^[A-Za-z0-9_.-]{1,64}$/;
|
|
7256
|
+
var MIGRATIONS2 = [
|
|
7257
|
+
{
|
|
7258
|
+
id: "board-initial",
|
|
7259
|
+
version: 1,
|
|
7260
|
+
description: "\u8BA8\u8BBA\u677F\uFF1A\u9891\u9053 / \u7EBF\u7A0B / \u5E16\u5B50 / \u8BA2\u9605",
|
|
7261
|
+
up: (db) => {
|
|
7262
|
+
db.exec(`
|
|
7263
|
+
CREATE TABLE IF NOT EXISTS board_channels (
|
|
7264
|
+
id TEXT PRIMARY KEY,
|
|
7265
|
+
name TEXT NOT NULL UNIQUE,
|
|
7266
|
+
description TEXT,
|
|
7267
|
+
created_by TEXT NOT NULL,
|
|
7268
|
+
created_at INTEGER NOT NULL
|
|
7269
|
+
);
|
|
7270
|
+
CREATE TABLE IF NOT EXISTS board_threads (
|
|
7271
|
+
id TEXT PRIMARY KEY,
|
|
7272
|
+
channel TEXT NOT NULL,
|
|
7273
|
+
title TEXT NOT NULL,
|
|
7274
|
+
created_by TEXT NOT NULL,
|
|
7275
|
+
created_at INTEGER NOT NULL,
|
|
7276
|
+
last_post_at INTEGER NOT NULL
|
|
7277
|
+
);
|
|
7278
|
+
CREATE INDEX IF NOT EXISTS board_threads_channel ON board_threads(channel, last_post_at DESC);
|
|
7279
|
+
CREATE TABLE IF NOT EXISTS board_posts (
|
|
7280
|
+
seq INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
7281
|
+
id TEXT NOT NULL UNIQUE,
|
|
7282
|
+
thread_id TEXT NOT NULL,
|
|
7283
|
+
author TEXT NOT NULL,
|
|
7284
|
+
text TEXT NOT NULL,
|
|
7285
|
+
created_at INTEGER NOT NULL
|
|
7286
|
+
);
|
|
7287
|
+
CREATE INDEX IF NOT EXISTS board_posts_thread ON board_posts(thread_id, seq);
|
|
7288
|
+
CREATE TABLE IF NOT EXISTS board_subscriptions (
|
|
7289
|
+
agent TEXT NOT NULL,
|
|
7290
|
+
target TEXT NOT NULL,
|
|
7291
|
+
last_seen_seq INTEGER NOT NULL DEFAULT 0,
|
|
7292
|
+
PRIMARY KEY (agent, target)
|
|
7293
|
+
);
|
|
7294
|
+
`);
|
|
7295
|
+
}
|
|
7296
|
+
}
|
|
7297
|
+
];
|
|
7298
|
+
function targetKey(t83) {
|
|
7299
|
+
return t83.kind === "channel" ? `channel:${t83.name}` : `thread:${t83.id}`;
|
|
7300
|
+
}
|
|
7301
|
+
var BoardStore = class {
|
|
7302
|
+
path;
|
|
7303
|
+
db;
|
|
7304
|
+
constructor(homeDir) {
|
|
7305
|
+
this.path = dbPath(homeDir);
|
|
7306
|
+
this.db = openDatabase(this.path);
|
|
7307
|
+
migrate(this.db, "board", MIGRATIONS2);
|
|
7308
|
+
}
|
|
7309
|
+
close() {
|
|
7310
|
+
releaseDatabase(this.path);
|
|
7311
|
+
}
|
|
7312
|
+
createChannel(args) {
|
|
7313
|
+
if (!CHANNEL_PATTERN.test(args.name)) {
|
|
7314
|
+
throw new Error(`\u9891\u9053\u540D\u4E0D\u5408\u6CD5\uFF1A${args.name}\uFF08\u53EA\u8BB8\u5B57\u6BCD\u6570\u5B57 _ . -\uFF0C\u6700\u957F 64\uFF09`);
|
|
7315
|
+
}
|
|
7316
|
+
const existing = this.channel(args.name);
|
|
7317
|
+
if (existing) return existing;
|
|
7318
|
+
const row = {
|
|
7319
|
+
id: `ch-${randomUUID().slice(0, 8)}`,
|
|
7320
|
+
name: args.name,
|
|
7321
|
+
...args.description ? { description: args.description } : {},
|
|
7322
|
+
createdBy: args.by,
|
|
7323
|
+
createdAt: Date.now()
|
|
7324
|
+
};
|
|
7325
|
+
this.db.prepare(
|
|
7326
|
+
`INSERT INTO board_channels (id, name, description, created_by, created_at)
|
|
7327
|
+
VALUES (?, ?, ?, ?, ?)`
|
|
7328
|
+
).run(row.id, row.name, row.description ?? null, row.createdBy, row.createdAt);
|
|
7329
|
+
return row;
|
|
7330
|
+
}
|
|
7331
|
+
upsertChannel(args) {
|
|
7332
|
+
const existing = this.channel(args.name);
|
|
7333
|
+
if (!existing) return this.createChannel(args);
|
|
7334
|
+
this.db.prepare(`UPDATE board_channels SET description = ? WHERE name = ?`).run(args.description, args.name);
|
|
7335
|
+
return { ...existing, description: args.description };
|
|
7336
|
+
}
|
|
7337
|
+
channel(name) {
|
|
7338
|
+
const row = this.db.prepare(
|
|
7339
|
+
`SELECT id, name, description, created_by, created_at FROM board_channels WHERE name = ?`
|
|
7340
|
+
).get(name);
|
|
7341
|
+
return row ? toChannel(row) : void 0;
|
|
7342
|
+
}
|
|
7343
|
+
listChannels() {
|
|
7344
|
+
const rows = this.db.prepare(
|
|
7345
|
+
`SELECT id, name, description, created_by, created_at FROM board_channels ORDER BY name`
|
|
7346
|
+
).all();
|
|
7347
|
+
return rows.map(toChannel);
|
|
7348
|
+
}
|
|
7349
|
+
listThreads(channel, limit = 20) {
|
|
7350
|
+
const rows = this.db.prepare(
|
|
7351
|
+
`SELECT t.id, t.channel, t.title, t.created_by, t.created_at, t.last_post_at,
|
|
7352
|
+
(SELECT COUNT(*) FROM board_posts p WHERE p.thread_id = t.id) AS posts
|
|
7353
|
+
FROM board_threads t WHERE t.channel = ? ORDER BY t.last_post_at DESC LIMIT ?`
|
|
7354
|
+
).all(channel, limit);
|
|
7355
|
+
return rows.map((r) => ({
|
|
7356
|
+
id: r.id,
|
|
7357
|
+
channel: r.channel,
|
|
7358
|
+
title: r.title,
|
|
7359
|
+
createdBy: r.created_by,
|
|
7360
|
+
createdAt: r.created_at,
|
|
7361
|
+
lastPostAt: r.last_post_at,
|
|
7362
|
+
postCount: r.posts
|
|
7363
|
+
}));
|
|
7364
|
+
}
|
|
7365
|
+
post(args) {
|
|
7366
|
+
return this.write({ ...args, notify: true });
|
|
7367
|
+
}
|
|
7368
|
+
append(args) {
|
|
7369
|
+
return this.write({ ...args, notify: false });
|
|
7370
|
+
}
|
|
7371
|
+
write(args) {
|
|
7372
|
+
const text = clip(args.text);
|
|
7373
|
+
const now = Date.now();
|
|
7374
|
+
const run = this.db.transaction(() => {
|
|
7375
|
+
let threadId;
|
|
7376
|
+
if (args.target.kind === "thread") {
|
|
7377
|
+
const exists2 = this.db.prepare(`SELECT id FROM board_threads WHERE id = ?`).get(args.target.id);
|
|
7378
|
+
if (!exists2) throw new Error(`\u6CA1\u6709\u8FD9\u4E2A\u7EBF\u7A0B\uFF1A${args.target.id}`);
|
|
7379
|
+
threadId = args.target.id;
|
|
7380
|
+
} else {
|
|
7381
|
+
const ch = this.channel(args.target.name);
|
|
7382
|
+
if (!ch) throw new Error(`\u6CA1\u6709\u8FD9\u4E2A\u9891\u9053\uFF1A${args.target.name}`);
|
|
7383
|
+
threadId = `th-${randomUUID().slice(0, 8)}`;
|
|
7384
|
+
this.db.prepare(
|
|
7385
|
+
`INSERT INTO board_threads (id, channel, title, created_by, created_at, last_post_at)
|
|
7386
|
+
VALUES (?, ?, ?, ?, ?, ?)`
|
|
7387
|
+
).run(threadId, ch.name, firstLine(text), args.author, now, now);
|
|
7388
|
+
}
|
|
7389
|
+
const id = `po-${randomUUID().slice(0, 8)}`;
|
|
7390
|
+
const info = this.db.prepare(
|
|
7391
|
+
`INSERT INTO board_posts (id, thread_id, author, text, created_at) VALUES (?, ?, ?, ?, ?)`
|
|
7392
|
+
).run(id, threadId, args.author, text, now);
|
|
7393
|
+
const seq = Number(info.lastInsertRowid);
|
|
7394
|
+
this.db.prepare(`UPDATE board_threads SET last_post_at = ? WHERE id = ?`).run(now, threadId);
|
|
7395
|
+
if (args.notify) {
|
|
7396
|
+
this.subscribe(args.author, { kind: "thread", id: threadId }, seq);
|
|
7397
|
+
}
|
|
7398
|
+
return {
|
|
7399
|
+
post: { id, threadId, author: args.author, text, createdAt: now, seq },
|
|
7400
|
+
threadId
|
|
7401
|
+
};
|
|
7402
|
+
});
|
|
7403
|
+
return run();
|
|
7404
|
+
}
|
|
7405
|
+
readThread(threadId, limit = 50) {
|
|
7406
|
+
const rows = this.db.prepare(
|
|
7407
|
+
`SELECT seq, id, thread_id, author, text, created_at FROM board_posts
|
|
7408
|
+
WHERE thread_id = ? ORDER BY seq ASC LIMIT ?`
|
|
7409
|
+
).all(threadId, limit);
|
|
7410
|
+
return rows.map(toPost);
|
|
7411
|
+
}
|
|
7412
|
+
readPost(id) {
|
|
7413
|
+
const row = this.db.prepare(`SELECT seq, id, thread_id, author, text, created_at FROM board_posts WHERE id = ?`).get(id);
|
|
7414
|
+
return row ? toPost(row) : void 0;
|
|
7415
|
+
}
|
|
7416
|
+
searchPosts(query, channel, limit = 20) {
|
|
7417
|
+
const like = `%${query}%`;
|
|
7418
|
+
const rows = channel ? this.db.prepare(
|
|
7419
|
+
`SELECT p.seq, p.id, p.thread_id, p.author, p.text, p.created_at
|
|
7420
|
+
FROM board_posts p JOIN board_threads t ON t.id = p.thread_id
|
|
7421
|
+
WHERE t.channel = ? AND p.text LIKE ? ORDER BY p.seq DESC LIMIT ?`
|
|
7422
|
+
).all(channel, like, limit) : this.db.prepare(
|
|
7423
|
+
`SELECT seq, id, thread_id, author, text, created_at FROM board_posts
|
|
7424
|
+
WHERE text LIKE ? ORDER BY seq DESC LIMIT ?`
|
|
7425
|
+
).all(like, limit);
|
|
7426
|
+
return rows.map(toPost);
|
|
7427
|
+
}
|
|
7428
|
+
subscribe(agent, target, seenSeq) {
|
|
7429
|
+
const key = targetKey(target);
|
|
7430
|
+
const initial = seenSeq ?? this.maxSeq();
|
|
7431
|
+
this.db.prepare(
|
|
7432
|
+
`INSERT INTO board_subscriptions (agent, target, last_seen_seq) VALUES (?, ?, ?)
|
|
7433
|
+
ON CONFLICT(agent, target) DO UPDATE SET
|
|
7434
|
+
last_seen_seq = MAX(board_subscriptions.last_seen_seq, excluded.last_seen_seq)`
|
|
7435
|
+
).run(agent, key, initial);
|
|
7436
|
+
}
|
|
7437
|
+
maxSeq() {
|
|
7438
|
+
const row = this.db.prepare(`SELECT COALESCE(MAX(seq), 0) AS n FROM board_posts`).get();
|
|
7439
|
+
return row.n;
|
|
7440
|
+
}
|
|
7441
|
+
unsubscribe(agent, target) {
|
|
7442
|
+
const info = this.db.prepare(`DELETE FROM board_subscriptions WHERE agent = ? AND target = ?`).run(agent, targetKey(target));
|
|
7443
|
+
return info.changes > 0;
|
|
7444
|
+
}
|
|
7445
|
+
pendingFor(agent) {
|
|
7446
|
+
const subs = this.db.prepare(`SELECT target, last_seen_seq FROM board_subscriptions WHERE agent = ?`).all(agent);
|
|
7447
|
+
const out = [];
|
|
7448
|
+
for (const s of subs) {
|
|
7449
|
+
const count = this.countSince(s.target, s.last_seen_seq);
|
|
7450
|
+
if (count > 0) out.push({ target: s.target, count });
|
|
7451
|
+
}
|
|
7452
|
+
return out;
|
|
7453
|
+
}
|
|
7454
|
+
markRead(agent, target) {
|
|
7455
|
+
if (target) {
|
|
7456
|
+
const key = targetKey(target);
|
|
7457
|
+
this.db.prepare(
|
|
7458
|
+
`UPDATE board_subscriptions SET last_seen_seq = (SELECT MAX(seq) FROM board_posts) WHERE agent = ? AND target = ?`
|
|
7459
|
+
).run(agent, key);
|
|
7460
|
+
return;
|
|
7461
|
+
}
|
|
7462
|
+
this.db.prepare(
|
|
7463
|
+
`UPDATE board_subscriptions SET last_seen_seq = (SELECT COALESCE(MAX(seq), 0) FROM board_posts) WHERE agent = ?`
|
|
7464
|
+
).run(agent);
|
|
7465
|
+
}
|
|
7466
|
+
countSince(target, sinceSeq) {
|
|
7467
|
+
if (target.startsWith("thread:")) {
|
|
7468
|
+
const id = target.slice("thread:".length);
|
|
7469
|
+
const row2 = this.db.prepare(`SELECT COUNT(*) AS n FROM board_posts WHERE thread_id = ? AND seq > ?`).get(id, sinceSeq);
|
|
7470
|
+
return row2.n;
|
|
7471
|
+
}
|
|
7472
|
+
const name = target.slice("channel:".length);
|
|
7473
|
+
const row = this.db.prepare(
|
|
7474
|
+
`SELECT COUNT(*) AS n FROM board_posts p JOIN board_threads t ON t.id = p.thread_id
|
|
7475
|
+
WHERE t.channel = ? AND p.seq > ?`
|
|
7476
|
+
).get(name, sinceSeq);
|
|
7477
|
+
return row.n;
|
|
7478
|
+
}
|
|
7479
|
+
};
|
|
7480
|
+
function clip(text) {
|
|
7481
|
+
if (text.length <= MAX_POST_CHARS) return text;
|
|
7482
|
+
return `${text.slice(0, MAX_POST_CHARS)}
|
|
7483
|
+
\u2026\uFF08\u622A\u65AD\uFF0C\u539F\u6587 ${text.length} \u5B57\uFF09`;
|
|
7484
|
+
}
|
|
7485
|
+
function firstLine(text) {
|
|
7486
|
+
const line = text.split("\n", 1)[0] ?? text;
|
|
7487
|
+
return line.length > 80 ? `${line.slice(0, 80)}\u2026` : line;
|
|
7488
|
+
}
|
|
7489
|
+
function toChannel(r) {
|
|
7490
|
+
return {
|
|
7491
|
+
id: r.id,
|
|
7492
|
+
name: r.name,
|
|
7493
|
+
...r.description ? { description: r.description } : {},
|
|
7494
|
+
createdBy: r.created_by,
|
|
7495
|
+
createdAt: r.created_at
|
|
7496
|
+
};
|
|
7497
|
+
}
|
|
7498
|
+
function toPost(r) {
|
|
7499
|
+
return {
|
|
7500
|
+
seq: r.seq,
|
|
7501
|
+
id: r.id,
|
|
7502
|
+
threadId: r.thread_id,
|
|
7503
|
+
author: r.author,
|
|
7504
|
+
text: r.text,
|
|
7505
|
+
createdAt: r.created_at
|
|
7506
|
+
};
|
|
7507
|
+
}
|
|
5935
7508
|
var PlanModeState = class {
|
|
5936
7509
|
constructor(permission2) {
|
|
5937
7510
|
this.permission = permission2;
|
|
@@ -6024,11 +7597,11 @@ function loadRoleDir(dir, source) {
|
|
|
6024
7597
|
let files;
|
|
6025
7598
|
try {
|
|
6026
7599
|
files = readdirSync(dir).filter((f) => f.endsWith(".md")).sort();
|
|
6027
|
-
} catch (
|
|
7600
|
+
} catch (err3) {
|
|
6028
7601
|
return {
|
|
6029
7602
|
roles: [],
|
|
6030
7603
|
issues: [
|
|
6031
|
-
{ path: dir, message: t("agent_role_load.dir_read_failed", { reason: reason(
|
|
7604
|
+
{ path: dir, message: t("agent_role_load.dir_read_failed", { reason: reason(err3) }) }
|
|
6032
7605
|
]
|
|
6033
7606
|
};
|
|
6034
7607
|
}
|
|
@@ -6045,9 +7618,9 @@ function loadRoleFile(path, file, source) {
|
|
|
6045
7618
|
let raw;
|
|
6046
7619
|
try {
|
|
6047
7620
|
raw = readFileSync(path, "utf8");
|
|
6048
|
-
} catch (
|
|
7621
|
+
} catch (err3) {
|
|
6049
7622
|
return {
|
|
6050
|
-
issues: [{ path: file, message: t("agent_role_load.read_failed", { reason: reason(
|
|
7623
|
+
issues: [{ path: file, message: t("agent_role_load.read_failed", { reason: reason(err3) }) }]
|
|
6051
7624
|
};
|
|
6052
7625
|
}
|
|
6053
7626
|
return parseRoleDefinition(raw, file, source);
|
|
@@ -6136,8 +7709,8 @@ function loadRoleDefinitions(opts) {
|
|
|
6136
7709
|
projectSkipped: false
|
|
6137
7710
|
};
|
|
6138
7711
|
}
|
|
6139
|
-
function reason(
|
|
6140
|
-
return
|
|
7712
|
+
function reason(err3) {
|
|
7713
|
+
return err3 instanceof Error ? err3.message : String(err3);
|
|
6141
7714
|
}
|
|
6142
7715
|
var READ_ONLY_TOOLS = [
|
|
6143
7716
|
"file_read",
|
|
@@ -6297,11 +7870,11 @@ function createRoleFile(input, opts) {
|
|
|
6297
7870
|
try {
|
|
6298
7871
|
mkdirSync(opts.dir, { recursive: true });
|
|
6299
7872
|
writeFileSync(path, text, { encoding: "utf-8", flag: "wx" });
|
|
6300
|
-
} catch (
|
|
6301
|
-
if (
|
|
7873
|
+
} catch (err3) {
|
|
7874
|
+
if (err3.code === "EEXIST") {
|
|
6302
7875
|
return { ok: false, reason: "duplicate", detail: t("role_write.taken", { name }) };
|
|
6303
7876
|
}
|
|
6304
|
-
return { ok: false, reason: "unwritable", detail: describe(
|
|
7877
|
+
return { ok: false, reason: "unwritable", detail: describe(err3) };
|
|
6305
7878
|
}
|
|
6306
7879
|
return { ok: true, path, role: back.role };
|
|
6307
7880
|
}
|
|
@@ -6341,8 +7914,8 @@ function driftOf(role, name, input) {
|
|
|
6341
7914
|
if ((role.maxTurns ?? null) !== (input.maxTurns ?? null)) return "maxTurns";
|
|
6342
7915
|
return void 0;
|
|
6343
7916
|
}
|
|
6344
|
-
function describe(
|
|
6345
|
-
return
|
|
7917
|
+
function describe(err3) {
|
|
7918
|
+
return err3 instanceof Error ? err3.message : String(err3);
|
|
6346
7919
|
}
|
|
6347
7920
|
function removeRoleFile(name, opts) {
|
|
6348
7921
|
const wanted = name.trim();
|
|
@@ -6371,8 +7944,8 @@ function removeRoleFile(name, opts) {
|
|
|
6371
7944
|
}
|
|
6372
7945
|
try {
|
|
6373
7946
|
rmSync(path);
|
|
6374
|
-
} catch (
|
|
6375
|
-
return { ok: false, reason: "failed", detail: describe2(
|
|
7947
|
+
} catch (err3) {
|
|
7948
|
+
return { ok: false, reason: "failed", detail: describe2(err3, path, opts.lang) };
|
|
6376
7949
|
}
|
|
6377
7950
|
return { ok: true, path };
|
|
6378
7951
|
}
|
|
@@ -6398,8 +7971,8 @@ function matchingFiles(dir, name) {
|
|
|
6398
7971
|
}
|
|
6399
7972
|
return hits;
|
|
6400
7973
|
}
|
|
6401
|
-
function describe2(
|
|
6402
|
-
const reason9 =
|
|
7974
|
+
function describe2(err3, path, lang) {
|
|
7975
|
+
const reason9 = err3 instanceof Error ? err3.message : String(err3);
|
|
6403
7976
|
return t("role_write.remove_failed", { path, reason: reason9 }, lang);
|
|
6404
7977
|
}
|
|
6405
7978
|
// src/agent-role/scope.ts
|
|
@@ -6480,14 +8053,14 @@ function walk(dir, prefix, depth, files, issues) {
|
|
|
6480
8053
|
let entries2;
|
|
6481
8054
|
try {
|
|
6482
8055
|
entries2 = readdirSync(dir, { withFileTypes: true });
|
|
6483
|
-
} catch (
|
|
6484
|
-
if (isMissing(
|
|
8056
|
+
} catch (err3) {
|
|
8057
|
+
if (isMissing(err3)) {
|
|
6485
8058
|
if (depth > 0) issues.push({ path: dir, message: t("custom_command.dir_vanished") });
|
|
6486
8059
|
return;
|
|
6487
8060
|
}
|
|
6488
8061
|
issues.push({
|
|
6489
8062
|
path: dir,
|
|
6490
|
-
message: t("custom_command.dir_read_failed", { reason: reason2(
|
|
8063
|
+
message: t("custom_command.dir_read_failed", { reason: reason2(err3) })
|
|
6491
8064
|
});
|
|
6492
8065
|
return;
|
|
6493
8066
|
}
|
|
@@ -6512,11 +8085,11 @@ function walk(dir, prefix, depth, files, issues) {
|
|
|
6512
8085
|
function commandNameFromRelPath(relPath) {
|
|
6513
8086
|
return relPath.replace(/\.md$/i, "").split("/").join(":").toLowerCase();
|
|
6514
8087
|
}
|
|
6515
|
-
function isMissing(
|
|
6516
|
-
return
|
|
8088
|
+
function isMissing(err3) {
|
|
8089
|
+
return err3?.code === "ENOENT";
|
|
6517
8090
|
}
|
|
6518
|
-
function reason2(
|
|
6519
|
-
return
|
|
8091
|
+
function reason2(err3) {
|
|
8092
|
+
return err3 instanceof Error ? err3.message : String(err3);
|
|
6520
8093
|
}
|
|
6521
8094
|
// src/extensions/commands.ts
|
|
6522
8095
|
var CommandFrontmatterSchema = z.object({
|
|
@@ -6563,9 +8136,9 @@ function loadCommandFile(file, source, prefix) {
|
|
|
6563
8136
|
let raw;
|
|
6564
8137
|
try {
|
|
6565
8138
|
raw = readFileSync(file.path, "utf8");
|
|
6566
|
-
} catch (
|
|
8139
|
+
} catch (err3) {
|
|
6567
8140
|
return {
|
|
6568
|
-
issues: [{ path: at, message: t("custom_command.read_failed", { reason: reason3(
|
|
8141
|
+
issues: [{ path: at, message: t("custom_command.read_failed", { reason: reason3(err3) }) }]
|
|
6569
8142
|
};
|
|
6570
8143
|
}
|
|
6571
8144
|
const parsed = parseFrontmatter(raw);
|
|
@@ -6668,8 +8241,8 @@ function resolveCommandModel(def, opts, warnings) {
|
|
|
6668
8241
|
}
|
|
6669
8242
|
return ref;
|
|
6670
8243
|
}
|
|
6671
|
-
function reason3(
|
|
6672
|
-
return
|
|
8244
|
+
function reason3(err3) {
|
|
8245
|
+
return err3 instanceof Error ? err3.message : String(err3);
|
|
6673
8246
|
}
|
|
6674
8247
|
// src/extensions/registry.ts
|
|
6675
8248
|
var SLASH_COMMANDS_DIAG_MODULE = "SlashCommands";
|
|
@@ -6952,10 +8525,10 @@ function scanHooks(dir, issues) {
|
|
|
6952
8525
|
let raw;
|
|
6953
8526
|
try {
|
|
6954
8527
|
raw = JSON.parse(readFileSync(path, "utf-8"));
|
|
6955
|
-
} catch (
|
|
8528
|
+
} catch (err3) {
|
|
6956
8529
|
issues.push({
|
|
6957
8530
|
path,
|
|
6958
|
-
message: t("plugin_inventory.hooks_bad_json", { reason:
|
|
8531
|
+
message: t("plugin_inventory.hooks_bad_json", { reason: firstLine2(err3) })
|
|
6959
8532
|
});
|
|
6960
8533
|
return [];
|
|
6961
8534
|
}
|
|
@@ -6981,8 +8554,8 @@ function scanMcp(dir, plugin, issues) {
|
|
|
6981
8554
|
let raw;
|
|
6982
8555
|
try {
|
|
6983
8556
|
raw = JSON.parse(readFileSync(path, "utf-8"));
|
|
6984
|
-
} catch (
|
|
6985
|
-
issues.push({ path, message: t("plugin.mcp_not_json", { reason:
|
|
8557
|
+
} catch (err3) {
|
|
8558
|
+
issues.push({ path, message: t("plugin.mcp_not_json", { reason: firstLine2(err3) }) });
|
|
6986
8559
|
return [];
|
|
6987
8560
|
}
|
|
6988
8561
|
if (raw === null || typeof raw !== "object" || Array.isArray(raw)) {
|
|
@@ -7007,10 +8580,10 @@ function readSettingsSummary(path, issues) {
|
|
|
7007
8580
|
let raw;
|
|
7008
8581
|
try {
|
|
7009
8582
|
raw = JSON.parse(readFileSync(path, "utf-8"));
|
|
7010
|
-
} catch (
|
|
8583
|
+
} catch (err3) {
|
|
7011
8584
|
issues.push({
|
|
7012
8585
|
path,
|
|
7013
|
-
message: t("plugin_inventory.settings_bad_json", { reason:
|
|
8586
|
+
message: t("plugin_inventory.settings_bad_json", { reason: firstLine2(err3) })
|
|
7014
8587
|
});
|
|
7015
8588
|
return { deny: 0, ignored: [] };
|
|
7016
8589
|
}
|
|
@@ -7038,16 +8611,16 @@ function readEntries(dir, issues) {
|
|
|
7038
8611
|
name: e.name,
|
|
7039
8612
|
isFile: e.isFile()
|
|
7040
8613
|
}));
|
|
7041
|
-
} catch (
|
|
8614
|
+
} catch (err3) {
|
|
7042
8615
|
issues.push({
|
|
7043
8616
|
path: dir,
|
|
7044
|
-
message: t("plugin_inventory.dir_read_failed", { reason:
|
|
8617
|
+
message: t("plugin_inventory.dir_read_failed", { reason: firstLine2(err3) })
|
|
7045
8618
|
});
|
|
7046
8619
|
return [];
|
|
7047
8620
|
}
|
|
7048
8621
|
}
|
|
7049
|
-
function
|
|
7050
|
-
const message =
|
|
8622
|
+
function firstLine2(err3) {
|
|
8623
|
+
const message = err3 instanceof Error ? err3.message : String(err3);
|
|
7051
8624
|
return message.split("\n")[0] ?? t("plugin_inventory.unknown_error");
|
|
7052
8625
|
}
|
|
7053
8626
|
var PLUGIN_MANIFEST_FILE = "epoch-plugin.json";
|
|
@@ -7109,13 +8682,13 @@ function readPluginManifest(dir) {
|
|
|
7109
8682
|
let raw;
|
|
7110
8683
|
try {
|
|
7111
8684
|
raw = readFileSync(path, "utf-8");
|
|
7112
|
-
} catch (
|
|
7113
|
-
const missing =
|
|
8685
|
+
} catch (err3) {
|
|
8686
|
+
const missing = err3.code === "ENOENT";
|
|
7114
8687
|
return {
|
|
7115
8688
|
issues: [
|
|
7116
8689
|
{
|
|
7117
8690
|
path,
|
|
7118
|
-
message: missing ? t("plugin_manifest.missing", { file: PLUGIN_MANIFEST_FILE }) : t("plugin_manifest.read_failed", { reason: reason4(
|
|
8691
|
+
message: missing ? t("plugin_manifest.missing", { file: PLUGIN_MANIFEST_FILE }) : t("plugin_manifest.read_failed", { reason: reason4(err3) })
|
|
7119
8692
|
}
|
|
7120
8693
|
]
|
|
7121
8694
|
};
|
|
@@ -7123,9 +8696,9 @@ function readPluginManifest(dir) {
|
|
|
7123
8696
|
let parsed;
|
|
7124
8697
|
try {
|
|
7125
8698
|
parsed = JSON.parse(raw);
|
|
7126
|
-
} catch (
|
|
8699
|
+
} catch (err3) {
|
|
7127
8700
|
return {
|
|
7128
|
-
issues: [{ path, message: t("plugin_manifest.bad_json", { reason:
|
|
8701
|
+
issues: [{ path, message: t("plugin_manifest.bad_json", { reason: firstLine3(err3) }) }]
|
|
7129
8702
|
};
|
|
7130
8703
|
}
|
|
7131
8704
|
const issues = unknownKeyIssues(PLUGIN_MANIFEST_KEYS, parsed, PLUGIN_MANIFEST_FILE);
|
|
@@ -7288,11 +8861,11 @@ function currentEpochVersion() {
|
|
|
7288
8861
|
cachedVersion = "unknown";
|
|
7289
8862
|
return cachedVersion;
|
|
7290
8863
|
}
|
|
7291
|
-
function reason4(
|
|
7292
|
-
return
|
|
8864
|
+
function reason4(err3) {
|
|
8865
|
+
return err3 instanceof Error ? err3.message : String(err3);
|
|
7293
8866
|
}
|
|
7294
|
-
function
|
|
7295
|
-
return reason4(
|
|
8867
|
+
function firstLine3(err3) {
|
|
8868
|
+
return reason4(err3).split("\n")[0] ?? t("plugin_manifest.unknown_error");
|
|
7296
8869
|
}
|
|
7297
8870
|
var RecordSchema = z.object({
|
|
7298
8871
|
name: z.string().regex(PLUGIN_NAME_PATTERN),
|
|
@@ -7327,8 +8900,8 @@ async function acquireStateLock(path) {
|
|
|
7327
8900
|
} catch {
|
|
7328
8901
|
}
|
|
7329
8902
|
};
|
|
7330
|
-
} catch (
|
|
7331
|
-
if (
|
|
8903
|
+
} catch (err3) {
|
|
8904
|
+
if (err3.code !== "EEXIST") throw err3;
|
|
7332
8905
|
if (breakStaleLock(lockPath)) continue;
|
|
7333
8906
|
if (Date.now() >= deadline) {
|
|
7334
8907
|
throw new Error(t("plugin_store.lock_timeout", { path: lockPath }));
|
|
@@ -7360,8 +8933,8 @@ function readPluginRecords(path) {
|
|
|
7360
8933
|
let raw;
|
|
7361
8934
|
try {
|
|
7362
8935
|
raw = JSON.parse(readFileSync(path, "utf-8"));
|
|
7363
|
-
} catch (
|
|
7364
|
-
const detail = (
|
|
8936
|
+
} catch (err3) {
|
|
8937
|
+
const detail = (err3 instanceof Error ? err3.message : String(err3)).split("\n")[0];
|
|
7365
8938
|
return {
|
|
7366
8939
|
records: [],
|
|
7367
8940
|
issues: [{ path, message: t("plugin_store.bad_json", { detail: detail ?? "" }) }]
|
|
@@ -7652,30 +9225,30 @@ function runCommand(file, args, opts = {}) {
|
|
|
7652
9225
|
windowsVerbatimArguments: viaCmd,
|
|
7653
9226
|
...opts.cwd ? { cwd: opts.cwd } : {}
|
|
7654
9227
|
},
|
|
7655
|
-
(
|
|
9228
|
+
(err3, stdout, stderr) => {
|
|
7656
9229
|
const out = String(stdout ?? "");
|
|
7657
9230
|
const errOut = String(stderr ?? "");
|
|
7658
|
-
if (!
|
|
9231
|
+
if (!err3) {
|
|
7659
9232
|
resolvePromise({ ok: true, stdout: out, stderr: errOut });
|
|
7660
9233
|
return;
|
|
7661
9234
|
}
|
|
7662
|
-
const detail = describe3(file,
|
|
9235
|
+
const detail = describe3(file, err3, errOut);
|
|
7663
9236
|
resolvePromise({
|
|
7664
9237
|
ok: false,
|
|
7665
9238
|
detail,
|
|
7666
9239
|
stdout: out,
|
|
7667
9240
|
stderr: errOut,
|
|
7668
|
-
...
|
|
9241
|
+
...err3.code === "ENOENT" ? { notFound: true } : {}
|
|
7669
9242
|
});
|
|
7670
9243
|
}
|
|
7671
9244
|
),
|
|
7672
|
-
(
|
|
9245
|
+
(err3) => {
|
|
7673
9246
|
resolvePromise({
|
|
7674
9247
|
ok: false,
|
|
7675
|
-
detail: describe3(file,
|
|
9248
|
+
detail: describe3(file, err3, ""),
|
|
7676
9249
|
stdout: "",
|
|
7677
9250
|
stderr: "",
|
|
7678
|
-
...
|
|
9251
|
+
...err3.code === "ENOENT" || err3.code === "ENOTDIR" ? { notFound: true } : {}
|
|
7679
9252
|
});
|
|
7680
9253
|
}
|
|
7681
9254
|
);
|
|
@@ -7688,11 +9261,11 @@ function escapeForCmd(arg) {
|
|
|
7688
9261
|
const quoted = `"${arg.replace(/(\\*)"/g, '$1$1\\"').replace(/(\\*)$/, "$1$1")}"`;
|
|
7689
9262
|
return quoted.replace(/([()%!^<>&|;,"])/g, "^$1");
|
|
7690
9263
|
}
|
|
7691
|
-
function describe3(file,
|
|
7692
|
-
if (
|
|
7693
|
-
if (
|
|
9264
|
+
function describe3(file, err3, stderr) {
|
|
9265
|
+
if (err3.code === "ENOENT") return t("plugin_cmd.not_found", { file });
|
|
9266
|
+
if (err3.killed) return t("plugin_cmd.timeout", { file });
|
|
7694
9267
|
const tail = stderr.trim().split("\n").slice(-4).join("\n").trim();
|
|
7695
|
-
return tail ||
|
|
9268
|
+
return tail || err3.message;
|
|
7696
9269
|
}
|
|
7697
9270
|
// src/plugin/archive.ts
|
|
7698
9271
|
function resolveTar() {
|
|
@@ -7757,8 +9330,8 @@ ${detail}` }) };
|
|
|
7757
9330
|
let entries2;
|
|
7758
9331
|
try {
|
|
7759
9332
|
entries2 = readdirSync(current, { withFileTypes: true });
|
|
7760
|
-
} catch (
|
|
7761
|
-
return t("plugin_pack.read_failed", { path: current, reason:
|
|
9333
|
+
} catch (err3) {
|
|
9334
|
+
return t("plugin_pack.read_failed", { path: current, reason: firstLine4(err3) });
|
|
7762
9335
|
}
|
|
7763
9336
|
for (const entry of entries2) {
|
|
7764
9337
|
if (PACK_EXCLUDES.includes(entry.name)) continue;
|
|
@@ -7781,8 +9354,8 @@ ${detail}` }) };
|
|
|
7781
9354
|
let stat5;
|
|
7782
9355
|
try {
|
|
7783
9356
|
stat5 = statSync(abs);
|
|
7784
|
-
} catch (
|
|
7785
|
-
return t("plugin_pack.read_failed", { path: abs, reason:
|
|
9357
|
+
} catch (err3) {
|
|
9358
|
+
return t("plugin_pack.read_failed", { path: abs, reason: firstLine4(err3) });
|
|
7786
9359
|
}
|
|
7787
9360
|
files.push({ path: rel, bytes: stat5.size, mtimeMs: Math.floor(stat5.mtimeMs) });
|
|
7788
9361
|
totalBytes += stat5.size;
|
|
@@ -7819,10 +9392,10 @@ async function packPlugin(plan, destDir) {
|
|
|
7819
9392
|
try {
|
|
7820
9393
|
writeFileSync(listFile, `${plan.files.map((f) => f.path).join("\n")}
|
|
7821
9394
|
`, "utf-8");
|
|
7822
|
-
} catch (
|
|
9395
|
+
} catch (err3) {
|
|
7823
9396
|
return {
|
|
7824
9397
|
ok: false,
|
|
7825
|
-
reason: t("plugin_pack.read_failed", { path: listFile, reason:
|
|
9398
|
+
reason: t("plugin_pack.read_failed", { path: listFile, reason: firstLine4(err3) })
|
|
7826
9399
|
};
|
|
7827
9400
|
}
|
|
7828
9401
|
let result;
|
|
@@ -7850,10 +9423,10 @@ async function packPlugin(plan, destDir) {
|
|
|
7850
9423
|
let bytes;
|
|
7851
9424
|
try {
|
|
7852
9425
|
bytes = statSync(archivePath).size;
|
|
7853
|
-
} catch (
|
|
9426
|
+
} catch (err3) {
|
|
7854
9427
|
return {
|
|
7855
9428
|
ok: false,
|
|
7856
|
-
reason: t("plugin_pack.read_failed", { path: archivePath, reason:
|
|
9429
|
+
reason: t("plugin_pack.read_failed", { path: archivePath, reason: firstLine4(err3) })
|
|
7857
9430
|
};
|
|
7858
9431
|
}
|
|
7859
9432
|
return { ok: true, archivePath, bytes };
|
|
@@ -7861,8 +9434,8 @@ async function packPlugin(plan, destDir) {
|
|
|
7861
9434
|
function isVirtualenv(dir) {
|
|
7862
9435
|
return existsSync(join(dir, "pyvenv.cfg"));
|
|
7863
9436
|
}
|
|
7864
|
-
function
|
|
7865
|
-
const message =
|
|
9437
|
+
function firstLine4(err3) {
|
|
9438
|
+
const message = err3 instanceof Error ? err3.message : String(err3);
|
|
7866
9439
|
return message.split("\n")[0] ?? message;
|
|
7867
9440
|
}
|
|
7868
9441
|
var ABOUT_README_MAX_CHARS = 32e3;
|
|
@@ -8118,11 +9691,11 @@ function readMarketplaces(statePath) {
|
|
|
8118
9691
|
let raw;
|
|
8119
9692
|
try {
|
|
8120
9693
|
raw = JSON.parse(readFileSync(statePath, "utf-8"));
|
|
8121
|
-
} catch (
|
|
9694
|
+
} catch (err3) {
|
|
8122
9695
|
return {
|
|
8123
9696
|
records: [],
|
|
8124
9697
|
issues: [
|
|
8125
|
-
{ path: statePath, message: t("plugin_marketplace.bad_json", { reason: first(
|
|
9698
|
+
{ path: statePath, message: t("plugin_marketplace.bad_json", { reason: first(err3) }) }
|
|
8126
9699
|
]
|
|
8127
9700
|
};
|
|
8128
9701
|
}
|
|
@@ -8282,8 +9855,8 @@ async function fetchCatalog(source) {
|
|
|
8282
9855
|
}
|
|
8283
9856
|
try {
|
|
8284
9857
|
return parseCatalog(readFileSync(local, "utf-8"), local);
|
|
8285
|
-
} catch (
|
|
8286
|
-
return { ok: false, reason: t("plugin_marketplace.read_failed", { reason: first(
|
|
9858
|
+
} catch (err3) {
|
|
9859
|
+
return { ok: false, reason: t("plugin_marketplace.read_failed", { reason: first(err3) }) };
|
|
8287
9860
|
}
|
|
8288
9861
|
}
|
|
8289
9862
|
const url = catalogUrl(input);
|
|
@@ -8303,8 +9876,8 @@ async function fetchCatalog(source) {
|
|
|
8303
9876
|
};
|
|
8304
9877
|
}
|
|
8305
9878
|
return parseCatalog(await response.text(), url);
|
|
8306
|
-
} catch (
|
|
8307
|
-
return { ok: false, reason: t("marketplace.fetch_error", { url, reason: first(
|
|
9879
|
+
} catch (err3) {
|
|
9880
|
+
return { ok: false, reason: t("marketplace.fetch_error", { url, reason: first(err3) }) };
|
|
8308
9881
|
}
|
|
8309
9882
|
}
|
|
8310
9883
|
function looksPrivate(status) {
|
|
@@ -8334,10 +9907,10 @@ function parseCatalog(body2, where) {
|
|
|
8334
9907
|
let raw;
|
|
8335
9908
|
try {
|
|
8336
9909
|
raw = JSON.parse(body2);
|
|
8337
|
-
} catch (
|
|
9910
|
+
} catch (err3) {
|
|
8338
9911
|
return {
|
|
8339
9912
|
ok: false,
|
|
8340
|
-
reason: t("plugin_marketplace.catalog_bad_json", { where, reason: first(
|
|
9913
|
+
reason: t("plugin_marketplace.catalog_bad_json", { where, reason: first(err3) })
|
|
8341
9914
|
};
|
|
8342
9915
|
}
|
|
8343
9916
|
const checked = parseLenient(CatalogSchema.optional(), raw, void 0);
|
|
@@ -8347,8 +9920,8 @@ function parseCatalog(body2, where) {
|
|
|
8347
9920
|
}
|
|
8348
9921
|
return { ok: true, catalog: checked.value };
|
|
8349
9922
|
}
|
|
8350
|
-
function first(
|
|
8351
|
-
const message =
|
|
9923
|
+
function first(err3) {
|
|
9924
|
+
const message = err3 instanceof Error ? err3.message : String(err3);
|
|
8352
9925
|
return message.split("\n")[0] ?? t("plugin_marketplace.unknown_error");
|
|
8353
9926
|
}
|
|
8354
9927
|
var NPM_SPEC = /^(?:@[a-z0-9][a-z0-9._-]*\/)?[a-z0-9][a-z0-9._-]*(?:@[a-zA-Z0-9.^~*+-]+)?$/;
|
|
@@ -8756,11 +10329,11 @@ async function fetchFromHost(source, staging, opts) {
|
|
|
8756
10329
|
);
|
|
8757
10330
|
}
|
|
8758
10331
|
});
|
|
8759
|
-
} catch (
|
|
10332
|
+
} catch (err3) {
|
|
8760
10333
|
return {
|
|
8761
10334
|
ok: false,
|
|
8762
10335
|
reason: t("plugin_install.host_fetch_threw", {
|
|
8763
|
-
reason: (
|
|
10336
|
+
reason: (err3 instanceof Error ? err3.message : String(err3)).split("\n")[0] ?? ""
|
|
8764
10337
|
})
|
|
8765
10338
|
};
|
|
8766
10339
|
}
|
|
@@ -8832,11 +10405,11 @@ async function fetchArchive(source, staging, opts) {
|
|
|
8832
10405
|
};
|
|
8833
10406
|
}
|
|
8834
10407
|
bytes = await readBodyWithProgress(response, byteReporter(opts, "download", source.target));
|
|
8835
|
-
} catch (
|
|
10408
|
+
} catch (err3) {
|
|
8836
10409
|
return {
|
|
8837
10410
|
ok: false,
|
|
8838
10411
|
reason: t("plugin_install.download_failed", {
|
|
8839
|
-
message:
|
|
10412
|
+
message: err3 instanceof Error ? err3.message : String(err3)
|
|
8840
10413
|
})
|
|
8841
10414
|
};
|
|
8842
10415
|
}
|
|
@@ -8974,8 +10547,8 @@ async function applyRewind(store, sessionId, manifest, apply, skippedConflicts)
|
|
|
8974
10547
|
let staged;
|
|
8975
10548
|
try {
|
|
8976
10549
|
staged = await stageAll(store, sessionId, manifest, todo, byPath);
|
|
8977
|
-
} catch (
|
|
8978
|
-
return { ...empty, failed: t("rewind.stage_failed", { message: messageOf(
|
|
10550
|
+
} catch (err3) {
|
|
10551
|
+
return { ...empty, failed: t("rewind.stage_failed", { message: messageOf(err3) }) };
|
|
8979
10552
|
}
|
|
8980
10553
|
return commitAll2(staged, skippedConflicts);
|
|
8981
10554
|
}
|
|
@@ -8999,9 +10572,9 @@ async function stageAll(store, sessionId, manifest, todo, byPath) {
|
|
|
8999
10572
|
}
|
|
9000
10573
|
staged.push(item);
|
|
9001
10574
|
}
|
|
9002
|
-
} catch (
|
|
10575
|
+
} catch (err3) {
|
|
9003
10576
|
await discard(staged);
|
|
9004
|
-
throw
|
|
10577
|
+
throw err3;
|
|
9005
10578
|
}
|
|
9006
10579
|
return staged;
|
|
9007
10580
|
}
|
|
@@ -9016,7 +10589,7 @@ async function commitAll2(staged, skippedConflicts) {
|
|
|
9016
10589
|
for (const item of staged) {
|
|
9017
10590
|
try {
|
|
9018
10591
|
await commitOne(item);
|
|
9019
|
-
} catch (
|
|
10592
|
+
} catch (err3) {
|
|
9020
10593
|
await rollback(done2);
|
|
9021
10594
|
await discard(staged);
|
|
9022
10595
|
return {
|
|
@@ -9024,7 +10597,7 @@ async function commitAll2(staged, skippedConflicts) {
|
|
|
9024
10597
|
restored: [],
|
|
9025
10598
|
deleted: [],
|
|
9026
10599
|
recreated: [],
|
|
9027
|
-
failed: t("rewind.commit_failed", { message: messageOf(
|
|
10600
|
+
failed: t("rewind.commit_failed", { message: messageOf(err3) })
|
|
9028
10601
|
};
|
|
9029
10602
|
}
|
|
9030
10603
|
done2.push(item);
|
|
@@ -9080,8 +10653,8 @@ function bucketOf(outcome, action) {
|
|
|
9080
10653
|
if (action === "recreate") return outcome.recreated;
|
|
9081
10654
|
return outcome.restored;
|
|
9082
10655
|
}
|
|
9083
|
-
function messageOf(
|
|
9084
|
-
return
|
|
10656
|
+
function messageOf(err3) {
|
|
10657
|
+
return err3 instanceof Error ? err3.message : String(err3);
|
|
9085
10658
|
}
|
|
9086
10659
|
// src/disk-ledger.ts
|
|
9087
10660
|
var CHECKPOINT_MAX_TOTAL_BYTES = 200 * 1024 * 1024;
|
|
@@ -9238,9 +10811,9 @@ async function atomicWrite(path, data) {
|
|
|
9238
10811
|
await writeFile(tmp, data);
|
|
9239
10812
|
try {
|
|
9240
10813
|
await rename(tmp, path);
|
|
9241
|
-
} catch (
|
|
10814
|
+
} catch (err3) {
|
|
9242
10815
|
await rm(tmp, { force: true });
|
|
9243
|
-
throw
|
|
10816
|
+
throw err3;
|
|
9244
10817
|
}
|
|
9245
10818
|
}
|
|
9246
10819
|
function isManifest(value) {
|
|
@@ -9334,9 +10907,9 @@ var CheckpointManager = class {
|
|
|
9334
10907
|
turnIndex = turn.turnIndex ?? await this.nextTurnIndex(sessionId);
|
|
9335
10908
|
turn.turnIndex = turnIndex;
|
|
9336
10909
|
for (const path of fresh) {
|
|
9337
|
-
const { file, ok:
|
|
10910
|
+
const { file, ok: ok4 } = await this.snapshotFile(sessionId, turnIndex, path);
|
|
9338
10911
|
turn.files.push(file);
|
|
9339
|
-
if (!
|
|
10912
|
+
if (!ok4) turn.incomplete = true;
|
|
9340
10913
|
}
|
|
9341
10914
|
await this.store.writeManifest(sessionId, manifestOf(turn, turnIndex, this.workDir()));
|
|
9342
10915
|
} catch {
|
|
@@ -9375,8 +10948,8 @@ var CheckpointManager = class {
|
|
|
9375
10948
|
if (info.size > MAX_FILE_BYTES) return { file: absent, ok: false };
|
|
9376
10949
|
const hash = await this.store.putBlob(sessionId, turnIndex, await readFile(path));
|
|
9377
10950
|
return { file: { path, hash, mode: info.mode & 511 }, ok: true };
|
|
9378
|
-
} catch (
|
|
9379
|
-
return { file: absent, ok: isNotFound(
|
|
10951
|
+
} catch (err3) {
|
|
10952
|
+
return { file: absent, ok: isNotFound(err3) };
|
|
9380
10953
|
}
|
|
9381
10954
|
}
|
|
9382
10955
|
async nextTurnIndex(sessionId) {
|
|
@@ -9426,8 +10999,8 @@ function preview(text) {
|
|
|
9426
10999
|
const flat = text.replace(/\s+/g, " ").trim();
|
|
9427
11000
|
return flat.length > PREVIEW_LEN ? `${flat.slice(0, PREVIEW_LEN)}\u2026` : flat;
|
|
9428
11001
|
}
|
|
9429
|
-
function isNotFound(
|
|
9430
|
-
return
|
|
11002
|
+
function isNotFound(err3) {
|
|
11003
|
+
return err3?.code === "ENOENT";
|
|
9431
11004
|
}
|
|
9432
11005
|
async function hashOf(path) {
|
|
9433
11006
|
try {
|
|
@@ -9515,8 +11088,8 @@ async function readSnapshot(path) {
|
|
|
9515
11088
|
const buf = await readFile(path);
|
|
9516
11089
|
if (buf.includes(0)) return { kind: "opaque" };
|
|
9517
11090
|
return { kind: "text", text: buf.toString("utf-8"), bytes: buf.byteLength };
|
|
9518
|
-
} catch (
|
|
9519
|
-
return isNotFound2(
|
|
11091
|
+
} catch (err3) {
|
|
11092
|
+
return isNotFound2(err3) ? { kind: "absent" } : { kind: "opaque" };
|
|
9520
11093
|
}
|
|
9521
11094
|
}
|
|
9522
11095
|
function workspaceDisplayPath(path, workDir) {
|
|
@@ -9524,34 +11097,64 @@ function workspaceDisplayPath(path, workDir) {
|
|
|
9524
11097
|
if (!rel || rel.startsWith("..") || isAbsolute(rel)) return path;
|
|
9525
11098
|
return sep === "/" ? rel : rel.split(sep).join("/");
|
|
9526
11099
|
}
|
|
9527
|
-
function isNotFound2(
|
|
9528
|
-
return
|
|
11100
|
+
function isNotFound2(err3) {
|
|
11101
|
+
return err3?.code === "ENOENT";
|
|
9529
11102
|
}
|
|
9530
11103
|
var TaskNoticeTracker = class {
|
|
9531
|
-
constructor(source) {
|
|
11104
|
+
constructor(source, team, board) {
|
|
9532
11105
|
this.source = source;
|
|
11106
|
+
this.team = team;
|
|
11107
|
+
this.board = board;
|
|
9533
11108
|
}
|
|
9534
11109
|
source;
|
|
11110
|
+
team;
|
|
11111
|
+
board;
|
|
9535
11112
|
seen = /* @__PURE__ */ new Map();
|
|
9536
|
-
|
|
9537
|
-
|
|
9538
|
-
|
|
9539
|
-
|
|
9540
|
-
|
|
9541
|
-
|
|
9542
|
-
|
|
9543
|
-
|
|
11113
|
+
takeAgentMessages(sessionId) {
|
|
11114
|
+
const inbox = this.team?.mainInbox(sessionId);
|
|
11115
|
+
if (!inbox?.pending()) return [];
|
|
11116
|
+
return inbox.take().map((c) => typeof c === "string" ? c : contentToText(c));
|
|
11117
|
+
}
|
|
11118
|
+
notice(sessionId = LEAD_AGENT_ID) {
|
|
11119
|
+
return this.noticeDetailed(sessionId)?.text ?? null;
|
|
11120
|
+
}
|
|
11121
|
+
noticeDetailed(sessionId = LEAD_AGENT_ID) {
|
|
9544
11122
|
const lines = [];
|
|
9545
|
-
|
|
9546
|
-
|
|
9547
|
-
|
|
9548
|
-
|
|
9549
|
-
|
|
9550
|
-
|
|
9551
|
-
|
|
11123
|
+
if (this.source) {
|
|
11124
|
+
let tasks;
|
|
11125
|
+
try {
|
|
11126
|
+
tasks = this.source();
|
|
11127
|
+
} catch {
|
|
11128
|
+
tasks = [];
|
|
11129
|
+
}
|
|
11130
|
+
for (const task of tasks) {
|
|
11131
|
+
if (task.kind === "shell") continue;
|
|
11132
|
+
const before = this.seen.get(task.id);
|
|
11133
|
+
if (before === task.status) continue;
|
|
11134
|
+
this.seen.set(task.id, task.status);
|
|
11135
|
+
if (task.kind === "agent" && task.status === "running") continue;
|
|
11136
|
+
lines.push(describeBackgroundTask(task));
|
|
11137
|
+
}
|
|
11138
|
+
}
|
|
11139
|
+
const agentLines = this.takeAgentMessages(sessionId);
|
|
11140
|
+
const boardLines = this.board?.pending() ?? [];
|
|
11141
|
+
if (lines.length === 0 && agentLines.length === 0 && boardLines.length === 0) return null;
|
|
11142
|
+
const out = [];
|
|
11143
|
+
if (lines.length > 0) {
|
|
11144
|
+
out.push(systemNote("\u540E\u53F0\u4EFB\u52A1\u72B6\u6001"), ...lines, "\u8981\u770B\u8F93\u51FA\u7528 task_output\u3002");
|
|
11145
|
+
}
|
|
11146
|
+
if (agentLines.length > 0) {
|
|
11147
|
+
out.push(systemNote(AGENT_MESSAGE_NOTE_TITLE), ...agentLines);
|
|
11148
|
+
}
|
|
11149
|
+
if (boardLines.length > 0) {
|
|
11150
|
+
out.push(
|
|
11151
|
+
systemNote("\u8BA8\u8BBA\u677F"),
|
|
11152
|
+
...boardLines.map((b) => `- ${b.target}\uFF1A${b.count} \u6761\u65B0\u5E16`),
|
|
11153
|
+
"\u8981\u770B\u5185\u5BB9\u7528 read_thread\uFF08\u8BFB\u5B8C\u81EA\u52A8\u6807\u6210\u5DF2\u770B\uFF09\u3002"
|
|
11154
|
+
);
|
|
11155
|
+
this.board?.markRead();
|
|
9552
11156
|
}
|
|
9553
|
-
|
|
9554
|
-
return [systemNote("\u540E\u53F0\u4EFB\u52A1\u72B6\u6001"), ...lines, "\u8981\u770B\u8F93\u51FA\u7528 task_output\u3002"].join("\n");
|
|
11157
|
+
return { text: out.join("\n"), agent: agentLines };
|
|
9555
11158
|
}
|
|
9556
11159
|
};
|
|
9557
11160
|
function describeBackgroundTask(task) {
|
|
@@ -9840,8 +11443,8 @@ function readImageSize(bytes) {
|
|
|
9840
11443
|
const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
9841
11444
|
const size = pngSize(bytes, view) ?? jpegSize(bytes, view) ?? gifSize(bytes, view) ?? webpSize(bytes, view);
|
|
9842
11445
|
if (!size) return void 0;
|
|
9843
|
-
const
|
|
9844
|
-
return
|
|
11446
|
+
const ok4 = (n) => Number.isInteger(n) && n > 0;
|
|
11447
|
+
return ok4(size.width) && ok4(size.height) ? size : void 0;
|
|
9845
11448
|
}
|
|
9846
11449
|
function sniffMediaType(bytes) {
|
|
9847
11450
|
if (bytes.length < 12) return void 0;
|
|
@@ -10181,8 +11784,8 @@ function imageFromPath(filePath, mediaType) {
|
|
|
10181
11784
|
const st = statSync(abs);
|
|
10182
11785
|
if (!st.isFile()) throw new ImageLoadError(t("image_load.not_a_file", { path: abs }));
|
|
10183
11786
|
size = st.size;
|
|
10184
|
-
} catch (
|
|
10185
|
-
if (
|
|
11787
|
+
} catch (err3) {
|
|
11788
|
+
if (err3 instanceof ImageLoadError) throw err3;
|
|
10186
11789
|
throw new ImageLoadError(t("image_load.unreadable", { path: abs }));
|
|
10187
11790
|
}
|
|
10188
11791
|
if (size === 0) throw new ImageLoadError(t("image_load.empty", { path: abs }));
|
|
@@ -10399,8 +12002,8 @@ function decideTrust(dir) {
|
|
|
10399
12002
|
return ambient ? ambient.decide(dir) : noGate();
|
|
10400
12003
|
}
|
|
10401
12004
|
var FILE_VERSION = 1;
|
|
10402
|
-
function describe5(
|
|
10403
|
-
return
|
|
12005
|
+
function describe5(err3) {
|
|
12006
|
+
return err3 instanceof Error ? err3.message : String(err3);
|
|
10404
12007
|
}
|
|
10405
12008
|
var ImportTrustStore = class {
|
|
10406
12009
|
constructor(filePath = trustedImportsPath()) {
|
|
@@ -10439,18 +12042,18 @@ var ImportTrustStore = class {
|
|
|
10439
12042
|
let raw;
|
|
10440
12043
|
try {
|
|
10441
12044
|
raw = readFileSync(this.filePath, "utf-8");
|
|
10442
|
-
} catch (
|
|
12045
|
+
} catch (err3) {
|
|
10443
12046
|
this.loadErrors.push(
|
|
10444
|
-
t("import_trust.read_failed", { path: this.filePath, reason: describe5(
|
|
12047
|
+
t("import_trust.read_failed", { path: this.filePath, reason: describe5(err3) })
|
|
10445
12048
|
);
|
|
10446
12049
|
return;
|
|
10447
12050
|
}
|
|
10448
12051
|
let parsed;
|
|
10449
12052
|
try {
|
|
10450
12053
|
parsed = JSON.parse(raw);
|
|
10451
|
-
} catch (
|
|
12054
|
+
} catch (err3) {
|
|
10452
12055
|
this.loadErrors.push(
|
|
10453
|
-
t("import_trust.bad_json", { path: this.filePath, reason: describe5(
|
|
12056
|
+
t("import_trust.bad_json", { path: this.filePath, reason: describe5(err3) })
|
|
10454
12057
|
);
|
|
10455
12058
|
return;
|
|
10456
12059
|
}
|
|
@@ -10505,10 +12108,10 @@ var ImportTrustStore = class {
|
|
|
10505
12108
|
try {
|
|
10506
12109
|
writeFileSync(tmp, body2, { encoding: "utf-8", mode: 384 });
|
|
10507
12110
|
renameSync(tmp, this.filePath);
|
|
10508
|
-
} catch (
|
|
12111
|
+
} catch (err3) {
|
|
10509
12112
|
rmSync(tmp, { force: true });
|
|
10510
12113
|
throw new Error(
|
|
10511
|
-
t("import_trust.write_failed", { path: this.filePath, reason: describe5(
|
|
12114
|
+
t("import_trust.write_failed", { path: this.filePath, reason: describe5(err3) })
|
|
10512
12115
|
);
|
|
10513
12116
|
}
|
|
10514
12117
|
}
|
|
@@ -11152,8 +12755,8 @@ var BudgetStore = class {
|
|
|
11152
12755
|
throw new Error(t("budget.state_missing_sessions"));
|
|
11153
12756
|
}
|
|
11154
12757
|
return { version: 1, sessions };
|
|
11155
|
-
} catch (
|
|
11156
|
-
const reason9 =
|
|
12758
|
+
} catch (err3) {
|
|
12759
|
+
const reason9 = err3 instanceof Error ? err3.message : String(err3);
|
|
11157
12760
|
this.quarantine();
|
|
11158
12761
|
this.onWarn?.(t("budget.state_corrupt", { reason: reason9, path: this.path }));
|
|
11159
12762
|
return empty;
|
|
@@ -11169,10 +12772,10 @@ var BudgetStore = class {
|
|
|
11169
12772
|
try {
|
|
11170
12773
|
mkdirSync(dirname(this.path), { recursive: true });
|
|
11171
12774
|
writeFileSync(this.path, JSON.stringify(state, null, 2));
|
|
11172
|
-
} catch (
|
|
12775
|
+
} catch (err3) {
|
|
11173
12776
|
this.onWarn?.(
|
|
11174
12777
|
t("budget.state_write_failed", {
|
|
11175
|
-
message:
|
|
12778
|
+
message: err3 instanceof Error ? err3.message : String(err3)
|
|
11176
12779
|
})
|
|
11177
12780
|
);
|
|
11178
12781
|
}
|
|
@@ -11496,25 +13099,25 @@ var PROVIDER_NO_CREDENTIAL = 1001;
|
|
|
11496
13099
|
var PROVIDER_ABORTED = 1060;
|
|
11497
13100
|
var PROVIDER_CONTEXT_OVERFLOW = 1030;
|
|
11498
13101
|
var PROVIDER_BODY_TOO_LARGE = 1051;
|
|
11499
|
-
function isContextOverflow(
|
|
11500
|
-
if (
|
|
11501
|
-
return classifyProviderError(
|
|
13102
|
+
function isContextOverflow(err3) {
|
|
13103
|
+
if (err3 instanceof ProviderError) return err3.code === PROVIDER_CONTEXT_OVERFLOW;
|
|
13104
|
+
return classifyProviderError(err3).code === PROVIDER_CONTEXT_OVERFLOW;
|
|
11502
13105
|
}
|
|
11503
|
-
function isBodyTooLarge(
|
|
11504
|
-
if (
|
|
11505
|
-
return classifyProviderError(
|
|
13106
|
+
function isBodyTooLarge(err3) {
|
|
13107
|
+
if (err3 instanceof ProviderError) return err3.code === PROVIDER_BODY_TOO_LARGE;
|
|
13108
|
+
return classifyProviderError(err3).code === PROVIDER_BODY_TOO_LARGE;
|
|
11506
13109
|
}
|
|
11507
|
-
function isAbortError(
|
|
11508
|
-
for (let cur =
|
|
13110
|
+
function isAbortError(err3) {
|
|
13111
|
+
for (let cur = err3, depth = 0; cur && depth < 5; depth++) {
|
|
11509
13112
|
if (typeof cur !== "object") return false;
|
|
11510
13113
|
if (cur.name === "AbortError") return true;
|
|
11511
13114
|
cur = cur.cause;
|
|
11512
13115
|
}
|
|
11513
13116
|
return false;
|
|
11514
13117
|
}
|
|
11515
|
-
function causeChain(
|
|
13118
|
+
function causeChain(err3) {
|
|
11516
13119
|
const out = [];
|
|
11517
|
-
for (let cur =
|
|
13120
|
+
for (let cur = err3, depth = 0; cur && depth < 5; depth++) {
|
|
11518
13121
|
if (typeof cur !== "object") break;
|
|
11519
13122
|
const e = cur;
|
|
11520
13123
|
out.push({
|
|
@@ -11539,20 +13142,20 @@ var NETWORK_ERROR_CODES = /* @__PURE__ */ new Set([
|
|
|
11539
13142
|
"UND_ERR_RESPONSE_STATUS_CODE"
|
|
11540
13143
|
]);
|
|
11541
13144
|
var NETWORK_MESSAGE_RE = /timeout|timed.?out|etimedout|econnreset|enotfound|socket.?hang.?up|other.?side.?closed|terminated|network.?error|fetch.?failed/i;
|
|
11542
|
-
function describeProviderError(
|
|
11543
|
-
const chain = causeChain(
|
|
11544
|
-
const head = chain[0]?.message ?? (typeof
|
|
13145
|
+
function describeProviderError(err3) {
|
|
13146
|
+
const chain = causeChain(err3);
|
|
13147
|
+
const head = chain[0]?.message ?? (typeof err3 === "string" ? err3 : String(err3));
|
|
11545
13148
|
const root = [...chain].reverse().find((link) => link.message !== "" && link.message !== head)?.message;
|
|
11546
13149
|
if (!head.trim()) {
|
|
11547
13150
|
if (root) return root;
|
|
11548
|
-
const status = extractStatus(
|
|
13151
|
+
const status = extractStatus(err3);
|
|
11549
13152
|
return status === void 0 ? t("provider_route.no_detail") : t("provider_route.no_detail_status", { status });
|
|
11550
13153
|
}
|
|
11551
13154
|
return root ? t("provider_route.root_cause", { message: head, cause: root }) : head;
|
|
11552
13155
|
}
|
|
11553
|
-
function extractStatus(
|
|
11554
|
-
if (!
|
|
11555
|
-
const e =
|
|
13156
|
+
function extractStatus(err3) {
|
|
13157
|
+
if (!err3 || typeof err3 !== "object") return void 0;
|
|
13158
|
+
const e = err3;
|
|
11556
13159
|
for (const candidate of [e.statusCode, e.status, e.response?.status]) {
|
|
11557
13160
|
if (typeof candidate === "number" && candidate >= 100 && candidate < 600) return candidate;
|
|
11558
13161
|
}
|
|
@@ -11565,10 +13168,10 @@ function extractStatusFromMessage(msg) {
|
|
|
11565
13168
|
if (labelled?.[1]) return Number(labelled[1]);
|
|
11566
13169
|
return void 0;
|
|
11567
13170
|
}
|
|
11568
|
-
function classifyProviderError(
|
|
11569
|
-
const msg =
|
|
11570
|
-
const status = extractStatus(
|
|
11571
|
-
if (isAbortError(
|
|
13171
|
+
function classifyProviderError(err3) {
|
|
13172
|
+
const msg = err3 instanceof Error ? err3.message : String(err3);
|
|
13173
|
+
const status = extractStatus(err3);
|
|
13174
|
+
if (isAbortError(err3)) return { code: PROVIDER_ABORTED, recovery: "abort" };
|
|
11572
13175
|
if (/context.?length|context.?window|maximum.*token|token.?limit|too.?many.?tokens|prompt.*too.?long|reduce.*(length|tokens)/i.test(
|
|
11573
13176
|
msg
|
|
11574
13177
|
))
|
|
@@ -11597,7 +13200,7 @@ function classifyProviderError(err) {
|
|
|
11597
13200
|
if (code >= 500) return { code: 1020, recovery: "retry" };
|
|
11598
13201
|
if (code >= 400) return { code: 1050, recovery: "abort" };
|
|
11599
13202
|
}
|
|
11600
|
-
for (const link of causeChain(
|
|
13203
|
+
for (const link of causeChain(err3)) {
|
|
11601
13204
|
if (link.code && NETWORK_ERROR_CODES.has(link.code)) return { code: 1041, recovery: "retry" };
|
|
11602
13205
|
if (NETWORK_MESSAGE_RE.test(link.message)) return { code: 1041, recovery: "retry" };
|
|
11603
13206
|
}
|
|
@@ -12885,12 +14488,12 @@ var ToolExecutor = class {
|
|
|
12885
14488
|
truncateForModel(failureText(r), budgetOf2(et, depth, "failure"), "text")
|
|
12886
14489
|
)
|
|
12887
14490
|
});
|
|
12888
|
-
} catch (
|
|
12889
|
-
span.recordError(
|
|
14491
|
+
} catch (err3) {
|
|
14492
|
+
span.recordError(err3);
|
|
12890
14493
|
return finish({
|
|
12891
14494
|
...base2,
|
|
12892
14495
|
success: false,
|
|
12893
|
-
output: `\u5DE5\u5177\u6267\u884C\u5F02\u5E38: ${
|
|
14496
|
+
output: `\u5DE5\u5177\u6267\u884C\u5F02\u5E38: ${err3 instanceof Error ? err3.message : String(err3)}`
|
|
12894
14497
|
});
|
|
12895
14498
|
}
|
|
12896
14499
|
}
|
|
@@ -13300,6 +14903,7 @@ var AgentLoop = class {
|
|
|
13300
14903
|
async *runTurns(input, turns) {
|
|
13301
14904
|
const maxTurns = turnLimitOf(input.maxTurns ?? this.config.maxTurns);
|
|
13302
14905
|
this.stallDetector.reset();
|
|
14906
|
+
const pendingReceived = [];
|
|
13303
14907
|
const rawUserText = contentToText(input.userMessage, { imagesCarriedAsParts: true });
|
|
13304
14908
|
const images = imageParts(input.userMessage);
|
|
13305
14909
|
const inputGate = this.config.compliance?.checkInput(rawUserText);
|
|
@@ -13397,6 +15001,7 @@ var AgentLoop = class {
|
|
|
13397
15001
|
...breach ? { breach } : {}
|
|
13398
15002
|
});
|
|
13399
15003
|
this.hooks.fire("session:start", { sessionId: input.sessionId });
|
|
15004
|
+
this.config.team?.registerSession(input.sessionId);
|
|
13400
15005
|
const runSpan = this.telemetry.startSpan("agent_run", {
|
|
13401
15006
|
[GEN_AI.OPERATION_NAME]: "agent_run",
|
|
13402
15007
|
[GEN_AI.CONVERSATION_ID]: input.sessionId
|
|
@@ -13427,7 +15032,11 @@ var AgentLoop = class {
|
|
|
13427
15032
|
...history,
|
|
13428
15033
|
{ role: "user", content: userContent, ...userParts ? { parts: userParts } : {} }
|
|
13429
15034
|
];
|
|
13430
|
-
const taskNotice = new TaskNoticeTracker(
|
|
15035
|
+
const taskNotice = new TaskNoticeTracker(
|
|
15036
|
+
this.config.backgroundTasks,
|
|
15037
|
+
this.config.team,
|
|
15038
|
+
this.config.board
|
|
15039
|
+
);
|
|
13431
15040
|
let todoNudged = false;
|
|
13432
15041
|
let idleNudged = false;
|
|
13433
15042
|
let blankNudged = false;
|
|
@@ -13456,9 +15065,21 @@ var AgentLoop = class {
|
|
|
13456
15065
|
yield finish("budget-exceeded", stop.breach);
|
|
13457
15066
|
return;
|
|
13458
15067
|
}
|
|
13459
|
-
const notice2 = taskNotice.
|
|
13460
|
-
if (notice2) messages.push({ role: "user", content: notice2 });
|
|
13461
|
-
if (
|
|
15068
|
+
const notice2 = taskNotice.noticeDetailed(input.sessionId);
|
|
15069
|
+
if (notice2) messages.push({ role: "user", content: notice2.text });
|
|
15070
|
+
if (notice2 && notice2.agent.length > 0) {
|
|
15071
|
+
yield {
|
|
15072
|
+
type: "notice",
|
|
15073
|
+
code: "agent-message",
|
|
15074
|
+
text: [systemNote(AGENT_MESSAGE_NOTE_TITLE), ...notice2.agent].join("\n")
|
|
15075
|
+
};
|
|
15076
|
+
}
|
|
15077
|
+
if (turn > 1) {
|
|
15078
|
+
for await (const ev of this.drainSteer(input, messages)) {
|
|
15079
|
+
if (ev.type === "steer") pendingReceived.push(ev.text);
|
|
15080
|
+
yield ev;
|
|
15081
|
+
}
|
|
15082
|
+
}
|
|
13462
15083
|
this.hooks.fire("turn:before", {
|
|
13463
15084
|
sessionId: input.sessionId,
|
|
13464
15085
|
userMessage: transformed,
|
|
@@ -13584,9 +15205,9 @@ var AgentLoop = class {
|
|
|
13584
15205
|
}
|
|
13585
15206
|
llmSpan.setAttribute("epoch.finish_reason", result.finishReason);
|
|
13586
15207
|
break;
|
|
13587
|
-
} catch (
|
|
13588
|
-
llmSpan.recordError(
|
|
13589
|
-
if (isBodyTooLarge(
|
|
15208
|
+
} catch (err3) {
|
|
15209
|
+
llmSpan.recordError(err3);
|
|
15210
|
+
if (isBodyTooLarge(err3) && imagesRescue.offloaded === 0) {
|
|
13590
15211
|
const saved = this.tryOffloadForBodyLimit(messages);
|
|
13591
15212
|
if (saved) {
|
|
13592
15213
|
messages = saved.messages;
|
|
@@ -13602,8 +15223,8 @@ var AgentLoop = class {
|
|
|
13602
15223
|
}
|
|
13603
15224
|
}
|
|
13604
15225
|
const engine = this.config.contextEngine;
|
|
13605
|
-
const retriable = isContextOverflow(
|
|
13606
|
-
if (overflowRescued || !engine || !retriable) throw
|
|
15226
|
+
const retriable = isContextOverflow(err3) || isBodyTooLarge(err3);
|
|
15227
|
+
if (overflowRescued || !engine || !retriable) throw err3;
|
|
13607
15228
|
overflowRescued = true;
|
|
13608
15229
|
const rescued = await this.compressNow(messages, {
|
|
13609
15230
|
totalTokens: totalInput + totalOutput,
|
|
@@ -13616,7 +15237,7 @@ var AgentLoop = class {
|
|
|
13616
15237
|
runUsage
|
|
13617
15238
|
);
|
|
13618
15239
|
}
|
|
13619
|
-
if (!shrank(messages, rescued.messages)) throw
|
|
15240
|
+
if (!shrank(messages, rescued.messages)) throw err3;
|
|
13620
15241
|
messages = rescued.messages;
|
|
13621
15242
|
yield {
|
|
13622
15243
|
type: "notice",
|
|
@@ -13729,7 +15350,8 @@ var AgentLoop = class {
|
|
|
13729
15350
|
index: turn,
|
|
13730
15351
|
llmResponse: result.text,
|
|
13731
15352
|
toolCalls: [],
|
|
13732
|
-
duration: Date.now() - turnStart
|
|
15353
|
+
duration: Date.now() - turnStart,
|
|
15354
|
+
...pendingReceived.length > 0 ? { received: pendingReceived.splice(0) } : {}
|
|
13733
15355
|
});
|
|
13734
15356
|
yield { type: "turn-complete", turn };
|
|
13735
15357
|
const finalText = await this.hooks.transformResponse(result.text, input.sessionId);
|
|
@@ -13750,7 +15372,10 @@ ${finalText}` };
|
|
|
13750
15372
|
content: finalText || NO_OUTPUT_TEXT,
|
|
13751
15373
|
...result.reasoningText ? { reasoning: result.reasoningText } : {}
|
|
13752
15374
|
});
|
|
13753
|
-
|
|
15375
|
+
for await (const ev of this.drainSteer(input, messages)) {
|
|
15376
|
+
if (ev.type === "steer") pendingReceived.push(ev.text);
|
|
15377
|
+
yield ev;
|
|
15378
|
+
}
|
|
13754
15379
|
continue;
|
|
13755
15380
|
}
|
|
13756
15381
|
const wantContinue = await this.hooks.wantsContinue(
|
|
@@ -13898,7 +15523,8 @@ ${finalText}` };
|
|
|
13898
15523
|
args: e.args,
|
|
13899
15524
|
result: e.output
|
|
13900
15525
|
})),
|
|
13901
|
-
duration: Date.now() - turnStart
|
|
15526
|
+
duration: Date.now() - turnStart,
|
|
15527
|
+
...pendingReceived.length > 0 ? { received: pendingReceived.splice(0) } : {}
|
|
13902
15528
|
});
|
|
13903
15529
|
this.hooks.fire("turn:after", {
|
|
13904
15530
|
sessionId: input.sessionId,
|
|
@@ -13954,15 +15580,15 @@ ${finalText}` };
|
|
|
13954
15580
|
turns
|
|
13955
15581
|
});
|
|
13956
15582
|
yield finish("max-turns");
|
|
13957
|
-
} catch (
|
|
15583
|
+
} catch (err3) {
|
|
13958
15584
|
if (this.isAborted(input.signal)) {
|
|
13959
15585
|
await this.prompt.syncMemory(userText, lastText);
|
|
13960
15586
|
yield { type: "notice", code: "aborted", text: t("agent_run.aborted") };
|
|
13961
15587
|
yield finish("aborted");
|
|
13962
15588
|
return;
|
|
13963
15589
|
}
|
|
13964
|
-
const msg =
|
|
13965
|
-
runSpan.recordError(
|
|
15590
|
+
const msg = err3 instanceof Error ? err3.message : String(err3);
|
|
15591
|
+
runSpan.recordError(err3);
|
|
13966
15592
|
await this.prompt.syncMemory(userText, "");
|
|
13967
15593
|
const errorText = t("agent_run.error", { message: msg });
|
|
13968
15594
|
this.hooks.fire("turn:after", { sessionId: input.sessionId, response: errorText });
|
|
@@ -14174,10 +15800,10 @@ function loadModelEntries(homeDir) {
|
|
|
14174
15800
|
let raw;
|
|
14175
15801
|
try {
|
|
14176
15802
|
raw = JSON.parse(readFileSync(path, "utf-8"));
|
|
14177
|
-
} catch (
|
|
15803
|
+
} catch (err3) {
|
|
14178
15804
|
return {
|
|
14179
15805
|
entries: [],
|
|
14180
|
-
issues: [`${path}: ${
|
|
15806
|
+
issues: [`${path}: ${err3 instanceof Error ? err3.message : String(err3)}`]
|
|
14181
15807
|
};
|
|
14182
15808
|
}
|
|
14183
15809
|
const list = raw?.models;
|
|
@@ -14225,9 +15851,9 @@ function saveModelEntries(homeDir, entries2, hostLabel) {
|
|
|
14225
15851
|
try {
|
|
14226
15852
|
writeFileSync(tmp, body2, { encoding: "utf-8", mode: 384 });
|
|
14227
15853
|
renameSync(tmp, path);
|
|
14228
|
-
} catch (
|
|
15854
|
+
} catch (err3) {
|
|
14229
15855
|
rmSync(tmp, { force: true });
|
|
14230
|
-
throw
|
|
15856
|
+
throw err3;
|
|
14231
15857
|
}
|
|
14232
15858
|
}
|
|
14233
15859
|
var EntryRefSchema = z.string().refine((v) => parseModelRef(v) !== void 0, { message: "expected @<model-entry-id>" });
|
|
@@ -14511,8 +16137,8 @@ var SettingsFileError = class extends Error {
|
|
|
14511
16137
|
this.hint = hint;
|
|
14512
16138
|
}
|
|
14513
16139
|
};
|
|
14514
|
-
function describeJsonError(
|
|
14515
|
-
const message =
|
|
16140
|
+
function describeJsonError(err3, text) {
|
|
16141
|
+
const message = err3 instanceof Error ? err3.message.split("\n")[0] ?? "" : "";
|
|
14516
16142
|
if (!message) return t("config_load.json_unknown_error");
|
|
14517
16143
|
const at = /position (\d+)/.exec(message);
|
|
14518
16144
|
if (!at?.[1]) return message;
|
|
@@ -14529,8 +16155,8 @@ function readSettingsFile(path, schema, known, empty, issues, sanitize = (raw) =
|
|
|
14529
16155
|
let raw;
|
|
14530
16156
|
try {
|
|
14531
16157
|
raw = JSON.parse(text);
|
|
14532
|
-
} catch (
|
|
14533
|
-
const reason9 = describeJsonError(
|
|
16158
|
+
} catch (err3) {
|
|
16159
|
+
const reason9 = describeJsonError(err3, text);
|
|
14534
16160
|
issues.push({ path, message: t("config_load.json_invalid", { reason: reason9 }) });
|
|
14535
16161
|
return { failed: reason9 };
|
|
14536
16162
|
}
|
|
@@ -14968,13 +16594,13 @@ function readRawConfig(configPath2, issues) {
|
|
|
14968
16594
|
const text = readFileSync(configPath2, "utf-8");
|
|
14969
16595
|
if (text.trim() === "") return { kind: "ok", raw: {} };
|
|
14970
16596
|
return { kind: "ok", raw: load(text) ?? {} };
|
|
14971
|
-
} catch (
|
|
16597
|
+
} catch (err3) {
|
|
14972
16598
|
const backup = backupCorruptConfig(configPath2);
|
|
14973
16599
|
issues.push({
|
|
14974
16600
|
path: "(root)",
|
|
14975
16601
|
message: t("config_load.bad_yaml", {
|
|
14976
16602
|
path: configPath2,
|
|
14977
|
-
reason:
|
|
16603
|
+
reason: err3.message.split("\n")[0] ?? "",
|
|
14978
16604
|
backup: backup ? t("config_load.bad_yaml_backup", { path: backup }) : t("config_load.bad_yaml_no_backup")
|
|
14979
16605
|
})
|
|
14980
16606
|
});
|
|
@@ -15254,16 +16880,16 @@ async function runImageProbe(model) {
|
|
|
15254
16880
|
let withImage;
|
|
15255
16881
|
try {
|
|
15256
16882
|
withImage = await shoot(model, true);
|
|
15257
|
-
} catch (
|
|
15258
|
-
return { verdict: "no", detail:
|
|
16883
|
+
} catch (err3) {
|
|
16884
|
+
return { verdict: "no", detail: err3 instanceof Error ? err3.message : String(err3) };
|
|
15259
16885
|
}
|
|
15260
16886
|
let baseline;
|
|
15261
16887
|
try {
|
|
15262
16888
|
baseline = await shoot(model, false);
|
|
15263
|
-
} catch (
|
|
16889
|
+
} catch (err3) {
|
|
15264
16890
|
return {
|
|
15265
16891
|
verdict: "inconclusive",
|
|
15266
|
-
detail: `baseline failed: ${
|
|
16892
|
+
detail: `baseline failed: ${err3 instanceof Error ? err3.message : String(err3)}`
|
|
15267
16893
|
};
|
|
15268
16894
|
}
|
|
15269
16895
|
const shot = withImage.inputTokens;
|
|
@@ -15793,11 +17419,11 @@ var ProviderSdkMissingError = class extends Error {
|
|
|
15793
17419
|
async function createModelFactory(type, opts) {
|
|
15794
17420
|
try {
|
|
15795
17421
|
return await LOADERS[type](opts);
|
|
15796
|
-
} catch (
|
|
15797
|
-
if (isModuleNotFound(
|
|
15798
|
-
throw new ProviderSdkMissingError(type, PACKAGES[type],
|
|
17422
|
+
} catch (err3) {
|
|
17423
|
+
if (isModuleNotFound(err3)) {
|
|
17424
|
+
throw new ProviderSdkMissingError(type, PACKAGES[type], err3);
|
|
15799
17425
|
}
|
|
15800
|
-
throw
|
|
17426
|
+
throw err3;
|
|
15801
17427
|
}
|
|
15802
17428
|
}
|
|
15803
17429
|
async function createEntryFactory(entry, apiKey) {
|
|
@@ -15805,9 +17431,9 @@ async function createEntryFactory(entry, apiKey) {
|
|
|
15805
17431
|
const pkg = type === "openai-compatible" && entry.protocol === "anthropic-messages" ? "@ai-sdk/anthropic" : PACKAGES[type];
|
|
15806
17432
|
try {
|
|
15807
17433
|
return await loadEntry(entry, apiKey);
|
|
15808
|
-
} catch (
|
|
15809
|
-
if (isModuleNotFound(
|
|
15810
|
-
throw
|
|
17434
|
+
} catch (err3) {
|
|
17435
|
+
if (isModuleNotFound(err3)) throw new ProviderSdkMissingError(type, pkg, err3);
|
|
17436
|
+
throw err3;
|
|
15811
17437
|
}
|
|
15812
17438
|
}
|
|
15813
17439
|
async function loadEntry(entry, apiKey) {
|
|
@@ -15880,11 +17506,11 @@ var CARRIES_REASONING_BACK = {
|
|
|
15880
17506
|
function carriesReasoningBack(type) {
|
|
15881
17507
|
return CARRIES_REASONING_BACK[type];
|
|
15882
17508
|
}
|
|
15883
|
-
function isModuleNotFound(
|
|
15884
|
-
if (!
|
|
15885
|
-
const code =
|
|
17509
|
+
function isModuleNotFound(err3) {
|
|
17510
|
+
if (!err3 || typeof err3 !== "object") return false;
|
|
17511
|
+
const code = err3.code;
|
|
15886
17512
|
if (code === "ERR_MODULE_NOT_FOUND" || code === "MODULE_NOT_FOUND") return true;
|
|
15887
|
-
const msg =
|
|
17513
|
+
const msg = err3 instanceof Error ? err3.message : "";
|
|
15888
17514
|
return /Cannot find (module|package)|Failed to resolve/i.test(msg);
|
|
15889
17515
|
}
|
|
15890
17516
|
// src/provider/entry-route.ts
|
|
@@ -16180,8 +17806,8 @@ var ProviderRouter = class {
|
|
|
16180
17806
|
}
|
|
16181
17807
|
if (this.effort !== void 0) {
|
|
16182
17808
|
const state = this.getEffort();
|
|
16183
|
-
const
|
|
16184
|
-
if (!
|
|
17809
|
+
const ok4 = this.effort === "off" ? state.canTurnOff : state.levels.includes(this.effort);
|
|
17810
|
+
if (!ok4) this.effort = void 0;
|
|
16185
17811
|
}
|
|
16186
17812
|
}
|
|
16187
17813
|
refreshedSelection(sel) {
|
|
@@ -16211,9 +17837,9 @@ var ProviderRouter = class {
|
|
|
16211
17837
|
this.effort = void 0;
|
|
16212
17838
|
return true;
|
|
16213
17839
|
}
|
|
16214
|
-
const
|
|
16215
|
-
if (
|
|
16216
|
-
return
|
|
17840
|
+
const ok4 = choice === "off" ? state.canTurnOff : state.levels.includes(choice);
|
|
17841
|
+
if (ok4) this.effort = choice;
|
|
17842
|
+
return ok4;
|
|
16217
17843
|
}
|
|
16218
17844
|
reasoningFor(input, ct, entry) {
|
|
16219
17845
|
if (input.entry || entry !== this.selection.entry) return void 0;
|
|
@@ -16314,8 +17940,8 @@ var ProviderRouter = class {
|
|
|
16314
17940
|
let factory;
|
|
16315
17941
|
try {
|
|
16316
17942
|
factory = opts.entry ? await createEntryFactory(opts.entry, opts.apiKey || void 0) : await createModelFactory(route, opts);
|
|
16317
|
-
} catch (
|
|
16318
|
-
throw new ProviderError(
|
|
17943
|
+
} catch (err3) {
|
|
17944
|
+
throw new ProviderError(err3 instanceof Error ? err3.message : String(err3), 1005, false);
|
|
16319
17945
|
}
|
|
16320
17946
|
this.factories.set(route, factory);
|
|
16321
17947
|
return factory(modelId ?? this.selection.model);
|
|
@@ -16344,9 +17970,9 @@ var ProviderRouter = class {
|
|
|
16344
17970
|
const fb = this.fallbackEntry(sel.entry, /* @__PURE__ */ new Set([entryTried(sel.entry)]));
|
|
16345
17971
|
return fb && !this.failures.isAbandoned(this.routeOf(fb.provider, fb.entry)) ? fb : sel;
|
|
16346
17972
|
}
|
|
16347
|
-
async recover(
|
|
16348
|
-
const { code, recovery } = classifyProviderError(
|
|
16349
|
-
const message = describeProviderError(
|
|
17973
|
+
async recover(err3, state) {
|
|
17974
|
+
const { code, recovery } = classifyProviderError(err3);
|
|
17975
|
+
const message = describeProviderError(err3);
|
|
16350
17976
|
const stay = { kind: "continue", ct: state.ct, cm: state.cm, entry: state.entry };
|
|
16351
17977
|
if (code === PROVIDER_ABORTED) return { kind: "give-up", message, code };
|
|
16352
17978
|
if (recovery === "retry") {
|
|
@@ -16471,8 +18097,8 @@ var ProviderRouter = class {
|
|
|
16471
18097
|
...applied === void 0 ? {} : { responseFormatApplied: applied },
|
|
16472
18098
|
...warnings ? { warnings } : {}
|
|
16473
18099
|
};
|
|
16474
|
-
} catch (
|
|
16475
|
-
const plan = await this.recover(
|
|
18100
|
+
} catch (err3) {
|
|
18101
|
+
const plan = await this.recover(err3, state);
|
|
16476
18102
|
if (plan.kind === "give-up") throw new ProviderError(plan.message, plan.code, false);
|
|
16477
18103
|
state.ct = plan.ct;
|
|
16478
18104
|
state.cm = plan.cm;
|
|
@@ -16574,8 +18200,8 @@ var ProviderRouter = class {
|
|
|
16574
18200
|
...warnings ? { warnings } : {}
|
|
16575
18201
|
};
|
|
16576
18202
|
return;
|
|
16577
|
-
} catch (
|
|
16578
|
-
const cause = streamPartError ??
|
|
18203
|
+
} catch (err3) {
|
|
18204
|
+
const cause = streamPartError ?? err3;
|
|
16579
18205
|
if (emitted) {
|
|
16580
18206
|
yield { type: "error", error: describeProviderError(cause) };
|
|
16581
18207
|
return;
|
|
@@ -16909,9 +18535,9 @@ async function testModelEntry(entry, apiKey) {
|
|
|
16909
18535
|
abortSignal: AbortSignal.timeout(2e4)
|
|
16910
18536
|
});
|
|
16911
18537
|
return { code: "ok", models, latencyMs: elapsed() };
|
|
16912
|
-
} catch (
|
|
16913
|
-
const status = extractStatus(
|
|
16914
|
-
const detail = redact(describeProviderError(
|
|
18538
|
+
} catch (err3) {
|
|
18539
|
+
const status = extractStatus(err3);
|
|
18540
|
+
const detail = redact(describeProviderError(err3), apiKey);
|
|
16915
18541
|
return {
|
|
16916
18542
|
code: classify(status, detail),
|
|
16917
18543
|
models,
|
|
@@ -17179,9 +18805,9 @@ function commit(path, body2, createMode, value) {
|
|
|
17179
18805
|
try {
|
|
17180
18806
|
writeFileSync(tmp, body2, { encoding: "utf-8", mode });
|
|
17181
18807
|
renameSync(tmp, path);
|
|
17182
|
-
} catch (
|
|
18808
|
+
} catch (err3) {
|
|
17183
18809
|
rmSync(tmp, { force: true });
|
|
17184
|
-
throw
|
|
18810
|
+
throw err3;
|
|
17185
18811
|
}
|
|
17186
18812
|
} catch {
|
|
17187
18813
|
return { ok: false, reason: "io" };
|
|
@@ -17598,13 +19224,13 @@ function readRaw(path) {
|
|
|
17598
19224
|
let text;
|
|
17599
19225
|
try {
|
|
17600
19226
|
text = readFileSync(path, "utf-8");
|
|
17601
|
-
} catch (
|
|
17602
|
-
return { issue: reason5(
|
|
19227
|
+
} catch (err3) {
|
|
19228
|
+
return { issue: reason5(err3) };
|
|
17603
19229
|
}
|
|
17604
19230
|
try {
|
|
17605
19231
|
return { value: JSON.parse(text) };
|
|
17606
|
-
} catch (
|
|
17607
|
-
return { issue: reason5(
|
|
19232
|
+
} catch (err3) {
|
|
19233
|
+
return { issue: reason5(err3) };
|
|
17608
19234
|
}
|
|
17609
19235
|
}
|
|
17610
19236
|
function readVimMode(raw, issues) {
|
|
@@ -17687,8 +19313,8 @@ function supportsSequence(action) {
|
|
|
17687
19313
|
function warn(detail, code) {
|
|
17688
19314
|
return { module: MODULE2, status: "warn", detail, code };
|
|
17689
19315
|
}
|
|
17690
|
-
function reason5(
|
|
17691
|
-
return (
|
|
19316
|
+
function reason5(err3) {
|
|
19317
|
+
return (err3 instanceof Error ? err3.message : String(err3)).split("\n")[0] ?? "";
|
|
17692
19318
|
}
|
|
17693
19319
|
// src/memory/tokenize.ts
|
|
17694
19320
|
var CJK_RUN = /[-ヿ㐀-䶿一-鿿豈-가-]+/gu;
|
|
@@ -17732,7 +19358,7 @@ function buildSearchQuery(query) {
|
|
|
17732
19358
|
// src/memory/db.ts
|
|
17733
19359
|
var NS2 = "memory";
|
|
17734
19360
|
var FTS_SCHEMA_VERSION = 2;
|
|
17735
|
-
var
|
|
19361
|
+
var MIGRATIONS3 = [
|
|
17736
19362
|
{
|
|
17737
19363
|
id: "memory-baseline",
|
|
17738
19364
|
version: 1,
|
|
@@ -17774,10 +19400,10 @@ var MemoryDB = class {
|
|
|
17774
19400
|
db;
|
|
17775
19401
|
path;
|
|
17776
19402
|
nextPosition = { memory: 0, user: 0 };
|
|
17777
|
-
constructor(
|
|
17778
|
-
this.path =
|
|
19403
|
+
constructor(dbPath2) {
|
|
19404
|
+
this.path = dbPath2;
|
|
17779
19405
|
this.db = openDatabase(this.path);
|
|
17780
|
-
migrate(this.db, NS2,
|
|
19406
|
+
migrate(this.db, NS2, MIGRATIONS3);
|
|
17781
19407
|
this.migrateFts();
|
|
17782
19408
|
for (const target of ["memory", "user"]) {
|
|
17783
19409
|
const row = this.db.prepare(
|
|
@@ -18020,9 +19646,9 @@ function stripUndefined(obj) {
|
|
|
18020
19646
|
return Object.fromEntries(Object.entries(obj).filter(([, v]) => v !== void 0));
|
|
18021
19647
|
}
|
|
18022
19648
|
var MemoryManager = class {
|
|
18023
|
-
constructor(
|
|
19649
|
+
constructor(dbPath2, memDir, config, options = {}) {
|
|
18024
19650
|
this.options = options;
|
|
18025
|
-
const dp =
|
|
19651
|
+
const dp = dbPath2 ?? DB_PATH;
|
|
18026
19652
|
const md = memDir ?? MEM_DIR;
|
|
18027
19653
|
this.memDir = md;
|
|
18028
19654
|
mkdirSync(dirname(dp), { recursive: true });
|
|
@@ -18440,8 +20066,8 @@ var MemoryManager = class {
|
|
|
18440
20066
|
});
|
|
18441
20067
|
continue;
|
|
18442
20068
|
}
|
|
18443
|
-
const
|
|
18444
|
-
const summary = countCodePoints(
|
|
20069
|
+
const firstLine5 = (entry.content.split("\n")[0] ?? "").trim();
|
|
20070
|
+
const summary = countCodePoints(firstLine5) > INDEX_SUMMARY_CHARS ? `${headCodePoints(firstLine5, INDEX_SUMMARY_CHARS)}\u2026` : firstLine5;
|
|
18445
20071
|
out.push({ id, target, summary, charLength: entry.content.length });
|
|
18446
20072
|
}
|
|
18447
20073
|
return out;
|
|
@@ -18768,7 +20394,7 @@ function nonEmpty(items) {
|
|
|
18768
20394
|
function isRecord4(v) {
|
|
18769
20395
|
return typeof v === "object" && v !== null;
|
|
18770
20396
|
}
|
|
18771
|
-
function
|
|
20397
|
+
function str5(v) {
|
|
18772
20398
|
return typeof v === "string" && v.length > 0 ? v : void 0;
|
|
18773
20399
|
}
|
|
18774
20400
|
function isSessionOmitReason(value) {
|
|
@@ -18780,8 +20406,8 @@ function parseToolCalls(json) {
|
|
|
18780
20406
|
const calls = [];
|
|
18781
20407
|
for (const item of raw) {
|
|
18782
20408
|
if (!isRecord4(item)) continue;
|
|
18783
|
-
const toolCallId =
|
|
18784
|
-
const toolName =
|
|
20409
|
+
const toolCallId = str5(item["toolCallId"]) ?? str5(item["id"]);
|
|
20410
|
+
const toolName = str5(item["toolName"]) ?? str5(item["name"]);
|
|
18785
20411
|
if (!toolCallId || !toolName) continue;
|
|
18786
20412
|
const input = item["input"] ?? item["args"];
|
|
18787
20413
|
calls.push({ toolCallId, toolName, input: isRecord4(input) ? input : {} });
|
|
@@ -18796,10 +20422,10 @@ function parseArtifacts(raw) {
|
|
|
18796
20422
|
const kind = item["kind"];
|
|
18797
20423
|
out.push({
|
|
18798
20424
|
kind: kind === "image" || kind === "audio" || kind === "file" ? kind : "file",
|
|
18799
|
-
mediaType:
|
|
20425
|
+
mediaType: str5(item["mediaType"]) ?? "application/octet-stream",
|
|
18800
20426
|
summary: typeof item["summary"] === "string" ? item["summary"] : "",
|
|
18801
20427
|
bytes: typeof item["bytes"] === "number" ? item["bytes"] : 0,
|
|
18802
|
-
...
|
|
20428
|
+
...str5(item["path"]) ? { path: item["path"] } : {},
|
|
18803
20429
|
...typeof item["width"] === "number" ? { width: item["width"] } : {},
|
|
18804
20430
|
...typeof item["height"] === "number" ? { height: item["height"] } : {},
|
|
18805
20431
|
...typeof item["estimatedTokens"] === "number" ? { estimatedTokens: item["estimatedTokens"] } : {}
|
|
@@ -18813,8 +20439,8 @@ function parseToolResults(json) {
|
|
|
18813
20439
|
const results = [];
|
|
18814
20440
|
for (const item of raw) {
|
|
18815
20441
|
if (!isRecord4(item)) continue;
|
|
18816
|
-
const toolCallId =
|
|
18817
|
-
const toolName =
|
|
20442
|
+
const toolCallId = str5(item["toolCallId"]);
|
|
20443
|
+
const toolName = str5(item["toolName"]);
|
|
18818
20444
|
if (!toolCallId || !toolName) continue;
|
|
18819
20445
|
const artifacts = parseArtifacts(item["artifacts"]);
|
|
18820
20446
|
results.push({
|
|
@@ -18826,24 +20452,41 @@ function parseToolResults(json) {
|
|
|
18826
20452
|
}
|
|
18827
20453
|
return nonEmpty(results);
|
|
18828
20454
|
}
|
|
20455
|
+
function parseDiffs(json) {
|
|
20456
|
+
const raw = parseArray(json);
|
|
20457
|
+
if (!raw) return void 0;
|
|
20458
|
+
const diffs = [];
|
|
20459
|
+
for (const item of raw) {
|
|
20460
|
+
if (!isRecord4(item)) continue;
|
|
20461
|
+
const filePath = str5(item["filePath"]);
|
|
20462
|
+
if (!filePath) continue;
|
|
20463
|
+
diffs.push({
|
|
20464
|
+
filePath,
|
|
20465
|
+
...typeof item["oldContent"] === "string" ? { oldContent: item["oldContent"] } : {},
|
|
20466
|
+
...typeof item["newContent"] === "string" ? { newContent: item["newContent"] } : {},
|
|
20467
|
+
...item["omitted"] === "too-large" ? { omitted: "too-large" } : {}
|
|
20468
|
+
});
|
|
20469
|
+
}
|
|
20470
|
+
return nonEmpty(diffs);
|
|
20471
|
+
}
|
|
18829
20472
|
function parseParts(json) {
|
|
18830
20473
|
const raw = parseArray(json);
|
|
18831
20474
|
if (!raw) return void 0;
|
|
18832
20475
|
const parts = [];
|
|
18833
20476
|
for (const item of raw) {
|
|
18834
20477
|
if (!isRecord4(item)) continue;
|
|
18835
|
-
const mediaType =
|
|
20478
|
+
const mediaType = str5(item["mediaType"]);
|
|
18836
20479
|
const media = mediaType ? { mediaType } : {};
|
|
18837
20480
|
if (item["type"] === "text") {
|
|
18838
20481
|
if (typeof item["text"] === "string") parts.push({ type: "text", text: item["text"] });
|
|
18839
20482
|
continue;
|
|
18840
20483
|
}
|
|
18841
20484
|
if (item["type"] === "session") {
|
|
18842
|
-
const ref =
|
|
20485
|
+
const ref = str5(item["ref"]);
|
|
18843
20486
|
if (!ref) continue;
|
|
18844
|
-
const sessionId =
|
|
18845
|
-
const title =
|
|
18846
|
-
const omitted =
|
|
20487
|
+
const sessionId = str5(item["sessionId"]);
|
|
20488
|
+
const title = str5(item["title"]);
|
|
20489
|
+
const omitted = str5(item["omitted"]);
|
|
18847
20490
|
parts.push({
|
|
18848
20491
|
type: "session",
|
|
18849
20492
|
ref,
|
|
@@ -18856,9 +20499,9 @@ function parseParts(json) {
|
|
|
18856
20499
|
continue;
|
|
18857
20500
|
}
|
|
18858
20501
|
if (item["type"] === "file") {
|
|
18859
|
-
const filePath =
|
|
20502
|
+
const filePath = str5(item["path"]);
|
|
18860
20503
|
if (!filePath) continue;
|
|
18861
|
-
const fileOmitted =
|
|
20504
|
+
const fileOmitted = str5(item["omitted"]);
|
|
18862
20505
|
parts.push({
|
|
18863
20506
|
type: "file",
|
|
18864
20507
|
path: filePath,
|
|
@@ -18868,8 +20511,8 @@ function parseParts(json) {
|
|
|
18868
20511
|
continue;
|
|
18869
20512
|
}
|
|
18870
20513
|
if (item["type"] !== "image") continue;
|
|
18871
|
-
const path =
|
|
18872
|
-
const url =
|
|
20514
|
+
const path = str5(item["path"]);
|
|
20515
|
+
const url = str5(item["url"]);
|
|
18873
20516
|
if (path) parts.push({ type: "image", path, ...media });
|
|
18874
20517
|
else if (url) parts.push({ type: "image", url, ...media });
|
|
18875
20518
|
}
|
|
@@ -18916,10 +20559,10 @@ function parseTurnFacts(json) {
|
|
|
18916
20559
|
const toolCalls = num2(raw["toolCalls"]);
|
|
18917
20560
|
if (toolCalls === void 0) return void 0;
|
|
18918
20561
|
const usage = parseUsage(raw["usage"]);
|
|
18919
|
-
const model =
|
|
18920
|
-
const requestedModel =
|
|
20562
|
+
const model = str5(raw["model"]);
|
|
20563
|
+
const requestedModel = str5(raw["requestedModel"]);
|
|
18921
20564
|
const durationMs = num2(raw["durationMs"]);
|
|
18922
|
-
const error =
|
|
20565
|
+
const error = str5(raw["error"])?.trim() || void 0;
|
|
18923
20566
|
return {
|
|
18924
20567
|
toolCalls,
|
|
18925
20568
|
...usage ? { usage } : {},
|
|
@@ -18941,10 +20584,10 @@ function parseUserCommand(json) {
|
|
|
18941
20584
|
return void 0;
|
|
18942
20585
|
}
|
|
18943
20586
|
if (!isRecord4(raw)) return void 0;
|
|
18944
|
-
const name =
|
|
20587
|
+
const name = str5(raw["name"]);
|
|
18945
20588
|
if (!name) return void 0;
|
|
18946
|
-
const displayName =
|
|
18947
|
-
const args =
|
|
20589
|
+
const displayName = str5(raw["displayName"]);
|
|
20590
|
+
const args = str5(raw["args"]);
|
|
18948
20591
|
return {
|
|
18949
20592
|
name,
|
|
18950
20593
|
...displayName ? { displayName } : {},
|
|
@@ -19269,13 +20912,21 @@ var FTS_EXTERNAL_MIGRATIONS = [
|
|
|
19269
20912
|
up: (db) => {
|
|
19270
20913
|
db.exec(`ALTER TABLE messages ADD COLUMN command TEXT`);
|
|
19271
20914
|
}
|
|
20915
|
+
},
|
|
20916
|
+
{
|
|
20917
|
+
id: "messages-diffs",
|
|
20918
|
+
version: 17,
|
|
20919
|
+
description: "\u6D88\u606F\u8868\u52A0 diffs \u4E00\u5217\uFF08\u8865\u4E01\u9884\u89C8\u843D\u76D8\uFF0C2026-10-30\uFF09",
|
|
20920
|
+
up: (db) => {
|
|
20921
|
+
db.exec(`ALTER TABLE messages ADD COLUMN diffs TEXT`);
|
|
20922
|
+
}
|
|
19272
20923
|
}
|
|
19273
20924
|
];
|
|
19274
20925
|
var SessionDB = class {
|
|
19275
20926
|
db;
|
|
19276
20927
|
path;
|
|
19277
|
-
constructor(
|
|
19278
|
-
this.path =
|
|
20928
|
+
constructor(dbPath2) {
|
|
20929
|
+
this.path = dbPath2 ?? dbPath();
|
|
19279
20930
|
this.db = openDatabase(this.path);
|
|
19280
20931
|
migrate(this.db, NS3, SESSION_MIGRATIONS);
|
|
19281
20932
|
this.migrateFtsIndex();
|
|
@@ -19283,10 +20934,10 @@ var SessionDB = class {
|
|
|
19283
20934
|
migrateFtsIndex() {
|
|
19284
20935
|
try {
|
|
19285
20936
|
migrate(this.db, NS3, FTS_EXTERNAL_MIGRATIONS);
|
|
19286
|
-
} catch (
|
|
20937
|
+
} catch (err3) {
|
|
19287
20938
|
log2.warn(
|
|
19288
20939
|
"FTS index rebuild (v8) failed; keeping the legacy schema for now (content stored three times, ~36% larger). Will retry on next start.",
|
|
19289
|
-
{ error:
|
|
20940
|
+
{ error: err3 instanceof Error ? err3.message : String(err3) }
|
|
19290
20941
|
);
|
|
19291
20942
|
}
|
|
19292
20943
|
}
|
|
@@ -19466,8 +21117,8 @@ var SessionDB = class {
|
|
|
19466
21117
|
insertMessage(msg) {
|
|
19467
21118
|
const info = this.db.prepare(
|
|
19468
21119
|
`
|
|
19469
|
-
INSERT INTO messages (session_id, role, content, tool_call_id, tool_calls, tool_results, parts, command, tool_name, timestamp, token_count, finish_reason, reasoning, turn_facts, active, compacted, observed)
|
|
19470
|
-
VALUES (@sessionId, @role, @content, @toolCallId, @toolCalls, @toolResults, @parts, @command, @toolName, @timestamp, @tokenCount, @finishReason, @reasoning, @turnFacts, 1, 0, 0)
|
|
21120
|
+
INSERT INTO messages (session_id, role, content, tool_call_id, tool_calls, tool_results, parts, command, tool_name, timestamp, token_count, finish_reason, reasoning, diffs, turn_facts, active, compacted, observed)
|
|
21121
|
+
VALUES (@sessionId, @role, @content, @toolCallId, @toolCalls, @toolResults, @parts, @command, @toolName, @timestamp, @tokenCount, @finishReason, @reasoning, @diffs, @turnFacts, 1, 0, 0)
|
|
19471
21122
|
`
|
|
19472
21123
|
).run({
|
|
19473
21124
|
...msg,
|
|
@@ -19480,6 +21131,7 @@ var SessionDB = class {
|
|
|
19480
21131
|
tokenCount: msg.tokenCount ?? null,
|
|
19481
21132
|
finishReason: msg.finishReason ?? null,
|
|
19482
21133
|
reasoning: msg.reasoning ?? null,
|
|
21134
|
+
diffs: encodeColumn(msg.diffs),
|
|
19483
21135
|
turnFacts: encodeTurnFacts(msg.turnFacts)
|
|
19484
21136
|
});
|
|
19485
21137
|
const toolCalls = msg.toolCalls?.length ?? 0;
|
|
@@ -19729,8 +21381,8 @@ var SessionDB = class {
|
|
|
19729
21381
|
forkMessages(fromSessionId, toSessionId, upToIndex) {
|
|
19730
21382
|
const messages = this.db.prepare("SELECT * FROM messages WHERE session_id = ? AND id <= ? ORDER BY timestamp ASC").all(fromSessionId, upToIndex);
|
|
19731
21383
|
const stmt = this.db.prepare(`
|
|
19732
|
-
INSERT INTO messages (session_id, role, content, tool_call_id, tool_calls, tool_results, parts, command, tool_name, timestamp, token_count, finish_reason, reasoning, turn_facts, active, compacted, observed)
|
|
19733
|
-
VALUES (@sessionId, @role, @content, @toolCallId, @toolCalls, @toolResults, @parts, @command, @toolName, @timestamp, @tokenCount, @finishReason, @reasoning, @turnFacts, @active, @compacted, @observed)
|
|
21384
|
+
INSERT INTO messages (session_id, role, content, tool_call_id, tool_calls, tool_results, parts, command, tool_name, timestamp, token_count, finish_reason, reasoning, diffs, turn_facts, active, compacted, observed)
|
|
21385
|
+
VALUES (@sessionId, @role, @content, @toolCallId, @toolCalls, @toolResults, @parts, @command, @toolName, @timestamp, @tokenCount, @finishReason, @reasoning, @diffs, @turnFacts, @active, @compacted, @observed)
|
|
19734
21386
|
`);
|
|
19735
21387
|
for (const m of messages) {
|
|
19736
21388
|
const { id: _id, ...rest } = m;
|
|
@@ -19748,6 +21400,7 @@ var SessionDB = class {
|
|
|
19748
21400
|
tokenCount: rest["token_count"] ?? null,
|
|
19749
21401
|
finishReason: rest["finish_reason"] ?? null,
|
|
19750
21402
|
reasoning: rest["reasoning"] ?? null,
|
|
21403
|
+
diffs: rest["diffs"] ?? null,
|
|
19751
21404
|
turnFacts: rest["turn_facts"] ?? null,
|
|
19752
21405
|
active: rest["active"] ?? 1,
|
|
19753
21406
|
compacted: rest["compacted"] ?? 0,
|
|
@@ -19831,6 +21484,7 @@ var SessionDB = class {
|
|
|
19831
21484
|
tokenCount: row["token_count"],
|
|
19832
21485
|
finishReason: row["finish_reason"],
|
|
19833
21486
|
reasoning: row["reasoning"],
|
|
21487
|
+
diffs: parseDiffs(row["diffs"]),
|
|
19834
21488
|
active: row["active"] === 1,
|
|
19835
21489
|
compacted: row["compacted"] === 1,
|
|
19836
21490
|
observed: row["observed"] === 1
|
|
@@ -19865,8 +21519,8 @@ function integrityOf(db, table, compareContent = false) {
|
|
|
19865
21519
|
db.prepare(`INSERT INTO ${table}(${table}) VALUES('integrity-check')`).run();
|
|
19866
21520
|
}
|
|
19867
21521
|
return null;
|
|
19868
|
-
} catch (
|
|
19869
|
-
return
|
|
21522
|
+
} catch (err3) {
|
|
21523
|
+
return err3 instanceof Error ? err3.message : String(err3);
|
|
19870
21524
|
}
|
|
19871
21525
|
}
|
|
19872
21526
|
function indexBytesOf(db) {
|
|
@@ -19942,8 +21596,8 @@ function reclaimFtsSpace(db, vacuum = true) {
|
|
|
19942
21596
|
if (vacuum) {
|
|
19943
21597
|
try {
|
|
19944
21598
|
db.exec("VACUUM");
|
|
19945
|
-
} catch (
|
|
19946
|
-
vacuumError =
|
|
21599
|
+
} catch (err3) {
|
|
21600
|
+
vacuumError = err3 instanceof Error ? err3.message : String(err3);
|
|
19947
21601
|
}
|
|
19948
21602
|
}
|
|
19949
21603
|
const vacuumed = vacuum && vacuumError === null;
|
|
@@ -20153,8 +21807,8 @@ var SessionManager = class {
|
|
|
20153
21807
|
queries;
|
|
20154
21808
|
goals;
|
|
20155
21809
|
references;
|
|
20156
|
-
constructor(
|
|
20157
|
-
this.db = new SessionDB(
|
|
21810
|
+
constructor(dbPath2) {
|
|
21811
|
+
this.db = new SessionDB(dbPath2);
|
|
20158
21812
|
this.queries = new SessionQueries(this.db.db);
|
|
20159
21813
|
this.goals = new GoalStore(this.db.db);
|
|
20160
21814
|
this.references = new SessionReferences(this.db.db);
|
|
@@ -20286,12 +21940,12 @@ var SessionManager = class {
|
|
|
20286
21940
|
...input.todos === void 0 ? {} : { todoIds: todos.map((t83) => t83.id) },
|
|
20287
21941
|
...goal === void 0 ? {} : { goalId: goal.id }
|
|
20288
21942
|
};
|
|
20289
|
-
} catch (
|
|
21943
|
+
} catch (err3) {
|
|
20290
21944
|
return {
|
|
20291
21945
|
ok: false,
|
|
20292
21946
|
id,
|
|
20293
21947
|
reason: "failed",
|
|
20294
|
-
...
|
|
21948
|
+
...err3 instanceof Error ? { detail: err3.name } : {}
|
|
20295
21949
|
};
|
|
20296
21950
|
}
|
|
20297
21951
|
}
|
|
@@ -20869,8 +22523,8 @@ function inspect(input, resolved, root, accepted) {
|
|
|
20869
22523
|
}
|
|
20870
22524
|
var MAX_RECENT_WORKSPACES = 20;
|
|
20871
22525
|
var FILE_VERSION2 = 1;
|
|
20872
|
-
function describe7(
|
|
20873
|
-
return
|
|
22526
|
+
function describe7(err3) {
|
|
22527
|
+
return err3 instanceof Error ? err3.message : String(err3);
|
|
20874
22528
|
}
|
|
20875
22529
|
var RecentWorkspaces = class {
|
|
20876
22530
|
constructor(filePath = workspacesPath()) {
|
|
@@ -20907,9 +22561,9 @@ var RecentWorkspaces = class {
|
|
|
20907
22561
|
let parsed;
|
|
20908
22562
|
try {
|
|
20909
22563
|
parsed = JSON.parse(readFileSync(this.filePath, "utf-8"));
|
|
20910
|
-
} catch (
|
|
22564
|
+
} catch (err3) {
|
|
20911
22565
|
this.loadErrors.push(
|
|
20912
|
-
(lang) => t("workspace.recent_unreadable", { path: this.filePath, reason: describe7(
|
|
22566
|
+
(lang) => t("workspace.recent_unreadable", { path: this.filePath, reason: describe7(err3) }, lang)
|
|
20913
22567
|
);
|
|
20914
22568
|
return;
|
|
20915
22569
|
}
|
|
@@ -20959,10 +22613,10 @@ var RecentWorkspaces = class {
|
|
|
20959
22613
|
mkdirSync(dirname(this.filePath), { recursive: true });
|
|
20960
22614
|
writeFileSync(tmp, body2, { encoding: "utf-8", mode: 384 });
|
|
20961
22615
|
renameSync(tmp, this.filePath);
|
|
20962
|
-
} catch (
|
|
22616
|
+
} catch (err3) {
|
|
20963
22617
|
rmSync(tmp, { force: true });
|
|
20964
22618
|
this.writeErrors.push(
|
|
20965
|
-
(lang) => t("workspace.recent_write_failed", { path: this.filePath, reason: describe7(
|
|
22619
|
+
(lang) => t("workspace.recent_write_failed", { path: this.filePath, reason: describe7(err3) }, lang)
|
|
20966
22620
|
);
|
|
20967
22621
|
}
|
|
20968
22622
|
}
|
|
@@ -20974,8 +22628,8 @@ function isRecentWorkspace(value) {
|
|
|
20974
22628
|
}
|
|
20975
22629
|
var MAX_LAST_OPEN_SESSIONS = 20;
|
|
20976
22630
|
var FILE_VERSION3 = 1;
|
|
20977
|
-
function describe8(
|
|
20978
|
-
return
|
|
22631
|
+
function describe8(err3) {
|
|
22632
|
+
return err3 instanceof Error ? err3.message : String(err3);
|
|
20979
22633
|
}
|
|
20980
22634
|
var LastOpenSessions = class {
|
|
20981
22635
|
constructor(filePath = lastSessionsPath()) {
|
|
@@ -21011,9 +22665,9 @@ var LastOpenSessions = class {
|
|
|
21011
22665
|
let parsed;
|
|
21012
22666
|
try {
|
|
21013
22667
|
parsed = JSON.parse(readFileSync(this.filePath, "utf-8"));
|
|
21014
|
-
} catch (
|
|
22668
|
+
} catch (err3) {
|
|
21015
22669
|
this.loadErrors.push(
|
|
21016
|
-
(lang) => t("last_session.unreadable", { path: this.filePath, reason: describe8(
|
|
22670
|
+
(lang) => t("last_session.unreadable", { path: this.filePath, reason: describe8(err3) }, lang)
|
|
21017
22671
|
);
|
|
21018
22672
|
return;
|
|
21019
22673
|
}
|
|
@@ -21037,10 +22691,10 @@ var LastOpenSessions = class {
|
|
|
21037
22691
|
mkdirSync(dirname(this.filePath), { recursive: true });
|
|
21038
22692
|
writeFileSync(tmp, body2, { encoding: "utf-8", mode: 384 });
|
|
21039
22693
|
renameSync(tmp, this.filePath);
|
|
21040
|
-
} catch (
|
|
22694
|
+
} catch (err3) {
|
|
21041
22695
|
rmSync(tmp, { force: true });
|
|
21042
22696
|
this.writeErrors.push(
|
|
21043
|
-
(lang) => t("last_session.write_failed", { path: this.filePath, reason: describe8(
|
|
22697
|
+
(lang) => t("last_session.write_failed", { path: this.filePath, reason: describe8(err3) }, lang)
|
|
21044
22698
|
);
|
|
21045
22699
|
}
|
|
21046
22700
|
}
|
|
@@ -21053,8 +22707,8 @@ function isLastOpenSession(value) {
|
|
|
21053
22707
|
var isWidthShaped = (value) => typeof value === "number" && Number.isInteger(value) && value > 0;
|
|
21054
22708
|
var FILE_VERSION4 = 2;
|
|
21055
22709
|
var isPlainObject2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
21056
|
-
function describe9(
|
|
21057
|
-
return
|
|
22710
|
+
function describe9(err3) {
|
|
22711
|
+
return err3 instanceof Error ? err3.message : String(err3);
|
|
21058
22712
|
}
|
|
21059
22713
|
var AppearanceStore = class {
|
|
21060
22714
|
constructor(filePath = appearancePath()) {
|
|
@@ -21109,9 +22763,9 @@ var AppearanceStore = class {
|
|
|
21109
22763
|
this.prefs = {};
|
|
21110
22764
|
try {
|
|
21111
22765
|
rmSync(this.filePath, { force: true });
|
|
21112
|
-
} catch (
|
|
22766
|
+
} catch (err3) {
|
|
21113
22767
|
this.writeErrors.push(
|
|
21114
|
-
(lang) => t("appearance.write_failed", { path: this.filePath, reason: describe9(
|
|
22768
|
+
(lang) => t("appearance.write_failed", { path: this.filePath, reason: describe9(err3) }, lang)
|
|
21115
22769
|
);
|
|
21116
22770
|
}
|
|
21117
22771
|
}
|
|
@@ -21121,9 +22775,9 @@ var AppearanceStore = class {
|
|
|
21121
22775
|
let parsed;
|
|
21122
22776
|
try {
|
|
21123
22777
|
parsed = JSON.parse(readFileSync(this.filePath, "utf-8"));
|
|
21124
|
-
} catch (
|
|
22778
|
+
} catch (err3) {
|
|
21125
22779
|
this.loadErrors.push(
|
|
21126
|
-
(lang) => t("appearance.unreadable", { path: this.filePath, reason: describe9(
|
|
22780
|
+
(lang) => t("appearance.unreadable", { path: this.filePath, reason: describe9(err3) }, lang)
|
|
21127
22781
|
);
|
|
21128
22782
|
return;
|
|
21129
22783
|
}
|
|
@@ -21172,10 +22826,10 @@ var AppearanceStore = class {
|
|
|
21172
22826
|
mkdirSync(dirname(this.filePath), { recursive: true });
|
|
21173
22827
|
writeFileSync(tmp, body2, { encoding: "utf-8", mode: 384 });
|
|
21174
22828
|
renameSync(tmp, this.filePath);
|
|
21175
|
-
} catch (
|
|
22829
|
+
} catch (err3) {
|
|
21176
22830
|
rmSync(tmp, { force: true });
|
|
21177
22831
|
this.writeErrors.push(
|
|
21178
|
-
(lang) => t("appearance.write_failed", { path: this.filePath, reason: describe9(
|
|
22832
|
+
(lang) => t("appearance.write_failed", { path: this.filePath, reason: describe9(err3) }, lang)
|
|
21179
22833
|
);
|
|
21180
22834
|
}
|
|
21181
22835
|
}
|
|
@@ -21931,7 +23585,7 @@ function suggestRuleFromApproval(request) {
|
|
|
21931
23585
|
// src/schedule/store.ts
|
|
21932
23586
|
init_trigger();
|
|
21933
23587
|
var NS4 = "schedule";
|
|
21934
|
-
var
|
|
23588
|
+
var MIGRATIONS4 = [
|
|
21935
23589
|
{
|
|
21936
23590
|
id: "schedule-baseline",
|
|
21937
23591
|
version: 1,
|
|
@@ -22018,10 +23672,10 @@ var MIGRATIONS3 = [
|
|
|
22018
23672
|
var ScheduleStore = class {
|
|
22019
23673
|
db;
|
|
22020
23674
|
path;
|
|
22021
|
-
constructor(
|
|
22022
|
-
this.path =
|
|
23675
|
+
constructor(dbPath2) {
|
|
23676
|
+
this.path = dbPath2;
|
|
22023
23677
|
this.db = openDatabase(this.path);
|
|
22024
|
-
migrate(this.db, NS4,
|
|
23678
|
+
migrate(this.db, NS4, MIGRATIONS4);
|
|
22025
23679
|
}
|
|
22026
23680
|
get connection() {
|
|
22027
23681
|
return this.db;
|
|
@@ -22399,8 +24053,8 @@ function pidAlive(pid) {
|
|
|
22399
24053
|
try {
|
|
22400
24054
|
process.kill(pid, 0);
|
|
22401
24055
|
return true;
|
|
22402
|
-
} catch (
|
|
22403
|
-
return
|
|
24056
|
+
} catch (err3) {
|
|
24057
|
+
return err3.code === "EPERM";
|
|
22404
24058
|
}
|
|
22405
24059
|
}
|
|
22406
24060
|
function acquireScheduleLock(db, scheduleId, clock2 = Date.now) {
|
|
@@ -22430,8 +24084,8 @@ function acquireScheduleLock(db, scheduleId, clock2 = Date.now) {
|
|
|
22430
24084
|
db.prepare(
|
|
22431
24085
|
"UPDATE schedule_locks SET heartbeat_at = ? WHERE schedule_id = ? AND pid = ? AND host = ?"
|
|
22432
24086
|
).run(clock2(), scheduleId, pid, host);
|
|
22433
|
-
} catch (
|
|
22434
|
-
log4.debug("lock heartbeat write failed", { scheduleId, err: String(
|
|
24087
|
+
} catch (err3) {
|
|
24088
|
+
log4.debug("lock heartbeat write failed", { scheduleId, err: String(err3) });
|
|
22435
24089
|
}
|
|
22436
24090
|
}, LOCK_HEARTBEAT_MS);
|
|
22437
24091
|
beat.unref?.();
|
|
@@ -22447,8 +24101,8 @@ function acquireScheduleLock(db, scheduleId, clock2 = Date.now) {
|
|
|
22447
24101
|
db.prepare(
|
|
22448
24102
|
"DELETE FROM schedule_locks WHERE schedule_id = ? AND pid = ? AND host = ?"
|
|
22449
24103
|
).run(scheduleId, pid, host);
|
|
22450
|
-
} catch (
|
|
22451
|
-
log4.debug("lock release failed", { scheduleId, err: String(
|
|
24104
|
+
} catch (err3) {
|
|
24105
|
+
log4.debug("lock release failed", { scheduleId, err: String(err3) });
|
|
22452
24106
|
}
|
|
22453
24107
|
}
|
|
22454
24108
|
}
|
|
@@ -22878,10 +24532,10 @@ function loadPolicyRules(dir) {
|
|
|
22878
24532
|
let files;
|
|
22879
24533
|
try {
|
|
22880
24534
|
files = readdirSync(dir).filter((f) => f.endsWith(".toml"));
|
|
22881
|
-
} catch (
|
|
24535
|
+
} catch (err3) {
|
|
22882
24536
|
return {
|
|
22883
24537
|
rules: [],
|
|
22884
|
-
issues: [{ path: dir, message: t("policy_load.dir_read_failed", { reason: reason6(
|
|
24538
|
+
issues: [{ path: dir, message: t("policy_load.dir_read_failed", { reason: reason6(err3) }) }]
|
|
22885
24539
|
};
|
|
22886
24540
|
}
|
|
22887
24541
|
const rules = [];
|
|
@@ -22890,10 +24544,10 @@ function loadPolicyRules(dir) {
|
|
|
22890
24544
|
let content;
|
|
22891
24545
|
try {
|
|
22892
24546
|
content = readFileSync(join(dir, file), "utf-8");
|
|
22893
|
-
} catch (
|
|
24547
|
+
} catch (err3) {
|
|
22894
24548
|
issues.push({
|
|
22895
24549
|
path: file,
|
|
22896
|
-
message: t("policy_load.file_read_failed", { reason: reason6(
|
|
24550
|
+
message: t("policy_load.file_read_failed", { reason: reason6(err3) })
|
|
22897
24551
|
});
|
|
22898
24552
|
continue;
|
|
22899
24553
|
}
|
|
@@ -23016,8 +24670,8 @@ function unescapeTomlString(s) {
|
|
|
23016
24670
|
function preview2(line) {
|
|
23017
24671
|
return line.length > 40 ? `${line.slice(0, 40)}\u2026` : line;
|
|
23018
24672
|
}
|
|
23019
|
-
function reason6(
|
|
23020
|
-
return
|
|
24673
|
+
function reason6(err3) {
|
|
24674
|
+
return err3 instanceof Error ? err3.message : String(err3);
|
|
23021
24675
|
}
|
|
23022
24676
|
var MODULE3 = "Policy";
|
|
23023
24677
|
function resolvePolicyDirs(opts) {
|
|
@@ -23738,12 +25392,12 @@ function loadLexiconDir(dir, source) {
|
|
|
23738
25392
|
let files;
|
|
23739
25393
|
try {
|
|
23740
25394
|
files = readdirSync(dir).filter((f) => f.endsWith(".txt"));
|
|
23741
|
-
} catch (
|
|
25395
|
+
} catch (err3) {
|
|
23742
25396
|
return {
|
|
23743
25397
|
rules: [],
|
|
23744
25398
|
exempt: [],
|
|
23745
25399
|
issues: [
|
|
23746
|
-
{ path: dir, message: t("compliance_load.dir_read_failed", { reason: reason7(
|
|
25400
|
+
{ path: dir, message: t("compliance_load.dir_read_failed", { reason: reason7(err3) }) }
|
|
23747
25401
|
]
|
|
23748
25402
|
};
|
|
23749
25403
|
}
|
|
@@ -23762,10 +25416,10 @@ function loadLexiconDir(dir, source) {
|
|
|
23762
25416
|
let content;
|
|
23763
25417
|
try {
|
|
23764
25418
|
content = readFileSync(join(dir, file), "utf-8");
|
|
23765
|
-
} catch (
|
|
25419
|
+
} catch (err3) {
|
|
23766
25420
|
out.issues.push({
|
|
23767
25421
|
path: file,
|
|
23768
|
-
message: t("compliance_load.file_read_failed", { reason: reason7(
|
|
25422
|
+
message: t("compliance_load.file_read_failed", { reason: reason7(err3) })
|
|
23769
25423
|
});
|
|
23770
25424
|
continue;
|
|
23771
25425
|
}
|
|
@@ -23812,12 +25466,12 @@ function regexError(pattern) {
|
|
|
23812
25466
|
try {
|
|
23813
25467
|
new RegExp(pattern, "gu");
|
|
23814
25468
|
return void 0;
|
|
23815
|
-
} catch (
|
|
23816
|
-
return reason7(
|
|
25469
|
+
} catch (err3) {
|
|
25470
|
+
return reason7(err3);
|
|
23817
25471
|
}
|
|
23818
25472
|
}
|
|
23819
|
-
function reason7(
|
|
23820
|
-
return
|
|
25473
|
+
function reason7(err3) {
|
|
25474
|
+
return err3 instanceof Error ? err3.message : String(err3);
|
|
23821
25475
|
}
|
|
23822
25476
|
var MODULE4 = "Compliance";
|
|
23823
25477
|
function resolveComplianceDirs(opts) {
|
|
@@ -23887,7 +25541,7 @@ function runCommandHook(config, event, workDir) {
|
|
|
23887
25541
|
let stdout = "";
|
|
23888
25542
|
let stderr = "";
|
|
23889
25543
|
let settled = false;
|
|
23890
|
-
const failToStart = (
|
|
25544
|
+
const failToStart = (err3) => {
|
|
23891
25545
|
if (settled) return;
|
|
23892
25546
|
settled = true;
|
|
23893
25547
|
resolve17({
|
|
@@ -23895,7 +25549,7 @@ function runCommandHook(config, event, workDir) {
|
|
|
23895
25549
|
stdout,
|
|
23896
25550
|
stderr,
|
|
23897
25551
|
blocked: false,
|
|
23898
|
-
rejectReason: t("hook_load.spawn_failed", { message:
|
|
25552
|
+
rejectReason: t("hook_load.spawn_failed", { message: err3.message }),
|
|
23899
25553
|
sandbox
|
|
23900
25554
|
});
|
|
23901
25555
|
};
|
|
@@ -23971,9 +25625,9 @@ function runCommandHook(config, event, workDir) {
|
|
|
23971
25625
|
...failure ? { failure } : {}
|
|
23972
25626
|
});
|
|
23973
25627
|
});
|
|
23974
|
-
child.on("error", (
|
|
25628
|
+
child.on("error", (err3) => {
|
|
23975
25629
|
clearTimeout(timer);
|
|
23976
|
-
failToStart(
|
|
25630
|
+
failToStart(err3);
|
|
23977
25631
|
});
|
|
23978
25632
|
const input = JSON.stringify({
|
|
23979
25633
|
session_id: event.sessionId,
|
|
@@ -24079,8 +25733,8 @@ var HookManager = class {
|
|
|
24079
25733
|
if (result.blocked) {
|
|
24080
25734
|
return { blocked: true, reason: result.rejectReason || t("hook_load.rejected") };
|
|
24081
25735
|
}
|
|
24082
|
-
} catch (
|
|
24083
|
-
this.log("warn", `[HookManager] ${type} \u7684 command hook \u6267\u884C\u5F02\u5E38: ${describe12(
|
|
25736
|
+
} catch (err3) {
|
|
25737
|
+
this.log("warn", `[HookManager] ${type} \u7684 command hook \u6267\u884C\u5F02\u5E38: ${describe12(err3)}`, {
|
|
24084
25738
|
hookType: type,
|
|
24085
25739
|
command: config.command
|
|
24086
25740
|
});
|
|
@@ -24097,8 +25751,8 @@ var HookManager = class {
|
|
|
24097
25751
|
new Promise(
|
|
24098
25752
|
(_, reject2) => setTimeout(() => reject2(new Error("Hook timeout")), HOOK_TIMEOUT_MS)
|
|
24099
25753
|
)
|
|
24100
|
-
]).catch((
|
|
24101
|
-
this.log("warn", `[HookManager] ${type} (${reg.plugin}) \u5931\u8D25: ${describe12(
|
|
25754
|
+
]).catch((err3) => {
|
|
25755
|
+
this.log("warn", `[HookManager] ${type} (${reg.plugin}) \u5931\u8D25: ${describe12(err3)}`, {
|
|
24102
25756
|
hookType: type,
|
|
24103
25757
|
plugin: reg.plugin
|
|
24104
25758
|
});
|
|
@@ -24109,8 +25763,8 @@ var HookManager = class {
|
|
|
24109
25763
|
for (const entry of cmdEntries) {
|
|
24110
25764
|
if (!matchesHook(entry.matcher, event)) continue;
|
|
24111
25765
|
for (const config of entry.configs) {
|
|
24112
|
-
runCommandHook(config, event, ctx.workDir).then((result) => reportIfNotRun(this.log, type, config, result)).catch((
|
|
24113
|
-
this.log("warn", `[HookManager] ${type} \u7684 command hook \u5F02\u6B65\u5F02\u5E38: ${describe12(
|
|
25766
|
+
runCommandHook(config, event, ctx.workDir).then((result) => reportIfNotRun(this.log, type, config, result)).catch((err3) => {
|
|
25767
|
+
this.log("warn", `[HookManager] ${type} \u7684 command hook \u5F02\u6B65\u5F02\u5E38: ${describe12(err3)}`, {
|
|
24114
25768
|
hookType: type,
|
|
24115
25769
|
command: config.command
|
|
24116
25770
|
});
|
|
@@ -24130,8 +25784,8 @@ var HookManager = class {
|
|
|
24130
25784
|
)
|
|
24131
25785
|
]);
|
|
24132
25786
|
if (result !== null && result !== void 0) return result;
|
|
24133
|
-
} catch (
|
|
24134
|
-
this.log("warn", `[HookManager] ${type} (${reg.plugin}) \u5931\u8D25: ${describe12(
|
|
25787
|
+
} catch (err3) {
|
|
25788
|
+
this.log("warn", `[HookManager] ${type} (${reg.plugin}) \u5931\u8D25: ${describe12(err3)}`, {
|
|
24135
25789
|
hookType: type,
|
|
24136
25790
|
plugin: reg.plugin
|
|
24137
25791
|
});
|
|
@@ -24151,8 +25805,8 @@ var HookManager = class {
|
|
|
24151
25805
|
)
|
|
24152
25806
|
]);
|
|
24153
25807
|
if (result) results.push(result);
|
|
24154
|
-
} catch (
|
|
24155
|
-
this.log("warn", `[HookManager] ${type} (${reg.plugin}) \u5931\u8D25: ${describe12(
|
|
25808
|
+
} catch (err3) {
|
|
25809
|
+
this.log("warn", `[HookManager] ${type} (${reg.plugin}) \u5931\u8D25: ${describe12(err3)}`, {
|
|
24156
25810
|
hookType: type,
|
|
24157
25811
|
plugin: reg.plugin
|
|
24158
25812
|
});
|
|
@@ -24168,8 +25822,8 @@ var HookManager = class {
|
|
|
24168
25822
|
reportIfNotRun(this.log, type, config, result);
|
|
24169
25823
|
const verdict = verdictOf2(result);
|
|
24170
25824
|
if (verdict) results.push(verdict);
|
|
24171
|
-
} catch (
|
|
24172
|
-
this.log("warn", `[HookManager] ${type} \u7684 command hook \u6267\u884C\u5F02\u5E38: ${describe12(
|
|
25825
|
+
} catch (err3) {
|
|
25826
|
+
this.log("warn", `[HookManager] ${type} \u7684 command hook \u6267\u884C\u5F02\u5E38: ${describe12(err3)}`, {
|
|
24173
25827
|
hookType: type,
|
|
24174
25828
|
command: config.command
|
|
24175
25829
|
});
|
|
@@ -24185,8 +25839,8 @@ var HookManager = class {
|
|
|
24185
25839
|
return [...list].sort((a, b) => a.priority - b.priority);
|
|
24186
25840
|
}
|
|
24187
25841
|
};
|
|
24188
|
-
function describe12(
|
|
24189
|
-
return
|
|
25842
|
+
function describe12(err3) {
|
|
25843
|
+
return err3 instanceof Error ? err3.message : String(err3);
|
|
24190
25844
|
}
|
|
24191
25845
|
function verdictOf2(result) {
|
|
24192
25846
|
const action = result.output?.["action"];
|
|
@@ -24738,8 +26392,8 @@ function readHooksFile(path, issues, opts = {}) {
|
|
|
24738
26392
|
let raw;
|
|
24739
26393
|
try {
|
|
24740
26394
|
raw = JSON.parse(readFileSync(path, "utf-8"));
|
|
24741
|
-
} catch (
|
|
24742
|
-
const reason9 =
|
|
26395
|
+
} catch (err3) {
|
|
26396
|
+
const reason9 = err3.message.split("\n")[0] ?? t("hook_load.unknown_error");
|
|
24743
26397
|
issues.push({ path, message: t("hook_load.bad_json", { reason: reason9 }) });
|
|
24744
26398
|
return void 0;
|
|
24745
26399
|
}
|
|
@@ -24954,8 +26608,8 @@ function readEntries2(dir, label, issues, lang) {
|
|
|
24954
26608
|
isDir: e.isDirectory(),
|
|
24955
26609
|
isFile: e.isFile()
|
|
24956
26610
|
}));
|
|
24957
|
-
} catch (
|
|
24958
|
-
const reason9 =
|
|
26611
|
+
} catch (err3) {
|
|
26612
|
+
const reason9 = err3 instanceof Error ? err3.message : String(err3);
|
|
24959
26613
|
issues.push({ path: label, message: t("skill.import_read_failed", { reason: reason9 }, lang) });
|
|
24960
26614
|
return [];
|
|
24961
26615
|
}
|
|
@@ -25070,10 +26724,10 @@ function scanOneDir(spec, skills, issues) {
|
|
|
25070
26724
|
let categories;
|
|
25071
26725
|
try {
|
|
25072
26726
|
categories = readdirSync(spec.dir, { withFileTypes: true });
|
|
25073
|
-
} catch (
|
|
26727
|
+
} catch (err3) {
|
|
25074
26728
|
issues.push({
|
|
25075
26729
|
path: spec.dir,
|
|
25076
|
-
message: t("skill_load.dir_read_failed", { reason: reason8(
|
|
26730
|
+
message: t("skill_load.dir_read_failed", { reason: reason8(err3) })
|
|
25077
26731
|
});
|
|
25078
26732
|
return;
|
|
25079
26733
|
}
|
|
@@ -25083,10 +26737,10 @@ function scanOneDir(spec, skills, issues) {
|
|
|
25083
26737
|
let entries2;
|
|
25084
26738
|
try {
|
|
25085
26739
|
entries2 = readdirSync(catPath, { withFileTypes: true });
|
|
25086
|
-
} catch (
|
|
26740
|
+
} catch (err3) {
|
|
25087
26741
|
issues.push({
|
|
25088
26742
|
path: cat.name,
|
|
25089
|
-
message: t("skill_load.category_read_failed", { reason: reason8(
|
|
26743
|
+
message: t("skill_load.category_read_failed", { reason: reason8(err3) })
|
|
25090
26744
|
});
|
|
25091
26745
|
continue;
|
|
25092
26746
|
}
|
|
@@ -25106,8 +26760,8 @@ function loadOne(mdFile, catPath, category, dirName, spec, skills, issues) {
|
|
|
25106
26760
|
try {
|
|
25107
26761
|
raw = readFileSync(mdFile, "utf-8");
|
|
25108
26762
|
stat5 = statSync(mdFile);
|
|
25109
|
-
} catch (
|
|
25110
|
-
issues.push({ path: label, message: t("skill_load.read_failed", { reason: reason8(
|
|
26763
|
+
} catch (err3) {
|
|
26764
|
+
issues.push({ path: label, message: t("skill_load.read_failed", { reason: reason8(err3) }) });
|
|
25111
26765
|
return;
|
|
25112
26766
|
}
|
|
25113
26767
|
const parsed = parseSkillFrontmatter(raw, label);
|
|
@@ -25144,8 +26798,8 @@ function loadOne(mdFile, catPath, category, dirName, spec, skills, issues) {
|
|
|
25144
26798
|
source: "manual"
|
|
25145
26799
|
});
|
|
25146
26800
|
}
|
|
25147
|
-
function reason8(
|
|
25148
|
-
return
|
|
26801
|
+
function reason8(err3) {
|
|
26802
|
+
return err3 instanceof Error ? err3.message : String(err3);
|
|
25149
26803
|
}
|
|
25150
26804
|
// src/skill/manager.ts
|
|
25151
26805
|
var SKILLS_DIR = join(homedir(), ".epoch", "skills");
|
|
@@ -25593,17 +27247,17 @@ function swapInto(from, old, dest, skillsDir) {
|
|
|
25593
27247
|
try {
|
|
25594
27248
|
mkdirSync(trash, { recursive: true });
|
|
25595
27249
|
renameSync(old, join(trash, "old"));
|
|
25596
|
-
} catch (
|
|
27250
|
+
} catch (err3) {
|
|
25597
27251
|
rmSync(trash, { recursive: true, force: true });
|
|
25598
|
-
return
|
|
27252
|
+
return err3 instanceof Error ? err3.message : String(err3);
|
|
25599
27253
|
}
|
|
25600
27254
|
try {
|
|
25601
27255
|
mkdirSync(dirname(dest), { recursive: true });
|
|
25602
27256
|
renameSync(from, dest);
|
|
25603
|
-
} catch (
|
|
27257
|
+
} catch (err3) {
|
|
25604
27258
|
renameSync(join(trash, "old"), old);
|
|
25605
27259
|
rmSync(trash, { recursive: true, force: true });
|
|
25606
|
-
return
|
|
27260
|
+
return err3 instanceof Error ? err3.message : String(err3);
|
|
25607
27261
|
}
|
|
25608
27262
|
rmSync(trash, { recursive: true, force: true });
|
|
25609
27263
|
return null;
|
|
@@ -25681,8 +27335,8 @@ function commit3(preview3, staged, skillsDir, lang, replace = false) {
|
|
|
25681
27335
|
mkdirSync(join(skillsDir, entry.category), { recursive: true });
|
|
25682
27336
|
renameSync(from, dest);
|
|
25683
27337
|
imported.push(entry.name);
|
|
25684
|
-
} catch (
|
|
25685
|
-
const reason9 =
|
|
27338
|
+
} catch (err3) {
|
|
27339
|
+
const reason9 = err3 instanceof Error ? err3.message : String(err3);
|
|
25686
27340
|
skipped.push({ path: label, message: t("skill.import_write_failed", { reason: reason9 }, lang) });
|
|
25687
27341
|
}
|
|
25688
27342
|
}
|
|
@@ -25769,8 +27423,8 @@ var SkillLearner = class {
|
|
|
25769
27423
|
messages: [{ role: "user", content: buildLearningPrompt(ctx) }]
|
|
25770
27424
|
});
|
|
25771
27425
|
text = result.text;
|
|
25772
|
-
} catch (
|
|
25773
|
-
return { created: false, reason: "provider-error", error: messageOf2(
|
|
27426
|
+
} catch (err3) {
|
|
27427
|
+
return { created: false, reason: "provider-error", error: messageOf2(err3) };
|
|
25774
27428
|
}
|
|
25775
27429
|
return this.parseAndCreate(text);
|
|
25776
27430
|
}
|
|
@@ -25803,13 +27457,13 @@ var SkillLearner = class {
|
|
|
25803
27457
|
try {
|
|
25804
27458
|
await this.skillSystem.create(declared, parsed.content, category);
|
|
25805
27459
|
return { created: true, skillName: declared };
|
|
25806
|
-
} catch (
|
|
25807
|
-
return { created: false, reason: "create-failed", error: messageOf2(
|
|
27460
|
+
} catch (err3) {
|
|
27461
|
+
return { created: false, reason: "create-failed", error: messageOf2(err3) };
|
|
25808
27462
|
}
|
|
25809
27463
|
}
|
|
25810
27464
|
};
|
|
25811
|
-
function messageOf2(
|
|
25812
|
-
return
|
|
27465
|
+
function messageOf2(err3) {
|
|
27466
|
+
return err3 instanceof Error ? err3.message : String(err3);
|
|
25813
27467
|
}
|
|
25814
27468
|
var MAX_FILES = 2e4;
|
|
25815
27469
|
var SKIP_DIRS = /* @__PURE__ */ new Set([
|
|
@@ -26082,11 +27736,11 @@ async function openArtifact(path, homeDir) {
|
|
|
26082
27736
|
const child = spawn(launch.command, launch.args, { stdio: "ignore", detached: true });
|
|
26083
27737
|
child.on(
|
|
26084
27738
|
"error",
|
|
26085
|
-
(
|
|
27739
|
+
(err3) => fail9(
|
|
26086
27740
|
new Error(
|
|
26087
27741
|
t("artifact.open_launch_failed_detail", {
|
|
26088
27742
|
reason: describeArtifactRefusal("launch-failed"),
|
|
26089
|
-
message:
|
|
27743
|
+
message: err3.message
|
|
26090
27744
|
})
|
|
26091
27745
|
)
|
|
26092
27746
|
)
|
|
@@ -26095,12 +27749,12 @@ async function openArtifact(path, homeDir) {
|
|
|
26095
27749
|
child.unref();
|
|
26096
27750
|
done2();
|
|
26097
27751
|
});
|
|
26098
|
-
} catch (
|
|
27752
|
+
} catch (err3) {
|
|
26099
27753
|
fail9(
|
|
26100
27754
|
new Error(
|
|
26101
27755
|
t("artifact.open_launch_failed_detail", {
|
|
26102
27756
|
reason: describeArtifactRefusal("launch-failed"),
|
|
26103
|
-
message: String(
|
|
27757
|
+
message: String(err3)
|
|
26104
27758
|
})
|
|
26105
27759
|
)
|
|
26106
27760
|
);
|
|
@@ -26439,8 +28093,8 @@ ${extra}` : withGoal;
|
|
|
26439
28093
|
var FILE_VERSION5 = 1;
|
|
26440
28094
|
var LEVELS = ["trusted", "untrusted"];
|
|
26441
28095
|
var SCOPES = ["directory", "directory-tree"];
|
|
26442
|
-
function describe14(
|
|
26443
|
-
return
|
|
28096
|
+
function describe14(err3) {
|
|
28097
|
+
return err3 instanceof Error ? err3.message : String(err3);
|
|
26444
28098
|
}
|
|
26445
28099
|
function covers(base2, target, scope) {
|
|
26446
28100
|
if (samePath(base2, target)) return true;
|
|
@@ -26511,18 +28165,18 @@ var TrustManager = class {
|
|
|
26511
28165
|
let raw;
|
|
26512
28166
|
try {
|
|
26513
28167
|
raw = readFileSync(this.filePath, "utf-8");
|
|
26514
|
-
} catch (
|
|
28168
|
+
} catch (err3) {
|
|
26515
28169
|
this.loadErrors.push(
|
|
26516
|
-
t("trust_gate.record_read_failed", { path: this.filePath, reason: describe14(
|
|
28170
|
+
t("trust_gate.record_read_failed", { path: this.filePath, reason: describe14(err3) })
|
|
26517
28171
|
);
|
|
26518
28172
|
return;
|
|
26519
28173
|
}
|
|
26520
28174
|
let parsed;
|
|
26521
28175
|
try {
|
|
26522
28176
|
parsed = JSON.parse(raw);
|
|
26523
|
-
} catch (
|
|
28177
|
+
} catch (err3) {
|
|
26524
28178
|
this.loadErrors.push(
|
|
26525
|
-
t("trust_gate.record_bad_json", { path: this.filePath, reason: describe14(
|
|
28179
|
+
t("trust_gate.record_bad_json", { path: this.filePath, reason: describe14(err3) })
|
|
26526
28180
|
);
|
|
26527
28181
|
return;
|
|
26528
28182
|
}
|
|
@@ -26568,10 +28222,10 @@ var TrustManager = class {
|
|
|
26568
28222
|
try {
|
|
26569
28223
|
writeFileSync(tmp, body2, { encoding: "utf-8", mode: 384 });
|
|
26570
28224
|
renameSync(tmp, this.filePath);
|
|
26571
|
-
} catch (
|
|
28225
|
+
} catch (err3) {
|
|
26572
28226
|
rmSync(tmp, { force: true });
|
|
26573
28227
|
throw new Error(
|
|
26574
|
-
t("trust_gate.record_write_failed", { path: this.filePath, reason: describe14(
|
|
28228
|
+
t("trust_gate.record_write_failed", { path: this.filePath, reason: describe14(err3) })
|
|
26575
28229
|
);
|
|
26576
28230
|
}
|
|
26577
28231
|
}
|
|
@@ -26718,4 +28372,4 @@ function hasDedicatedExecContent(inv) {
|
|
|
26718
28372
|
* `--tree` 的命令帮助里,让用户自己知道 `--tree` 意味着什么。
|
|
26719
28373
|
*/
|
|
26720
28374
|
|
|
26721
|
-
export { ABOUT_DESC_MAX_CHARS, ABOUT_README_MAX_CHARS, AGENT_ROLE_DIAG_MODULE, ARTIFACT_MAX_TOTAL_BYTES, ARTIFACT_RETENTION_DEFAULTS, ATTACHMENT_MAX_TOTAL_BYTES, ATTACHMENT_RETENTION_DEFAULTS, AgentLoop, AppearanceStore, ApprovalCache, BLOCKED_TOOLS, BudgetGuard, BudgetStore, CHECKPOINT_MAX_TOTAL_BYTES, CLAUDE_EVENT_NAMES, CLAUDE_TOOL_NAMES, CODE_MODE_LIMITS, CODE_MODE_SDK_TAG, CONFIG_KEYS, CURRENT_CONFIG_VERSION, CheckpointManager, CheckpointStore, CodeSandbox, ComplianceEngine, ContextCompressor, DEFAULT_COMPLIANCE_ACTIONS, DEFAULT_COMPLIANCE_SETTINGS, DEFAULT_COMPRESSION_THRESHOLD, DEFAULT_GOAL_MAX_ROUNDS, DEFAULT_MAX_HOLD_CHARS, DELEGATE_SESSION_SOURCE, DelegateManager, EMPTY_RULES, EPOCH_DISK_LEDGER, EpochConfigSchema, FTS_TABLES, FTS_TRIGGERS, GOAL_BLOCK_CODES, GoalService, GoalStore, HEADLESS_AUDIT_CODES, HookManager, INSTRUCTION_BUDGET_CHARS, INSTRUCTION_FILES, ImageLoadError, ImportTrustStore, LAUNCHD_LABEL_PREFIX, LOCK_HEARTBEAT_MS, LOCK_STALE_MS, LastOpenSessions, MARKETPLACE_DISPLAY_FIELDS, MARKETPLACE_FILE, MAX_AUDIT_ENTRIES, MAX_COMMAND_DEPTH, MAX_GOAL_MAX_ROUNDS, MAX_IMPORT_DEPTH, MAX_LAST_OPEN_SESSIONS, MAX_OBJECTIVE_CHARS, MAX_REASON_CHARS, MAX_RECENT_WORKSPACES, MODEL_ENTRIES_FILE, MODEL_GIVE_UP_THRESHOLD, MULTIMODAL_DEFAULTS, ManagedPolicyError, ManagedSettingsSchema, MemoryManager, ModelFailureTracker, NOMINAL_TOTAL_BYTES, NO_REVEALED_TOOLS, PACK_EXCLUDES, PERMISSION_AUDIT_CODES, PLUGIN_ICON_MAX_BYTES, PLUGIN_LAYOUT, PLUGIN_MANIFEST_FILE, PLUGIN_MANIFEST_KEYS, PLUGIN_NAME_PATTERN, PLUGIN_ROOT_ENV, PLUGIN_ROOT_TOKEN, PLUGIN_VISIBILITY, POLICY_DECISIONS, PROBE_VERSION, PROJECT_AGENTS_SUBDIR, PROVIDER_NO_CREDENTIAL, PermissionManager, PlanModeState, PluginAuthorSchema, PluginStore, PolicyRuleSchema, ProviderError, ProviderRouter, RECORDING_KEEP_RUNS, RECORDING_MAX_BYTES, ROLE_FRONTMATTER_SCHEMA, RUN_CODE_TOOL, RecentWorkspaces, SANDBOX_COVERS, SANDBOX_EXCLUDES, SCALAR_KEYS, SCHEDULE_DEFAULTS, SCHEDULE_DEFAULT_ALLOWLIST, SCHEDULE_ISSUE_CODES, SCHTASKS_FOLDER, SESSION_MESSAGES_READ_TOOL, SESSION_MESSAGES_SEARCH_TOOL, SESSION_QUERY_TOOLS, SESSION_SEARCH_TOOL, SESSION_TRACE_TOOL, SETTINGS_LAYER_ORDER, SETTING_WRITE_KEYS, SETTING_WRITE_LAYERS, SKILL_ASSET_DIRS, SKILL_CREATE_TOOL, SKILL_EDIT_TOOL, SKILL_FILE, SKILL_PATCH_TOOL, SKILL_VIEW_TOOL, SKILL_WRITE_FILE_TOOL, SLASH_COMMANDS_DIAG_MODULE, ScheduleRecorder, ScheduleRegistrar, ScheduleStore, SessionManager, SessionQueries, SessionReferences, SettingsFileError, SettingsFileSchema, SkillLearner, SkillSystem, TOOL_SEARCH_TOOL, TaskNoticeTracker, ToolRegistry, TrackerDB, TrustManager, UNSETTABLE_USER_KEYS, Workspace, acquireScheduleLock, addMarketplace, addUsage, admitArtifact, admitArtifacts, affectedPaths, approvalEntryFor, approvalRootFor, artifactLaunchArgv, artifactOpenRefusal, assertLevelAllowed, blockedRoleTools, buildContextBreakdown, buildFireArgv, buildFtsMatchQuery, buildSchemaExports, buildSystemPrompt, buildTrigramMatchQuery, builtinRoles, capabilityOfRef, checkConfigValue, checkEpochVersion, checkFtsHealth, checkShadowing, classifyPersistFailure, classifyProviderError, clearModelCache, coalesceRecording, codeModeWorkerPath, commandNameFromRelPath, compileRuleLists, compressionOptions, computeCost, computeCostMicros, computeExecHash, configKeyByPath, configKeyTable, countRules, createAllowAllGate, createAllowAllImportGate, createAskQuestionTool, createCodeExecTool, createDelegateTool, createDenyAllGate, createDenyAllImportGate, createGoalTool, createImportGate, createMemoryTool, createPlanModeTools, createPluginScope, createRoleFile, createRoleScope, createRunCodeTool, createScheduleDraftTool, createSessionMessagesReadTool, createSessionMessagesSearchTool, createSessionSearchTool, createSessionSearchTools, createSessionTraceTool, createSkillViewTool, createSkillWriteTools, createTodoTool, createToolRevealState, createToolScope, createToolSearchTool, createTrustGate, currentEpochVersion, decideImport, decideTrust, defaultConfig, describeArtifactRefusal, describeBackgroundTask, describeHeadlessPolicy, describeIsolation, describeJsonError, diagnoseSchedules, discoverMarkdown, discoverModels, discoverProject, discoverySpec, displayAllows, displayCurrency, draftCommandLine, draftWidening, escapeRuleContent, estimateImageTokens, estimateRunTokens, estimateTokens, evaluateSelection, expandCommand, expandImports, explainSetting, extractArchive, findInstructionFiles, findProjectInstructions, findRole, formatBytes, formatSkillIndex, formatUsd, gateForTool, getCapability, getConfigIssues, getConfigOrigins, getImportGate, getTrustGate, grantedPathsFor, hasDedicatedExecContent, hasExecTierContent, hasPromptCaching, hasProviderCredentials, hasReadTierContent, hasUsableModel, imageFromBase64, imageFromPath, imagePartTokens, importParts, importSkills, installPlugin, instructionDirs, instructionNotices, intervalSlots, inventoryProjectExtensions, inventoryTotal, isBlockCode, isCodeModeDeferred, isEmptyRules, isGoalPhase, isNonInteractive, isReadOnlySubCall, isSettingWriteLayer, isTransientPersistFailure, isValidInterval, isValidPluginName, isWithinWindow, isWritableSettingKey, labelSlug, layerRank, listEntryModels, listRunningSchedules, listSessionCandidates, listWorkspaceFiles, loadCommandDefinitions, loadCommandFile, loadCommands, loadConfig, loadHookSources, loadKeybindings, loadLexiconDir, loadLexiconFiles, loadModelEntries, loadPlugins, loadPolicyFiles, loadPolicyRules, loadRoleDefinitions, loadRoleDir, loadedImports, localDateString, managedSwitchNotes, mapClaudeToolName, mapEpochToolName, mapOperationType, matchPreauthorization, matchRuleLists, matchesHook, mentionsPluginRoot, mergeHeadlessPolicy, mergeRoles, mergeSchedulePatch, microsToUsd, modelEntriesPath, modelListCandidates, needsAllowlist, nextRunAt, noConfigOrigins, noManagedPolicy, noPlugins, normalizeModelEntry, normalizeTrigger, offloadOldestImages, openArtifact, originOf, packFileName, packPlugin, parseClaudeSettingsHooks, parseClock, parseDate, parseFrontmatter, parseHooksConfig, parseHooksConfigVerbose, parseImportLine, parseModelEntry, parseModelList, parseRoleDefinition, parseScheduleDraft, parseSkillFrontmatter, parseTrigger, pendingImageTokens, persistFailureCode, persistParts, persistToolResults, persistedUsage, planPack, previewSkillImport, pricingFor, projectEntryForDisplay, pruneArtifacts, pruneAttachments, pruneRecordings, pruneSchedules, readEntryKey, readImageSize, readMarketplaces, readPluginAbout, readPluginIcon, readPluginManifest, readPluginRecords, readRecording, readSessionSurface, reclaimFtsSpace, redactLine, refreshOpenRouterMetadata, removeMarketplace, removeRecordings, removeRoleFile, removeSessionArtifacts, removeSessionAttachments, renderImportTree, renderProjectContext, renderSdkDeclaration, renderSelfIndex, repairSchedules, requestImageBytes, resolveArtifactRetention, resolveCodeModeWorker, resolveComplianceDirs, resolveEntrySource, resolveInWorkspace, resolveMarketplaceRef, resolveMentions, resolveMultimodalPolicy, resolvePolicyDirs, resolvePricingAt, resolveProjectRoot, resolveScheduleBackend, resolveSessionReference, resolveSessionVisibility, resolveSettings, resolveSkillDirs, resolveSource, resolveTar, resolveWorkspace, restoreParts, revealScopedProvider, roleScopedProvider, roleSourceLabel, ruleCovers, ruleFromString, ruleToString, runCode, runCommand2 as runCommand, sanitizeArgNames, sanitizeCommand, sanitizeFtsQuery, sanitizePath, sanitizeToolOutput, saveModelEntries, scanInstructions, scanPluginDir, scanSkillDirs, searchMarketplaces, setDisplayCurrency, setImportGate, setPluginEnabled, setTrustGate, settingValueChoices, settingValueKind, settingWriteApply, settingWriteLayers, settingWriteTargets, skillIndexDescription, skillIndexResidency, skillIndexStats, sniffMediaType, splitFrontmatter, staticToolProvider, stripArtifactData, substitutePluginRoot, suggestRuleFromApproval, systemOpenArgv, systemPromptSegments, testModelEntry, toPosix, toolDefinitionTokens, toolMatches, toolTableTokens, totalTokens, traceSession, triggerPeriodMs, unescapeRuleContent, uninstallPlugin, unknownRoleSkills, unknownRoleTools, unloadedInstructionFiles, unsetUserSetting, updateMarketplace, updatePlugin, usdToMicros, validateSchedule, validateTrigger, validateWindow, withGoalCompression, withGoalPrompt, workspaceDisplayPath, writableConfigKeys, writeSettingValue };
|
|
28375
|
+
export { ABOUT_DESC_MAX_CHARS, ABOUT_README_MAX_CHARS, AGENT_ROLE_DIAG_MODULE, ARTIFACT_MAX_TOTAL_BYTES, ARTIFACT_RETENTION_DEFAULTS, ATTACHMENT_MAX_TOTAL_BYTES, ATTACHMENT_RETENTION_DEFAULTS, AgentInbox, AgentLoop, AppearanceStore, ApprovalCache, BLOCKED_TOOLS, BOARD_TOOL_NAMES, BoardStore, BudgetGuard, BudgetStore, CHECKPOINT_MAX_TOTAL_BYTES, CLAUDE_EVENT_NAMES, CLAUDE_TOOL_NAMES, CODE_MODE_LIMITS, CODE_MODE_SDK_TAG, CONFIG_KEYS, CURRENT_CONFIG_VERSION, CheckpointManager, CheckpointStore, CodeSandbox, ComplianceEngine, ContextCompressor, DEFAULT_COMPLIANCE_ACTIONS, DEFAULT_COMPLIANCE_SETTINGS, DEFAULT_COMPRESSION_THRESHOLD, DEFAULT_GOAL_MAX_ROUNDS, DEFAULT_INBOX_CAPACITY, DEFAULT_MAX_HOLD_CHARS, DELEGATE_SESSION_SOURCE, DelegateManager, EMPTY_RULES, EPOCH_DISK_LEDGER, EpochConfigSchema, FTS_TABLES, FTS_TRIGGERS, GOAL_BLOCK_CODES, GoalService, GoalStore, HEADLESS_AUDIT_CODES, HookManager, INSTRUCTION_BUDGET_CHARS, INSTRUCTION_FILES, ImageLoadError, ImportTrustStore, LAUNCHD_LABEL_PREFIX, LOCK_HEARTBEAT_MS, LOCK_STALE_MS, LastOpenSessions, MARKETPLACE_DISPLAY_FIELDS, MARKETPLACE_FILE, MAX_AUDIT_ENTRIES, MAX_COMMAND_DEPTH, MAX_GOAL_MAX_ROUNDS, MAX_IMPORT_DEPTH, MAX_LAST_OPEN_SESSIONS, MAX_OBJECTIVE_CHARS, MAX_POST_CHARS, MAX_REASON_CHARS, MAX_RECENT_WORKSPACES, MODEL_ENTRIES_FILE, MODEL_GIVE_UP_THRESHOLD, MULTIMODAL_DEFAULTS, ManagedPolicyError, ManagedSettingsSchema, MemoryManager, ModelFailureTracker, NOMINAL_TOTAL_BYTES, NO_REVEALED_TOOLS, PACK_EXCLUDES, PERMISSION_AUDIT_CODES, PLUGIN_ICON_MAX_BYTES, PLUGIN_LAYOUT, PLUGIN_MANIFEST_FILE, PLUGIN_MANIFEST_KEYS, PLUGIN_NAME_PATTERN, PLUGIN_ROOT_ENV, PLUGIN_ROOT_TOKEN, PLUGIN_VISIBILITY, POLICY_DECISIONS, PROBE_VERSION, PROJECT_AGENTS_SUBDIR, PROVIDER_NO_CREDENTIAL, PermissionManager, PlanModeState, PluginAuthorSchema, PluginStore, PolicyRuleSchema, ProviderError, ProviderRouter, RECORDING_KEEP_RUNS, RECORDING_MAX_BYTES, ROLE_FRONTMATTER_SCHEMA, RUN_CODE_TOOL, RecentWorkspaces, SANDBOX_COVERS, SANDBOX_EXCLUDES, SCALAR_KEYS, SCHEDULE_DEFAULTS, SCHEDULE_DEFAULT_ALLOWLIST, SCHEDULE_ISSUE_CODES, SCHTASKS_FOLDER, SEND_MESSAGE_TOOL, SESSION_MESSAGES_READ_TOOL, SESSION_MESSAGES_SEARCH_TOOL, SESSION_QUERY_TOOLS, SESSION_SEARCH_TOOL, SESSION_TRACE_TOOL, SETTINGS_LAYER_ORDER, SETTING_WRITE_KEYS, SETTING_WRITE_LAYERS, SKILL_ASSET_DIRS, SKILL_CREATE_TOOL, SKILL_EDIT_TOOL, SKILL_FILE, SKILL_PATCH_TOOL, SKILL_VIEW_TOOL, SKILL_WRITE_FILE_TOOL, SLASH_COMMANDS_DIAG_MODULE, ScheduleRecorder, ScheduleRegistrar, ScheduleStore, SessionManager, SessionQueries, SessionReferences, SettingsFileError, SettingsFileSchema, SkillLearner, SkillSystem, TEAM_TOOL_NAMES, TOOL_SEARCH_TOOL, TaskNoticeTracker, TeamRegistry, ToolRegistry, TrackerDB, TrustManager, UNSETTABLE_USER_KEYS, Workspace, acquireScheduleLock, addMarketplace, addUsage, admitArtifact, admitArtifacts, affectedPaths, approvalEntryFor, approvalRootFor, artifactLaunchArgv, artifactOpenRefusal, assertLevelAllowed, blockedRoleTools, buildContextBreakdown, buildFireArgv, buildFtsMatchQuery, buildSchemaExports, buildSystemPrompt, buildTrigramMatchQuery, builtinRoles, capabilityOfRef, checkConfigValue, checkEpochVersion, checkFtsHealth, checkShadowing, classifyPersistFailure, classifyProviderError, clearModelCache, coalesceRecording, codeModeWorkerPath, commandNameFromRelPath, compileRuleLists, compressionOptions, computeCost, computeCostMicros, computeExecHash, configKeyByPath, configKeyTable, countRules, createAllowAllGate, createAllowAllImportGate, createAskQuestionTool, createBoardTools, createCodeExecTool, createDelegateTool, createDenyAllGate, createDenyAllImportGate, createGoalTool, createImportGate, createMemoryTool, createPlanModeTools, createPluginScope, createRoleFile, createRoleScope, createRunCodeTool, createScheduleDraftTool, createSendMessageTool, createSessionMessagesReadTool, createSessionMessagesSearchTool, createSessionSearchTool, createSessionSearchTools, createSessionTraceTool, createSkillViewTool, createSkillWriteTools, createTeamTools, createTodoTool, createToolRevealState, createToolScope, createToolSearchTool, createTrustGate, currentEpochVersion, decideImport, decideTrust, defaultConfig, describeArtifactRefusal, describeBackgroundTask, describeHeadlessPolicy, describeIsolation, describeJsonError, diagnoseSchedules, discoverMarkdown, discoverModels, discoverProject, discoverySpec, displayAllows, displayCurrency, draftCommandLine, draftWidening, escapeRuleContent, estimateImageTokens, estimateRunTokens, estimateTokens, evaluateSelection, expandCommand, expandImports, explainSetting, extractArchive, findInstructionFiles, findProjectInstructions, findRole, formatBytes, formatSkillIndex, formatUsd, gateForTool, getCapability, getConfigIssues, getConfigOrigins, getImportGate, getTrustGate, grantedPathsFor, hasDedicatedExecContent, hasExecTierContent, hasPromptCaching, hasProviderCredentials, hasReadTierContent, hasUsableModel, imageFromBase64, imageFromPath, imagePartTokens, importParts, importSkills, installPlugin, instructionDirs, instructionNotices, intervalSlots, inventoryProjectExtensions, inventoryTotal, isBlockCode, isCodeModeDeferred, isEmptyRules, isGoalPhase, isNonInteractive, isReadOnlySubCall, isSettingWriteLayer, isTransientPersistFailure, isValidInterval, isValidPluginName, isWithinWindow, isWritableSettingKey, labelSlug, layerRank, listEntryModels, listRunningSchedules, listSessionCandidates, listWorkspaceFiles, loadCommandDefinitions, loadCommandFile, loadCommands, loadConfig, loadHookSources, loadKeybindings, loadLexiconDir, loadLexiconFiles, loadModelEntries, loadPlugins, loadPolicyFiles, loadPolicyRules, loadRoleDefinitions, loadRoleDir, loadedImports, localDateString, managedSwitchNotes, mapClaudeToolName, mapEpochToolName, mapOperationType, matchPreauthorization, matchRuleLists, matchesHook, mentionsPluginRoot, mergeHeadlessPolicy, mergeRoles, mergeSchedulePatch, microsToUsd, modelEntriesPath, modelListCandidates, needsAllowlist, nextRunAt, noConfigOrigins, noManagedPolicy, noPlugins, normalizeModelEntry, normalizeTrigger, offloadOldestImages, openArtifact, originOf, packFileName, packPlugin, parseClaudeSettingsHooks, parseClock, parseDate, parseFrontmatter, parseHooksConfig, parseHooksConfigVerbose, parseImportLine, parseModelEntry, parseModelList, parseRoleDefinition, parseScheduleDraft, parseSkillFrontmatter, parseTrigger, pendingImageTokens, persistFailureCode, persistParts, persistToolResults, persistedUsage, planPack, previewSkillImport, pricingFor, projectEntryForDisplay, pruneArtifacts, pruneAttachments, pruneRecordings, pruneSchedules, readEntryKey, readImageSize, readMarketplaces, readPluginAbout, readPluginIcon, readPluginManifest, readPluginRecords, readRecording, readSessionSurface, reclaimFtsSpace, redactLine, refreshOpenRouterMetadata, removeMarketplace, removeRecordings, removeRoleFile, removeSessionArtifacts, removeSessionAttachments, renderImportTree, renderProjectContext, renderSdkDeclaration, renderSelfIndex, repairSchedules, requestImageBytes, resolveArtifactRetention, resolveCodeModeWorker, resolveComplianceDirs, resolveEntrySource, resolveInWorkspace, resolveMarketplaceRef, resolveMentions, resolveMultimodalPolicy, resolvePolicyDirs, resolvePricingAt, resolveProjectRoot, resolveScheduleBackend, resolveSessionReference, resolveSessionVisibility, resolveSettings, resolveSkillDirs, resolveSource, resolveTar, resolveWorkspace, restoreParts, revealScopedProvider, roleScopedProvider, roleSourceLabel, ruleCovers, ruleFromString, ruleToString, runCode, runCommand2 as runCommand, sanitizeArgNames, sanitizeCommand, sanitizeFtsQuery, sanitizePath, sanitizeToolOutput, saveModelEntries, scanInstructions, scanPluginDir, scanSkillDirs, searchMarketplaces, setDisplayCurrency, setImportGate, setPluginEnabled, setTrustGate, settingValueChoices, settingValueKind, settingWriteApply, settingWriteLayers, settingWriteTargets, skillIndexDescription, skillIndexResidency, skillIndexStats, sniffMediaType, splitFrontmatter, staticToolProvider, stripArtifactData, substitutePluginRoot, suggestRuleFromApproval, systemOpenArgv, systemPromptSegments, testModelEntry, toPosix, toolDefinitionTokens, toolMatches, toolTableTokens, totalTokens, traceSession, triggerPeriodMs, unescapeRuleContent, uninstallPlugin, unknownRoleSkills, unknownRoleTools, unloadedInstructionFiles, unsetUserSetting, updateMarketplace, updatePlugin, usdToMicros, validateSchedule, validateTrigger, validateWindow, withGoalCompression, withGoalPrompt, workspaceDisplayPath, writableConfigKeys, writeSettingValue };
|