@simonepri/refined-antigravity-acp 0.2.0 → 1.0.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/bin/cli.js +2 -51
- package/dist/bin/cli.js.map +1 -1
- package/dist/src/cli.d.ts +2 -0
- package/dist/src/cli.d.ts.map +1 -0
- package/dist/src/cli.js +44 -0
- package/dist/src/cli.js.map +1 -0
- package/dist/src/{command.d.ts → core/command.d.ts} +4 -0
- package/dist/src/core/command.d.ts.map +1 -0
- package/dist/src/{command.js → core/command.js} +27 -11
- package/dist/src/core/command.js.map +1 -0
- package/dist/src/core/pipeline.d.ts +20 -0
- package/dist/src/core/pipeline.d.ts.map +1 -0
- package/dist/src/core/pipeline.js +94 -0
- package/dist/src/core/pipeline.js.map +1 -0
- package/dist/src/core/session-cache.d.ts +12 -0
- package/dist/src/core/session-cache.d.ts.map +1 -0
- package/dist/src/core/session-cache.js +85 -0
- package/dist/src/core/session-cache.js.map +1 -0
- package/dist/src/core/supervisor.d.ts +90 -0
- package/dist/src/core/supervisor.d.ts.map +1 -0
- package/dist/src/core/supervisor.js +582 -0
- package/dist/src/core/supervisor.js.map +1 -0
- package/dist/src/core/telemetry.d.ts +23 -0
- package/dist/src/core/telemetry.d.ts.map +1 -0
- package/dist/src/core/telemetry.js +75 -0
- package/dist/src/core/telemetry.js.map +1 -0
- package/dist/src/core/transport.d.ts +7 -0
- package/dist/src/core/transport.d.ts.map +1 -0
- package/dist/src/core/transport.js +37 -0
- package/dist/src/core/transport.js.map +1 -0
- package/dist/src/core/types.d.ts +293 -0
- package/dist/src/core/types.d.ts.map +1 -0
- package/dist/src/core/types.js +78 -0
- package/dist/src/core/types.js.map +1 -0
- package/dist/src/fixes/active-turn-collision/index.d.ts +27 -0
- package/dist/src/fixes/active-turn-collision/index.d.ts.map +1 -0
- package/dist/src/fixes/active-turn-collision/index.js +117 -0
- package/dist/src/fixes/active-turn-collision/index.js.map +1 -0
- package/dist/src/fixes/cancellation-leak/index.d.ts +17 -0
- package/dist/src/fixes/cancellation-leak/index.d.ts.map +1 -0
- package/dist/src/fixes/cancellation-leak/index.js +57 -0
- package/dist/src/fixes/cancellation-leak/index.js.map +1 -0
- package/dist/src/fixes/dangling-tool-calls/index.d.ts +32 -0
- package/dist/src/fixes/dangling-tool-calls/index.d.ts.map +1 -0
- package/dist/src/fixes/dangling-tool-calls/index.js +188 -0
- package/dist/src/fixes/dangling-tool-calls/index.js.map +1 -0
- package/dist/src/fixes/dropped-history-chunks/index.d.ts +47 -0
- package/dist/src/fixes/dropped-history-chunks/index.d.ts.map +1 -0
- package/dist/src/fixes/dropped-history-chunks/index.js +202 -0
- package/dist/src/fixes/dropped-history-chunks/index.js.map +1 -0
- package/dist/src/fixes/flattened-model-efforts/index.d.ts +39 -0
- package/dist/src/fixes/flattened-model-efforts/index.d.ts.map +1 -0
- package/dist/src/fixes/flattened-model-efforts/index.js +306 -0
- package/dist/src/fixes/flattened-model-efforts/index.js.map +1 -0
- package/dist/src/fixes/index.d.ts +25 -0
- package/dist/src/fixes/index.d.ts.map +1 -0
- package/dist/src/fixes/index.js +61 -0
- package/dist/src/fixes/index.js.map +1 -0
- package/dist/src/fixes/malformed-stream-syntax/index.d.ts +44 -0
- package/dist/src/fixes/malformed-stream-syntax/index.d.ts.map +1 -0
- package/dist/src/fixes/malformed-stream-syntax/index.js +346 -0
- package/dist/src/fixes/malformed-stream-syntax/index.js.map +1 -0
- package/dist/src/fixes/missing-localharness/index.d.ts +20 -0
- package/dist/src/fixes/missing-localharness/index.d.ts.map +1 -0
- package/dist/src/fixes/missing-localharness/index.js +103 -0
- package/dist/src/fixes/missing-localharness/index.js.map +1 -0
- package/dist/src/fixes/missing-question-fallback/index.d.ts +30 -0
- package/dist/src/fixes/missing-question-fallback/index.d.ts.map +1 -0
- package/dist/src/fixes/missing-question-fallback/index.js +119 -0
- package/dist/src/fixes/missing-question-fallback/index.js.map +1 -0
- package/dist/src/fixes/missing-slash-skills/index.d.ts +17 -0
- package/dist/src/fixes/missing-slash-skills/index.d.ts.map +1 -0
- package/dist/src/fixes/missing-slash-skills/index.js +107 -0
- package/dist/src/fixes/missing-slash-skills/index.js.map +1 -0
- package/dist/src/{skills.d.ts → fixes/missing-slash-skills/skills.d.ts} +2 -1
- package/dist/src/fixes/missing-slash-skills/skills.d.ts.map +1 -0
- package/dist/src/fixes/missing-slash-skills/skills.js +199 -0
- package/dist/src/fixes/missing-slash-skills/skills.js.map +1 -0
- package/dist/src/fixes/missing-system-prompt/index.d.ts +19 -0
- package/dist/src/fixes/missing-system-prompt/index.d.ts.map +1 -0
- package/dist/src/fixes/missing-system-prompt/index.js +118 -0
- package/dist/src/fixes/missing-system-prompt/index.js.map +1 -0
- package/dist/src/fixes/missing-usage-metrics/index.d.ts +26 -0
- package/dist/src/fixes/missing-usage-metrics/index.d.ts.map +1 -0
- package/dist/src/fixes/missing-usage-metrics/index.js +132 -0
- package/dist/src/fixes/missing-usage-metrics/index.js.map +1 -0
- package/dist/src/fixes/noisy-stderr-logs/index.d.ts +15 -0
- package/dist/src/fixes/noisy-stderr-logs/index.d.ts.map +1 -0
- package/dist/src/fixes/noisy-stderr-logs/index.js +23 -0
- package/dist/src/fixes/noisy-stderr-logs/index.js.map +1 -0
- package/dist/src/fixes/non-canonical-mode-ids/index.d.ts +26 -0
- package/dist/src/fixes/non-canonical-mode-ids/index.d.ts.map +1 -0
- package/dist/src/fixes/non-canonical-mode-ids/index.js +47 -0
- package/dist/src/fixes/non-canonical-mode-ids/index.js.map +1 -0
- package/dist/src/fixes/orphaned-checkpoints/index.d.ts +31 -0
- package/dist/src/fixes/orphaned-checkpoints/index.d.ts.map +1 -0
- package/dist/src/fixes/orphaned-checkpoints/index.js +82 -0
- package/dist/src/fixes/orphaned-checkpoints/index.js.map +1 -0
- package/dist/src/fixes/silent-background-tasks/index.d.ts +66 -0
- package/dist/src/fixes/silent-background-tasks/index.d.ts.map +1 -0
- package/dist/src/fixes/silent-background-tasks/index.js +491 -0
- package/dist/src/fixes/silent-background-tasks/index.js.map +1 -0
- package/dist/src/{mcp-proxy.d.ts → fixes/stale-mcp-endpoints/index.d.ts} +31 -4
- package/dist/src/fixes/stale-mcp-endpoints/index.d.ts.map +1 -0
- package/dist/src/{mcp-proxy.js → fixes/stale-mcp-endpoints/index.js} +162 -14
- package/dist/src/fixes/stale-mcp-endpoints/index.js.map +1 -0
- package/dist/src/fixes/subagent-hang/index.d.ts +2 -0
- package/dist/src/fixes/subagent-hang/index.d.ts.map +1 -0
- package/dist/src/fixes/subagent-hang/index.js +2 -0
- package/dist/src/fixes/subagent-hang/index.js.map +1 -0
- package/dist/src/fixes/subagent-hang/subagent-hang.d.ts +43 -0
- package/dist/src/fixes/subagent-hang/subagent-hang.d.ts.map +1 -0
- package/dist/src/fixes/subagent-hang/subagent-hang.js +114 -0
- package/dist/src/fixes/subagent-hang/subagent-hang.js.map +1 -0
- package/dist/src/index.d.ts +27 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +43 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/lib/protobuf.d.ts +9 -0
- package/dist/src/lib/protobuf.d.ts.map +1 -0
- package/dist/src/lib/protobuf.js +89 -0
- package/dist/src/lib/protobuf.js.map +1 -0
- package/package.json +22 -7
- package/readme.md +147 -141
- package/assets/icon.svg +0 -3
- package/build/paseo/assets/icon.svg +0 -3
- package/build/paseo/assets/logo.svg +0 -62
- package/build/paseo/index.server.ts +0 -9
- package/build/paseo/paseo-plugin.json +0 -7
- package/build/paseo/server/agy-patch.ts +0 -445
- package/build/paseo/server/auth.ts +0 -122
- package/build/paseo/server/command.ts +0 -92
- package/build/paseo/server/connector.ts +0 -1371
- package/build/paseo/server/history.ts +0 -157
- package/build/paseo/server/mcp-proxy.ts +0 -375
- package/build/paseo/server/provider.ts +0 -37
- package/build/paseo/server/sanitize.ts +0 -286
- package/build/paseo/server/skills.ts +0 -183
- package/build/paseo/server/steering.ts +0 -199
- package/dist/index.server.d.ts +0 -4
- package/dist/index.server.d.ts.map +0 -1
- package/dist/index.server.js +0 -7
- package/dist/index.server.js.map +0 -1
- package/dist/src/agy-patch.d.ts +0 -65
- package/dist/src/agy-patch.d.ts.map +0 -1
- package/dist/src/agy-patch.js +0 -351
- package/dist/src/agy-patch.js.map +0 -1
- package/dist/src/auth.d.ts +0 -27
- package/dist/src/auth.d.ts.map +0 -1
- package/dist/src/auth.js +0 -113
- package/dist/src/auth.js.map +0 -1
- package/dist/src/command.d.ts.map +0 -1
- package/dist/src/command.js.map +0 -1
- package/dist/src/connector.d.ts +0 -187
- package/dist/src/connector.d.ts.map +0 -1
- package/dist/src/connector.js +0 -1127
- package/dist/src/connector.js.map +0 -1
- package/dist/src/history.d.ts +0 -12
- package/dist/src/history.d.ts.map +0 -1
- package/dist/src/history.js +0 -152
- package/dist/src/history.js.map +0 -1
- package/dist/src/mcp-proxy.d.ts.map +0 -1
- package/dist/src/mcp-proxy.js.map +0 -1
- package/dist/src/provider.d.ts +0 -11
- package/dist/src/provider.d.ts.map +0 -1
- package/dist/src/provider.js +0 -31
- package/dist/src/provider.js.map +0 -1
- package/dist/src/sanitize.d.ts +0 -29
- package/dist/src/sanitize.d.ts.map +0 -1
- package/dist/src/sanitize.js +0 -237
- package/dist/src/sanitize.js.map +0 -1
- package/dist/src/skills.d.ts.map +0 -1
- package/dist/src/skills.js +0 -140
- package/dist/src/skills.js.map +0 -1
- package/dist/src/steering.d.ts +0 -30
- package/dist/src/steering.d.ts.map +0 -1
- package/dist/src/steering.js +0 -174
- package/dist/src/steering.js.map +0 -1
- package/paseo-plugin.json +0 -8
- package/scripts/build-paseo.js +0 -60
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Problem:
|
|
3
|
+
* Upstream system prompts explicitly forbid the model from providing an "Other" option in
|
|
4
|
+
* multiple-choice user prompts (`"Do NOT add an 'Other' option to questions"`), stranding users
|
|
5
|
+
* with no way to enter custom or free-text answers when none of the choices apply.
|
|
6
|
+
*
|
|
7
|
+
* Solution:
|
|
8
|
+
* Injects a prompt override directing the model to always provide an "Other" option for free-text
|
|
9
|
+
* answers, and intercepts inbound `ask_question` tool calls to append a fallback "Other" choice if omitted.
|
|
10
|
+
*/
|
|
11
|
+
import { ACP_METHODS, SESSION_UPDATES, isMethod, } from "../../core/types.js";
|
|
12
|
+
export const QUESTION_OPTIONS_INSTRUCTIONS = [
|
|
13
|
+
"Ignore the ask_question 'no other' rule: always include an 'Other' option for free-text responses.",
|
|
14
|
+
];
|
|
15
|
+
export const OTHER_OPTION_REGEX = /\b(?:other|none\s+of\s+the\s+above|something\s+else)\b/i;
|
|
16
|
+
function parsePayload(raw) {
|
|
17
|
+
if (typeof raw === "string") {
|
|
18
|
+
try {
|
|
19
|
+
const parsed = JSON.parse(raw);
|
|
20
|
+
return typeof parsed === "object" && parsed !== null
|
|
21
|
+
? { parsed: parsed, isString: true }
|
|
22
|
+
: { parsed: null, isString: true };
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return { parsed: null, isString: true };
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
if (typeof raw === "object" && raw !== null) {
|
|
29
|
+
return { parsed: raw, isString: false };
|
|
30
|
+
}
|
|
31
|
+
return { parsed: null, isString: false };
|
|
32
|
+
}
|
|
33
|
+
function appendOtherIfMissing(question) {
|
|
34
|
+
if (!Array.isArray(question.options))
|
|
35
|
+
return false;
|
|
36
|
+
const hasOther = question.options.some((opt) => typeof opt === "string" && OTHER_OPTION_REGEX.test(opt));
|
|
37
|
+
if (hasOther)
|
|
38
|
+
return false;
|
|
39
|
+
question.options.push("Other");
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
export function ensureOtherOption(raw) {
|
|
43
|
+
if (!raw)
|
|
44
|
+
return { modified: false, result: raw };
|
|
45
|
+
const { parsed, isString } = parsePayload(raw);
|
|
46
|
+
if (!parsed || !Array.isArray(parsed.questions)) {
|
|
47
|
+
return { modified: false, result: raw };
|
|
48
|
+
}
|
|
49
|
+
let anyModified = false;
|
|
50
|
+
for (const q of parsed.questions) {
|
|
51
|
+
if (q && appendOtherIfMissing(q)) {
|
|
52
|
+
anyModified = true;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if (!anyModified)
|
|
56
|
+
return { modified: false, result: raw };
|
|
57
|
+
const finalResult = isString ? JSON.stringify(parsed) : parsed;
|
|
58
|
+
return { modified: true, result: finalResult };
|
|
59
|
+
}
|
|
60
|
+
function patchFieldIfAskQuestion(container, field) {
|
|
61
|
+
const value = container[field];
|
|
62
|
+
if (value === undefined)
|
|
63
|
+
return;
|
|
64
|
+
const { modified, result } = ensureOtherOption(value);
|
|
65
|
+
if (modified) {
|
|
66
|
+
container[field] = result;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
function isAskQuestionName(name, title) {
|
|
70
|
+
if (name === "ask_question")
|
|
71
|
+
return true;
|
|
72
|
+
return typeof title === "string" && title.toLowerCase().includes("ask_question");
|
|
73
|
+
}
|
|
74
|
+
function handleSessionUpdate(update) {
|
|
75
|
+
const isToolCall = update.sessionUpdate === SESSION_UPDATES.TOOL_CALL ||
|
|
76
|
+
update.sessionUpdate === SESSION_UPDATES.TOOL_CALL_UPDATE;
|
|
77
|
+
if (!isToolCall)
|
|
78
|
+
return;
|
|
79
|
+
if (isAskQuestionName(update.name ?? undefined, update.title ?? undefined)) {
|
|
80
|
+
patchFieldIfAskQuestion(update, "rawInput");
|
|
81
|
+
patchFieldIfAskQuestion(update, "arguments");
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
function handleRpcRequest(msg) {
|
|
85
|
+
if (!("method" in msg) || typeof msg.method !== "string")
|
|
86
|
+
return;
|
|
87
|
+
const isToolInvocation = msg.method === "tools/call" || msg.method === "session/requestPermission";
|
|
88
|
+
if (!isToolInvocation || !msg.params || typeof msg.params !== "object")
|
|
89
|
+
return;
|
|
90
|
+
const p = msg.params;
|
|
91
|
+
const toolName = (p.name ?? p.tool);
|
|
92
|
+
if (toolName === "ask_question") {
|
|
93
|
+
patchFieldIfAskQuestion(p, "arguments");
|
|
94
|
+
patchFieldIfAskQuestion(p, "rawInput");
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
function processInboundToolCall(msg) {
|
|
98
|
+
if (isMethod(msg, ACP_METHODS.SESSION_UPDATE)) {
|
|
99
|
+
const update = msg.params?.update;
|
|
100
|
+
if (update)
|
|
101
|
+
handleSessionUpdate(update);
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
handleRpcRequest(msg);
|
|
105
|
+
}
|
|
106
|
+
return msg;
|
|
107
|
+
}
|
|
108
|
+
export const missingQuestionFallbackFix = {
|
|
109
|
+
name: "missing-question-fallback",
|
|
110
|
+
description: "Steers model to include an Other choice and injects a fallback option into ask_question tool calls",
|
|
111
|
+
getSystemInstructions() {
|
|
112
|
+
return QUESTION_OPTIONS_INSTRUCTIONS;
|
|
113
|
+
},
|
|
114
|
+
onInbound(msg) {
|
|
115
|
+
return [processInboundToolCall(msg)];
|
|
116
|
+
},
|
|
117
|
+
};
|
|
118
|
+
export const questionOptionsFix = missingQuestionFallbackFix;
|
|
119
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/fixes/missing-question-fallback/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Problem:
|
|
3
|
+
* Upstream `agy_acp_server` only advertises built-in model commands and ignores custom
|
|
4
|
+
* workspace slash skills defined in standard project directories (e.g. `.agents/skills`, `.gemini/skills`).
|
|
5
|
+
*
|
|
6
|
+
* Solution:
|
|
7
|
+
* Recursively discovers `SKILL.md` skill definitions across all configured workspace directories,
|
|
8
|
+
* injects the skills catalog into active prompts, and dynamically augments `available_commands_update`.
|
|
9
|
+
*/
|
|
10
|
+
import { type AcpFix } from "../../core/types.js";
|
|
11
|
+
import { type AvailableCommand, type DiscoveredSkill, BUILTIN_COMMANDS, parseSkillFile, resolveSkillRoots, discoverSkills, augmentCommands, formatSkillsCatalog } from "./skills.js";
|
|
12
|
+
export { BUILTIN_COMMANDS, parseSkillFile, resolveSkillRoots, discoverSkills, augmentCommands, formatSkillsCatalog, };
|
|
13
|
+
export type { AvailableCommand, DiscoveredSkill };
|
|
14
|
+
export declare function injectSkillsCatalog(prompt: unknown, cwd?: string): void;
|
|
15
|
+
export declare const missingSlashSkillsFix: AcpFix;
|
|
16
|
+
export declare const slashSkillsFix: AcpFix;
|
|
17
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/fixes/missing-slash-skills/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAML,KAAK,MAAM,EAOZ,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,gBAAgB,EAChB,cAAc,EACd,iBAAiB,EACjB,cAAc,EACd,eAAe,EACf,mBAAmB,EACpB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,gBAAgB,EAChB,cAAc,EACd,iBAAiB,EACjB,cAAc,EACd,eAAe,EACf,mBAAmB,GACpB,CAAC;AACF,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,CAAC;AA8ClD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAevE;AAiBD,eAAO,MAAM,qBAAqB,EAAE,MAqBnC,CAAC;AAEF,eAAO,MAAM,cAAc,QAAwB,CAAC"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Problem:
|
|
3
|
+
* Upstream `agy_acp_server` only advertises built-in model commands and ignores custom
|
|
4
|
+
* workspace slash skills defined in standard project directories (e.g. `.agents/skills`, `.gemini/skills`).
|
|
5
|
+
*
|
|
6
|
+
* Solution:
|
|
7
|
+
* Recursively discovers `SKILL.md` skill definitions across all configured workspace directories,
|
|
8
|
+
* injects the skills catalog into active prompts, and dynamically augments `available_commands_update`.
|
|
9
|
+
*/
|
|
10
|
+
import { ACP_METHODS, SESSION_UPDATES, isMethod, isJsonRpcSuccessResponse, } from "../../core/types.js";
|
|
11
|
+
import { extractSessionId, getSession, getOrCreateSession } from "../../core/session-cache.js";
|
|
12
|
+
import { BUILTIN_COMMANDS, parseSkillFile, resolveSkillRoots, discoverSkills, augmentCommands, formatSkillsCatalog, } from "./skills.js";
|
|
13
|
+
export { BUILTIN_COMMANDS, parseSkillFile, resolveSkillRoots, discoverSkills, augmentCommands, formatSkillsCatalog, };
|
|
14
|
+
function availableCommandsUpdateOf(msg) {
|
|
15
|
+
if (!isMethod(msg, ACP_METHODS.SESSION_UPDATE))
|
|
16
|
+
return null;
|
|
17
|
+
const params = msg.params;
|
|
18
|
+
const update = params?.update;
|
|
19
|
+
if (!update || typeof update !== "object")
|
|
20
|
+
return null;
|
|
21
|
+
if (update.sessionUpdate !== SESSION_UPDATES.AVAILABLE_COMMANDS_UPDATE)
|
|
22
|
+
return null;
|
|
23
|
+
return { sessionId: params?.sessionId, update };
|
|
24
|
+
}
|
|
25
|
+
function augmentAvailableCommandsUpdate(msg, context) {
|
|
26
|
+
const found = availableCommandsUpdateOf(msg);
|
|
27
|
+
if (!found)
|
|
28
|
+
return;
|
|
29
|
+
const cwd = getSession(context.sessionCache, found.sessionId)?.cwd;
|
|
30
|
+
const existing = Array.isArray(found.update.availableCommands)
|
|
31
|
+
? found.update.availableCommands
|
|
32
|
+
: undefined;
|
|
33
|
+
found.update.availableCommands = augmentCommands(existing, cwd);
|
|
34
|
+
}
|
|
35
|
+
function initialAvailableCommandsOf(msg, context) {
|
|
36
|
+
if (!isJsonRpcSuccessResponse(msg))
|
|
37
|
+
return null;
|
|
38
|
+
const sessionId = typeof msg.result?.sessionId === "string" ? msg.result.sessionId : undefined;
|
|
39
|
+
if (!sessionId)
|
|
40
|
+
return null;
|
|
41
|
+
const cwd = getSession(context.sessionCache, sessionId)?.cwd;
|
|
42
|
+
const commands = augmentCommands(undefined, cwd);
|
|
43
|
+
if (commands.length === 0)
|
|
44
|
+
return null;
|
|
45
|
+
return {
|
|
46
|
+
jsonrpc: "2.0",
|
|
47
|
+
method: ACP_METHODS.SESSION_UPDATE,
|
|
48
|
+
params: {
|
|
49
|
+
sessionId,
|
|
50
|
+
update: {
|
|
51
|
+
sessionUpdate: SESSION_UPDATES.AVAILABLE_COMMANDS_UPDATE,
|
|
52
|
+
availableCommands: commands,
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
export function injectSkillsCatalog(prompt, cwd) {
|
|
58
|
+
if (!Array.isArray(prompt))
|
|
59
|
+
return;
|
|
60
|
+
const skills = discoverSkills(cwd);
|
|
61
|
+
const catalog = formatSkillsCatalog(skills);
|
|
62
|
+
if (!catalog)
|
|
63
|
+
return;
|
|
64
|
+
const firstChunk = prompt[0];
|
|
65
|
+
if (firstChunk && firstChunk.type === "text" && typeof firstChunk.text === "string") {
|
|
66
|
+
firstChunk.text = `${catalog}\n\n${firstChunk.text}`;
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
prompt.unshift({
|
|
70
|
+
type: "text",
|
|
71
|
+
text: catalog,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
function handleSessionPromptOutbound(msg, context) {
|
|
76
|
+
const sessionId = extractSessionId(msg);
|
|
77
|
+
if (!sessionId)
|
|
78
|
+
return;
|
|
79
|
+
const session = getOrCreateSession(context.sessionCache, sessionId);
|
|
80
|
+
const hasInjected = session.fixData?.get("hasInjectedSkillsCatalog");
|
|
81
|
+
if (!hasInjected) {
|
|
82
|
+
const prompt = "params" in msg ? msg.params?.prompt : undefined;
|
|
83
|
+
injectSkillsCatalog(prompt, session.cwd);
|
|
84
|
+
session.fixData ??= new Map();
|
|
85
|
+
session.fixData.set("hasInjectedSkillsCatalog", true);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
export const missingSlashSkillsFix = {
|
|
89
|
+
name: "missing-slash-skills",
|
|
90
|
+
description: "Discovers workspace skills from SKILL.md files and augments ACP available_commands_update",
|
|
91
|
+
onOutbound(msg, context) {
|
|
92
|
+
if (isMethod(msg, ACP_METHODS.SESSION_PROMPT)) {
|
|
93
|
+
handleSessionPromptOutbound(msg, context);
|
|
94
|
+
}
|
|
95
|
+
return msg;
|
|
96
|
+
},
|
|
97
|
+
onInbound(msg, context) {
|
|
98
|
+
if ("result" in msg && msg.result) {
|
|
99
|
+
const initialCommands = initialAvailableCommandsOf(msg, context);
|
|
100
|
+
return initialCommands ? [msg, initialCommands] : [msg];
|
|
101
|
+
}
|
|
102
|
+
augmentAvailableCommandsUpdate(msg, context);
|
|
103
|
+
return [msg];
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
export const slashSkillsFix = missingSlashSkillsFix;
|
|
107
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/fixes/missing-slash-skills/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -12,6 +12,7 @@ export interface DiscoveredSkill {
|
|
|
12
12
|
export declare function parseSkillFile(filePath: string): DiscoveredSkill | null;
|
|
13
13
|
export declare function resolveSkillRoots(cwd?: string): string[];
|
|
14
14
|
export declare function discoverSkills(cwd?: string): Map<string, DiscoveredSkill>;
|
|
15
|
+
export declare const BUILTIN_COMMANDS: AvailableCommand[];
|
|
15
16
|
export declare function augmentCommands(existingCommands: AvailableCommand[] | undefined, cwd?: string): AvailableCommand[];
|
|
16
|
-
export declare function
|
|
17
|
+
export declare function formatSkillsCatalog(skills: Map<string, DiscoveredSkill>): string;
|
|
17
18
|
//# sourceMappingURL=skills.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../../../../src/fixes/missing-slash-skills/skills.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,OAAO,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAmFD,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CAiBvE;AAED,wBAAgB,iBAAiB,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAoBxD;AAwBD,wBAAgB,cAAc,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,CAgBzE;AAED,eAAO,MAAM,gBAAgB,EAAE,gBAAgB,EAuC9C,CAAC;AAEF,wBAAgB,eAAe,CAC7B,gBAAgB,EAAE,gBAAgB,EAAE,GAAG,SAAS,EAChD,GAAG,CAAC,EAAE,MAAM,GACX,gBAAgB,EAAE,CAkBpB;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,GAAG,MAAM,CAgBhF"}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
function unquote(val) {
|
|
5
|
+
const trimmed = val.trim();
|
|
6
|
+
if ((trimmed.startsWith('"') && trimmed.endsWith('"')) ||
|
|
7
|
+
(trimmed.startsWith("'") && trimmed.endsWith("'"))) {
|
|
8
|
+
return trimmed.slice(1, -1).replace(/''/g, "'");
|
|
9
|
+
}
|
|
10
|
+
const commentIdx = trimmed.search(/\s+#/);
|
|
11
|
+
return commentIdx !== -1 ? trimmed.slice(0, commentIdx).trim() : trimmed;
|
|
12
|
+
}
|
|
13
|
+
function parseInvocable(val) {
|
|
14
|
+
const v = unquote(val).toLowerCase();
|
|
15
|
+
return v !== "false" && v !== "no" && v !== "0";
|
|
16
|
+
}
|
|
17
|
+
function parseDescription(rest, lines, i) {
|
|
18
|
+
if (rest === ">" || rest === ">-" || rest === "|" || rest === "|-") {
|
|
19
|
+
const block = [];
|
|
20
|
+
let idx = i + 1;
|
|
21
|
+
while (idx < lines.length) {
|
|
22
|
+
const line = lines[idx];
|
|
23
|
+
if (line === undefined || (!/^\s+/.test(line) && line.trim().length !== 0)) {
|
|
24
|
+
break;
|
|
25
|
+
}
|
|
26
|
+
block.push(line.trim());
|
|
27
|
+
idx++;
|
|
28
|
+
}
|
|
29
|
+
const text = rest.startsWith(">") ? block.join(" ") : block.join("\n").trim();
|
|
30
|
+
return { desc: text, nextIndex: idx - 1 };
|
|
31
|
+
}
|
|
32
|
+
return { desc: unquote(rest), nextIndex: i };
|
|
33
|
+
}
|
|
34
|
+
function parseFrontmatter(frontmatter) {
|
|
35
|
+
const lines = frontmatter.split(/\r?\n/);
|
|
36
|
+
let name;
|
|
37
|
+
let description;
|
|
38
|
+
let userInvocable = true;
|
|
39
|
+
for (let i = 0; i < lines.length; i++) {
|
|
40
|
+
const line = lines[i];
|
|
41
|
+
if (line === undefined)
|
|
42
|
+
continue;
|
|
43
|
+
const nameMatch = line.match(/^name:\s*(.*)$/);
|
|
44
|
+
if (nameMatch && nameMatch[1] !== undefined)
|
|
45
|
+
name = unquote(nameMatch[1]);
|
|
46
|
+
const invocableMatch = line.match(/^(?:user-invocable|user_invocable):\s*(.*)$/);
|
|
47
|
+
if (invocableMatch && invocableMatch[1] !== undefined) {
|
|
48
|
+
userInvocable = parseInvocable(invocableMatch[1]);
|
|
49
|
+
}
|
|
50
|
+
const descMatch = line.match(/^description:\s*(.*)$/);
|
|
51
|
+
if (descMatch && descMatch[1] !== undefined) {
|
|
52
|
+
const parsed = parseDescription(descMatch[1].trim(), lines, i);
|
|
53
|
+
description = parsed.desc;
|
|
54
|
+
i = parsed.nextIndex;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return { name, description, userInvocable };
|
|
58
|
+
}
|
|
59
|
+
function extractFrontmatterAndBody(content) {
|
|
60
|
+
const fmMatch = content.match(/^---\r?\n([\s\S]*?)\r?\n(?:---|\.\.\.)(?:\r?\n|$)([\s\S]*)$/);
|
|
61
|
+
if (!fmMatch)
|
|
62
|
+
return { meta: { userInvocable: true }, instructions: content };
|
|
63
|
+
const frontmatter = fmMatch[1] ?? "";
|
|
64
|
+
const body = fmMatch[2] ?? content;
|
|
65
|
+
return { meta: parseFrontmatter(frontmatter), instructions: body.trim() };
|
|
66
|
+
}
|
|
67
|
+
export function parseSkillFile(filePath) {
|
|
68
|
+
if (!existsSync(filePath))
|
|
69
|
+
return null;
|
|
70
|
+
try {
|
|
71
|
+
const content = readFileSync(filePath, "utf-8");
|
|
72
|
+
const { meta, instructions } = extractFrontmatterAndBody(content);
|
|
73
|
+
const fallbackName = path.basename(path.dirname(filePath));
|
|
74
|
+
return {
|
|
75
|
+
name: meta.name || fallbackName,
|
|
76
|
+
description: meta.description || `Skill: ${fallbackName}`,
|
|
77
|
+
instructions,
|
|
78
|
+
userInvocable: meta.userInvocable,
|
|
79
|
+
filePath,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
export function resolveSkillRoots(cwd) {
|
|
87
|
+
const candidates = [];
|
|
88
|
+
if (cwd) {
|
|
89
|
+
candidates.push(path.join(cwd, ".agents/skills"), path.join(cwd, ".gemini/skills"), path.join(cwd, ".codex/skills"), path.join(cwd, "skills"));
|
|
90
|
+
}
|
|
91
|
+
const home = os.homedir();
|
|
92
|
+
candidates.push(path.join(home, ".gemini/antigravity-cli/skills"), path.join(home, ".gemini/config/skills"), path.join(home, ".gemini/skills"), path.join(home, ".agents/skills"), path.join(home, ".claude/skills"), path.join(home, ".codex/skills"));
|
|
93
|
+
return Array.from(new Set(candidates.filter((dir) => existsSync(dir))));
|
|
94
|
+
}
|
|
95
|
+
const skillsCache = new Map();
|
|
96
|
+
const SKILLS_CACHE_TTL_MS = 5000;
|
|
97
|
+
function scanSkillRoot(root, skills) {
|
|
98
|
+
try {
|
|
99
|
+
for (const entry of readdirSync(root, { withFileTypes: true })) {
|
|
100
|
+
if (!entry.isDirectory() && !entry.isSymbolicLink())
|
|
101
|
+
continue;
|
|
102
|
+
const skill = parseSkillFile(path.join(root, entry.name, "SKILL.md"));
|
|
103
|
+
if (skill && !skills.has(skill.name)) {
|
|
104
|
+
skills.set(skill.name, skill);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
// Ignore unreadable dirs
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
export function discoverSkills(cwd) {
|
|
113
|
+
const key = cwd ?? "";
|
|
114
|
+
const now = Date.now();
|
|
115
|
+
const cached = skillsCache.get(key);
|
|
116
|
+
if (cached && now - cached.timestamp < SKILLS_CACHE_TTL_MS) {
|
|
117
|
+
return cached.skills;
|
|
118
|
+
}
|
|
119
|
+
const roots = resolveSkillRoots(cwd);
|
|
120
|
+
const skills = new Map();
|
|
121
|
+
for (const root of roots) {
|
|
122
|
+
scanSkillRoot(root, skills);
|
|
123
|
+
}
|
|
124
|
+
skillsCache.set(key, { timestamp: now, skills });
|
|
125
|
+
return skills;
|
|
126
|
+
}
|
|
127
|
+
export const BUILTIN_COMMANDS = [
|
|
128
|
+
{
|
|
129
|
+
name: "boost",
|
|
130
|
+
description: "Deep thinking, strategic planning, multiple perspectives, and rigorous verification (https://antigravity.google/docs/boost/)",
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
name: "teamwork",
|
|
134
|
+
description: "Coordinate a team of autonomous subagents working together on complex tasks (https://antigravity.google/docs/teamwork/)",
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
name: "teamwork-preview",
|
|
138
|
+
description: "Preview multi-agent team orchestration for collaborative parallel tasks",
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
name: "goal",
|
|
142
|
+
description: "Run a long-running task autonomously until the goal is fully achieved",
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
name: "plan",
|
|
146
|
+
description: "Plan complex tasks step-by-step before execution",
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
name: "schedule",
|
|
150
|
+
description: "Run an instruction on a recurring schedule or set a one-time timer",
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
name: "browser",
|
|
154
|
+
description: "Interact with web applications and browse the web",
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
name: "grill-me",
|
|
158
|
+
description: "Interactive interview to resolve design decisions and align on plans",
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
name: "learn",
|
|
162
|
+
description: "Persist learnings, corrections, and complex setups for future tasks",
|
|
163
|
+
},
|
|
164
|
+
];
|
|
165
|
+
export function augmentCommands(existingCommands, cwd) {
|
|
166
|
+
const result = new Map();
|
|
167
|
+
if (Array.isArray(existingCommands)) {
|
|
168
|
+
for (const cmd of existingCommands) {
|
|
169
|
+
if (cmd?.name)
|
|
170
|
+
result.set(cmd.name, cmd);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
for (const cmd of BUILTIN_COMMANDS) {
|
|
174
|
+
if (!result.has(cmd.name)) {
|
|
175
|
+
result.set(cmd.name, cmd);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
for (const skill of discoverSkills(cwd).values()) {
|
|
179
|
+
if (skill.userInvocable && !result.has(skill.name)) {
|
|
180
|
+
result.set(skill.name, { name: skill.name, description: skill.description });
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return Array.from(result.values());
|
|
184
|
+
}
|
|
185
|
+
export function formatSkillsCatalog(skills) {
|
|
186
|
+
if (skills.size === 0)
|
|
187
|
+
return "";
|
|
188
|
+
const lines = Array.from(skills.values()).map((skill) => `- ${skill.name} (${skill.filePath}): ${skill.description}`);
|
|
189
|
+
return [
|
|
190
|
+
"<skills>",
|
|
191
|
+
"You can use specialized 'skills' to help you with complex tasks.",
|
|
192
|
+
"If a skill seems relevant to your current task, read its SKILL.md instructions using your file reading tool before proceeding.",
|
|
193
|
+
"",
|
|
194
|
+
"Available skills:",
|
|
195
|
+
...lines,
|
|
196
|
+
"</skills>",
|
|
197
|
+
].join("\n");
|
|
198
|
+
}
|
|
199
|
+
//# sourceMappingURL=skills.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skills.js","sourceRoot":"","sources":["../../../../src/fixes/missing-slash-skills/skills.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Problem:
|
|
3
|
+
* Standard ACP protocol clients configure custom system prompts, workspace instructions,
|
|
4
|
+
* and personas via `_meta.systemPrompt` (or client-nested metadata). Upstream `agy_acp_server`
|
|
5
|
+
* ignores these metadata fields, providing no native mechanism to inject custom personas or rules.
|
|
6
|
+
*
|
|
7
|
+
* Solution:
|
|
8
|
+
* Caches client system prompts and dynamically injects them into the initial prompt turn
|
|
9
|
+
* enclosed in `<system_instruction>` and `<user_instruction>` blocks without mutating persisted history.
|
|
10
|
+
*/
|
|
11
|
+
import { type AcpStreamMessage, type AcpFix } from "../../core/types.js";
|
|
12
|
+
export declare const INSTRUCTION_BLOCKS_PREFIX_PATTERN: RegExp;
|
|
13
|
+
export declare function stripSystemContext(text: string): string;
|
|
14
|
+
export declare function formatSystemContext(systemPrompt?: string, harnessInstructions?: readonly string[]): string;
|
|
15
|
+
export declare function extractSystemPrompt(msg: AcpStreamMessage): string | undefined;
|
|
16
|
+
export declare function injectSystemContext(prompt: unknown, systemPrompt?: string, harnessInstructions?: readonly string[]): void;
|
|
17
|
+
export declare const missingSystemPromptFix: AcpFix;
|
|
18
|
+
export declare const systemPromptFix: AcpFix;
|
|
19
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/fixes/missing-system-prompt/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAGL,KAAK,gBAAgB,EACrB,KAAK,MAAM,EAGZ,MAAM,qBAAqB,CAAC;AAO7B,eAAO,MAAM,iCAAiC,QAC+I,CAAC;AAE9L,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED,wBAAgB,mBAAmB,CACjC,YAAY,CAAC,EAAE,MAAM,EACrB,mBAAmB,GAAE,SAAS,MAAM,EAAO,GAC1C,MAAM,CAaR;AA8BD,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,gBAAgB,GAAG,MAAM,GAAG,SAAS,CAW7E;AAED,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,OAAO,EACf,YAAY,CAAC,EAAE,MAAM,EACrB,mBAAmB,GAAE,SAAS,MAAM,EAAO,GAC1C,IAAI,CAcN;AA8CD,eAAO,MAAM,sBAAsB,EAAE,MAapC,CAAC;AAEF,eAAO,MAAM,eAAe,QAAyB,CAAC"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Problem:
|
|
3
|
+
* Standard ACP protocol clients configure custom system prompts, workspace instructions,
|
|
4
|
+
* and personas via `_meta.systemPrompt` (or client-nested metadata). Upstream `agy_acp_server`
|
|
5
|
+
* ignores these metadata fields, providing no native mechanism to inject custom personas or rules.
|
|
6
|
+
*
|
|
7
|
+
* Solution:
|
|
8
|
+
* Caches client system prompts and dynamically injects them into the initial prompt turn
|
|
9
|
+
* enclosed in `<system_instruction>` and `<user_instruction>` blocks without mutating persisted history.
|
|
10
|
+
*/
|
|
11
|
+
import { ACP_METHODS, isMethod, } from "../../core/types.js";
|
|
12
|
+
import { extractSessionId, getOrCreateSession, recordPendingSessionMetadata, } from "../../core/session-cache.js";
|
|
13
|
+
export const INSTRUCTION_BLOCKS_PREFIX_PATTERN = /^\s*(?:<\s*(?:system|user)[-_](?:instruction|message)(?:\s+[^>]*)?>[\s\S]*?<\/\s*(?:system|user)[-_](?:instruction|message)\s*>\s*|<\s*skills(?:\s+[^>]*)?>[\s\S]*?<\/\s*skills\s*>\s*)+/i;
|
|
14
|
+
export function stripSystemContext(text) {
|
|
15
|
+
return text.replace(INSTRUCTION_BLOCKS_PREFIX_PATTERN, "");
|
|
16
|
+
}
|
|
17
|
+
export function formatSystemContext(systemPrompt, harnessInstructions = []) {
|
|
18
|
+
const blocks = [];
|
|
19
|
+
if (harnessInstructions.length > 0) {
|
|
20
|
+
const formatted = harnessInstructions.map((r) => `- ${r}`).join("\n");
|
|
21
|
+
blocks.push(`<system_instruction>\n${formatted}\n</system_instruction>`);
|
|
22
|
+
}
|
|
23
|
+
if (systemPrompt && systemPrompt.trim().length > 0) {
|
|
24
|
+
blocks.push(`<user_instruction>\n${systemPrompt.trim()}\n</user_instruction>`);
|
|
25
|
+
}
|
|
26
|
+
return blocks.join("\n\n");
|
|
27
|
+
}
|
|
28
|
+
function findNestedSystemPrompt(meta) {
|
|
29
|
+
for (const val of Object.values(meta)) {
|
|
30
|
+
if (val && typeof val === "object" && "systemPrompt" in val) {
|
|
31
|
+
const nested = val.systemPrompt;
|
|
32
|
+
if (typeof nested === "string" && nested.trim().length > 0) {
|
|
33
|
+
return nested.trim();
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return undefined;
|
|
38
|
+
}
|
|
39
|
+
export function extractSystemPrompt(msg) {
|
|
40
|
+
if (!("params" in msg) || !msg.params)
|
|
41
|
+
return undefined;
|
|
42
|
+
const params = msg.params;
|
|
43
|
+
if (!params._meta)
|
|
44
|
+
return undefined;
|
|
45
|
+
if (typeof params._meta.systemPrompt === "string") {
|
|
46
|
+
const trimmed = params._meta.systemPrompt.trim();
|
|
47
|
+
if (trimmed.length > 0)
|
|
48
|
+
return trimmed;
|
|
49
|
+
}
|
|
50
|
+
return findNestedSystemPrompt(params._meta);
|
|
51
|
+
}
|
|
52
|
+
export function injectSystemContext(prompt, systemPrompt, harnessInstructions = []) {
|
|
53
|
+
if (!Array.isArray(prompt))
|
|
54
|
+
return;
|
|
55
|
+
const context = formatSystemContext(systemPrompt, harnessInstructions);
|
|
56
|
+
if (!context)
|
|
57
|
+
return;
|
|
58
|
+
const firstChunk = prompt[0];
|
|
59
|
+
if (firstChunk && firstChunk.type === "text" && typeof firstChunk.text === "string") {
|
|
60
|
+
firstChunk.text = `${context}\n\n${firstChunk.text}`;
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
prompt.unshift({
|
|
64
|
+
type: "text",
|
|
65
|
+
text: context,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
function handleSessionNewOutbound(msg, context) {
|
|
70
|
+
const systemPrompt = extractSystemPrompt(msg);
|
|
71
|
+
if (!systemPrompt || !("id" in msg) || msg.id === null || msg.id === undefined)
|
|
72
|
+
return;
|
|
73
|
+
const pending = context.sessionCache.pendingSessionMetadata.get(msg.id) ?? {};
|
|
74
|
+
pending.fixData ??= new Map();
|
|
75
|
+
pending.fixData.set("systemPrompt", systemPrompt);
|
|
76
|
+
recordPendingSessionMetadata(context.sessionCache, msg.id, pending);
|
|
77
|
+
}
|
|
78
|
+
function collectSystemInstructions(fixes, session, context) {
|
|
79
|
+
if (!fixes)
|
|
80
|
+
return [];
|
|
81
|
+
const instructions = [];
|
|
82
|
+
for (const fix of fixes) {
|
|
83
|
+
const list = fix.getSystemInstructions?.(session, context);
|
|
84
|
+
if (list && list.length > 0) {
|
|
85
|
+
instructions.push(...list);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return instructions;
|
|
89
|
+
}
|
|
90
|
+
function handleSessionPromptOutbound(msg, context) {
|
|
91
|
+
const sessionId = extractSessionId(msg);
|
|
92
|
+
if (!sessionId)
|
|
93
|
+
return;
|
|
94
|
+
const session = getOrCreateSession(context.sessionCache, sessionId);
|
|
95
|
+
if (session.fixData?.get("hasInjectedSystemContext"))
|
|
96
|
+
return;
|
|
97
|
+
const systemPrompt = session.fixData?.get("systemPrompt");
|
|
98
|
+
const prompt = "params" in msg ? msg.params?.prompt : undefined;
|
|
99
|
+
const instructions = collectSystemInstructions(context.fixes, session, context);
|
|
100
|
+
injectSystemContext(prompt, systemPrompt, instructions);
|
|
101
|
+
session.fixData ??= new Map();
|
|
102
|
+
session.fixData.set("hasInjectedSystemContext", true);
|
|
103
|
+
}
|
|
104
|
+
export const missingSystemPromptFix = {
|
|
105
|
+
name: "missing-system-prompt",
|
|
106
|
+
description: "Injects client-configured custom system prompts and instructions into session prompts",
|
|
107
|
+
onOutbound(msg, context) {
|
|
108
|
+
if (isMethod(msg, ACP_METHODS.SESSION_NEW)) {
|
|
109
|
+
handleSessionNewOutbound(msg, context);
|
|
110
|
+
}
|
|
111
|
+
else if (isMethod(msg, ACP_METHODS.SESSION_PROMPT)) {
|
|
112
|
+
handleSessionPromptOutbound(msg, context);
|
|
113
|
+
}
|
|
114
|
+
return msg;
|
|
115
|
+
},
|
|
116
|
+
};
|
|
117
|
+
export const systemPromptFix = missingSystemPromptFix;
|
|
118
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/fixes/missing-system-prompt/index.ts"],"names":[],"mappings":"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"}
|