svamp-cli 0.2.341 → 0.2.346
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/bin/skills/artifact/SKILL.md +1 -1
- package/bin/skills/crew/SKILL.md +21 -3
- package/dist/DefaultTransport-vfp78fug.mjs +47 -0
- package/dist/GeminiTransport-3OkhtFRO.mjs +130 -0
- package/dist/KimiTransport-D8n009Tr.mjs +141 -0
- package/dist/acpAgentConfig-CObOPlA8.mjs +48 -0
- package/dist/acpBackend-BZ1MJhQV.mjs +922 -0
- package/dist/{adminCommands-Btl3is3z.mjs → adminCommands-BvsYnRDA.mjs} +2 -18
- package/dist/{agentCommands-B7JaByb0.mjs → agentCommands-B2Nl7Fof.mjs} +6 -23
- package/dist/api-BHjyC0Ph.mjs +157 -0
- package/dist/{auth-pTUm-zt4.mjs → auth-CRz8TsEl.mjs} +1 -22
- package/dist/bootStatus-DqtNgJch.mjs +143 -0
- package/dist/claudeAuth-iAerdaMr.mjs +247 -0
- package/dist/cli.mjs +2939 -5
- package/dist/codexAppServerBackend-VGsYtbqg.mjs +786 -0
- package/dist/codexProvider-BtxYc5Rj.mjs +68 -0
- package/dist/{commands-BaxjRuxM.mjs → commands-BB1Kcyt-.mjs} +13 -19
- package/dist/{commands-BUkV04q6.mjs → commands-BOpoVBOM.mjs} +55 -25
- package/dist/{commands-C1L_R1H6.mjs → commands-C2aODeVc.mjs} +58 -33
- package/dist/{commands-znQSQbTX.mjs → commands-CiRCwjkJ.mjs} +10 -32
- package/dist/{commands-C4whLEwv.mjs → commands-D1pZq3d4.mjs} +103 -41
- package/dist/{commands-CMCSUI4A.mjs → commands-D69mnkYu.mjs} +20 -30
- package/dist/{commands-CfP6gPZF.mjs → commands-DW5RnHZw.mjs} +2 -19
- package/dist/{commands-EcIOSJHF.mjs → commands-H4PsTGn8.mjs} +58 -26
- package/dist/cron-hHGdb5kU.mjs +132 -0
- package/dist/detectIsolation-CzoDCEnh.mjs +319 -0
- package/dist/envFlag-COOuJ3AH.mjs +11 -0
- package/dist/fileLock-BMPwCrB6.mjs +80 -0
- package/dist/{fleet-U-WXVbW_.mjs → fleet-DM_Q7w69.mjs} +85 -24
- package/dist/flushExit-C-i6SGjj.mjs +37 -0
- package/dist/friendlyName-1UZcyDhu.mjs +586 -0
- package/dist/{headlessCli-CptF7_lZ.mjs → headlessCli-C8HzQvis.mjs} +3 -21
- package/dist/hookSettings-DYMTUgVA.mjs +10399 -0
- package/dist/{httpServer-Be1Hcddr.mjs → httpServer-BzEDbOGn.mjs} +14 -5
- package/dist/hyphaClient-ybivOjZo.mjs +49 -0
- package/dist/index.mjs +40 -8
- package/dist/instance-CeHz5C8v.mjs +203 -0
- package/dist/kimiProvider-DbxODebR.mjs +69 -0
- package/dist/kimiSetup-NGsoYB5h.mjs +48 -0
- package/dist/loopVerify-B47sSjxe.mjs +444 -0
- package/dist/machineTools-DygM1jXW.mjs +580 -0
- package/dist/model-CUHojegn.mjs +66 -0
- package/dist/{notifyCommands-DitnhzYz.mjs → notifyCommands-D-IKIxiq.mjs} +3 -18
- package/dist/package-DtuINqf5.mjs +64 -0
- package/dist/pinnedCodex-XW4qvOAe.mjs +11 -0
- package/dist/pinnedNono-5ZHb6328.mjs +15 -0
- package/dist/{rpc-zndUgvJ7.mjs → rpc-BB6RF4-F.mjs} +38 -6
- package/dist/{rpc-BPT9DJXL.mjs → rpc-Cf0grcru.mjs} +28 -20
- package/dist/{run-CrUTBmi4.mjs → run-ChdsgaSD.mjs} +17 -9
- package/dist/run-DkjwF-zA.mjs +9695 -0
- package/dist/sandboxDetect-Cdzsj5TC.mjs +19 -0
- package/dist/{scheduler-B0h2sfGn.mjs → scheduler-BY30ZrB9.mjs} +38 -6
- package/dist/securityContext-Cm5UTCuD.mjs +218 -0
- package/dist/serveAuth-DbVLRCRR.mjs +418 -0
- package/dist/{serveCommands-DpF0xKvz.mjs → serveCommands-CUHUiYnZ.mjs} +13 -34
- package/dist/sharingNotificationSync-qGIQ-3yf.mjs +359 -0
- package/dist/{sideband-B5n9fNxM.mjs → sideband-68HhGT0i.mjs} +1 -21
- package/dist/store-Bn0ByYev.mjs +347 -0
- package/dist/store-fi0f-ff1.mjs +184 -0
- package/dist/types-57J3Re0n.mjs +17 -0
- package/dist/wantsHelp-6bMOeNUz.mjs +5 -0
- package/dist/wrapCommand-CdNawSaa.mjs +117 -0
- package/package.json +3 -3
- package/dist/cli-pFCLXDrP.mjs +0 -2749
- package/dist/package-CigJ8nhu.mjs +0 -64
- package/dist/run-LHJh7jLy.mjs +0 -26384
- package/dist/sandboxDetect-DNTcbgWD.mjs +0 -12
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: artifact
|
|
3
|
-
version: 1.3.
|
|
3
|
+
version: 1.3.1
|
|
4
4
|
description: Embed a rendered HTML file or live URL inline in chat via a single self-closing `<artifact src="..." />` tag — the Svamp client renders it as a sandboxed iframe with modes for inline, card, bare, and immersive.
|
|
5
5
|
tags:
|
|
6
6
|
- svamp
|
package/bin/skills/crew/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: crew
|
|
3
|
-
version: 0.3.
|
|
3
|
+
version: 0.3.2
|
|
4
4
|
description: Coordinate work as a lead delegating features to managed worktree children — spawn a child per feature on its own branch, run it as a loop until done, and pull finished work back to the base branch with merge-and-close. Use when one session should run a project and farm out features instead of piling many sessions on one working tree.
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -25,6 +25,10 @@ svamp feature start "<brief>" [--oracle "<test cmd>"] [--base <branch>] [--actio
|
|
|
25
25
|
[--issue <id>] [--max N] [--model <id>]
|
|
26
26
|
# (lead) create a worktree child on a new branch, run it as a loop until done
|
|
27
27
|
# (oracle → parent verdict), and brief it. Prints the child id.
|
|
28
|
+
# --action nudge|block: how the lead learns the child reported or finished.
|
|
29
|
+
# nudge (default) = normal urgency, the lead sees it on its next idle turn;
|
|
30
|
+
# block = urgent, which WAKES the lead. Use block for a child whose result
|
|
31
|
+
# gates your next step; nudge for one you will collect when convenient.
|
|
28
32
|
# --issue <id> links the child to an existing backlog issue: its verdict routes
|
|
29
33
|
# ONTO that issue. This is the seam that joins crew to the backlog the loop
|
|
30
34
|
# oracle (`svamp issue pending`) reads — without it the child's result is
|
|
@@ -65,6 +69,12 @@ You coordinate the project. Keep your own working tree (the base branch, e.g. `m
|
|
|
65
69
|
branch into the base, removes the worktree, and archives the child. On a conflict or a dirty
|
|
66
70
|
worktree the merge is **deferred to rework** (the child is re-woken with guidance and left
|
|
67
71
|
alive — un-merged work is never destroyed); help it resolve, then merge again.
|
|
72
|
+
- **A merge can also HARD-fail.** When the failure is not something the child can fix by editing
|
|
73
|
+
(e.g. the base tree is on the wrong branch or is dirty), `feature merge` exits 1 and sends the
|
|
74
|
+
child `<crew-blocked>` instead of `<crew-rework>`. The child is told to STOP and hold; it will
|
|
75
|
+
not retry. Resolving it is **yours or the operator's** — fix the blocker in the base tree, then
|
|
76
|
+
re-run `svamp feature merge <child-id>`. A blocked child left unattended is idle, not working,
|
|
77
|
+
so do not wait for it to report again.
|
|
68
78
|
- **Nudge stalled children.** If `feature list` shows a child idle with committed, ahead-of-base
|
|
69
79
|
work that hasn't been reported done, send `svamp session inbox send <child> "status?"` (or
|
|
70
80
|
`feature report`-style ping) to move it along.
|
|
@@ -81,8 +91,16 @@ brief (and your loop's "until" criteria) is injected each turn.
|
|
|
81
91
|
run `svamp feature done --summary "<what changed>"`. This sends a merge-request to your lead.
|
|
82
92
|
- **Do not merge your own branch or remove your own worktree** — the lead does the merge-back so
|
|
83
93
|
the base tree isn't corrupted. After the lead merges, your worktree is removed and you are
|
|
84
|
-
archived.
|
|
85
|
-
|
|
94
|
+
archived. Three control messages can arrive from your lead — they look similar and mean
|
|
95
|
+
different things, so read the tag:
|
|
96
|
+
- `<crew-freeze>` — stop editing immediately.
|
|
97
|
+
- `<crew-rework>` — the merge was **deferred**; address the guidance and run
|
|
98
|
+
`svamp feature done` again.
|
|
99
|
+
- `<crew-blocked>` — the merge **hard-failed**. "Stop editing and hold — do not keep working.
|
|
100
|
+
Once the blocker is resolved, the lead can retry `svamp feature merge`." Do **not** run
|
|
101
|
+
`svamp feature done` again: nothing you can do from here changes the outcome, and re-sending
|
|
102
|
+
a merge-request into a hard-failed state just burns loop turns toward the cost ceiling. Hold
|
|
103
|
+
until the lead retries the merge. Your un-merged work is preserved.
|
|
86
104
|
|
|
87
105
|
## Standalone (no-worktree) children — managing a fleet of folders
|
|
88
106
|
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
const DEFAULT_TIMEOUTS = {
|
|
2
|
+
init: 6e4,
|
|
3
|
+
toolCall: 12e4,
|
|
4
|
+
think: 3e4
|
|
5
|
+
};
|
|
6
|
+
class DefaultTransport {
|
|
7
|
+
agentName;
|
|
8
|
+
constructor(agentName = "generic-acp") {
|
|
9
|
+
this.agentName = agentName;
|
|
10
|
+
}
|
|
11
|
+
getInitTimeout() {
|
|
12
|
+
return DEFAULT_TIMEOUTS.init;
|
|
13
|
+
}
|
|
14
|
+
filterStdoutLine(line) {
|
|
15
|
+
const trimmed = line.trim();
|
|
16
|
+
if (!trimmed) return null;
|
|
17
|
+
if (!trimmed.startsWith("{") && !trimmed.startsWith("[")) return null;
|
|
18
|
+
try {
|
|
19
|
+
const parsed = JSON.parse(trimmed);
|
|
20
|
+
if (typeof parsed !== "object" || parsed === null) return null;
|
|
21
|
+
return line;
|
|
22
|
+
} catch {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
handleStderr(_text, _context) {
|
|
27
|
+
return { message: null };
|
|
28
|
+
}
|
|
29
|
+
getToolPatterns() {
|
|
30
|
+
return [];
|
|
31
|
+
}
|
|
32
|
+
isInvestigationTool(_toolCallId, _toolKind) {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
getToolCallTimeout(_toolCallId, toolKind) {
|
|
36
|
+
if (toolKind === "think") return DEFAULT_TIMEOUTS.think;
|
|
37
|
+
return DEFAULT_TIMEOUTS.toolCall;
|
|
38
|
+
}
|
|
39
|
+
extractToolNameFromId(_toolCallId) {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
determineToolName(toolName, _toolCallId, _input, _context) {
|
|
43
|
+
return toolName;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export { DefaultTransport };
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
const GEMINI_TIMEOUTS = {
|
|
2
|
+
init: 12e4,
|
|
3
|
+
toolCall: 12e4,
|
|
4
|
+
investigation: 6e5,
|
|
5
|
+
think: 3e4,
|
|
6
|
+
idle: 500
|
|
7
|
+
};
|
|
8
|
+
const GEMINI_TOOL_PATTERNS = [
|
|
9
|
+
{
|
|
10
|
+
name: "change_title",
|
|
11
|
+
patterns: ["change_title", "change-title", "svamp__change_title", "mcp__svamp__change_title"],
|
|
12
|
+
inputFields: ["title"],
|
|
13
|
+
emptyInputDefault: true
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
name: "set_session_link",
|
|
17
|
+
patterns: ["set_session_link", "set-session-link", "svamp__set_session_link", "mcp__svamp__set_session_link"],
|
|
18
|
+
inputFields: ["url"]
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
name: "save_memory",
|
|
22
|
+
patterns: ["save_memory", "save-memory"],
|
|
23
|
+
inputFields: ["memory", "content"]
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
name: "think",
|
|
27
|
+
patterns: ["think"],
|
|
28
|
+
inputFields: ["thought", "thinking"]
|
|
29
|
+
}
|
|
30
|
+
];
|
|
31
|
+
const AVAILABLE_MODELS = [
|
|
32
|
+
"gemini-2.5-pro",
|
|
33
|
+
"gemini-2.5-flash",
|
|
34
|
+
"gemini-2.5-flash-lite"
|
|
35
|
+
];
|
|
36
|
+
class GeminiTransport {
|
|
37
|
+
agentName = "gemini";
|
|
38
|
+
getInitTimeout() {
|
|
39
|
+
return GEMINI_TIMEOUTS.init;
|
|
40
|
+
}
|
|
41
|
+
filterStdoutLine(line) {
|
|
42
|
+
const trimmed = line.trim();
|
|
43
|
+
if (!trimmed) return null;
|
|
44
|
+
if (!trimmed.startsWith("{") && !trimmed.startsWith("[")) return null;
|
|
45
|
+
try {
|
|
46
|
+
const parsed = JSON.parse(trimmed);
|
|
47
|
+
if (typeof parsed !== "object" || parsed === null) return null;
|
|
48
|
+
return line;
|
|
49
|
+
} catch {
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
handleStderr(text, context) {
|
|
54
|
+
const trimmed = text.trim();
|
|
55
|
+
if (!trimmed) return { message: null, suppress: true };
|
|
56
|
+
if (trimmed.includes("status 429") || trimmed.includes('code":429') || trimmed.includes("rateLimitExceeded") || trimmed.includes("RESOURCE_EXHAUSTED")) {
|
|
57
|
+
return { message: null, suppress: false };
|
|
58
|
+
}
|
|
59
|
+
if (trimmed.includes("status 404") || trimmed.includes('code":404')) {
|
|
60
|
+
const msg = {
|
|
61
|
+
type: "status",
|
|
62
|
+
status: "error",
|
|
63
|
+
detail: `Model not found. Available models: ${AVAILABLE_MODELS.join(", ")}`
|
|
64
|
+
};
|
|
65
|
+
return { message: msg };
|
|
66
|
+
}
|
|
67
|
+
if (context.hasActiveInvestigation) {
|
|
68
|
+
const hasError = trimmed.includes("timeout") || trimmed.includes("Timeout") || trimmed.includes("failed") || trimmed.includes("Failed") || trimmed.includes("error") || trimmed.includes("Error");
|
|
69
|
+
if (hasError) {
|
|
70
|
+
return { message: null, suppress: false };
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return { message: null };
|
|
74
|
+
}
|
|
75
|
+
getToolPatterns() {
|
|
76
|
+
return GEMINI_TOOL_PATTERNS;
|
|
77
|
+
}
|
|
78
|
+
isInvestigationTool(toolCallId, toolKind) {
|
|
79
|
+
const lowerId = toolCallId.toLowerCase();
|
|
80
|
+
return lowerId.includes("codebase_investigator") || lowerId.includes("investigator") || typeof toolKind === "string" && toolKind.includes("investigator");
|
|
81
|
+
}
|
|
82
|
+
getToolCallTimeout(toolCallId, toolKind) {
|
|
83
|
+
if (this.isInvestigationTool(toolCallId, toolKind)) return GEMINI_TIMEOUTS.investigation;
|
|
84
|
+
if (toolKind === "think") return GEMINI_TIMEOUTS.think;
|
|
85
|
+
return GEMINI_TIMEOUTS.toolCall;
|
|
86
|
+
}
|
|
87
|
+
getIdleTimeout() {
|
|
88
|
+
return GEMINI_TIMEOUTS.idle;
|
|
89
|
+
}
|
|
90
|
+
extractToolNameFromId(toolCallId) {
|
|
91
|
+
const lowerId = toolCallId.toLowerCase();
|
|
92
|
+
for (const toolPattern of GEMINI_TOOL_PATTERNS) {
|
|
93
|
+
for (const pattern of toolPattern.patterns) {
|
|
94
|
+
if (lowerId.includes(pattern.toLowerCase())) {
|
|
95
|
+
return toolPattern.name;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
isEmptyInput(input) {
|
|
102
|
+
if (!input) return true;
|
|
103
|
+
if (Array.isArray(input)) return input.length === 0;
|
|
104
|
+
if (typeof input === "object") return Object.keys(input).length === 0;
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
determineToolName(toolName, toolCallId, input, _context) {
|
|
108
|
+
if (toolName !== "other" && toolName !== "Unknown tool") return toolName;
|
|
109
|
+
const idToolName = this.extractToolNameFromId(toolCallId);
|
|
110
|
+
if (idToolName) return idToolName;
|
|
111
|
+
if (input && typeof input === "object" && !Array.isArray(input)) {
|
|
112
|
+
const inputKeys = Object.keys(input);
|
|
113
|
+
for (const toolPattern of GEMINI_TOOL_PATTERNS) {
|
|
114
|
+
if (toolPattern.inputFields) {
|
|
115
|
+
const hasMatchingField = toolPattern.inputFields.some(
|
|
116
|
+
(field) => inputKeys.some((key) => key.toLowerCase() === field.toLowerCase())
|
|
117
|
+
);
|
|
118
|
+
if (hasMatchingField) return toolPattern.name;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
if (this.isEmptyInput(input) && toolName === "other") {
|
|
123
|
+
const defaultTool = GEMINI_TOOL_PATTERNS.find((p) => p.emptyInputDefault);
|
|
124
|
+
if (defaultTool) return defaultTool.name;
|
|
125
|
+
}
|
|
126
|
+
return toolName;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export { GEMINI_TIMEOUTS, GeminiTransport };
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
const KIMI_TIMEOUTS = {
|
|
2
|
+
init: 12e4,
|
|
3
|
+
toolCall: 12e4,
|
|
4
|
+
investigation: 6e5,
|
|
5
|
+
think: 3e4,
|
|
6
|
+
idle: 500
|
|
7
|
+
};
|
|
8
|
+
const KIMI_TOOL_PATTERNS = [
|
|
9
|
+
{
|
|
10
|
+
name: "change_title",
|
|
11
|
+
patterns: ["change_title", "change-title", "svamp__change_title", "mcp__svamp__change_title"],
|
|
12
|
+
inputFields: ["title"],
|
|
13
|
+
emptyInputDefault: true
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
name: "set_session_link",
|
|
17
|
+
patterns: ["set_session_link", "set-session-link", "svamp__set_session_link", "mcp__svamp__set_session_link"],
|
|
18
|
+
inputFields: ["url"]
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
name: "save_memory",
|
|
22
|
+
patterns: ["save_memory", "save-memory"],
|
|
23
|
+
inputFields: ["memory", "content"]
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
name: "think",
|
|
27
|
+
patterns: ["think"],
|
|
28
|
+
inputFields: ["thought", "thinking"]
|
|
29
|
+
}
|
|
30
|
+
];
|
|
31
|
+
const AVAILABLE_MODELS = [
|
|
32
|
+
"moonshotai/kimi-k2.5",
|
|
33
|
+
"moonshotai/kimi-k3",
|
|
34
|
+
"moonshotai/kimi-k2.7-code",
|
|
35
|
+
"moonshotai/kimi-k2-thinking",
|
|
36
|
+
"moonshotai/kimi-k2-turbo-preview",
|
|
37
|
+
"kimi-for-coding/kimi-for-coding"
|
|
38
|
+
];
|
|
39
|
+
class KimiTransport {
|
|
40
|
+
agentName = "kimi";
|
|
41
|
+
getInitTimeout() {
|
|
42
|
+
return KIMI_TIMEOUTS.init;
|
|
43
|
+
}
|
|
44
|
+
filterStdoutLine(line) {
|
|
45
|
+
const trimmed = line.trim();
|
|
46
|
+
if (!trimmed) return null;
|
|
47
|
+
if (!trimmed.startsWith("{") && !trimmed.startsWith("[")) return null;
|
|
48
|
+
try {
|
|
49
|
+
const parsed = JSON.parse(trimmed);
|
|
50
|
+
if (typeof parsed !== "object" || parsed === null) return null;
|
|
51
|
+
return line;
|
|
52
|
+
} catch {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
handleStderr(text, context) {
|
|
57
|
+
const trimmed = text.trim();
|
|
58
|
+
if (!trimmed) return { message: null, suppress: true };
|
|
59
|
+
if (trimmed.includes("no provider configured") || trimmed.includes("Authentication required") || trimmed.includes("Invalid Authentication") || trimmed.includes("authentication_error") || trimmed.includes("401")) {
|
|
60
|
+
const msg = {
|
|
61
|
+
type: "status",
|
|
62
|
+
status: "error",
|
|
63
|
+
detail: "Kimi has no valid provider configured. Run `svamp daemon kimi-auth use-moonshot <api-key>` (or `use-coding` / `set`) on this machine, then restart the daemon."
|
|
64
|
+
};
|
|
65
|
+
return { message: msg };
|
|
66
|
+
}
|
|
67
|
+
if (trimmed.includes("status 429") || trimmed.includes('code":429') || trimmed.includes("429") || trimmed.includes("rate limit") || trimmed.includes("RESOURCE_EXHAUSTED")) {
|
|
68
|
+
return { message: null, suppress: false };
|
|
69
|
+
}
|
|
70
|
+
if (trimmed.includes("status 404") || trimmed.includes('code":404') || trimmed.includes("model_not_found")) {
|
|
71
|
+
const msg = {
|
|
72
|
+
type: "status",
|
|
73
|
+
status: "error",
|
|
74
|
+
detail: `Model not found. Example Kimi models: ${AVAILABLE_MODELS.join(", ")}`
|
|
75
|
+
};
|
|
76
|
+
return { message: msg };
|
|
77
|
+
}
|
|
78
|
+
if (context.hasActiveInvestigation) {
|
|
79
|
+
const hasError = trimmed.includes("timeout") || trimmed.includes("Timeout") || trimmed.includes("failed") || trimmed.includes("Failed") || trimmed.includes("error") || trimmed.includes("Error");
|
|
80
|
+
if (hasError) {
|
|
81
|
+
return { message: null, suppress: false };
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return { message: null };
|
|
85
|
+
}
|
|
86
|
+
getToolPatterns() {
|
|
87
|
+
return KIMI_TOOL_PATTERNS;
|
|
88
|
+
}
|
|
89
|
+
isInvestigationTool(toolCallId, toolKind) {
|
|
90
|
+
const lowerId = toolCallId.toLowerCase();
|
|
91
|
+
return lowerId.includes("codebase_investigator") || lowerId.includes("investigator") || typeof toolKind === "string" && toolKind.includes("investigator");
|
|
92
|
+
}
|
|
93
|
+
getToolCallTimeout(toolCallId, toolKind) {
|
|
94
|
+
if (this.isInvestigationTool(toolCallId, toolKind)) return KIMI_TIMEOUTS.investigation;
|
|
95
|
+
if (toolKind === "think") return KIMI_TIMEOUTS.think;
|
|
96
|
+
return KIMI_TIMEOUTS.toolCall;
|
|
97
|
+
}
|
|
98
|
+
getIdleTimeout() {
|
|
99
|
+
return KIMI_TIMEOUTS.idle;
|
|
100
|
+
}
|
|
101
|
+
extractToolNameFromId(toolCallId) {
|
|
102
|
+
const lowerId = toolCallId.toLowerCase();
|
|
103
|
+
for (const toolPattern of KIMI_TOOL_PATTERNS) {
|
|
104
|
+
for (const pattern of toolPattern.patterns) {
|
|
105
|
+
if (lowerId.includes(pattern.toLowerCase())) {
|
|
106
|
+
return toolPattern.name;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
isEmptyInput(input) {
|
|
113
|
+
if (!input) return true;
|
|
114
|
+
if (Array.isArray(input)) return input.length === 0;
|
|
115
|
+
if (typeof input === "object") return Object.keys(input).length === 0;
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
determineToolName(toolName, toolCallId, input, _context) {
|
|
119
|
+
if (toolName !== "other" && toolName !== "Unknown tool") return toolName;
|
|
120
|
+
const idToolName = this.extractToolNameFromId(toolCallId);
|
|
121
|
+
if (idToolName) return idToolName;
|
|
122
|
+
if (input && typeof input === "object" && !Array.isArray(input)) {
|
|
123
|
+
const inputKeys = Object.keys(input);
|
|
124
|
+
for (const toolPattern of KIMI_TOOL_PATTERNS) {
|
|
125
|
+
if (toolPattern.inputFields) {
|
|
126
|
+
const hasMatchingField = toolPattern.inputFields.some(
|
|
127
|
+
(field) => inputKeys.some((key) => key.toLowerCase() === field.toLowerCase())
|
|
128
|
+
);
|
|
129
|
+
if (hasMatchingField) return toolPattern.name;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
if (this.isEmptyInput(input) && toolName === "other") {
|
|
134
|
+
const defaultTool = KIMI_TOOL_PATTERNS.find((p) => p.emptyInputDefault);
|
|
135
|
+
if (defaultTool) return defaultTool.name;
|
|
136
|
+
}
|
|
137
|
+
return toolName;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export { KIMI_TIMEOUTS, KimiTransport };
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
const KNOWN_ACP_AGENTS = {
|
|
2
|
+
gemini: { command: "gemini", args: ["--experimental-acp"] },
|
|
3
|
+
kimi: { command: "kimi", args: ["acp"] }
|
|
4
|
+
};
|
|
5
|
+
const KNOWN_CODEX_AGENTS = {
|
|
6
|
+
codex: { command: "codex", args: ["app-server", "--listen", "stdio://"] }
|
|
7
|
+
};
|
|
8
|
+
function resolveAcpAgentConfig(cliArgs) {
|
|
9
|
+
if (cliArgs.length === 0) {
|
|
10
|
+
throw new Error("Usage: svamp agent <agent-name> or svamp agent -- <command> [args]");
|
|
11
|
+
}
|
|
12
|
+
if (cliArgs[0] === "--") {
|
|
13
|
+
const command = cliArgs[1];
|
|
14
|
+
if (!command) {
|
|
15
|
+
throw new Error('Missing command after "--". Usage: svamp agent -- <command> [args]');
|
|
16
|
+
}
|
|
17
|
+
return {
|
|
18
|
+
agentName: command,
|
|
19
|
+
command,
|
|
20
|
+
args: cliArgs.slice(2)
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
const agentName = cliArgs[0];
|
|
24
|
+
const knownAcp = KNOWN_ACP_AGENTS[agentName];
|
|
25
|
+
if (knownAcp) {
|
|
26
|
+
const passthroughArgs = cliArgs.slice(1).filter(Boolean);
|
|
27
|
+
return {
|
|
28
|
+
agentName,
|
|
29
|
+
command: knownAcp.command,
|
|
30
|
+
args: [...knownAcp.args, ...passthroughArgs]
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
const knownCodex = KNOWN_CODEX_AGENTS[agentName];
|
|
34
|
+
if (knownCodex) {
|
|
35
|
+
return {
|
|
36
|
+
agentName,
|
|
37
|
+
command: knownCodex.command,
|
|
38
|
+
args: [...knownCodex.args, ...cliArgs.slice(1)]
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
return {
|
|
42
|
+
agentName,
|
|
43
|
+
command: agentName,
|
|
44
|
+
args: cliArgs.slice(1)
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export { KNOWN_ACP_AGENTS, KNOWN_CODEX_AGENTS, resolveAcpAgentConfig };
|