@epoch-agent/core 3.0.0 → 3.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -29
- package/dist/index.d.ts +901 -8
- package/dist/index.js +2391 -535
- 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, sessionSenderLabel, 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",
|
|
@@ -2006,7 +2034,7 @@ var DelegateManager = class {
|
|
|
2006
2034
|
async delegate(args, parentSessionId, signal) {
|
|
2007
2035
|
const start = Date.now();
|
|
2008
2036
|
const tasks = this.normalizeTasks(args);
|
|
2009
|
-
|
|
2037
|
+
let maxConcurrent = args.max_concurrent ?? this.config.max_concurrent_children;
|
|
2010
2038
|
if (this.currentDepth >= this.config.max_spawn_depth) {
|
|
2011
2039
|
return {
|
|
2012
2040
|
success: false,
|
|
@@ -2018,6 +2046,18 @@ var DelegateManager = class {
|
|
|
2018
2046
|
return { success: true, output: this.buildSummary([], Date.now() - start), duration: 0 };
|
|
2019
2047
|
}
|
|
2020
2048
|
const background = args.background === true;
|
|
2049
|
+
const team = this.config.team;
|
|
2050
|
+
if (team) {
|
|
2051
|
+
const slots = team.availableMemberSlots(parentSessionId);
|
|
2052
|
+
if (slots <= 0) {
|
|
2053
|
+
return {
|
|
2054
|
+
success: false,
|
|
2055
|
+
output: `\u8FD9\u4E2A\u4F1A\u8BDD\u5DF2\u7ECF\u6709 ${team.memberLimit} \u4E2A\u6210\u5458\u5728\u8DD1\uFF08\u5E76\u53D1\u4E0A\u9650\uFF09\uFF0C\u8FD9\u4E00\u6279\u6CA1\u6D3E\u51FA\u53BB \u2014\u2014 \u7B49\u5176\u4E2D\u4E00\u4E2A\u6536\u5DE5\u518D\u6765\uFF0C\u6216\u8005\u5148 interrupt_agent \u6536\u6389\u4E00\u4E2A`,
|
|
2056
|
+
duration: 0
|
|
2057
|
+
};
|
|
2058
|
+
}
|
|
2059
|
+
maxConcurrent = Math.min(maxConcurrent, slots);
|
|
2060
|
+
}
|
|
2021
2061
|
if (signal?.aborted) {
|
|
2022
2062
|
return { success: false, output: ABORTED, duration: 0 };
|
|
2023
2063
|
}
|
|
@@ -2037,13 +2077,13 @@ var DelegateManager = class {
|
|
|
2037
2077
|
).then((results) => {
|
|
2038
2078
|
const total = Date.now() - start;
|
|
2039
2079
|
const summary = this.buildSummary(results, total);
|
|
2040
|
-
const
|
|
2080
|
+
const ok4 = results.every((r) => r.success);
|
|
2041
2081
|
if (job) {
|
|
2042
2082
|
job.append(`
|
|
2043
2083
|
${summary}`);
|
|
2044
|
-
job.finish(
|
|
2084
|
+
job.finish(ok4 ? "exited" : "failed");
|
|
2045
2085
|
}
|
|
2046
|
-
return { results, summary, total, ok:
|
|
2086
|
+
return { results, summary, total, ok: ok4 };
|
|
2047
2087
|
});
|
|
2048
2088
|
if (background && job) {
|
|
2049
2089
|
void run.catch(() => void 0);
|
|
@@ -2120,7 +2160,9 @@ ${summary}`);
|
|
|
2120
2160
|
}
|
|
2121
2161
|
async runSingleTask(task, parentSessionId, signal, onProgress) {
|
|
2122
2162
|
const start = Date.now();
|
|
2123
|
-
const
|
|
2163
|
+
const resuming = task.resumeSessionId !== void 0;
|
|
2164
|
+
const sessionId = task.resumeSessionId ?? `delegate-${randomUUID().slice(0, 8)}`;
|
|
2165
|
+
const memberId = task.agentId ?? sessionId;
|
|
2124
2166
|
const failed = (error, summary = "") => ({
|
|
2125
2167
|
goal: task.goal,
|
|
2126
2168
|
success: false,
|
|
@@ -2129,11 +2171,29 @@ ${summary}`);
|
|
|
2129
2171
|
duration: Date.now() - start,
|
|
2130
2172
|
...task.role ? { role: task.role } : {}
|
|
2131
2173
|
});
|
|
2174
|
+
const team = this.config.team;
|
|
2132
2175
|
if (signal?.aborted) return failed(ABORTED);
|
|
2176
|
+
if (team && team.availableMemberSlots(parentSessionId) <= 0) {
|
|
2177
|
+
return failed(
|
|
2178
|
+
`\u8FD9\u4E2A\u4F1A\u8BDD\u5DF2\u7ECF\u6709 ${team.memberLimit} \u4E2A\u6210\u5458\u5728\u8DD1\uFF08\u5E76\u53D1\u4E0A\u9650\uFF09\uFF0C\u8FD9\u4E00\u4E2A\u6CA1\u6D3E\u51FA\u53BB\u3002\u7B49\u5176\u4E2D\u4E00\u4E2A\u6536\u5DE5\u518D\u6765\uFF0C\u6216\u8005\u5148 interrupt_agent \u6536\u6389\u4E00\u4E2A`
|
|
2179
|
+
);
|
|
2180
|
+
}
|
|
2181
|
+
if (resuming) {
|
|
2182
|
+
this.config.team?.markRunning(memberId);
|
|
2183
|
+
} else {
|
|
2184
|
+
this.config.team?.createMember({
|
|
2185
|
+
sessionId,
|
|
2186
|
+
parentSessionId,
|
|
2187
|
+
...task.agentId ? { agentId: task.agentId } : {},
|
|
2188
|
+
...task.role ? { role: task.role } : {}
|
|
2189
|
+
});
|
|
2190
|
+
}
|
|
2133
2191
|
const controller = new AbortController();
|
|
2192
|
+
this.config.team?.setAbort(memberId, () => controller.abort());
|
|
2134
2193
|
const unlink = linkAbort(isAbortSignal(signal) ? signal : void 0, controller);
|
|
2135
2194
|
const ms = this.config.task_timeout;
|
|
2136
2195
|
let timer;
|
|
2196
|
+
let outcome = "failed";
|
|
2137
2197
|
try {
|
|
2138
2198
|
const work = this.runner(
|
|
2139
2199
|
task.goal,
|
|
@@ -2142,7 +2202,11 @@ ${summary}`);
|
|
|
2142
2202
|
task.role,
|
|
2143
2203
|
parentSessionId,
|
|
2144
2204
|
controller.signal,
|
|
2145
|
-
|
|
2205
|
+
(line) => {
|
|
2206
|
+
this.config.team?.setActivity(memberId, line);
|
|
2207
|
+
onProgress?.(line);
|
|
2208
|
+
},
|
|
2209
|
+
resuming ? { resume: true } : void 0
|
|
2146
2210
|
);
|
|
2147
2211
|
const result = await (ms > 0 ? Promise.race([
|
|
2148
2212
|
work,
|
|
@@ -2154,6 +2218,7 @@ ${summary}`);
|
|
|
2154
2218
|
})
|
|
2155
2219
|
]) : work);
|
|
2156
2220
|
if (controller.signal.aborted) return failed(ABORTED, result.text);
|
|
2221
|
+
outcome = result.error ? "failed" : "finalized";
|
|
2157
2222
|
return {
|
|
2158
2223
|
goal: task.goal,
|
|
2159
2224
|
success: !result.error,
|
|
@@ -2162,11 +2227,12 @@ ${summary}`);
|
|
|
2162
2227
|
duration: Date.now() - start,
|
|
2163
2228
|
...task.role ? { role: task.role } : {}
|
|
2164
2229
|
};
|
|
2165
|
-
} catch (
|
|
2166
|
-
const msg =
|
|
2230
|
+
} catch (err3) {
|
|
2231
|
+
const msg = err3 instanceof Error ? err3.message : String(err3);
|
|
2167
2232
|
if (signal?.aborted) return failed(ABORTED);
|
|
2168
2233
|
return failed(msg.includes("\u8D85\u65F6") ? `[\u8D85\u65F6] ${msg}` : msg);
|
|
2169
2234
|
} finally {
|
|
2235
|
+
this.config.team?.markFinished(memberId, outcome);
|
|
2170
2236
|
clearTimeout(timer);
|
|
2171
2237
|
unlink();
|
|
2172
2238
|
}
|
|
@@ -2211,8 +2277,9 @@ function renderRoles(roles) {
|
|
|
2211
2277
|
...roles.map((r) => `- ${r.name}: ${r.description}`)
|
|
2212
2278
|
];
|
|
2213
2279
|
}
|
|
2214
|
-
function createDelegateTool(runner, config, roles) {
|
|
2280
|
+
function createDelegateTool(runner, config, roles, onManager) {
|
|
2215
2281
|
const manager = new DelegateManager(runner, config);
|
|
2282
|
+
onManager?.(manager);
|
|
2216
2283
|
const listRoles = roles ?? (() => []);
|
|
2217
2284
|
return {
|
|
2218
2285
|
name: "delegate_task",
|
|
@@ -2413,9 +2480,9 @@ function goalBlockBody(view) {
|
|
|
2413
2480
|
return lines;
|
|
2414
2481
|
}
|
|
2415
2482
|
// src/tools/builtin/goal.ts
|
|
2416
|
-
function say2(text,
|
|
2483
|
+
function say2(text, ok4, startedAt) {
|
|
2417
2484
|
const duration = Date.now() - startedAt;
|
|
2418
|
-
return
|
|
2485
|
+
return ok4 ? { success: true, output: text, duration } : { success: false, output: "", error: { code: 7101, message: text }, duration };
|
|
2419
2486
|
}
|
|
2420
2487
|
function createGoalTool(deps) {
|
|
2421
2488
|
return {
|
|
@@ -2629,8 +2696,8 @@ ${f.content}`);
|
|
|
2629
2696
|
);
|
|
2630
2697
|
}
|
|
2631
2698
|
return ok(`\u5DF2\u5220\u9664 ${target} \u8BB0\u5FC6\u6761\u76EE`, start);
|
|
2632
|
-
} catch (
|
|
2633
|
-
return fail(
|
|
2699
|
+
} catch (err3) {
|
|
2700
|
+
return fail(err3 instanceof Error ? err3.message : String(err3), start, 4002);
|
|
2634
2701
|
}
|
|
2635
2702
|
}
|
|
2636
2703
|
};
|
|
@@ -2837,9 +2904,9 @@ async function runCode(input) {
|
|
|
2837
2904
|
}
|
|
2838
2905
|
void relay(msg);
|
|
2839
2906
|
});
|
|
2840
|
-
worker.on("error", (
|
|
2907
|
+
worker.on("error", (err3) => {
|
|
2841
2908
|
if (settled) return;
|
|
2842
|
-
ending =
|
|
2909
|
+
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
2910
|
finish();
|
|
2844
2911
|
});
|
|
2845
2912
|
worker.on("exit", () => {
|
|
@@ -2862,11 +2929,11 @@ async function runCode(input) {
|
|
|
2862
2929
|
const result = await input.callTool(msg.name, msg.args);
|
|
2863
2930
|
if (result.success) reply(msg.id, { ok: true, output: result.output });
|
|
2864
2931
|
else reply(msg.id, { ok: false, fatal: false, message: result.output });
|
|
2865
|
-
} catch (
|
|
2932
|
+
} catch (err3) {
|
|
2866
2933
|
reply(msg.id, {
|
|
2867
2934
|
ok: false,
|
|
2868
2935
|
fatal: false,
|
|
2869
|
-
message:
|
|
2936
|
+
message: err3 instanceof Error ? err3.message : String(err3)
|
|
2870
2937
|
});
|
|
2871
2938
|
}
|
|
2872
2939
|
};
|
|
@@ -3959,9 +4026,9 @@ function needsAllowlist(permission2) {
|
|
|
3959
4026
|
return permission2 !== "plan" && approvalPolicyForLevel(permission2) !== "never";
|
|
3960
4027
|
}
|
|
3961
4028
|
// src/tools/builtin/schedule-draft.ts
|
|
3962
|
-
function say4(text,
|
|
4029
|
+
function say4(text, ok4, startedAt) {
|
|
3963
4030
|
const duration = Date.now() - startedAt;
|
|
3964
|
-
return
|
|
4031
|
+
return ok4 ? { success: true, output: text, duration } : { success: false, output: "", error: { code: 7201, message: text }, duration };
|
|
3965
4032
|
}
|
|
3966
4033
|
function describeRow(def) {
|
|
3967
4034
|
const state = def.enabled ? "\u542F\u7528" : "\u505C\u7528";
|
|
@@ -4188,83 +4255,1488 @@ function createScheduleDraftTool(deps) {
|
|
|
4188
4255
|
items: { type: "string" },
|
|
4189
4256
|
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
4257
|
},
|
|
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" }
|
|
4258
|
+
enabled: { type: "boolean", description: "\u53EA\u6709 update \u7528\u3002\u542F\u7528 / \u505C\u7528\u90A3\u4E00\u6761" },
|
|
4259
|
+
maxTurns: { type: "number", description: "\u53EA\u6709 update \u7528\u3002\u8F6E\u6B21\u4E0A\u9650\uFF0C\u6B63\u6574\u6570" },
|
|
4260
|
+
timeoutMs: { type: "number", description: "\u53EA\u6709 update \u7528\u3002\u5899\u949F\u8D85\u65F6\uFF0C\u6BEB\u79D2" }
|
|
4261
|
+
},
|
|
4262
|
+
required: ["action"]
|
|
4263
|
+
},
|
|
4264
|
+
exposure: ToolExposure.Direct,
|
|
4265
|
+
supportsParallel: false,
|
|
4266
|
+
annotations: {
|
|
4267
|
+
readOnlyHint: false,
|
|
4268
|
+
destructiveHint: true,
|
|
4269
|
+
idempotentHint: false,
|
|
4270
|
+
openWorldHint: false
|
|
4271
|
+
},
|
|
4272
|
+
operation: "file_read",
|
|
4273
|
+
describeTarget: (args) => `schedule_draft:${String(args["action"] ?? "list")}`,
|
|
4274
|
+
async execute(rawArgs, ctx) {
|
|
4275
|
+
const startedAt = Date.now();
|
|
4276
|
+
const action = rawArgs["action"];
|
|
4277
|
+
if (action === "list") {
|
|
4278
|
+
const rows = deps.list();
|
|
4279
|
+
return say4(
|
|
4280
|
+
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
|
|
4281
|
+
${rows.map(describeRow).join("\n")}`,
|
|
4282
|
+
true,
|
|
4283
|
+
startedAt
|
|
4284
|
+
);
|
|
4285
|
+
}
|
|
4286
|
+
const parsed = parseScheduleDraft(rawArgs);
|
|
4287
|
+
if (!parsed.ok) return say4(parsed.message, false, startedAt);
|
|
4288
|
+
const draft = parsed.value;
|
|
4289
|
+
const current = draft.action === "update" ? deps.get(draft.id) : void 0;
|
|
4290
|
+
if (draft.action === "update" && current === void 0) {
|
|
4291
|
+
return say4(
|
|
4292
|
+
`\u6CA1\u6709 id \u4E3A ${draft.id} \u7684\u4EFB\u52A1\u3002\u5148\u7528 action=list \u770B\u4E00\u773C\u73B0\u6709\u7684\u3002`,
|
|
4293
|
+
false,
|
|
4294
|
+
startedAt
|
|
4295
|
+
);
|
|
4296
|
+
}
|
|
4297
|
+
const issues = validateDraft(draft, deps.homeDir, current);
|
|
4298
|
+
if (issues.length > 0) {
|
|
4299
|
+
return say4(
|
|
4300
|
+
`\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`,
|
|
4301
|
+
false,
|
|
4302
|
+
startedAt
|
|
4303
|
+
);
|
|
4304
|
+
}
|
|
4305
|
+
const unattended = unattendedIssues(draft);
|
|
4306
|
+
if (unattended.length > 0) {
|
|
4307
|
+
return say4(
|
|
4308
|
+
`\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
|
|
4309
|
+
${unattended.map((x) => `\xB7 ${x}`).join("\n")}`,
|
|
4310
|
+
false,
|
|
4311
|
+
startedAt
|
|
4312
|
+
);
|
|
4313
|
+
}
|
|
4314
|
+
const readOnly = ctx.permissionLevel === "plan";
|
|
4315
|
+
if (readOnly || deps.save === void 0) {
|
|
4316
|
+
return say4(summarizeProposal(draft, current, readOnly), true, startedAt);
|
|
4317
|
+
}
|
|
4318
|
+
const saved = await persist(deps.save, draft, current);
|
|
4319
|
+
if (saved.issues.length > 0) {
|
|
4320
|
+
const codes = saved.issues.map((x) => x.detail ? `${x.code}\uFF08${x.detail}\uFF09` : x.code);
|
|
4321
|
+
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);
|
|
4322
|
+
}
|
|
4323
|
+
const def = saved.schedule;
|
|
4324
|
+
if (def === void 0) {
|
|
4325
|
+
return say4(
|
|
4326
|
+
"\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",
|
|
4327
|
+
false,
|
|
4328
|
+
startedAt
|
|
4329
|
+
);
|
|
4330
|
+
}
|
|
4331
|
+
return say4(summarizeSaved(draft, def, saved.registration, current), true, startedAt);
|
|
4332
|
+
}
|
|
4333
|
+
};
|
|
4334
|
+
}
|
|
4335
|
+
var DEFAULT_INBOX_CAPACITY = 20;
|
|
4336
|
+
var AgentInbox = class {
|
|
4337
|
+
constructor(capacity = DEFAULT_INBOX_CAPACITY) {
|
|
4338
|
+
this.capacity = capacity;
|
|
4339
|
+
}
|
|
4340
|
+
capacity;
|
|
4341
|
+
queue = [];
|
|
4342
|
+
dropped = 0;
|
|
4343
|
+
push(msg) {
|
|
4344
|
+
let evicted = false;
|
|
4345
|
+
while (this.queue.length >= this.capacity) {
|
|
4346
|
+
this.queue.shift();
|
|
4347
|
+
this.dropped += 1;
|
|
4348
|
+
evicted = true;
|
|
4349
|
+
}
|
|
4350
|
+
this.queue.push(msg);
|
|
4351
|
+
return !evicted;
|
|
4352
|
+
}
|
|
4353
|
+
pending() {
|
|
4354
|
+
return this.queue.length > 0;
|
|
4355
|
+
}
|
|
4356
|
+
take() {
|
|
4357
|
+
if (this.queue.length === 0) return [];
|
|
4358
|
+
const lines = this.queue.map((m) => agentMessageLine(m));
|
|
4359
|
+
this.queue = [];
|
|
4360
|
+
if (this.dropped > 0) {
|
|
4361
|
+
lines.unshift(systemNote(`\u6536\u4EF6\u7BB1\u6EE1\u4E86\uFF0C\u6709 ${this.dropped} \u6761\u66F4\u65E9\u7684\u6D88\u606F\u88AB\u4E22\u5F03`));
|
|
4362
|
+
this.dropped = 0;
|
|
4363
|
+
}
|
|
4364
|
+
return [lines.join("\n")];
|
|
4365
|
+
}
|
|
4366
|
+
get size() {
|
|
4367
|
+
return this.queue.length;
|
|
4368
|
+
}
|
|
4369
|
+
};
|
|
4370
|
+
var DEFAULT_TASK_CAPACITY = 200;
|
|
4371
|
+
var TeamTaskBoard = class {
|
|
4372
|
+
constructor(capacity = DEFAULT_TASK_CAPACITY) {
|
|
4373
|
+
this.capacity = capacity;
|
|
4374
|
+
}
|
|
4375
|
+
capacity;
|
|
4376
|
+
tasks = /* @__PURE__ */ new Map();
|
|
4377
|
+
listeners = /* @__PURE__ */ new Set();
|
|
4378
|
+
onChange(cb) {
|
|
4379
|
+
this.listeners.add(cb);
|
|
4380
|
+
return () => {
|
|
4381
|
+
this.listeners.delete(cb);
|
|
4382
|
+
};
|
|
4383
|
+
}
|
|
4384
|
+
notify() {
|
|
4385
|
+
for (const cb of this.listeners) {
|
|
4386
|
+
try {
|
|
4387
|
+
cb();
|
|
4388
|
+
} catch {
|
|
4389
|
+
}
|
|
4390
|
+
}
|
|
4391
|
+
}
|
|
4392
|
+
create(input) {
|
|
4393
|
+
if (this.tasks.size >= this.capacity) {
|
|
4394
|
+
return { ok: false, reason: `\u4EFB\u52A1\u677F\u6EE1\u4E86\uFF08${this.capacity} \u6761\uFF09\uFF0C\u5148\u505A\u5B8C\u518D\u5EFA` };
|
|
4395
|
+
}
|
|
4396
|
+
const dependsOn = input.dependsOn ?? [];
|
|
4397
|
+
const missing = dependsOn.filter((id) => !this.tasks.has(id));
|
|
4398
|
+
if (missing.length > 0) {
|
|
4399
|
+
return { ok: false, reason: `\u4F9D\u8D56\u7684\u4EFB\u52A1\u4E0D\u5B58\u5728\uFF1A${missing.join(", ")}` };
|
|
4400
|
+
}
|
|
4401
|
+
const now = Date.now();
|
|
4402
|
+
const task = {
|
|
4403
|
+
id: `task-${randomUUID().slice(0, 8)}`,
|
|
4404
|
+
title: input.title,
|
|
4405
|
+
...input.description ? { description: input.description } : {},
|
|
4406
|
+
...input.owner ? { owner: input.owner } : {},
|
|
4407
|
+
status: "pending",
|
|
4408
|
+
dependsOn,
|
|
4409
|
+
revision: 1,
|
|
4410
|
+
createdAt: now,
|
|
4411
|
+
updatedAt: now
|
|
4412
|
+
};
|
|
4413
|
+
this.tasks.set(task.id, task);
|
|
4414
|
+
this.notify();
|
|
4415
|
+
return { ok: true, task: { ...task } };
|
|
4416
|
+
}
|
|
4417
|
+
get(id) {
|
|
4418
|
+
const t83 = this.tasks.get(id);
|
|
4419
|
+
return t83 ? { ...t83 } : void 0;
|
|
4420
|
+
}
|
|
4421
|
+
list(filter) {
|
|
4422
|
+
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 }));
|
|
4423
|
+
}
|
|
4424
|
+
update(id, patch, expectedRevision) {
|
|
4425
|
+
const current = this.tasks.get(id);
|
|
4426
|
+
if (!current) return { ok: false, reason: `\u6CA1\u6709\u8FD9\u4E2A\u4EFB\u52A1\uFF1A${id}` };
|
|
4427
|
+
if (expectedRevision !== void 0 && current.revision !== expectedRevision) {
|
|
4428
|
+
return {
|
|
4429
|
+
ok: false,
|
|
4430
|
+
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`
|
|
4431
|
+
};
|
|
4432
|
+
}
|
|
4433
|
+
const next = {
|
|
4434
|
+
...current,
|
|
4435
|
+
...patch.title !== void 0 ? { title: patch.title } : {},
|
|
4436
|
+
...patch.description !== void 0 ? { description: patch.description } : {},
|
|
4437
|
+
...patch.status !== void 0 ? { status: patch.status } : {},
|
|
4438
|
+
...patch.owner !== void 0 ? { owner: patch.owner } : {},
|
|
4439
|
+
revision: current.revision + 1,
|
|
4440
|
+
updatedAt: Date.now()
|
|
4441
|
+
};
|
|
4442
|
+
this.tasks.set(id, next);
|
|
4443
|
+
this.notify();
|
|
4444
|
+
return { ok: true, task: { ...next } };
|
|
4445
|
+
}
|
|
4446
|
+
};
|
|
4447
|
+
// src/team/registry.ts
|
|
4448
|
+
var DEFAULT_MAX_RUNNING_MEMBERS = 3;
|
|
4449
|
+
var DEFAULT_MAX_WOKEN_SESSIONS = 3;
|
|
4450
|
+
var WAKE_RAMP_MS = 6e4;
|
|
4451
|
+
var TeamRegistry = class {
|
|
4452
|
+
constructor(inboxCapacity = DEFAULT_INBOX_CAPACITY, limits = {}) {
|
|
4453
|
+
this.inboxCapacity = inboxCapacity;
|
|
4454
|
+
this.limits = {
|
|
4455
|
+
maxRunningMembers: limits.maxRunningMembers ?? DEFAULT_MAX_RUNNING_MEMBERS,
|
|
4456
|
+
maxWokenSessions: limits.maxWokenSessions ?? DEFAULT_MAX_WOKEN_SESSIONS
|
|
4457
|
+
};
|
|
4458
|
+
this.tasks = new TeamTaskBoard();
|
|
4459
|
+
this.tasks.onChange(() => this.notify());
|
|
4460
|
+
}
|
|
4461
|
+
inboxCapacity;
|
|
4462
|
+
members = /* @__PURE__ */ new Map();
|
|
4463
|
+
bySessionId = /* @__PURE__ */ new Map();
|
|
4464
|
+
mainInboxes = /* @__PURE__ */ new Map();
|
|
4465
|
+
sessions = /* @__PURE__ */ new Set();
|
|
4466
|
+
activeTurns = /* @__PURE__ */ new Map();
|
|
4467
|
+
wokenSessions = /* @__PURE__ */ new Map();
|
|
4468
|
+
limits;
|
|
4469
|
+
bridge;
|
|
4470
|
+
aborters = /* @__PURE__ */ new Map();
|
|
4471
|
+
listeners = /* @__PURE__ */ new Set();
|
|
4472
|
+
tasks;
|
|
4473
|
+
onChange(cb) {
|
|
4474
|
+
this.listeners.add(cb);
|
|
4475
|
+
return () => {
|
|
4476
|
+
this.listeners.delete(cb);
|
|
4477
|
+
};
|
|
4478
|
+
}
|
|
4479
|
+
notify() {
|
|
4480
|
+
for (const cb of this.listeners) {
|
|
4481
|
+
try {
|
|
4482
|
+
cb();
|
|
4483
|
+
} catch {
|
|
4484
|
+
}
|
|
4485
|
+
}
|
|
4486
|
+
}
|
|
4487
|
+
waitForChange(ms, signal) {
|
|
4488
|
+
return new Promise((resolve17) => {
|
|
4489
|
+
let done2 = false;
|
|
4490
|
+
const onAbort = () => finish(false);
|
|
4491
|
+
const cleanup = () => {
|
|
4492
|
+
off();
|
|
4493
|
+
clearTimeout(timer);
|
|
4494
|
+
signal?.removeEventListener?.("abort", onAbort);
|
|
4495
|
+
};
|
|
4496
|
+
const finish = (v) => {
|
|
4497
|
+
if (done2) return;
|
|
4498
|
+
done2 = true;
|
|
4499
|
+
cleanup();
|
|
4500
|
+
resolve17(v);
|
|
4501
|
+
};
|
|
4502
|
+
const off = this.onChange(() => finish(true));
|
|
4503
|
+
const timer = setTimeout(() => finish(false), ms);
|
|
4504
|
+
signal?.addEventListener?.("abort", onAbort);
|
|
4505
|
+
});
|
|
4506
|
+
}
|
|
4507
|
+
createMember(args) {
|
|
4508
|
+
const agentId = args.agentId ?? args.sessionId;
|
|
4509
|
+
if (this.members.has(agentId)) {
|
|
4510
|
+
throw new Error(`\u6210\u5458\u540D\u5DF2\u88AB\u5360\u7528\uFF1A${agentId}`);
|
|
4511
|
+
}
|
|
4512
|
+
const info = {
|
|
4513
|
+
agentId,
|
|
4514
|
+
sessionId: args.sessionId,
|
|
4515
|
+
parentSessionId: args.parentSessionId,
|
|
4516
|
+
status: "running",
|
|
4517
|
+
...args.role ? { role: args.role } : {},
|
|
4518
|
+
startedAt: Date.now()
|
|
4519
|
+
};
|
|
4520
|
+
this.members.set(agentId, {
|
|
4521
|
+
info,
|
|
4522
|
+
inbox: new AgentInbox(this.inboxCapacity)
|
|
4523
|
+
});
|
|
4524
|
+
this.bySessionId.set(args.sessionId, agentId);
|
|
4525
|
+
this.notify();
|
|
4526
|
+
return { ...info };
|
|
4527
|
+
}
|
|
4528
|
+
setAbort(agentId, fn) {
|
|
4529
|
+
if (!this.members.has(agentId)) return;
|
|
4530
|
+
this.aborters.set(agentId, fn);
|
|
4531
|
+
}
|
|
4532
|
+
interrupt(agentId) {
|
|
4533
|
+
const fn = this.aborters.get(agentId);
|
|
4534
|
+
if (!fn) return false;
|
|
4535
|
+
fn();
|
|
4536
|
+
this.notify();
|
|
4537
|
+
return true;
|
|
4538
|
+
}
|
|
4539
|
+
get(agentId) {
|
|
4540
|
+
const entry = this.members.get(agentId);
|
|
4541
|
+
return entry ? { ...entry.info } : void 0;
|
|
4542
|
+
}
|
|
4543
|
+
bySession(sessionId) {
|
|
4544
|
+
const agentId = this.bySessionId.get(sessionId);
|
|
4545
|
+
return agentId ? this.get(agentId) : void 0;
|
|
4546
|
+
}
|
|
4547
|
+
list() {
|
|
4548
|
+
return [...this.members.values()].map((e) => e.info).sort((a, b) => a.startedAt - b.startedAt);
|
|
4549
|
+
}
|
|
4550
|
+
inboxOf(agentId) {
|
|
4551
|
+
return this.members.get(agentId)?.inbox;
|
|
4552
|
+
}
|
|
4553
|
+
inboxBySession(sessionId) {
|
|
4554
|
+
const agentId = this.bySessionId.get(sessionId);
|
|
4555
|
+
return agentId ? this.inboxOf(agentId) : void 0;
|
|
4556
|
+
}
|
|
4557
|
+
registerSession(sessionId) {
|
|
4558
|
+
if (this.sessions.has(sessionId)) return;
|
|
4559
|
+
this.sessions.add(sessionId);
|
|
4560
|
+
this.notify();
|
|
4561
|
+
}
|
|
4562
|
+
hasSession(sessionId) {
|
|
4563
|
+
return this.sessions.has(sessionId);
|
|
4564
|
+
}
|
|
4565
|
+
beginSessionTurn(sessionId) {
|
|
4566
|
+
this.activeTurns.set(sessionId, (this.activeTurns.get(sessionId) ?? 0) + 1);
|
|
4567
|
+
}
|
|
4568
|
+
endSessionTurn(sessionId) {
|
|
4569
|
+
const n = this.activeTurns.get(sessionId);
|
|
4570
|
+
if (n === void 0) return;
|
|
4571
|
+
if (n <= 1) {
|
|
4572
|
+
this.activeTurns.delete(sessionId);
|
|
4573
|
+
this.wokenSessions.delete(sessionId);
|
|
4574
|
+
return;
|
|
4575
|
+
}
|
|
4576
|
+
this.activeTurns.set(sessionId, n - 1);
|
|
4577
|
+
}
|
|
4578
|
+
isSessionActive(sessionId) {
|
|
4579
|
+
return this.activeTurns.has(sessionId);
|
|
4580
|
+
}
|
|
4581
|
+
setSessionBridge(bridge) {
|
|
4582
|
+
this.bridge = bridge;
|
|
4583
|
+
}
|
|
4584
|
+
async wakeSession(sessionId, text) {
|
|
4585
|
+
if (!this.bridge) {
|
|
4586
|
+
return {
|
|
4587
|
+
ok: false,
|
|
4588
|
+
reason: "\u8FD9\u4E2A\u5BBF\u4E3B\u4E0D\u652F\u6301\u5524\u9192\u522B\u7684\u4F1A\u8BDD\uFF08CLI \u5355\u4F1A\u8BDD\u6A21\u5F0F\uFF09\u3002\u8BA9\u5B83\u81EA\u5DF1\u53D1\u4E00\u53E5\u8BDD\u624D\u80FD\u63A5\u4E0A"
|
|
4589
|
+
};
|
|
4590
|
+
}
|
|
4591
|
+
const now = Date.now();
|
|
4592
|
+
this.reapWokenSessions(now);
|
|
4593
|
+
if (this.wokenSessions.has(sessionId)) {
|
|
4594
|
+
return {
|
|
4595
|
+
ok: false,
|
|
4596
|
+
reason: `${sessionId} \u521A\u88AB\u53EB\u8D77\u6765\uFF0C\u8FD8\u6CA1\u771F\u6B63\u5F00\u8DD1 \u2014\u2014 \u522B\u91CD\u590D\u53EB\u3002\u770B\u5B83\u7B54\u4E86\u4EC0\u4E48\uFF1Asession_messages_read ${sessionId}`
|
|
4597
|
+
};
|
|
4598
|
+
}
|
|
4599
|
+
if (this.wokenSessions.size >= this.limits.maxWokenSessions) {
|
|
4600
|
+
return {
|
|
4601
|
+
ok: false,
|
|
4602
|
+
reason: `\u73B0\u5728\u5DF2\u7ECF\u6709 ${this.wokenSessions.size} \u6BB5\u88AB\u53EB\u9192\u7684\u4F1A\u8BDD\u5728\u8DD1\uFF08\u4E0A\u9650 ${this.limits.maxWokenSessions} \u6BB5\uFF09\u2014\u2014 \u7B49\u5176\u4E2D\u4E00\u6BB5\u8DD1\u5B8C\u518D\u53EB\u4E0B\u4E00\u4E2A\uFF0C\u6216\u8005\u628A\u5B83\u4EEC\u8981\u5E72\u7684\u4E8B\u5199\u8FDB\u4F60\u81EA\u5DF1\u7684\u7ED3\u8BBA\u91CC`
|
|
4603
|
+
};
|
|
4604
|
+
}
|
|
4605
|
+
const r = await this.bridge.wake(sessionId, text);
|
|
4606
|
+
if (r.ok) this.wokenSessions.set(sessionId, now);
|
|
4607
|
+
return r;
|
|
4608
|
+
}
|
|
4609
|
+
reapWokenSessions(now) {
|
|
4610
|
+
for (const [id, at] of this.wokenSessions) {
|
|
4611
|
+
if (!this.activeTurns.has(id) && now - at > WAKE_RAMP_MS) this.wokenSessions.delete(id);
|
|
4612
|
+
}
|
|
4613
|
+
}
|
|
4614
|
+
get memberLimit() {
|
|
4615
|
+
return this.limits.maxRunningMembers;
|
|
4616
|
+
}
|
|
4617
|
+
availableMemberSlots(parentSessionId) {
|
|
4618
|
+
let running = 0;
|
|
4619
|
+
for (const entry of this.members.values()) {
|
|
4620
|
+
if (entry.info.parentSessionId === parentSessionId && entry.info.status === "running") {
|
|
4621
|
+
running += 1;
|
|
4622
|
+
}
|
|
4623
|
+
}
|
|
4624
|
+
return Math.max(0, this.limits.maxRunningMembers - running);
|
|
4625
|
+
}
|
|
4626
|
+
sessionExists(sessionId) {
|
|
4627
|
+
if (this.bridge) return this.bridge.exists(sessionId);
|
|
4628
|
+
return this.sessions.has(sessionId);
|
|
4629
|
+
}
|
|
4630
|
+
sessionTitle(sessionId) {
|
|
4631
|
+
return this.bridge?.title?.(sessionId);
|
|
4632
|
+
}
|
|
4633
|
+
sessionIds() {
|
|
4634
|
+
return [...this.sessions];
|
|
4635
|
+
}
|
|
4636
|
+
mainInbox(sessionId) {
|
|
4637
|
+
let inbox = this.mainInboxes.get(sessionId);
|
|
4638
|
+
if (!inbox) {
|
|
4639
|
+
inbox = new AgentInbox(this.inboxCapacity);
|
|
4640
|
+
this.mainInboxes.set(sessionId, inbox);
|
|
4641
|
+
}
|
|
4642
|
+
return inbox;
|
|
4643
|
+
}
|
|
4644
|
+
setActivity(agentId, line) {
|
|
4645
|
+
const entry = this.members.get(agentId);
|
|
4646
|
+
if (!entry) return;
|
|
4647
|
+
entry.info.activity = line;
|
|
4648
|
+
}
|
|
4649
|
+
markRunning(agentId) {
|
|
4650
|
+
const entry = this.members.get(agentId);
|
|
4651
|
+
if (!entry) return;
|
|
4652
|
+
entry.info.status = "running";
|
|
4653
|
+
delete entry.info.finishedAt;
|
|
4654
|
+
delete entry.info.activity;
|
|
4655
|
+
this.notify();
|
|
4656
|
+
}
|
|
4657
|
+
markFinished(agentId, status) {
|
|
4658
|
+
const entry = this.members.get(agentId);
|
|
4659
|
+
if (!entry) return;
|
|
4660
|
+
if (entry.info.finishedAt !== void 0) return;
|
|
4661
|
+
entry.info.status = status;
|
|
4662
|
+
entry.info.finishedAt = Date.now();
|
|
4663
|
+
this.aborters.delete(agentId);
|
|
4664
|
+
this.notify();
|
|
4665
|
+
}
|
|
4666
|
+
deliver(msg) {
|
|
4667
|
+
if (msg.to === LEAD_AGENT_ID) {
|
|
4668
|
+
const sender = this.members.get(msg.from);
|
|
4669
|
+
if (sender) {
|
|
4670
|
+
const parent = sender.info.parentSessionId;
|
|
4671
|
+
this.mainInbox(parent).push(msg);
|
|
4672
|
+
this.notify();
|
|
4673
|
+
return { ok: true, to: msg.to, status: this.isSessionActive(parent) ? "running" : "idle" };
|
|
4674
|
+
}
|
|
4675
|
+
return { ok: false, to: msg.to, reason: `\u4E3B\u4F1A\u8BDD\u4E0D\u80FD\u53D1\u7ED9 ${LEAD_AGENT_ID}` };
|
|
4676
|
+
}
|
|
4677
|
+
const entry = this.members.get(msg.to);
|
|
4678
|
+
if (entry) {
|
|
4679
|
+
if (entry.info.status === "finalized" || entry.info.status === "failed") {
|
|
4680
|
+
return {
|
|
4681
|
+
ok: false,
|
|
4682
|
+
to: msg.to,
|
|
4683
|
+
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`
|
|
4684
|
+
};
|
|
4685
|
+
}
|
|
4686
|
+
entry.inbox.push(msg);
|
|
4687
|
+
this.notify();
|
|
4688
|
+
return { ok: true, to: msg.to, status: entry.info.status };
|
|
4689
|
+
}
|
|
4690
|
+
if (this.isSessionActive(msg.to)) {
|
|
4691
|
+
this.mainInbox(msg.to).push(msg);
|
|
4692
|
+
this.notify();
|
|
4693
|
+
return { ok: true, to: msg.to, status: "running" };
|
|
4694
|
+
}
|
|
4695
|
+
if (this.sessionExists(msg.to)) {
|
|
4696
|
+
const senderIsMember = this.members.has(msg.from);
|
|
4697
|
+
return {
|
|
4698
|
+
ok: false,
|
|
4699
|
+
to: msg.to,
|
|
4700
|
+
reason: senderIsMember ? `${msg.to} \u73B0\u5728\u6CA1\u5728\u8DD1\uFF0C\u4E0B\u4E00\u8F6E\u4E0D\u4F1A\u6765 \u2014\u2014 \u8FD9\u6761\u6D88\u606F\u6CA1\u9001\u51FA\u53BB\u3002\u4F60\u53EB\u4E0D\u9192\u522B\u7684\u4F1A\u8BDD\uFF08\u6210\u5458\u62FF\u4E0D\u5230 followup_task\uFF09\uFF1A\u8981\u7D27\u7684\u8BDD\u5199\u8FDB\u4F60\u8FD9\u4E00\u8F6E\u7684\u7ED3\u8BBA\u91CC\uFF0C\u6D3E\u4F60\u51FA\u6765\u7684\u4F1A\u8BDD\u4F1A\u770B\u5230` : `${msg.to} \u73B0\u5728\u6CA1\u5728\u8DD1\uFF0C\u4E0B\u4E00\u8F6E\u4E0D\u4F1A\u6765 \u2014\u2014 \u8FD9\u6761\u6D88\u606F\u6CA1\u9001\u51FA\u53BB\u3002\u8981\u7528 followup_task \u628A\u5B83\u53EB\u8D77\u6765\u8DD1\u4E00\u8F6E\uFF08agentId \u586B ${msg.to}\uFF0Cmessage \u586B\u4F60\u8981\u8BF4\u7684\u8BDD\uFF09`
|
|
4701
|
+
};
|
|
4702
|
+
}
|
|
4703
|
+
return {
|
|
4704
|
+
ok: false,
|
|
4705
|
+
to: msg.to,
|
|
4706
|
+
reason: `\u6CA1\u6709\u8FD9\u4E2A\u6210\u5458\u6216\u4F1A\u8BDD\uFF1A${msg.to}\u3002\u7528 list_agents --all \u770B\u73B0\u5728\u6709\u8C01`
|
|
4707
|
+
};
|
|
4708
|
+
}
|
|
4709
|
+
static message(args) {
|
|
4710
|
+
return {
|
|
4711
|
+
id: randomUUID(),
|
|
4712
|
+
from: args.from,
|
|
4713
|
+
to: args.to,
|
|
4714
|
+
text: args.text,
|
|
4715
|
+
sentAt: Date.now(),
|
|
4716
|
+
...args.fromLabel ? { fromLabel: args.fromLabel } : {}
|
|
4717
|
+
};
|
|
4718
|
+
}
|
|
4719
|
+
};
|
|
4720
|
+
// src/tools/builtin/send-message.ts
|
|
4721
|
+
var SEND_MESSAGE_TOOL = "send_message";
|
|
4722
|
+
function createSendMessageTool(team) {
|
|
4723
|
+
return {
|
|
4724
|
+
name: SEND_MESSAGE_TOOL,
|
|
4725
|
+
description: [
|
|
4726
|
+
"\u7ED9\u53E6\u4E00\u4E2A agent \u6216**\u6B63\u6709\u4E00\u6BB5\u5728\u8DD1\u7684\u4E3B\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",
|
|
4727
|
+
"\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",
|
|
4728
|
+
`\u53D1\u7ED9 \`${LEAD_AGENT_ID}\`\uFF08\u6D3E\u4F60\u51FA\u6765\u7684\u90A3\u4E2A\u4F1A\u8BDD\uFF09\uFF1A\u5B83\u5728\u8DD1\u65F6\u63A5\u4E0B\u6765\u7684\u6B65\u9AA4\u91CC\u4F1A\u770B\u5230\uFF1B\u5B83\u6CA1\u5728\u8DD1\u65F6\u8FD9\u6761\u53EA\u662F\u6392\u8FDB\u5B83\u7684\u6536\u4EF6\u7BB1\uFF0C\u7B49\u5B83\u4E0B\u6B21\u8DD1\u8D77\u6765\u624D\u8BFB\u5F97\u5230\uFF08\u4F60\u73B0\u5728\u7B49\u4E0D\u5230\u56DE\u97F3\uFF09\u3002`,
|
|
4729
|
+
"\u53D1\u7ED9**\u53E6\u4E00\u6BB5\u4E3B\u4F1A\u8BDD**\uFF08\u7528 list_agents --all \u770B\u5230\u7684\u90A3\u4E2A sessionId\uFF09\uFF1A\u53EA\u6709\u5B83**\u6B64\u523B\u6B63\u5728\u8DD1**\u624D\u9001\u5F97\u5230\u3002",
|
|
4730
|
+
"\u5BF9\u65B9\u6CA1\u5728\u8DD1\uFF08\u4F11\u7720 / \u5DF2\u7ECF\u6536\u5DE5\uFF09\u4F1A\u5F53\u573A\u5931\u8D25\uFF08\u53D1\u7ED9 lead \u90A3\u4E00\u6761\u9664\u5916\uFF0C\u5B83\u6392\u961F\uFF09\u2014\u2014 \u90A3\u79CD\u60C5\u51B5\u7528 followup_task \u628A\u5B83\u53EB\u8D77\u6765\u8DD1\u4E00\u8F6E\uFF0C\u522B\u5E72\u7B49\u3002",
|
|
4731
|
+
"\u7528 list_agents \u770B\u672C\u4F1A\u8BDD\u7684\u6210\u5458\uFF1B\u52A0 --all \u770B\u6240\u6709\u4F1A\u8BDD\u548C\u6210\u5458\u3002"
|
|
4732
|
+
].join("\n"),
|
|
4733
|
+
parameters: {
|
|
4734
|
+
type: "object",
|
|
4735
|
+
properties: {
|
|
4736
|
+
to: {
|
|
4737
|
+
type: "string",
|
|
4738
|
+
description: `\u6536\u4EF6\u4EBA\uFF1A\u67D0\u4E2A\u6210\u5458\u7684 id\uFF0C\u6216 \`${LEAD_AGENT_ID}\``
|
|
4739
|
+
},
|
|
4740
|
+
text: {
|
|
4741
|
+
type: "string",
|
|
4742
|
+
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"
|
|
4743
|
+
}
|
|
4744
|
+
},
|
|
4745
|
+
required: ["to", "text"]
|
|
4746
|
+
},
|
|
4747
|
+
exposure: ToolExposure.Direct,
|
|
4748
|
+
supportsParallel: false,
|
|
4749
|
+
operation: "file_read",
|
|
4750
|
+
annotations: {
|
|
4751
|
+
readOnlyHint: true,
|
|
4752
|
+
destructiveHint: false,
|
|
4753
|
+
idempotentHint: false,
|
|
4754
|
+
openWorldHint: false
|
|
4755
|
+
},
|
|
4756
|
+
describeTarget: (args) => String(args["to"] ?? ""),
|
|
4757
|
+
async execute(args, ctx) {
|
|
4758
|
+
const start = Date.now();
|
|
4759
|
+
const to = typeof args["to"] === "string" ? args["to"].trim() : "";
|
|
4760
|
+
const text = typeof args["text"] === "string" ? args["text"].trim() : "";
|
|
4761
|
+
if (!to) {
|
|
4762
|
+
return {
|
|
4763
|
+
success: false,
|
|
4764
|
+
output: "",
|
|
4765
|
+
error: {
|
|
4766
|
+
code: 7101,
|
|
4767
|
+
message: "\u7F3A\u5C11\u6536\u4EF6\u4EBA\uFF08to\uFF09",
|
|
4768
|
+
suggestion: `\u586B\u4E00\u4E2A\u6210\u5458 id\uFF0C\u6216 \`${LEAD_AGENT_ID}\``
|
|
4769
|
+
},
|
|
4770
|
+
duration: Date.now() - start
|
|
4771
|
+
};
|
|
4772
|
+
}
|
|
4773
|
+
if (!text) {
|
|
4774
|
+
return {
|
|
4775
|
+
success: false,
|
|
4776
|
+
output: "",
|
|
4777
|
+
error: { code: 7102, message: "\u6D88\u606F\u5185\u5BB9\uFF08text\uFF09\u662F\u7A7A\u7684" },
|
|
4778
|
+
duration: Date.now() - start
|
|
4779
|
+
};
|
|
4780
|
+
}
|
|
4781
|
+
const memberInfo = team.bySession(ctx.sessionId);
|
|
4782
|
+
const target = team.get(to);
|
|
4783
|
+
const ownMember = target !== void 0 && target.parentSessionId === ctx.sessionId;
|
|
4784
|
+
const from = memberInfo ? memberInfo.agentId : ownMember ? LEAD_AGENT_ID : ctx.sessionId;
|
|
4785
|
+
const labelled = from === ctx.sessionId ? sessionSenderLabel(from, team.sessionTitle(from)) : "";
|
|
4786
|
+
const result = team.deliver(
|
|
4787
|
+
TeamRegistry.message({
|
|
4788
|
+
from,
|
|
4789
|
+
to,
|
|
4790
|
+
text,
|
|
4791
|
+
...labelled && labelled !== from ? { fromLabel: labelled } : {}
|
|
4792
|
+
})
|
|
4793
|
+
);
|
|
4794
|
+
if (!result.ok) {
|
|
4795
|
+
return {
|
|
4796
|
+
success: false,
|
|
4797
|
+
output: "",
|
|
4798
|
+
error: { code: 7103, message: result.reason },
|
|
4799
|
+
duration: Date.now() - start
|
|
4800
|
+
};
|
|
4801
|
+
}
|
|
4802
|
+
if (result.status !== "running") {
|
|
4803
|
+
const who = result.to === LEAD_AGENT_ID ? "lead" : result.to;
|
|
4804
|
+
return {
|
|
4805
|
+
success: true,
|
|
4806
|
+
output: `\u5DF2\u6392\u8FDB ${who} \u7684\u6536\u4EF6\u7BB1\uFF0C\u4F46\u5B83\u73B0\u5728\u6CA1\u5728\u8DD1 \u2014\u2014 \u8FD9\u6761\u8981\u7B49\u5B83\u4E0B\u6B21\u8DD1\u8D77\u6765\u624D\u4F1A\u88AB\u8BFB\u5230\uFF0C\u4F60\u73B0\u5728\u7B49\u4E0D\u5230\u56DE\u97F3\u3002` + (result.to === LEAD_AGENT_ID ? "\u8981\u7D27\u7684\u8BDD\u4E5F\u5199\u8FDB\u4F60\u8FD9\u4E00\u8F6E\u7684\u7ED3\u8BBA\u91CC\u3002" : ""),
|
|
4807
|
+
duration: Date.now() - start
|
|
4808
|
+
};
|
|
4809
|
+
}
|
|
4810
|
+
return {
|
|
4811
|
+
success: true,
|
|
4812
|
+
output: result.to === LEAD_AGENT_ID ? `\u5DF2\u9001\u5230 lead\uFF0C\u5B83\u63A5\u4E0B\u6765\u7684\u6B65\u9AA4\u91CC\u4F1A\u770B\u5230\u3002` : `\u5DF2\u9001\u5230 ${result.to}\uFF0C\u5B83\u6B63\u5728\u8DD1\u7684\u90A3\u4E00\u8F6E\u4F1A\u770B\u5230\u3002`,
|
|
4813
|
+
duration: Date.now() - start
|
|
4814
|
+
};
|
|
4815
|
+
}
|
|
4816
|
+
};
|
|
4817
|
+
}
|
|
4818
|
+
function err(code, message, suggestion) {
|
|
4819
|
+
return {
|
|
4820
|
+
success: false,
|
|
4821
|
+
output: "",
|
|
4822
|
+
error: { code, message, ...{} },
|
|
4823
|
+
duration: 0
|
|
4824
|
+
};
|
|
4825
|
+
}
|
|
4826
|
+
function ok2(output) {
|
|
4827
|
+
return { success: true, output, duration: 0 };
|
|
4828
|
+
}
|
|
4829
|
+
function str2(args, key) {
|
|
4830
|
+
const v = args[key];
|
|
4831
|
+
return typeof v === "string" ? v.trim() : "";
|
|
4832
|
+
}
|
|
4833
|
+
function parseTarget(raw) {
|
|
4834
|
+
const t83 = raw.trim();
|
|
4835
|
+
if (!t83) return null;
|
|
4836
|
+
return t83.startsWith("th-") ? { kind: "thread", id: t83 } : { kind: "channel", name: t83 };
|
|
4837
|
+
}
|
|
4838
|
+
function authorOf(deps, ctx) {
|
|
4839
|
+
return deps.agentOf(ctx.sessionId) ?? LEAD_AGENT_ID;
|
|
4840
|
+
}
|
|
4841
|
+
function renderPost(p) {
|
|
4842
|
+
const who = p.author;
|
|
4843
|
+
const when = new Date(p.createdAt).toISOString().slice(0, 16).replace("T", " ");
|
|
4844
|
+
const body2 = p.text.length > 2e3 ? `${p.text.slice(0, 2e3)}\u2026` : p.text;
|
|
4845
|
+
return `#${p.seq} [${p.id}] ${who} \xB7 ${when}
|
|
4846
|
+
${body2}`;
|
|
4847
|
+
}
|
|
4848
|
+
function renderThread(t83) {
|
|
4849
|
+
return `- ${t83.id} ${t83.title} (${t83.postCount} \u5E16\uFF0C\u6700\u540E ${new Date(t83.lastPostAt).toISOString().slice(0, 16).replace("T", " ")})`;
|
|
4850
|
+
}
|
|
4851
|
+
function createBoardTools(store, deps) {
|
|
4852
|
+
const targetParam = {
|
|
4853
|
+
type: "string",
|
|
4854
|
+
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"
|
|
4855
|
+
};
|
|
4856
|
+
const tools = [
|
|
4857
|
+
{
|
|
4858
|
+
name: "get_channels",
|
|
4859
|
+
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",
|
|
4860
|
+
parameters: { type: "object", properties: {}, required: [] },
|
|
4861
|
+
exposure: ToolExposure.Direct,
|
|
4862
|
+
supportsParallel: true,
|
|
4863
|
+
operation: "file_read",
|
|
4864
|
+
annotations: {
|
|
4865
|
+
readOnlyHint: true,
|
|
4866
|
+
destructiveHint: false,
|
|
4867
|
+
idempotentHint: true,
|
|
4868
|
+
openWorldHint: false
|
|
4869
|
+
},
|
|
4870
|
+
describeTarget: () => "\u9891\u9053\u5217\u8868",
|
|
4871
|
+
async execute() {
|
|
4872
|
+
const channels = store.listChannels();
|
|
4873
|
+
if (channels.length === 0) return ok2("\u8FD8\u6CA1\u6709\u9891\u9053\u3002\u7528 create_channel \u5EFA\u4E00\u4E2A\u3002");
|
|
4874
|
+
return ok2(
|
|
4875
|
+
channels.map((c) => `- ${c.name}${c.description ? `\uFF1A${c.description}` : ""}`).join("\n")
|
|
4876
|
+
);
|
|
4877
|
+
}
|
|
4878
|
+
},
|
|
4879
|
+
{
|
|
4880
|
+
name: "create_channel",
|
|
4881
|
+
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",
|
|
4882
|
+
parameters: {
|
|
4883
|
+
type: "object",
|
|
4884
|
+
properties: {
|
|
4885
|
+
name: { type: "string", description: "\u9891\u9053\u540D\uFF0C\u5B57\u6BCD\u6570\u5B57 _ . -" },
|
|
4886
|
+
description: { type: "string", description: "\u8FD9\u4E2A\u9891\u9053\u662F\u5E72\u4EC0\u4E48\u7684" }
|
|
4887
|
+
},
|
|
4888
|
+
required: ["name"]
|
|
4889
|
+
},
|
|
4890
|
+
exposure: ToolExposure.Deferred,
|
|
4891
|
+
supportsParallel: false,
|
|
4892
|
+
operation: "file_read",
|
|
4893
|
+
annotations: {
|
|
4894
|
+
readOnlyHint: false,
|
|
4895
|
+
destructiveHint: false,
|
|
4896
|
+
idempotentHint: true,
|
|
4897
|
+
openWorldHint: false
|
|
4898
|
+
},
|
|
4899
|
+
describeTarget: (args) => String(args["name"] ?? ""),
|
|
4900
|
+
async execute(args, ctx) {
|
|
4901
|
+
const name = str2(args, "name");
|
|
4902
|
+
if (!name) return err(7401, "\u7F3A\u5C11 name");
|
|
4903
|
+
try {
|
|
4904
|
+
const description = str2(args, "description");
|
|
4905
|
+
const ch = store.createChannel({
|
|
4906
|
+
name,
|
|
4907
|
+
...description ? { description } : {},
|
|
4908
|
+
by: authorOf(deps, ctx)
|
|
4909
|
+
});
|
|
4910
|
+
return ok2(`\u9891\u9053 ${ch.name} \u5C31\u7EEA${ch.description ? `\uFF1A${ch.description}` : ""}`);
|
|
4911
|
+
} catch (cause) {
|
|
4912
|
+
return err(7402, cause instanceof Error ? cause.message : String(cause));
|
|
4913
|
+
}
|
|
4914
|
+
}
|
|
4915
|
+
},
|
|
4916
|
+
{
|
|
4917
|
+
name: "upsert_channel",
|
|
4918
|
+
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",
|
|
4919
|
+
parameters: {
|
|
4920
|
+
type: "object",
|
|
4921
|
+
properties: {
|
|
4922
|
+
name: { type: "string", description: "\u9891\u9053\u540D" },
|
|
4923
|
+
description: { type: "string", description: "\u65B0\u7684\u63CF\u8FF0" }
|
|
4924
|
+
},
|
|
4925
|
+
required: ["name", "description"]
|
|
4926
|
+
},
|
|
4927
|
+
exposure: ToolExposure.Deferred,
|
|
4928
|
+
supportsParallel: false,
|
|
4929
|
+
operation: "file_read",
|
|
4930
|
+
annotations: {
|
|
4931
|
+
readOnlyHint: false,
|
|
4932
|
+
destructiveHint: false,
|
|
4933
|
+
idempotentHint: true,
|
|
4934
|
+
openWorldHint: false
|
|
4935
|
+
},
|
|
4936
|
+
describeTarget: (args) => String(args["name"] ?? ""),
|
|
4937
|
+
async execute(args, ctx) {
|
|
4938
|
+
const name = str2(args, "name");
|
|
4939
|
+
const description = str2(args, "description");
|
|
4940
|
+
if (!name) return err(7403, "\u7F3A\u5C11 name");
|
|
4941
|
+
if (!description) return err(7404, "\u7F3A\u5C11 description");
|
|
4942
|
+
try {
|
|
4943
|
+
store.upsertChannel({ name, description, by: authorOf(deps, ctx) });
|
|
4944
|
+
return ok2(`\u9891\u9053 ${name} \u7684\u63CF\u8FF0\u5DF2\u66F4\u65B0\u3002`);
|
|
4945
|
+
} catch (cause) {
|
|
4946
|
+
return err(7405, cause instanceof Error ? cause.message : String(cause));
|
|
4947
|
+
}
|
|
4948
|
+
}
|
|
4949
|
+
},
|
|
4950
|
+
{
|
|
4951
|
+
name: "list_threads",
|
|
4952
|
+
description: "\u5217\u51FA\u67D0\u4E2A\u9891\u9053\u91CC\u7684\u7EBF\u7A0B\uFF0C\u6309\u6700\u540E\u6D3B\u52A8\u6392\u5E8F\u3002",
|
|
4953
|
+
parameters: {
|
|
4954
|
+
type: "object",
|
|
4955
|
+
properties: {
|
|
4956
|
+
channel: { type: "string", description: "\u9891\u9053\u540D" },
|
|
4957
|
+
limit: { type: "number", description: "\u6700\u591A\u51E0\u6761\uFF0C\u9ED8\u8BA4 20" }
|
|
4958
|
+
},
|
|
4959
|
+
required: ["channel"]
|
|
4960
|
+
},
|
|
4961
|
+
exposure: ToolExposure.Deferred,
|
|
4962
|
+
supportsParallel: true,
|
|
4963
|
+
operation: "file_read",
|
|
4964
|
+
annotations: {
|
|
4965
|
+
readOnlyHint: true,
|
|
4966
|
+
destructiveHint: false,
|
|
4967
|
+
idempotentHint: true,
|
|
4968
|
+
openWorldHint: false
|
|
4969
|
+
},
|
|
4970
|
+
describeTarget: (args) => String(args["channel"] ?? ""),
|
|
4971
|
+
async execute(args) {
|
|
4972
|
+
const channel = str2(args, "channel");
|
|
4973
|
+
if (!channel) return err(7406, "\u7F3A\u5C11 channel");
|
|
4974
|
+
if (!store.channel(channel)) return err(7407, `\u6CA1\u6709\u8FD9\u4E2A\u9891\u9053\uFF1A${channel}`);
|
|
4975
|
+
const limit = typeof args["limit"] === "number" ? Math.min(Math.max(1, args["limit"]), 200) : 20;
|
|
4976
|
+
const threads = store.listThreads(channel, limit);
|
|
4977
|
+
if (threads.length === 0) return ok2(`\u9891\u9053 ${channel} \u91CC\u8FD8\u6CA1\u6709\u7EBF\u7A0B\u3002`);
|
|
4978
|
+
return ok2(threads.map(renderThread).join("\n"));
|
|
4979
|
+
}
|
|
4980
|
+
},
|
|
4981
|
+
{
|
|
4982
|
+
name: "read_thread",
|
|
4983
|
+
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",
|
|
4984
|
+
parameters: {
|
|
4985
|
+
type: "object",
|
|
4986
|
+
properties: {
|
|
4987
|
+
threadId: { type: "string", description: "\u7EBF\u7A0B id\uFF08th- \u5F00\u5934\uFF09" },
|
|
4988
|
+
limit: { type: "number", description: "\u6700\u591A\u51E0\u6761\uFF0C\u9ED8\u8BA4 50" }
|
|
4989
|
+
},
|
|
4990
|
+
required: ["threadId"]
|
|
4991
|
+
},
|
|
4992
|
+
exposure: ToolExposure.Direct,
|
|
4993
|
+
supportsParallel: true,
|
|
4994
|
+
operation: "file_read",
|
|
4995
|
+
annotations: {
|
|
4996
|
+
readOnlyHint: false,
|
|
4997
|
+
destructiveHint: false,
|
|
4998
|
+
idempotentHint: false,
|
|
4999
|
+
openWorldHint: false
|
|
5000
|
+
},
|
|
5001
|
+
describeTarget: (args) => String(args["threadId"] ?? ""),
|
|
5002
|
+
async execute(args, ctx) {
|
|
5003
|
+
const threadId = str2(args, "threadId");
|
|
5004
|
+
if (!threadId) return err(7408, "\u7F3A\u5C11 threadId");
|
|
5005
|
+
const limit = typeof args["limit"] === "number" ? Math.min(Math.max(1, args["limit"]), 500) : 50;
|
|
5006
|
+
const posts = store.readThread(threadId, limit);
|
|
5007
|
+
if (posts.length === 0) {
|
|
5008
|
+
return ok2(`\u7EBF\u7A0B ${threadId} \u91CC\u6CA1\u6709\u5E16\u5B50\uFF08\u6216\u8005\u8FD9\u4E2A\u7EBF\u7A0B\u4E0D\u5B58\u5728\uFF09\u3002`);
|
|
5009
|
+
}
|
|
5010
|
+
store.markRead(authorOf(deps, ctx), { kind: "thread", id: threadId });
|
|
5011
|
+
return ok2(posts.map(renderPost).join("\n\n"));
|
|
5012
|
+
}
|
|
5013
|
+
},
|
|
5014
|
+
{
|
|
5015
|
+
name: "read_post",
|
|
5016
|
+
description: "\u8BFB\u4E00\u6761\u5E16\u5B50\u7684\u5168\u6587\uFF08`read_thread` \u4F1A\u622A\u65AD\u957F\u5E16\uFF09\u3002",
|
|
5017
|
+
parameters: {
|
|
5018
|
+
type: "object",
|
|
5019
|
+
properties: { postId: { type: "string", description: "\u5E16\u5B50 id\uFF08po- \u5F00\u5934\uFF09" } },
|
|
5020
|
+
required: ["postId"]
|
|
5021
|
+
},
|
|
5022
|
+
exposure: ToolExposure.Deferred,
|
|
5023
|
+
supportsParallel: true,
|
|
5024
|
+
operation: "file_read",
|
|
5025
|
+
annotations: {
|
|
5026
|
+
readOnlyHint: true,
|
|
5027
|
+
destructiveHint: false,
|
|
5028
|
+
idempotentHint: true,
|
|
5029
|
+
openWorldHint: false
|
|
5030
|
+
},
|
|
5031
|
+
describeTarget: (args) => String(args["postId"] ?? ""),
|
|
5032
|
+
async execute(args) {
|
|
5033
|
+
const id = str2(args, "postId");
|
|
5034
|
+
const p = store.readPost(id);
|
|
5035
|
+
if (!p) return err(7409, `\u6CA1\u6709\u8FD9\u6761\u5E16\u5B50\uFF1A${id}`);
|
|
5036
|
+
return ok2(renderPost(p));
|
|
5037
|
+
}
|
|
5038
|
+
},
|
|
5039
|
+
{
|
|
5040
|
+
name: "search_posts",
|
|
5041
|
+
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",
|
|
5042
|
+
parameters: {
|
|
5043
|
+
type: "object",
|
|
5044
|
+
properties: {
|
|
5045
|
+
query: { type: "string", description: "\u8981\u627E\u7684\u8BCD" },
|
|
5046
|
+
channel: { type: "string", description: "\u53EA\u5728\u8FD9\u4E2A\u9891\u9053\u91CC\u627E" },
|
|
5047
|
+
limit: { type: "number", description: "\u6700\u591A\u51E0\u6761\uFF0C\u9ED8\u8BA4 20" }
|
|
5048
|
+
},
|
|
5049
|
+
required: ["query"]
|
|
5050
|
+
},
|
|
5051
|
+
exposure: ToolExposure.Deferred,
|
|
5052
|
+
supportsParallel: true,
|
|
5053
|
+
operation: "file_read",
|
|
5054
|
+
annotations: {
|
|
5055
|
+
readOnlyHint: true,
|
|
5056
|
+
destructiveHint: false,
|
|
5057
|
+
idempotentHint: true,
|
|
5058
|
+
openWorldHint: false
|
|
5059
|
+
},
|
|
5060
|
+
describeTarget: (args) => String(args["query"] ?? ""),
|
|
5061
|
+
async execute(args) {
|
|
5062
|
+
const query = str2(args, "query");
|
|
5063
|
+
if (!query) return err(7410, "\u7F3A\u5C11 query");
|
|
5064
|
+
const channel = str2(args, "channel");
|
|
5065
|
+
const limit = typeof args["limit"] === "number" ? Math.min(Math.max(1, args["limit"]), 100) : 20;
|
|
5066
|
+
const posts = store.searchPosts(query, channel || void 0, limit);
|
|
5067
|
+
if (posts.length === 0) return ok2(`\u6CA1\u6709\u627E\u5230\u5305\u542B\u300C${query}\u300D\u7684\u5E16\u5B50\u3002`);
|
|
5068
|
+
return ok2(posts.map(renderPost).join("\n\n"));
|
|
5069
|
+
}
|
|
5070
|
+
},
|
|
5071
|
+
{
|
|
5072
|
+
name: "post",
|
|
5073
|
+
description: [
|
|
5074
|
+
"\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",
|
|
5075
|
+
"**\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",
|
|
5076
|
+
"\u60F3\u9759\u9ED8\u8BB0\u4E2A\u6D41\u6C34\uFF08\u4E0D\u901A\u77E5\u4EFB\u4F55\u4EBA\uFF09\u7528 append\u3002"
|
|
5077
|
+
].join("\n"),
|
|
5078
|
+
parameters: {
|
|
5079
|
+
type: "object",
|
|
5080
|
+
properties: { target: targetParam, text: { type: "string", description: "\u5E16\u5B50\u6B63\u6587" } },
|
|
5081
|
+
required: ["target", "text"]
|
|
5082
|
+
},
|
|
5083
|
+
exposure: ToolExposure.Deferred,
|
|
5084
|
+
supportsParallel: false,
|
|
5085
|
+
operation: "file_read",
|
|
5086
|
+
annotations: {
|
|
5087
|
+
readOnlyHint: false,
|
|
5088
|
+
destructiveHint: false,
|
|
5089
|
+
idempotentHint: false,
|
|
5090
|
+
openWorldHint: false
|
|
5091
|
+
},
|
|
5092
|
+
describeTarget: (args) => String(args["target"] ?? ""),
|
|
5093
|
+
async execute(args, ctx) {
|
|
5094
|
+
const target = parseTarget(str2(args, "target"));
|
|
5095
|
+
const text = str2(args, "text");
|
|
5096
|
+
if (!target) return err(7411, "\u7F3A\u5C11 target");
|
|
5097
|
+
if (!text) return err(7412, "\u7F3A\u5C11 text");
|
|
5098
|
+
try {
|
|
5099
|
+
const r = store.post({ target, author: authorOf(deps, ctx), text });
|
|
5100
|
+
return ok2(`\u5DF2\u53D1\u5E16 ${r.post.id}\uFF08\u7EBF\u7A0B ${r.threadId}\uFF0C#${r.post.seq}\uFF09\u3002`);
|
|
5101
|
+
} catch (cause) {
|
|
5102
|
+
return err(7413, cause instanceof Error ? cause.message : String(cause));
|
|
5103
|
+
}
|
|
5104
|
+
}
|
|
5105
|
+
},
|
|
5106
|
+
{
|
|
5107
|
+
name: "append",
|
|
5108
|
+
description: [
|
|
5109
|
+
"**\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",
|
|
5110
|
+
"\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**",
|
|
5111
|
+
"\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"
|
|
5112
|
+
].join("\n"),
|
|
5113
|
+
parameters: {
|
|
5114
|
+
type: "object",
|
|
5115
|
+
properties: { target: targetParam, text: { type: "string", description: "\u6B63\u6587" } },
|
|
5116
|
+
required: ["target", "text"]
|
|
5117
|
+
},
|
|
5118
|
+
exposure: ToolExposure.Deferred,
|
|
5119
|
+
supportsParallel: false,
|
|
5120
|
+
operation: "file_read",
|
|
5121
|
+
annotations: {
|
|
5122
|
+
readOnlyHint: false,
|
|
5123
|
+
destructiveHint: false,
|
|
5124
|
+
idempotentHint: false,
|
|
5125
|
+
openWorldHint: false
|
|
5126
|
+
},
|
|
5127
|
+
describeTarget: (args) => String(args["target"] ?? ""),
|
|
5128
|
+
async execute(args, ctx) {
|
|
5129
|
+
const target = parseTarget(str2(args, "target"));
|
|
5130
|
+
const text = str2(args, "text");
|
|
5131
|
+
if (!target) return err(7414, "\u7F3A\u5C11 target");
|
|
5132
|
+
if (!text) return err(7415, "\u7F3A\u5C11 text");
|
|
5133
|
+
try {
|
|
5134
|
+
const r = store.append({ target, author: authorOf(deps, ctx), text });
|
|
5135
|
+
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`);
|
|
5136
|
+
} catch (cause) {
|
|
5137
|
+
return err(7416, cause instanceof Error ? cause.message : String(cause));
|
|
5138
|
+
}
|
|
5139
|
+
}
|
|
5140
|
+
},
|
|
5141
|
+
{
|
|
5142
|
+
name: "subscribe",
|
|
5143
|
+
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",
|
|
5144
|
+
parameters: {
|
|
5145
|
+
type: "object",
|
|
5146
|
+
properties: { target: { ...targetParam, description: "\u9891\u9053\u540D\u6216\u7EBF\u7A0B id" } },
|
|
5147
|
+
required: ["target"]
|
|
5148
|
+
},
|
|
5149
|
+
exposure: ToolExposure.Deferred,
|
|
5150
|
+
supportsParallel: false,
|
|
5151
|
+
operation: "file_read",
|
|
5152
|
+
annotations: {
|
|
5153
|
+
readOnlyHint: false,
|
|
5154
|
+
destructiveHint: false,
|
|
5155
|
+
idempotentHint: true,
|
|
5156
|
+
openWorldHint: false
|
|
5157
|
+
},
|
|
5158
|
+
describeTarget: (args) => String(args["target"] ?? ""),
|
|
5159
|
+
async execute(args, ctx) {
|
|
5160
|
+
const target = parseTarget(str2(args, "target"));
|
|
5161
|
+
if (!target) return err(7417, "\u7F3A\u5C11 target");
|
|
5162
|
+
store.subscribe(authorOf(deps, ctx), target);
|
|
5163
|
+
return ok2(`\u5DF2\u8BA2\u9605 ${str2(args, "target")}\u3002`);
|
|
5164
|
+
}
|
|
5165
|
+
},
|
|
5166
|
+
{
|
|
5167
|
+
name: "unsubscribe",
|
|
5168
|
+
description: "\u53D6\u6D88\u8BA2\u9605\u3002",
|
|
5169
|
+
parameters: {
|
|
5170
|
+
type: "object",
|
|
5171
|
+
properties: { target: { ...targetParam, description: "\u9891\u9053\u540D\u6216\u7EBF\u7A0B id" } },
|
|
5172
|
+
required: ["target"]
|
|
5173
|
+
},
|
|
5174
|
+
exposure: ToolExposure.Deferred,
|
|
5175
|
+
supportsParallel: false,
|
|
5176
|
+
operation: "file_read",
|
|
5177
|
+
annotations: {
|
|
5178
|
+
readOnlyHint: false,
|
|
5179
|
+
destructiveHint: false,
|
|
5180
|
+
idempotentHint: true,
|
|
5181
|
+
openWorldHint: false
|
|
5182
|
+
},
|
|
5183
|
+
describeTarget: (args) => String(args["target"] ?? ""),
|
|
5184
|
+
async execute(args, ctx) {
|
|
5185
|
+
const target = parseTarget(str2(args, "target"));
|
|
5186
|
+
if (!target) return err(7418, "\u7F3A\u5C11 target");
|
|
5187
|
+
const removed = store.unsubscribe(authorOf(deps, ctx), target);
|
|
5188
|
+
return ok2(
|
|
5189
|
+
removed ? `\u5DF2\u53D6\u6D88\u8BA2\u9605 ${str2(args, "target")}\u3002` : `\u672C\u6765\u5C31\u6CA1\u8BA2\u9605 ${str2(args, "target")}\u3002`
|
|
5190
|
+
);
|
|
5191
|
+
}
|
|
5192
|
+
}
|
|
5193
|
+
];
|
|
5194
|
+
return tools;
|
|
5195
|
+
}
|
|
5196
|
+
var BOARD_TOOL_NAMES = Object.freeze([
|
|
5197
|
+
"create_channel",
|
|
5198
|
+
"upsert_channel",
|
|
5199
|
+
"get_channels",
|
|
5200
|
+
"list_threads",
|
|
5201
|
+
"search_posts",
|
|
5202
|
+
"read_thread",
|
|
5203
|
+
"read_post",
|
|
5204
|
+
"subscribe",
|
|
5205
|
+
"unsubscribe",
|
|
5206
|
+
"post",
|
|
5207
|
+
"append"
|
|
5208
|
+
]);
|
|
5209
|
+
var TASK_STATUSES = ["pending", "in_progress", "done", "blocked"];
|
|
5210
|
+
var AGENT_ID_PATTERN = /^[A-Za-z0-9_-]{1,64}$/;
|
|
5211
|
+
function err2(code, message, suggestion) {
|
|
5212
|
+
return {
|
|
5213
|
+
success: false,
|
|
5214
|
+
output: "",
|
|
5215
|
+
error: { code, message, ...suggestion ? { suggestion } : {} },
|
|
5216
|
+
duration: 0
|
|
5217
|
+
};
|
|
5218
|
+
}
|
|
5219
|
+
function ok3(output, start = Date.now()) {
|
|
5220
|
+
return { success: true, output, duration: Date.now() - start };
|
|
5221
|
+
}
|
|
5222
|
+
function str3(args, key) {
|
|
5223
|
+
const v = args[key];
|
|
5224
|
+
return typeof v === "string" ? v.trim() : "";
|
|
5225
|
+
}
|
|
5226
|
+
function spawnTeammate(team, manager) {
|
|
5227
|
+
return {
|
|
5228
|
+
name: "spawn_teammate",
|
|
5229
|
+
description: [
|
|
5230
|
+
"\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",
|
|
5231
|
+
"\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",
|
|
5232
|
+
"\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",
|
|
5233
|
+
"\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",
|
|
5234
|
+
"\u540C\u4E00\u4E2A\u4F1A\u8BDD\u6700\u591A\u540C\u65F6\u8DD1\u51E0\u4E2A\u6210\u5458\u662F\u6709\u4E0A\u9650\u7684\uFF08list_agents \u91CC\u6570 running \u90A3\u51E0\u6761\uFF09\uFF0C\u6EE1\u4E86\u4F1A\u6D3E\u4E0D\u51FA\u53BB \u2014\u2014 \u7B49\u4E00\u4E2A\u6536\u5DE5\uFF0C\u6216\u8005\u5148 interrupt_agent \u6536\u6389\u4E00\u4E2A\u3002"
|
|
5235
|
+
].join("\n"),
|
|
5236
|
+
parameters: {
|
|
5237
|
+
type: "object",
|
|
5238
|
+
properties: {
|
|
5239
|
+
agentId: {
|
|
5240
|
+
type: "string",
|
|
5241
|
+
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"
|
|
5242
|
+
},
|
|
5243
|
+
goal: { type: "string", description: "\u8981\u5B83\u5B8C\u6210\u4EC0\u4E48\uFF0C\u5199\u5177\u4F53" },
|
|
5244
|
+
context: {
|
|
5245
|
+
type: "string",
|
|
5246
|
+
description: "\u5B8C\u6210\u8FD9\u4E2A\u4EFB\u52A1\u9700\u8981\u77E5\u9053\u7684\u80CC\u666F\uFF08\u5B83\u770B\u4E0D\u5230\u5F53\u524D\u5BF9\u8BDD\uFF09"
|
|
5247
|
+
}
|
|
5248
|
+
},
|
|
5249
|
+
required: ["agentId", "goal"]
|
|
5250
|
+
},
|
|
5251
|
+
exposure: ToolExposure.Deferred,
|
|
5252
|
+
supportsParallel: false,
|
|
5253
|
+
operation: "command",
|
|
5254
|
+
annotations: {
|
|
5255
|
+
readOnlyHint: false,
|
|
5256
|
+
destructiveHint: true,
|
|
5257
|
+
idempotentHint: false,
|
|
5258
|
+
openWorldHint: true
|
|
5259
|
+
},
|
|
5260
|
+
describeTarget: (args) => `${String(args["agentId"] ?? "")}: ${String(args["goal"] ?? "")}`,
|
|
5261
|
+
async execute(args, ctx) {
|
|
5262
|
+
const start = Date.now();
|
|
5263
|
+
const agentId = str3(args, "agentId");
|
|
5264
|
+
const goal = str3(args, "goal");
|
|
5265
|
+
const context = str3(args, "context");
|
|
5266
|
+
if (!AGENT_ID_PATTERN.test(agentId)) {
|
|
5267
|
+
return err2(
|
|
5268
|
+
7201,
|
|
5269
|
+
`\u6210\u5458\u540D\u4E0D\u5408\u6CD5\uFF1A${agentId || "(\u7A7A)"}`,
|
|
5270
|
+
"\u53EA\u8BB8\u5B57\u6BCD\u3001\u6570\u5B57\u3001\u4E0B\u5212\u7EBF\u3001\u8FDE\u5B57\u7B26\uFF0C\u6700\u957F 64"
|
|
5271
|
+
);
|
|
5272
|
+
}
|
|
5273
|
+
if (!goal) return err2(7202, "\u7F3A\u5C11 goal");
|
|
5274
|
+
if (team.get(agentId)) {
|
|
5275
|
+
return err2(
|
|
5276
|
+
7203,
|
|
5277
|
+
`\u5DF2\u7ECF\u6709\u4E00\u4E2A\u6210\u5458\u53EB ${agentId} \u4E86`,
|
|
5278
|
+
"\u6362\u4E00\u4E2A\u540D\u5B57\uFF0C\u6216\u8005\u76F4\u63A5 send_message \u7ED9\u5B83"
|
|
5279
|
+
);
|
|
5280
|
+
}
|
|
5281
|
+
const r = await manager.delegate(
|
|
5282
|
+
{
|
|
5283
|
+
tasks: [{ goal, ...context ? { context } : {}, agentId }],
|
|
5284
|
+
background: true,
|
|
5285
|
+
max_concurrent: 1
|
|
5286
|
+
},
|
|
5287
|
+
ctx.sessionId,
|
|
5288
|
+
ctx.signal
|
|
5289
|
+
);
|
|
5290
|
+
if (!r.success) return { ...err2(7204, r.output), duration: Date.now() - start };
|
|
5291
|
+
return ok3(
|
|
5292
|
+
[
|
|
5293
|
+
`\u5DF2\u6D3E\u51FA\u6210\u5458 ${agentId}\uFF08\u540E\u53F0\u4F5C\u4E1A ${r.jobId ?? "(\u65E0)"}\uFF09\u3002`,
|
|
5294
|
+
`\u8DDF\u5B83\u8BF4\u8BDD\uFF1Asend_message({ to: "${agentId}", text: "\u2026" })`,
|
|
5295
|
+
`\u770B\u5B83\u5728\u5E72\u4EC0\u4E48\uFF1Alist_agents\u3002\u6536\u6389\u5B83\uFF1Ainterrupt_agent({ agentId: "${agentId}" })`
|
|
5296
|
+
].join("\n"),
|
|
5297
|
+
start
|
|
5298
|
+
);
|
|
5299
|
+
}
|
|
5300
|
+
};
|
|
5301
|
+
}
|
|
5302
|
+
function listAgents(team) {
|
|
5303
|
+
return {
|
|
5304
|
+
name: "list_agents",
|
|
5305
|
+
description: [
|
|
5306
|
+
"\u5217\u51FA\u56E2\u961F\u6210\u5458\u548C\u5B83\u4EEC\u7684\u72B6\u6001\u3002",
|
|
5307
|
+
"status \u662F running\uFF08\u6B63\u5728\u8DD1\uFF09/ finalized\uFF08\u8DD1\u5B8C\u4E86\uFF09/ failed\uFF08\u6302\u4E86\uFF09\u3002",
|
|
5308
|
+
"running \u7684\u6210\u5458\u80FD\u88AB send_message \u5F53\u8F6E\u6536\u5230\uFF1B\u6536\u5DE5\u7684\u6536\u4E0D\u5230\u3002",
|
|
5309
|
+
"",
|
|
5310
|
+
"\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",
|
|
5311
|
+
"\u52A0 --all \u53EF\u4EE5\u770B\u5230\u6240\u6709\u6D3B\u8DC3\u4F1A\u8BDD\u548C\u6210\u5458\u3002"
|
|
5312
|
+
].join("\n"),
|
|
5313
|
+
parameters: {
|
|
5314
|
+
type: "object",
|
|
5315
|
+
properties: {
|
|
5316
|
+
all: {
|
|
5317
|
+
type: "boolean",
|
|
5318
|
+
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"
|
|
5319
|
+
}
|
|
5320
|
+
},
|
|
5321
|
+
required: []
|
|
5322
|
+
},
|
|
5323
|
+
exposure: ToolExposure.Direct,
|
|
5324
|
+
supportsParallel: true,
|
|
5325
|
+
operation: "file_read",
|
|
5326
|
+
annotations: {
|
|
5327
|
+
readOnlyHint: true,
|
|
5328
|
+
destructiveHint: false,
|
|
5329
|
+
idempotentHint: true,
|
|
5330
|
+
openWorldHint: false
|
|
5331
|
+
},
|
|
5332
|
+
describeTarget: () => "\u56E2\u961F\u6210\u5458",
|
|
5333
|
+
async execute(args, ctx) {
|
|
5334
|
+
const showAll = args["all"] === true;
|
|
5335
|
+
const self = team.bySession(ctx.sessionId);
|
|
5336
|
+
const scopeParent = self?.parentSessionId ?? ctx.sessionId;
|
|
5337
|
+
const members = showAll ? team.list() : team.list().filter((m) => m.parentSessionId === scopeParent);
|
|
5338
|
+
const others = showAll ? team.sessionIds().filter((id) => id !== ctx.sessionId).map(
|
|
5339
|
+
(id) => `- ${id} [\u4F1A\u8BDD] ${team.isSessionActive(id) ? "running" : "idle"} \u2014 \u53E6\u4E00\u6BB5\u4E3B\u4F1A\u8BDD`
|
|
5340
|
+
) : [];
|
|
5341
|
+
if (members.length === 0 && others.length === 0) {
|
|
5342
|
+
return ok3(
|
|
5343
|
+
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`
|
|
5344
|
+
);
|
|
5345
|
+
}
|
|
5346
|
+
const lines = members.map((m) => {
|
|
5347
|
+
const bits = [`- ${m.agentId}`, m.status];
|
|
5348
|
+
if (m.role) bits.push(`[${m.role}]`);
|
|
5349
|
+
if (m.activity) bits.push(`\u2014 ${m.activity}`);
|
|
5350
|
+
return bits.join(" ");
|
|
5351
|
+
});
|
|
5352
|
+
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`;
|
|
5353
|
+
return ok3([head, ...lines, ...others].join("\n"));
|
|
5354
|
+
}
|
|
5355
|
+
};
|
|
5356
|
+
}
|
|
5357
|
+
function waitAgent(team) {
|
|
5358
|
+
return {
|
|
5359
|
+
name: "wait_agent",
|
|
5360
|
+
description: [
|
|
5361
|
+
"\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",
|
|
5362
|
+
"\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",
|
|
5363
|
+
"\u9002\u5408\uFF1A\u6D3E\u5B8C\u6D3B\u4E4B\u540E\u7B49\u5B83\u4EEC\u5E72\u6D3B\uFF0C\u800C\u4E0D\u662F\u53CD\u590D\u8F6E\u8BE2\u3002"
|
|
5364
|
+
].join("\n"),
|
|
5365
|
+
parameters: {
|
|
5366
|
+
type: "object",
|
|
5367
|
+
properties: {
|
|
5368
|
+
timeoutSec: {
|
|
5369
|
+
type: "number",
|
|
5370
|
+
description: "\u6700\u591A\u7B49\u591A\u4E45\uFF08\u79D2\uFF09\uFF0C1\u20133600\uFF0C\u9ED8\u8BA4 30"
|
|
5371
|
+
}
|
|
5372
|
+
},
|
|
5373
|
+
required: []
|
|
5374
|
+
},
|
|
5375
|
+
exposure: ToolExposure.Deferred,
|
|
5376
|
+
supportsParallel: false,
|
|
5377
|
+
operation: "file_read",
|
|
5378
|
+
annotations: {
|
|
5379
|
+
readOnlyHint: true,
|
|
5380
|
+
destructiveHint: false,
|
|
5381
|
+
idempotentHint: false,
|
|
5382
|
+
openWorldHint: false
|
|
5383
|
+
},
|
|
5384
|
+
describeTarget: () => "\u7B49\u5F85\u56E2\u961F\u53D8\u5316",
|
|
5385
|
+
async execute(args, ctx) {
|
|
5386
|
+
const raw = typeof args["timeoutSec"] === "number" ? args["timeoutSec"] : 30;
|
|
5387
|
+
const sec = Math.min(Math.max(Math.floor(raw), 1), 3600);
|
|
5388
|
+
const changed = await team.waitForChange(sec * 1e3, ctx.signal);
|
|
5389
|
+
if (ctx.signal?.aborted) return err2(7205, "\u7B49\u5F85\u88AB\u4E2D\u6B62\u4E86");
|
|
5390
|
+
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`);
|
|
5391
|
+
}
|
|
5392
|
+
};
|
|
5393
|
+
}
|
|
5394
|
+
function interruptAgent(team) {
|
|
5395
|
+
return {
|
|
5396
|
+
name: "interrupt_agent",
|
|
5397
|
+
description: [
|
|
5398
|
+
"\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",
|
|
5399
|
+
"\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"
|
|
5400
|
+
].join("\n"),
|
|
5401
|
+
parameters: {
|
|
5402
|
+
type: "object",
|
|
5403
|
+
properties: {
|
|
5404
|
+
agentId: { type: "string", description: "\u8981\u6253\u65AD\u7684\u6210\u5458\u540D" }
|
|
5405
|
+
},
|
|
5406
|
+
required: ["agentId"]
|
|
5407
|
+
},
|
|
5408
|
+
exposure: ToolExposure.Deferred,
|
|
5409
|
+
supportsParallel: false,
|
|
5410
|
+
operation: "command",
|
|
5411
|
+
annotations: {
|
|
5412
|
+
readOnlyHint: false,
|
|
5413
|
+
destructiveHint: true,
|
|
5414
|
+
idempotentHint: false,
|
|
5415
|
+
openWorldHint: false
|
|
5416
|
+
},
|
|
5417
|
+
describeTarget: (args) => String(args["agentId"] ?? ""),
|
|
5418
|
+
async execute(args) {
|
|
5419
|
+
const agentId = str3(args, "agentId");
|
|
5420
|
+
if (!agentId) return err2(7206, "\u7F3A\u5C11 agentId");
|
|
5421
|
+
const member = team.get(agentId);
|
|
5422
|
+
if (!member) return err2(7207, `\u6CA1\u6709\u8FD9\u4E2A\u6210\u5458\uFF1A${agentId}`, "\u7528 list_agents \u770B\u5F53\u524D\u6709\u8C01");
|
|
5423
|
+
if (!team.interrupt(agentId)) {
|
|
5424
|
+
return err2(
|
|
5425
|
+
7208,
|
|
5426
|
+
`${agentId} \u73B0\u5728\u6253\u4E0D\u65AD\uFF08${member.status}\uFF09`,
|
|
5427
|
+
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"
|
|
5428
|
+
);
|
|
5429
|
+
}
|
|
5430
|
+
return ok3(`\u5DF2\u6253\u65AD ${agentId}\u3002`);
|
|
5431
|
+
}
|
|
5432
|
+
};
|
|
5433
|
+
}
|
|
5434
|
+
function taskCreate(team) {
|
|
5435
|
+
return {
|
|
5436
|
+
name: "team_task_create",
|
|
5437
|
+
description: [
|
|
5438
|
+
"\u5728\u5171\u4EAB\u4EFB\u52A1\u677F\u4E0A\u5EFA\u4E00\u6761\u4EFB\u52A1\u3002\u5168\u961F\u90FD\u770B\u5F97\u5230\u540C\u4E00\u4EFD\u3002",
|
|
5439
|
+
"dependsOn \u586B\u522B\u7684\u4EFB\u52A1 id\uFF08\u53EA\u80FD\u662F\u5DF2\u7ECF\u5B58\u5728\u7684\uFF09\u3002",
|
|
5440
|
+
"owner \u586B\u67D0\u4E2A\u6210\u5458\u540D\uFF0C\u8868\u793A\u8FD9\u6761\u5F52\u5B83\u3002"
|
|
5441
|
+
].join("\n"),
|
|
5442
|
+
parameters: {
|
|
5443
|
+
type: "object",
|
|
5444
|
+
properties: {
|
|
5445
|
+
title: { type: "string", description: "\u4E00\u53E5\u8BDD\u8BF4\u660E\u8981\u505A\u4EC0\u4E48" },
|
|
5446
|
+
description: { type: "string", description: "\u7EC6\u8282" },
|
|
5447
|
+
owner: { type: "string", description: "\u5F52\u8C01\uFF08\u6210\u5458\u540D\uFF09" },
|
|
5448
|
+
dependsOn: {
|
|
5449
|
+
type: "array",
|
|
5450
|
+
items: { type: "string" },
|
|
5451
|
+
description: "\u4F9D\u8D56\u54EA\u4E9B\u4EFB\u52A1\u7684 id"
|
|
5452
|
+
}
|
|
5453
|
+
},
|
|
5454
|
+
required: ["title"]
|
|
5455
|
+
},
|
|
5456
|
+
exposure: ToolExposure.Deferred,
|
|
5457
|
+
supportsParallel: true,
|
|
5458
|
+
operation: "file_read",
|
|
5459
|
+
annotations: {
|
|
5460
|
+
readOnlyHint: false,
|
|
5461
|
+
destructiveHint: false,
|
|
5462
|
+
idempotentHint: false,
|
|
5463
|
+
openWorldHint: false
|
|
5464
|
+
},
|
|
5465
|
+
describeTarget: (args) => String(args["title"] ?? ""),
|
|
5466
|
+
async execute(args) {
|
|
5467
|
+
const title = str3(args, "title");
|
|
5468
|
+
if (!title) return err2(7301, "\u7F3A\u5C11 title");
|
|
5469
|
+
const dependsOn = Array.isArray(args["dependsOn"]) ? args["dependsOn"].map(String).filter(Boolean) : [];
|
|
5470
|
+
const description = str3(args, "description");
|
|
5471
|
+
const owner = str3(args, "owner");
|
|
5472
|
+
const r = team.tasks.create({
|
|
5473
|
+
title,
|
|
5474
|
+
...description ? { description } : {},
|
|
5475
|
+
...owner ? { owner } : {},
|
|
5476
|
+
...dependsOn.length > 0 ? { dependsOn } : {}
|
|
5477
|
+
});
|
|
5478
|
+
if (!r.ok) return err2(7302, r.reason);
|
|
5479
|
+
return ok3(`\u5DF2\u5EFA\u4EFB\u52A1 ${r.task.id}\uFF08revision ${r.task.revision}\uFF09\uFF1A${r.task.title}`);
|
|
5480
|
+
}
|
|
5481
|
+
};
|
|
5482
|
+
}
|
|
5483
|
+
function taskList(team) {
|
|
5484
|
+
return {
|
|
5485
|
+
name: "team_task_list",
|
|
5486
|
+
description: "\u5217\u51FA\u5171\u4EAB\u4EFB\u52A1\u677F\u4E0A\u7684\u4EFB\u52A1\uFF0C\u53EF\u6309\u72B6\u6001\u6216 owner \u8FC7\u6EE4\u3002",
|
|
5487
|
+
parameters: {
|
|
5488
|
+
type: "object",
|
|
5489
|
+
properties: {
|
|
5490
|
+
status: { type: "string", enum: [...TASK_STATUSES], description: "\u53EA\u770B\u8FD9\u4E2A\u72B6\u6001" },
|
|
5491
|
+
owner: { type: "string", description: "\u53EA\u770B\u5F52\u8FD9\u4E2A\u6210\u5458\u7684" }
|
|
5492
|
+
},
|
|
5493
|
+
required: []
|
|
5494
|
+
},
|
|
5495
|
+
exposure: ToolExposure.Deferred,
|
|
5496
|
+
supportsParallel: true,
|
|
5497
|
+
operation: "file_read",
|
|
5498
|
+
annotations: {
|
|
5499
|
+
readOnlyHint: true,
|
|
5500
|
+
destructiveHint: false,
|
|
5501
|
+
idempotentHint: true,
|
|
5502
|
+
openWorldHint: false
|
|
5503
|
+
},
|
|
5504
|
+
describeTarget: () => "\u56E2\u961F\u4EFB\u52A1\u677F",
|
|
5505
|
+
async execute(args) {
|
|
5506
|
+
const status = str3(args, "status");
|
|
5507
|
+
if (status && !TASK_STATUSES.includes(status)) {
|
|
5508
|
+
return err2(7303, `\u4E0D\u8BA4\u8BC6\u7684\u72B6\u6001\uFF1A${status}`, `\u53EF\u7528\uFF1A${TASK_STATUSES.join(" / ")}`);
|
|
5509
|
+
}
|
|
5510
|
+
const owner = str3(args, "owner");
|
|
5511
|
+
const tasks = team.tasks.list({
|
|
5512
|
+
...status ? { status } : {},
|
|
5513
|
+
...owner ? { owner } : {}
|
|
5514
|
+
});
|
|
5515
|
+
if (tasks.length === 0) return ok3("\u677F\u5B50\u4E0A\u6CA1\u6709\u7B26\u5408\u6761\u4EF6\u7684\u4EFB\u52A1\u3002");
|
|
5516
|
+
const lines = tasks.map((t83) => {
|
|
5517
|
+
const bits = [`- ${t83.id}`, `[${t83.status}]`, t83.title, `rev ${t83.revision}`];
|
|
5518
|
+
if (t83.owner) bits.push(`\u2192 ${t83.owner}`);
|
|
5519
|
+
if (t83.dependsOn.length > 0) bits.push(`(\u7B49 ${t83.dependsOn.join(", ")})`);
|
|
5520
|
+
return bits.join(" ");
|
|
5521
|
+
});
|
|
5522
|
+
return ok3(`\u5171 ${tasks.length} \u6761\uFF1A
|
|
5523
|
+
${lines.join("\n")}`);
|
|
5524
|
+
}
|
|
5525
|
+
};
|
|
5526
|
+
}
|
|
5527
|
+
function taskGet(team) {
|
|
5528
|
+
return {
|
|
5529
|
+
name: "team_task_get",
|
|
5530
|
+
description: "\u8BFB\u4E00\u6761\u4EFB\u52A1\u7684\u5B8C\u6574\u5185\u5BB9\uFF08\u542B revision \u2014\u2014 \u6539\u4E4B\u524D\u5148\u8BFB\u5B83\uFF09\u3002",
|
|
5531
|
+
parameters: {
|
|
5532
|
+
type: "object",
|
|
5533
|
+
properties: { id: { type: "string", description: "\u4EFB\u52A1 id" } },
|
|
5534
|
+
required: ["id"]
|
|
5535
|
+
},
|
|
5536
|
+
exposure: ToolExposure.Deferred,
|
|
5537
|
+
supportsParallel: true,
|
|
5538
|
+
operation: "file_read",
|
|
5539
|
+
annotations: {
|
|
5540
|
+
readOnlyHint: true,
|
|
5541
|
+
destructiveHint: false,
|
|
5542
|
+
idempotentHint: true,
|
|
5543
|
+
openWorldHint: false
|
|
5544
|
+
},
|
|
5545
|
+
describeTarget: (args) => String(args["id"] ?? ""),
|
|
5546
|
+
async execute(args) {
|
|
5547
|
+
const id = str3(args, "id");
|
|
5548
|
+
const t83 = team.tasks.get(id);
|
|
5549
|
+
if (!t83) return err2(7304, `\u6CA1\u6709\u8FD9\u4E2A\u4EFB\u52A1\uFF1A${id}`, "\u7528 team_task_list \u770B\u6709\u54EA\u4E9B");
|
|
5550
|
+
return ok3(
|
|
5551
|
+
[
|
|
5552
|
+
`${t83.id} [${t83.status}] revision ${t83.revision}`,
|
|
5553
|
+
`\u6807\u9898\uFF1A${t83.title}`,
|
|
5554
|
+
t83.description ? `\u7EC6\u8282\uFF1A${t83.description}` : "",
|
|
5555
|
+
t83.owner ? `\u5F52\u5C5E\uFF1A${t83.owner}` : "\u5F52\u5C5E\uFF1A\uFF08\u65E0\uFF09",
|
|
5556
|
+
t83.dependsOn.length > 0 ? `\u4F9D\u8D56\uFF1A${t83.dependsOn.join(", ")}` : "\u4F9D\u8D56\uFF1A\u65E0"
|
|
5557
|
+
].filter(Boolean).join("\n")
|
|
5558
|
+
);
|
|
5559
|
+
}
|
|
5560
|
+
};
|
|
5561
|
+
}
|
|
5562
|
+
function taskUpdate(team) {
|
|
5563
|
+
return {
|
|
5564
|
+
name: "team_task_update",
|
|
5565
|
+
description: [
|
|
5566
|
+
"\u6539\u4E00\u6761\u4EFB\u52A1\u3002**\u6539\u4E4B\u524D\u5148 team_task_get \u62FF\u5230 revision\uFF0C\u539F\u6837\u586B\u8FDB expectedRevision**\u3002",
|
|
5567
|
+
"\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",
|
|
5568
|
+
"\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"
|
|
5569
|
+
].join("\n"),
|
|
5570
|
+
parameters: {
|
|
5571
|
+
type: "object",
|
|
5572
|
+
properties: {
|
|
5573
|
+
id: { type: "string", description: "\u4EFB\u52A1 id" },
|
|
5574
|
+
expectedRevision: {
|
|
5575
|
+
type: "number",
|
|
5576
|
+
description: "\u4F60\u4E0A\u6B21\u8BFB\u5230\u7684 revision\u3002\u5BF9\u4E0D\u4E0A\u5C31\u62D2\u7EDD\u6574\u7B14\u5199\u5165"
|
|
5577
|
+
},
|
|
5578
|
+
title: { type: "string" },
|
|
5579
|
+
description: { type: "string" },
|
|
5580
|
+
status: { type: "string", enum: [...TASK_STATUSES] },
|
|
5581
|
+
owner: { type: "string", description: "\u6539\u6210\u5F52\u8C01" }
|
|
4194
5582
|
},
|
|
4195
|
-
required: ["
|
|
5583
|
+
required: ["id"]
|
|
4196
5584
|
},
|
|
4197
|
-
exposure: ToolExposure.
|
|
5585
|
+
exposure: ToolExposure.Deferred,
|
|
4198
5586
|
supportsParallel: false,
|
|
5587
|
+
operation: "file_read",
|
|
4199
5588
|
annotations: {
|
|
4200
5589
|
readOnlyHint: false,
|
|
4201
|
-
destructiveHint:
|
|
5590
|
+
destructiveHint: false,
|
|
4202
5591
|
idempotentHint: false,
|
|
4203
5592
|
openWorldHint: false
|
|
4204
5593
|
},
|
|
4205
|
-
|
|
4206
|
-
|
|
4207
|
-
|
|
4208
|
-
|
|
4209
|
-
const
|
|
4210
|
-
if (
|
|
4211
|
-
|
|
4212
|
-
return say4(
|
|
4213
|
-
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
|
|
4214
|
-
${rows.map(describeRow).join("\n")}`,
|
|
4215
|
-
true,
|
|
4216
|
-
startedAt
|
|
4217
|
-
);
|
|
5594
|
+
describeTarget: (args) => String(args["id"] ?? ""),
|
|
5595
|
+
async execute(args) {
|
|
5596
|
+
const id = str3(args, "id");
|
|
5597
|
+
if (!id) return err2(7305, "\u7F3A\u5C11 id");
|
|
5598
|
+
const status = str3(args, "status");
|
|
5599
|
+
if (status && !TASK_STATUSES.includes(status)) {
|
|
5600
|
+
return err2(7306, `\u4E0D\u8BA4\u8BC6\u7684\u72B6\u6001\uFF1A${status}`, `\u53EF\u7528\uFF1A${TASK_STATUSES.join(" / ")}`);
|
|
4218
5601
|
}
|
|
4219
|
-
const
|
|
4220
|
-
|
|
4221
|
-
const
|
|
4222
|
-
const
|
|
4223
|
-
if (
|
|
4224
|
-
|
|
4225
|
-
|
|
4226
|
-
|
|
4227
|
-
|
|
5602
|
+
const patch = {};
|
|
5603
|
+
const title = str3(args, "title");
|
|
5604
|
+
const description = str3(args, "description");
|
|
5605
|
+
const owner = str3(args, "owner");
|
|
5606
|
+
if (title) patch.title = title;
|
|
5607
|
+
if (description) patch.description = description;
|
|
5608
|
+
if (status) patch.status = status;
|
|
5609
|
+
if (owner) patch.owner = owner;
|
|
5610
|
+
if (Object.keys(patch).length === 0) return err2(7307, "\u4E00\u4E2A\u5B57\u6BB5\u90FD\u6CA1\u7ED9\uFF0C\u6CA1\u4EC0\u4E48\u53EF\u6539\u7684");
|
|
5611
|
+
const expected = typeof args["expectedRevision"] === "number" ? args["expectedRevision"] : void 0;
|
|
5612
|
+
const r = team.tasks.update(id, patch, expected);
|
|
5613
|
+
if (!r.ok) return err2(7308, r.reason);
|
|
5614
|
+
return ok3(`\u5DF2\u66F4\u65B0 ${r.task.id}\uFF08revision ${r.task.revision}\uFF0C\u72B6\u6001 ${r.task.status}\uFF09\u3002`);
|
|
5615
|
+
}
|
|
5616
|
+
};
|
|
5617
|
+
}
|
|
5618
|
+
function followupTask(team, manager) {
|
|
5619
|
+
return {
|
|
5620
|
+
name: "followup_task",
|
|
5621
|
+
description: [
|
|
5622
|
+
"\u53EB\u9192\u4E00\u4E2A**\u6CA1\u5728\u8DD1**\u7684\u5BF9\u65B9\uFF0C\u8BA9\u5B83\u5E26\u7740\u4E0A\u4E00\u6B21\u7684\u5168\u90E8\u4E0A\u4E0B\u6587\u518D\u8DD1\u4E00\u8F6E\u3002",
|
|
5623
|
+
"\u5BF9\u8C61\u53EF\u4EE5\u662F\uFF1A\u5DF2\u7ECF\u6536\u5DE5\u7684\u6210\u5458\uFF08list_agents \u91CC\u7684 agentId\uFF09\uFF0C\u6216\u8005**\u53E6\u4E00\u6BB5\u4E3B\u4F1A\u8BDD**\uFF08list_agents --all \u91CC\u7684 sessionId\uFF09\u3002",
|
|
5624
|
+
"\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",
|
|
5625
|
+
"\u5BF9\u65B9\u6CA1\u5728\u8DD1\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",
|
|
5626
|
+
"\u53EB\u9192\u662F\u5F02\u6B65\u7684\uFF1A\u5DE5\u5177\u4E00\u8FD4\u56DE\u5C31\u7B97\u5B8C\u6210\uFF0C\u5B83\u81EA\u5DF1\u90A3\u4E00\u8F6E\u5728\u540E\u53F0\u8DD1\uFF0C\u4E0D\u7528\u7B49\u5B83\u7B54\u5B8C\u3002",
|
|
5627
|
+
"\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",
|
|
5628
|
+
"\u540C\u65F6\u88AB\u53EB\u9192\u7684\u4F1A\u8BDD\u662F\u6709\u4E0A\u9650\u7684\uFF08\u9ED8\u8BA4 3 \u6BB5\uFF09\uFF0C\u8FDE\u7740\u53EB\u7B2C\u56DB\u6BB5\u4F1A\u88AB\u62D2 \u2014\u2014 \u7B49\u4E00\u6BB5\u8DD1\u5B8C\u518D\u53EB\u3002"
|
|
5629
|
+
].join("\n"),
|
|
5630
|
+
parameters: {
|
|
5631
|
+
type: "object",
|
|
5632
|
+
properties: {
|
|
5633
|
+
agentId: { type: "string", description: "\u6210\u5458\u540D\uFF08list_agents \u91CC\u6709\uFF09" },
|
|
5634
|
+
message: { type: "string", description: "\u8FD9\u4E00\u8F6E\u8981\u5B83\u505A\u4EC0\u4E48" }
|
|
5635
|
+
},
|
|
5636
|
+
required: ["agentId", "message"]
|
|
5637
|
+
},
|
|
5638
|
+
exposure: ToolExposure.Deferred,
|
|
5639
|
+
supportsParallel: false,
|
|
5640
|
+
operation: "command",
|
|
5641
|
+
annotations: {
|
|
5642
|
+
readOnlyHint: false,
|
|
5643
|
+
destructiveHint: true,
|
|
5644
|
+
idempotentHint: false,
|
|
5645
|
+
openWorldHint: true
|
|
5646
|
+
},
|
|
5647
|
+
describeTarget: (args) => `${String(args["agentId"] ?? "")}: ${String(args["message"] ?? "")}`,
|
|
5648
|
+
async execute(args, ctx) {
|
|
5649
|
+
const start = Date.now();
|
|
5650
|
+
const agentId = str3(args, "agentId");
|
|
5651
|
+
const message = str3(args, "message");
|
|
5652
|
+
if (!agentId) return err2(7205, "\u7F3A\u5C11 agentId");
|
|
5653
|
+
if (!message) return err2(7206, "\u7F3A\u5C11 message");
|
|
5654
|
+
const member = team.get(agentId);
|
|
5655
|
+
if (member) {
|
|
5656
|
+
if (member.status === "running") {
|
|
5657
|
+
return err2(
|
|
5658
|
+
7208,
|
|
5659
|
+
`${agentId} \u6B63\u5728\u8DD1\uFF0C\u4E0D\u9700\u8981\u5524\u9192`,
|
|
5660
|
+
"\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"
|
|
5661
|
+
);
|
|
5662
|
+
}
|
|
5663
|
+
const r = await manager.delegate(
|
|
5664
|
+
{
|
|
5665
|
+
tasks: [
|
|
5666
|
+
{
|
|
5667
|
+
goal: message,
|
|
5668
|
+
agentId,
|
|
5669
|
+
resumeSessionId: member.sessionId,
|
|
5670
|
+
...member.role ? { role: member.role } : {}
|
|
5671
|
+
}
|
|
5672
|
+
],
|
|
5673
|
+
background: true,
|
|
5674
|
+
max_concurrent: 1
|
|
5675
|
+
},
|
|
5676
|
+
ctx.sessionId,
|
|
5677
|
+
ctx.signal
|
|
4228
5678
|
);
|
|
4229
|
-
|
|
4230
|
-
|
|
4231
|
-
|
|
4232
|
-
|
|
4233
|
-
|
|
4234
|
-
|
|
4235
|
-
|
|
5679
|
+
if (!r.success) return { ...err2(7209, r.output), duration: Date.now() - start };
|
|
5680
|
+
return ok3(
|
|
5681
|
+
[
|
|
5682
|
+
`\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`,
|
|
5683
|
+
`\u770B\u5B83\u5E72\u5230\u54EA\u513F\u4E86\uFF1Atask_output ${r.jobId ?? ""} \u6216 list_agents`
|
|
5684
|
+
].join("\n"),
|
|
5685
|
+
start
|
|
4236
5686
|
);
|
|
4237
5687
|
}
|
|
4238
|
-
|
|
4239
|
-
|
|
4240
|
-
|
|
4241
|
-
|
|
4242
|
-
|
|
4243
|
-
|
|
4244
|
-
|
|
5688
|
+
if (team.sessionExists(agentId)) {
|
|
5689
|
+
if (team.isSessionActive(agentId)) {
|
|
5690
|
+
return err2(
|
|
5691
|
+
7210,
|
|
5692
|
+
`${agentId} \u6B63\u5728\u8DD1\uFF0C\u4E0D\u9700\u8981\u5524\u9192`,
|
|
5693
|
+
"\u73B0\u5728\u7ED9\u5B83\u8BF4\u8BDD\u7528 send_message \u2014\u2014 \u90A3\u6761\u4F1A\u8FDB\u5B83\u6B63\u5728\u8DD1\u7684\u90A3\u4E00\u8F6E"
|
|
5694
|
+
);
|
|
5695
|
+
}
|
|
5696
|
+
const self = team.bySession(ctx.sessionId);
|
|
5697
|
+
const from = self ? self.agentId : ctx.sessionId;
|
|
5698
|
+
const fromLabel = self ? void 0 : sessionSenderLabel(from, team.sessionTitle(from));
|
|
5699
|
+
const r = await team.wakeSession(
|
|
5700
|
+
agentId,
|
|
5701
|
+
agentMessageLine({ from, text: message, ...fromLabel ? { fromLabel } : {} })
|
|
4245
5702
|
);
|
|
4246
|
-
|
|
4247
|
-
|
|
4248
|
-
|
|
4249
|
-
|
|
4250
|
-
|
|
4251
|
-
|
|
4252
|
-
|
|
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);
|
|
4255
|
-
}
|
|
4256
|
-
const def = saved.schedule;
|
|
4257
|
-
if (def === void 0) {
|
|
4258
|
-
return say4(
|
|
4259
|
-
"\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",
|
|
4260
|
-
false,
|
|
4261
|
-
startedAt
|
|
5703
|
+
if (!r.ok) return { ...err2(7211, r.reason ?? "\u5524\u9192\u5931\u8D25"), duration: Date.now() - start };
|
|
5704
|
+
return ok3(
|
|
5705
|
+
[
|
|
5706
|
+
`\u5DF2\u628A\u4F1A\u8BDD ${agentId} \u53EB\u8D77\u6765\u8DD1\u4E00\u8F6E\uFF08\u4E0D\u7B49\u5B83\u7B54\u5B8C\uFF0C\u5B83\u81EA\u5DF1\u90A3\u4E00\u8F6E\u5728\u540E\u53F0\u8DD1\uFF09\u3002`,
|
|
5707
|
+
`\u770B\u5B83\u7B54\u4E86\u4EC0\u4E48\uFF1Asession_messages_read ${agentId}\uFF1B\u6216\u8005\u7B49\u5B83\u7ED9\u4F60\u56DE\u6D88\u606F\u3002`
|
|
5708
|
+
].join("\n"),
|
|
5709
|
+
start
|
|
4262
5710
|
);
|
|
4263
5711
|
}
|
|
4264
|
-
return
|
|
5712
|
+
return err2(7207, `\u6CA1\u6709\u8FD9\u4E2A\u6210\u5458\u6216\u4F1A\u8BDD\uFF1A${agentId}`, "\u7528 list_agents --all \u770B\u5F53\u524D\u6709\u8C01");
|
|
4265
5713
|
}
|
|
4266
5714
|
};
|
|
4267
5715
|
}
|
|
5716
|
+
function createTeamTools(team, manager) {
|
|
5717
|
+
return [
|
|
5718
|
+
listAgents(team),
|
|
5719
|
+
spawnTeammate(team, manager),
|
|
5720
|
+
waitAgent(team),
|
|
5721
|
+
interruptAgent(team),
|
|
5722
|
+
followupTask(team, manager),
|
|
5723
|
+
taskCreate(team),
|
|
5724
|
+
taskList(team),
|
|
5725
|
+
taskGet(team),
|
|
5726
|
+
taskUpdate(team)
|
|
5727
|
+
];
|
|
5728
|
+
}
|
|
5729
|
+
var TEAM_TOOL_NAMES = Object.freeze([
|
|
5730
|
+
"spawn_teammate",
|
|
5731
|
+
"list_agents",
|
|
5732
|
+
"wait_agent",
|
|
5733
|
+
"interrupt_agent",
|
|
5734
|
+
"followup_task",
|
|
5735
|
+
"team_task_create",
|
|
5736
|
+
"team_task_list",
|
|
5737
|
+
"team_task_get",
|
|
5738
|
+
"team_task_update"
|
|
5739
|
+
]);
|
|
4268
5740
|
// src/session/authorization.ts
|
|
4269
5741
|
function lineageOf(db, sessionId) {
|
|
4270
5742
|
const rows = db.prepare(
|
|
@@ -4520,6 +5992,14 @@ var SessionQueries = class {
|
|
|
4520
5992
|
if (!meta) return { authorized: false, title: "", before: [], after: [], total: 0 };
|
|
4521
5993
|
const total = this.db.prepare(`SELECT count(*) AS n FROM messages WHERE session_id = @sid`).get({ sid: input.sessionId }).n;
|
|
4522
5994
|
const base2 = { authorized: true, title: meta.title, total };
|
|
5995
|
+
if (input.messageId === void 0) {
|
|
5996
|
+
return {
|
|
5997
|
+
...base2,
|
|
5998
|
+
before: [],
|
|
5999
|
+
after: [],
|
|
6000
|
+
tail: this.tailRows(input.sessionId, input.tail ?? 0).reverse().map(toRecord)
|
|
6001
|
+
};
|
|
6002
|
+
}
|
|
4523
6003
|
const anchor = this.recordRow(input.sessionId, input.messageId);
|
|
4524
6004
|
if (!anchor) return { ...base2, before: [], after: [] };
|
|
4525
6005
|
return {
|
|
@@ -4625,6 +6105,16 @@ var SessionQueries = class {
|
|
|
4625
6105
|
LIMIT @n`
|
|
4626
6106
|
).all({ sid: sessionId, anchor: anchorId, n });
|
|
4627
6107
|
}
|
|
6108
|
+
tailRows(sessionId, n) {
|
|
6109
|
+
if (n <= 0) return [];
|
|
6110
|
+
return this.db.prepare(
|
|
6111
|
+
`SELECT id, role, content, timestamp, active, tool_name
|
|
6112
|
+
FROM messages
|
|
6113
|
+
WHERE session_id = @sid
|
|
6114
|
+
ORDER BY id DESC
|
|
6115
|
+
LIMIT @n`
|
|
6116
|
+
).all({ sid: sessionId, n });
|
|
6117
|
+
}
|
|
4628
6118
|
messageRows(safe, sessionId, limit) {
|
|
4629
6119
|
const sql = (table) => `
|
|
4630
6120
|
SELECT m.id, m.session_id, m.role, m.content, m.timestamp, m.active,
|
|
@@ -4749,14 +6239,16 @@ function createSessionListTool(deps) {
|
|
|
4749
6239
|
output: render(out, scopeNote(allWorkspaces, archived)),
|
|
4750
6240
|
duration: Date.now() - start
|
|
4751
6241
|
});
|
|
4752
|
-
} catch (
|
|
4753
|
-
return Promise.resolve(fail3(
|
|
6242
|
+
} catch (err3) {
|
|
6243
|
+
return Promise.resolve(fail3(err3 instanceof Error ? err3.message : String(err3), start, 8014));
|
|
4754
6244
|
}
|
|
4755
6245
|
}
|
|
4756
6246
|
};
|
|
4757
6247
|
}
|
|
4758
6248
|
var DEFAULT_WINDOW = 2;
|
|
4759
6249
|
var MAX_WINDOW = 10;
|
|
6250
|
+
var DEFAULT_TAIL = 5;
|
|
6251
|
+
var MAX_TAIL = MAX_WINDOW;
|
|
4760
6252
|
var DEFAULT_TRACE_LIMIT = 20;
|
|
4761
6253
|
var MAX_TRACE_LIMIT = 50;
|
|
4762
6254
|
var BODY_BUDGET = 1500;
|
|
@@ -4789,7 +6281,7 @@ function body(text, budget) {
|
|
|
4789
6281
|
if (flat.length <= budget) return flat;
|
|
4790
6282
|
const rest = flat.length - budget;
|
|
4791
6283
|
return `${flat.slice(0, budget)}
|
|
4792
|
-
\u2026[cut ${rest} more chars \u2014
|
|
6284
|
+
\u2026[cut ${rest} more chars \u2014 narrow the window (before / after / tail) to spend the budget on fewer messages]`;
|
|
4793
6285
|
}
|
|
4794
6286
|
function surfaceOf(record, isCurrent) {
|
|
4795
6287
|
if (!isCurrent) return record.surface === "active" ? "active there" : "compacted there";
|
|
@@ -4802,7 +6294,21 @@ function renderRecord(record, mark, budget, isCurrent) {
|
|
|
4802
6294
|
` ${body(record.content, budget).split("\n").join("\n ")}`
|
|
4803
6295
|
].join("\n");
|
|
4804
6296
|
}
|
|
6297
|
+
function tailBudgetOf(count) {
|
|
6298
|
+
return Math.max(MIN_BODY, Math.floor(BODY_BUDGET / Math.max(1, count)));
|
|
6299
|
+
}
|
|
6300
|
+
function renderTail(out, sessionId, isCurrent) {
|
|
6301
|
+
const tail = out.tail ?? [];
|
|
6302
|
+
const head = [
|
|
6303
|
+
`Session ${sessionId}${isCurrent ? " (this session)" : ""} \u2014 ${out.title || "(untitled)"}`,
|
|
6304
|
+
tail.length === 0 ? "this session has no messages." : `latest ${tail.length} of ${out.total} message(s), oldest first:`
|
|
6305
|
+
];
|
|
6306
|
+
if (tail.length === 0) return head.join("\n");
|
|
6307
|
+
const budget = tailBudgetOf(tail.length);
|
|
6308
|
+
return [...head, "", ...tail.map((r) => renderRecord(r, " ", budget, isCurrent))].join("\n");
|
|
6309
|
+
}
|
|
4805
6310
|
function renderWindow(out, sessionId, isCurrent) {
|
|
6311
|
+
if (out.tail) return renderTail(out, sessionId, isCurrent);
|
|
4806
6312
|
const anchor = out.anchor;
|
|
4807
6313
|
if (!anchor) return "";
|
|
4808
6314
|
const count = out.before.length + out.after.length + 1;
|
|
@@ -4821,6 +6327,7 @@ function createSessionMessagesReadTool(deps) {
|
|
|
4821
6327
|
name: SESSION_MESSAGES_READ_TOOL,
|
|
4822
6328
|
description: `\u628A\u67D0\u4E00\u6761\u5386\u53F2\u6D88\u606F\u8FDE\u540C\u5B83\u524D\u540E\u51E0\u6761\u4E00\u8D77\u8BFB\u51FA\u6765 \u2014\u2014 \u68C0\u7D22\u7ED9\u7684\u662F\u7247\u6BB5\uFF0C\u8FD9\u4E2A\u7ED9\u7684\u662F\u539F\u6587\u3002
|
|
4823
6329
|
sessionId + messageId \u6765\u81EA session_search / session_messages_search \u7684\u547D\u4E2D\u3002
|
|
6330
|
+
**\u4E0D\u4F20 messageId \u5C31\u6539\u8BFB\u8FD9\u6BB5\u4F1A\u8BDD\u6700\u8FD1\u51E0\u6761** \u2014\u2014 \u6CA1\u547D\u4E2D\u3001\u4E0D\u77E5\u9053\u4ECE\u54EA\u8BFB\u8D77\u65F6\u7528\u8FD9\u4E2A\uFF0C\u522B\u53BB\u731C id\uFF08id \u662F\u5168\u5E93\u81EA\u589E\u7684\uFF0C\u731C\u4E0D\u4E2D\uFF09\u3002
|
|
4824
6331
|
before / after \u5404\u9ED8\u8BA4 ${DEFAULT_WINDOW}\u3001\u4E0A\u9650 ${MAX_WINDOW}\uFF08\u4F20\u5927\u4E86\u81EA\u52A8\u5939\u7D27\uFF0C\u4E0D\u62A5\u9519\uFF09\u3002
|
|
4825
6332
|
\u6B63\u6587\u6709\u5B57\u7B26\u9884\u7B97\uFF0C\u8D85\u4E86\u4F1A\u622A\u65AD\u5E76\u660E\u8BF4\u622A\u4E86\u591A\u5C11 \u2014\u2014 \u60F3\u770B\u5168\u5C31\u628A before / after \u8C03\u5C0F\u3002
|
|
4826
6333
|
\u5DF2\u7ECF\u88AB\u538B\u7F29\u76D6\u6389\u7684\u539F\u6587\u7167\u6837\u8BFB\u5F97\u5230\uFF0C\u90A3\u6B63\u662F\u8FD9\u4E2A\u5DE5\u5177\u5B58\u5728\u7684\u7406\u7531\u3002`,
|
|
@@ -4831,7 +6338,11 @@ before / after \u5404\u9ED8\u8BA4 ${DEFAULT_WINDOW}\u3001\u4E0A\u9650 ${MAX_WIND
|
|
|
4831
6338
|
sessionId: { type: "string", description: "\u8BFB\u54EA\u6BB5\u4F1A\u8BDD\u3002\u6765\u81EA\u68C0\u7D22\u7ED3\u679C" },
|
|
4832
6339
|
messageId: {
|
|
4833
6340
|
type: "number",
|
|
4834
|
-
description:
|
|
6341
|
+
description: `\u951A\u70B9\u6D88\u606F\u7684 id\uFF08\u68C0\u7D22\u547D\u4E2D\u91CC # \u540E\u9762\u90A3\u4E2A\u6570\u5B57\uFF09\u3002\u7701\u7565\u65F6\u6539\u4E3A\u8BFB\u6700\u8FD1 ${DEFAULT_TAIL} \u6761`
|
|
6342
|
+
},
|
|
6343
|
+
tail: {
|
|
6344
|
+
type: "number",
|
|
6345
|
+
description: `\u7701\u7565 messageId \u65F6\u8BFB\u6700\u8FD1\u51E0\u6761\uFF0C\u9ED8\u8BA4 ${DEFAULT_TAIL}\uFF0C\u4E0A\u9650 ${MAX_TAIL}`
|
|
4835
6346
|
},
|
|
4836
6347
|
before: {
|
|
4837
6348
|
type: "number",
|
|
@@ -4848,7 +6359,7 @@ before / after \u5404\u9ED8\u8BA4 ${DEFAULT_WINDOW}\u3001\u4E0A\u9650 ${MAX_WIND
|
|
|
4848
6359
|
}
|
|
4849
6360
|
} : {}
|
|
4850
6361
|
},
|
|
4851
|
-
required: ["sessionId"
|
|
6362
|
+
required: ["sessionId"]
|
|
4852
6363
|
};
|
|
4853
6364
|
},
|
|
4854
6365
|
exposure: ToolExposure.Direct,
|
|
@@ -4865,14 +6376,15 @@ before / after \u5404\u9ED8\u8BA4 ${DEFAULT_WINDOW}\u3001\u4E0A\u9650 ${MAX_WIND
|
|
|
4865
6376
|
const start = Date.now();
|
|
4866
6377
|
const sessionId = String(args["sessionId"] ?? "").trim();
|
|
4867
6378
|
if (!sessionId) return Promise.resolve(fail4("sessionId must not be empty", start, 8007));
|
|
4868
|
-
const
|
|
4869
|
-
|
|
6379
|
+
const rawId = args["messageId"];
|
|
6380
|
+
const messageId = rawId === void 0 || rawId === null || rawId === "" ? void 0 : Number(rawId);
|
|
6381
|
+
if (messageId !== void 0 && (!Number.isInteger(messageId) || messageId <= 0)) {
|
|
4870
6382
|
return Promise.resolve(
|
|
4871
6383
|
fail4(
|
|
4872
6384
|
"messageId must be a positive integer",
|
|
4873
6385
|
start,
|
|
4874
6386
|
8008,
|
|
4875
|
-
"Use the number after # from a session_search / session_messages_search hit"
|
|
6387
|
+
"Use the number after # from a session_search / session_messages_search hit \u2014 or omit messageId entirely to read the latest messages in that session"
|
|
4876
6388
|
)
|
|
4877
6389
|
);
|
|
4878
6390
|
}
|
|
@@ -4880,9 +6392,10 @@ before / after \u5404\u9ED8\u8BA4 ${DEFAULT_WINDOW}\u3001\u4E0A\u9650 ${MAX_WIND
|
|
|
4880
6392
|
try {
|
|
4881
6393
|
const out = deps.queries.readMessages({
|
|
4882
6394
|
sessionId,
|
|
4883
|
-
messageId,
|
|
6395
|
+
...messageId === void 0 ? {} : { messageId },
|
|
4884
6396
|
before: clampWindow(args["before"], DEFAULT_WINDOW, MAX_WINDOW),
|
|
4885
6397
|
after: clampWindow(args["after"], DEFAULT_WINDOW, MAX_WINDOW),
|
|
6398
|
+
tail: clampWindow(args["tail"], DEFAULT_TAIL, MAX_TAIL),
|
|
4886
6399
|
currentSessionId: ctx.sessionId,
|
|
4887
6400
|
workspaceCwd: deps.workspaceCwd,
|
|
4888
6401
|
allWorkspaces
|
|
@@ -4897,13 +6410,13 @@ before / after \u5404\u9ED8\u8BA4 ${DEFAULT_WINDOW}\u3001\u4E0A\u9650 ${MAX_WIND
|
|
|
4897
6410
|
)
|
|
4898
6411
|
);
|
|
4899
6412
|
}
|
|
4900
|
-
if (!out.anchor) {
|
|
6413
|
+
if (messageId !== void 0 && !out.anchor) {
|
|
4901
6414
|
return Promise.resolve(
|
|
4902
6415
|
fail4(
|
|
4903
6416
|
`session ${sessionId} has no message #${messageId} (it has ${out.total})`,
|
|
4904
6417
|
start,
|
|
4905
6418
|
8010,
|
|
4906
|
-
"messageId must come from a hit in that same session \u2014 ids are not positions"
|
|
6419
|
+
"messageId must come from a hit in that same session \u2014 ids are not positions. Omit messageId entirely to read the latest messages instead."
|
|
4907
6420
|
)
|
|
4908
6421
|
);
|
|
4909
6422
|
}
|
|
@@ -4912,8 +6425,8 @@ before / after \u5404\u9ED8\u8BA4 ${DEFAULT_WINDOW}\u3001\u4E0A\u9650 ${MAX_WIND
|
|
|
4912
6425
|
output: renderWindow(out, sessionId, sessionId === ctx.sessionId),
|
|
4913
6426
|
duration: Date.now() - start
|
|
4914
6427
|
});
|
|
4915
|
-
} catch (
|
|
4916
|
-
return Promise.resolve(fail4(
|
|
6428
|
+
} catch (err3) {
|
|
6429
|
+
return Promise.resolve(fail4(err3 instanceof Error ? err3.message : String(err3), start, 8011));
|
|
4917
6430
|
}
|
|
4918
6431
|
}
|
|
4919
6432
|
};
|
|
@@ -5019,8 +6532,8 @@ function createSessionTraceTool(deps) {
|
|
|
5019
6532
|
output: renderTrace(trace, ctx.sessionId),
|
|
5020
6533
|
duration: Date.now() - start
|
|
5021
6534
|
});
|
|
5022
|
-
} catch (
|
|
5023
|
-
return Promise.resolve(fail4(
|
|
6535
|
+
} catch (err3) {
|
|
6536
|
+
return Promise.resolve(fail4(err3 instanceof Error ? err3.message : String(err3), start, 8013));
|
|
5024
6537
|
}
|
|
5025
6538
|
}
|
|
5026
6539
|
};
|
|
@@ -5036,7 +6549,9 @@ function fail5(message, start, code, suggestion) {
|
|
|
5036
6549
|
};
|
|
5037
6550
|
}
|
|
5038
6551
|
function emptyHint(query) {
|
|
5039
|
-
return belowTrigramFloor(sanitizeFtsQuery(query)) ? ` Note: every word here is shorter than ${TRIGRAM_MIN_CHARS} characters, which the substring index cannot match at all \u2014 this is "cannot search", not "not found". Retry with a longer phrase.` :
|
|
6552
|
+
return belowTrigramFloor(sanitizeFtsQuery(query)) ? ` Note: every word here is shorter than ${TRIGRAM_MIN_CHARS} characters, which the substring index cannot match at all \u2014 this is "cannot search", not "not found". Retry with a longer phrase.` : (
|
|
6553
|
+
" Try a shorter phrase copied verbatim from the text you expect \u2014 matching is on a continuous substring (at least 3 characters), not on separate keywords joined together."
|
|
6554
|
+
);
|
|
5040
6555
|
}
|
|
5041
6556
|
function clampLimit2(raw) {
|
|
5042
6557
|
const n = Number(raw);
|
|
@@ -5078,7 +6593,7 @@ function createSessionSearchTool(deps) {
|
|
|
5078
6593
|
properties: {
|
|
5079
6594
|
query: {
|
|
5080
6595
|
type: "string",
|
|
5081
|
-
description: "\u68C0\u7D22\u8BCD\u3002\u5F53\u666E\u901A\u6587\u672C\u5199\uFF0C\u4E0D\u8981\u5199 FTS5 \u8BED\u6CD5\uFF08\u5F15\u53F7 / \u62EC\u53F7 / AND \u4F1A\u88AB\u6E05\u6389\uFF09"
|
|
6596
|
+
description: "\u68C0\u7D22\u8BCD\u3002\u5F53\u666E\u901A\u6587\u672C\u5199\uFF0C\u4E0D\u8981\u5199 FTS5 \u8BED\u6CD5\uFF08\u5F15\u53F7 / \u62EC\u53F7 / AND \u4F1A\u88AB\u6E05\u6389\uFF09\u3002\n\u5339\u914D\u7684\u662F**\u539F\u6587\u91CC\u8FDE\u7EED\u51FA\u73B0\u7684\u4E00\u6BB5**\uFF08\u81F3\u5C11 3 \u4E2A\u5B57\uFF09\uFF0C\u4E0D\u662F\u5206\u8BCD \u2014\u2014 \u6284\u539F\u6587\u91CC\u8FB9\u8FDE\u7740\u7684\u51E0\u4E2A\u5B57\u6BD4\u62FC\u5173\u952E\u8BCD\u51C6\u3002"
|
|
5082
6597
|
},
|
|
5083
6598
|
limit: {
|
|
5084
6599
|
type: "number",
|
|
@@ -5143,10 +6658,10 @@ function createSessionSearchTool(deps) {
|
|
|
5143
6658
|
].join("\n"),
|
|
5144
6659
|
duration: Date.now() - start
|
|
5145
6660
|
});
|
|
5146
|
-
} catch (
|
|
6661
|
+
} catch (err3) {
|
|
5147
6662
|
return Promise.resolve(
|
|
5148
6663
|
fail5(
|
|
5149
|
-
|
|
6664
|
+
err3 instanceof Error ? err3.message : String(err3),
|
|
5150
6665
|
start,
|
|
5151
6666
|
8002,
|
|
5152
6667
|
"Retry with different words"
|
|
@@ -5170,7 +6685,7 @@ function createSessionMessagesSearchTool(deps) {
|
|
|
5170
6685
|
},
|
|
5171
6686
|
query: {
|
|
5172
6687
|
type: "string",
|
|
5173
|
-
description: "\u68C0\u7D22\u8BCD\u3002\u5F53\u666E\u901A\u6587\u672C\u5199\uFF0C\u4E0D\u8981\u5199 FTS5 \u8BED\u6CD5"
|
|
6688
|
+
description: "\u68C0\u7D22\u8BCD\u3002\u5F53\u666E\u901A\u6587\u672C\u5199\uFF0C\u4E0D\u8981\u5199 FTS5 \u8BED\u6CD5\u3002\n\u5339\u914D\u7684\u662F**\u539F\u6587\u91CC\u8FDE\u7EED\u51FA\u73B0\u7684\u4E00\u6BB5**\uFF08\u81F3\u5C11 3 \u4E2A\u5B57\uFF09\uFF0C\u4E0D\u662F\u5206\u8BCD \u2014\u2014 \u6284\u539F\u6587\u91CC\u8FB9\u8FDE\u7740\u7684\u51E0\u4E2A\u5B57\u6BD4\u62FC\u5173\u952E\u8BCD\u51C6\u3002"
|
|
5174
6689
|
},
|
|
5175
6690
|
limit: {
|
|
5176
6691
|
type: "number",
|
|
@@ -5239,10 +6754,10 @@ function createSessionMessagesSearchTool(deps) {
|
|
|
5239
6754
|
].join("\n"),
|
|
5240
6755
|
duration: Date.now() - start
|
|
5241
6756
|
});
|
|
5242
|
-
} catch (
|
|
6757
|
+
} catch (err3) {
|
|
5243
6758
|
return Promise.resolve(
|
|
5244
6759
|
fail5(
|
|
5245
|
-
|
|
6760
|
+
err3 instanceof Error ? err3.message : String(err3),
|
|
5246
6761
|
start,
|
|
5247
6762
|
8006,
|
|
5248
6763
|
"Retry with different words"
|
|
@@ -5341,10 +6856,10 @@ function parseFrontmatter(raw) {
|
|
|
5341
6856
|
if (!split) return { error: t("frontmatter.missing") };
|
|
5342
6857
|
try {
|
|
5343
6858
|
return { data: load(split.frontmatter), body: split.body };
|
|
5344
|
-
} catch (
|
|
6859
|
+
} catch (err3) {
|
|
5345
6860
|
return {
|
|
5346
6861
|
error: t("frontmatter.bad_yaml", {
|
|
5347
|
-
reason:
|
|
6862
|
+
reason: err3 instanceof Error ? err3.message : String(err3)
|
|
5348
6863
|
})
|
|
5349
6864
|
};
|
|
5350
6865
|
}
|
|
@@ -5457,10 +6972,10 @@ function fail7(message, start, code, suggestion) {
|
|
|
5457
6972
|
function done(output, start) {
|
|
5458
6973
|
return { success: true, output, duration: Date.now() - start };
|
|
5459
6974
|
}
|
|
5460
|
-
function fromThrow(
|
|
5461
|
-
return fail7(
|
|
6975
|
+
function fromThrow(err3, start, suggestion) {
|
|
6976
|
+
return fail7(err3 instanceof Error ? err3.message : String(err3), start, 3102, suggestion);
|
|
5462
6977
|
}
|
|
5463
|
-
function
|
|
6978
|
+
function str4(args, key) {
|
|
5464
6979
|
const raw = args[key];
|
|
5465
6980
|
return typeof raw === "string" ? raw : "";
|
|
5466
6981
|
}
|
|
@@ -5510,9 +7025,9 @@ function createTool(deps) {
|
|
|
5510
7025
|
describeTarget: (args) => `${SKILL_CREATE_TOOL}:${String(args["name"] ?? "")}`,
|
|
5511
7026
|
async execute(args) {
|
|
5512
7027
|
const start = Date.now();
|
|
5513
|
-
const name =
|
|
5514
|
-
const content =
|
|
5515
|
-
const category =
|
|
7028
|
+
const name = str4(args, "name").trim();
|
|
7029
|
+
const content = str4(args, "content");
|
|
7030
|
+
const category = str4(args, "category").trim() || "general";
|
|
5516
7031
|
if (!WRITABLE_SKILL_NAME.test(name)) {
|
|
5517
7032
|
return fail7(`invalid skill name: ${JSON.stringify(name)}`, start, 3101, WRITABLE_HINT);
|
|
5518
7033
|
}
|
|
@@ -5524,8 +7039,8 @@ function createTool(deps) {
|
|
|
5524
7039
|
try {
|
|
5525
7040
|
const path = await deps.skills.create(name, content, category);
|
|
5526
7041
|
return done(`created skill "${name}" at ${path}`, start);
|
|
5527
|
-
} catch (
|
|
5528
|
-
return fromThrow(
|
|
7042
|
+
} catch (err3) {
|
|
7043
|
+
return fromThrow(err3, start);
|
|
5529
7044
|
}
|
|
5530
7045
|
}
|
|
5531
7046
|
};
|
|
@@ -5549,8 +7064,8 @@ function editTool(deps) {
|
|
|
5549
7064
|
describeTarget: (args) => `${SKILL_EDIT_TOOL}:${String(args["name"] ?? "")}`,
|
|
5550
7065
|
async execute(args) {
|
|
5551
7066
|
const start = Date.now();
|
|
5552
|
-
const name =
|
|
5553
|
-
const content =
|
|
7067
|
+
const name = str4(args, "name").trim();
|
|
7068
|
+
const content = str4(args, "content");
|
|
5554
7069
|
if (!name) {
|
|
5555
7070
|
return fail7("name must not be empty", start, 3101, describeAvailableSkills(deps.skills));
|
|
5556
7071
|
}
|
|
@@ -5559,8 +7074,8 @@ function editTool(deps) {
|
|
|
5559
7074
|
try {
|
|
5560
7075
|
await deps.skills.edit(name, content);
|
|
5561
7076
|
return done(`rewrote SKILL.md of skill "${name}"`, start);
|
|
5562
|
-
} catch (
|
|
5563
|
-
return fromThrow(
|
|
7077
|
+
} catch (err3) {
|
|
7078
|
+
return fromThrow(err3, start, describeAvailableSkills(deps.skills));
|
|
5564
7079
|
}
|
|
5565
7080
|
}
|
|
5566
7081
|
};
|
|
@@ -5589,9 +7104,9 @@ function patchTool(deps) {
|
|
|
5589
7104
|
describeTarget: (args) => `${SKILL_PATCH_TOOL}:${String(args["name"] ?? "")}/${String(args["file_path"] ?? "SKILL.md")}`,
|
|
5590
7105
|
async execute(args) {
|
|
5591
7106
|
const start = Date.now();
|
|
5592
|
-
const name =
|
|
5593
|
-
const oldString =
|
|
5594
|
-
const filePath =
|
|
7107
|
+
const name = str4(args, "name").trim();
|
|
7108
|
+
const oldString = str4(args, "old_string");
|
|
7109
|
+
const filePath = str4(args, "file_path").trim();
|
|
5595
7110
|
if (!name) {
|
|
5596
7111
|
return fail7("name must not be empty", start, 3101, describeAvailableSkills(deps.skills));
|
|
5597
7112
|
}
|
|
@@ -5602,12 +7117,12 @@ function patchTool(deps) {
|
|
|
5602
7117
|
await deps.skills.patch(
|
|
5603
7118
|
name,
|
|
5604
7119
|
oldString,
|
|
5605
|
-
|
|
7120
|
+
str4(args, "new_string"),
|
|
5606
7121
|
filePath === "" ? void 0 : filePath
|
|
5607
7122
|
);
|
|
5608
7123
|
return done(`patched ${filePath || "SKILL.md"} of skill "${name}"`, start);
|
|
5609
|
-
} catch (
|
|
5610
|
-
return fromThrow(
|
|
7124
|
+
} catch (err3) {
|
|
7125
|
+
return fromThrow(err3, start, describeAvailableSkills(deps.skills));
|
|
5611
7126
|
}
|
|
5612
7127
|
}
|
|
5613
7128
|
};
|
|
@@ -5635,17 +7150,17 @@ function writeFileTool(deps) {
|
|
|
5635
7150
|
describeTarget: (args) => `${SKILL_WRITE_FILE_TOOL}:${String(args["name"] ?? "")}/${String(args["file_path"] ?? "")}`,
|
|
5636
7151
|
async execute(args) {
|
|
5637
7152
|
const start = Date.now();
|
|
5638
|
-
const name =
|
|
5639
|
-
const filePath =
|
|
7153
|
+
const name = str4(args, "name").trim();
|
|
7154
|
+
const filePath = str4(args, "file_path").trim();
|
|
5640
7155
|
if (!name) {
|
|
5641
7156
|
return fail7("name must not be empty", start, 3101, describeAvailableSkills(deps.skills));
|
|
5642
7157
|
}
|
|
5643
7158
|
if (!filePath) return fail7("file_path must not be empty", start, 3101);
|
|
5644
7159
|
try {
|
|
5645
|
-
await deps.skills.writeFile(name, filePath,
|
|
7160
|
+
await deps.skills.writeFile(name, filePath, str4(args, "content"));
|
|
5646
7161
|
return done(`wrote ${filePath} into skill "${name}"`, start);
|
|
5647
|
-
} catch (
|
|
5648
|
-
return fromThrow(
|
|
7162
|
+
} catch (err3) {
|
|
7163
|
+
return fromThrow(err3, start, describeAvailableSkills(deps.skills));
|
|
5649
7164
|
}
|
|
5650
7165
|
}
|
|
5651
7166
|
};
|
|
@@ -5680,7 +7195,7 @@ function matches(tool, terms) {
|
|
|
5680
7195
|
function createToolSearchTool(deps) {
|
|
5681
7196
|
return {
|
|
5682
7197
|
name: "tool_search",
|
|
5683
|
-
description: '\u6309\u5173\u952E\u8BCD\u627E\u51FA**\u5F53\u524D\u5DE5\u5177\u5217\u8868\u91CC\u6CA1\u6709**\u7684\u5DE5\u5177\uFF0C\u627E\u5230\u4E4B\u540E\u5B83\u4EEC\u5C31\u4F1A\u51FA\u73B0\u5728\u4F60\u7684\u5DE5\u5177\u5217\u8868\u91CC\u3002\n\u8FD9\u53F0\u673A\u5668\u4E0A\u63A5\u7684\u5DE5\u5177\u53EF\u80FD\u5F88\u591A\uFF08\u6BD4\u5982\u5404\u79CD MCP server\uFF09\uFF0C\u5168\u90E8\u585E\u8FDB\u5217\u8868\u4F1A\u5360\u6389\u5927\u91CF\u4E0A\u4E0B\u6587\uFF0C\u6240\u4EE5\u4E0D\u5E38\u7528\u7684\u90A3\u4E9B\u9ED8\u8BA4\u4E0D\u5728\u91CC\u9762 \u2014\u2014 \u9700\u8981\u65F6\u7528\u8FD9\u4E2A\u5DE5\u5177\u628A\u5B83\u4EEC\u627E\u51FA\u6765\u3002\n\u67E5\u8BE2\u8BCD\u5199\u4F60\u60F3\u5E72\u7684\u4E8B\u6216\u76EE\u6807\u7CFB\u7EDF\uFF0C\u6BD4\u5982 "github issue"\u3001"\u6570\u636E\u5E93 \u67E5\u8BE2"\u3002\u591A\u4E2A\u8BCD\u662F\u300C\u90FD\u8981\u547D\u4E2D\u300D\uFF0C\u5148\u5199\u5BBD\u4E00\u70B9\u518D\u6536\u7A84\u3002\n\u26A0\uFE0F \u627E\u5230\u4E4B\u540E**\u4E0D\u8981\
|
|
7198
|
+
description: '\u6309\u5173\u952E\u8BCD\u627E\u51FA**\u5F53\u524D\u5DE5\u5177\u5217\u8868\u91CC\u6CA1\u6709**\u7684\u5DE5\u5177\uFF0C\u627E\u5230\u4E4B\u540E\u5B83\u4EEC\u5C31\u4F1A\u51FA\u73B0\u5728\u4F60\u7684\u5DE5\u5177\u5217\u8868\u91CC\u3002\n\u8FD9\u53F0\u673A\u5668\u4E0A\u63A5\u7684\u5DE5\u5177\u53EF\u80FD\u5F88\u591A\uFF08\u6BD4\u5982\u5404\u79CD MCP server\uFF09\uFF0C\u5168\u90E8\u585E\u8FDB\u5217\u8868\u4F1A\u5360\u6389\u5927\u91CF\u4E0A\u4E0B\u6587\uFF0C\u6240\u4EE5\u4E0D\u5E38\u7528\u7684\u90A3\u4E9B\u9ED8\u8BA4\u4E0D\u5728\u91CC\u9762 \u2014\u2014 \u9700\u8981\u65F6\u7528\u8FD9\u4E2A\u5DE5\u5177\u628A\u5B83\u4EEC\u627E\u51FA\u6765\u3002\n\u67E5\u8BE2\u8BCD\u5199\u4F60\u60F3\u5E72\u7684\u4E8B\u6216\u76EE\u6807\u7CFB\u7EDF\uFF0C\u6BD4\u5982 "github issue"\u3001"\u6570\u636E\u5E93 \u67E5\u8BE2"\u3002\u591A\u4E2A\u8BCD\u662F\u300C\u90FD\u8981\u547D\u4E2D\u300D\uFF0C\u5148\u5199\u5BBD\u4E00\u70B9\u518D\u6536\u7A84\u3002\n\u26A0\uFE0F \u627E\u5230\u4E4B\u540E**\u4E0D\u8981\u505C\u4E0B\u6765\u7B49\u7528\u6237** \u2014\u2014 \u7D27\u63A5\u7740\u518D\u53D1\u8D77\u4E00\u6B21\u8BF7\u6C42\uFF0C\u5B83\u4EEC\u5C31\u5DF2\u7ECF\u5728\u4F60\u7684\u5DE5\u5177\u5217\u8868\u91CC\u4E86\uFF1B\n\u552F\u4E00\u505A\u4E0D\u5230\u7684\u662F\u548C `tool_search` \u5728**\u540C\u4E00\u6B21\u54CD\u5E94\u91CC**\u5E76\u884C\u8C03\u5B83\u4EEC\uFF08\u53D1\u8FD9\u6B21\u8BF7\u6C42\u65F6\u5B83\u4EEC\u8FD8\u4E0D\u5728\u5217\u8868\u91CC\uFF09\u3002',
|
|
5684
7199
|
parameters: {
|
|
5685
7200
|
type: "object",
|
|
5686
7201
|
properties: {
|
|
@@ -5721,7 +7236,7 @@ function createToolSearchTool(deps) {
|
|
|
5721
7236
|
(${hits.length - picked.length} more matched but were not added \u2014 narrow the query if the tool you want is missing.)` : "";
|
|
5722
7237
|
return Promise.resolve({
|
|
5723
7238
|
success: true,
|
|
5724
|
-
output: `Added ${picked.length} tool(s) to your tool list. They
|
|
7239
|
+
output: `Added ${picked.length} tool(s) to your tool list. They are callable on your **next request** \u2014 the next step of this same turn. The only thing you cannot do is call them in the same response that ran this search. Do not stop and wait for the user.
|
|
5725
7240
|
|
|
5726
7241
|
${lines.join("\n")}${truncated}`,
|
|
5727
7242
|
duration: Date.now() - start
|
|
@@ -5765,8 +7280,8 @@ var MIGRATIONS = [
|
|
|
5765
7280
|
var TrackerDB = class {
|
|
5766
7281
|
db;
|
|
5767
7282
|
path;
|
|
5768
|
-
constructor(
|
|
5769
|
-
this.path =
|
|
7283
|
+
constructor(dbPath2) {
|
|
7284
|
+
this.path = dbPath2;
|
|
5770
7285
|
this.db = openDatabase(this.path);
|
|
5771
7286
|
migrate(this.db, NS, MIGRATIONS);
|
|
5772
7287
|
}
|
|
@@ -5918,13 +7433,13 @@ function createTodoTool(db) {
|
|
|
5918
7433
|
output: formatTodoList(todos, pendingCount),
|
|
5919
7434
|
duration: Date.now() - startTime
|
|
5920
7435
|
};
|
|
5921
|
-
} catch (
|
|
7436
|
+
} catch (err3) {
|
|
5922
7437
|
return {
|
|
5923
7438
|
success: false,
|
|
5924
7439
|
output: "TODO \u5217\u8868\u5199\u5165\u5931\u8D25",
|
|
5925
7440
|
error: {
|
|
5926
7441
|
code: 1,
|
|
5927
|
-
message:
|
|
7442
|
+
message: err3 instanceof Error ? err3.message : String(err3)
|
|
5928
7443
|
},
|
|
5929
7444
|
duration: Date.now() - startTime
|
|
5930
7445
|
};
|
|
@@ -5932,6 +7447,260 @@ function createTodoTool(db) {
|
|
|
5932
7447
|
}
|
|
5933
7448
|
};
|
|
5934
7449
|
}
|
|
7450
|
+
var MAX_POST_CHARS = 2e4;
|
|
7451
|
+
var CHANNEL_PATTERN = /^[A-Za-z0-9_.-]{1,64}$/;
|
|
7452
|
+
var MIGRATIONS2 = [
|
|
7453
|
+
{
|
|
7454
|
+
id: "board-initial",
|
|
7455
|
+
version: 1,
|
|
7456
|
+
description: "\u8BA8\u8BBA\u677F\uFF1A\u9891\u9053 / \u7EBF\u7A0B / \u5E16\u5B50 / \u8BA2\u9605",
|
|
7457
|
+
up: (db) => {
|
|
7458
|
+
db.exec(`
|
|
7459
|
+
CREATE TABLE IF NOT EXISTS board_channels (
|
|
7460
|
+
id TEXT PRIMARY KEY,
|
|
7461
|
+
name TEXT NOT NULL UNIQUE,
|
|
7462
|
+
description TEXT,
|
|
7463
|
+
created_by TEXT NOT NULL,
|
|
7464
|
+
created_at INTEGER NOT NULL
|
|
7465
|
+
);
|
|
7466
|
+
CREATE TABLE IF NOT EXISTS board_threads (
|
|
7467
|
+
id TEXT PRIMARY KEY,
|
|
7468
|
+
channel TEXT NOT NULL,
|
|
7469
|
+
title TEXT NOT NULL,
|
|
7470
|
+
created_by TEXT NOT NULL,
|
|
7471
|
+
created_at INTEGER NOT NULL,
|
|
7472
|
+
last_post_at INTEGER NOT NULL
|
|
7473
|
+
);
|
|
7474
|
+
CREATE INDEX IF NOT EXISTS board_threads_channel ON board_threads(channel, last_post_at DESC);
|
|
7475
|
+
CREATE TABLE IF NOT EXISTS board_posts (
|
|
7476
|
+
seq INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
7477
|
+
id TEXT NOT NULL UNIQUE,
|
|
7478
|
+
thread_id TEXT NOT NULL,
|
|
7479
|
+
author TEXT NOT NULL,
|
|
7480
|
+
text TEXT NOT NULL,
|
|
7481
|
+
created_at INTEGER NOT NULL
|
|
7482
|
+
);
|
|
7483
|
+
CREATE INDEX IF NOT EXISTS board_posts_thread ON board_posts(thread_id, seq);
|
|
7484
|
+
CREATE TABLE IF NOT EXISTS board_subscriptions (
|
|
7485
|
+
agent TEXT NOT NULL,
|
|
7486
|
+
target TEXT NOT NULL,
|
|
7487
|
+
last_seen_seq INTEGER NOT NULL DEFAULT 0,
|
|
7488
|
+
PRIMARY KEY (agent, target)
|
|
7489
|
+
);
|
|
7490
|
+
`);
|
|
7491
|
+
}
|
|
7492
|
+
}
|
|
7493
|
+
];
|
|
7494
|
+
function targetKey(t83) {
|
|
7495
|
+
return t83.kind === "channel" ? `channel:${t83.name}` : `thread:${t83.id}`;
|
|
7496
|
+
}
|
|
7497
|
+
var BoardStore = class {
|
|
7498
|
+
path;
|
|
7499
|
+
db;
|
|
7500
|
+
constructor(homeDir) {
|
|
7501
|
+
this.path = dbPath(homeDir);
|
|
7502
|
+
this.db = openDatabase(this.path);
|
|
7503
|
+
migrate(this.db, "board", MIGRATIONS2);
|
|
7504
|
+
}
|
|
7505
|
+
close() {
|
|
7506
|
+
releaseDatabase(this.path);
|
|
7507
|
+
}
|
|
7508
|
+
createChannel(args) {
|
|
7509
|
+
if (!CHANNEL_PATTERN.test(args.name)) {
|
|
7510
|
+
throw new Error(`\u9891\u9053\u540D\u4E0D\u5408\u6CD5\uFF1A${args.name}\uFF08\u53EA\u8BB8\u5B57\u6BCD\u6570\u5B57 _ . -\uFF0C\u6700\u957F 64\uFF09`);
|
|
7511
|
+
}
|
|
7512
|
+
const existing = this.channel(args.name);
|
|
7513
|
+
if (existing) return existing;
|
|
7514
|
+
const row = {
|
|
7515
|
+
id: `ch-${randomUUID().slice(0, 8)}`,
|
|
7516
|
+
name: args.name,
|
|
7517
|
+
...args.description ? { description: args.description } : {},
|
|
7518
|
+
createdBy: args.by,
|
|
7519
|
+
createdAt: Date.now()
|
|
7520
|
+
};
|
|
7521
|
+
this.db.prepare(
|
|
7522
|
+
`INSERT INTO board_channels (id, name, description, created_by, created_at)
|
|
7523
|
+
VALUES (?, ?, ?, ?, ?)`
|
|
7524
|
+
).run(row.id, row.name, row.description ?? null, row.createdBy, row.createdAt);
|
|
7525
|
+
return row;
|
|
7526
|
+
}
|
|
7527
|
+
upsertChannel(args) {
|
|
7528
|
+
const existing = this.channel(args.name);
|
|
7529
|
+
if (!existing) return this.createChannel(args);
|
|
7530
|
+
this.db.prepare(`UPDATE board_channels SET description = ? WHERE name = ?`).run(args.description, args.name);
|
|
7531
|
+
return { ...existing, description: args.description };
|
|
7532
|
+
}
|
|
7533
|
+
channel(name) {
|
|
7534
|
+
const row = this.db.prepare(
|
|
7535
|
+
`SELECT id, name, description, created_by, created_at FROM board_channels WHERE name = ?`
|
|
7536
|
+
).get(name);
|
|
7537
|
+
return row ? toChannel(row) : void 0;
|
|
7538
|
+
}
|
|
7539
|
+
listChannels() {
|
|
7540
|
+
const rows = this.db.prepare(
|
|
7541
|
+
`SELECT id, name, description, created_by, created_at FROM board_channels ORDER BY name`
|
|
7542
|
+
).all();
|
|
7543
|
+
return rows.map(toChannel);
|
|
7544
|
+
}
|
|
7545
|
+
listThreads(channel, limit = 20) {
|
|
7546
|
+
const rows = this.db.prepare(
|
|
7547
|
+
`SELECT t.id, t.channel, t.title, t.created_by, t.created_at, t.last_post_at,
|
|
7548
|
+
(SELECT COUNT(*) FROM board_posts p WHERE p.thread_id = t.id) AS posts
|
|
7549
|
+
FROM board_threads t WHERE t.channel = ? ORDER BY t.last_post_at DESC LIMIT ?`
|
|
7550
|
+
).all(channel, limit);
|
|
7551
|
+
return rows.map((r) => ({
|
|
7552
|
+
id: r.id,
|
|
7553
|
+
channel: r.channel,
|
|
7554
|
+
title: r.title,
|
|
7555
|
+
createdBy: r.created_by,
|
|
7556
|
+
createdAt: r.created_at,
|
|
7557
|
+
lastPostAt: r.last_post_at,
|
|
7558
|
+
postCount: r.posts
|
|
7559
|
+
}));
|
|
7560
|
+
}
|
|
7561
|
+
post(args) {
|
|
7562
|
+
return this.write({ ...args, notify: true });
|
|
7563
|
+
}
|
|
7564
|
+
append(args) {
|
|
7565
|
+
return this.write({ ...args, notify: false });
|
|
7566
|
+
}
|
|
7567
|
+
write(args) {
|
|
7568
|
+
const text = clip(args.text);
|
|
7569
|
+
const now = Date.now();
|
|
7570
|
+
const run = this.db.transaction(() => {
|
|
7571
|
+
let threadId;
|
|
7572
|
+
if (args.target.kind === "thread") {
|
|
7573
|
+
const exists2 = this.db.prepare(`SELECT id FROM board_threads WHERE id = ?`).get(args.target.id);
|
|
7574
|
+
if (!exists2) throw new Error(`\u6CA1\u6709\u8FD9\u4E2A\u7EBF\u7A0B\uFF1A${args.target.id}`);
|
|
7575
|
+
threadId = args.target.id;
|
|
7576
|
+
} else {
|
|
7577
|
+
const ch = this.channel(args.target.name);
|
|
7578
|
+
if (!ch) throw new Error(`\u6CA1\u6709\u8FD9\u4E2A\u9891\u9053\uFF1A${args.target.name}`);
|
|
7579
|
+
threadId = `th-${randomUUID().slice(0, 8)}`;
|
|
7580
|
+
this.db.prepare(
|
|
7581
|
+
`INSERT INTO board_threads (id, channel, title, created_by, created_at, last_post_at)
|
|
7582
|
+
VALUES (?, ?, ?, ?, ?, ?)`
|
|
7583
|
+
).run(threadId, ch.name, firstLine(text), args.author, now, now);
|
|
7584
|
+
}
|
|
7585
|
+
const id = `po-${randomUUID().slice(0, 8)}`;
|
|
7586
|
+
const info = this.db.prepare(
|
|
7587
|
+
`INSERT INTO board_posts (id, thread_id, author, text, created_at) VALUES (?, ?, ?, ?, ?)`
|
|
7588
|
+
).run(id, threadId, args.author, text, now);
|
|
7589
|
+
const seq = Number(info.lastInsertRowid);
|
|
7590
|
+
this.db.prepare(`UPDATE board_threads SET last_post_at = ? WHERE id = ?`).run(now, threadId);
|
|
7591
|
+
if (args.notify) {
|
|
7592
|
+
this.subscribe(args.author, { kind: "thread", id: threadId }, seq);
|
|
7593
|
+
}
|
|
7594
|
+
return {
|
|
7595
|
+
post: { id, threadId, author: args.author, text, createdAt: now, seq },
|
|
7596
|
+
threadId
|
|
7597
|
+
};
|
|
7598
|
+
});
|
|
7599
|
+
return run();
|
|
7600
|
+
}
|
|
7601
|
+
readThread(threadId, limit = 50) {
|
|
7602
|
+
const rows = this.db.prepare(
|
|
7603
|
+
`SELECT seq, id, thread_id, author, text, created_at FROM board_posts
|
|
7604
|
+
WHERE thread_id = ? ORDER BY seq ASC LIMIT ?`
|
|
7605
|
+
).all(threadId, limit);
|
|
7606
|
+
return rows.map(toPost);
|
|
7607
|
+
}
|
|
7608
|
+
readPost(id) {
|
|
7609
|
+
const row = this.db.prepare(`SELECT seq, id, thread_id, author, text, created_at FROM board_posts WHERE id = ?`).get(id);
|
|
7610
|
+
return row ? toPost(row) : void 0;
|
|
7611
|
+
}
|
|
7612
|
+
searchPosts(query, channel, limit = 20) {
|
|
7613
|
+
const like = `%${query}%`;
|
|
7614
|
+
const rows = channel ? this.db.prepare(
|
|
7615
|
+
`SELECT p.seq, p.id, p.thread_id, p.author, p.text, p.created_at
|
|
7616
|
+
FROM board_posts p JOIN board_threads t ON t.id = p.thread_id
|
|
7617
|
+
WHERE t.channel = ? AND p.text LIKE ? ORDER BY p.seq DESC LIMIT ?`
|
|
7618
|
+
).all(channel, like, limit) : this.db.prepare(
|
|
7619
|
+
`SELECT seq, id, thread_id, author, text, created_at FROM board_posts
|
|
7620
|
+
WHERE text LIKE ? ORDER BY seq DESC LIMIT ?`
|
|
7621
|
+
).all(like, limit);
|
|
7622
|
+
return rows.map(toPost);
|
|
7623
|
+
}
|
|
7624
|
+
subscribe(agent, target, seenSeq) {
|
|
7625
|
+
const key = targetKey(target);
|
|
7626
|
+
const initial = seenSeq ?? this.maxSeq();
|
|
7627
|
+
this.db.prepare(
|
|
7628
|
+
`INSERT INTO board_subscriptions (agent, target, last_seen_seq) VALUES (?, ?, ?)
|
|
7629
|
+
ON CONFLICT(agent, target) DO UPDATE SET
|
|
7630
|
+
last_seen_seq = MAX(board_subscriptions.last_seen_seq, excluded.last_seen_seq)`
|
|
7631
|
+
).run(agent, key, initial);
|
|
7632
|
+
}
|
|
7633
|
+
maxSeq() {
|
|
7634
|
+
const row = this.db.prepare(`SELECT COALESCE(MAX(seq), 0) AS n FROM board_posts`).get();
|
|
7635
|
+
return row.n;
|
|
7636
|
+
}
|
|
7637
|
+
unsubscribe(agent, target) {
|
|
7638
|
+
const info = this.db.prepare(`DELETE FROM board_subscriptions WHERE agent = ? AND target = ?`).run(agent, targetKey(target));
|
|
7639
|
+
return info.changes > 0;
|
|
7640
|
+
}
|
|
7641
|
+
pendingFor(agent) {
|
|
7642
|
+
const subs = this.db.prepare(`SELECT target, last_seen_seq FROM board_subscriptions WHERE agent = ?`).all(agent);
|
|
7643
|
+
const out = [];
|
|
7644
|
+
for (const s of subs) {
|
|
7645
|
+
const count = this.countSince(s.target, s.last_seen_seq);
|
|
7646
|
+
if (count > 0) out.push({ target: s.target, count });
|
|
7647
|
+
}
|
|
7648
|
+
return out;
|
|
7649
|
+
}
|
|
7650
|
+
markRead(agent, target) {
|
|
7651
|
+
if (target) {
|
|
7652
|
+
const key = targetKey(target);
|
|
7653
|
+
this.db.prepare(
|
|
7654
|
+
`UPDATE board_subscriptions SET last_seen_seq = (SELECT MAX(seq) FROM board_posts) WHERE agent = ? AND target = ?`
|
|
7655
|
+
).run(agent, key);
|
|
7656
|
+
return;
|
|
7657
|
+
}
|
|
7658
|
+
this.db.prepare(
|
|
7659
|
+
`UPDATE board_subscriptions SET last_seen_seq = (SELECT COALESCE(MAX(seq), 0) FROM board_posts) WHERE agent = ?`
|
|
7660
|
+
).run(agent);
|
|
7661
|
+
}
|
|
7662
|
+
countSince(target, sinceSeq) {
|
|
7663
|
+
if (target.startsWith("thread:")) {
|
|
7664
|
+
const id = target.slice("thread:".length);
|
|
7665
|
+
const row2 = this.db.prepare(`SELECT COUNT(*) AS n FROM board_posts WHERE thread_id = ? AND seq > ?`).get(id, sinceSeq);
|
|
7666
|
+
return row2.n;
|
|
7667
|
+
}
|
|
7668
|
+
const name = target.slice("channel:".length);
|
|
7669
|
+
const row = this.db.prepare(
|
|
7670
|
+
`SELECT COUNT(*) AS n FROM board_posts p JOIN board_threads t ON t.id = p.thread_id
|
|
7671
|
+
WHERE t.channel = ? AND p.seq > ?`
|
|
7672
|
+
).get(name, sinceSeq);
|
|
7673
|
+
return row.n;
|
|
7674
|
+
}
|
|
7675
|
+
};
|
|
7676
|
+
function clip(text) {
|
|
7677
|
+
if (text.length <= MAX_POST_CHARS) return text;
|
|
7678
|
+
return `${text.slice(0, MAX_POST_CHARS)}
|
|
7679
|
+
\u2026\uFF08\u622A\u65AD\uFF0C\u539F\u6587 ${text.length} \u5B57\uFF09`;
|
|
7680
|
+
}
|
|
7681
|
+
function firstLine(text) {
|
|
7682
|
+
const line = text.split("\n", 1)[0] ?? text;
|
|
7683
|
+
return line.length > 80 ? `${line.slice(0, 80)}\u2026` : line;
|
|
7684
|
+
}
|
|
7685
|
+
function toChannel(r) {
|
|
7686
|
+
return {
|
|
7687
|
+
id: r.id,
|
|
7688
|
+
name: r.name,
|
|
7689
|
+
...r.description ? { description: r.description } : {},
|
|
7690
|
+
createdBy: r.created_by,
|
|
7691
|
+
createdAt: r.created_at
|
|
7692
|
+
};
|
|
7693
|
+
}
|
|
7694
|
+
function toPost(r) {
|
|
7695
|
+
return {
|
|
7696
|
+
seq: r.seq,
|
|
7697
|
+
id: r.id,
|
|
7698
|
+
threadId: r.thread_id,
|
|
7699
|
+
author: r.author,
|
|
7700
|
+
text: r.text,
|
|
7701
|
+
createdAt: r.created_at
|
|
7702
|
+
};
|
|
7703
|
+
}
|
|
5935
7704
|
var PlanModeState = class {
|
|
5936
7705
|
constructor(permission2) {
|
|
5937
7706
|
this.permission = permission2;
|
|
@@ -6024,11 +7793,11 @@ function loadRoleDir(dir, source) {
|
|
|
6024
7793
|
let files;
|
|
6025
7794
|
try {
|
|
6026
7795
|
files = readdirSync(dir).filter((f) => f.endsWith(".md")).sort();
|
|
6027
|
-
} catch (
|
|
7796
|
+
} catch (err3) {
|
|
6028
7797
|
return {
|
|
6029
7798
|
roles: [],
|
|
6030
7799
|
issues: [
|
|
6031
|
-
{ path: dir, message: t("agent_role_load.dir_read_failed", { reason: reason(
|
|
7800
|
+
{ path: dir, message: t("agent_role_load.dir_read_failed", { reason: reason(err3) }) }
|
|
6032
7801
|
]
|
|
6033
7802
|
};
|
|
6034
7803
|
}
|
|
@@ -6045,9 +7814,9 @@ function loadRoleFile(path, file, source) {
|
|
|
6045
7814
|
let raw;
|
|
6046
7815
|
try {
|
|
6047
7816
|
raw = readFileSync(path, "utf8");
|
|
6048
|
-
} catch (
|
|
7817
|
+
} catch (err3) {
|
|
6049
7818
|
return {
|
|
6050
|
-
issues: [{ path: file, message: t("agent_role_load.read_failed", { reason: reason(
|
|
7819
|
+
issues: [{ path: file, message: t("agent_role_load.read_failed", { reason: reason(err3) }) }]
|
|
6051
7820
|
};
|
|
6052
7821
|
}
|
|
6053
7822
|
return parseRoleDefinition(raw, file, source);
|
|
@@ -6136,8 +7905,8 @@ function loadRoleDefinitions(opts) {
|
|
|
6136
7905
|
projectSkipped: false
|
|
6137
7906
|
};
|
|
6138
7907
|
}
|
|
6139
|
-
function reason(
|
|
6140
|
-
return
|
|
7908
|
+
function reason(err3) {
|
|
7909
|
+
return err3 instanceof Error ? err3.message : String(err3);
|
|
6141
7910
|
}
|
|
6142
7911
|
var READ_ONLY_TOOLS = [
|
|
6143
7912
|
"file_read",
|
|
@@ -6297,11 +8066,11 @@ function createRoleFile(input, opts) {
|
|
|
6297
8066
|
try {
|
|
6298
8067
|
mkdirSync(opts.dir, { recursive: true });
|
|
6299
8068
|
writeFileSync(path, text, { encoding: "utf-8", flag: "wx" });
|
|
6300
|
-
} catch (
|
|
6301
|
-
if (
|
|
8069
|
+
} catch (err3) {
|
|
8070
|
+
if (err3.code === "EEXIST") {
|
|
6302
8071
|
return { ok: false, reason: "duplicate", detail: t("role_write.taken", { name }) };
|
|
6303
8072
|
}
|
|
6304
|
-
return { ok: false, reason: "unwritable", detail: describe(
|
|
8073
|
+
return { ok: false, reason: "unwritable", detail: describe(err3) };
|
|
6305
8074
|
}
|
|
6306
8075
|
return { ok: true, path, role: back.role };
|
|
6307
8076
|
}
|
|
@@ -6341,8 +8110,8 @@ function driftOf(role, name, input) {
|
|
|
6341
8110
|
if ((role.maxTurns ?? null) !== (input.maxTurns ?? null)) return "maxTurns";
|
|
6342
8111
|
return void 0;
|
|
6343
8112
|
}
|
|
6344
|
-
function describe(
|
|
6345
|
-
return
|
|
8113
|
+
function describe(err3) {
|
|
8114
|
+
return err3 instanceof Error ? err3.message : String(err3);
|
|
6346
8115
|
}
|
|
6347
8116
|
function removeRoleFile(name, opts) {
|
|
6348
8117
|
const wanted = name.trim();
|
|
@@ -6371,8 +8140,8 @@ function removeRoleFile(name, opts) {
|
|
|
6371
8140
|
}
|
|
6372
8141
|
try {
|
|
6373
8142
|
rmSync(path);
|
|
6374
|
-
} catch (
|
|
6375
|
-
return { ok: false, reason: "failed", detail: describe2(
|
|
8143
|
+
} catch (err3) {
|
|
8144
|
+
return { ok: false, reason: "failed", detail: describe2(err3, path, opts.lang) };
|
|
6376
8145
|
}
|
|
6377
8146
|
return { ok: true, path };
|
|
6378
8147
|
}
|
|
@@ -6398,8 +8167,8 @@ function matchingFiles(dir, name) {
|
|
|
6398
8167
|
}
|
|
6399
8168
|
return hits;
|
|
6400
8169
|
}
|
|
6401
|
-
function describe2(
|
|
6402
|
-
const reason9 =
|
|
8170
|
+
function describe2(err3, path, lang) {
|
|
8171
|
+
const reason9 = err3 instanceof Error ? err3.message : String(err3);
|
|
6403
8172
|
return t("role_write.remove_failed", { path, reason: reason9 }, lang);
|
|
6404
8173
|
}
|
|
6405
8174
|
// src/agent-role/scope.ts
|
|
@@ -6480,14 +8249,14 @@ function walk(dir, prefix, depth, files, issues) {
|
|
|
6480
8249
|
let entries2;
|
|
6481
8250
|
try {
|
|
6482
8251
|
entries2 = readdirSync(dir, { withFileTypes: true });
|
|
6483
|
-
} catch (
|
|
6484
|
-
if (isMissing(
|
|
8252
|
+
} catch (err3) {
|
|
8253
|
+
if (isMissing(err3)) {
|
|
6485
8254
|
if (depth > 0) issues.push({ path: dir, message: t("custom_command.dir_vanished") });
|
|
6486
8255
|
return;
|
|
6487
8256
|
}
|
|
6488
8257
|
issues.push({
|
|
6489
8258
|
path: dir,
|
|
6490
|
-
message: t("custom_command.dir_read_failed", { reason: reason2(
|
|
8259
|
+
message: t("custom_command.dir_read_failed", { reason: reason2(err3) })
|
|
6491
8260
|
});
|
|
6492
8261
|
return;
|
|
6493
8262
|
}
|
|
@@ -6512,11 +8281,11 @@ function walk(dir, prefix, depth, files, issues) {
|
|
|
6512
8281
|
function commandNameFromRelPath(relPath) {
|
|
6513
8282
|
return relPath.replace(/\.md$/i, "").split("/").join(":").toLowerCase();
|
|
6514
8283
|
}
|
|
6515
|
-
function isMissing(
|
|
6516
|
-
return
|
|
8284
|
+
function isMissing(err3) {
|
|
8285
|
+
return err3?.code === "ENOENT";
|
|
6517
8286
|
}
|
|
6518
|
-
function reason2(
|
|
6519
|
-
return
|
|
8287
|
+
function reason2(err3) {
|
|
8288
|
+
return err3 instanceof Error ? err3.message : String(err3);
|
|
6520
8289
|
}
|
|
6521
8290
|
// src/extensions/commands.ts
|
|
6522
8291
|
var CommandFrontmatterSchema = z.object({
|
|
@@ -6563,9 +8332,9 @@ function loadCommandFile(file, source, prefix) {
|
|
|
6563
8332
|
let raw;
|
|
6564
8333
|
try {
|
|
6565
8334
|
raw = readFileSync(file.path, "utf8");
|
|
6566
|
-
} catch (
|
|
8335
|
+
} catch (err3) {
|
|
6567
8336
|
return {
|
|
6568
|
-
issues: [{ path: at, message: t("custom_command.read_failed", { reason: reason3(
|
|
8337
|
+
issues: [{ path: at, message: t("custom_command.read_failed", { reason: reason3(err3) }) }]
|
|
6569
8338
|
};
|
|
6570
8339
|
}
|
|
6571
8340
|
const parsed = parseFrontmatter(raw);
|
|
@@ -6668,8 +8437,8 @@ function resolveCommandModel(def, opts, warnings) {
|
|
|
6668
8437
|
}
|
|
6669
8438
|
return ref;
|
|
6670
8439
|
}
|
|
6671
|
-
function reason3(
|
|
6672
|
-
return
|
|
8440
|
+
function reason3(err3) {
|
|
8441
|
+
return err3 instanceof Error ? err3.message : String(err3);
|
|
6673
8442
|
}
|
|
6674
8443
|
// src/extensions/registry.ts
|
|
6675
8444
|
var SLASH_COMMANDS_DIAG_MODULE = "SlashCommands";
|
|
@@ -6952,10 +8721,10 @@ function scanHooks(dir, issues) {
|
|
|
6952
8721
|
let raw;
|
|
6953
8722
|
try {
|
|
6954
8723
|
raw = JSON.parse(readFileSync(path, "utf-8"));
|
|
6955
|
-
} catch (
|
|
8724
|
+
} catch (err3) {
|
|
6956
8725
|
issues.push({
|
|
6957
8726
|
path,
|
|
6958
|
-
message: t("plugin_inventory.hooks_bad_json", { reason:
|
|
8727
|
+
message: t("plugin_inventory.hooks_bad_json", { reason: firstLine2(err3) })
|
|
6959
8728
|
});
|
|
6960
8729
|
return [];
|
|
6961
8730
|
}
|
|
@@ -6981,8 +8750,8 @@ function scanMcp(dir, plugin, issues) {
|
|
|
6981
8750
|
let raw;
|
|
6982
8751
|
try {
|
|
6983
8752
|
raw = JSON.parse(readFileSync(path, "utf-8"));
|
|
6984
|
-
} catch (
|
|
6985
|
-
issues.push({ path, message: t("plugin.mcp_not_json", { reason:
|
|
8753
|
+
} catch (err3) {
|
|
8754
|
+
issues.push({ path, message: t("plugin.mcp_not_json", { reason: firstLine2(err3) }) });
|
|
6986
8755
|
return [];
|
|
6987
8756
|
}
|
|
6988
8757
|
if (raw === null || typeof raw !== "object" || Array.isArray(raw)) {
|
|
@@ -7007,10 +8776,10 @@ function readSettingsSummary(path, issues) {
|
|
|
7007
8776
|
let raw;
|
|
7008
8777
|
try {
|
|
7009
8778
|
raw = JSON.parse(readFileSync(path, "utf-8"));
|
|
7010
|
-
} catch (
|
|
8779
|
+
} catch (err3) {
|
|
7011
8780
|
issues.push({
|
|
7012
8781
|
path,
|
|
7013
|
-
message: t("plugin_inventory.settings_bad_json", { reason:
|
|
8782
|
+
message: t("plugin_inventory.settings_bad_json", { reason: firstLine2(err3) })
|
|
7014
8783
|
});
|
|
7015
8784
|
return { deny: 0, ignored: [] };
|
|
7016
8785
|
}
|
|
@@ -7038,16 +8807,16 @@ function readEntries(dir, issues) {
|
|
|
7038
8807
|
name: e.name,
|
|
7039
8808
|
isFile: e.isFile()
|
|
7040
8809
|
}));
|
|
7041
|
-
} catch (
|
|
8810
|
+
} catch (err3) {
|
|
7042
8811
|
issues.push({
|
|
7043
8812
|
path: dir,
|
|
7044
|
-
message: t("plugin_inventory.dir_read_failed", { reason:
|
|
8813
|
+
message: t("plugin_inventory.dir_read_failed", { reason: firstLine2(err3) })
|
|
7045
8814
|
});
|
|
7046
8815
|
return [];
|
|
7047
8816
|
}
|
|
7048
8817
|
}
|
|
7049
|
-
function
|
|
7050
|
-
const message =
|
|
8818
|
+
function firstLine2(err3) {
|
|
8819
|
+
const message = err3 instanceof Error ? err3.message : String(err3);
|
|
7051
8820
|
return message.split("\n")[0] ?? t("plugin_inventory.unknown_error");
|
|
7052
8821
|
}
|
|
7053
8822
|
var PLUGIN_MANIFEST_FILE = "epoch-plugin.json";
|
|
@@ -7109,13 +8878,13 @@ function readPluginManifest(dir) {
|
|
|
7109
8878
|
let raw;
|
|
7110
8879
|
try {
|
|
7111
8880
|
raw = readFileSync(path, "utf-8");
|
|
7112
|
-
} catch (
|
|
7113
|
-
const missing =
|
|
8881
|
+
} catch (err3) {
|
|
8882
|
+
const missing = err3.code === "ENOENT";
|
|
7114
8883
|
return {
|
|
7115
8884
|
issues: [
|
|
7116
8885
|
{
|
|
7117
8886
|
path,
|
|
7118
|
-
message: missing ? t("plugin_manifest.missing", { file: PLUGIN_MANIFEST_FILE }) : t("plugin_manifest.read_failed", { reason: reason4(
|
|
8887
|
+
message: missing ? t("plugin_manifest.missing", { file: PLUGIN_MANIFEST_FILE }) : t("plugin_manifest.read_failed", { reason: reason4(err3) })
|
|
7119
8888
|
}
|
|
7120
8889
|
]
|
|
7121
8890
|
};
|
|
@@ -7123,9 +8892,9 @@ function readPluginManifest(dir) {
|
|
|
7123
8892
|
let parsed;
|
|
7124
8893
|
try {
|
|
7125
8894
|
parsed = JSON.parse(raw);
|
|
7126
|
-
} catch (
|
|
8895
|
+
} catch (err3) {
|
|
7127
8896
|
return {
|
|
7128
|
-
issues: [{ path, message: t("plugin_manifest.bad_json", { reason:
|
|
8897
|
+
issues: [{ path, message: t("plugin_manifest.bad_json", { reason: firstLine3(err3) }) }]
|
|
7129
8898
|
};
|
|
7130
8899
|
}
|
|
7131
8900
|
const issues = unknownKeyIssues(PLUGIN_MANIFEST_KEYS, parsed, PLUGIN_MANIFEST_FILE);
|
|
@@ -7288,11 +9057,11 @@ function currentEpochVersion() {
|
|
|
7288
9057
|
cachedVersion = "unknown";
|
|
7289
9058
|
return cachedVersion;
|
|
7290
9059
|
}
|
|
7291
|
-
function reason4(
|
|
7292
|
-
return
|
|
9060
|
+
function reason4(err3) {
|
|
9061
|
+
return err3 instanceof Error ? err3.message : String(err3);
|
|
7293
9062
|
}
|
|
7294
|
-
function
|
|
7295
|
-
return reason4(
|
|
9063
|
+
function firstLine3(err3) {
|
|
9064
|
+
return reason4(err3).split("\n")[0] ?? t("plugin_manifest.unknown_error");
|
|
7296
9065
|
}
|
|
7297
9066
|
var RecordSchema = z.object({
|
|
7298
9067
|
name: z.string().regex(PLUGIN_NAME_PATTERN),
|
|
@@ -7327,8 +9096,8 @@ async function acquireStateLock(path) {
|
|
|
7327
9096
|
} catch {
|
|
7328
9097
|
}
|
|
7329
9098
|
};
|
|
7330
|
-
} catch (
|
|
7331
|
-
if (
|
|
9099
|
+
} catch (err3) {
|
|
9100
|
+
if (err3.code !== "EEXIST") throw err3;
|
|
7332
9101
|
if (breakStaleLock(lockPath)) continue;
|
|
7333
9102
|
if (Date.now() >= deadline) {
|
|
7334
9103
|
throw new Error(t("plugin_store.lock_timeout", { path: lockPath }));
|
|
@@ -7360,8 +9129,8 @@ function readPluginRecords(path) {
|
|
|
7360
9129
|
let raw;
|
|
7361
9130
|
try {
|
|
7362
9131
|
raw = JSON.parse(readFileSync(path, "utf-8"));
|
|
7363
|
-
} catch (
|
|
7364
|
-
const detail = (
|
|
9132
|
+
} catch (err3) {
|
|
9133
|
+
const detail = (err3 instanceof Error ? err3.message : String(err3)).split("\n")[0];
|
|
7365
9134
|
return {
|
|
7366
9135
|
records: [],
|
|
7367
9136
|
issues: [{ path, message: t("plugin_store.bad_json", { detail: detail ?? "" }) }]
|
|
@@ -7652,30 +9421,30 @@ function runCommand(file, args, opts = {}) {
|
|
|
7652
9421
|
windowsVerbatimArguments: viaCmd,
|
|
7653
9422
|
...opts.cwd ? { cwd: opts.cwd } : {}
|
|
7654
9423
|
},
|
|
7655
|
-
(
|
|
9424
|
+
(err3, stdout, stderr) => {
|
|
7656
9425
|
const out = String(stdout ?? "");
|
|
7657
9426
|
const errOut = String(stderr ?? "");
|
|
7658
|
-
if (!
|
|
9427
|
+
if (!err3) {
|
|
7659
9428
|
resolvePromise({ ok: true, stdout: out, stderr: errOut });
|
|
7660
9429
|
return;
|
|
7661
9430
|
}
|
|
7662
|
-
const detail = describe3(file,
|
|
9431
|
+
const detail = describe3(file, err3, errOut);
|
|
7663
9432
|
resolvePromise({
|
|
7664
9433
|
ok: false,
|
|
7665
9434
|
detail,
|
|
7666
9435
|
stdout: out,
|
|
7667
9436
|
stderr: errOut,
|
|
7668
|
-
...
|
|
9437
|
+
...err3.code === "ENOENT" ? { notFound: true } : {}
|
|
7669
9438
|
});
|
|
7670
9439
|
}
|
|
7671
9440
|
),
|
|
7672
|
-
(
|
|
9441
|
+
(err3) => {
|
|
7673
9442
|
resolvePromise({
|
|
7674
9443
|
ok: false,
|
|
7675
|
-
detail: describe3(file,
|
|
9444
|
+
detail: describe3(file, err3, ""),
|
|
7676
9445
|
stdout: "",
|
|
7677
9446
|
stderr: "",
|
|
7678
|
-
...
|
|
9447
|
+
...err3.code === "ENOENT" || err3.code === "ENOTDIR" ? { notFound: true } : {}
|
|
7679
9448
|
});
|
|
7680
9449
|
}
|
|
7681
9450
|
);
|
|
@@ -7688,11 +9457,11 @@ function escapeForCmd(arg) {
|
|
|
7688
9457
|
const quoted = `"${arg.replace(/(\\*)"/g, '$1$1\\"').replace(/(\\*)$/, "$1$1")}"`;
|
|
7689
9458
|
return quoted.replace(/([()%!^<>&|;,"])/g, "^$1");
|
|
7690
9459
|
}
|
|
7691
|
-
function describe3(file,
|
|
7692
|
-
if (
|
|
7693
|
-
if (
|
|
9460
|
+
function describe3(file, err3, stderr) {
|
|
9461
|
+
if (err3.code === "ENOENT") return t("plugin_cmd.not_found", { file });
|
|
9462
|
+
if (err3.killed) return t("plugin_cmd.timeout", { file });
|
|
7694
9463
|
const tail = stderr.trim().split("\n").slice(-4).join("\n").trim();
|
|
7695
|
-
return tail ||
|
|
9464
|
+
return tail || err3.message;
|
|
7696
9465
|
}
|
|
7697
9466
|
// src/plugin/archive.ts
|
|
7698
9467
|
function resolveTar() {
|
|
@@ -7757,8 +9526,8 @@ ${detail}` }) };
|
|
|
7757
9526
|
let entries2;
|
|
7758
9527
|
try {
|
|
7759
9528
|
entries2 = readdirSync(current, { withFileTypes: true });
|
|
7760
|
-
} catch (
|
|
7761
|
-
return t("plugin_pack.read_failed", { path: current, reason:
|
|
9529
|
+
} catch (err3) {
|
|
9530
|
+
return t("plugin_pack.read_failed", { path: current, reason: firstLine4(err3) });
|
|
7762
9531
|
}
|
|
7763
9532
|
for (const entry of entries2) {
|
|
7764
9533
|
if (PACK_EXCLUDES.includes(entry.name)) continue;
|
|
@@ -7781,8 +9550,8 @@ ${detail}` }) };
|
|
|
7781
9550
|
let stat5;
|
|
7782
9551
|
try {
|
|
7783
9552
|
stat5 = statSync(abs);
|
|
7784
|
-
} catch (
|
|
7785
|
-
return t("plugin_pack.read_failed", { path: abs, reason:
|
|
9553
|
+
} catch (err3) {
|
|
9554
|
+
return t("plugin_pack.read_failed", { path: abs, reason: firstLine4(err3) });
|
|
7786
9555
|
}
|
|
7787
9556
|
files.push({ path: rel, bytes: stat5.size, mtimeMs: Math.floor(stat5.mtimeMs) });
|
|
7788
9557
|
totalBytes += stat5.size;
|
|
@@ -7819,10 +9588,10 @@ async function packPlugin(plan, destDir) {
|
|
|
7819
9588
|
try {
|
|
7820
9589
|
writeFileSync(listFile, `${plan.files.map((f) => f.path).join("\n")}
|
|
7821
9590
|
`, "utf-8");
|
|
7822
|
-
} catch (
|
|
9591
|
+
} catch (err3) {
|
|
7823
9592
|
return {
|
|
7824
9593
|
ok: false,
|
|
7825
|
-
reason: t("plugin_pack.read_failed", { path: listFile, reason:
|
|
9594
|
+
reason: t("plugin_pack.read_failed", { path: listFile, reason: firstLine4(err3) })
|
|
7826
9595
|
};
|
|
7827
9596
|
}
|
|
7828
9597
|
let result;
|
|
@@ -7850,10 +9619,10 @@ async function packPlugin(plan, destDir) {
|
|
|
7850
9619
|
let bytes;
|
|
7851
9620
|
try {
|
|
7852
9621
|
bytes = statSync(archivePath).size;
|
|
7853
|
-
} catch (
|
|
9622
|
+
} catch (err3) {
|
|
7854
9623
|
return {
|
|
7855
9624
|
ok: false,
|
|
7856
|
-
reason: t("plugin_pack.read_failed", { path: archivePath, reason:
|
|
9625
|
+
reason: t("plugin_pack.read_failed", { path: archivePath, reason: firstLine4(err3) })
|
|
7857
9626
|
};
|
|
7858
9627
|
}
|
|
7859
9628
|
return { ok: true, archivePath, bytes };
|
|
@@ -7861,8 +9630,8 @@ async function packPlugin(plan, destDir) {
|
|
|
7861
9630
|
function isVirtualenv(dir) {
|
|
7862
9631
|
return existsSync(join(dir, "pyvenv.cfg"));
|
|
7863
9632
|
}
|
|
7864
|
-
function
|
|
7865
|
-
const message =
|
|
9633
|
+
function firstLine4(err3) {
|
|
9634
|
+
const message = err3 instanceof Error ? err3.message : String(err3);
|
|
7866
9635
|
return message.split("\n")[0] ?? message;
|
|
7867
9636
|
}
|
|
7868
9637
|
var ABOUT_README_MAX_CHARS = 32e3;
|
|
@@ -8118,11 +9887,11 @@ function readMarketplaces(statePath) {
|
|
|
8118
9887
|
let raw;
|
|
8119
9888
|
try {
|
|
8120
9889
|
raw = JSON.parse(readFileSync(statePath, "utf-8"));
|
|
8121
|
-
} catch (
|
|
9890
|
+
} catch (err3) {
|
|
8122
9891
|
return {
|
|
8123
9892
|
records: [],
|
|
8124
9893
|
issues: [
|
|
8125
|
-
{ path: statePath, message: t("plugin_marketplace.bad_json", { reason: first(
|
|
9894
|
+
{ path: statePath, message: t("plugin_marketplace.bad_json", { reason: first(err3) }) }
|
|
8126
9895
|
]
|
|
8127
9896
|
};
|
|
8128
9897
|
}
|
|
@@ -8282,8 +10051,8 @@ async function fetchCatalog(source) {
|
|
|
8282
10051
|
}
|
|
8283
10052
|
try {
|
|
8284
10053
|
return parseCatalog(readFileSync(local, "utf-8"), local);
|
|
8285
|
-
} catch (
|
|
8286
|
-
return { ok: false, reason: t("plugin_marketplace.read_failed", { reason: first(
|
|
10054
|
+
} catch (err3) {
|
|
10055
|
+
return { ok: false, reason: t("plugin_marketplace.read_failed", { reason: first(err3) }) };
|
|
8287
10056
|
}
|
|
8288
10057
|
}
|
|
8289
10058
|
const url = catalogUrl(input);
|
|
@@ -8303,8 +10072,8 @@ async function fetchCatalog(source) {
|
|
|
8303
10072
|
};
|
|
8304
10073
|
}
|
|
8305
10074
|
return parseCatalog(await response.text(), url);
|
|
8306
|
-
} catch (
|
|
8307
|
-
return { ok: false, reason: t("marketplace.fetch_error", { url, reason: first(
|
|
10075
|
+
} catch (err3) {
|
|
10076
|
+
return { ok: false, reason: t("marketplace.fetch_error", { url, reason: first(err3) }) };
|
|
8308
10077
|
}
|
|
8309
10078
|
}
|
|
8310
10079
|
function looksPrivate(status) {
|
|
@@ -8334,10 +10103,10 @@ function parseCatalog(body2, where) {
|
|
|
8334
10103
|
let raw;
|
|
8335
10104
|
try {
|
|
8336
10105
|
raw = JSON.parse(body2);
|
|
8337
|
-
} catch (
|
|
10106
|
+
} catch (err3) {
|
|
8338
10107
|
return {
|
|
8339
10108
|
ok: false,
|
|
8340
|
-
reason: t("plugin_marketplace.catalog_bad_json", { where, reason: first(
|
|
10109
|
+
reason: t("plugin_marketplace.catalog_bad_json", { where, reason: first(err3) })
|
|
8341
10110
|
};
|
|
8342
10111
|
}
|
|
8343
10112
|
const checked = parseLenient(CatalogSchema.optional(), raw, void 0);
|
|
@@ -8347,8 +10116,8 @@ function parseCatalog(body2, where) {
|
|
|
8347
10116
|
}
|
|
8348
10117
|
return { ok: true, catalog: checked.value };
|
|
8349
10118
|
}
|
|
8350
|
-
function first(
|
|
8351
|
-
const message =
|
|
10119
|
+
function first(err3) {
|
|
10120
|
+
const message = err3 instanceof Error ? err3.message : String(err3);
|
|
8352
10121
|
return message.split("\n")[0] ?? t("plugin_marketplace.unknown_error");
|
|
8353
10122
|
}
|
|
8354
10123
|
var NPM_SPEC = /^(?:@[a-z0-9][a-z0-9._-]*\/)?[a-z0-9][a-z0-9._-]*(?:@[a-zA-Z0-9.^~*+-]+)?$/;
|
|
@@ -8756,11 +10525,11 @@ async function fetchFromHost(source, staging, opts) {
|
|
|
8756
10525
|
);
|
|
8757
10526
|
}
|
|
8758
10527
|
});
|
|
8759
|
-
} catch (
|
|
10528
|
+
} catch (err3) {
|
|
8760
10529
|
return {
|
|
8761
10530
|
ok: false,
|
|
8762
10531
|
reason: t("plugin_install.host_fetch_threw", {
|
|
8763
|
-
reason: (
|
|
10532
|
+
reason: (err3 instanceof Error ? err3.message : String(err3)).split("\n")[0] ?? ""
|
|
8764
10533
|
})
|
|
8765
10534
|
};
|
|
8766
10535
|
}
|
|
@@ -8832,11 +10601,11 @@ async function fetchArchive(source, staging, opts) {
|
|
|
8832
10601
|
};
|
|
8833
10602
|
}
|
|
8834
10603
|
bytes = await readBodyWithProgress(response, byteReporter(opts, "download", source.target));
|
|
8835
|
-
} catch (
|
|
10604
|
+
} catch (err3) {
|
|
8836
10605
|
return {
|
|
8837
10606
|
ok: false,
|
|
8838
10607
|
reason: t("plugin_install.download_failed", {
|
|
8839
|
-
message:
|
|
10608
|
+
message: err3 instanceof Error ? err3.message : String(err3)
|
|
8840
10609
|
})
|
|
8841
10610
|
};
|
|
8842
10611
|
}
|
|
@@ -8974,8 +10743,8 @@ async function applyRewind(store, sessionId, manifest, apply, skippedConflicts)
|
|
|
8974
10743
|
let staged;
|
|
8975
10744
|
try {
|
|
8976
10745
|
staged = await stageAll(store, sessionId, manifest, todo, byPath);
|
|
8977
|
-
} catch (
|
|
8978
|
-
return { ...empty, failed: t("rewind.stage_failed", { message: messageOf(
|
|
10746
|
+
} catch (err3) {
|
|
10747
|
+
return { ...empty, failed: t("rewind.stage_failed", { message: messageOf(err3) }) };
|
|
8979
10748
|
}
|
|
8980
10749
|
return commitAll2(staged, skippedConflicts);
|
|
8981
10750
|
}
|
|
@@ -8999,9 +10768,9 @@ async function stageAll(store, sessionId, manifest, todo, byPath) {
|
|
|
8999
10768
|
}
|
|
9000
10769
|
staged.push(item);
|
|
9001
10770
|
}
|
|
9002
|
-
} catch (
|
|
10771
|
+
} catch (err3) {
|
|
9003
10772
|
await discard(staged);
|
|
9004
|
-
throw
|
|
10773
|
+
throw err3;
|
|
9005
10774
|
}
|
|
9006
10775
|
return staged;
|
|
9007
10776
|
}
|
|
@@ -9016,7 +10785,7 @@ async function commitAll2(staged, skippedConflicts) {
|
|
|
9016
10785
|
for (const item of staged) {
|
|
9017
10786
|
try {
|
|
9018
10787
|
await commitOne(item);
|
|
9019
|
-
} catch (
|
|
10788
|
+
} catch (err3) {
|
|
9020
10789
|
await rollback(done2);
|
|
9021
10790
|
await discard(staged);
|
|
9022
10791
|
return {
|
|
@@ -9024,7 +10793,7 @@ async function commitAll2(staged, skippedConflicts) {
|
|
|
9024
10793
|
restored: [],
|
|
9025
10794
|
deleted: [],
|
|
9026
10795
|
recreated: [],
|
|
9027
|
-
failed: t("rewind.commit_failed", { message: messageOf(
|
|
10796
|
+
failed: t("rewind.commit_failed", { message: messageOf(err3) })
|
|
9028
10797
|
};
|
|
9029
10798
|
}
|
|
9030
10799
|
done2.push(item);
|
|
@@ -9080,8 +10849,8 @@ function bucketOf(outcome, action) {
|
|
|
9080
10849
|
if (action === "recreate") return outcome.recreated;
|
|
9081
10850
|
return outcome.restored;
|
|
9082
10851
|
}
|
|
9083
|
-
function messageOf(
|
|
9084
|
-
return
|
|
10852
|
+
function messageOf(err3) {
|
|
10853
|
+
return err3 instanceof Error ? err3.message : String(err3);
|
|
9085
10854
|
}
|
|
9086
10855
|
// src/disk-ledger.ts
|
|
9087
10856
|
var CHECKPOINT_MAX_TOTAL_BYTES = 200 * 1024 * 1024;
|
|
@@ -9238,9 +11007,9 @@ async function atomicWrite(path, data) {
|
|
|
9238
11007
|
await writeFile(tmp, data);
|
|
9239
11008
|
try {
|
|
9240
11009
|
await rename(tmp, path);
|
|
9241
|
-
} catch (
|
|
11010
|
+
} catch (err3) {
|
|
9242
11011
|
await rm(tmp, { force: true });
|
|
9243
|
-
throw
|
|
11012
|
+
throw err3;
|
|
9244
11013
|
}
|
|
9245
11014
|
}
|
|
9246
11015
|
function isManifest(value) {
|
|
@@ -9334,9 +11103,9 @@ var CheckpointManager = class {
|
|
|
9334
11103
|
turnIndex = turn.turnIndex ?? await this.nextTurnIndex(sessionId);
|
|
9335
11104
|
turn.turnIndex = turnIndex;
|
|
9336
11105
|
for (const path of fresh) {
|
|
9337
|
-
const { file, ok:
|
|
11106
|
+
const { file, ok: ok4 } = await this.snapshotFile(sessionId, turnIndex, path);
|
|
9338
11107
|
turn.files.push(file);
|
|
9339
|
-
if (!
|
|
11108
|
+
if (!ok4) turn.incomplete = true;
|
|
9340
11109
|
}
|
|
9341
11110
|
await this.store.writeManifest(sessionId, manifestOf(turn, turnIndex, this.workDir()));
|
|
9342
11111
|
} catch {
|
|
@@ -9375,8 +11144,8 @@ var CheckpointManager = class {
|
|
|
9375
11144
|
if (info.size > MAX_FILE_BYTES) return { file: absent, ok: false };
|
|
9376
11145
|
const hash = await this.store.putBlob(sessionId, turnIndex, await readFile(path));
|
|
9377
11146
|
return { file: { path, hash, mode: info.mode & 511 }, ok: true };
|
|
9378
|
-
} catch (
|
|
9379
|
-
return { file: absent, ok: isNotFound(
|
|
11147
|
+
} catch (err3) {
|
|
11148
|
+
return { file: absent, ok: isNotFound(err3) };
|
|
9380
11149
|
}
|
|
9381
11150
|
}
|
|
9382
11151
|
async nextTurnIndex(sessionId) {
|
|
@@ -9426,8 +11195,8 @@ function preview(text) {
|
|
|
9426
11195
|
const flat = text.replace(/\s+/g, " ").trim();
|
|
9427
11196
|
return flat.length > PREVIEW_LEN ? `${flat.slice(0, PREVIEW_LEN)}\u2026` : flat;
|
|
9428
11197
|
}
|
|
9429
|
-
function isNotFound(
|
|
9430
|
-
return
|
|
11198
|
+
function isNotFound(err3) {
|
|
11199
|
+
return err3?.code === "ENOENT";
|
|
9431
11200
|
}
|
|
9432
11201
|
async function hashOf(path) {
|
|
9433
11202
|
try {
|
|
@@ -9515,8 +11284,8 @@ async function readSnapshot(path) {
|
|
|
9515
11284
|
const buf = await readFile(path);
|
|
9516
11285
|
if (buf.includes(0)) return { kind: "opaque" };
|
|
9517
11286
|
return { kind: "text", text: buf.toString("utf-8"), bytes: buf.byteLength };
|
|
9518
|
-
} catch (
|
|
9519
|
-
return isNotFound2(
|
|
11287
|
+
} catch (err3) {
|
|
11288
|
+
return isNotFound2(err3) ? { kind: "absent" } : { kind: "opaque" };
|
|
9520
11289
|
}
|
|
9521
11290
|
}
|
|
9522
11291
|
function workspaceDisplayPath(path, workDir) {
|
|
@@ -9524,34 +11293,64 @@ function workspaceDisplayPath(path, workDir) {
|
|
|
9524
11293
|
if (!rel || rel.startsWith("..") || isAbsolute(rel)) return path;
|
|
9525
11294
|
return sep === "/" ? rel : rel.split(sep).join("/");
|
|
9526
11295
|
}
|
|
9527
|
-
function isNotFound2(
|
|
9528
|
-
return
|
|
11296
|
+
function isNotFound2(err3) {
|
|
11297
|
+
return err3?.code === "ENOENT";
|
|
9529
11298
|
}
|
|
9530
11299
|
var TaskNoticeTracker = class {
|
|
9531
|
-
constructor(source) {
|
|
11300
|
+
constructor(source, team, board) {
|
|
9532
11301
|
this.source = source;
|
|
11302
|
+
this.team = team;
|
|
11303
|
+
this.board = board;
|
|
9533
11304
|
}
|
|
9534
11305
|
source;
|
|
11306
|
+
team;
|
|
11307
|
+
board;
|
|
9535
11308
|
seen = /* @__PURE__ */ new Map();
|
|
9536
|
-
|
|
9537
|
-
|
|
9538
|
-
|
|
9539
|
-
|
|
9540
|
-
|
|
9541
|
-
|
|
9542
|
-
|
|
9543
|
-
|
|
11309
|
+
takeAgentMessages(sessionId) {
|
|
11310
|
+
const inbox = this.team?.mainInbox(sessionId);
|
|
11311
|
+
if (!inbox?.pending()) return [];
|
|
11312
|
+
return inbox.take().map((c) => typeof c === "string" ? c : contentToText(c));
|
|
11313
|
+
}
|
|
11314
|
+
notice(sessionId = LEAD_AGENT_ID) {
|
|
11315
|
+
return this.noticeDetailed(sessionId)?.text ?? null;
|
|
11316
|
+
}
|
|
11317
|
+
noticeDetailed(sessionId = LEAD_AGENT_ID) {
|
|
9544
11318
|
const lines = [];
|
|
9545
|
-
|
|
9546
|
-
|
|
9547
|
-
|
|
9548
|
-
|
|
9549
|
-
|
|
9550
|
-
|
|
9551
|
-
|
|
11319
|
+
if (this.source) {
|
|
11320
|
+
let tasks;
|
|
11321
|
+
try {
|
|
11322
|
+
tasks = this.source();
|
|
11323
|
+
} catch {
|
|
11324
|
+
tasks = [];
|
|
11325
|
+
}
|
|
11326
|
+
for (const task of tasks) {
|
|
11327
|
+
if (task.kind === "shell") continue;
|
|
11328
|
+
const before = this.seen.get(task.id);
|
|
11329
|
+
if (before === task.status) continue;
|
|
11330
|
+
this.seen.set(task.id, task.status);
|
|
11331
|
+
if (task.kind === "agent" && task.status === "running") continue;
|
|
11332
|
+
lines.push(describeBackgroundTask(task));
|
|
11333
|
+
}
|
|
11334
|
+
}
|
|
11335
|
+
const agentLines = this.takeAgentMessages(sessionId);
|
|
11336
|
+
const boardLines = this.board?.pending() ?? [];
|
|
11337
|
+
if (lines.length === 0 && agentLines.length === 0 && boardLines.length === 0) return null;
|
|
11338
|
+
const out = [];
|
|
11339
|
+
if (lines.length > 0) {
|
|
11340
|
+
out.push(systemNote("\u540E\u53F0\u4EFB\u52A1\u72B6\u6001"), ...lines, "\u8981\u770B\u8F93\u51FA\u7528 task_output\u3002");
|
|
11341
|
+
}
|
|
11342
|
+
if (agentLines.length > 0) {
|
|
11343
|
+
out.push(systemNote(AGENT_MESSAGE_NOTE_TITLE), ...agentLines);
|
|
11344
|
+
}
|
|
11345
|
+
if (boardLines.length > 0) {
|
|
11346
|
+
out.push(
|
|
11347
|
+
systemNote("\u8BA8\u8BBA\u677F"),
|
|
11348
|
+
...boardLines.map((b) => `- ${b.target}\uFF1A${b.count} \u6761\u65B0\u5E16`),
|
|
11349
|
+
"\u8981\u770B\u5185\u5BB9\u7528 read_thread\uFF08\u8BFB\u5B8C\u81EA\u52A8\u6807\u6210\u5DF2\u770B\uFF09\u3002"
|
|
11350
|
+
);
|
|
11351
|
+
this.board?.markRead();
|
|
9552
11352
|
}
|
|
9553
|
-
|
|
9554
|
-
return [systemNote("\u540E\u53F0\u4EFB\u52A1\u72B6\u6001"), ...lines, "\u8981\u770B\u8F93\u51FA\u7528 task_output\u3002"].join("\n");
|
|
11353
|
+
return { text: out.join("\n"), agent: agentLines };
|
|
9555
11354
|
}
|
|
9556
11355
|
};
|
|
9557
11356
|
function describeBackgroundTask(task) {
|
|
@@ -9840,8 +11639,8 @@ function readImageSize(bytes) {
|
|
|
9840
11639
|
const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
9841
11640
|
const size = pngSize(bytes, view) ?? jpegSize(bytes, view) ?? gifSize(bytes, view) ?? webpSize(bytes, view);
|
|
9842
11641
|
if (!size) return void 0;
|
|
9843
|
-
const
|
|
9844
|
-
return
|
|
11642
|
+
const ok4 = (n) => Number.isInteger(n) && n > 0;
|
|
11643
|
+
return ok4(size.width) && ok4(size.height) ? size : void 0;
|
|
9845
11644
|
}
|
|
9846
11645
|
function sniffMediaType(bytes) {
|
|
9847
11646
|
if (bytes.length < 12) return void 0;
|
|
@@ -10181,8 +11980,8 @@ function imageFromPath(filePath, mediaType) {
|
|
|
10181
11980
|
const st = statSync(abs);
|
|
10182
11981
|
if (!st.isFile()) throw new ImageLoadError(t("image_load.not_a_file", { path: abs }));
|
|
10183
11982
|
size = st.size;
|
|
10184
|
-
} catch (
|
|
10185
|
-
if (
|
|
11983
|
+
} catch (err3) {
|
|
11984
|
+
if (err3 instanceof ImageLoadError) throw err3;
|
|
10186
11985
|
throw new ImageLoadError(t("image_load.unreadable", { path: abs }));
|
|
10187
11986
|
}
|
|
10188
11987
|
if (size === 0) throw new ImageLoadError(t("image_load.empty", { path: abs }));
|
|
@@ -10399,8 +12198,8 @@ function decideTrust(dir) {
|
|
|
10399
12198
|
return ambient ? ambient.decide(dir) : noGate();
|
|
10400
12199
|
}
|
|
10401
12200
|
var FILE_VERSION = 1;
|
|
10402
|
-
function describe5(
|
|
10403
|
-
return
|
|
12201
|
+
function describe5(err3) {
|
|
12202
|
+
return err3 instanceof Error ? err3.message : String(err3);
|
|
10404
12203
|
}
|
|
10405
12204
|
var ImportTrustStore = class {
|
|
10406
12205
|
constructor(filePath = trustedImportsPath()) {
|
|
@@ -10439,18 +12238,18 @@ var ImportTrustStore = class {
|
|
|
10439
12238
|
let raw;
|
|
10440
12239
|
try {
|
|
10441
12240
|
raw = readFileSync(this.filePath, "utf-8");
|
|
10442
|
-
} catch (
|
|
12241
|
+
} catch (err3) {
|
|
10443
12242
|
this.loadErrors.push(
|
|
10444
|
-
t("import_trust.read_failed", { path: this.filePath, reason: describe5(
|
|
12243
|
+
t("import_trust.read_failed", { path: this.filePath, reason: describe5(err3) })
|
|
10445
12244
|
);
|
|
10446
12245
|
return;
|
|
10447
12246
|
}
|
|
10448
12247
|
let parsed;
|
|
10449
12248
|
try {
|
|
10450
12249
|
parsed = JSON.parse(raw);
|
|
10451
|
-
} catch (
|
|
12250
|
+
} catch (err3) {
|
|
10452
12251
|
this.loadErrors.push(
|
|
10453
|
-
t("import_trust.bad_json", { path: this.filePath, reason: describe5(
|
|
12252
|
+
t("import_trust.bad_json", { path: this.filePath, reason: describe5(err3) })
|
|
10454
12253
|
);
|
|
10455
12254
|
return;
|
|
10456
12255
|
}
|
|
@@ -10505,10 +12304,10 @@ var ImportTrustStore = class {
|
|
|
10505
12304
|
try {
|
|
10506
12305
|
writeFileSync(tmp, body2, { encoding: "utf-8", mode: 384 });
|
|
10507
12306
|
renameSync(tmp, this.filePath);
|
|
10508
|
-
} catch (
|
|
12307
|
+
} catch (err3) {
|
|
10509
12308
|
rmSync(tmp, { force: true });
|
|
10510
12309
|
throw new Error(
|
|
10511
|
-
t("import_trust.write_failed", { path: this.filePath, reason: describe5(
|
|
12310
|
+
t("import_trust.write_failed", { path: this.filePath, reason: describe5(err3) })
|
|
10512
12311
|
);
|
|
10513
12312
|
}
|
|
10514
12313
|
}
|
|
@@ -11152,8 +12951,8 @@ var BudgetStore = class {
|
|
|
11152
12951
|
throw new Error(t("budget.state_missing_sessions"));
|
|
11153
12952
|
}
|
|
11154
12953
|
return { version: 1, sessions };
|
|
11155
|
-
} catch (
|
|
11156
|
-
const reason9 =
|
|
12954
|
+
} catch (err3) {
|
|
12955
|
+
const reason9 = err3 instanceof Error ? err3.message : String(err3);
|
|
11157
12956
|
this.quarantine();
|
|
11158
12957
|
this.onWarn?.(t("budget.state_corrupt", { reason: reason9, path: this.path }));
|
|
11159
12958
|
return empty;
|
|
@@ -11169,10 +12968,10 @@ var BudgetStore = class {
|
|
|
11169
12968
|
try {
|
|
11170
12969
|
mkdirSync(dirname(this.path), { recursive: true });
|
|
11171
12970
|
writeFileSync(this.path, JSON.stringify(state, null, 2));
|
|
11172
|
-
} catch (
|
|
12971
|
+
} catch (err3) {
|
|
11173
12972
|
this.onWarn?.(
|
|
11174
12973
|
t("budget.state_write_failed", {
|
|
11175
|
-
message:
|
|
12974
|
+
message: err3 instanceof Error ? err3.message : String(err3)
|
|
11176
12975
|
})
|
|
11177
12976
|
);
|
|
11178
12977
|
}
|
|
@@ -11496,25 +13295,25 @@ var PROVIDER_NO_CREDENTIAL = 1001;
|
|
|
11496
13295
|
var PROVIDER_ABORTED = 1060;
|
|
11497
13296
|
var PROVIDER_CONTEXT_OVERFLOW = 1030;
|
|
11498
13297
|
var PROVIDER_BODY_TOO_LARGE = 1051;
|
|
11499
|
-
function isContextOverflow(
|
|
11500
|
-
if (
|
|
11501
|
-
return classifyProviderError(
|
|
13298
|
+
function isContextOverflow(err3) {
|
|
13299
|
+
if (err3 instanceof ProviderError) return err3.code === PROVIDER_CONTEXT_OVERFLOW;
|
|
13300
|
+
return classifyProviderError(err3).code === PROVIDER_CONTEXT_OVERFLOW;
|
|
11502
13301
|
}
|
|
11503
|
-
function isBodyTooLarge(
|
|
11504
|
-
if (
|
|
11505
|
-
return classifyProviderError(
|
|
13302
|
+
function isBodyTooLarge(err3) {
|
|
13303
|
+
if (err3 instanceof ProviderError) return err3.code === PROVIDER_BODY_TOO_LARGE;
|
|
13304
|
+
return classifyProviderError(err3).code === PROVIDER_BODY_TOO_LARGE;
|
|
11506
13305
|
}
|
|
11507
|
-
function isAbortError(
|
|
11508
|
-
for (let cur =
|
|
13306
|
+
function isAbortError(err3) {
|
|
13307
|
+
for (let cur = err3, depth = 0; cur && depth < 5; depth++) {
|
|
11509
13308
|
if (typeof cur !== "object") return false;
|
|
11510
13309
|
if (cur.name === "AbortError") return true;
|
|
11511
13310
|
cur = cur.cause;
|
|
11512
13311
|
}
|
|
11513
13312
|
return false;
|
|
11514
13313
|
}
|
|
11515
|
-
function causeChain(
|
|
13314
|
+
function causeChain(err3) {
|
|
11516
13315
|
const out = [];
|
|
11517
|
-
for (let cur =
|
|
13316
|
+
for (let cur = err3, depth = 0; cur && depth < 5; depth++) {
|
|
11518
13317
|
if (typeof cur !== "object") break;
|
|
11519
13318
|
const e = cur;
|
|
11520
13319
|
out.push({
|
|
@@ -11539,20 +13338,20 @@ var NETWORK_ERROR_CODES = /* @__PURE__ */ new Set([
|
|
|
11539
13338
|
"UND_ERR_RESPONSE_STATUS_CODE"
|
|
11540
13339
|
]);
|
|
11541
13340
|
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
|
|
13341
|
+
function describeProviderError(err3) {
|
|
13342
|
+
const chain = causeChain(err3);
|
|
13343
|
+
const head = chain[0]?.message ?? (typeof err3 === "string" ? err3 : String(err3));
|
|
11545
13344
|
const root = [...chain].reverse().find((link) => link.message !== "" && link.message !== head)?.message;
|
|
11546
13345
|
if (!head.trim()) {
|
|
11547
13346
|
if (root) return root;
|
|
11548
|
-
const status = extractStatus(
|
|
13347
|
+
const status = extractStatus(err3);
|
|
11549
13348
|
return status === void 0 ? t("provider_route.no_detail") : t("provider_route.no_detail_status", { status });
|
|
11550
13349
|
}
|
|
11551
13350
|
return root ? t("provider_route.root_cause", { message: head, cause: root }) : head;
|
|
11552
13351
|
}
|
|
11553
|
-
function extractStatus(
|
|
11554
|
-
if (!
|
|
11555
|
-
const e =
|
|
13352
|
+
function extractStatus(err3) {
|
|
13353
|
+
if (!err3 || typeof err3 !== "object") return void 0;
|
|
13354
|
+
const e = err3;
|
|
11556
13355
|
for (const candidate of [e.statusCode, e.status, e.response?.status]) {
|
|
11557
13356
|
if (typeof candidate === "number" && candidate >= 100 && candidate < 600) return candidate;
|
|
11558
13357
|
}
|
|
@@ -11565,10 +13364,10 @@ function extractStatusFromMessage(msg) {
|
|
|
11565
13364
|
if (labelled?.[1]) return Number(labelled[1]);
|
|
11566
13365
|
return void 0;
|
|
11567
13366
|
}
|
|
11568
|
-
function classifyProviderError(
|
|
11569
|
-
const msg =
|
|
11570
|
-
const status = extractStatus(
|
|
11571
|
-
if (isAbortError(
|
|
13367
|
+
function classifyProviderError(err3) {
|
|
13368
|
+
const msg = err3 instanceof Error ? err3.message : String(err3);
|
|
13369
|
+
const status = extractStatus(err3);
|
|
13370
|
+
if (isAbortError(err3)) return { code: PROVIDER_ABORTED, recovery: "abort" };
|
|
11572
13371
|
if (/context.?length|context.?window|maximum.*token|token.?limit|too.?many.?tokens|prompt.*too.?long|reduce.*(length|tokens)/i.test(
|
|
11573
13372
|
msg
|
|
11574
13373
|
))
|
|
@@ -11597,7 +13396,7 @@ function classifyProviderError(err) {
|
|
|
11597
13396
|
if (code >= 500) return { code: 1020, recovery: "retry" };
|
|
11598
13397
|
if (code >= 400) return { code: 1050, recovery: "abort" };
|
|
11599
13398
|
}
|
|
11600
|
-
for (const link of causeChain(
|
|
13399
|
+
for (const link of causeChain(err3)) {
|
|
11601
13400
|
if (link.code && NETWORK_ERROR_CODES.has(link.code)) return { code: 1041, recovery: "retry" };
|
|
11602
13401
|
if (NETWORK_MESSAGE_RE.test(link.message)) return { code: 1041, recovery: "retry" };
|
|
11603
13402
|
}
|
|
@@ -12752,7 +14551,10 @@ function outputText(output) {
|
|
|
12752
14551
|
function failureText(r) {
|
|
12753
14552
|
const detail = r.error?.message?.trim() || outputText(r.output).trim();
|
|
12754
14553
|
if (!detail) return "\u5DE5\u5177\u6267\u884C\u5931\u8D25\uFF08\u5DE5\u5177\u672A\u63D0\u4F9B\u539F\u56E0\uFF09";
|
|
12755
|
-
|
|
14554
|
+
const head = r.error?.code === void 0 ? `\u5DE5\u5177\u6267\u884C\u5931\u8D25\uFF1A${detail}` : `\u5DE5\u5177\u6267\u884C\u5931\u8D25 [${r.error.code}]: ${detail}`;
|
|
14555
|
+
const hint = r.error?.suggestion?.trim();
|
|
14556
|
+
return hint ? `${head}
|
|
14557
|
+
${hint}` : head;
|
|
12756
14558
|
}
|
|
12757
14559
|
var ToolExecutor = class {
|
|
12758
14560
|
constructor(deps) {
|
|
@@ -12885,12 +14687,12 @@ var ToolExecutor = class {
|
|
|
12885
14687
|
truncateForModel(failureText(r), budgetOf2(et, depth, "failure"), "text")
|
|
12886
14688
|
)
|
|
12887
14689
|
});
|
|
12888
|
-
} catch (
|
|
12889
|
-
span.recordError(
|
|
14690
|
+
} catch (err3) {
|
|
14691
|
+
span.recordError(err3);
|
|
12890
14692
|
return finish({
|
|
12891
14693
|
...base2,
|
|
12892
14694
|
success: false,
|
|
12893
|
-
output: `\u5DE5\u5177\u6267\u884C\u5F02\u5E38: ${
|
|
14695
|
+
output: `\u5DE5\u5177\u6267\u884C\u5F02\u5E38: ${err3 instanceof Error ? err3.message : String(err3)}`
|
|
12894
14696
|
});
|
|
12895
14697
|
}
|
|
12896
14698
|
}
|
|
@@ -13300,6 +15102,7 @@ var AgentLoop = class {
|
|
|
13300
15102
|
async *runTurns(input, turns) {
|
|
13301
15103
|
const maxTurns = turnLimitOf(input.maxTurns ?? this.config.maxTurns);
|
|
13302
15104
|
this.stallDetector.reset();
|
|
15105
|
+
const pendingReceived = [];
|
|
13303
15106
|
const rawUserText = contentToText(input.userMessage, { imagesCarriedAsParts: true });
|
|
13304
15107
|
const images = imageParts(input.userMessage);
|
|
13305
15108
|
const inputGate = this.config.compliance?.checkInput(rawUserText);
|
|
@@ -13397,11 +15200,13 @@ var AgentLoop = class {
|
|
|
13397
15200
|
...breach ? { breach } : {}
|
|
13398
15201
|
});
|
|
13399
15202
|
this.hooks.fire("session:start", { sessionId: input.sessionId });
|
|
15203
|
+
this.config.team?.registerSession(input.sessionId);
|
|
13400
15204
|
const runSpan = this.telemetry.startSpan("agent_run", {
|
|
13401
15205
|
[GEN_AI.OPERATION_NAME]: "agent_run",
|
|
13402
15206
|
[GEN_AI.CONVERSATION_ID]: input.sessionId
|
|
13403
15207
|
});
|
|
13404
15208
|
try {
|
|
15209
|
+
this.config.team?.beginSessionTurn(input.sessionId);
|
|
13405
15210
|
const rawHistory = (input.history ?? []).map((h) => ({
|
|
13406
15211
|
role: h.role,
|
|
13407
15212
|
content: h.content,
|
|
@@ -13427,7 +15232,11 @@ var AgentLoop = class {
|
|
|
13427
15232
|
...history,
|
|
13428
15233
|
{ role: "user", content: userContent, ...userParts ? { parts: userParts } : {} }
|
|
13429
15234
|
];
|
|
13430
|
-
const taskNotice = new TaskNoticeTracker(
|
|
15235
|
+
const taskNotice = new TaskNoticeTracker(
|
|
15236
|
+
this.config.backgroundTasks,
|
|
15237
|
+
this.config.team,
|
|
15238
|
+
this.config.board
|
|
15239
|
+
);
|
|
13431
15240
|
let todoNudged = false;
|
|
13432
15241
|
let idleNudged = false;
|
|
13433
15242
|
let blankNudged = false;
|
|
@@ -13456,9 +15265,21 @@ var AgentLoop = class {
|
|
|
13456
15265
|
yield finish("budget-exceeded", stop.breach);
|
|
13457
15266
|
return;
|
|
13458
15267
|
}
|
|
13459
|
-
const notice2 = taskNotice.
|
|
13460
|
-
if (notice2) messages.push({ role: "user", content: notice2 });
|
|
13461
|
-
if (
|
|
15268
|
+
const notice2 = taskNotice.noticeDetailed(input.sessionId);
|
|
15269
|
+
if (notice2) messages.push({ role: "user", content: notice2.text });
|
|
15270
|
+
if (notice2 && notice2.agent.length > 0) {
|
|
15271
|
+
yield {
|
|
15272
|
+
type: "notice",
|
|
15273
|
+
code: "agent-message",
|
|
15274
|
+
text: [systemNote(AGENT_MESSAGE_NOTE_TITLE), ...notice2.agent].join("\n")
|
|
15275
|
+
};
|
|
15276
|
+
}
|
|
15277
|
+
if (turn > 1) {
|
|
15278
|
+
for await (const ev of this.drainSteer(input, messages)) {
|
|
15279
|
+
if (ev.type === "steer") pendingReceived.push(ev.text);
|
|
15280
|
+
yield ev;
|
|
15281
|
+
}
|
|
15282
|
+
}
|
|
13462
15283
|
this.hooks.fire("turn:before", {
|
|
13463
15284
|
sessionId: input.sessionId,
|
|
13464
15285
|
userMessage: transformed,
|
|
@@ -13584,9 +15405,9 @@ var AgentLoop = class {
|
|
|
13584
15405
|
}
|
|
13585
15406
|
llmSpan.setAttribute("epoch.finish_reason", result.finishReason);
|
|
13586
15407
|
break;
|
|
13587
|
-
} catch (
|
|
13588
|
-
llmSpan.recordError(
|
|
13589
|
-
if (isBodyTooLarge(
|
|
15408
|
+
} catch (err3) {
|
|
15409
|
+
llmSpan.recordError(err3);
|
|
15410
|
+
if (isBodyTooLarge(err3) && imagesRescue.offloaded === 0) {
|
|
13590
15411
|
const saved = this.tryOffloadForBodyLimit(messages);
|
|
13591
15412
|
if (saved) {
|
|
13592
15413
|
messages = saved.messages;
|
|
@@ -13602,8 +15423,8 @@ var AgentLoop = class {
|
|
|
13602
15423
|
}
|
|
13603
15424
|
}
|
|
13604
15425
|
const engine = this.config.contextEngine;
|
|
13605
|
-
const retriable = isContextOverflow(
|
|
13606
|
-
if (overflowRescued || !engine || !retriable) throw
|
|
15426
|
+
const retriable = isContextOverflow(err3) || isBodyTooLarge(err3);
|
|
15427
|
+
if (overflowRescued || !engine || !retriable) throw err3;
|
|
13607
15428
|
overflowRescued = true;
|
|
13608
15429
|
const rescued = await this.compressNow(messages, {
|
|
13609
15430
|
totalTokens: totalInput + totalOutput,
|
|
@@ -13616,7 +15437,7 @@ var AgentLoop = class {
|
|
|
13616
15437
|
runUsage
|
|
13617
15438
|
);
|
|
13618
15439
|
}
|
|
13619
|
-
if (!shrank(messages, rescued.messages)) throw
|
|
15440
|
+
if (!shrank(messages, rescued.messages)) throw err3;
|
|
13620
15441
|
messages = rescued.messages;
|
|
13621
15442
|
yield {
|
|
13622
15443
|
type: "notice",
|
|
@@ -13729,7 +15550,8 @@ var AgentLoop = class {
|
|
|
13729
15550
|
index: turn,
|
|
13730
15551
|
llmResponse: result.text,
|
|
13731
15552
|
toolCalls: [],
|
|
13732
|
-
duration: Date.now() - turnStart
|
|
15553
|
+
duration: Date.now() - turnStart,
|
|
15554
|
+
...pendingReceived.length > 0 ? { received: pendingReceived.splice(0) } : {}
|
|
13733
15555
|
});
|
|
13734
15556
|
yield { type: "turn-complete", turn };
|
|
13735
15557
|
const finalText = await this.hooks.transformResponse(result.text, input.sessionId);
|
|
@@ -13750,7 +15572,10 @@ ${finalText}` };
|
|
|
13750
15572
|
content: finalText || NO_OUTPUT_TEXT,
|
|
13751
15573
|
...result.reasoningText ? { reasoning: result.reasoningText } : {}
|
|
13752
15574
|
});
|
|
13753
|
-
|
|
15575
|
+
for await (const ev of this.drainSteer(input, messages)) {
|
|
15576
|
+
if (ev.type === "steer") pendingReceived.push(ev.text);
|
|
15577
|
+
yield ev;
|
|
15578
|
+
}
|
|
13754
15579
|
continue;
|
|
13755
15580
|
}
|
|
13756
15581
|
const wantContinue = await this.hooks.wantsContinue(
|
|
@@ -13898,7 +15723,8 @@ ${finalText}` };
|
|
|
13898
15723
|
args: e.args,
|
|
13899
15724
|
result: e.output
|
|
13900
15725
|
})),
|
|
13901
|
-
duration: Date.now() - turnStart
|
|
15726
|
+
duration: Date.now() - turnStart,
|
|
15727
|
+
...pendingReceived.length > 0 ? { received: pendingReceived.splice(0) } : {}
|
|
13902
15728
|
});
|
|
13903
15729
|
this.hooks.fire("turn:after", {
|
|
13904
15730
|
sessionId: input.sessionId,
|
|
@@ -13954,15 +15780,15 @@ ${finalText}` };
|
|
|
13954
15780
|
turns
|
|
13955
15781
|
});
|
|
13956
15782
|
yield finish("max-turns");
|
|
13957
|
-
} catch (
|
|
15783
|
+
} catch (err3) {
|
|
13958
15784
|
if (this.isAborted(input.signal)) {
|
|
13959
15785
|
await this.prompt.syncMemory(userText, lastText);
|
|
13960
15786
|
yield { type: "notice", code: "aborted", text: t("agent_run.aborted") };
|
|
13961
15787
|
yield finish("aborted");
|
|
13962
15788
|
return;
|
|
13963
15789
|
}
|
|
13964
|
-
const msg =
|
|
13965
|
-
runSpan.recordError(
|
|
15790
|
+
const msg = err3 instanceof Error ? err3.message : String(err3);
|
|
15791
|
+
runSpan.recordError(err3);
|
|
13966
15792
|
await this.prompt.syncMemory(userText, "");
|
|
13967
15793
|
const errorText = t("agent_run.error", { message: msg });
|
|
13968
15794
|
this.hooks.fire("turn:after", { sessionId: input.sessionId, response: errorText });
|
|
@@ -13978,6 +15804,7 @@ ${finalText}` };
|
|
|
13978
15804
|
sessionId: input.sessionId,
|
|
13979
15805
|
totalTokens: totalInput + totalOutput
|
|
13980
15806
|
});
|
|
15807
|
+
this.config.team?.endSessionTurn(input.sessionId);
|
|
13981
15808
|
runSpan.setAttribute("epoch.turns", turns.length);
|
|
13982
15809
|
runSpan.setAttribute(GEN_AI.USAGE_INPUT_TOKENS, totalInput);
|
|
13983
15810
|
runSpan.setAttribute(GEN_AI.USAGE_OUTPUT_TOKENS, totalOutput);
|
|
@@ -14048,7 +15875,8 @@ ${finalText}` };
|
|
|
14048
15875
|
messages: compressed.messages.map((m) => unflattenMessage(m)),
|
|
14049
15876
|
...bill,
|
|
14050
15877
|
...compressed.carriedHead === void 0 ? {} : { carriedHead: compressed.carriedHead },
|
|
14051
|
-
...compressed.carriedTail === void 0 ? {} : { carriedTail: compressed.carriedTail }
|
|
15878
|
+
...compressed.carriedTail === void 0 ? {} : { carriedTail: compressed.carriedTail },
|
|
15879
|
+
summarySkipped: compressed.summarySkipped === true
|
|
14052
15880
|
};
|
|
14053
15881
|
} catch {
|
|
14054
15882
|
return { messages };
|
|
@@ -14174,10 +16002,10 @@ function loadModelEntries(homeDir) {
|
|
|
14174
16002
|
let raw;
|
|
14175
16003
|
try {
|
|
14176
16004
|
raw = JSON.parse(readFileSync(path, "utf-8"));
|
|
14177
|
-
} catch (
|
|
16005
|
+
} catch (err3) {
|
|
14178
16006
|
return {
|
|
14179
16007
|
entries: [],
|
|
14180
|
-
issues: [`${path}: ${
|
|
16008
|
+
issues: [`${path}: ${err3 instanceof Error ? err3.message : String(err3)}`]
|
|
14181
16009
|
};
|
|
14182
16010
|
}
|
|
14183
16011
|
const list = raw?.models;
|
|
@@ -14225,9 +16053,9 @@ function saveModelEntries(homeDir, entries2, hostLabel) {
|
|
|
14225
16053
|
try {
|
|
14226
16054
|
writeFileSync(tmp, body2, { encoding: "utf-8", mode: 384 });
|
|
14227
16055
|
renameSync(tmp, path);
|
|
14228
|
-
} catch (
|
|
16056
|
+
} catch (err3) {
|
|
14229
16057
|
rmSync(tmp, { force: true });
|
|
14230
|
-
throw
|
|
16058
|
+
throw err3;
|
|
14231
16059
|
}
|
|
14232
16060
|
}
|
|
14233
16061
|
var EntryRefSchema = z.string().refine((v) => parseModelRef(v) !== void 0, { message: "expected @<model-entry-id>" });
|
|
@@ -14511,8 +16339,8 @@ var SettingsFileError = class extends Error {
|
|
|
14511
16339
|
this.hint = hint;
|
|
14512
16340
|
}
|
|
14513
16341
|
};
|
|
14514
|
-
function describeJsonError(
|
|
14515
|
-
const message =
|
|
16342
|
+
function describeJsonError(err3, text) {
|
|
16343
|
+
const message = err3 instanceof Error ? err3.message.split("\n")[0] ?? "" : "";
|
|
14516
16344
|
if (!message) return t("config_load.json_unknown_error");
|
|
14517
16345
|
const at = /position (\d+)/.exec(message);
|
|
14518
16346
|
if (!at?.[1]) return message;
|
|
@@ -14529,8 +16357,8 @@ function readSettingsFile(path, schema, known, empty, issues, sanitize = (raw) =
|
|
|
14529
16357
|
let raw;
|
|
14530
16358
|
try {
|
|
14531
16359
|
raw = JSON.parse(text);
|
|
14532
|
-
} catch (
|
|
14533
|
-
const reason9 = describeJsonError(
|
|
16360
|
+
} catch (err3) {
|
|
16361
|
+
const reason9 = describeJsonError(err3, text);
|
|
14534
16362
|
issues.push({ path, message: t("config_load.json_invalid", { reason: reason9 }) });
|
|
14535
16363
|
return { failed: reason9 };
|
|
14536
16364
|
}
|
|
@@ -14968,13 +16796,13 @@ function readRawConfig(configPath2, issues) {
|
|
|
14968
16796
|
const text = readFileSync(configPath2, "utf-8");
|
|
14969
16797
|
if (text.trim() === "") return { kind: "ok", raw: {} };
|
|
14970
16798
|
return { kind: "ok", raw: load(text) ?? {} };
|
|
14971
|
-
} catch (
|
|
16799
|
+
} catch (err3) {
|
|
14972
16800
|
const backup = backupCorruptConfig(configPath2);
|
|
14973
16801
|
issues.push({
|
|
14974
16802
|
path: "(root)",
|
|
14975
16803
|
message: t("config_load.bad_yaml", {
|
|
14976
16804
|
path: configPath2,
|
|
14977
|
-
reason:
|
|
16805
|
+
reason: err3.message.split("\n")[0] ?? "",
|
|
14978
16806
|
backup: backup ? t("config_load.bad_yaml_backup", { path: backup }) : t("config_load.bad_yaml_no_backup")
|
|
14979
16807
|
})
|
|
14980
16808
|
});
|
|
@@ -15254,16 +17082,16 @@ async function runImageProbe(model) {
|
|
|
15254
17082
|
let withImage;
|
|
15255
17083
|
try {
|
|
15256
17084
|
withImage = await shoot(model, true);
|
|
15257
|
-
} catch (
|
|
15258
|
-
return { verdict: "no", detail:
|
|
17085
|
+
} catch (err3) {
|
|
17086
|
+
return { verdict: "no", detail: err3 instanceof Error ? err3.message : String(err3) };
|
|
15259
17087
|
}
|
|
15260
17088
|
let baseline;
|
|
15261
17089
|
try {
|
|
15262
17090
|
baseline = await shoot(model, false);
|
|
15263
|
-
} catch (
|
|
17091
|
+
} catch (err3) {
|
|
15264
17092
|
return {
|
|
15265
17093
|
verdict: "inconclusive",
|
|
15266
|
-
detail: `baseline failed: ${
|
|
17094
|
+
detail: `baseline failed: ${err3 instanceof Error ? err3.message : String(err3)}`
|
|
15267
17095
|
};
|
|
15268
17096
|
}
|
|
15269
17097
|
const shot = withImage.inputTokens;
|
|
@@ -15793,11 +17621,11 @@ var ProviderSdkMissingError = class extends Error {
|
|
|
15793
17621
|
async function createModelFactory(type, opts) {
|
|
15794
17622
|
try {
|
|
15795
17623
|
return await LOADERS[type](opts);
|
|
15796
|
-
} catch (
|
|
15797
|
-
if (isModuleNotFound(
|
|
15798
|
-
throw new ProviderSdkMissingError(type, PACKAGES[type],
|
|
17624
|
+
} catch (err3) {
|
|
17625
|
+
if (isModuleNotFound(err3)) {
|
|
17626
|
+
throw new ProviderSdkMissingError(type, PACKAGES[type], err3);
|
|
15799
17627
|
}
|
|
15800
|
-
throw
|
|
17628
|
+
throw err3;
|
|
15801
17629
|
}
|
|
15802
17630
|
}
|
|
15803
17631
|
async function createEntryFactory(entry, apiKey) {
|
|
@@ -15805,9 +17633,9 @@ async function createEntryFactory(entry, apiKey) {
|
|
|
15805
17633
|
const pkg = type === "openai-compatible" && entry.protocol === "anthropic-messages" ? "@ai-sdk/anthropic" : PACKAGES[type];
|
|
15806
17634
|
try {
|
|
15807
17635
|
return await loadEntry(entry, apiKey);
|
|
15808
|
-
} catch (
|
|
15809
|
-
if (isModuleNotFound(
|
|
15810
|
-
throw
|
|
17636
|
+
} catch (err3) {
|
|
17637
|
+
if (isModuleNotFound(err3)) throw new ProviderSdkMissingError(type, pkg, err3);
|
|
17638
|
+
throw err3;
|
|
15811
17639
|
}
|
|
15812
17640
|
}
|
|
15813
17641
|
async function loadEntry(entry, apiKey) {
|
|
@@ -15880,11 +17708,11 @@ var CARRIES_REASONING_BACK = {
|
|
|
15880
17708
|
function carriesReasoningBack(type) {
|
|
15881
17709
|
return CARRIES_REASONING_BACK[type];
|
|
15882
17710
|
}
|
|
15883
|
-
function isModuleNotFound(
|
|
15884
|
-
if (!
|
|
15885
|
-
const code =
|
|
17711
|
+
function isModuleNotFound(err3) {
|
|
17712
|
+
if (!err3 || typeof err3 !== "object") return false;
|
|
17713
|
+
const code = err3.code;
|
|
15886
17714
|
if (code === "ERR_MODULE_NOT_FOUND" || code === "MODULE_NOT_FOUND") return true;
|
|
15887
|
-
const msg =
|
|
17715
|
+
const msg = err3 instanceof Error ? err3.message : "";
|
|
15888
17716
|
return /Cannot find (module|package)|Failed to resolve/i.test(msg);
|
|
15889
17717
|
}
|
|
15890
17718
|
// src/provider/entry-route.ts
|
|
@@ -16180,8 +18008,8 @@ var ProviderRouter = class {
|
|
|
16180
18008
|
}
|
|
16181
18009
|
if (this.effort !== void 0) {
|
|
16182
18010
|
const state = this.getEffort();
|
|
16183
|
-
const
|
|
16184
|
-
if (!
|
|
18011
|
+
const ok4 = this.effort === "off" ? state.canTurnOff : state.levels.includes(this.effort);
|
|
18012
|
+
if (!ok4) this.effort = void 0;
|
|
16185
18013
|
}
|
|
16186
18014
|
}
|
|
16187
18015
|
refreshedSelection(sel) {
|
|
@@ -16211,9 +18039,9 @@ var ProviderRouter = class {
|
|
|
16211
18039
|
this.effort = void 0;
|
|
16212
18040
|
return true;
|
|
16213
18041
|
}
|
|
16214
|
-
const
|
|
16215
|
-
if (
|
|
16216
|
-
return
|
|
18042
|
+
const ok4 = choice === "off" ? state.canTurnOff : state.levels.includes(choice);
|
|
18043
|
+
if (ok4) this.effort = choice;
|
|
18044
|
+
return ok4;
|
|
16217
18045
|
}
|
|
16218
18046
|
reasoningFor(input, ct, entry) {
|
|
16219
18047
|
if (input.entry || entry !== this.selection.entry) return void 0;
|
|
@@ -16314,8 +18142,8 @@ var ProviderRouter = class {
|
|
|
16314
18142
|
let factory;
|
|
16315
18143
|
try {
|
|
16316
18144
|
factory = opts.entry ? await createEntryFactory(opts.entry, opts.apiKey || void 0) : await createModelFactory(route, opts);
|
|
16317
|
-
} catch (
|
|
16318
|
-
throw new ProviderError(
|
|
18145
|
+
} catch (err3) {
|
|
18146
|
+
throw new ProviderError(err3 instanceof Error ? err3.message : String(err3), 1005, false);
|
|
16319
18147
|
}
|
|
16320
18148
|
this.factories.set(route, factory);
|
|
16321
18149
|
return factory(modelId ?? this.selection.model);
|
|
@@ -16344,9 +18172,9 @@ var ProviderRouter = class {
|
|
|
16344
18172
|
const fb = this.fallbackEntry(sel.entry, /* @__PURE__ */ new Set([entryTried(sel.entry)]));
|
|
16345
18173
|
return fb && !this.failures.isAbandoned(this.routeOf(fb.provider, fb.entry)) ? fb : sel;
|
|
16346
18174
|
}
|
|
16347
|
-
async recover(
|
|
16348
|
-
const { code, recovery } = classifyProviderError(
|
|
16349
|
-
const message = describeProviderError(
|
|
18175
|
+
async recover(err3, state) {
|
|
18176
|
+
const { code, recovery } = classifyProviderError(err3);
|
|
18177
|
+
const message = describeProviderError(err3);
|
|
16350
18178
|
const stay = { kind: "continue", ct: state.ct, cm: state.cm, entry: state.entry };
|
|
16351
18179
|
if (code === PROVIDER_ABORTED) return { kind: "give-up", message, code };
|
|
16352
18180
|
if (recovery === "retry") {
|
|
@@ -16471,8 +18299,8 @@ var ProviderRouter = class {
|
|
|
16471
18299
|
...applied === void 0 ? {} : { responseFormatApplied: applied },
|
|
16472
18300
|
...warnings ? { warnings } : {}
|
|
16473
18301
|
};
|
|
16474
|
-
} catch (
|
|
16475
|
-
const plan = await this.recover(
|
|
18302
|
+
} catch (err3) {
|
|
18303
|
+
const plan = await this.recover(err3, state);
|
|
16476
18304
|
if (plan.kind === "give-up") throw new ProviderError(plan.message, plan.code, false);
|
|
16477
18305
|
state.ct = plan.ct;
|
|
16478
18306
|
state.cm = plan.cm;
|
|
@@ -16574,8 +18402,8 @@ var ProviderRouter = class {
|
|
|
16574
18402
|
...warnings ? { warnings } : {}
|
|
16575
18403
|
};
|
|
16576
18404
|
return;
|
|
16577
|
-
} catch (
|
|
16578
|
-
const cause = streamPartError ??
|
|
18405
|
+
} catch (err3) {
|
|
18406
|
+
const cause = streamPartError ?? err3;
|
|
16579
18407
|
if (emitted) {
|
|
16580
18408
|
yield { type: "error", error: describeProviderError(cause) };
|
|
16581
18409
|
return;
|
|
@@ -16909,9 +18737,9 @@ async function testModelEntry(entry, apiKey) {
|
|
|
16909
18737
|
abortSignal: AbortSignal.timeout(2e4)
|
|
16910
18738
|
});
|
|
16911
18739
|
return { code: "ok", models, latencyMs: elapsed() };
|
|
16912
|
-
} catch (
|
|
16913
|
-
const status = extractStatus(
|
|
16914
|
-
const detail = redact(describeProviderError(
|
|
18740
|
+
} catch (err3) {
|
|
18741
|
+
const status = extractStatus(err3);
|
|
18742
|
+
const detail = redact(describeProviderError(err3), apiKey);
|
|
16915
18743
|
return {
|
|
16916
18744
|
code: classify(status, detail),
|
|
16917
18745
|
models,
|
|
@@ -17179,9 +19007,9 @@ function commit(path, body2, createMode, value) {
|
|
|
17179
19007
|
try {
|
|
17180
19008
|
writeFileSync(tmp, body2, { encoding: "utf-8", mode });
|
|
17181
19009
|
renameSync(tmp, path);
|
|
17182
|
-
} catch (
|
|
19010
|
+
} catch (err3) {
|
|
17183
19011
|
rmSync(tmp, { force: true });
|
|
17184
|
-
throw
|
|
19012
|
+
throw err3;
|
|
17185
19013
|
}
|
|
17186
19014
|
} catch {
|
|
17187
19015
|
return { ok: false, reason: "io" };
|
|
@@ -17598,13 +19426,13 @@ function readRaw(path) {
|
|
|
17598
19426
|
let text;
|
|
17599
19427
|
try {
|
|
17600
19428
|
text = readFileSync(path, "utf-8");
|
|
17601
|
-
} catch (
|
|
17602
|
-
return { issue: reason5(
|
|
19429
|
+
} catch (err3) {
|
|
19430
|
+
return { issue: reason5(err3) };
|
|
17603
19431
|
}
|
|
17604
19432
|
try {
|
|
17605
19433
|
return { value: JSON.parse(text) };
|
|
17606
|
-
} catch (
|
|
17607
|
-
return { issue: reason5(
|
|
19434
|
+
} catch (err3) {
|
|
19435
|
+
return { issue: reason5(err3) };
|
|
17608
19436
|
}
|
|
17609
19437
|
}
|
|
17610
19438
|
function readVimMode(raw, issues) {
|
|
@@ -17687,8 +19515,8 @@ function supportsSequence(action) {
|
|
|
17687
19515
|
function warn(detail, code) {
|
|
17688
19516
|
return { module: MODULE2, status: "warn", detail, code };
|
|
17689
19517
|
}
|
|
17690
|
-
function reason5(
|
|
17691
|
-
return (
|
|
19518
|
+
function reason5(err3) {
|
|
19519
|
+
return (err3 instanceof Error ? err3.message : String(err3)).split("\n")[0] ?? "";
|
|
17692
19520
|
}
|
|
17693
19521
|
// src/memory/tokenize.ts
|
|
17694
19522
|
var CJK_RUN = /[-ヿ㐀-䶿一-鿿豈-가-]+/gu;
|
|
@@ -17732,7 +19560,7 @@ function buildSearchQuery(query) {
|
|
|
17732
19560
|
// src/memory/db.ts
|
|
17733
19561
|
var NS2 = "memory";
|
|
17734
19562
|
var FTS_SCHEMA_VERSION = 2;
|
|
17735
|
-
var
|
|
19563
|
+
var MIGRATIONS3 = [
|
|
17736
19564
|
{
|
|
17737
19565
|
id: "memory-baseline",
|
|
17738
19566
|
version: 1,
|
|
@@ -17774,10 +19602,10 @@ var MemoryDB = class {
|
|
|
17774
19602
|
db;
|
|
17775
19603
|
path;
|
|
17776
19604
|
nextPosition = { memory: 0, user: 0 };
|
|
17777
|
-
constructor(
|
|
17778
|
-
this.path =
|
|
19605
|
+
constructor(dbPath2) {
|
|
19606
|
+
this.path = dbPath2;
|
|
17779
19607
|
this.db = openDatabase(this.path);
|
|
17780
|
-
migrate(this.db, NS2,
|
|
19608
|
+
migrate(this.db, NS2, MIGRATIONS3);
|
|
17781
19609
|
this.migrateFts();
|
|
17782
19610
|
for (const target of ["memory", "user"]) {
|
|
17783
19611
|
const row = this.db.prepare(
|
|
@@ -18020,9 +19848,9 @@ function stripUndefined(obj) {
|
|
|
18020
19848
|
return Object.fromEntries(Object.entries(obj).filter(([, v]) => v !== void 0));
|
|
18021
19849
|
}
|
|
18022
19850
|
var MemoryManager = class {
|
|
18023
|
-
constructor(
|
|
19851
|
+
constructor(dbPath2, memDir, config, options = {}) {
|
|
18024
19852
|
this.options = options;
|
|
18025
|
-
const dp =
|
|
19853
|
+
const dp = dbPath2 ?? DB_PATH;
|
|
18026
19854
|
const md = memDir ?? MEM_DIR;
|
|
18027
19855
|
this.memDir = md;
|
|
18028
19856
|
mkdirSync(dirname(dp), { recursive: true });
|
|
@@ -18440,8 +20268,8 @@ var MemoryManager = class {
|
|
|
18440
20268
|
});
|
|
18441
20269
|
continue;
|
|
18442
20270
|
}
|
|
18443
|
-
const
|
|
18444
|
-
const summary = countCodePoints(
|
|
20271
|
+
const firstLine5 = (entry.content.split("\n")[0] ?? "").trim();
|
|
20272
|
+
const summary = countCodePoints(firstLine5) > INDEX_SUMMARY_CHARS ? `${headCodePoints(firstLine5, INDEX_SUMMARY_CHARS)}\u2026` : firstLine5;
|
|
18445
20273
|
out.push({ id, target, summary, charLength: entry.content.length });
|
|
18446
20274
|
}
|
|
18447
20275
|
return out;
|
|
@@ -18768,7 +20596,7 @@ function nonEmpty(items) {
|
|
|
18768
20596
|
function isRecord4(v) {
|
|
18769
20597
|
return typeof v === "object" && v !== null;
|
|
18770
20598
|
}
|
|
18771
|
-
function
|
|
20599
|
+
function str5(v) {
|
|
18772
20600
|
return typeof v === "string" && v.length > 0 ? v : void 0;
|
|
18773
20601
|
}
|
|
18774
20602
|
function isSessionOmitReason(value) {
|
|
@@ -18780,8 +20608,8 @@ function parseToolCalls(json) {
|
|
|
18780
20608
|
const calls = [];
|
|
18781
20609
|
for (const item of raw) {
|
|
18782
20610
|
if (!isRecord4(item)) continue;
|
|
18783
|
-
const toolCallId =
|
|
18784
|
-
const toolName =
|
|
20611
|
+
const toolCallId = str5(item["toolCallId"]) ?? str5(item["id"]);
|
|
20612
|
+
const toolName = str5(item["toolName"]) ?? str5(item["name"]);
|
|
18785
20613
|
if (!toolCallId || !toolName) continue;
|
|
18786
20614
|
const input = item["input"] ?? item["args"];
|
|
18787
20615
|
calls.push({ toolCallId, toolName, input: isRecord4(input) ? input : {} });
|
|
@@ -18796,10 +20624,10 @@ function parseArtifacts(raw) {
|
|
|
18796
20624
|
const kind = item["kind"];
|
|
18797
20625
|
out.push({
|
|
18798
20626
|
kind: kind === "image" || kind === "audio" || kind === "file" ? kind : "file",
|
|
18799
|
-
mediaType:
|
|
20627
|
+
mediaType: str5(item["mediaType"]) ?? "application/octet-stream",
|
|
18800
20628
|
summary: typeof item["summary"] === "string" ? item["summary"] : "",
|
|
18801
20629
|
bytes: typeof item["bytes"] === "number" ? item["bytes"] : 0,
|
|
18802
|
-
...
|
|
20630
|
+
...str5(item["path"]) ? { path: item["path"] } : {},
|
|
18803
20631
|
...typeof item["width"] === "number" ? { width: item["width"] } : {},
|
|
18804
20632
|
...typeof item["height"] === "number" ? { height: item["height"] } : {},
|
|
18805
20633
|
...typeof item["estimatedTokens"] === "number" ? { estimatedTokens: item["estimatedTokens"] } : {}
|
|
@@ -18813,8 +20641,8 @@ function parseToolResults(json) {
|
|
|
18813
20641
|
const results = [];
|
|
18814
20642
|
for (const item of raw) {
|
|
18815
20643
|
if (!isRecord4(item)) continue;
|
|
18816
|
-
const toolCallId =
|
|
18817
|
-
const toolName =
|
|
20644
|
+
const toolCallId = str5(item["toolCallId"]);
|
|
20645
|
+
const toolName = str5(item["toolName"]);
|
|
18818
20646
|
if (!toolCallId || !toolName) continue;
|
|
18819
20647
|
const artifacts = parseArtifacts(item["artifacts"]);
|
|
18820
20648
|
results.push({
|
|
@@ -18826,24 +20654,41 @@ function parseToolResults(json) {
|
|
|
18826
20654
|
}
|
|
18827
20655
|
return nonEmpty(results);
|
|
18828
20656
|
}
|
|
20657
|
+
function parseDiffs(json) {
|
|
20658
|
+
const raw = parseArray(json);
|
|
20659
|
+
if (!raw) return void 0;
|
|
20660
|
+
const diffs = [];
|
|
20661
|
+
for (const item of raw) {
|
|
20662
|
+
if (!isRecord4(item)) continue;
|
|
20663
|
+
const filePath = str5(item["filePath"]);
|
|
20664
|
+
if (!filePath) continue;
|
|
20665
|
+
diffs.push({
|
|
20666
|
+
filePath,
|
|
20667
|
+
...typeof item["oldContent"] === "string" ? { oldContent: item["oldContent"] } : {},
|
|
20668
|
+
...typeof item["newContent"] === "string" ? { newContent: item["newContent"] } : {},
|
|
20669
|
+
...item["omitted"] === "too-large" ? { omitted: "too-large" } : {}
|
|
20670
|
+
});
|
|
20671
|
+
}
|
|
20672
|
+
return nonEmpty(diffs);
|
|
20673
|
+
}
|
|
18829
20674
|
function parseParts(json) {
|
|
18830
20675
|
const raw = parseArray(json);
|
|
18831
20676
|
if (!raw) return void 0;
|
|
18832
20677
|
const parts = [];
|
|
18833
20678
|
for (const item of raw) {
|
|
18834
20679
|
if (!isRecord4(item)) continue;
|
|
18835
|
-
const mediaType =
|
|
20680
|
+
const mediaType = str5(item["mediaType"]);
|
|
18836
20681
|
const media = mediaType ? { mediaType } : {};
|
|
18837
20682
|
if (item["type"] === "text") {
|
|
18838
20683
|
if (typeof item["text"] === "string") parts.push({ type: "text", text: item["text"] });
|
|
18839
20684
|
continue;
|
|
18840
20685
|
}
|
|
18841
20686
|
if (item["type"] === "session") {
|
|
18842
|
-
const ref =
|
|
20687
|
+
const ref = str5(item["ref"]);
|
|
18843
20688
|
if (!ref) continue;
|
|
18844
|
-
const sessionId =
|
|
18845
|
-
const title =
|
|
18846
|
-
const omitted =
|
|
20689
|
+
const sessionId = str5(item["sessionId"]);
|
|
20690
|
+
const title = str5(item["title"]);
|
|
20691
|
+
const omitted = str5(item["omitted"]);
|
|
18847
20692
|
parts.push({
|
|
18848
20693
|
type: "session",
|
|
18849
20694
|
ref,
|
|
@@ -18856,9 +20701,9 @@ function parseParts(json) {
|
|
|
18856
20701
|
continue;
|
|
18857
20702
|
}
|
|
18858
20703
|
if (item["type"] === "file") {
|
|
18859
|
-
const filePath =
|
|
20704
|
+
const filePath = str5(item["path"]);
|
|
18860
20705
|
if (!filePath) continue;
|
|
18861
|
-
const fileOmitted =
|
|
20706
|
+
const fileOmitted = str5(item["omitted"]);
|
|
18862
20707
|
parts.push({
|
|
18863
20708
|
type: "file",
|
|
18864
20709
|
path: filePath,
|
|
@@ -18868,8 +20713,8 @@ function parseParts(json) {
|
|
|
18868
20713
|
continue;
|
|
18869
20714
|
}
|
|
18870
20715
|
if (item["type"] !== "image") continue;
|
|
18871
|
-
const path =
|
|
18872
|
-
const url =
|
|
20716
|
+
const path = str5(item["path"]);
|
|
20717
|
+
const url = str5(item["url"]);
|
|
18873
20718
|
if (path) parts.push({ type: "image", path, ...media });
|
|
18874
20719
|
else if (url) parts.push({ type: "image", url, ...media });
|
|
18875
20720
|
}
|
|
@@ -18916,10 +20761,10 @@ function parseTurnFacts(json) {
|
|
|
18916
20761
|
const toolCalls = num2(raw["toolCalls"]);
|
|
18917
20762
|
if (toolCalls === void 0) return void 0;
|
|
18918
20763
|
const usage = parseUsage(raw["usage"]);
|
|
18919
|
-
const model =
|
|
18920
|
-
const requestedModel =
|
|
20764
|
+
const model = str5(raw["model"]);
|
|
20765
|
+
const requestedModel = str5(raw["requestedModel"]);
|
|
18921
20766
|
const durationMs = num2(raw["durationMs"]);
|
|
18922
|
-
const error =
|
|
20767
|
+
const error = str5(raw["error"])?.trim() || void 0;
|
|
18923
20768
|
return {
|
|
18924
20769
|
toolCalls,
|
|
18925
20770
|
...usage ? { usage } : {},
|
|
@@ -18941,10 +20786,10 @@ function parseUserCommand(json) {
|
|
|
18941
20786
|
return void 0;
|
|
18942
20787
|
}
|
|
18943
20788
|
if (!isRecord4(raw)) return void 0;
|
|
18944
|
-
const name =
|
|
20789
|
+
const name = str5(raw["name"]);
|
|
18945
20790
|
if (!name) return void 0;
|
|
18946
|
-
const displayName =
|
|
18947
|
-
const args =
|
|
20791
|
+
const displayName = str5(raw["displayName"]);
|
|
20792
|
+
const args = str5(raw["args"]);
|
|
18948
20793
|
return {
|
|
18949
20794
|
name,
|
|
18950
20795
|
...displayName ? { displayName } : {},
|
|
@@ -19269,13 +21114,21 @@ var FTS_EXTERNAL_MIGRATIONS = [
|
|
|
19269
21114
|
up: (db) => {
|
|
19270
21115
|
db.exec(`ALTER TABLE messages ADD COLUMN command TEXT`);
|
|
19271
21116
|
}
|
|
21117
|
+
},
|
|
21118
|
+
{
|
|
21119
|
+
id: "messages-diffs",
|
|
21120
|
+
version: 17,
|
|
21121
|
+
description: "\u6D88\u606F\u8868\u52A0 diffs \u4E00\u5217\uFF08\u8865\u4E01\u9884\u89C8\u843D\u76D8\uFF0C2026-10-30\uFF09",
|
|
21122
|
+
up: (db) => {
|
|
21123
|
+
db.exec(`ALTER TABLE messages ADD COLUMN diffs TEXT`);
|
|
21124
|
+
}
|
|
19272
21125
|
}
|
|
19273
21126
|
];
|
|
19274
21127
|
var SessionDB = class {
|
|
19275
21128
|
db;
|
|
19276
21129
|
path;
|
|
19277
|
-
constructor(
|
|
19278
|
-
this.path =
|
|
21130
|
+
constructor(dbPath2) {
|
|
21131
|
+
this.path = dbPath2 ?? dbPath();
|
|
19279
21132
|
this.db = openDatabase(this.path);
|
|
19280
21133
|
migrate(this.db, NS3, SESSION_MIGRATIONS);
|
|
19281
21134
|
this.migrateFtsIndex();
|
|
@@ -19283,10 +21136,10 @@ var SessionDB = class {
|
|
|
19283
21136
|
migrateFtsIndex() {
|
|
19284
21137
|
try {
|
|
19285
21138
|
migrate(this.db, NS3, FTS_EXTERNAL_MIGRATIONS);
|
|
19286
|
-
} catch (
|
|
21139
|
+
} catch (err3) {
|
|
19287
21140
|
log2.warn(
|
|
19288
21141
|
"FTS index rebuild (v8) failed; keeping the legacy schema for now (content stored three times, ~36% larger). Will retry on next start.",
|
|
19289
|
-
{ error:
|
|
21142
|
+
{ error: err3 instanceof Error ? err3.message : String(err3) }
|
|
19290
21143
|
);
|
|
19291
21144
|
}
|
|
19292
21145
|
}
|
|
@@ -19466,8 +21319,8 @@ var SessionDB = class {
|
|
|
19466
21319
|
insertMessage(msg) {
|
|
19467
21320
|
const info = this.db.prepare(
|
|
19468
21321
|
`
|
|
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)
|
|
21322
|
+
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)
|
|
21323
|
+
VALUES (@sessionId, @role, @content, @toolCallId, @toolCalls, @toolResults, @parts, @command, @toolName, @timestamp, @tokenCount, @finishReason, @reasoning, @diffs, @turnFacts, 1, 0, 0)
|
|
19471
21324
|
`
|
|
19472
21325
|
).run({
|
|
19473
21326
|
...msg,
|
|
@@ -19480,6 +21333,7 @@ var SessionDB = class {
|
|
|
19480
21333
|
tokenCount: msg.tokenCount ?? null,
|
|
19481
21334
|
finishReason: msg.finishReason ?? null,
|
|
19482
21335
|
reasoning: msg.reasoning ?? null,
|
|
21336
|
+
diffs: encodeColumn(msg.diffs),
|
|
19483
21337
|
turnFacts: encodeTurnFacts(msg.turnFacts)
|
|
19484
21338
|
});
|
|
19485
21339
|
const toolCalls = msg.toolCalls?.length ?? 0;
|
|
@@ -19729,8 +21583,8 @@ var SessionDB = class {
|
|
|
19729
21583
|
forkMessages(fromSessionId, toSessionId, upToIndex) {
|
|
19730
21584
|
const messages = this.db.prepare("SELECT * FROM messages WHERE session_id = ? AND id <= ? ORDER BY timestamp ASC").all(fromSessionId, upToIndex);
|
|
19731
21585
|
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)
|
|
21586
|
+
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)
|
|
21587
|
+
VALUES (@sessionId, @role, @content, @toolCallId, @toolCalls, @toolResults, @parts, @command, @toolName, @timestamp, @tokenCount, @finishReason, @reasoning, @diffs, @turnFacts, @active, @compacted, @observed)
|
|
19734
21588
|
`);
|
|
19735
21589
|
for (const m of messages) {
|
|
19736
21590
|
const { id: _id, ...rest } = m;
|
|
@@ -19748,6 +21602,7 @@ var SessionDB = class {
|
|
|
19748
21602
|
tokenCount: rest["token_count"] ?? null,
|
|
19749
21603
|
finishReason: rest["finish_reason"] ?? null,
|
|
19750
21604
|
reasoning: rest["reasoning"] ?? null,
|
|
21605
|
+
diffs: rest["diffs"] ?? null,
|
|
19751
21606
|
turnFacts: rest["turn_facts"] ?? null,
|
|
19752
21607
|
active: rest["active"] ?? 1,
|
|
19753
21608
|
compacted: rest["compacted"] ?? 0,
|
|
@@ -19831,6 +21686,7 @@ var SessionDB = class {
|
|
|
19831
21686
|
tokenCount: row["token_count"],
|
|
19832
21687
|
finishReason: row["finish_reason"],
|
|
19833
21688
|
reasoning: row["reasoning"],
|
|
21689
|
+
diffs: parseDiffs(row["diffs"]),
|
|
19834
21690
|
active: row["active"] === 1,
|
|
19835
21691
|
compacted: row["compacted"] === 1,
|
|
19836
21692
|
observed: row["observed"] === 1
|
|
@@ -19865,8 +21721,8 @@ function integrityOf(db, table, compareContent = false) {
|
|
|
19865
21721
|
db.prepare(`INSERT INTO ${table}(${table}) VALUES('integrity-check')`).run();
|
|
19866
21722
|
}
|
|
19867
21723
|
return null;
|
|
19868
|
-
} catch (
|
|
19869
|
-
return
|
|
21724
|
+
} catch (err3) {
|
|
21725
|
+
return err3 instanceof Error ? err3.message : String(err3);
|
|
19870
21726
|
}
|
|
19871
21727
|
}
|
|
19872
21728
|
function indexBytesOf(db) {
|
|
@@ -19942,8 +21798,8 @@ function reclaimFtsSpace(db, vacuum = true) {
|
|
|
19942
21798
|
if (vacuum) {
|
|
19943
21799
|
try {
|
|
19944
21800
|
db.exec("VACUUM");
|
|
19945
|
-
} catch (
|
|
19946
|
-
vacuumError =
|
|
21801
|
+
} catch (err3) {
|
|
21802
|
+
vacuumError = err3 instanceof Error ? err3.message : String(err3);
|
|
19947
21803
|
}
|
|
19948
21804
|
}
|
|
19949
21805
|
const vacuumed = vacuum && vacuumError === null;
|
|
@@ -20153,8 +22009,8 @@ var SessionManager = class {
|
|
|
20153
22009
|
queries;
|
|
20154
22010
|
goals;
|
|
20155
22011
|
references;
|
|
20156
|
-
constructor(
|
|
20157
|
-
this.db = new SessionDB(
|
|
22012
|
+
constructor(dbPath2) {
|
|
22013
|
+
this.db = new SessionDB(dbPath2);
|
|
20158
22014
|
this.queries = new SessionQueries(this.db.db);
|
|
20159
22015
|
this.goals = new GoalStore(this.db.db);
|
|
20160
22016
|
this.references = new SessionReferences(this.db.db);
|
|
@@ -20286,12 +22142,12 @@ var SessionManager = class {
|
|
|
20286
22142
|
...input.todos === void 0 ? {} : { todoIds: todos.map((t83) => t83.id) },
|
|
20287
22143
|
...goal === void 0 ? {} : { goalId: goal.id }
|
|
20288
22144
|
};
|
|
20289
|
-
} catch (
|
|
22145
|
+
} catch (err3) {
|
|
20290
22146
|
return {
|
|
20291
22147
|
ok: false,
|
|
20292
22148
|
id,
|
|
20293
22149
|
reason: "failed",
|
|
20294
|
-
...
|
|
22150
|
+
...err3 instanceof Error ? { detail: err3.name } : {}
|
|
20295
22151
|
};
|
|
20296
22152
|
}
|
|
20297
22153
|
}
|
|
@@ -20869,8 +22725,8 @@ function inspect(input, resolved, root, accepted) {
|
|
|
20869
22725
|
}
|
|
20870
22726
|
var MAX_RECENT_WORKSPACES = 20;
|
|
20871
22727
|
var FILE_VERSION2 = 1;
|
|
20872
|
-
function describe7(
|
|
20873
|
-
return
|
|
22728
|
+
function describe7(err3) {
|
|
22729
|
+
return err3 instanceof Error ? err3.message : String(err3);
|
|
20874
22730
|
}
|
|
20875
22731
|
var RecentWorkspaces = class {
|
|
20876
22732
|
constructor(filePath = workspacesPath()) {
|
|
@@ -20907,9 +22763,9 @@ var RecentWorkspaces = class {
|
|
|
20907
22763
|
let parsed;
|
|
20908
22764
|
try {
|
|
20909
22765
|
parsed = JSON.parse(readFileSync(this.filePath, "utf-8"));
|
|
20910
|
-
} catch (
|
|
22766
|
+
} catch (err3) {
|
|
20911
22767
|
this.loadErrors.push(
|
|
20912
|
-
(lang) => t("workspace.recent_unreadable", { path: this.filePath, reason: describe7(
|
|
22768
|
+
(lang) => t("workspace.recent_unreadable", { path: this.filePath, reason: describe7(err3) }, lang)
|
|
20913
22769
|
);
|
|
20914
22770
|
return;
|
|
20915
22771
|
}
|
|
@@ -20959,10 +22815,10 @@ var RecentWorkspaces = class {
|
|
|
20959
22815
|
mkdirSync(dirname(this.filePath), { recursive: true });
|
|
20960
22816
|
writeFileSync(tmp, body2, { encoding: "utf-8", mode: 384 });
|
|
20961
22817
|
renameSync(tmp, this.filePath);
|
|
20962
|
-
} catch (
|
|
22818
|
+
} catch (err3) {
|
|
20963
22819
|
rmSync(tmp, { force: true });
|
|
20964
22820
|
this.writeErrors.push(
|
|
20965
|
-
(lang) => t("workspace.recent_write_failed", { path: this.filePath, reason: describe7(
|
|
22821
|
+
(lang) => t("workspace.recent_write_failed", { path: this.filePath, reason: describe7(err3) }, lang)
|
|
20966
22822
|
);
|
|
20967
22823
|
}
|
|
20968
22824
|
}
|
|
@@ -20974,8 +22830,8 @@ function isRecentWorkspace(value) {
|
|
|
20974
22830
|
}
|
|
20975
22831
|
var MAX_LAST_OPEN_SESSIONS = 20;
|
|
20976
22832
|
var FILE_VERSION3 = 1;
|
|
20977
|
-
function describe8(
|
|
20978
|
-
return
|
|
22833
|
+
function describe8(err3) {
|
|
22834
|
+
return err3 instanceof Error ? err3.message : String(err3);
|
|
20979
22835
|
}
|
|
20980
22836
|
var LastOpenSessions = class {
|
|
20981
22837
|
constructor(filePath = lastSessionsPath()) {
|
|
@@ -21011,9 +22867,9 @@ var LastOpenSessions = class {
|
|
|
21011
22867
|
let parsed;
|
|
21012
22868
|
try {
|
|
21013
22869
|
parsed = JSON.parse(readFileSync(this.filePath, "utf-8"));
|
|
21014
|
-
} catch (
|
|
22870
|
+
} catch (err3) {
|
|
21015
22871
|
this.loadErrors.push(
|
|
21016
|
-
(lang) => t("last_session.unreadable", { path: this.filePath, reason: describe8(
|
|
22872
|
+
(lang) => t("last_session.unreadable", { path: this.filePath, reason: describe8(err3) }, lang)
|
|
21017
22873
|
);
|
|
21018
22874
|
return;
|
|
21019
22875
|
}
|
|
@@ -21037,10 +22893,10 @@ var LastOpenSessions = class {
|
|
|
21037
22893
|
mkdirSync(dirname(this.filePath), { recursive: true });
|
|
21038
22894
|
writeFileSync(tmp, body2, { encoding: "utf-8", mode: 384 });
|
|
21039
22895
|
renameSync(tmp, this.filePath);
|
|
21040
|
-
} catch (
|
|
22896
|
+
} catch (err3) {
|
|
21041
22897
|
rmSync(tmp, { force: true });
|
|
21042
22898
|
this.writeErrors.push(
|
|
21043
|
-
(lang) => t("last_session.write_failed", { path: this.filePath, reason: describe8(
|
|
22899
|
+
(lang) => t("last_session.write_failed", { path: this.filePath, reason: describe8(err3) }, lang)
|
|
21044
22900
|
);
|
|
21045
22901
|
}
|
|
21046
22902
|
}
|
|
@@ -21053,8 +22909,8 @@ function isLastOpenSession(value) {
|
|
|
21053
22909
|
var isWidthShaped = (value) => typeof value === "number" && Number.isInteger(value) && value > 0;
|
|
21054
22910
|
var FILE_VERSION4 = 2;
|
|
21055
22911
|
var isPlainObject2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
21056
|
-
function describe9(
|
|
21057
|
-
return
|
|
22912
|
+
function describe9(err3) {
|
|
22913
|
+
return err3 instanceof Error ? err3.message : String(err3);
|
|
21058
22914
|
}
|
|
21059
22915
|
var AppearanceStore = class {
|
|
21060
22916
|
constructor(filePath = appearancePath()) {
|
|
@@ -21109,9 +22965,9 @@ var AppearanceStore = class {
|
|
|
21109
22965
|
this.prefs = {};
|
|
21110
22966
|
try {
|
|
21111
22967
|
rmSync(this.filePath, { force: true });
|
|
21112
|
-
} catch (
|
|
22968
|
+
} catch (err3) {
|
|
21113
22969
|
this.writeErrors.push(
|
|
21114
|
-
(lang) => t("appearance.write_failed", { path: this.filePath, reason: describe9(
|
|
22970
|
+
(lang) => t("appearance.write_failed", { path: this.filePath, reason: describe9(err3) }, lang)
|
|
21115
22971
|
);
|
|
21116
22972
|
}
|
|
21117
22973
|
}
|
|
@@ -21121,9 +22977,9 @@ var AppearanceStore = class {
|
|
|
21121
22977
|
let parsed;
|
|
21122
22978
|
try {
|
|
21123
22979
|
parsed = JSON.parse(readFileSync(this.filePath, "utf-8"));
|
|
21124
|
-
} catch (
|
|
22980
|
+
} catch (err3) {
|
|
21125
22981
|
this.loadErrors.push(
|
|
21126
|
-
(lang) => t("appearance.unreadable", { path: this.filePath, reason: describe9(
|
|
22982
|
+
(lang) => t("appearance.unreadable", { path: this.filePath, reason: describe9(err3) }, lang)
|
|
21127
22983
|
);
|
|
21128
22984
|
return;
|
|
21129
22985
|
}
|
|
@@ -21172,10 +23028,10 @@ var AppearanceStore = class {
|
|
|
21172
23028
|
mkdirSync(dirname(this.filePath), { recursive: true });
|
|
21173
23029
|
writeFileSync(tmp, body2, { encoding: "utf-8", mode: 384 });
|
|
21174
23030
|
renameSync(tmp, this.filePath);
|
|
21175
|
-
} catch (
|
|
23031
|
+
} catch (err3) {
|
|
21176
23032
|
rmSync(tmp, { force: true });
|
|
21177
23033
|
this.writeErrors.push(
|
|
21178
|
-
(lang) => t("appearance.write_failed", { path: this.filePath, reason: describe9(
|
|
23034
|
+
(lang) => t("appearance.write_failed", { path: this.filePath, reason: describe9(err3) }, lang)
|
|
21179
23035
|
);
|
|
21180
23036
|
}
|
|
21181
23037
|
}
|
|
@@ -21931,7 +23787,7 @@ function suggestRuleFromApproval(request) {
|
|
|
21931
23787
|
// src/schedule/store.ts
|
|
21932
23788
|
init_trigger();
|
|
21933
23789
|
var NS4 = "schedule";
|
|
21934
|
-
var
|
|
23790
|
+
var MIGRATIONS4 = [
|
|
21935
23791
|
{
|
|
21936
23792
|
id: "schedule-baseline",
|
|
21937
23793
|
version: 1,
|
|
@@ -22018,10 +23874,10 @@ var MIGRATIONS3 = [
|
|
|
22018
23874
|
var ScheduleStore = class {
|
|
22019
23875
|
db;
|
|
22020
23876
|
path;
|
|
22021
|
-
constructor(
|
|
22022
|
-
this.path =
|
|
23877
|
+
constructor(dbPath2) {
|
|
23878
|
+
this.path = dbPath2;
|
|
22023
23879
|
this.db = openDatabase(this.path);
|
|
22024
|
-
migrate(this.db, NS4,
|
|
23880
|
+
migrate(this.db, NS4, MIGRATIONS4);
|
|
22025
23881
|
}
|
|
22026
23882
|
get connection() {
|
|
22027
23883
|
return this.db;
|
|
@@ -22399,8 +24255,8 @@ function pidAlive(pid) {
|
|
|
22399
24255
|
try {
|
|
22400
24256
|
process.kill(pid, 0);
|
|
22401
24257
|
return true;
|
|
22402
|
-
} catch (
|
|
22403
|
-
return
|
|
24258
|
+
} catch (err3) {
|
|
24259
|
+
return err3.code === "EPERM";
|
|
22404
24260
|
}
|
|
22405
24261
|
}
|
|
22406
24262
|
function acquireScheduleLock(db, scheduleId, clock2 = Date.now) {
|
|
@@ -22430,8 +24286,8 @@ function acquireScheduleLock(db, scheduleId, clock2 = Date.now) {
|
|
|
22430
24286
|
db.prepare(
|
|
22431
24287
|
"UPDATE schedule_locks SET heartbeat_at = ? WHERE schedule_id = ? AND pid = ? AND host = ?"
|
|
22432
24288
|
).run(clock2(), scheduleId, pid, host);
|
|
22433
|
-
} catch (
|
|
22434
|
-
log4.debug("lock heartbeat write failed", { scheduleId, err: String(
|
|
24289
|
+
} catch (err3) {
|
|
24290
|
+
log4.debug("lock heartbeat write failed", { scheduleId, err: String(err3) });
|
|
22435
24291
|
}
|
|
22436
24292
|
}, LOCK_HEARTBEAT_MS);
|
|
22437
24293
|
beat.unref?.();
|
|
@@ -22447,8 +24303,8 @@ function acquireScheduleLock(db, scheduleId, clock2 = Date.now) {
|
|
|
22447
24303
|
db.prepare(
|
|
22448
24304
|
"DELETE FROM schedule_locks WHERE schedule_id = ? AND pid = ? AND host = ?"
|
|
22449
24305
|
).run(scheduleId, pid, host);
|
|
22450
|
-
} catch (
|
|
22451
|
-
log4.debug("lock release failed", { scheduleId, err: String(
|
|
24306
|
+
} catch (err3) {
|
|
24307
|
+
log4.debug("lock release failed", { scheduleId, err: String(err3) });
|
|
22452
24308
|
}
|
|
22453
24309
|
}
|
|
22454
24310
|
}
|
|
@@ -22878,10 +24734,10 @@ function loadPolicyRules(dir) {
|
|
|
22878
24734
|
let files;
|
|
22879
24735
|
try {
|
|
22880
24736
|
files = readdirSync(dir).filter((f) => f.endsWith(".toml"));
|
|
22881
|
-
} catch (
|
|
24737
|
+
} catch (err3) {
|
|
22882
24738
|
return {
|
|
22883
24739
|
rules: [],
|
|
22884
|
-
issues: [{ path: dir, message: t("policy_load.dir_read_failed", { reason: reason6(
|
|
24740
|
+
issues: [{ path: dir, message: t("policy_load.dir_read_failed", { reason: reason6(err3) }) }]
|
|
22885
24741
|
};
|
|
22886
24742
|
}
|
|
22887
24743
|
const rules = [];
|
|
@@ -22890,10 +24746,10 @@ function loadPolicyRules(dir) {
|
|
|
22890
24746
|
let content;
|
|
22891
24747
|
try {
|
|
22892
24748
|
content = readFileSync(join(dir, file), "utf-8");
|
|
22893
|
-
} catch (
|
|
24749
|
+
} catch (err3) {
|
|
22894
24750
|
issues.push({
|
|
22895
24751
|
path: file,
|
|
22896
|
-
message: t("policy_load.file_read_failed", { reason: reason6(
|
|
24752
|
+
message: t("policy_load.file_read_failed", { reason: reason6(err3) })
|
|
22897
24753
|
});
|
|
22898
24754
|
continue;
|
|
22899
24755
|
}
|
|
@@ -23016,8 +24872,8 @@ function unescapeTomlString(s) {
|
|
|
23016
24872
|
function preview2(line) {
|
|
23017
24873
|
return line.length > 40 ? `${line.slice(0, 40)}\u2026` : line;
|
|
23018
24874
|
}
|
|
23019
|
-
function reason6(
|
|
23020
|
-
return
|
|
24875
|
+
function reason6(err3) {
|
|
24876
|
+
return err3 instanceof Error ? err3.message : String(err3);
|
|
23021
24877
|
}
|
|
23022
24878
|
var MODULE3 = "Policy";
|
|
23023
24879
|
function resolvePolicyDirs(opts) {
|
|
@@ -23738,12 +25594,12 @@ function loadLexiconDir(dir, source) {
|
|
|
23738
25594
|
let files;
|
|
23739
25595
|
try {
|
|
23740
25596
|
files = readdirSync(dir).filter((f) => f.endsWith(".txt"));
|
|
23741
|
-
} catch (
|
|
25597
|
+
} catch (err3) {
|
|
23742
25598
|
return {
|
|
23743
25599
|
rules: [],
|
|
23744
25600
|
exempt: [],
|
|
23745
25601
|
issues: [
|
|
23746
|
-
{ path: dir, message: t("compliance_load.dir_read_failed", { reason: reason7(
|
|
25602
|
+
{ path: dir, message: t("compliance_load.dir_read_failed", { reason: reason7(err3) }) }
|
|
23747
25603
|
]
|
|
23748
25604
|
};
|
|
23749
25605
|
}
|
|
@@ -23762,10 +25618,10 @@ function loadLexiconDir(dir, source) {
|
|
|
23762
25618
|
let content;
|
|
23763
25619
|
try {
|
|
23764
25620
|
content = readFileSync(join(dir, file), "utf-8");
|
|
23765
|
-
} catch (
|
|
25621
|
+
} catch (err3) {
|
|
23766
25622
|
out.issues.push({
|
|
23767
25623
|
path: file,
|
|
23768
|
-
message: t("compliance_load.file_read_failed", { reason: reason7(
|
|
25624
|
+
message: t("compliance_load.file_read_failed", { reason: reason7(err3) })
|
|
23769
25625
|
});
|
|
23770
25626
|
continue;
|
|
23771
25627
|
}
|
|
@@ -23812,12 +25668,12 @@ function regexError(pattern) {
|
|
|
23812
25668
|
try {
|
|
23813
25669
|
new RegExp(pattern, "gu");
|
|
23814
25670
|
return void 0;
|
|
23815
|
-
} catch (
|
|
23816
|
-
return reason7(
|
|
25671
|
+
} catch (err3) {
|
|
25672
|
+
return reason7(err3);
|
|
23817
25673
|
}
|
|
23818
25674
|
}
|
|
23819
|
-
function reason7(
|
|
23820
|
-
return
|
|
25675
|
+
function reason7(err3) {
|
|
25676
|
+
return err3 instanceof Error ? err3.message : String(err3);
|
|
23821
25677
|
}
|
|
23822
25678
|
var MODULE4 = "Compliance";
|
|
23823
25679
|
function resolveComplianceDirs(opts) {
|
|
@@ -23887,7 +25743,7 @@ function runCommandHook(config, event, workDir) {
|
|
|
23887
25743
|
let stdout = "";
|
|
23888
25744
|
let stderr = "";
|
|
23889
25745
|
let settled = false;
|
|
23890
|
-
const failToStart = (
|
|
25746
|
+
const failToStart = (err3) => {
|
|
23891
25747
|
if (settled) return;
|
|
23892
25748
|
settled = true;
|
|
23893
25749
|
resolve17({
|
|
@@ -23895,7 +25751,7 @@ function runCommandHook(config, event, workDir) {
|
|
|
23895
25751
|
stdout,
|
|
23896
25752
|
stderr,
|
|
23897
25753
|
blocked: false,
|
|
23898
|
-
rejectReason: t("hook_load.spawn_failed", { message:
|
|
25754
|
+
rejectReason: t("hook_load.spawn_failed", { message: err3.message }),
|
|
23899
25755
|
sandbox
|
|
23900
25756
|
});
|
|
23901
25757
|
};
|
|
@@ -23971,9 +25827,9 @@ function runCommandHook(config, event, workDir) {
|
|
|
23971
25827
|
...failure ? { failure } : {}
|
|
23972
25828
|
});
|
|
23973
25829
|
});
|
|
23974
|
-
child.on("error", (
|
|
25830
|
+
child.on("error", (err3) => {
|
|
23975
25831
|
clearTimeout(timer);
|
|
23976
|
-
failToStart(
|
|
25832
|
+
failToStart(err3);
|
|
23977
25833
|
});
|
|
23978
25834
|
const input = JSON.stringify({
|
|
23979
25835
|
session_id: event.sessionId,
|
|
@@ -24079,8 +25935,8 @@ var HookManager = class {
|
|
|
24079
25935
|
if (result.blocked) {
|
|
24080
25936
|
return { blocked: true, reason: result.rejectReason || t("hook_load.rejected") };
|
|
24081
25937
|
}
|
|
24082
|
-
} catch (
|
|
24083
|
-
this.log("warn", `[HookManager] ${type} \u7684 command hook \u6267\u884C\u5F02\u5E38: ${describe12(
|
|
25938
|
+
} catch (err3) {
|
|
25939
|
+
this.log("warn", `[HookManager] ${type} \u7684 command hook \u6267\u884C\u5F02\u5E38: ${describe12(err3)}`, {
|
|
24084
25940
|
hookType: type,
|
|
24085
25941
|
command: config.command
|
|
24086
25942
|
});
|
|
@@ -24097,8 +25953,8 @@ var HookManager = class {
|
|
|
24097
25953
|
new Promise(
|
|
24098
25954
|
(_, reject2) => setTimeout(() => reject2(new Error("Hook timeout")), HOOK_TIMEOUT_MS)
|
|
24099
25955
|
)
|
|
24100
|
-
]).catch((
|
|
24101
|
-
this.log("warn", `[HookManager] ${type} (${reg.plugin}) \u5931\u8D25: ${describe12(
|
|
25956
|
+
]).catch((err3) => {
|
|
25957
|
+
this.log("warn", `[HookManager] ${type} (${reg.plugin}) \u5931\u8D25: ${describe12(err3)}`, {
|
|
24102
25958
|
hookType: type,
|
|
24103
25959
|
plugin: reg.plugin
|
|
24104
25960
|
});
|
|
@@ -24109,8 +25965,8 @@ var HookManager = class {
|
|
|
24109
25965
|
for (const entry of cmdEntries) {
|
|
24110
25966
|
if (!matchesHook(entry.matcher, event)) continue;
|
|
24111
25967
|
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(
|
|
25968
|
+
runCommandHook(config, event, ctx.workDir).then((result) => reportIfNotRun(this.log, type, config, result)).catch((err3) => {
|
|
25969
|
+
this.log("warn", `[HookManager] ${type} \u7684 command hook \u5F02\u6B65\u5F02\u5E38: ${describe12(err3)}`, {
|
|
24114
25970
|
hookType: type,
|
|
24115
25971
|
command: config.command
|
|
24116
25972
|
});
|
|
@@ -24130,8 +25986,8 @@ var HookManager = class {
|
|
|
24130
25986
|
)
|
|
24131
25987
|
]);
|
|
24132
25988
|
if (result !== null && result !== void 0) return result;
|
|
24133
|
-
} catch (
|
|
24134
|
-
this.log("warn", `[HookManager] ${type} (${reg.plugin}) \u5931\u8D25: ${describe12(
|
|
25989
|
+
} catch (err3) {
|
|
25990
|
+
this.log("warn", `[HookManager] ${type} (${reg.plugin}) \u5931\u8D25: ${describe12(err3)}`, {
|
|
24135
25991
|
hookType: type,
|
|
24136
25992
|
plugin: reg.plugin
|
|
24137
25993
|
});
|
|
@@ -24151,8 +26007,8 @@ var HookManager = class {
|
|
|
24151
26007
|
)
|
|
24152
26008
|
]);
|
|
24153
26009
|
if (result) results.push(result);
|
|
24154
|
-
} catch (
|
|
24155
|
-
this.log("warn", `[HookManager] ${type} (${reg.plugin}) \u5931\u8D25: ${describe12(
|
|
26010
|
+
} catch (err3) {
|
|
26011
|
+
this.log("warn", `[HookManager] ${type} (${reg.plugin}) \u5931\u8D25: ${describe12(err3)}`, {
|
|
24156
26012
|
hookType: type,
|
|
24157
26013
|
plugin: reg.plugin
|
|
24158
26014
|
});
|
|
@@ -24168,8 +26024,8 @@ var HookManager = class {
|
|
|
24168
26024
|
reportIfNotRun(this.log, type, config, result);
|
|
24169
26025
|
const verdict = verdictOf2(result);
|
|
24170
26026
|
if (verdict) results.push(verdict);
|
|
24171
|
-
} catch (
|
|
24172
|
-
this.log("warn", `[HookManager] ${type} \u7684 command hook \u6267\u884C\u5F02\u5E38: ${describe12(
|
|
26027
|
+
} catch (err3) {
|
|
26028
|
+
this.log("warn", `[HookManager] ${type} \u7684 command hook \u6267\u884C\u5F02\u5E38: ${describe12(err3)}`, {
|
|
24173
26029
|
hookType: type,
|
|
24174
26030
|
command: config.command
|
|
24175
26031
|
});
|
|
@@ -24185,8 +26041,8 @@ var HookManager = class {
|
|
|
24185
26041
|
return [...list].sort((a, b) => a.priority - b.priority);
|
|
24186
26042
|
}
|
|
24187
26043
|
};
|
|
24188
|
-
function describe12(
|
|
24189
|
-
return
|
|
26044
|
+
function describe12(err3) {
|
|
26045
|
+
return err3 instanceof Error ? err3.message : String(err3);
|
|
24190
26046
|
}
|
|
24191
26047
|
function verdictOf2(result) {
|
|
24192
26048
|
const action = result.output?.["action"];
|
|
@@ -24738,8 +26594,8 @@ function readHooksFile(path, issues, opts = {}) {
|
|
|
24738
26594
|
let raw;
|
|
24739
26595
|
try {
|
|
24740
26596
|
raw = JSON.parse(readFileSync(path, "utf-8"));
|
|
24741
|
-
} catch (
|
|
24742
|
-
const reason9 =
|
|
26597
|
+
} catch (err3) {
|
|
26598
|
+
const reason9 = err3.message.split("\n")[0] ?? t("hook_load.unknown_error");
|
|
24743
26599
|
issues.push({ path, message: t("hook_load.bad_json", { reason: reason9 }) });
|
|
24744
26600
|
return void 0;
|
|
24745
26601
|
}
|
|
@@ -24954,8 +26810,8 @@ function readEntries2(dir, label, issues, lang) {
|
|
|
24954
26810
|
isDir: e.isDirectory(),
|
|
24955
26811
|
isFile: e.isFile()
|
|
24956
26812
|
}));
|
|
24957
|
-
} catch (
|
|
24958
|
-
const reason9 =
|
|
26813
|
+
} catch (err3) {
|
|
26814
|
+
const reason9 = err3 instanceof Error ? err3.message : String(err3);
|
|
24959
26815
|
issues.push({ path: label, message: t("skill.import_read_failed", { reason: reason9 }, lang) });
|
|
24960
26816
|
return [];
|
|
24961
26817
|
}
|
|
@@ -25070,10 +26926,10 @@ function scanOneDir(spec, skills, issues) {
|
|
|
25070
26926
|
let categories;
|
|
25071
26927
|
try {
|
|
25072
26928
|
categories = readdirSync(spec.dir, { withFileTypes: true });
|
|
25073
|
-
} catch (
|
|
26929
|
+
} catch (err3) {
|
|
25074
26930
|
issues.push({
|
|
25075
26931
|
path: spec.dir,
|
|
25076
|
-
message: t("skill_load.dir_read_failed", { reason: reason8(
|
|
26932
|
+
message: t("skill_load.dir_read_failed", { reason: reason8(err3) })
|
|
25077
26933
|
});
|
|
25078
26934
|
return;
|
|
25079
26935
|
}
|
|
@@ -25083,10 +26939,10 @@ function scanOneDir(spec, skills, issues) {
|
|
|
25083
26939
|
let entries2;
|
|
25084
26940
|
try {
|
|
25085
26941
|
entries2 = readdirSync(catPath, { withFileTypes: true });
|
|
25086
|
-
} catch (
|
|
26942
|
+
} catch (err3) {
|
|
25087
26943
|
issues.push({
|
|
25088
26944
|
path: cat.name,
|
|
25089
|
-
message: t("skill_load.category_read_failed", { reason: reason8(
|
|
26945
|
+
message: t("skill_load.category_read_failed", { reason: reason8(err3) })
|
|
25090
26946
|
});
|
|
25091
26947
|
continue;
|
|
25092
26948
|
}
|
|
@@ -25106,8 +26962,8 @@ function loadOne(mdFile, catPath, category, dirName, spec, skills, issues) {
|
|
|
25106
26962
|
try {
|
|
25107
26963
|
raw = readFileSync(mdFile, "utf-8");
|
|
25108
26964
|
stat5 = statSync(mdFile);
|
|
25109
|
-
} catch (
|
|
25110
|
-
issues.push({ path: label, message: t("skill_load.read_failed", { reason: reason8(
|
|
26965
|
+
} catch (err3) {
|
|
26966
|
+
issues.push({ path: label, message: t("skill_load.read_failed", { reason: reason8(err3) }) });
|
|
25111
26967
|
return;
|
|
25112
26968
|
}
|
|
25113
26969
|
const parsed = parseSkillFrontmatter(raw, label);
|
|
@@ -25144,8 +27000,8 @@ function loadOne(mdFile, catPath, category, dirName, spec, skills, issues) {
|
|
|
25144
27000
|
source: "manual"
|
|
25145
27001
|
});
|
|
25146
27002
|
}
|
|
25147
|
-
function reason8(
|
|
25148
|
-
return
|
|
27003
|
+
function reason8(err3) {
|
|
27004
|
+
return err3 instanceof Error ? err3.message : String(err3);
|
|
25149
27005
|
}
|
|
25150
27006
|
// src/skill/manager.ts
|
|
25151
27007
|
var SKILLS_DIR = join(homedir(), ".epoch", "skills");
|
|
@@ -25593,17 +27449,17 @@ function swapInto(from, old, dest, skillsDir) {
|
|
|
25593
27449
|
try {
|
|
25594
27450
|
mkdirSync(trash, { recursive: true });
|
|
25595
27451
|
renameSync(old, join(trash, "old"));
|
|
25596
|
-
} catch (
|
|
27452
|
+
} catch (err3) {
|
|
25597
27453
|
rmSync(trash, { recursive: true, force: true });
|
|
25598
|
-
return
|
|
27454
|
+
return err3 instanceof Error ? err3.message : String(err3);
|
|
25599
27455
|
}
|
|
25600
27456
|
try {
|
|
25601
27457
|
mkdirSync(dirname(dest), { recursive: true });
|
|
25602
27458
|
renameSync(from, dest);
|
|
25603
|
-
} catch (
|
|
27459
|
+
} catch (err3) {
|
|
25604
27460
|
renameSync(join(trash, "old"), old);
|
|
25605
27461
|
rmSync(trash, { recursive: true, force: true });
|
|
25606
|
-
return
|
|
27462
|
+
return err3 instanceof Error ? err3.message : String(err3);
|
|
25607
27463
|
}
|
|
25608
27464
|
rmSync(trash, { recursive: true, force: true });
|
|
25609
27465
|
return null;
|
|
@@ -25681,8 +27537,8 @@ function commit3(preview3, staged, skillsDir, lang, replace = false) {
|
|
|
25681
27537
|
mkdirSync(join(skillsDir, entry.category), { recursive: true });
|
|
25682
27538
|
renameSync(from, dest);
|
|
25683
27539
|
imported.push(entry.name);
|
|
25684
|
-
} catch (
|
|
25685
|
-
const reason9 =
|
|
27540
|
+
} catch (err3) {
|
|
27541
|
+
const reason9 = err3 instanceof Error ? err3.message : String(err3);
|
|
25686
27542
|
skipped.push({ path: label, message: t("skill.import_write_failed", { reason: reason9 }, lang) });
|
|
25687
27543
|
}
|
|
25688
27544
|
}
|
|
@@ -25769,8 +27625,8 @@ var SkillLearner = class {
|
|
|
25769
27625
|
messages: [{ role: "user", content: buildLearningPrompt(ctx) }]
|
|
25770
27626
|
});
|
|
25771
27627
|
text = result.text;
|
|
25772
|
-
} catch (
|
|
25773
|
-
return { created: false, reason: "provider-error", error: messageOf2(
|
|
27628
|
+
} catch (err3) {
|
|
27629
|
+
return { created: false, reason: "provider-error", error: messageOf2(err3) };
|
|
25774
27630
|
}
|
|
25775
27631
|
return this.parseAndCreate(text);
|
|
25776
27632
|
}
|
|
@@ -25803,13 +27659,13 @@ var SkillLearner = class {
|
|
|
25803
27659
|
try {
|
|
25804
27660
|
await this.skillSystem.create(declared, parsed.content, category);
|
|
25805
27661
|
return { created: true, skillName: declared };
|
|
25806
|
-
} catch (
|
|
25807
|
-
return { created: false, reason: "create-failed", error: messageOf2(
|
|
27662
|
+
} catch (err3) {
|
|
27663
|
+
return { created: false, reason: "create-failed", error: messageOf2(err3) };
|
|
25808
27664
|
}
|
|
25809
27665
|
}
|
|
25810
27666
|
};
|
|
25811
|
-
function messageOf2(
|
|
25812
|
-
return
|
|
27667
|
+
function messageOf2(err3) {
|
|
27668
|
+
return err3 instanceof Error ? err3.message : String(err3);
|
|
25813
27669
|
}
|
|
25814
27670
|
var MAX_FILES = 2e4;
|
|
25815
27671
|
var SKIP_DIRS = /* @__PURE__ */ new Set([
|
|
@@ -26082,11 +27938,11 @@ async function openArtifact(path, homeDir) {
|
|
|
26082
27938
|
const child = spawn(launch.command, launch.args, { stdio: "ignore", detached: true });
|
|
26083
27939
|
child.on(
|
|
26084
27940
|
"error",
|
|
26085
|
-
(
|
|
27941
|
+
(err3) => fail9(
|
|
26086
27942
|
new Error(
|
|
26087
27943
|
t("artifact.open_launch_failed_detail", {
|
|
26088
27944
|
reason: describeArtifactRefusal("launch-failed"),
|
|
26089
|
-
message:
|
|
27945
|
+
message: err3.message
|
|
26090
27946
|
})
|
|
26091
27947
|
)
|
|
26092
27948
|
)
|
|
@@ -26095,12 +27951,12 @@ async function openArtifact(path, homeDir) {
|
|
|
26095
27951
|
child.unref();
|
|
26096
27952
|
done2();
|
|
26097
27953
|
});
|
|
26098
|
-
} catch (
|
|
27954
|
+
} catch (err3) {
|
|
26099
27955
|
fail9(
|
|
26100
27956
|
new Error(
|
|
26101
27957
|
t("artifact.open_launch_failed_detail", {
|
|
26102
27958
|
reason: describeArtifactRefusal("launch-failed"),
|
|
26103
|
-
message: String(
|
|
27959
|
+
message: String(err3)
|
|
26104
27960
|
})
|
|
26105
27961
|
)
|
|
26106
27962
|
);
|
|
@@ -26439,8 +28295,8 @@ ${extra}` : withGoal;
|
|
|
26439
28295
|
var FILE_VERSION5 = 1;
|
|
26440
28296
|
var LEVELS = ["trusted", "untrusted"];
|
|
26441
28297
|
var SCOPES = ["directory", "directory-tree"];
|
|
26442
|
-
function describe14(
|
|
26443
|
-
return
|
|
28298
|
+
function describe14(err3) {
|
|
28299
|
+
return err3 instanceof Error ? err3.message : String(err3);
|
|
26444
28300
|
}
|
|
26445
28301
|
function covers(base2, target, scope) {
|
|
26446
28302
|
if (samePath(base2, target)) return true;
|
|
@@ -26511,18 +28367,18 @@ var TrustManager = class {
|
|
|
26511
28367
|
let raw;
|
|
26512
28368
|
try {
|
|
26513
28369
|
raw = readFileSync(this.filePath, "utf-8");
|
|
26514
|
-
} catch (
|
|
28370
|
+
} catch (err3) {
|
|
26515
28371
|
this.loadErrors.push(
|
|
26516
|
-
t("trust_gate.record_read_failed", { path: this.filePath, reason: describe14(
|
|
28372
|
+
t("trust_gate.record_read_failed", { path: this.filePath, reason: describe14(err3) })
|
|
26517
28373
|
);
|
|
26518
28374
|
return;
|
|
26519
28375
|
}
|
|
26520
28376
|
let parsed;
|
|
26521
28377
|
try {
|
|
26522
28378
|
parsed = JSON.parse(raw);
|
|
26523
|
-
} catch (
|
|
28379
|
+
} catch (err3) {
|
|
26524
28380
|
this.loadErrors.push(
|
|
26525
|
-
t("trust_gate.record_bad_json", { path: this.filePath, reason: describe14(
|
|
28381
|
+
t("trust_gate.record_bad_json", { path: this.filePath, reason: describe14(err3) })
|
|
26526
28382
|
);
|
|
26527
28383
|
return;
|
|
26528
28384
|
}
|
|
@@ -26568,10 +28424,10 @@ var TrustManager = class {
|
|
|
26568
28424
|
try {
|
|
26569
28425
|
writeFileSync(tmp, body2, { encoding: "utf-8", mode: 384 });
|
|
26570
28426
|
renameSync(tmp, this.filePath);
|
|
26571
|
-
} catch (
|
|
28427
|
+
} catch (err3) {
|
|
26572
28428
|
rmSync(tmp, { force: true });
|
|
26573
28429
|
throw new Error(
|
|
26574
|
-
t("trust_gate.record_write_failed", { path: this.filePath, reason: describe14(
|
|
28430
|
+
t("trust_gate.record_write_failed", { path: this.filePath, reason: describe14(err3) })
|
|
26575
28431
|
);
|
|
26576
28432
|
}
|
|
26577
28433
|
}
|
|
@@ -26718,4 +28574,4 @@ function hasDedicatedExecContent(inv) {
|
|
|
26718
28574
|
* `--tree` 的命令帮助里,让用户自己知道 `--tree` 意味着什么。
|
|
26719
28575
|
*/
|
|
26720
28576
|
|
|
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 };
|
|
28577
|
+
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, DEFAULT_MAX_RUNNING_MEMBERS, DEFAULT_MAX_WOKEN_SESSIONS, 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 };
|