@moonshot-ai/kimi-code 0.13.0 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/main.mjs +1813 -146
- package/package.json +3 -3
package/dist/main.mjs
CHANGED
|
@@ -8220,15 +8220,16 @@ const OPENAI_VISION_TOOL_PREFIXES = [
|
|
|
8220
8220
|
"gpt-4.1",
|
|
8221
8221
|
"gpt-4.5"
|
|
8222
8222
|
];
|
|
8223
|
-
const
|
|
8223
|
+
const CLAUDE_VISION_TOOL_PREFIXES = [
|
|
8224
8224
|
"claude-3-",
|
|
8225
8225
|
"claude-3.5-",
|
|
8226
8226
|
"claude-3.7-"
|
|
8227
8227
|
];
|
|
8228
|
-
const
|
|
8228
|
+
const CLAUDE_THINKING_VISION_TOOL_PREFIXES = [
|
|
8229
8229
|
"claude-opus-4",
|
|
8230
8230
|
"claude-sonnet-4",
|
|
8231
|
-
"claude-haiku-4"
|
|
8231
|
+
"claude-haiku-4",
|
|
8232
|
+
"claude-fable"
|
|
8232
8233
|
];
|
|
8233
8234
|
const GEMINI_CATALOGUED_PREFIXES = [
|
|
8234
8235
|
"gemini-1.5-pro",
|
|
@@ -8316,10 +8317,10 @@ const OPENAI_RESPONSES_CAPABILITY_CATALOG = [{
|
|
|
8316
8317
|
capability: OPENAI_VISION_TOOL_CAPABILITY
|
|
8317
8318
|
}];
|
|
8318
8319
|
const ANTHROPIC_CAPABILITY_CATALOG = [{
|
|
8319
|
-
matches: (name) => hasPrefix(name,
|
|
8320
|
+
matches: (name) => hasPrefix(name, CLAUDE_VISION_TOOL_PREFIXES),
|
|
8320
8321
|
capability: ANTHROPIC_VISION_TOOL_CAPABILITY
|
|
8321
8322
|
}, {
|
|
8322
|
-
matches: (name) => hasPrefix(name,
|
|
8323
|
+
matches: (name) => hasPrefix(name, CLAUDE_THINKING_VISION_TOOL_PREFIXES),
|
|
8323
8324
|
capability: ANTHROPIC_THINKING_VISION_TOOL_CAPABILITY
|
|
8324
8325
|
}];
|
|
8325
8326
|
function normalizeModelName(modelName) {
|
|
@@ -8552,6 +8553,7 @@ const ANTHROPIC_TOOL_CALL_ID_POLICY = {
|
|
|
8552
8553
|
* family's baseline rather than the generic fallback.
|
|
8553
8554
|
*/
|
|
8554
8555
|
const CEILING_BY_FAMILY_VERSION = {
|
|
8556
|
+
"fable-5": 128e3,
|
|
8555
8557
|
"opus-4-7": 128e3,
|
|
8556
8558
|
"opus-4-6": 128e3,
|
|
8557
8559
|
"opus-4-5": 64e3,
|
|
@@ -8573,7 +8575,7 @@ const CEILING_BY_FAMILY_VERSION = {
|
|
|
8573
8575
|
"haiku-3": 4096
|
|
8574
8576
|
};
|
|
8575
8577
|
const FALLBACK_MAX_TOKENS = 32e3;
|
|
8576
|
-
const FAMILY_FIRST_RE = /(opus|sonnet|haiku)[-._](\d{1,2})(?!\d)(?:[-._](\d{1,2})(?!\d))?/;
|
|
8578
|
+
const FAMILY_FIRST_RE = /(opus|sonnet|haiku|fable)[-._](\d{1,2})(?!\d)(?:[-._](\d{1,2})(?!\d))?/;
|
|
8577
8579
|
const VERSION_FIRST_RE = /(\d{1,2})[-._](\d{1,2})[-._](opus|sonnet|haiku)/;
|
|
8578
8580
|
const BARE_FAMILY_RE = /(\d{1,2})[-._](opus|sonnet|haiku)/;
|
|
8579
8581
|
/**
|
|
@@ -8660,10 +8662,10 @@ function versionAtLeast(version, minimum) {
|
|
|
8660
8662
|
}
|
|
8661
8663
|
function supportsAdaptiveThinking(model) {
|
|
8662
8664
|
const version = parseClaudeAliasVersion(model);
|
|
8663
|
-
if (version === null
|
|
8665
|
+
if (version === null) return false;
|
|
8664
8666
|
return versionAtLeast({
|
|
8665
8667
|
major: version.major,
|
|
8666
|
-
minor: version.minor
|
|
8668
|
+
minor: version.minor ?? 0
|
|
8667
8669
|
}, ADAPTIVE_MIN_VERSION);
|
|
8668
8670
|
}
|
|
8669
8671
|
function isOpus47(model) {
|
|
@@ -8672,6 +8674,9 @@ function isOpus47(model) {
|
|
|
8672
8674
|
const version = parseVersion(match);
|
|
8673
8675
|
return version.major === 4 && version.minor === 7;
|
|
8674
8676
|
}
|
|
8677
|
+
function isFableModel(model) {
|
|
8678
|
+
return parseClaudeAliasVersion(model)?.family === "fable";
|
|
8679
|
+
}
|
|
8675
8680
|
function supportsEffortParam(model, adaptive) {
|
|
8676
8681
|
if (adaptive) return true;
|
|
8677
8682
|
const normalized = model.toLowerCase();
|
|
@@ -8679,7 +8684,7 @@ function supportsEffortParam(model, adaptive) {
|
|
|
8679
8684
|
}
|
|
8680
8685
|
function clampEffort(effort, model, adaptive) {
|
|
8681
8686
|
if (effort === "off") return effort;
|
|
8682
|
-
if (effort === "xhigh" && !isOpus47(model)) return "high";
|
|
8687
|
+
if (effort === "xhigh" && !isOpus47(model) && !isFableModel(model)) return "high";
|
|
8683
8688
|
if (effort === "max" && !adaptive) return "high";
|
|
8684
8689
|
return effort;
|
|
8685
8690
|
}
|
|
@@ -9114,7 +9119,8 @@ var AnthropicChatProvider = class {
|
|
|
9114
9119
|
if (this._generationKwargs.temperature !== void 0) kwargs["temperature"] = this._generationKwargs.temperature;
|
|
9115
9120
|
if (this._generationKwargs.top_k !== void 0) kwargs["top_k"] = this._generationKwargs.top_k;
|
|
9116
9121
|
if (this._generationKwargs.top_p !== void 0) kwargs["top_p"] = this._generationKwargs.top_p;
|
|
9117
|
-
|
|
9122
|
+
const thinking = this._generationKwargs.thinking;
|
|
9123
|
+
if (thinking !== void 0 && !(thinking.type === "disabled" && isFableModel(this._model))) kwargs["thinking"] = thinking;
|
|
9118
9124
|
if (this._generationKwargs.output_config !== void 0) kwargs["output_config"] = this._generationKwargs.output_config;
|
|
9119
9125
|
const betas = this._generationKwargs.betaFeatures ?? [];
|
|
9120
9126
|
const extraHeaders = {};
|
|
@@ -45834,6 +45840,8 @@ const OPENAI_CHAT_TOOL_CALL_ID_POLICY = {
|
|
|
45834
45840
|
normalize: (id) => sanitizeToolCallId(id, 64),
|
|
45835
45841
|
maxLength: 64
|
|
45836
45842
|
};
|
|
45843
|
+
const TOOL_RESULT_IMAGE_PROMPT = "Attached image(s) from tool result:";
|
|
45844
|
+
const TOOL_RESULT_IMAGE_PLACEHOLDER = "(see attached image)";
|
|
45837
45845
|
function extractReasoningContent(source, explicitKey) {
|
|
45838
45846
|
if (typeof source !== "object" || source === null) return void 0;
|
|
45839
45847
|
const record = source;
|
|
@@ -45866,7 +45874,7 @@ function convertMessage$1(message, reasoningKey, toolMessageConversion) {
|
|
|
45866
45874
|
const result = { role: message.role };
|
|
45867
45875
|
if (message.role === "tool") {
|
|
45868
45876
|
const effectiveConversion = message.content.some((p) => p.type !== "text" && p.type !== "think") ? "extract_text" : toolMessageConversion;
|
|
45869
|
-
if (effectiveConversion !== null) result.content =
|
|
45877
|
+
if (effectiveConversion !== null) result.content = convertToolMessageContentForChat(message, effectiveConversion);
|
|
45870
45878
|
else {
|
|
45871
45879
|
const firstPart = nonThinkParts[0];
|
|
45872
45880
|
if (nonThinkParts.length === 1 && firstPart?.type === "text") result.content = firstPart.text;
|
|
@@ -45890,6 +45898,47 @@ function convertMessage$1(message, reasoningKey, toolMessageConversion) {
|
|
|
45890
45898
|
if (reasoningContent) result[reasoningKey ?? DEFAULT_OUTBOUND_REASONING_KEY] = reasoningContent;
|
|
45891
45899
|
return result;
|
|
45892
45900
|
}
|
|
45901
|
+
function convertToolMessageContentForChat(message, conversion) {
|
|
45902
|
+
const content = convertToolMessageContent(message, conversion);
|
|
45903
|
+
if (typeof content === "string" && content.length === 0 && message.content.some((part) => part.type === "image_url")) return TOOL_RESULT_IMAGE_PLACEHOLDER;
|
|
45904
|
+
return content;
|
|
45905
|
+
}
|
|
45906
|
+
function toolResultImageParts(message) {
|
|
45907
|
+
const images = [];
|
|
45908
|
+
for (const part of message.content) {
|
|
45909
|
+
if (part.type !== "image_url") continue;
|
|
45910
|
+
images.push({
|
|
45911
|
+
type: "image_url",
|
|
45912
|
+
image_url: part.imageUrl.id === void 0 ? { url: part.imageUrl.url } : {
|
|
45913
|
+
url: part.imageUrl.url,
|
|
45914
|
+
id: part.imageUrl.id
|
|
45915
|
+
}
|
|
45916
|
+
});
|
|
45917
|
+
}
|
|
45918
|
+
return images;
|
|
45919
|
+
}
|
|
45920
|
+
function appendToolResultImagesMessage(messages, pendingToolResultImages) {
|
|
45921
|
+
if (pendingToolResultImages.length === 0) return;
|
|
45922
|
+
messages.push({
|
|
45923
|
+
role: "user",
|
|
45924
|
+
content: [{
|
|
45925
|
+
type: "text",
|
|
45926
|
+
text: TOOL_RESULT_IMAGE_PROMPT
|
|
45927
|
+
}, ...pendingToolResultImages]
|
|
45928
|
+
});
|
|
45929
|
+
pendingToolResultImages.length = 0;
|
|
45930
|
+
}
|
|
45931
|
+
function convertHistoryMessages(history, reasoningKey, toolMessageConversion) {
|
|
45932
|
+
const messages = [];
|
|
45933
|
+
const pendingToolResultImages = [];
|
|
45934
|
+
for (const msg of history) {
|
|
45935
|
+
if (msg.role !== "tool") appendToolResultImagesMessage(messages, pendingToolResultImages);
|
|
45936
|
+
messages.push(convertMessage$1(msg, reasoningKey, toolMessageConversion));
|
|
45937
|
+
if (msg.role === "tool") pendingToolResultImages.push(...toolResultImageParts(msg));
|
|
45938
|
+
}
|
|
45939
|
+
appendToolResultImagesMessage(messages, pendingToolResultImages);
|
|
45940
|
+
return messages;
|
|
45941
|
+
}
|
|
45893
45942
|
var OpenAILegacyStreamedMessage = class {
|
|
45894
45943
|
_id = null;
|
|
45895
45944
|
_usage = null;
|
|
@@ -46025,7 +46074,7 @@ var OpenAILegacyChatProvider = class {
|
|
|
46025
46074
|
content: systemPrompt
|
|
46026
46075
|
});
|
|
46027
46076
|
const normalizedHistory = normalizeToolCallIdsForProvider(history, OPENAI_CHAT_TOOL_CALL_ID_POLICY);
|
|
46028
|
-
|
|
46077
|
+
messages.push(...convertHistoryMessages(normalizedHistory, this._reasoningKey, this._toolMessageConversion));
|
|
46029
46078
|
const kwargs = normalizeGenerationKwargs(this._model, this._generationKwargs);
|
|
46030
46079
|
let reasoningEffort = this._reasoningEffort;
|
|
46031
46080
|
if (reasoningEffort === void 0 && kwargs["reasoning_effort"] === void 0) {
|
|
@@ -56514,7 +56563,12 @@ var ContextMemory = class {
|
|
|
56514
56563
|
this.deferredMessages = [];
|
|
56515
56564
|
this.agent.microCompaction.reset(this._history.length);
|
|
56516
56565
|
this.agent.emitStatusUpdated();
|
|
56517
|
-
if (!this.agent.records.restoring && (stoppedAtBoundary || removedUserCount < count)) throw new KimiError(ErrorCodes.REQUEST_INVALID,
|
|
56566
|
+
if (!this.agent.records.restoring && (stoppedAtBoundary || removedUserCount < count)) throw new KimiError(ErrorCodes.REQUEST_INVALID, formatUndoUnavailableMessage(count, removedUserCount, stoppedAtBoundary), { details: {
|
|
56567
|
+
reason: "undo_limit",
|
|
56568
|
+
requestedCount: count,
|
|
56569
|
+
undoableCount: removedUserCount,
|
|
56570
|
+
stoppedAtCompaction: stoppedAtBoundary
|
|
56571
|
+
} });
|
|
56518
56572
|
}
|
|
56519
56573
|
applyCompaction(summary) {
|
|
56520
56574
|
this.agent.records.logRecord({
|
|
@@ -56683,6 +56737,13 @@ function isRealUserPrompt(message) {
|
|
|
56683
56737
|
if (origin.kind === "skill_activation") return origin.trigger === "user-slash";
|
|
56684
56738
|
return false;
|
|
56685
56739
|
}
|
|
56740
|
+
function formatUndoUnavailableMessage(requestedCount, undoableCount, stoppedAtCompaction) {
|
|
56741
|
+
const reason = stoppedAtCompaction ? " after the last compaction" : "";
|
|
56742
|
+
return `Cannot undo ${formatPromptCount(requestedCount)}; only ${formatPromptCount(undoableCount)} can be undone in the active context${reason}.`;
|
|
56743
|
+
function formatPromptCount(count) {
|
|
56744
|
+
return `${String(count)} ${count === 1 ? "prompt" : "prompts"}`;
|
|
56745
|
+
}
|
|
56746
|
+
}
|
|
56686
56747
|
//#endregion
|
|
56687
56748
|
//#region ../../packages/agent-core/src/agent/goal/index.ts
|
|
56688
56749
|
/**
|
|
@@ -57459,6 +57520,7 @@ const HOOK_EVENT_TYPES = [
|
|
|
57459
57520
|
"UserPromptSubmit",
|
|
57460
57521
|
"Stop",
|
|
57461
57522
|
"StopFailure",
|
|
57523
|
+
"Interrupt",
|
|
57462
57524
|
"SessionStart",
|
|
57463
57525
|
"SessionEnd",
|
|
57464
57526
|
"SubagentStart",
|
|
@@ -58449,26 +58511,6 @@ var GitControlPathAccessAskPermissionPolicy = class {
|
|
|
58449
58511
|
};
|
|
58450
58512
|
}
|
|
58451
58513
|
};
|
|
58452
|
-
var CwdOutsideFileWriteAskPermissionPolicy = class {
|
|
58453
|
-
agent;
|
|
58454
|
-
name = "cwd-outside-file-write-ask";
|
|
58455
|
-
constructor(agent) {
|
|
58456
|
-
this.agent = agent;
|
|
58457
|
-
}
|
|
58458
|
-
evaluate(context) {
|
|
58459
|
-
const cwd = this.agent.config.cwd;
|
|
58460
|
-
if (cwd.length === 0) return;
|
|
58461
|
-
const pathClass = this.agent.kaos.pathClass();
|
|
58462
|
-
const access = writeFileAccesses(context).find((fileAccess) => {
|
|
58463
|
-
return !isWithinDirectory(fileAccess.path, cwd, pathClass);
|
|
58464
|
-
});
|
|
58465
|
-
if (access === void 0) return;
|
|
58466
|
-
return {
|
|
58467
|
-
kind: "ask",
|
|
58468
|
-
reason: fileAccessReason(access, { cwd_outside: true })
|
|
58469
|
-
};
|
|
58470
|
-
}
|
|
58471
|
-
};
|
|
58472
58514
|
function fileAccesses(context) {
|
|
58473
58515
|
return context.execution.accesses?.filter((access) => access.kind === "file") ?? [];
|
|
58474
58516
|
}
|
|
@@ -60689,7 +60731,6 @@ function createPermissionDecisionPolicies(agent) {
|
|
|
60689
60731
|
new PlanModeToolApprovePermissionPolicy(agent),
|
|
60690
60732
|
new SensitiveFileAccessAskPermissionPolicy(agent),
|
|
60691
60733
|
new GitControlPathAccessAskPermissionPolicy(agent),
|
|
60692
|
-
new CwdOutsideFileWriteAskPermissionPolicy(agent),
|
|
60693
60734
|
new YoloModeApprovePermissionPolicy(agent),
|
|
60694
60735
|
new SwarmModeAgentSwarmApprovePermissionPolicy(agent),
|
|
60695
60736
|
new DefaultToolApprovePermissionPolicy(),
|
|
@@ -66161,6 +66202,43 @@ function truncate$1(value, max) {
|
|
|
66161
66202
|
return value.length > max ? value.slice(0, max) : value;
|
|
66162
66203
|
}
|
|
66163
66204
|
//#endregion
|
|
66205
|
+
//#region ../../packages/agent-core/src/agent/skill/prompt.ts
|
|
66206
|
+
function renderUserSlashSkillPrompt(input) {
|
|
66207
|
+
return [
|
|
66208
|
+
`User activated the skill "${escapeXml(input.skillName)}". Follow the loaded skill instructions.`,
|
|
66209
|
+
"",
|
|
66210
|
+
renderSkillLoadedBlock({
|
|
66211
|
+
...input,
|
|
66212
|
+
trigger: "user-slash"
|
|
66213
|
+
})
|
|
66214
|
+
].join("\n");
|
|
66215
|
+
}
|
|
66216
|
+
function renderModelToolSkillPrompt(input) {
|
|
66217
|
+
return [
|
|
66218
|
+
"Skill tool loaded instructions for this request. Follow them.",
|
|
66219
|
+
"",
|
|
66220
|
+
renderSkillLoadedBlock({
|
|
66221
|
+
...input,
|
|
66222
|
+
trigger: input.trigger
|
|
66223
|
+
})
|
|
66224
|
+
].join("\n");
|
|
66225
|
+
}
|
|
66226
|
+
function renderSkillLoadedBlock(input) {
|
|
66227
|
+
return [
|
|
66228
|
+
`<kimi-skill-loaded${renderSkillAttributes(input)}>`,
|
|
66229
|
+
input.skillContent,
|
|
66230
|
+
"</kimi-skill-loaded>"
|
|
66231
|
+
].join("\n");
|
|
66232
|
+
}
|
|
66233
|
+
function renderSkillAttributes(input) {
|
|
66234
|
+
return [
|
|
66235
|
+
["name", input.skillName],
|
|
66236
|
+
["trigger", input.trigger],
|
|
66237
|
+
["source", input.skillSource],
|
|
66238
|
+
["args", input.skillArgs]
|
|
66239
|
+
].filter((item) => item[1] !== void 0).map(([name, value]) => ` ${name}="${escapeXml(value)}"`).join("");
|
|
66240
|
+
}
|
|
66241
|
+
//#endregion
|
|
66164
66242
|
//#region ../../packages/agent-core/src/agent/skill/index.ts
|
|
66165
66243
|
var SkillManager = class {
|
|
66166
66244
|
agent;
|
|
@@ -66173,12 +66251,16 @@ var SkillManager = class {
|
|
|
66173
66251
|
const skill = this.registry.getSkill(input.name);
|
|
66174
66252
|
if (skill === void 0) throw new KimiError(ErrorCodes.SKILL_NOT_FOUND, `Skill "${input.name}" was not found`);
|
|
66175
66253
|
if (!isUserActivatableSkillType(skill.metadata.type)) throw new KimiError(ErrorCodes.SKILL_TYPE_UNSUPPORTED, `Skill "${skill.name}" cannot be activated by the user`);
|
|
66176
|
-
const
|
|
66177
|
-
const
|
|
66178
|
-
const argsAttr = args ? ` args="${escapeXml(args)}"` : "";
|
|
66254
|
+
const skillArgs = input.args ?? "";
|
|
66255
|
+
const skillContent = this.registry.renderSkillPrompt(skill, skillArgs);
|
|
66179
66256
|
const wrapped = [{
|
|
66180
66257
|
type: "text",
|
|
66181
|
-
text:
|
|
66258
|
+
text: renderUserSlashSkillPrompt({
|
|
66259
|
+
skillName: skill.name,
|
|
66260
|
+
skillArgs,
|
|
66261
|
+
skillContent,
|
|
66262
|
+
skillSource: skill.source
|
|
66263
|
+
})
|
|
66182
66264
|
}];
|
|
66183
66265
|
this.recordActivation({
|
|
66184
66266
|
kind: "skill_activation",
|
|
@@ -74401,8 +74483,1283 @@ function makeInterruptedEvent(reason, attemptedSteps, activeStep, message) {
|
|
|
74401
74483
|
};
|
|
74402
74484
|
}
|
|
74403
74485
|
//#endregion
|
|
74404
|
-
//#region ../../packages/
|
|
74486
|
+
//#region ../../packages/protocol/src/error-codes.ts
|
|
74487
|
+
/**
|
|
74488
|
+
* Integer namespaces:
|
|
74489
|
+
* - 0 success
|
|
74490
|
+
* - 4xxxx 客户端错误 (HTTP-4xx analog)
|
|
74491
|
+
* - 5xxxx daemon 内部错误
|
|
74492
|
+
* - 6xxxx 工具运行时
|
|
74493
|
+
* - 7xxxx LLM provider 透传 (msg = original upstream text)
|
|
74494
|
+
* - 8xxxx MCP server 透传 (msg = original upstream text)
|
|
74495
|
+
* - 9xxxx 预留
|
|
74496
|
+
*/
|
|
74497
|
+
const ErrorCode$1 = {
|
|
74498
|
+
/** 成功 */
|
|
74499
|
+
SUCCESS: 0,
|
|
74500
|
+
/** Zod 校验失败,`details` 含字段路径列表 */
|
|
74501
|
+
VALIDATION_FAILED: 40001,
|
|
74502
|
+
/** JSON 解析失败、字段类型错 */
|
|
74503
|
+
REQUEST_MALFORMED: 40002,
|
|
74504
|
+
/** daemon 没有任何 provider 配置 */
|
|
74505
|
+
AUTH_PROVISIONING_REQUIRED: 40110,
|
|
74506
|
+
/** provider 存在但 token / api_key 缺失 */
|
|
74507
|
+
AUTH_TOKEN_MISSING: 40111,
|
|
74508
|
+
/** 刷新 token 收到 401(用户撤销了授权) */
|
|
74509
|
+
AUTH_TOKEN_UNAUTHORIZED: 40112,
|
|
74510
|
+
/** 默认 / 请求的 model 解析不到 provider */
|
|
74511
|
+
AUTH_MODEL_NOT_RESOLVED: 40113,
|
|
74512
|
+
/** session_id 不存在 */
|
|
74513
|
+
SESSION_NOT_FOUND: 40401,
|
|
74514
|
+
/** prompt_id 不存在 */
|
|
74515
|
+
PROMPT_NOT_FOUND: 40402,
|
|
74516
|
+
/** message_id 不存在 */
|
|
74517
|
+
MESSAGE_NOT_FOUND: 40403,
|
|
74518
|
+
/** approval_id 不存在 */
|
|
74519
|
+
APPROVAL_NOT_FOUND: 40404,
|
|
74520
|
+
/** question_id 不存在 */
|
|
74521
|
+
QUESTION_NOT_FOUND: 40405,
|
|
74522
|
+
/** task_id 不存在 */
|
|
74523
|
+
TASK_NOT_FOUND: 40406,
|
|
74524
|
+
/** file_id 不存在 */
|
|
74525
|
+
FILE_NOT_FOUND: 40407,
|
|
74526
|
+
/** mcp_server_id 不存在 */
|
|
74527
|
+
MCP_SERVER_NOT_FOUND: 40408,
|
|
74528
|
+
/** fs path 不存在 */
|
|
74529
|
+
FS_PATH_NOT_FOUND: 40409,
|
|
74530
|
+
/** workspace_id 不存在 */
|
|
74531
|
+
WORKSPACE_NOT_FOUND: 40410,
|
|
74532
|
+
/** fs 路径存在但当前进程无权限读取 */
|
|
74533
|
+
FS_PERMISSION_DENIED: 40411,
|
|
74534
|
+
/** provider_id 不存在 */
|
|
74535
|
+
PROVIDER_NOT_FOUND: 40412,
|
|
74536
|
+
/** model_id 不存在 */
|
|
74537
|
+
MODEL_NOT_FOUND: 40413,
|
|
74538
|
+
/** session 有正在进行的 prompt,拒绝新请求 */
|
|
74539
|
+
SESSION_BUSY: 40901,
|
|
74540
|
+
/** approval 已被其他 client 应答 */
|
|
74541
|
+
APPROVAL_ALREADY_RESOLVED: 40902,
|
|
74542
|
+
/** prompt 已结束(abort 幂等返回 0) */
|
|
74543
|
+
PROMPT_ALREADY_COMPLETED: 40903,
|
|
74544
|
+
/** task 已完结,无法取消 */
|
|
74545
|
+
TASK_ALREADY_FINISHED: 40904,
|
|
74546
|
+
/** mcp restart 时若已在 connecting/connected */
|
|
74547
|
+
MCP_ALREADY_CONNECTED: 40905,
|
|
74548
|
+
/** fs.read 请求 file,但 path 是目录 */
|
|
74549
|
+
FS_IS_DIRECTORY: 40906,
|
|
74550
|
+
/** fs.read 请求 utf-8,但 path 是二进制;client 改走 `:download` */
|
|
74551
|
+
FS_IS_BINARY: 40907,
|
|
74552
|
+
/** fs.git_status 但 session.cwd 不是 git repo */
|
|
74553
|
+
FS_GIT_UNAVAILABLE: 40908,
|
|
74554
|
+
/** 用户 ESC / 关闭面板放弃整组(client 调 `:dismiss`) */
|
|
74555
|
+
QUESTION_DISMISSED: 40909,
|
|
74556
|
+
/** 当前历史没有可 compact 的前缀 */
|
|
74557
|
+
COMPACTION_UNABLE: 40910,
|
|
74558
|
+
/** 当前历史没有足够的用户提示词可撤回 */
|
|
74559
|
+
SESSION_UNDO_UNAVAILABLE: 40911,
|
|
74560
|
+
/** approval 60s 超时 */
|
|
74561
|
+
APPROVAL_EXPIRED: 41001,
|
|
74562
|
+
/** question 60s 超时 */
|
|
74563
|
+
QUESTION_EXPIRED: 41002,
|
|
74564
|
+
/** 临时文件已过期 */
|
|
74565
|
+
FILE_EXPIRED: 41003,
|
|
74566
|
+
/** 上传超 50MB */
|
|
74567
|
+
FILE_TOO_LARGE: 41301,
|
|
74568
|
+
/** fs.read 超 10MB */
|
|
74569
|
+
FS_TOO_LARGE: 41302,
|
|
74570
|
+
/** fs.list / fs.search / fs.grep 命中超上限 */
|
|
74571
|
+
FS_TOO_MANY_RESULTS: 41303,
|
|
74572
|
+
/** path 越出 session cwd 边界 */
|
|
74573
|
+
FS_PATH_ESCAPES_SESSION: 41304,
|
|
74574
|
+
/** fs.grep 执行 >30s */
|
|
74575
|
+
FS_GREP_TIMEOUT: 41305,
|
|
74576
|
+
/** WS 单连接 watch_paths > 100 */
|
|
74577
|
+
FS_WATCH_LIMIT_EXCEEDED: 42902,
|
|
74578
|
+
/** 兜底 */
|
|
74579
|
+
INTERNAL_ERROR: 50001,
|
|
74580
|
+
/** 写入 session 持久化失败 */
|
|
74581
|
+
PERSISTENCE_FAILURE: 50003,
|
|
74582
|
+
/** tool 执行抛错 */
|
|
74583
|
+
TOOL_EXECUTION_FAILED: 60001,
|
|
74584
|
+
/** tool 在此 session 未启用 */
|
|
74585
|
+
TOOL_NOT_AVAILABLE: 60002
|
|
74586
|
+
};
|
|
74587
|
+
ErrorCode$1.SUCCESS, ErrorCode$1.VALIDATION_FAILED, ErrorCode$1.REQUEST_MALFORMED, ErrorCode$1.AUTH_PROVISIONING_REQUIRED, ErrorCode$1.AUTH_TOKEN_MISSING, ErrorCode$1.AUTH_TOKEN_UNAUTHORIZED, ErrorCode$1.AUTH_MODEL_NOT_RESOLVED, ErrorCode$1.SESSION_NOT_FOUND, ErrorCode$1.PROMPT_NOT_FOUND, ErrorCode$1.MESSAGE_NOT_FOUND, ErrorCode$1.APPROVAL_NOT_FOUND, ErrorCode$1.QUESTION_NOT_FOUND, ErrorCode$1.TASK_NOT_FOUND, ErrorCode$1.FILE_NOT_FOUND, ErrorCode$1.MCP_SERVER_NOT_FOUND, ErrorCode$1.FS_PATH_NOT_FOUND, ErrorCode$1.WORKSPACE_NOT_FOUND, ErrorCode$1.FS_PERMISSION_DENIED, ErrorCode$1.PROVIDER_NOT_FOUND, ErrorCode$1.MODEL_NOT_FOUND, ErrorCode$1.SESSION_BUSY, ErrorCode$1.APPROVAL_ALREADY_RESOLVED, ErrorCode$1.PROMPT_ALREADY_COMPLETED, ErrorCode$1.TASK_ALREADY_FINISHED, ErrorCode$1.MCP_ALREADY_CONNECTED, ErrorCode$1.FS_IS_DIRECTORY, ErrorCode$1.FS_IS_BINARY, ErrorCode$1.FS_GIT_UNAVAILABLE, ErrorCode$1.QUESTION_DISMISSED, ErrorCode$1.COMPACTION_UNABLE, ErrorCode$1.SESSION_UNDO_UNAVAILABLE, ErrorCode$1.APPROVAL_EXPIRED, ErrorCode$1.QUESTION_EXPIRED, ErrorCode$1.FILE_EXPIRED, ErrorCode$1.FILE_TOO_LARGE, ErrorCode$1.FS_TOO_LARGE, ErrorCode$1.FS_TOO_MANY_RESULTS, ErrorCode$1.FS_PATH_ESCAPES_SESSION, ErrorCode$1.FS_GREP_TIMEOUT, ErrorCode$1.FS_WATCH_LIMIT_EXCEEDED, ErrorCode$1.INTERNAL_ERROR, ErrorCode$1.PERSISTENCE_FAILURE, ErrorCode$1.TOOL_EXECUTION_FAILED, ErrorCode$1.TOOL_NOT_AVAILABLE;
|
|
74588
|
+
//#endregion
|
|
74589
|
+
//#region ../../packages/protocol/src/pagination.ts
|
|
74590
|
+
const cursorQuerySchema = z.object({
|
|
74591
|
+
before_id: z.string().min(1).optional(),
|
|
74592
|
+
after_id: z.string().min(1).optional(),
|
|
74593
|
+
page_size: z.number().int().min(1).max(100).optional()
|
|
74594
|
+
}).superRefine((value, ctx) => {
|
|
74595
|
+
if (value.before_id !== void 0 && value.after_id !== void 0) ctx.addIssue({
|
|
74596
|
+
code: "custom",
|
|
74597
|
+
message: "before_id and after_id are mutually exclusive",
|
|
74598
|
+
path: ["before_id"],
|
|
74599
|
+
params: { code: ErrorCode$1.VALIDATION_FAILED }
|
|
74600
|
+
});
|
|
74601
|
+
});
|
|
74602
|
+
const pageResponseSchema = (item) => z.object({
|
|
74603
|
+
items: z.array(item),
|
|
74604
|
+
has_more: z.boolean()
|
|
74605
|
+
});
|
|
74606
|
+
//#endregion
|
|
74607
|
+
//#region ../../packages/protocol/src/time.ts
|
|
74608
|
+
const ISO_8601_REGEX = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{1,9})?(?:Z|[+-]\d{2}(?::?\d{2})?)$/;
|
|
74609
|
+
const isoDateTimeSchema = z.string().refine((value) => ISO_8601_REGEX.test(value), { message: "must be an ISO 8601 datetime string" }).transform((value, ctx) => {
|
|
74610
|
+
const ms = Date.parse(value);
|
|
74611
|
+
if (Number.isNaN(ms)) {
|
|
74612
|
+
ctx.addIssue({
|
|
74613
|
+
code: "custom",
|
|
74614
|
+
message: "invalid ISO 8601 datetime"
|
|
74615
|
+
});
|
|
74616
|
+
return z.NEVER;
|
|
74617
|
+
}
|
|
74618
|
+
return new Date(ms).toISOString();
|
|
74619
|
+
});
|
|
74620
|
+
//#endregion
|
|
74621
|
+
//#region ../../packages/protocol/src/events.ts
|
|
74405
74622
|
const MCP_OAUTH_AUTHORIZATION_URL_TOOL_UPDATE = "mcp.oauth.authorization_url";
|
|
74623
|
+
z.discriminatedUnion("kind", [
|
|
74624
|
+
z.object({
|
|
74625
|
+
kind: z.literal("command"),
|
|
74626
|
+
command: z.string(),
|
|
74627
|
+
cwd: z.string().optional(),
|
|
74628
|
+
description: z.string().optional(),
|
|
74629
|
+
language: z.literal("bash").optional()
|
|
74630
|
+
}),
|
|
74631
|
+
z.object({
|
|
74632
|
+
kind: z.literal("file_io"),
|
|
74633
|
+
operation: z.enum([
|
|
74634
|
+
"read",
|
|
74635
|
+
"write",
|
|
74636
|
+
"edit",
|
|
74637
|
+
"glob",
|
|
74638
|
+
"grep"
|
|
74639
|
+
]),
|
|
74640
|
+
path: z.string(),
|
|
74641
|
+
detail: z.string().optional(),
|
|
74642
|
+
content: z.string().optional(),
|
|
74643
|
+
before: z.string().optional(),
|
|
74644
|
+
after: z.string().optional()
|
|
74645
|
+
}),
|
|
74646
|
+
z.object({
|
|
74647
|
+
kind: z.literal("diff"),
|
|
74648
|
+
path: z.string(),
|
|
74649
|
+
before: z.string(),
|
|
74650
|
+
after: z.string(),
|
|
74651
|
+
hunks: z.number().optional()
|
|
74652
|
+
}),
|
|
74653
|
+
z.object({
|
|
74654
|
+
kind: z.literal("search"),
|
|
74655
|
+
query: z.string(),
|
|
74656
|
+
scope: z.string().optional()
|
|
74657
|
+
}),
|
|
74658
|
+
z.object({
|
|
74659
|
+
kind: z.literal("url_fetch"),
|
|
74660
|
+
url: z.string(),
|
|
74661
|
+
method: z.string().optional()
|
|
74662
|
+
}),
|
|
74663
|
+
z.object({
|
|
74664
|
+
kind: z.literal("agent_call"),
|
|
74665
|
+
agent_name: z.string(),
|
|
74666
|
+
prompt: z.string(),
|
|
74667
|
+
background: z.boolean().optional()
|
|
74668
|
+
}),
|
|
74669
|
+
z.object({
|
|
74670
|
+
kind: z.literal("skill_call"),
|
|
74671
|
+
skill_name: z.string(),
|
|
74672
|
+
args: z.string().optional()
|
|
74673
|
+
}),
|
|
74674
|
+
z.object({
|
|
74675
|
+
kind: z.literal("todo_list"),
|
|
74676
|
+
items: z.array(z.object({
|
|
74677
|
+
title: z.string(),
|
|
74678
|
+
status: z.string()
|
|
74679
|
+
}))
|
|
74680
|
+
}),
|
|
74681
|
+
z.object({
|
|
74682
|
+
kind: z.literal("background_task"),
|
|
74683
|
+
task_id: z.string(),
|
|
74684
|
+
status: z.string(),
|
|
74685
|
+
description: z.string(),
|
|
74686
|
+
task_kind: z.string().optional()
|
|
74687
|
+
}),
|
|
74688
|
+
z.object({
|
|
74689
|
+
kind: z.literal("task_stop"),
|
|
74690
|
+
task_id: z.string(),
|
|
74691
|
+
task_description: z.string()
|
|
74692
|
+
}),
|
|
74693
|
+
z.object({
|
|
74694
|
+
kind: z.literal("plan_review"),
|
|
74695
|
+
plan: z.string(),
|
|
74696
|
+
path: z.string().optional(),
|
|
74697
|
+
options: z.array(z.object({
|
|
74698
|
+
label: z.string(),
|
|
74699
|
+
description: z.string()
|
|
74700
|
+
})).readonly().optional()
|
|
74701
|
+
}),
|
|
74702
|
+
z.object({
|
|
74703
|
+
kind: z.literal("generic"),
|
|
74704
|
+
summary: z.string(),
|
|
74705
|
+
detail: z.unknown().optional()
|
|
74706
|
+
})
|
|
74707
|
+
]);
|
|
74708
|
+
z.discriminatedUnion("kind", [
|
|
74709
|
+
z.object({
|
|
74710
|
+
kind: z.literal("command_output"),
|
|
74711
|
+
exit_code: z.number(),
|
|
74712
|
+
stdout: z.string().optional(),
|
|
74713
|
+
stderr: z.string().optional()
|
|
74714
|
+
}),
|
|
74715
|
+
z.object({
|
|
74716
|
+
kind: z.literal("file_content"),
|
|
74717
|
+
path: z.string(),
|
|
74718
|
+
content: z.string(),
|
|
74719
|
+
range: z.object({
|
|
74720
|
+
start: z.number(),
|
|
74721
|
+
end: z.number()
|
|
74722
|
+
}).optional(),
|
|
74723
|
+
truncated: z.boolean().optional()
|
|
74724
|
+
}),
|
|
74725
|
+
z.object({
|
|
74726
|
+
kind: z.literal("diff"),
|
|
74727
|
+
path: z.string(),
|
|
74728
|
+
before: z.string(),
|
|
74729
|
+
after: z.string(),
|
|
74730
|
+
hunks: z.number().optional()
|
|
74731
|
+
}),
|
|
74732
|
+
z.object({
|
|
74733
|
+
kind: z.literal("search_results"),
|
|
74734
|
+
query: z.string(),
|
|
74735
|
+
matches: z.array(z.object({
|
|
74736
|
+
file: z.string(),
|
|
74737
|
+
line: z.number(),
|
|
74738
|
+
text: z.string()
|
|
74739
|
+
}))
|
|
74740
|
+
}),
|
|
74741
|
+
z.object({
|
|
74742
|
+
kind: z.literal("url_content"),
|
|
74743
|
+
url: z.string(),
|
|
74744
|
+
status: z.number(),
|
|
74745
|
+
preview: z.string().optional(),
|
|
74746
|
+
content_type: z.string().optional()
|
|
74747
|
+
}),
|
|
74748
|
+
z.object({
|
|
74749
|
+
kind: z.literal("agent_summary"),
|
|
74750
|
+
agent_name: z.string(),
|
|
74751
|
+
result: z.string().optional(),
|
|
74752
|
+
steps: z.number().optional()
|
|
74753
|
+
}),
|
|
74754
|
+
z.object({
|
|
74755
|
+
kind: z.literal("background_task"),
|
|
74756
|
+
task_id: z.string(),
|
|
74757
|
+
status: z.string(),
|
|
74758
|
+
description: z.string()
|
|
74759
|
+
}),
|
|
74760
|
+
z.object({
|
|
74761
|
+
kind: z.literal("todo_list"),
|
|
74762
|
+
items: z.array(z.object({
|
|
74763
|
+
title: z.string(),
|
|
74764
|
+
status: z.string()
|
|
74765
|
+
}))
|
|
74766
|
+
}),
|
|
74767
|
+
z.object({
|
|
74768
|
+
kind: z.literal("structured"),
|
|
74769
|
+
data: z.unknown()
|
|
74770
|
+
}),
|
|
74771
|
+
z.object({
|
|
74772
|
+
kind: z.literal("text"),
|
|
74773
|
+
text: z.string(),
|
|
74774
|
+
truncated: z.boolean().optional()
|
|
74775
|
+
}),
|
|
74776
|
+
z.object({
|
|
74777
|
+
kind: z.literal("error"),
|
|
74778
|
+
message: z.string(),
|
|
74779
|
+
code: z.string().optional()
|
|
74780
|
+
}),
|
|
74781
|
+
z.object({
|
|
74782
|
+
kind: z.literal("generic"),
|
|
74783
|
+
summary: z.string(),
|
|
74784
|
+
detail: z.unknown().optional()
|
|
74785
|
+
})
|
|
74786
|
+
]);
|
|
74787
|
+
//#endregion
|
|
74788
|
+
//#region ../../packages/protocol/src/ws-control.ts
|
|
74789
|
+
/**
|
|
74790
|
+
* Event: { type, seq, session_id?, timestamp, payload }
|
|
74791
|
+
* Control: { type, id?, payload }
|
|
74792
|
+
* Ack: { type: 'ack', id, code, msg, payload }
|
|
74793
|
+
*/
|
|
74794
|
+
const serverHelloPayloadSchema = z.object({
|
|
74795
|
+
ws_connection_id: z.string(),
|
|
74796
|
+
heartbeat_ms: z.number().int().positive(),
|
|
74797
|
+
max_event_buffer_size: z.number().int().positive(),
|
|
74798
|
+
capabilities: z.object({
|
|
74799
|
+
event_batching: z.boolean(),
|
|
74800
|
+
compression: z.boolean()
|
|
74801
|
+
})
|
|
74802
|
+
});
|
|
74803
|
+
const serverHelloMessageSchema = z.object({
|
|
74804
|
+
type: z.literal("server_hello"),
|
|
74805
|
+
timestamp: isoDateTimeSchema,
|
|
74806
|
+
payload: serverHelloPayloadSchema
|
|
74807
|
+
});
|
|
74808
|
+
const clientHelloPayloadSchema = z.object({
|
|
74809
|
+
client_id: z.string(),
|
|
74810
|
+
subscriptions: z.array(z.string()),
|
|
74811
|
+
last_seq_by_session: z.record(z.string(), z.number().int().nonnegative()).optional()
|
|
74812
|
+
});
|
|
74813
|
+
const clientHelloMessageSchema = z.object({
|
|
74814
|
+
type: z.literal("client_hello"),
|
|
74815
|
+
id: z.string(),
|
|
74816
|
+
payload: clientHelloPayloadSchema
|
|
74817
|
+
});
|
|
74818
|
+
z.object({
|
|
74819
|
+
accepted_subscriptions: z.array(z.string()).optional(),
|
|
74820
|
+
accepted: z.array(z.string()).optional(),
|
|
74821
|
+
not_found: z.array(z.string()).optional(),
|
|
74822
|
+
resync_required: z.array(z.string())
|
|
74823
|
+
});
|
|
74824
|
+
const watchFsConfigSchema = z.object({
|
|
74825
|
+
paths: z.array(z.string()),
|
|
74826
|
+
recursive: z.boolean().optional()
|
|
74827
|
+
});
|
|
74828
|
+
const subscribePayloadSchema = z.object({
|
|
74829
|
+
session_ids: z.array(z.string()),
|
|
74830
|
+
last_seq_by_session: z.record(z.string(), z.number().int().nonnegative()).optional(),
|
|
74831
|
+
watch_fs: z.record(z.string(), watchFsConfigSchema).optional()
|
|
74832
|
+
});
|
|
74833
|
+
const subscribeMessageSchema = z.object({
|
|
74834
|
+
type: z.literal("subscribe"),
|
|
74835
|
+
id: z.string(),
|
|
74836
|
+
payload: subscribePayloadSchema
|
|
74837
|
+
});
|
|
74838
|
+
const unsubscribePayloadSchema = z.object({ session_ids: z.array(z.string()) });
|
|
74839
|
+
const unsubscribeMessageSchema = z.object({
|
|
74840
|
+
type: z.literal("unsubscribe"),
|
|
74841
|
+
id: z.string(),
|
|
74842
|
+
payload: unsubscribePayloadSchema
|
|
74843
|
+
});
|
|
74844
|
+
const watchFsAddPayloadSchema = z.object({
|
|
74845
|
+
session_id: z.string(),
|
|
74846
|
+
paths: z.array(z.string()),
|
|
74847
|
+
recursive: z.boolean().optional()
|
|
74848
|
+
});
|
|
74849
|
+
const watchFsAddMessageSchema = z.object({
|
|
74850
|
+
type: z.literal("watch_fs_add"),
|
|
74851
|
+
id: z.string(),
|
|
74852
|
+
payload: watchFsAddPayloadSchema
|
|
74853
|
+
});
|
|
74854
|
+
const watchFsRemovePayloadSchema = z.object({
|
|
74855
|
+
session_id: z.string(),
|
|
74856
|
+
paths: z.array(z.string())
|
|
74857
|
+
});
|
|
74858
|
+
const watchFsRemoveMessageSchema = z.object({
|
|
74859
|
+
type: z.literal("watch_fs_remove"),
|
|
74860
|
+
id: z.string(),
|
|
74861
|
+
payload: watchFsRemovePayloadSchema
|
|
74862
|
+
});
|
|
74863
|
+
z.object({
|
|
74864
|
+
watched_paths: z.array(z.string()).optional(),
|
|
74865
|
+
current_count: z.number().int().nonnegative().optional()
|
|
74866
|
+
});
|
|
74867
|
+
const abortPayloadSchema = z.object({
|
|
74868
|
+
session_id: z.string(),
|
|
74869
|
+
prompt_id: z.string()
|
|
74870
|
+
});
|
|
74871
|
+
const abortMessageSchema = z.object({
|
|
74872
|
+
type: z.literal("abort"),
|
|
74873
|
+
id: z.string(),
|
|
74874
|
+
payload: abortPayloadSchema
|
|
74875
|
+
});
|
|
74876
|
+
z.object({
|
|
74877
|
+
aborted: z.boolean().optional(),
|
|
74878
|
+
at_seq: z.number().int().nonnegative().optional()
|
|
74879
|
+
});
|
|
74880
|
+
const pingPayloadSchema = z.object({ nonce: z.string() });
|
|
74881
|
+
const pingMessageSchema = z.object({
|
|
74882
|
+
type: z.literal("ping"),
|
|
74883
|
+
timestamp: isoDateTimeSchema,
|
|
74884
|
+
payload: pingPayloadSchema
|
|
74885
|
+
});
|
|
74886
|
+
const pongPayloadSchema = z.object({ nonce: z.string() });
|
|
74887
|
+
const pongMessageSchema = z.object({
|
|
74888
|
+
type: z.literal("pong"),
|
|
74889
|
+
payload: pongPayloadSchema
|
|
74890
|
+
});
|
|
74891
|
+
const resyncRequiredPayloadSchema = z.object({
|
|
74892
|
+
session_id: z.string(),
|
|
74893
|
+
reason: z.enum(["buffer_overflow", "session_recreated"]),
|
|
74894
|
+
current_seq: z.number().int().nonnegative()
|
|
74895
|
+
});
|
|
74896
|
+
const resyncRequiredMessageSchema = z.object({
|
|
74897
|
+
type: z.literal("resync_required"),
|
|
74898
|
+
timestamp: isoDateTimeSchema,
|
|
74899
|
+
payload: resyncRequiredPayloadSchema
|
|
74900
|
+
});
|
|
74901
|
+
const wsErrorPayloadSchema = z.object({
|
|
74902
|
+
code: z.number().int(),
|
|
74903
|
+
msg: z.string(),
|
|
74904
|
+
fatal: z.boolean(),
|
|
74905
|
+
request_id: z.string().optional(),
|
|
74906
|
+
details: z.unknown().optional()
|
|
74907
|
+
});
|
|
74908
|
+
const wsErrorMessageSchema = z.object({
|
|
74909
|
+
type: z.literal("error"),
|
|
74910
|
+
timestamp: isoDateTimeSchema,
|
|
74911
|
+
payload: wsErrorPayloadSchema
|
|
74912
|
+
});
|
|
74913
|
+
z.discriminatedUnion("type", [
|
|
74914
|
+
clientHelloMessageSchema,
|
|
74915
|
+
subscribeMessageSchema,
|
|
74916
|
+
unsubscribeMessageSchema,
|
|
74917
|
+
watchFsAddMessageSchema,
|
|
74918
|
+
watchFsRemoveMessageSchema,
|
|
74919
|
+
abortMessageSchema,
|
|
74920
|
+
pongMessageSchema
|
|
74921
|
+
]);
|
|
74922
|
+
z.discriminatedUnion("type", [
|
|
74923
|
+
serverHelloMessageSchema,
|
|
74924
|
+
pingMessageSchema,
|
|
74925
|
+
resyncRequiredMessageSchema,
|
|
74926
|
+
wsErrorMessageSchema
|
|
74927
|
+
]);
|
|
74928
|
+
//#endregion
|
|
74929
|
+
//#region ../../packages/protocol/src/message.ts
|
|
74930
|
+
const messageRoleSchema = z.enum([
|
|
74931
|
+
"user",
|
|
74932
|
+
"assistant",
|
|
74933
|
+
"tool",
|
|
74934
|
+
"system"
|
|
74935
|
+
]);
|
|
74936
|
+
const textContentSchema = z.object({
|
|
74937
|
+
type: z.literal("text"),
|
|
74938
|
+
text: z.string()
|
|
74939
|
+
});
|
|
74940
|
+
const toolUseContentSchema = z.object({
|
|
74941
|
+
type: z.literal("tool_use"),
|
|
74942
|
+
tool_call_id: z.string().min(1),
|
|
74943
|
+
tool_name: z.string().min(1),
|
|
74944
|
+
input: z.unknown()
|
|
74945
|
+
});
|
|
74946
|
+
const toolResultContentSchema = z.object({
|
|
74947
|
+
type: z.literal("tool_result"),
|
|
74948
|
+
tool_call_id: z.string().min(1),
|
|
74949
|
+
output: z.unknown(),
|
|
74950
|
+
is_error: z.boolean().optional()
|
|
74951
|
+
});
|
|
74952
|
+
const imageSourceSchema = z.discriminatedUnion("kind", [
|
|
74953
|
+
z.object({
|
|
74954
|
+
kind: z.literal("url"),
|
|
74955
|
+
url: z.string().min(1)
|
|
74956
|
+
}),
|
|
74957
|
+
z.object({
|
|
74958
|
+
kind: z.literal("base64"),
|
|
74959
|
+
media_type: z.string().min(1),
|
|
74960
|
+
data: z.string().min(1)
|
|
74961
|
+
}),
|
|
74962
|
+
z.object({
|
|
74963
|
+
kind: z.literal("file"),
|
|
74964
|
+
file_id: z.string().min(1)
|
|
74965
|
+
})
|
|
74966
|
+
]);
|
|
74967
|
+
const imageContentSchema = z.object({
|
|
74968
|
+
type: z.literal("image"),
|
|
74969
|
+
source: imageSourceSchema
|
|
74970
|
+
});
|
|
74971
|
+
const fileContentSchema = z.object({
|
|
74972
|
+
type: z.literal("file"),
|
|
74973
|
+
file_id: z.string().min(1),
|
|
74974
|
+
name: z.string(),
|
|
74975
|
+
media_type: z.string().min(1),
|
|
74976
|
+
size: z.number().int().nonnegative()
|
|
74977
|
+
});
|
|
74978
|
+
const thinkingContentSchema = z.object({
|
|
74979
|
+
type: z.literal("thinking"),
|
|
74980
|
+
thinking: z.string(),
|
|
74981
|
+
signature: z.string().optional()
|
|
74982
|
+
});
|
|
74983
|
+
const messageContentSchema = z.discriminatedUnion("type", [
|
|
74984
|
+
textContentSchema,
|
|
74985
|
+
toolUseContentSchema,
|
|
74986
|
+
toolResultContentSchema,
|
|
74987
|
+
imageContentSchema,
|
|
74988
|
+
fileContentSchema,
|
|
74989
|
+
thinkingContentSchema
|
|
74990
|
+
]);
|
|
74991
|
+
const messageSchema = z.object({
|
|
74992
|
+
id: z.string().min(1),
|
|
74993
|
+
session_id: z.string().min(1),
|
|
74994
|
+
role: messageRoleSchema,
|
|
74995
|
+
content: z.array(messageContentSchema),
|
|
74996
|
+
created_at: isoDateTimeSchema,
|
|
74997
|
+
prompt_id: z.string().min(1).optional(),
|
|
74998
|
+
parent_message_id: z.string().min(1).optional(),
|
|
74999
|
+
metadata: z.record(z.string(), z.unknown()).optional()
|
|
75000
|
+
});
|
|
75001
|
+
//#endregion
|
|
75002
|
+
//#region ../../packages/protocol/src/rest/prompt.ts
|
|
75003
|
+
/**
|
|
75004
|
+
* POST /v1/sessions/{sid}/prompts
|
|
75005
|
+
* Body: PromptSubmission {
|
|
75006
|
+
* content: MessageContent[],
|
|
75007
|
+
* metadata?: ...,
|
|
75008
|
+
* model?: string,
|
|
75009
|
+
* thinking?: 'off'|'low'|'medium'|'high'|'xhigh'|'max',
|
|
75010
|
+
* permission_mode?: 'manual'|'yolo'|'auto',
|
|
75011
|
+
* plan_mode?: boolean,
|
|
75012
|
+
* }
|
|
75013
|
+
* Reply: PromptSubmitResult { prompt_id, user_message_id, status, content, created_at }
|
|
75014
|
+
* status='running' when sent immediately, status='queued' when
|
|
75015
|
+
* another prompt is already active.
|
|
75016
|
+
*
|
|
75017
|
+
* GET /v1/sessions/{sid}/prompts
|
|
75018
|
+
* Reply: { active: PromptItem | null, queued: PromptItem[] }
|
|
75019
|
+
*
|
|
75020
|
+
* POST /v1/sessions/{sid}/prompts/{pid}:steer
|
|
75021
|
+
* POST /v1/sessions/{sid}/prompts:steer
|
|
75022
|
+
* Body: { prompt_ids: string[] } for the collection route
|
|
75023
|
+
* Reply: { steered: true, prompt_ids: string[] }
|
|
75024
|
+
*
|
|
75025
|
+
* POST /v1/sessions/{sid}/prompts/{pid}:abort
|
|
75026
|
+
* Body: empty
|
|
75027
|
+
* Reply: { aborted: true, at_seq: number } (envelope code 0)
|
|
75028
|
+
* { aborted: false, at_seq: number } (envelope code 40903, idempotent)
|
|
75029
|
+
*/
|
|
75030
|
+
const promptThinkingSchema = z.enum([
|
|
75031
|
+
"off",
|
|
75032
|
+
"low",
|
|
75033
|
+
"medium",
|
|
75034
|
+
"high",
|
|
75035
|
+
"xhigh",
|
|
75036
|
+
"max"
|
|
75037
|
+
]);
|
|
75038
|
+
const promptPermissionModeSchema = z.enum([
|
|
75039
|
+
"manual",
|
|
75040
|
+
"yolo",
|
|
75041
|
+
"auto"
|
|
75042
|
+
]);
|
|
75043
|
+
z.object({
|
|
75044
|
+
content: z.array(messageContentSchema).min(1),
|
|
75045
|
+
metadata: z.record(z.string(), z.unknown()).optional(),
|
|
75046
|
+
model: z.string().min(1).optional(),
|
|
75047
|
+
thinking: promptThinkingSchema.optional(),
|
|
75048
|
+
permission_mode: promptPermissionModeSchema.optional(),
|
|
75049
|
+
plan_mode: z.boolean().optional()
|
|
75050
|
+
});
|
|
75051
|
+
const promptStatusSchema = z.enum(["running", "queued"]);
|
|
75052
|
+
const promptItemSchema = z.object({
|
|
75053
|
+
prompt_id: z.string().min(1),
|
|
75054
|
+
user_message_id: z.string().min(1),
|
|
75055
|
+
status: promptStatusSchema,
|
|
75056
|
+
content: z.array(messageContentSchema).min(1),
|
|
75057
|
+
created_at: isoDateTimeSchema
|
|
75058
|
+
});
|
|
75059
|
+
z.object({
|
|
75060
|
+
active: promptItemSchema.nullable(),
|
|
75061
|
+
queued: z.array(promptItemSchema)
|
|
75062
|
+
});
|
|
75063
|
+
z.object({ prompt_ids: z.array(z.string().min(1)).min(1) });
|
|
75064
|
+
z.object({
|
|
75065
|
+
steered: z.literal(true),
|
|
75066
|
+
prompt_ids: z.array(z.string().min(1)).min(1)
|
|
75067
|
+
});
|
|
75068
|
+
z.object({
|
|
75069
|
+
aborted: z.boolean(),
|
|
75070
|
+
at_seq: z.number().int().nonnegative().optional()
|
|
75071
|
+
});
|
|
75072
|
+
//#endregion
|
|
75073
|
+
//#region ../../packages/protocol/src/workspace.ts
|
|
75074
|
+
const workspaceIdSchema = z.string().regex(/^wd_[a-z0-9._-]+_[0-9a-f]{12}$/, { message: "workspace_id must be a wd_<slug>_<hash12> string" });
|
|
75075
|
+
const workspaceSchema = z.object({
|
|
75076
|
+
id: workspaceIdSchema,
|
|
75077
|
+
root: z.string().min(1),
|
|
75078
|
+
name: z.string().min(1).max(100),
|
|
75079
|
+
is_git_repo: z.boolean(),
|
|
75080
|
+
branch: z.string().nullable(),
|
|
75081
|
+
created_at: isoDateTimeSchema,
|
|
75082
|
+
last_opened_at: isoDateTimeSchema,
|
|
75083
|
+
session_count: z.number().int().nonnegative()
|
|
75084
|
+
});
|
|
75085
|
+
z.object({
|
|
75086
|
+
root: z.string().min(1),
|
|
75087
|
+
name: z.string().min(1).max(100).optional()
|
|
75088
|
+
});
|
|
75089
|
+
z.object({ name: z.string().min(1).max(100) });
|
|
75090
|
+
//#endregion
|
|
75091
|
+
//#region ../../packages/protocol/src/session.ts
|
|
75092
|
+
const sessionStatusSchema = z.enum([
|
|
75093
|
+
"idle",
|
|
75094
|
+
"running",
|
|
75095
|
+
"awaiting_approval",
|
|
75096
|
+
"awaiting_question",
|
|
75097
|
+
"aborted"
|
|
75098
|
+
]);
|
|
75099
|
+
const sessionUsageSchema = z.object({
|
|
75100
|
+
input_tokens: z.number().int().nonnegative(),
|
|
75101
|
+
output_tokens: z.number().int().nonnegative(),
|
|
75102
|
+
cache_read_tokens: z.number().int().nonnegative(),
|
|
75103
|
+
cache_creation_tokens: z.number().int().nonnegative(),
|
|
75104
|
+
total_cost_usd: z.number().nonnegative(),
|
|
75105
|
+
context_tokens: z.number().int().nonnegative(),
|
|
75106
|
+
context_limit: z.number().int().nonnegative(),
|
|
75107
|
+
turn_count: z.number().int().nonnegative()
|
|
75108
|
+
});
|
|
75109
|
+
const permissionRuleMatcherSchema = z.object({
|
|
75110
|
+
kind: z.enum([
|
|
75111
|
+
"command_prefix",
|
|
75112
|
+
"path_glob",
|
|
75113
|
+
"exact_input",
|
|
75114
|
+
"always"
|
|
75115
|
+
]),
|
|
75116
|
+
value: z.string().optional()
|
|
75117
|
+
});
|
|
75118
|
+
const permissionRuleSchema = z.object({
|
|
75119
|
+
id: z.string().min(1),
|
|
75120
|
+
tool_name: z.string().min(1),
|
|
75121
|
+
matcher: permissionRuleMatcherSchema.optional(),
|
|
75122
|
+
decision: z.literal("approved"),
|
|
75123
|
+
created_at: isoDateTimeSchema,
|
|
75124
|
+
created_by: z.enum(["user", "agent"])
|
|
75125
|
+
});
|
|
75126
|
+
const sessionAgentConfigSchema = z.object({
|
|
75127
|
+
model: z.string(),
|
|
75128
|
+
system_prompt: z.string().optional(),
|
|
75129
|
+
tools: z.array(z.string()).optional(),
|
|
75130
|
+
mcp_servers: z.array(z.string()).optional(),
|
|
75131
|
+
thinking: promptThinkingSchema.optional(),
|
|
75132
|
+
permission_mode: promptPermissionModeSchema.optional(),
|
|
75133
|
+
plan_mode: z.boolean().optional()
|
|
75134
|
+
});
|
|
75135
|
+
const sessionAgentConfigPartialSchema = sessionAgentConfigSchema.partial();
|
|
75136
|
+
const sessionMetadataSchema = z.object({ cwd: z.string().min(1) }).catchall(z.unknown());
|
|
75137
|
+
const sessionSchema = z.object({
|
|
75138
|
+
id: z.string().min(1),
|
|
75139
|
+
workspace_id: workspaceIdSchema,
|
|
75140
|
+
title: z.string(),
|
|
75141
|
+
created_at: isoDateTimeSchema,
|
|
75142
|
+
updated_at: isoDateTimeSchema,
|
|
75143
|
+
status: sessionStatusSchema,
|
|
75144
|
+
current_prompt_id: z.string().min(1).optional(),
|
|
75145
|
+
metadata: sessionMetadataSchema,
|
|
75146
|
+
agent_config: sessionAgentConfigSchema,
|
|
75147
|
+
usage: sessionUsageSchema,
|
|
75148
|
+
permission_rules: z.array(permissionRuleSchema),
|
|
75149
|
+
message_count: z.number().int().nonnegative(),
|
|
75150
|
+
last_seq: z.number().int().nonnegative()
|
|
75151
|
+
});
|
|
75152
|
+
z.object({
|
|
75153
|
+
title: z.string().min(1).optional(),
|
|
75154
|
+
metadata: sessionMetadataSchema.optional(),
|
|
75155
|
+
agent_config: sessionAgentConfigPartialSchema.optional(),
|
|
75156
|
+
workspace_id: workspaceIdSchema.optional()
|
|
75157
|
+
});
|
|
75158
|
+
z.object({
|
|
75159
|
+
title: z.string().min(1).optional(),
|
|
75160
|
+
metadata: sessionMetadataSchema.partial().optional(),
|
|
75161
|
+
agent_config: sessionAgentConfigPartialSchema.optional(),
|
|
75162
|
+
permission_rules: z.array(permissionRuleSchema).optional()
|
|
75163
|
+
});
|
|
75164
|
+
z.object({
|
|
75165
|
+
title: z.string().min(1).optional(),
|
|
75166
|
+
metadata: z.record(z.string(), z.unknown()).optional()
|
|
75167
|
+
});
|
|
75168
|
+
z.object({
|
|
75169
|
+
title: z.string().min(1).optional(),
|
|
75170
|
+
metadata: z.record(z.string(), z.unknown()).optional()
|
|
75171
|
+
});
|
|
75172
|
+
//#endregion
|
|
75173
|
+
//#region ../../packages/protocol/src/approval.ts
|
|
75174
|
+
const approvalDecisionSchema = z.enum([
|
|
75175
|
+
"approved",
|
|
75176
|
+
"rejected",
|
|
75177
|
+
"cancelled"
|
|
75178
|
+
]);
|
|
75179
|
+
const approvalScopeSchema = z.enum(["session"]);
|
|
75180
|
+
const approvalRequestSchema = z.object({
|
|
75181
|
+
approval_id: z.string().min(1),
|
|
75182
|
+
session_id: z.string().min(1),
|
|
75183
|
+
turn_id: z.number().int().nonnegative().optional(),
|
|
75184
|
+
tool_call_id: z.string().min(1),
|
|
75185
|
+
tool_name: z.string().min(1),
|
|
75186
|
+
action: z.string(),
|
|
75187
|
+
tool_input_display: z.unknown(),
|
|
75188
|
+
created_at: isoDateTimeSchema,
|
|
75189
|
+
expires_at: isoDateTimeSchema
|
|
75190
|
+
});
|
|
75191
|
+
z.object({
|
|
75192
|
+
decision: approvalDecisionSchema,
|
|
75193
|
+
scope: approvalScopeSchema.optional(),
|
|
75194
|
+
feedback: z.string().optional(),
|
|
75195
|
+
selected_label: z.string().optional()
|
|
75196
|
+
});
|
|
75197
|
+
//#endregion
|
|
75198
|
+
//#region ../../packages/protocol/src/question.ts
|
|
75199
|
+
const questionOptionSchema = z.object({
|
|
75200
|
+
id: z.string().min(1),
|
|
75201
|
+
label: z.string().min(1),
|
|
75202
|
+
description: z.string().optional()
|
|
75203
|
+
});
|
|
75204
|
+
const questionItemSchema = z.object({
|
|
75205
|
+
id: z.string().min(1),
|
|
75206
|
+
question: z.string().min(1),
|
|
75207
|
+
header: z.string().optional(),
|
|
75208
|
+
body: z.string().optional(),
|
|
75209
|
+
options: z.array(questionOptionSchema).min(2).max(4),
|
|
75210
|
+
multi_select: z.boolean().optional(),
|
|
75211
|
+
allow_other: z.boolean().optional(),
|
|
75212
|
+
other_label: z.string().optional(),
|
|
75213
|
+
other_description: z.string().optional()
|
|
75214
|
+
});
|
|
75215
|
+
const questionRequestSchema = z.object({
|
|
75216
|
+
question_id: z.string().min(1),
|
|
75217
|
+
session_id: z.string().min(1),
|
|
75218
|
+
turn_id: z.number().int().nonnegative().optional(),
|
|
75219
|
+
tool_call_id: z.string().min(1).optional(),
|
|
75220
|
+
questions: z.array(questionItemSchema).min(1).max(4),
|
|
75221
|
+
created_at: isoDateTimeSchema,
|
|
75222
|
+
expires_at: isoDateTimeSchema
|
|
75223
|
+
});
|
|
75224
|
+
const questionAnswerSchema = z.discriminatedUnion("kind", [
|
|
75225
|
+
z.object({
|
|
75226
|
+
kind: z.literal("single"),
|
|
75227
|
+
option_id: z.string().min(1)
|
|
75228
|
+
}),
|
|
75229
|
+
z.object({
|
|
75230
|
+
kind: z.literal("multi"),
|
|
75231
|
+
option_ids: z.array(z.string().min(1)).min(1)
|
|
75232
|
+
}),
|
|
75233
|
+
z.object({
|
|
75234
|
+
kind: z.literal("other"),
|
|
75235
|
+
text: z.string()
|
|
75236
|
+
}),
|
|
75237
|
+
z.object({
|
|
75238
|
+
kind: z.literal("multi_with_other"),
|
|
75239
|
+
option_ids: z.array(z.string().min(1)),
|
|
75240
|
+
other_text: z.string()
|
|
75241
|
+
}),
|
|
75242
|
+
z.object({ kind: z.literal("skipped") })
|
|
75243
|
+
]);
|
|
75244
|
+
const questionAnswerMethodSchema = z.enum([
|
|
75245
|
+
"enter",
|
|
75246
|
+
"space",
|
|
75247
|
+
"number_key",
|
|
75248
|
+
"click"
|
|
75249
|
+
]);
|
|
75250
|
+
z.object({
|
|
75251
|
+
answers: z.record(z.string().min(1), questionAnswerSchema),
|
|
75252
|
+
method: questionAnswerMethodSchema.optional(),
|
|
75253
|
+
note: z.string().optional()
|
|
75254
|
+
});
|
|
75255
|
+
//#endregion
|
|
75256
|
+
//#region ../../packages/protocol/src/tool.ts
|
|
75257
|
+
const toolSourceSchema = z.enum([
|
|
75258
|
+
"builtin",
|
|
75259
|
+
"skill",
|
|
75260
|
+
"mcp"
|
|
75261
|
+
]);
|
|
75262
|
+
const toolDescriptorSchema = z.object({
|
|
75263
|
+
name: z.string().min(1),
|
|
75264
|
+
description: z.string(),
|
|
75265
|
+
input_schema: z.unknown(),
|
|
75266
|
+
source: toolSourceSchema,
|
|
75267
|
+
mcp_server_id: z.string().min(1).optional()
|
|
75268
|
+
});
|
|
75269
|
+
const mcpServerStatusSchema = z.enum([
|
|
75270
|
+
"connected",
|
|
75271
|
+
"connecting",
|
|
75272
|
+
"disconnected",
|
|
75273
|
+
"error"
|
|
75274
|
+
]);
|
|
75275
|
+
const mcpServerTransportSchema = z.enum([
|
|
75276
|
+
"stdio",
|
|
75277
|
+
"http",
|
|
75278
|
+
"sse"
|
|
75279
|
+
]);
|
|
75280
|
+
const mcpServerSchema = z.object({
|
|
75281
|
+
id: z.string().min(1),
|
|
75282
|
+
name: z.string().min(1),
|
|
75283
|
+
transport: mcpServerTransportSchema,
|
|
75284
|
+
status: mcpServerStatusSchema,
|
|
75285
|
+
last_error: z.string().optional(),
|
|
75286
|
+
tool_count: z.number().int().nonnegative()
|
|
75287
|
+
});
|
|
75288
|
+
//#endregion
|
|
75289
|
+
//#region ../../packages/protocol/src/task.ts
|
|
75290
|
+
const backgroundTaskKindSchema = z.enum([
|
|
75291
|
+
"subagent",
|
|
75292
|
+
"bash",
|
|
75293
|
+
"tool"
|
|
75294
|
+
]);
|
|
75295
|
+
const backgroundTaskStatusSchema = z.enum([
|
|
75296
|
+
"running",
|
|
75297
|
+
"completed",
|
|
75298
|
+
"failed",
|
|
75299
|
+
"cancelled"
|
|
75300
|
+
]);
|
|
75301
|
+
const backgroundTaskSchema = z.object({
|
|
75302
|
+
id: z.string().min(1),
|
|
75303
|
+
session_id: z.string().min(1),
|
|
75304
|
+
kind: backgroundTaskKindSchema,
|
|
75305
|
+
description: z.string(),
|
|
75306
|
+
status: backgroundTaskStatusSchema,
|
|
75307
|
+
created_at: isoDateTimeSchema,
|
|
75308
|
+
started_at: isoDateTimeSchema.optional(),
|
|
75309
|
+
completed_at: isoDateTimeSchema.optional(),
|
|
75310
|
+
output_preview: z.string().optional(),
|
|
75311
|
+
output_bytes: z.number().int().nonnegative().optional()
|
|
75312
|
+
});
|
|
75313
|
+
//#endregion
|
|
75314
|
+
//#region ../../packages/protocol/src/fs.ts
|
|
75315
|
+
const fsKindSchema = z.enum([
|
|
75316
|
+
"file",
|
|
75317
|
+
"directory",
|
|
75318
|
+
"symlink"
|
|
75319
|
+
]);
|
|
75320
|
+
const fsGitStatusSchema = z.enum([
|
|
75321
|
+
"clean",
|
|
75322
|
+
"modified",
|
|
75323
|
+
"added",
|
|
75324
|
+
"deleted",
|
|
75325
|
+
"renamed",
|
|
75326
|
+
"untracked",
|
|
75327
|
+
"ignored",
|
|
75328
|
+
"conflicted"
|
|
75329
|
+
]);
|
|
75330
|
+
const fsEntrySchema = z.object({
|
|
75331
|
+
path: z.string(),
|
|
75332
|
+
name: z.string(),
|
|
75333
|
+
kind: fsKindSchema,
|
|
75334
|
+
size: z.number().int().nonnegative().optional(),
|
|
75335
|
+
modified_at: isoDateTimeSchema,
|
|
75336
|
+
etag: z.string().optional(),
|
|
75337
|
+
mime: z.string().optional(),
|
|
75338
|
+
language_id: z.string().optional(),
|
|
75339
|
+
is_binary: z.boolean().optional(),
|
|
75340
|
+
is_symlink_to: z.string().optional(),
|
|
75341
|
+
git_status: fsGitStatusSchema.optional(),
|
|
75342
|
+
child_count: z.number().int().nonnegative().optional()
|
|
75343
|
+
});
|
|
75344
|
+
const fsSearchHitSchema = z.object({
|
|
75345
|
+
path: z.string(),
|
|
75346
|
+
name: z.string(),
|
|
75347
|
+
kind: fsKindSchema,
|
|
75348
|
+
score: z.number().min(0).max(1),
|
|
75349
|
+
match_positions: z.array(z.number().int().nonnegative())
|
|
75350
|
+
});
|
|
75351
|
+
const fsGrepMatchSchema = z.object({
|
|
75352
|
+
line: z.number().int().positive(),
|
|
75353
|
+
col: z.number().int().positive(),
|
|
75354
|
+
text: z.string(),
|
|
75355
|
+
before: z.array(z.string()),
|
|
75356
|
+
after: z.array(z.string())
|
|
75357
|
+
});
|
|
75358
|
+
const fsGrepFileHitSchema = z.object({
|
|
75359
|
+
path: z.string(),
|
|
75360
|
+
matches: z.array(fsGrepMatchSchema)
|
|
75361
|
+
});
|
|
75362
|
+
z.object({
|
|
75363
|
+
path: z.string(),
|
|
75364
|
+
status: fsGitStatusSchema,
|
|
75365
|
+
rename_from: z.string().optional()
|
|
75366
|
+
});
|
|
75367
|
+
const fsChangeKindSchema = z.enum([
|
|
75368
|
+
"file",
|
|
75369
|
+
"directory",
|
|
75370
|
+
"symlink"
|
|
75371
|
+
]);
|
|
75372
|
+
const fsChangeActionSchema = z.enum([
|
|
75373
|
+
"created",
|
|
75374
|
+
"modified",
|
|
75375
|
+
"deleted"
|
|
75376
|
+
]);
|
|
75377
|
+
const fsChangeEntrySchema = z.object({
|
|
75378
|
+
path: z.string(),
|
|
75379
|
+
change: fsChangeActionSchema,
|
|
75380
|
+
kind: fsChangeKindSchema,
|
|
75381
|
+
size_delta: z.number().int().optional(),
|
|
75382
|
+
etag: z.string().optional()
|
|
75383
|
+
});
|
|
75384
|
+
z.object({
|
|
75385
|
+
changes: z.array(fsChangeEntrySchema),
|
|
75386
|
+
coalesced_window_ms: z.number().int().positive(),
|
|
75387
|
+
truncated: z.boolean().optional(),
|
|
75388
|
+
count: z.number().int().nonnegative().optional()
|
|
75389
|
+
});
|
|
75390
|
+
z.object({
|
|
75391
|
+
id: z.string().min(1),
|
|
75392
|
+
name: z.string().min(1),
|
|
75393
|
+
media_type: z.string().min(1),
|
|
75394
|
+
size: z.number().int().nonnegative(),
|
|
75395
|
+
created_at: isoDateTimeSchema,
|
|
75396
|
+
expires_at: isoDateTimeSchema.optional()
|
|
75397
|
+
});
|
|
75398
|
+
//#endregion
|
|
75399
|
+
//#region ../../packages/protocol/src/modelCatalog.ts
|
|
75400
|
+
const modelCatalogItemSchema = z.object({
|
|
75401
|
+
provider: z.string().min(1),
|
|
75402
|
+
model: z.string().min(1),
|
|
75403
|
+
display_name: z.string().min(1).optional(),
|
|
75404
|
+
max_context_size: z.number().int().min(1),
|
|
75405
|
+
capabilities: z.array(z.string()).optional()
|
|
75406
|
+
});
|
|
75407
|
+
const providerCatalogStatusSchema = z.enum([
|
|
75408
|
+
"connected",
|
|
75409
|
+
"error",
|
|
75410
|
+
"unconfigured"
|
|
75411
|
+
]);
|
|
75412
|
+
const providerCatalogItemSchema = z.object({
|
|
75413
|
+
id: z.string().min(1),
|
|
75414
|
+
type: z.string().min(1),
|
|
75415
|
+
base_url: z.string().min(1).optional(),
|
|
75416
|
+
default_model: z.string().min(1).optional(),
|
|
75417
|
+
has_api_key: z.boolean(),
|
|
75418
|
+
status: providerCatalogStatusSchema,
|
|
75419
|
+
models: z.array(z.string().min(1)).optional()
|
|
75420
|
+
});
|
|
75421
|
+
//#endregion
|
|
75422
|
+
//#region ../../packages/protocol/src/rest/meta.ts
|
|
75423
|
+
/**
|
|
75424
|
+
* GET /v1/meta
|
|
75425
|
+
* Reply: MetaResponse {
|
|
75426
|
+
* daemon_version,
|
|
75427
|
+
* capabilities,
|
|
75428
|
+
* daemon_id,
|
|
75429
|
+
* started_at
|
|
75430
|
+
* }
|
|
75431
|
+
*/
|
|
75432
|
+
const metaCapabilitiesSchema = z.object({
|
|
75433
|
+
websocket: z.literal(true),
|
|
75434
|
+
file_upload: z.literal(true),
|
|
75435
|
+
fs_query: z.literal(true),
|
|
75436
|
+
mcp: z.literal(true),
|
|
75437
|
+
background_tasks: z.literal(true)
|
|
75438
|
+
});
|
|
75439
|
+
z.object({
|
|
75440
|
+
daemon_version: z.string().min(1),
|
|
75441
|
+
capabilities: metaCapabilitiesSchema,
|
|
75442
|
+
daemon_id: z.string().min(1),
|
|
75443
|
+
started_at: isoDateTimeSchema
|
|
75444
|
+
});
|
|
75445
|
+
//#endregion
|
|
75446
|
+
//#region ../../packages/protocol/src/rest/auth.ts
|
|
75447
|
+
/**
|
|
75448
|
+
* GET /v1/auth
|
|
75449
|
+
* Reply: AuthSummary {
|
|
75450
|
+
* ready,
|
|
75451
|
+
* providers_count,
|
|
75452
|
+
* default_model,
|
|
75453
|
+
* managed_provider
|
|
75454
|
+
* }
|
|
75455
|
+
*/
|
|
75456
|
+
const managedProviderStatusSchema = z.enum([
|
|
75457
|
+
"authenticated",
|
|
75458
|
+
"expired",
|
|
75459
|
+
"revoked",
|
|
75460
|
+
"unauthenticated"
|
|
75461
|
+
]);
|
|
75462
|
+
const managedProviderSummarySchema = z.object({
|
|
75463
|
+
name: z.string().min(1),
|
|
75464
|
+
status: managedProviderStatusSchema
|
|
75465
|
+
});
|
|
75466
|
+
z.object({
|
|
75467
|
+
ready: z.boolean(),
|
|
75468
|
+
providers_count: z.number().int().nonnegative(),
|
|
75469
|
+
default_model: z.string().nullable(),
|
|
75470
|
+
managed_provider: managedProviderSummarySchema.nullable()
|
|
75471
|
+
});
|
|
75472
|
+
//#endregion
|
|
75473
|
+
//#region ../../packages/protocol/src/rest/oauth.ts
|
|
75474
|
+
/**
|
|
75475
|
+
* POST /v1/oauth/login body: { provider? } data: OAuthFlowStart
|
|
75476
|
+
* GET /v1/oauth/login query: { provider? } data: OAuthFlowStatus | null
|
|
75477
|
+
* DELETE /v1/oauth/login query: { provider? } data: { cancelled, status }
|
|
75478
|
+
* POST /v1/oauth/logout body: { provider? } data: { logged_out, provider }
|
|
75479
|
+
*/
|
|
75480
|
+
const oauthFlowStatusEnum = z.enum([
|
|
75481
|
+
"pending",
|
|
75482
|
+
"authenticated",
|
|
75483
|
+
"denied",
|
|
75484
|
+
"expired",
|
|
75485
|
+
"cancelled"
|
|
75486
|
+
]);
|
|
75487
|
+
z.object({ provider: z.string().min(1).optional() });
|
|
75488
|
+
z.object({
|
|
75489
|
+
flow_id: z.string().min(1),
|
|
75490
|
+
provider: z.string().min(1),
|
|
75491
|
+
verification_uri: z.string().url(),
|
|
75492
|
+
verification_uri_complete: z.string().url(),
|
|
75493
|
+
user_code: z.string().min(1),
|
|
75494
|
+
expires_in: z.number().int().positive(),
|
|
75495
|
+
interval: z.number().int().positive(),
|
|
75496
|
+
status: z.literal("pending"),
|
|
75497
|
+
expires_at: isoDateTimeSchema
|
|
75498
|
+
});
|
|
75499
|
+
z.object({
|
|
75500
|
+
flow_id: z.string().min(1),
|
|
75501
|
+
provider: z.string().min(1),
|
|
75502
|
+
status: oauthFlowStatusEnum,
|
|
75503
|
+
verification_uri: z.string().url(),
|
|
75504
|
+
verification_uri_complete: z.string().url(),
|
|
75505
|
+
user_code: z.string().min(1),
|
|
75506
|
+
expires_in: z.number().int().positive(),
|
|
75507
|
+
expires_at: isoDateTimeSchema,
|
|
75508
|
+
interval: z.number().int().positive(),
|
|
75509
|
+
resolved_at: isoDateTimeSchema.optional(),
|
|
75510
|
+
error_message: z.string().optional()
|
|
75511
|
+
});
|
|
75512
|
+
z.object({ provider: z.string().min(1).optional() });
|
|
75513
|
+
z.object({
|
|
75514
|
+
cancelled: z.boolean(),
|
|
75515
|
+
status: oauthFlowStatusEnum
|
|
75516
|
+
});
|
|
75517
|
+
z.object({ provider: z.string().min(1).optional() });
|
|
75518
|
+
z.object({
|
|
75519
|
+
logged_out: z.literal(true),
|
|
75520
|
+
provider: z.string().min(1)
|
|
75521
|
+
});
|
|
75522
|
+
cursorQuerySchema.and(z.object({ status: sessionStatusSchema.optional() }));
|
|
75523
|
+
pageResponseSchema(sessionSchema);
|
|
75524
|
+
const sessionStatusResponseSchema = z.object({
|
|
75525
|
+
model: z.string().optional(),
|
|
75526
|
+
thinking_level: z.string(),
|
|
75527
|
+
permission: z.string(),
|
|
75528
|
+
plan_mode: z.boolean(),
|
|
75529
|
+
context_tokens: z.number().int().nonnegative(),
|
|
75530
|
+
max_context_tokens: z.number().int().nonnegative(),
|
|
75531
|
+
context_usage: z.number().min(0).max(1)
|
|
75532
|
+
});
|
|
75533
|
+
z.preprocess((value) => value === void 0 ? {} : value, z.object({ instruction: z.string().optional() }));
|
|
75534
|
+
z.object({});
|
|
75535
|
+
z.preprocess((value) => value === void 0 ? {} : value, z.object({
|
|
75536
|
+
count: z.number().int().positive().default(1),
|
|
75537
|
+
page_size: z.number().int().min(1).max(100).optional()
|
|
75538
|
+
}));
|
|
75539
|
+
z.object({
|
|
75540
|
+
messages: pageResponseSchema(messageSchema),
|
|
75541
|
+
status: sessionStatusResponseSchema
|
|
75542
|
+
});
|
|
75543
|
+
z.object({ deleted: z.literal(true) });
|
|
75544
|
+
z.object({ items: z.array(workspaceSchema) });
|
|
75545
|
+
z.object({ workspace_id: workspaceIdSchema });
|
|
75546
|
+
z.object({ deleted: z.literal(true) });
|
|
75547
|
+
z.object({ path: z.string().min(1).optional() });
|
|
75548
|
+
const fsBrowseEntrySchema = z.object({
|
|
75549
|
+
name: z.string().min(1),
|
|
75550
|
+
path: z.string().min(1),
|
|
75551
|
+
is_dir: z.literal(true),
|
|
75552
|
+
is_git_repo: z.boolean(),
|
|
75553
|
+
branch: z.string().optional()
|
|
75554
|
+
});
|
|
75555
|
+
z.object({
|
|
75556
|
+
path: z.string().min(1),
|
|
75557
|
+
parent: z.string().min(1).nullable(),
|
|
75558
|
+
entries: z.array(fsBrowseEntrySchema)
|
|
75559
|
+
});
|
|
75560
|
+
z.object({
|
|
75561
|
+
home: z.string().min(1),
|
|
75562
|
+
recent_roots: z.array(z.string().min(1))
|
|
75563
|
+
});
|
|
75564
|
+
cursorQuerySchema.and(z.object({ role: messageRoleSchema.optional() }));
|
|
75565
|
+
z.object({
|
|
75566
|
+
items: z.array(messageSchema),
|
|
75567
|
+
has_more: z.boolean()
|
|
75568
|
+
});
|
|
75569
|
+
z.object({ status: z.literal("pending") });
|
|
75570
|
+
z.object({ items: z.array(approvalRequestSchema) });
|
|
75571
|
+
z.object({
|
|
75572
|
+
resolved: z.literal(true),
|
|
75573
|
+
resolved_at: isoDateTimeSchema
|
|
75574
|
+
});
|
|
75575
|
+
z.object({ resolved: z.literal(false) });
|
|
75576
|
+
z.object({ status: z.literal("pending") });
|
|
75577
|
+
z.object({ items: z.array(questionRequestSchema) });
|
|
75578
|
+
z.object({
|
|
75579
|
+
resolved: z.literal(true),
|
|
75580
|
+
resolved_at: isoDateTimeSchema
|
|
75581
|
+
});
|
|
75582
|
+
z.object({ resolved: z.literal(false) });
|
|
75583
|
+
z.object({
|
|
75584
|
+
dismissed: z.literal(true),
|
|
75585
|
+
dismissed_at: isoDateTimeSchema
|
|
75586
|
+
});
|
|
75587
|
+
z.object({ session_id: z.string().min(1).optional() });
|
|
75588
|
+
z.object({ tools: z.array(toolDescriptorSchema) });
|
|
75589
|
+
z.object({ servers: z.array(mcpServerSchema) });
|
|
75590
|
+
z.object({ restarting: z.literal(true) });
|
|
75591
|
+
z.object({ status: backgroundTaskStatusSchema.optional() });
|
|
75592
|
+
z.object({ items: z.array(backgroundTaskSchema) });
|
|
75593
|
+
z.object({
|
|
75594
|
+
with_output: z.coerce.boolean().optional(),
|
|
75595
|
+
output_bytes: z.coerce.number().int().nonnegative().optional()
|
|
75596
|
+
});
|
|
75597
|
+
z.object({ cancelled: z.literal(true) });
|
|
75598
|
+
z.object({ cancelled: z.literal(false) });
|
|
75599
|
+
//#endregion
|
|
75600
|
+
//#region ../../packages/protocol/src/rest/fs.ts
|
|
75601
|
+
/**
|
|
75602
|
+
* POST /v1/sessions/{sid}/fs:list
|
|
75603
|
+
* Body: FsListRequest
|
|
75604
|
+
* Response data: FsListResponse { items, children_by_path?, truncated }
|
|
75605
|
+
* Errors: 40401, 40409, 41304, 41303
|
|
75606
|
+
*
|
|
75607
|
+
* POST /v1/sessions/{sid}/fs:read
|
|
75608
|
+
* Body: FsReadRequest
|
|
75609
|
+
* Response data: FsReadResponse
|
|
75610
|
+
* Errors: 40401, 40409, 40906, 40907, 41302, 41304
|
|
75611
|
+
* POST /v1/sessions/{sid}/fs:list_many
|
|
75612
|
+
* Body: FsListManyRequest (paths[] up to 100)
|
|
75613
|
+
* Response data: FsListManyResponse { results, truncated_paths?,
|
|
75614
|
+
* partial_errors? }
|
|
75615
|
+
*
|
|
75616
|
+
* POST /v1/sessions/{sid}/fs:stat
|
|
75617
|
+
* Body: FsStatRequest
|
|
75618
|
+
* Response data: FsEntry
|
|
75619
|
+
* Errors: 40401, 40409, 41304
|
|
75620
|
+
*
|
|
75621
|
+
* POST /v1/sessions/{sid}/fs:stat_many
|
|
75622
|
+
* Body: FsStatManyRequest (paths[] up to 1000)
|
|
75623
|
+
* Response data: FsStatManyResponse { entries: { [path]: FsEntry | null } }
|
|
75624
|
+
* Per-path failures land as `null` (REST.md §3.9 line 524); only
|
|
75625
|
+
* path-safety (41304) fails the whole call.
|
|
75626
|
+
* POST /v1/sessions/{sid}/fs:search
|
|
75627
|
+
* Body: FsSearchRequest { query, limit?, include_globs?, exclude_globs?,
|
|
75628
|
+
* follow_gitignore? }
|
|
75629
|
+
* Response data: FsSearchResponse { items, truncated }
|
|
75630
|
+
* Errors: 40401, 41303, 41304
|
|
75631
|
+
*
|
|
75632
|
+
* POST /v1/sessions/{sid}/fs:grep
|
|
75633
|
+
* Body: FsGrepRequest
|
|
75634
|
+
* Response data: FsGrepResponse { files, files_scanned, truncated,
|
|
75635
|
+
* elapsed_ms }
|
|
75636
|
+
* Errors: 40401, 41303, 41304, 41305 (>30s grep timeout)
|
|
75637
|
+
* POST /v1/sessions/{sid}/fs:git_status
|
|
75638
|
+
* Body: FsGitStatusRequest { paths? }
|
|
75639
|
+
* Response data: FsGitStatusResponse { branch, ahead, behind, entries }
|
|
75640
|
+
* Errors: 40401, 40908 (not a git repo), 41304
|
|
75641
|
+
*
|
|
75642
|
+
* GET /v1/sessions/{sid}/fs/{path}:download
|
|
75643
|
+
* Response: binary stream or envelope (40401 / 40409 / 41304)
|
|
75644
|
+
*/
|
|
75645
|
+
const fsListSortSchema = z.enum([
|
|
75646
|
+
"type_first",
|
|
75647
|
+
"name_asc",
|
|
75648
|
+
"name_desc",
|
|
75649
|
+
"mtime_desc",
|
|
75650
|
+
"size_desc"
|
|
75651
|
+
]);
|
|
75652
|
+
z.object({
|
|
75653
|
+
path: z.string().default("."),
|
|
75654
|
+
depth: z.number().int().min(1).max(10).default(1),
|
|
75655
|
+
limit: z.number().int().min(1).max(1e3).default(200),
|
|
75656
|
+
show_hidden: z.boolean().default(false),
|
|
75657
|
+
follow_gitignore: z.boolean().default(true),
|
|
75658
|
+
exclude_globs: z.array(z.string()).optional(),
|
|
75659
|
+
sort: fsListSortSchema.default("type_first"),
|
|
75660
|
+
include_git_status: z.boolean().default(false)
|
|
75661
|
+
});
|
|
75662
|
+
z.object({
|
|
75663
|
+
items: z.array(fsEntrySchema),
|
|
75664
|
+
children_by_path: z.record(z.string(), z.array(fsEntrySchema)).optional(),
|
|
75665
|
+
truncated: z.boolean()
|
|
75666
|
+
});
|
|
75667
|
+
const fsReadEncodingRequestSchema = z.enum([
|
|
75668
|
+
"auto",
|
|
75669
|
+
"utf-8",
|
|
75670
|
+
"base64"
|
|
75671
|
+
]);
|
|
75672
|
+
const fsReadEncodingResponseSchema = z.enum(["utf-8", "base64"]);
|
|
75673
|
+
z.object({
|
|
75674
|
+
path: z.string().min(1),
|
|
75675
|
+
offset: z.number().int().nonnegative().default(0),
|
|
75676
|
+
length: z.number().int().min(1).max(10485760).default(1048576),
|
|
75677
|
+
encoding: fsReadEncodingRequestSchema.default("auto")
|
|
75678
|
+
});
|
|
75679
|
+
z.object({
|
|
75680
|
+
path: z.string(),
|
|
75681
|
+
content: z.string(),
|
|
75682
|
+
encoding: fsReadEncodingResponseSchema,
|
|
75683
|
+
size: z.number().int().nonnegative(),
|
|
75684
|
+
truncated: z.boolean(),
|
|
75685
|
+
etag: z.string(),
|
|
75686
|
+
mime: z.string(),
|
|
75687
|
+
language_id: z.string().optional(),
|
|
75688
|
+
line_count: z.number().int().nonnegative().optional(),
|
|
75689
|
+
is_binary: z.boolean()
|
|
75690
|
+
});
|
|
75691
|
+
z.object({
|
|
75692
|
+
paths: z.array(z.string().min(1)).min(1).max(100),
|
|
75693
|
+
depth: z.number().int().min(1).max(10).default(1),
|
|
75694
|
+
limit: z.number().int().min(1).max(1e3).default(200),
|
|
75695
|
+
show_hidden: z.boolean().default(false),
|
|
75696
|
+
follow_gitignore: z.boolean().default(true),
|
|
75697
|
+
exclude_globs: z.array(z.string()).optional(),
|
|
75698
|
+
sort: fsListSortSchema.default("type_first"),
|
|
75699
|
+
include_git_status: z.boolean().default(false)
|
|
75700
|
+
});
|
|
75701
|
+
const fsListManyPartialErrorSchema = z.object({
|
|
75702
|
+
code: z.number().int(),
|
|
75703
|
+
msg: z.string()
|
|
75704
|
+
});
|
|
75705
|
+
z.object({
|
|
75706
|
+
results: z.record(z.string(), z.array(fsEntrySchema)),
|
|
75707
|
+
truncated_paths: z.array(z.string()).optional(),
|
|
75708
|
+
partial_errors: z.record(z.string(), fsListManyPartialErrorSchema).optional()
|
|
75709
|
+
});
|
|
75710
|
+
z.object({ path: z.string().min(1) });
|
|
75711
|
+
z.object({ paths: z.array(z.string().min(1)).min(1).max(1e3) });
|
|
75712
|
+
z.object({ entries: z.record(z.string(), fsEntrySchema.nullable()) });
|
|
75713
|
+
z.object({
|
|
75714
|
+
query: z.string().min(1),
|
|
75715
|
+
limit: z.number().int().min(1).max(200).default(50),
|
|
75716
|
+
include_globs: z.array(z.string()).optional(),
|
|
75717
|
+
exclude_globs: z.array(z.string()).optional(),
|
|
75718
|
+
follow_gitignore: z.boolean().default(true)
|
|
75719
|
+
});
|
|
75720
|
+
z.object({
|
|
75721
|
+
items: z.array(fsSearchHitSchema),
|
|
75722
|
+
truncated: z.boolean()
|
|
75723
|
+
});
|
|
75724
|
+
z.object({
|
|
75725
|
+
pattern: z.string().min(1),
|
|
75726
|
+
regex: z.boolean().default(false),
|
|
75727
|
+
case_sensitive: z.boolean().default(true),
|
|
75728
|
+
include_globs: z.array(z.string()).optional(),
|
|
75729
|
+
exclude_globs: z.array(z.string()).optional(),
|
|
75730
|
+
follow_gitignore: z.boolean().default(true),
|
|
75731
|
+
max_files: z.number().int().min(1).max(1e4).default(200),
|
|
75732
|
+
max_matches_per_file: z.number().int().min(1).max(1e4).default(50),
|
|
75733
|
+
max_total_matches: z.number().int().min(1).max(1e5).default(5e3),
|
|
75734
|
+
context_lines: z.number().int().min(0).max(10).default(2)
|
|
75735
|
+
});
|
|
75736
|
+
z.object({
|
|
75737
|
+
files: z.array(fsGrepFileHitSchema),
|
|
75738
|
+
files_scanned: z.number().int().nonnegative(),
|
|
75739
|
+
truncated: z.boolean(),
|
|
75740
|
+
elapsed_ms: z.number().int().nonnegative()
|
|
75741
|
+
});
|
|
75742
|
+
z.object({ paths: z.array(z.string().min(1)).optional() });
|
|
75743
|
+
z.object({
|
|
75744
|
+
branch: z.string(),
|
|
75745
|
+
ahead: z.number().int().nonnegative(),
|
|
75746
|
+
behind: z.number().int().nonnegative(),
|
|
75747
|
+
entries: z.record(z.string(), fsGitStatusSchema)
|
|
75748
|
+
});
|
|
75749
|
+
z.object({
|
|
75750
|
+
path: z.string().min(1),
|
|
75751
|
+
range: z.string().optional(),
|
|
75752
|
+
if_none_match: z.string().optional()
|
|
75753
|
+
});
|
|
75754
|
+
z.object({ file_id: z.string().min(1) });
|
|
75755
|
+
z.object({ file_id: z.string().min(1) });
|
|
75756
|
+
z.object({ deleted: z.literal(true) });
|
|
75757
|
+
z.object({ items: z.array(modelCatalogItemSchema) });
|
|
75758
|
+
z.object({ items: z.array(providerCatalogItemSchema) });
|
|
75759
|
+
z.object({
|
|
75760
|
+
default_model: z.string().min(1),
|
|
75761
|
+
model: modelCatalogItemSchema
|
|
75762
|
+
});
|
|
74406
75763
|
//#endregion
|
|
74407
75764
|
//#region ../../packages/agent-core/src/mcp/oauth/callback-server.ts
|
|
74408
75765
|
/**
|
|
@@ -80754,9 +82111,19 @@ var SkillTool = class SkillTool {
|
|
|
80754
82111
|
const skillArgs = args.args ?? "";
|
|
80755
82112
|
if (!isInlineSkillType(skill.metadata.type)) return errorResult(`Skill "${skill.name}" is not an inline skill and cannot be invoked by the model in v1.`);
|
|
80756
82113
|
const origin = skillOrigin(skill, skillArgs, currentDepth);
|
|
82114
|
+
const promptTrigger = origin.trigger === "nested-skill" ? "nested-skill" : "model-tool";
|
|
80757
82115
|
skills.recordActivation(origin);
|
|
80758
82116
|
const skillContent = skills.registry.renderSkillPrompt(skill, skillArgs);
|
|
80759
|
-
this.agent.context.
|
|
82117
|
+
this.agent.context.appendUserMessage([{
|
|
82118
|
+
type: "text",
|
|
82119
|
+
text: renderModelToolSkillPrompt({
|
|
82120
|
+
skillName: skill.name,
|
|
82121
|
+
skillArgs,
|
|
82122
|
+
skillContent,
|
|
82123
|
+
skillSource: skill.source,
|
|
82124
|
+
trigger: promptTrigger
|
|
82125
|
+
})
|
|
82126
|
+
}], origin);
|
|
80760
82127
|
return { output: `Skill "${skill.name}" loaded inline. Follow its instructions.` };
|
|
80761
82128
|
}
|
|
80762
82129
|
};
|
|
@@ -80816,7 +82183,7 @@ function makeCarriageReturnsVisible(text) {
|
|
|
80816
82183
|
}
|
|
80817
82184
|
//#endregion
|
|
80818
82185
|
//#region ../../packages/agent-core/src/tools/builtin/file/edit.md
|
|
80819
|
-
var edit_default = "Perform exact
|
|
82186
|
+
var edit_default = "Perform exact replacements in existing files.\n\n- Edit is mandatory for every incremental change, especially small edits. DO NOT use Write or Bash `sed`.\n- Read the target file before every Edit. DO NOT call Edit from memory, stale context, or a guessed `old_string`.\n- Take `old_string` and `new_string` from the Read output view.\n- Drop the line-number prefix and tab; match only file content.\n- `old_string` must be unique unless `replace_all` is set.\n- If `old_string` is ambiguous, add surrounding context. Use `replace_all` only when every occurrence should change.\n- Multiple Edit calls may run in one response only when they do not target the same file.\n- DO NOT issue consecutive Edit calls on the same file. A previous Edit can invalidate a later Edit's `old_string`, causing `old_string not found`. Read the file again before the next Edit.\n- A write lock serializes same-file edits in response order, but serialization does not make stale `old_string` valid.\n- For pure CRLF files, Read shows LF; use LF in `old_string` and `new_string`, and Edit writes CRLF back.\n- For mixed endings or lone carriage returns, Read shows carriage returns as \\r; include actual \\r escapes in those positions.\n";
|
|
80820
82187
|
//#endregion
|
|
80821
82188
|
//#region ../../packages/agent-core/src/tools/builtin/file/edit.ts
|
|
80822
82189
|
const EditInputSchema = z.object({
|
|
@@ -87103,7 +88470,7 @@ var ReadMediaFileTool = class {
|
|
|
87103
88470
|
};
|
|
87104
88471
|
//#endregion
|
|
87105
88472
|
//#region ../../packages/agent-core/src/tools/builtin/file/write.md
|
|
87106
|
-
var write_default = "
|
|
88473
|
+
var write_default = "Create, append to, or replace a file entirely.\n\n- The parent directory must already exist.\n- Mode defaults to overwrite; append adds content at EOF without adding a newline.\n- Write is NOT ALLOWED for incremental changes to existing files, including trivial, one-line, quick, or cosmetic edits. Use Edit instead.\n- Use Write only when the file does not exist, you intend a complete replacement, or the new contents have little continuity with the old contents.\n- Read before overwriting an existing file.\n- Write ignores the Read/Edit line-number view. NEVER include line prefixes.\n- Write outputs content literally, including supplied line endings: \\n stays LF, \\r\\n stays CRLF.\n- For new content too large for one call, overwrite the first chunk, then append subsequent chunks. Never chunk Write to modify an existing file.\n";
|
|
87107
88474
|
//#endregion
|
|
87108
88475
|
//#region ../../packages/agent-core/src/tools/builtin/file/write.ts
|
|
87109
88476
|
/** Mask isolating the file-type bits of a stat mode. */
|
|
@@ -87893,6 +89260,10 @@ var TurnFlow = class {
|
|
|
87893
89260
|
}
|
|
87894
89261
|
}
|
|
87895
89262
|
if (this.currentId === turnId) this.agent.usage.endTurn();
|
|
89263
|
+
if (ended.reason === "cancelled" && isUserCancellation(signal.reason)) this.agent.hooks?.fireAndForgetTrigger("Interrupt", { inputData: {
|
|
89264
|
+
turnId,
|
|
89265
|
+
reason: "cancelled"
|
|
89266
|
+
} });
|
|
87896
89267
|
this.agent.emitEvent(ended);
|
|
87897
89268
|
if (standalone && this.currentId === turnId) this.activeTurn = null;
|
|
87898
89269
|
if (this.agent.swarmMode.shouldAutoExit) this.agent.swarmMode.exit();
|
|
@@ -137212,6 +138583,9 @@ new AsyncLocalStorage();
|
|
|
137212
138583
|
//#endregion
|
|
137213
138584
|
//#region ../../packages/agent-core/src/rpc/core-impl.ts
|
|
137214
138585
|
const KIMI_CODE_PROVIDER_NAME$1 = "managed:kimi-code";
|
|
138586
|
+
const KIMI_CODE_BASE_URL_ENV = "KIMI_CODE_BASE_URL";
|
|
138587
|
+
const KIMI_CODE_OAUTH_HOST_ENV = "KIMI_CODE_OAUTH_HOST";
|
|
138588
|
+
const KIMI_OAUTH_HOST_ENV = "KIMI_OAUTH_HOST";
|
|
137215
138589
|
var KimiCore = class {
|
|
137216
138590
|
rpcClient;
|
|
137217
138591
|
sdk;
|
|
@@ -137417,6 +138791,7 @@ var KimiCore = class {
|
|
|
137417
138791
|
async forkSession(input) {
|
|
137418
138792
|
const source = await this.sessionStore.get(input.sessionId);
|
|
137419
138793
|
const active = this.sessions.get(source.id);
|
|
138794
|
+
if (active?.hasActiveTurn === true) throw new KimiError(ErrorCodes.SESSION_FORK_ACTIVE_TURN, `Session "${source.id}" cannot be forked while a turn is running`, { details: { sessionId: source.id } });
|
|
137420
138795
|
if (active !== void 0) await active.flushMetadata();
|
|
137421
138796
|
const id = input.id ?? createSessionId();
|
|
137422
138797
|
await this.sessionStore.fork({
|
|
@@ -137700,13 +139075,38 @@ var KimiCore = class {
|
|
|
137700
139075
|
});
|
|
137701
139076
|
}
|
|
137702
139077
|
mergePluginMcpConfig(base) {
|
|
137703
|
-
const pluginServers = this.plugins.enabledMcpServers();
|
|
139078
|
+
const pluginServers = this.withManagedKimiPluginEnv(this.plugins.enabledMcpServers());
|
|
137704
139079
|
if (Object.keys(pluginServers).length === 0) return base;
|
|
137705
139080
|
return { servers: {
|
|
137706
139081
|
...base?.servers,
|
|
137707
139082
|
...pluginServers
|
|
137708
139083
|
} };
|
|
137709
139084
|
}
|
|
139085
|
+
withManagedKimiPluginEnv(pluginServers) {
|
|
139086
|
+
const managedEnv = this.managedKimiCodeEnvForPlugins();
|
|
139087
|
+
if (Object.keys(managedEnv).length === 0) return pluginServers;
|
|
139088
|
+
const out = {};
|
|
139089
|
+
for (const [name, server] of Object.entries(pluginServers)) out[name] = server.transport === "stdio" ? {
|
|
139090
|
+
...server,
|
|
139091
|
+
env: {
|
|
139092
|
+
...server.env,
|
|
139093
|
+
...managedEnv
|
|
139094
|
+
}
|
|
139095
|
+
} : server;
|
|
139096
|
+
return out;
|
|
139097
|
+
}
|
|
139098
|
+
managedKimiCodeEnvForPlugins() {
|
|
139099
|
+
const provider = this.config.providers[KIMI_CODE_PROVIDER_NAME$1];
|
|
139100
|
+
const envBaseUrl = process.env[KIMI_CODE_BASE_URL_ENV];
|
|
139101
|
+
const envOAuthHost = process.env[KIMI_CODE_OAUTH_HOST_ENV] ?? process.env[KIMI_OAUTH_HOST_ENV];
|
|
139102
|
+
const hasEnvOverride = envBaseUrl !== void 0 || envOAuthHost !== void 0;
|
|
139103
|
+
const baseUrl = envBaseUrl !== void 0 ? envBaseUrl.replace(/\/+$/, "") : provider?.baseUrl;
|
|
139104
|
+
const oauthHost = hasEnvOverride ? envOAuthHost : provider?.oauth?.oauthHost;
|
|
139105
|
+
const env = {};
|
|
139106
|
+
if (baseUrl !== void 0) env[KIMI_CODE_BASE_URL_ENV] = baseUrl;
|
|
139107
|
+
if (oauthHost !== void 0) env[KIMI_CODE_OAUTH_HOST_ENV] = oauthHost;
|
|
139108
|
+
return env;
|
|
139109
|
+
}
|
|
137710
139110
|
sessionApi(sessionId) {
|
|
137711
139111
|
const session = this.sessions.get(sessionId);
|
|
137712
139112
|
if (session === void 0) throw new KimiError(ErrorCodes.SESSION_NOT_FOUND, `Session "${sessionId}" was not found`, { details: { sessionId } });
|
|
@@ -160203,6 +161603,163 @@ var WelcomeComponent = class {
|
|
|
160203
161603
|
}
|
|
160204
161604
|
};
|
|
160205
161605
|
//#endregion
|
|
161606
|
+
//#region src/tui/components/dialogs/compaction.ts
|
|
161607
|
+
/**
|
|
161608
|
+
* Renders a compaction block in the transcript.
|
|
161609
|
+
*
|
|
161610
|
+
* Lifecycle:
|
|
161611
|
+
* - constructed on `compaction.started` → blinking white bullet +
|
|
161612
|
+
* "Compacting context..." and optional custom instruction
|
|
161613
|
+
* - `markDone()` on `compaction.completed` → solid green bullet +
|
|
161614
|
+
* "Compaction complete (X → Y tokens)"
|
|
161615
|
+
* - `markCanceled()` on `compaction.cancelled` → solid warning bullet +
|
|
161616
|
+
* "Compaction cancelled"
|
|
161617
|
+
*
|
|
161618
|
+
* Bullet animation mirrors `ToolCallComponent` (500ms blink) so the user
|
|
161619
|
+
* reads the same "work in progress" signal across the UI.
|
|
161620
|
+
*/
|
|
161621
|
+
const BLINK_INTERVAL = 500;
|
|
161622
|
+
var CompactionComponent = class extends Container {
|
|
161623
|
+
ui;
|
|
161624
|
+
headerText;
|
|
161625
|
+
instruction;
|
|
161626
|
+
blinkOn = true;
|
|
161627
|
+
blinkTimer = null;
|
|
161628
|
+
done = false;
|
|
161629
|
+
canceled = false;
|
|
161630
|
+
tokensBefore;
|
|
161631
|
+
tokensAfter;
|
|
161632
|
+
constructor(ui, instruction) {
|
|
161633
|
+
super();
|
|
161634
|
+
this.ui = ui;
|
|
161635
|
+
this.instruction = instruction;
|
|
161636
|
+
this.addChild(new Spacer(1));
|
|
161637
|
+
this.headerText = new Text(this.buildHeader(), 0, 0);
|
|
161638
|
+
this.addChild(this.headerText);
|
|
161639
|
+
this.addInstructionChild();
|
|
161640
|
+
this.startBlink();
|
|
161641
|
+
}
|
|
161642
|
+
addInstructionChild() {
|
|
161643
|
+
if (this.instruction !== void 0) this.addChild(new Text(currentTheme.dim(` ${this.instruction}`), 0, 0));
|
|
161644
|
+
}
|
|
161645
|
+
invalidate() {
|
|
161646
|
+
this.headerText.setText(this.buildHeader());
|
|
161647
|
+
if (this.instruction !== void 0) {
|
|
161648
|
+
if (this.children.length > 2) this.children.pop();
|
|
161649
|
+
this.addInstructionChild();
|
|
161650
|
+
}
|
|
161651
|
+
super.invalidate();
|
|
161652
|
+
}
|
|
161653
|
+
markDone(tokensBefore, tokensAfter) {
|
|
161654
|
+
if (this.done || this.canceled) return;
|
|
161655
|
+
this.done = true;
|
|
161656
|
+
this.tokensBefore = tokensBefore;
|
|
161657
|
+
this.tokensAfter = tokensAfter;
|
|
161658
|
+
this.stopBlink();
|
|
161659
|
+
this.headerText.setText(this.buildHeader());
|
|
161660
|
+
this.ui?.requestRender();
|
|
161661
|
+
}
|
|
161662
|
+
markCanceled() {
|
|
161663
|
+
if (this.done || this.canceled) return;
|
|
161664
|
+
this.canceled = true;
|
|
161665
|
+
this.stopBlink();
|
|
161666
|
+
this.headerText.setText(this.buildHeader());
|
|
161667
|
+
this.ui?.requestRender();
|
|
161668
|
+
}
|
|
161669
|
+
dispose() {
|
|
161670
|
+
this.stopBlink();
|
|
161671
|
+
}
|
|
161672
|
+
buildHeader() {
|
|
161673
|
+
if (this.done) return `${currentTheme.fg("success", STATUS_BULLET)}${currentTheme.boldFg("success", "Compaction complete")}${this.tokensBefore !== void 0 && this.tokensAfter !== void 0 ? currentTheme.dim(` (${String(this.tokensBefore)} → ${String(this.tokensAfter)} tokens)`) : ""}`;
|
|
161674
|
+
if (this.canceled) return `${currentTheme.fg("warning", STATUS_BULLET)}${currentTheme.boldFg("warning", "Compaction cancelled")}`;
|
|
161675
|
+
return `${this.blinkOn ? currentTheme.fg("text", STATUS_BULLET) : " "}${currentTheme.boldFg("primary", "Compacting context...")}`;
|
|
161676
|
+
}
|
|
161677
|
+
startBlink() {
|
|
161678
|
+
this.blinkTimer = setInterval(() => {
|
|
161679
|
+
this.blinkOn = !this.blinkOn;
|
|
161680
|
+
this.headerText.setText(this.buildHeader());
|
|
161681
|
+
this.ui?.requestRender();
|
|
161682
|
+
}, BLINK_INTERVAL);
|
|
161683
|
+
}
|
|
161684
|
+
stopBlink() {
|
|
161685
|
+
if (this.blinkTimer !== null) {
|
|
161686
|
+
clearInterval(this.blinkTimer);
|
|
161687
|
+
this.blinkTimer = null;
|
|
161688
|
+
}
|
|
161689
|
+
}
|
|
161690
|
+
};
|
|
161691
|
+
//#endregion
|
|
161692
|
+
//#region src/tui/components/dialogs/undo-selector.ts
|
|
161693
|
+
const MAX_VISIBLE_CHOICES = 5;
|
|
161694
|
+
const PREFERRED_SELECTED_OFFSET = 2;
|
|
161695
|
+
var UndoSelectorComponent = class extends Container {
|
|
161696
|
+
focused = false;
|
|
161697
|
+
opts;
|
|
161698
|
+
list;
|
|
161699
|
+
submitted = false;
|
|
161700
|
+
constructor(opts) {
|
|
161701
|
+
super();
|
|
161702
|
+
this.opts = opts;
|
|
161703
|
+
this.list = new SearchableList({
|
|
161704
|
+
items: opts.choices,
|
|
161705
|
+
toSearchText: (choice) => choice.label,
|
|
161706
|
+
initialIndex: Math.max(0, opts.choices.length - 1)
|
|
161707
|
+
});
|
|
161708
|
+
}
|
|
161709
|
+
handleInput(data) {
|
|
161710
|
+
if (this.submitted) return;
|
|
161711
|
+
if (matchesKey(data, Key.escape)) {
|
|
161712
|
+
this.opts.onCancel();
|
|
161713
|
+
return;
|
|
161714
|
+
}
|
|
161715
|
+
if (this.list.handleKey(data)) return;
|
|
161716
|
+
if (matchesKey(data, Key.enter)) {
|
|
161717
|
+
const selected = this.list.selected();
|
|
161718
|
+
if (selected !== void 0) {
|
|
161719
|
+
this.submitted = true;
|
|
161720
|
+
this.opts.onSelect(selected);
|
|
161721
|
+
}
|
|
161722
|
+
}
|
|
161723
|
+
}
|
|
161724
|
+
render(width) {
|
|
161725
|
+
const view = this.list.view();
|
|
161726
|
+
const lines = [
|
|
161727
|
+
currentTheme.fg("primary", "─".repeat(width)),
|
|
161728
|
+
currentTheme.boldFg("primary", " Select messages to undo"),
|
|
161729
|
+
currentTheme.fg("textMuted", " " + [
|
|
161730
|
+
"↑↓ navigate",
|
|
161731
|
+
"Enter select",
|
|
161732
|
+
"Esc cancel"
|
|
161733
|
+
].join(" · ")),
|
|
161734
|
+
""
|
|
161735
|
+
];
|
|
161736
|
+
if (view.items.length === 0) lines.push(currentTheme.fg("textMuted", " No messages"));
|
|
161737
|
+
else {
|
|
161738
|
+
const visibleCount = Math.min(MAX_VISIBLE_CHOICES, view.items.length);
|
|
161739
|
+
const maxStart = view.items.length - visibleCount;
|
|
161740
|
+
const start = Math.min(Math.max(0, view.selectedIndex - PREFERRED_SELECTED_OFFSET), maxStart);
|
|
161741
|
+
const end = start + visibleCount;
|
|
161742
|
+
for (let i = start; i < end; i++) {
|
|
161743
|
+
const choice = view.items[i];
|
|
161744
|
+
if (choice === void 0) continue;
|
|
161745
|
+
lines.push(this.renderChoiceLine(choice, i === view.selectedIndex, i > view.selectedIndex, width));
|
|
161746
|
+
}
|
|
161747
|
+
}
|
|
161748
|
+
lines.push("");
|
|
161749
|
+
lines.push(currentTheme.fg("primary", "─".repeat(width)));
|
|
161750
|
+
return lines.map((line) => truncateToWidth(line, width));
|
|
161751
|
+
}
|
|
161752
|
+
renderChoiceLine(choice, isSelected, inUndoRange, width) {
|
|
161753
|
+
const prefix = ` ${isSelected ? "❯" : " "} `;
|
|
161754
|
+
const labelBudget = Math.max(8, width - visibleWidth(prefix));
|
|
161755
|
+
const label = truncateToWidth(choice.label, labelBudget, "…");
|
|
161756
|
+
const token = isSelected ? "primary" : inUndoRange ? "textDim" : "text";
|
|
161757
|
+
let line = currentTheme.fg(isSelected ? "primary" : "textDim", prefix);
|
|
161758
|
+
line += isSelected ? currentTheme.boldFg(token, label) : currentTheme.fg(token, label);
|
|
161759
|
+
return line;
|
|
161760
|
+
}
|
|
161761
|
+
};
|
|
161762
|
+
//#endregion
|
|
160206
161763
|
//#region src/tui/components/messages/agent-group.ts
|
|
160207
161764
|
const THROTTLE_MS$1 = 200;
|
|
160208
161765
|
var AgentGroupComponent = class extends Container {
|
|
@@ -164517,34 +166074,64 @@ function getTranscriptComponentEntry(component) {
|
|
|
164517
166074
|
return componentEntries.get(component);
|
|
164518
166075
|
}
|
|
164519
166076
|
//#endregion
|
|
166077
|
+
//#region src/tui/utils/transcript-id.ts
|
|
166078
|
+
let transcriptIdCounter = 0;
|
|
166079
|
+
function nextTranscriptId() {
|
|
166080
|
+
transcriptIdCounter += 1;
|
|
166081
|
+
return `entry-${String(transcriptIdCounter)}`;
|
|
166082
|
+
}
|
|
166083
|
+
//#endregion
|
|
164520
166084
|
//#region src/tui/commands/undo.ts
|
|
166085
|
+
const UNDO_LIMIT_STATUS_TURN_ID = "undo-limit-status";
|
|
164521
166086
|
async function handleUndoCommand(host, args = "") {
|
|
164522
166087
|
if (host.state.appState.streamingPhase !== "idle") {
|
|
164523
166088
|
host.showError("Cannot undo while streaming — press Esc or Ctrl-C first.");
|
|
164524
166089
|
return;
|
|
164525
166090
|
}
|
|
164526
|
-
const
|
|
166091
|
+
const trimmed = args.trim();
|
|
166092
|
+
if (trimmed.length === 0) {
|
|
166093
|
+
await showUndoSelector(host);
|
|
166094
|
+
return;
|
|
166095
|
+
}
|
|
166096
|
+
const count = parseUndoCount(trimmed);
|
|
164527
166097
|
if (count === void 0) {
|
|
164528
166098
|
host.showError("Usage: /undo [count], where count is a positive integer.");
|
|
164529
166099
|
return;
|
|
164530
166100
|
}
|
|
166101
|
+
if (host.session === void 0) {
|
|
166102
|
+
host.showError(NO_ACTIVE_SESSION_MESSAGE);
|
|
166103
|
+
return;
|
|
166104
|
+
}
|
|
166105
|
+
const availability = await resolveUndoAvailability(host);
|
|
166106
|
+
if (count > availability.maxCount) {
|
|
166107
|
+
showUndoLimitStatus(host, formatUndoLimitMessage(count, availability));
|
|
166108
|
+
return;
|
|
166109
|
+
}
|
|
166110
|
+
await undoByCount(host, count);
|
|
166111
|
+
}
|
|
166112
|
+
async function undoByCount(host, count) {
|
|
164531
166113
|
const session = host.session;
|
|
164532
166114
|
if (session === void 0) {
|
|
164533
166115
|
host.showError(NO_ACTIVE_SESSION_MESSAGE);
|
|
164534
|
-
return;
|
|
166116
|
+
return false;
|
|
164535
166117
|
}
|
|
164536
166118
|
const entries = host.state.transcriptEntries;
|
|
164537
166119
|
const lastUserIndex = findUndoAnchorEntryIndex(entries, count);
|
|
164538
166120
|
if (lastUserIndex === void 0) {
|
|
164539
|
-
host
|
|
164540
|
-
return;
|
|
166121
|
+
showUndoLimitStatus(host, "Nothing to undo.");
|
|
166122
|
+
return false;
|
|
164541
166123
|
}
|
|
164542
166124
|
try {
|
|
164543
166125
|
await session.undoHistory(count);
|
|
164544
166126
|
} catch (error) {
|
|
166127
|
+
const limit = undoLimitFromError(error);
|
|
166128
|
+
if (limit !== void 0) {
|
|
166129
|
+
showUndoLimitStatus(host, formatUndoLimitMessage(limit.requestedCount, limit));
|
|
166130
|
+
return false;
|
|
166131
|
+
}
|
|
164545
166132
|
const message = formatErrorMessage$2(error);
|
|
164546
166133
|
host.showError(`Failed to undo: ${message}`);
|
|
164547
|
-
return;
|
|
166134
|
+
return false;
|
|
164548
166135
|
}
|
|
164549
166136
|
const children = host.state.transcriptContainer.children;
|
|
164550
166137
|
const lastUserComponentIndex = findUndoAnchorComponentIndex(children, count);
|
|
@@ -164556,6 +166143,34 @@ async function handleUndoCommand(host, args = "") {
|
|
|
164556
166143
|
entries.splice(lastUserIndex, entries.length - lastUserIndex, ...preservedEntries);
|
|
164557
166144
|
if (entries.length === 0) renderWelcome(host);
|
|
164558
166145
|
host.state.ui.requestRender();
|
|
166146
|
+
return true;
|
|
166147
|
+
}
|
|
166148
|
+
async function showUndoSelector(host) {
|
|
166149
|
+
if (host.session === void 0) {
|
|
166150
|
+
host.showError(NO_ACTIVE_SESSION_MESSAGE);
|
|
166151
|
+
return;
|
|
166152
|
+
}
|
|
166153
|
+
const availability = await resolveUndoAvailability(host);
|
|
166154
|
+
const choices = createUndoChoices(host.state.transcriptEntries, host.state.transcriptContainer.children, availability.maxCount);
|
|
166155
|
+
if (choices.length === 0) {
|
|
166156
|
+
showUndoLimitStatus(host, formatNothingToUndoMessage(availability));
|
|
166157
|
+
return;
|
|
166158
|
+
}
|
|
166159
|
+
host.mountEditorReplacement(new UndoSelectorComponent({
|
|
166160
|
+
choices,
|
|
166161
|
+
onSelect: (choice) => {
|
|
166162
|
+
undoByCount(host, choice.count).then((undone) => {
|
|
166163
|
+
if (undone) {
|
|
166164
|
+
host.restoreInputText(choice.input);
|
|
166165
|
+
return;
|
|
166166
|
+
}
|
|
166167
|
+
host.restoreEditor();
|
|
166168
|
+
});
|
|
166169
|
+
},
|
|
166170
|
+
onCancel: () => {
|
|
166171
|
+
host.restoreEditor();
|
|
166172
|
+
}
|
|
166173
|
+
}));
|
|
164559
166174
|
}
|
|
164560
166175
|
function parseUndoCount(args) {
|
|
164561
166176
|
const value = args.trim();
|
|
@@ -164564,6 +166179,138 @@ function parseUndoCount(args) {
|
|
|
164564
166179
|
const count = Number(value);
|
|
164565
166180
|
return Number.isSafeInteger(count) ? count : void 0;
|
|
164566
166181
|
}
|
|
166182
|
+
async function resolveUndoAvailability(host) {
|
|
166183
|
+
const local = undoAvailabilityFromTranscript(host.state.transcriptEntries, host.state.transcriptContainer.children);
|
|
166184
|
+
const context = await getSessionContext(host.session);
|
|
166185
|
+
if (context === void 0) return local;
|
|
166186
|
+
const activeContext = undoAvailabilityFromContext(context.history);
|
|
166187
|
+
return {
|
|
166188
|
+
maxCount: Math.min(local.maxCount, activeContext.maxCount),
|
|
166189
|
+
stoppedAtCompaction: local.stoppedAtCompaction || activeContext.stoppedAtCompaction
|
|
166190
|
+
};
|
|
166191
|
+
}
|
|
166192
|
+
async function getSessionContext(session) {
|
|
166193
|
+
const getContext = session?.getContext;
|
|
166194
|
+
if (session === void 0 || getContext === void 0) return void 0;
|
|
166195
|
+
try {
|
|
166196
|
+
return await getContext.call(session);
|
|
166197
|
+
} catch {
|
|
166198
|
+
return;
|
|
166199
|
+
}
|
|
166200
|
+
}
|
|
166201
|
+
function undoAvailabilityFromTranscript(entries, children) {
|
|
166202
|
+
const { anchors, stoppedAtCompaction } = activeUndoAnchorEntries(entries, children);
|
|
166203
|
+
return {
|
|
166204
|
+
maxCount: anchors.length,
|
|
166205
|
+
stoppedAtCompaction
|
|
166206
|
+
};
|
|
166207
|
+
}
|
|
166208
|
+
function undoAvailabilityFromContext(history) {
|
|
166209
|
+
let maxCount = 0;
|
|
166210
|
+
let stoppedAtCompaction = false;
|
|
166211
|
+
for (let i = history.length - 1; i >= 0; i--) {
|
|
166212
|
+
const message = history[i];
|
|
166213
|
+
if (message === void 0) continue;
|
|
166214
|
+
if (message.origin?.kind === "injection") continue;
|
|
166215
|
+
if (message.origin?.kind === "compaction_summary") {
|
|
166216
|
+
stoppedAtCompaction = true;
|
|
166217
|
+
break;
|
|
166218
|
+
}
|
|
166219
|
+
if (isContextUndoAnchor(message)) maxCount++;
|
|
166220
|
+
}
|
|
166221
|
+
return {
|
|
166222
|
+
maxCount,
|
|
166223
|
+
stoppedAtCompaction
|
|
166224
|
+
};
|
|
166225
|
+
}
|
|
166226
|
+
function isContextUndoAnchor(message) {
|
|
166227
|
+
if (message.role !== "user") return false;
|
|
166228
|
+
const origin = message.origin;
|
|
166229
|
+
if (origin === void 0 || origin.kind === "user") return true;
|
|
166230
|
+
if (origin.kind === "skill_activation") return origin.trigger === "user-slash";
|
|
166231
|
+
return false;
|
|
166232
|
+
}
|
|
166233
|
+
function createUndoChoices(entries, children, maxCount) {
|
|
166234
|
+
if (maxCount <= 0) return [];
|
|
166235
|
+
const anchors = activeUndoAnchorEntries(entries, children).anchors.slice(-maxCount);
|
|
166236
|
+
return anchors.map((entry, index) => ({
|
|
166237
|
+
id: entry.id,
|
|
166238
|
+
count: anchors.length - index,
|
|
166239
|
+
input: formatUndoChoiceInput(entry),
|
|
166240
|
+
label: formatUndoChoiceLabel(entry)
|
|
166241
|
+
}));
|
|
166242
|
+
}
|
|
166243
|
+
function activeUndoAnchorEntries(entries, children) {
|
|
166244
|
+
const lastCompactionChildIndex = children.findLastIndex((child) => child instanceof CompactionComponent);
|
|
166245
|
+
if (lastCompactionChildIndex >= 0) return {
|
|
166246
|
+
anchors: children.slice(lastCompactionChildIndex + 1).map((child) => getTranscriptComponentEntry(child)).filter((entry) => entry !== void 0).filter(isUndoAnchorEntry),
|
|
166247
|
+
stoppedAtCompaction: true
|
|
166248
|
+
};
|
|
166249
|
+
const lastCompactionEntryIndex = entries.findLastIndex((entry) => entry.compactionData !== void 0);
|
|
166250
|
+
return {
|
|
166251
|
+
anchors: (lastCompactionEntryIndex >= 0 ? entries.slice(lastCompactionEntryIndex + 1) : entries).filter(isUndoAnchorEntry),
|
|
166252
|
+
stoppedAtCompaction: lastCompactionEntryIndex >= 0
|
|
166253
|
+
};
|
|
166254
|
+
}
|
|
166255
|
+
function formatUndoChoiceLabel(entry) {
|
|
166256
|
+
if (entry.kind === "skill_activation") {
|
|
166257
|
+
const name = singleLine$2(entry.skillName ?? entry.content.replace(/^Activated skill:\s*/, ""));
|
|
166258
|
+
const args = singleLine$2(entry.skillArgs ?? "");
|
|
166259
|
+
if (name.length === 0) return "Skill: unknown";
|
|
166260
|
+
return args.length > 0 ? `/${name} ${args}` : `/${name}`;
|
|
166261
|
+
}
|
|
166262
|
+
const content = singleLine$2(entry.content);
|
|
166263
|
+
const imageCount = entry.imageAttachmentIds?.length ?? 0;
|
|
166264
|
+
if (content.length > 0) return content;
|
|
166265
|
+
if (imageCount > 0) return `User message (${String(imageCount)} ${imageCount === 1 ? "image" : "images"})`;
|
|
166266
|
+
return "User message";
|
|
166267
|
+
}
|
|
166268
|
+
function formatUndoChoiceInput(entry) {
|
|
166269
|
+
if (entry.kind === "skill_activation") {
|
|
166270
|
+
const name = singleLine$2(entry.skillName ?? entry.content.replace(/^Activated skill:\s*/, ""));
|
|
166271
|
+
const args = singleLine$2(entry.skillArgs ?? "");
|
|
166272
|
+
if (name.length === 0) return "";
|
|
166273
|
+
return args.length > 0 ? `/${name} ${args}` : `/${name}`;
|
|
166274
|
+
}
|
|
166275
|
+
return entry.content;
|
|
166276
|
+
}
|
|
166277
|
+
function singleLine$2(text) {
|
|
166278
|
+
return text.replaceAll(/\s+/g, " ").trim();
|
|
166279
|
+
}
|
|
166280
|
+
function formatUndoLimitMessage(requestedCount, availability) {
|
|
166281
|
+
const reason = availability.stoppedAtCompaction ? " after the last compaction" : "";
|
|
166282
|
+
return `Cannot undo ${formatPromptCount(requestedCount)}; only ${formatPromptCount(availability.maxCount)} can be undone in the active context${reason}.`;
|
|
166283
|
+
}
|
|
166284
|
+
function formatNothingToUndoMessage(availability) {
|
|
166285
|
+
if (availability.stoppedAtCompaction) return "Nothing to undo after the last compaction.";
|
|
166286
|
+
return "Nothing to undo.";
|
|
166287
|
+
}
|
|
166288
|
+
function formatPromptCount(count) {
|
|
166289
|
+
return `${String(count)} ${count === 1 ? "prompt" : "prompts"}`;
|
|
166290
|
+
}
|
|
166291
|
+
function showUndoLimitStatus(host, message) {
|
|
166292
|
+
host.appendTranscriptEntry({
|
|
166293
|
+
id: nextTranscriptId(),
|
|
166294
|
+
kind: "status",
|
|
166295
|
+
turnId: UNDO_LIMIT_STATUS_TURN_ID,
|
|
166296
|
+
renderMode: "plain",
|
|
166297
|
+
content: message
|
|
166298
|
+
});
|
|
166299
|
+
}
|
|
166300
|
+
function undoLimitFromError(error) {
|
|
166301
|
+
if (!isKimiError(error)) return void 0;
|
|
166302
|
+
const details = error.details;
|
|
166303
|
+
if (details?.["reason"] !== "undo_limit") return void 0;
|
|
166304
|
+
const requestedCount = details["requestedCount"];
|
|
166305
|
+
const maxCount = details["undoableCount"];
|
|
166306
|
+
const stoppedAtCompaction = details["stoppedAtCompaction"];
|
|
166307
|
+
if (typeof requestedCount !== "number" || typeof maxCount !== "number" || typeof stoppedAtCompaction !== "boolean") return;
|
|
166308
|
+
return {
|
|
166309
|
+
requestedCount,
|
|
166310
|
+
maxCount,
|
|
166311
|
+
stoppedAtCompaction
|
|
166312
|
+
};
|
|
166313
|
+
}
|
|
164567
166314
|
function isUndoAnchorEntry(entry) {
|
|
164568
166315
|
return entry.kind === "user" || entry.kind === "skill_activation" && entry.skillTrigger === "user-slash";
|
|
164569
166316
|
}
|
|
@@ -166187,92 +167934,6 @@ function stripLeadingSpace(s) {
|
|
|
166187
167934
|
return s.replace(/^ +/, "");
|
|
166188
167935
|
}
|
|
166189
167936
|
//#endregion
|
|
166190
|
-
//#region src/tui/components/dialogs/compaction.ts
|
|
166191
|
-
/**
|
|
166192
|
-
* Renders a compaction block in the transcript.
|
|
166193
|
-
*
|
|
166194
|
-
* Lifecycle:
|
|
166195
|
-
* - constructed on `compaction.started` → blinking white bullet +
|
|
166196
|
-
* "Compacting context..." and optional custom instruction
|
|
166197
|
-
* - `markDone()` on `compaction.completed` → solid green bullet +
|
|
166198
|
-
* "Compaction complete (X → Y tokens)"
|
|
166199
|
-
* - `markCanceled()` on `compaction.cancelled` → solid warning bullet +
|
|
166200
|
-
* "Compaction cancelled"
|
|
166201
|
-
*
|
|
166202
|
-
* Bullet animation mirrors `ToolCallComponent` (500ms blink) so the user
|
|
166203
|
-
* reads the same "work in progress" signal across the UI.
|
|
166204
|
-
*/
|
|
166205
|
-
const BLINK_INTERVAL = 500;
|
|
166206
|
-
var CompactionComponent = class extends Container {
|
|
166207
|
-
ui;
|
|
166208
|
-
headerText;
|
|
166209
|
-
instruction;
|
|
166210
|
-
blinkOn = true;
|
|
166211
|
-
blinkTimer = null;
|
|
166212
|
-
done = false;
|
|
166213
|
-
canceled = false;
|
|
166214
|
-
tokensBefore;
|
|
166215
|
-
tokensAfter;
|
|
166216
|
-
constructor(ui, instruction) {
|
|
166217
|
-
super();
|
|
166218
|
-
this.ui = ui;
|
|
166219
|
-
this.instruction = instruction;
|
|
166220
|
-
this.addChild(new Spacer(1));
|
|
166221
|
-
this.headerText = new Text(this.buildHeader(), 0, 0);
|
|
166222
|
-
this.addChild(this.headerText);
|
|
166223
|
-
this.addInstructionChild();
|
|
166224
|
-
this.startBlink();
|
|
166225
|
-
}
|
|
166226
|
-
addInstructionChild() {
|
|
166227
|
-
if (this.instruction !== void 0) this.addChild(new Text(currentTheme.dim(` ${this.instruction}`), 0, 0));
|
|
166228
|
-
}
|
|
166229
|
-
invalidate() {
|
|
166230
|
-
this.headerText.setText(this.buildHeader());
|
|
166231
|
-
if (this.instruction !== void 0) {
|
|
166232
|
-
if (this.children.length > 2) this.children.pop();
|
|
166233
|
-
this.addInstructionChild();
|
|
166234
|
-
}
|
|
166235
|
-
super.invalidate();
|
|
166236
|
-
}
|
|
166237
|
-
markDone(tokensBefore, tokensAfter) {
|
|
166238
|
-
if (this.done || this.canceled) return;
|
|
166239
|
-
this.done = true;
|
|
166240
|
-
this.tokensBefore = tokensBefore;
|
|
166241
|
-
this.tokensAfter = tokensAfter;
|
|
166242
|
-
this.stopBlink();
|
|
166243
|
-
this.headerText.setText(this.buildHeader());
|
|
166244
|
-
this.ui?.requestRender();
|
|
166245
|
-
}
|
|
166246
|
-
markCanceled() {
|
|
166247
|
-
if (this.done || this.canceled) return;
|
|
166248
|
-
this.canceled = true;
|
|
166249
|
-
this.stopBlink();
|
|
166250
|
-
this.headerText.setText(this.buildHeader());
|
|
166251
|
-
this.ui?.requestRender();
|
|
166252
|
-
}
|
|
166253
|
-
dispose() {
|
|
166254
|
-
this.stopBlink();
|
|
166255
|
-
}
|
|
166256
|
-
buildHeader() {
|
|
166257
|
-
if (this.done) return `${currentTheme.fg("success", STATUS_BULLET)}${currentTheme.boldFg("success", "Compaction complete")}${this.tokensBefore !== void 0 && this.tokensAfter !== void 0 ? currentTheme.dim(` (${String(this.tokensBefore)} → ${String(this.tokensAfter)} tokens)`) : ""}`;
|
|
166258
|
-
if (this.canceled) return `${currentTheme.fg("warning", STATUS_BULLET)}${currentTheme.boldFg("warning", "Compaction cancelled")}`;
|
|
166259
|
-
return `${this.blinkOn ? currentTheme.fg("text", STATUS_BULLET) : " "}${currentTheme.boldFg("primary", "Compacting context...")}`;
|
|
166260
|
-
}
|
|
166261
|
-
startBlink() {
|
|
166262
|
-
this.blinkTimer = setInterval(() => {
|
|
166263
|
-
this.blinkOn = !this.blinkOn;
|
|
166264
|
-
this.headerText.setText(this.buildHeader());
|
|
166265
|
-
this.ui?.requestRender();
|
|
166266
|
-
}, BLINK_INTERVAL);
|
|
166267
|
-
}
|
|
166268
|
-
stopBlink() {
|
|
166269
|
-
if (this.blinkTimer !== null) {
|
|
166270
|
-
clearInterval(this.blinkTimer);
|
|
166271
|
-
this.blinkTimer = null;
|
|
166272
|
-
}
|
|
166273
|
-
}
|
|
166274
|
-
};
|
|
166275
|
-
//#endregion
|
|
166276
167937
|
//#region src/tui/components/dialogs/help-panel.ts
|
|
166277
167938
|
/**
|
|
166278
167939
|
* HelpPanel — modal `/help` display. Lists keyboard shortcuts, slash
|
|
@@ -169022,6 +170683,14 @@ var EditorKeyboardController = class {
|
|
|
169022
170683
|
};
|
|
169023
170684
|
//#endregion
|
|
169024
170685
|
//#region src/tui/components/messages/goal-markers.ts
|
|
170686
|
+
/**
|
|
170687
|
+
* Low-profile transcript markers for the autonomous goal loop.
|
|
170688
|
+
*
|
|
170689
|
+
* Lifecycle changes (paused / resumed / cancelled) and `no_progress` verdicts
|
|
170690
|
+
* render as a single dim line — `◦ Goal paused` — that expands (ctrl+o, shared
|
|
170691
|
+
* with tool output) to show the reason when there is one. Terminal outcomes use
|
|
170692
|
+
* the richer completion card (the `/goal` box), not this marker.
|
|
170693
|
+
*/
|
|
169025
170694
|
const HEAD_INDENT = " ";
|
|
169026
170695
|
const DETAIL_INDENT = " ";
|
|
169027
170696
|
var GoalMarkerComponent = class {
|
|
@@ -169051,13 +170720,18 @@ var GoalMarkerComponent = class {
|
|
|
169051
170720
|
render(width) {
|
|
169052
170721
|
const dot = currentTheme.fg(this.accentToken, this.marker);
|
|
169053
170722
|
const head = currentTheme.fg(this.textToken, this.headline);
|
|
169054
|
-
if (!(this.detail !== void 0 && this.detail.length > 0)) return this.
|
|
169055
|
-
if (!this.expandable) return this.
|
|
169056
|
-
if (!this.expanded) return this.
|
|
170723
|
+
if (!(this.detail !== void 0 && this.detail.length > 0)) return this.clampToWidth([`${this.indent}${dot} ${head}`], width);
|
|
170724
|
+
if (!this.expandable) return this.clampToWidth([`${this.indent}${dot} ${head}`], width);
|
|
170725
|
+
if (!this.expanded) return this.clampToWidth([`${this.indent}${dot} ${head} ${currentTheme.fg("textMuted", "(ctrl+o)")}`], width);
|
|
169057
170726
|
const out = [`${this.indent}${dot} ${head}`];
|
|
169058
170727
|
const wrapWidth = Math.max(20, width - 4);
|
|
169059
170728
|
for (const line of wrap(this.detail, wrapWidth)) out.push(DETAIL_INDENT + currentTheme.fg("textDim", line));
|
|
169060
|
-
return this.
|
|
170729
|
+
return this.clampToWidth(out, width);
|
|
170730
|
+
}
|
|
170731
|
+
clampToWidth(lines, width) {
|
|
170732
|
+
const withBlank = this.withLeadingBlank(lines);
|
|
170733
|
+
if (width <= 0) return withBlank.map(() => "");
|
|
170734
|
+
return withBlank.map((line) => truncateToWidth(line, width));
|
|
169061
170735
|
}
|
|
169062
170736
|
withLeadingBlank(lines) {
|
|
169063
170737
|
return this.leadingBlank ? ["", ...lines] : lines;
|
|
@@ -169118,7 +170792,7 @@ function lowercaseFirst(text) {
|
|
|
169118
170792
|
return text.length === 0 ? text : `${text[0].toLowerCase()}${text.slice(1)}`;
|
|
169119
170793
|
}
|
|
169120
170794
|
function wrap(text, width) {
|
|
169121
|
-
const words = text.
|
|
170795
|
+
const words = text.replaceAll(/\s+/g, " ").trim().split(" ");
|
|
169122
170796
|
const lines = [];
|
|
169123
170797
|
let current = "";
|
|
169124
170798
|
for (const word of words) {
|
|
@@ -169381,13 +171055,6 @@ function formatDuration(ms) {
|
|
|
169381
171055
|
return `${(ms / 1e3).toFixed(1)}s`;
|
|
169382
171056
|
}
|
|
169383
171057
|
//#endregion
|
|
169384
|
-
//#region src/tui/utils/transcript-id.ts
|
|
169385
|
-
let transcriptIdCounter = 0;
|
|
169386
|
-
function nextTranscriptId() {
|
|
169387
|
-
transcriptIdCounter += 1;
|
|
169388
|
-
return `entry-${String(transcriptIdCounter)}`;
|
|
169389
|
-
}
|
|
169390
|
-
//#endregion
|
|
169391
171058
|
//#region src/tui/utils/background-agent-status.ts
|
|
169392
171059
|
const MAX_BACKGROUND_FIELD_LENGTH = 240;
|
|
169393
171060
|
function normalizeBackgroundField(value) {
|