@kenkaiiii/ggcoder 5.6.0 → 5.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app-sidecar.js +274 -53
- package/dist/app-sidecar.js.map +1 -1
- package/dist/core/agent-session-queue.test.d.ts +2 -0
- package/dist/core/agent-session-queue.test.d.ts.map +1 -0
- package/dist/core/agent-session-queue.test.js +122 -0
- package/dist/core/agent-session-queue.test.js.map +1 -0
- package/dist/core/agent-session.d.ts +8 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +7 -0
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/autopilot-cycle.d.ts +67 -0
- package/dist/core/autopilot-cycle.d.ts.map +1 -0
- package/dist/core/autopilot-cycle.js +50 -0
- package/dist/core/autopilot-cycle.js.map +1 -0
- package/dist/core/autopilot-cycle.test.d.ts +2 -0
- package/dist/core/autopilot-cycle.test.d.ts.map +1 -0
- package/dist/core/autopilot-cycle.test.js +179 -0
- package/dist/core/autopilot-cycle.test.js.map +1 -0
- package/dist/core/autopilot-gate.d.ts +83 -0
- package/dist/core/autopilot-gate.d.ts.map +1 -0
- package/dist/core/autopilot-gate.js +96 -0
- package/dist/core/autopilot-gate.js.map +1 -0
- package/dist/core/autopilot-gate.test.d.ts +2 -0
- package/dist/core/autopilot-gate.test.d.ts.map +1 -0
- package/dist/core/autopilot-gate.test.js +159 -0
- package/dist/core/autopilot-gate.test.js.map +1 -0
- package/dist/core/ken-context.d.ts +17 -0
- package/dist/core/ken-context.d.ts.map +1 -1
- package/dist/core/ken-context.js +47 -6
- package/dist/core/ken-context.js.map +1 -1
- package/dist/core/ken-context.test.js +122 -1
- package/dist/core/ken-context.test.js.map +1 -1
- package/dist/core/ken-model.d.ts +46 -0
- package/dist/core/ken-model.d.ts.map +1 -0
- package/dist/core/ken-model.js +26 -0
- package/dist/core/ken-model.js.map +1 -0
- package/dist/core/ken-model.test.d.ts +2 -0
- package/dist/core/ken-model.test.d.ts.map +1 -0
- package/dist/core/ken-model.test.js +51 -0
- package/dist/core/ken-model.test.js.map +1 -0
- package/dist/core/ken-prompt.js +8 -4
- package/dist/core/ken-prompt.js.map +1 -1
- package/dist/core/ken-prompt.test.d.ts +2 -0
- package/dist/core/ken-prompt.test.d.ts.map +1 -0
- package/dist/core/ken-prompt.test.js +43 -0
- package/dist/core/ken-prompt.test.js.map +1 -0
- package/dist/core/speed-benchmark.test.js +2 -3
- package/dist/core/speed-benchmark.test.js.map +1 -1
- package/package.json +4 -4
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Autopilot gate — pure decision logic for whether Ken's auto-review cycle may
|
|
3
|
+
* start after a finished GG Coder turn.
|
|
4
|
+
*
|
|
5
|
+
* Autopilot must NOT review every turn. The concrete leak cases this gate
|
|
6
|
+
* closes (each has a matching unit test in autopilot-gate.test.ts):
|
|
7
|
+
*
|
|
8
|
+
* - Workflow slash commands (`/compare`, `/bullet-proof`, `/expand`, custom
|
|
9
|
+
* `.gg/commands/*.md`) end with reports or A/B/C choices that are reserved
|
|
10
|
+
* for the USER. Ken reviewing them reads "findings" as "something real is
|
|
11
|
+
* wrong" and injects fix prompts the user never approved.
|
|
12
|
+
* - Registry commands (`/help`, `/session`, unknown `/foo`) and failed runs
|
|
13
|
+
* add no assistant work at all — a review would judge the PREVIOUS turn
|
|
14
|
+
* again (Ken's cycle memory is wiped per turn) and can flip a settled
|
|
15
|
+
* ALL_CLEAR into a fresh PROMPT.
|
|
16
|
+
* - A turn that ended in plan mode has a pending Accept/Reject modal; Ken must
|
|
17
|
+
* never inject a prompt into a read-only plan-mode session.
|
|
18
|
+
*
|
|
19
|
+
* Kept pure + dependency-light so it's unit-testable without booting the
|
|
20
|
+
* sidecar (which runs `main()` at import time).
|
|
21
|
+
*/
|
|
22
|
+
/** The exact separator AgentSession.prompt() inserts between a command's
|
|
23
|
+
* template and the user's extra args (see agent-session.ts prompt expansion).
|
|
24
|
+
* Must stay byte-identical or expanded-command detection silently breaks. */
|
|
25
|
+
export const USER_INSTRUCTIONS_HEADER = "\n\n## User Instructions\n\n";
|
|
26
|
+
/** Extract the `/name` token from raw input, or null when it isn't a slash
|
|
27
|
+
* invocation. */
|
|
28
|
+
function parseSlashName(text) {
|
|
29
|
+
const trimmed = text.trim();
|
|
30
|
+
if (!trimmed.startsWith("/"))
|
|
31
|
+
return null;
|
|
32
|
+
const name = trimmed.slice(1).split(/\s/, 1)[0]?.toLowerCase() ?? "";
|
|
33
|
+
return name.length > 0 ? name : null;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* True when `text` invokes a known workflow command (first token, name or
|
|
37
|
+
* alias, case-insensitive). Registry/UI commands and unknown `/foo` return
|
|
38
|
+
* false — those add no assistant work and are caught by the
|
|
39
|
+
* `no-assistant-output` gate instead.
|
|
40
|
+
*/
|
|
41
|
+
export function isWorkflowCommandText(text, commands) {
|
|
42
|
+
const name = parseSlashName(text);
|
|
43
|
+
if (!name)
|
|
44
|
+
return false;
|
|
45
|
+
return commands.some((c) => c.name.toLowerCase() === name || (c.aliases ?? []).some((a) => a.toLowerCase() === name));
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Match a transcript user-message body back to the workflow command it was
|
|
49
|
+
* expanded from. AgentSession stores the EXPANDED template as a plain user
|
|
50
|
+
* message, so without this Ken's digest renders 400-line templates as
|
|
51
|
+
* `**User:** …` and treats them as user-authored asks.
|
|
52
|
+
*
|
|
53
|
+
* Returns the matched command plus any trailing user args, or null.
|
|
54
|
+
*/
|
|
55
|
+
export function matchExpandedCommand(text, commands) {
|
|
56
|
+
for (const command of commands) {
|
|
57
|
+
if (!command.prompt)
|
|
58
|
+
continue;
|
|
59
|
+
if (text === command.prompt)
|
|
60
|
+
return { command, args: null };
|
|
61
|
+
const prefix = command.prompt + USER_INSTRUCTIONS_HEADER;
|
|
62
|
+
if (text.startsWith(prefix)) {
|
|
63
|
+
const args = text.slice(prefix.length).trim();
|
|
64
|
+
return { command, args: args.length > 0 ? args : null };
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
/** Count assistant messages — the "did this run produce reviewable work"
|
|
70
|
+
* signal. Compared before/after a run by the sidecar. */
|
|
71
|
+
export function countAssistantMessages(messages) {
|
|
72
|
+
let count = 0;
|
|
73
|
+
for (const m of messages)
|
|
74
|
+
if (m.role === "assistant")
|
|
75
|
+
count++;
|
|
76
|
+
return count;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Decide whether the autopilot cycle may start for a just-finished turn.
|
|
80
|
+
* Checks are ordered cheapest/most-fundamental first; the reason is logged by
|
|
81
|
+
* the sidecar so skips are debuggable from gg-app-sidecar.log.
|
|
82
|
+
*/
|
|
83
|
+
export function shouldStartAutopilotCycle(input) {
|
|
84
|
+
if (!input.enabled)
|
|
85
|
+
return { start: false, reason: "disabled" };
|
|
86
|
+
if (input.cancelled)
|
|
87
|
+
return { start: false, reason: "cancelled" };
|
|
88
|
+
if (input.planMode)
|
|
89
|
+
return { start: false, reason: "plan-mode" };
|
|
90
|
+
if (input.workflowCommand)
|
|
91
|
+
return { start: false, reason: "workflow-command" };
|
|
92
|
+
if (input.assistantMessagesAdded <= 0)
|
|
93
|
+
return { start: false, reason: "no-assistant-output" };
|
|
94
|
+
return { start: true };
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=autopilot-gate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"autopilot-gate.js","sourceRoot":"","sources":["../../src/core/autopilot-gate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"autopilot-gate.test.d.ts","sourceRoot":"","sources":["../../src/core/autopilot-gate.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { isWorkflowCommandText, matchExpandedCommand, countAssistantMessages, shouldStartAutopilotCycle, USER_INSTRUCTIONS_HEADER, } from "./autopilot-gate.js";
|
|
3
|
+
import { PROMPT_COMMANDS } from "./prompt-commands.js";
|
|
4
|
+
const COMMANDS = [
|
|
5
|
+
{ name: "compare", aliases: [], prompt: "Compare the code you just created…" },
|
|
6
|
+
{ name: "bullet-proof", aliases: ["bp"], prompt: "Audit the project…" },
|
|
7
|
+
];
|
|
8
|
+
describe("isWorkflowCommandText", () => {
|
|
9
|
+
it("matches a bare command", () => {
|
|
10
|
+
expect(isWorkflowCommandText("/compare", COMMANDS)).toBe(true);
|
|
11
|
+
});
|
|
12
|
+
it("matches a command with trailing args", () => {
|
|
13
|
+
expect(isWorkflowCommandText("/compare src/foo.ts please", COMMANDS)).toBe(true);
|
|
14
|
+
});
|
|
15
|
+
it("matches aliases and is case-insensitive", () => {
|
|
16
|
+
expect(isWorkflowCommandText("/bp", COMMANDS)).toBe(true);
|
|
17
|
+
expect(isWorkflowCommandText("/COMPARE", COMMANDS)).toBe(true);
|
|
18
|
+
expect(isWorkflowCommandText("/Bullet-Proof", COMMANDS)).toBe(true);
|
|
19
|
+
});
|
|
20
|
+
it("tolerates leading whitespace (matches trim semantics of the prompt path)", () => {
|
|
21
|
+
expect(isWorkflowCommandText(" /compare", COMMANDS)).toBe(true);
|
|
22
|
+
});
|
|
23
|
+
it("rejects unknown commands, non-slash text, and prefix collisions", () => {
|
|
24
|
+
expect(isWorkflowCommandText("/help", COMMANDS)).toBe(false);
|
|
25
|
+
expect(isWorkflowCommandText("/comparex", COMMANDS)).toBe(false);
|
|
26
|
+
expect(isWorkflowCommandText("compare the files", COMMANDS)).toBe(false);
|
|
27
|
+
expect(isWorkflowCommandText("run /compare for me", COMMANDS)).toBe(false);
|
|
28
|
+
expect(isWorkflowCommandText("/", COMMANDS)).toBe(false);
|
|
29
|
+
expect(isWorkflowCommandText("", COMMANDS)).toBe(false);
|
|
30
|
+
});
|
|
31
|
+
it("recognizes EVERY built-in workflow command (the real leak set)", () => {
|
|
32
|
+
// The reported bug: /compare fired an autopilot review of a report-only
|
|
33
|
+
// command. Prove the gate recognizes every shipped PROMPT_COMMAND (and its
|
|
34
|
+
// aliases) so none of them can leak into a review.
|
|
35
|
+
for (const cmd of PROMPT_COMMANDS) {
|
|
36
|
+
expect(isWorkflowCommandText(`/${cmd.name}`, PROMPT_COMMANDS)).toBe(true);
|
|
37
|
+
expect(isWorkflowCommandText(`/${cmd.name} with args`, PROMPT_COMMANDS)).toBe(true);
|
|
38
|
+
for (const alias of cmd.aliases) {
|
|
39
|
+
expect(isWorkflowCommandText(`/${alias}`, PROMPT_COMMANDS)).toBe(true);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
describe("matchExpandedCommand", () => {
|
|
45
|
+
it("matches an exact template body", () => {
|
|
46
|
+
const m = matchExpandedCommand("Compare the code you just created…", COMMANDS);
|
|
47
|
+
expect(m?.command.name).toBe("compare");
|
|
48
|
+
expect(m?.args).toBeNull();
|
|
49
|
+
});
|
|
50
|
+
it("matches template + user-instructions suffix and extracts the args", () => {
|
|
51
|
+
const text = `Audit the project…${USER_INSTRUCTIONS_HEADER}only the auth module`;
|
|
52
|
+
const m = matchExpandedCommand(text, COMMANDS);
|
|
53
|
+
expect(m?.command.name).toBe("bullet-proof");
|
|
54
|
+
expect(m?.args).toBe("only the auth module");
|
|
55
|
+
});
|
|
56
|
+
it("uses the exact separator AgentSession.prompt() inserts", () => {
|
|
57
|
+
// Lockstep guard: if agent-session.ts ever changes its expansion format,
|
|
58
|
+
// this literal must change with it or digest labeling silently breaks.
|
|
59
|
+
expect(USER_INSTRUCTIONS_HEADER).toBe("\n\n## User Instructions\n\n");
|
|
60
|
+
});
|
|
61
|
+
it("returns null for ordinary user text and near-misses", () => {
|
|
62
|
+
expect(matchExpandedCommand("compare my code to the repo", COMMANDS)).toBeNull();
|
|
63
|
+
// Template body with arbitrary extra text but no separator is NOT an expansion.
|
|
64
|
+
expect(matchExpandedCommand("Compare the code you just created… and also do X", COMMANDS)).toBeNull();
|
|
65
|
+
expect(matchExpandedCommand("", COMMANDS)).toBeNull();
|
|
66
|
+
});
|
|
67
|
+
it("matches every real built-in template round-tripped through expansion", () => {
|
|
68
|
+
for (const cmd of PROMPT_COMMANDS) {
|
|
69
|
+
// Mirrors AgentSession.prompt(): bare command → template verbatim.
|
|
70
|
+
expect(matchExpandedCommand(cmd.prompt, PROMPT_COMMANDS)?.command.name).toBe(cmd.name);
|
|
71
|
+
// Command with args → template + header + args.
|
|
72
|
+
const withArgs = `${cmd.prompt}${USER_INSTRUCTIONS_HEADER}focus on src/`;
|
|
73
|
+
const m = matchExpandedCommand(withArgs, PROMPT_COMMANDS);
|
|
74
|
+
expect(m?.command.name).toBe(cmd.name);
|
|
75
|
+
expect(m?.args).toBe("focus on src/");
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
describe("countAssistantMessages", () => {
|
|
80
|
+
it("counts only assistant-role messages", () => {
|
|
81
|
+
expect(countAssistantMessages([
|
|
82
|
+
{ role: "system" },
|
|
83
|
+
{ role: "user" },
|
|
84
|
+
{ role: "assistant" },
|
|
85
|
+
{ role: "tool" },
|
|
86
|
+
{ role: "assistant" },
|
|
87
|
+
])).toBe(2);
|
|
88
|
+
expect(countAssistantMessages([])).toBe(0);
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
describe("shouldStartAutopilotCycle", () => {
|
|
92
|
+
const reviewable = {
|
|
93
|
+
enabled: true,
|
|
94
|
+
cancelled: false,
|
|
95
|
+
planMode: false,
|
|
96
|
+
workflowCommand: false,
|
|
97
|
+
assistantMessagesAdded: 1,
|
|
98
|
+
};
|
|
99
|
+
it("starts for a normal reviewable turn", () => {
|
|
100
|
+
expect(shouldStartAutopilotCycle(reviewable)).toEqual({ start: true });
|
|
101
|
+
});
|
|
102
|
+
it("skips when autopilot is off", () => {
|
|
103
|
+
expect(shouldStartAutopilotCycle({ ...reviewable, enabled: false })).toEqual({
|
|
104
|
+
start: false,
|
|
105
|
+
reason: "disabled",
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
it("skips when the turn was cancelled", () => {
|
|
109
|
+
expect(shouldStartAutopilotCycle({ ...reviewable, cancelled: true })).toEqual({
|
|
110
|
+
start: false,
|
|
111
|
+
reason: "cancelled",
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
it("skips when the turn ended in plan mode (pending Accept/Reject modal)", () => {
|
|
115
|
+
expect(shouldStartAutopilotCycle({ ...reviewable, planMode: true })).toEqual({
|
|
116
|
+
start: false,
|
|
117
|
+
reason: "plan-mode",
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
it("skips workflow-command turns (/compare — the reported bug)", () => {
|
|
121
|
+
expect(shouldStartAutopilotCycle({ ...reviewable, workflowCommand: true })).toEqual({
|
|
122
|
+
start: false,
|
|
123
|
+
reason: "workflow-command",
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
it("skips turns that added no assistant output (/help, unknown /foo, failed runs)", () => {
|
|
127
|
+
expect(shouldStartAutopilotCycle({ ...reviewable, assistantMessagesAdded: 0 })).toEqual({
|
|
128
|
+
start: false,
|
|
129
|
+
reason: "no-assistant-output",
|
|
130
|
+
});
|
|
131
|
+
// A run that somehow REMOVED messages (defensive) also never reviews.
|
|
132
|
+
expect(shouldStartAutopilotCycle({ ...reviewable, assistantMessagesAdded: -1 })).toEqual({
|
|
133
|
+
start: false,
|
|
134
|
+
reason: "no-assistant-output",
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
it("resolves multiple skip conditions in fixed priority order", () => {
|
|
138
|
+
// disabled beats everything; plan-mode beats workflow-command beats no-output.
|
|
139
|
+
expect(shouldStartAutopilotCycle({
|
|
140
|
+
enabled: false,
|
|
141
|
+
cancelled: true,
|
|
142
|
+
planMode: true,
|
|
143
|
+
workflowCommand: true,
|
|
144
|
+
assistantMessagesAdded: 0,
|
|
145
|
+
})).toEqual({ start: false, reason: "disabled" });
|
|
146
|
+
expect(shouldStartAutopilotCycle({
|
|
147
|
+
...reviewable,
|
|
148
|
+
planMode: true,
|
|
149
|
+
workflowCommand: true,
|
|
150
|
+
assistantMessagesAdded: 0,
|
|
151
|
+
})).toEqual({ start: false, reason: "plan-mode" });
|
|
152
|
+
expect(shouldStartAutopilotCycle({
|
|
153
|
+
...reviewable,
|
|
154
|
+
workflowCommand: true,
|
|
155
|
+
assistantMessagesAdded: 0,
|
|
156
|
+
})).toEqual({ start: false, reason: "workflow-command" });
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
//# sourceMappingURL=autopilot-gate.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"autopilot-gate.test.js","sourceRoot":"","sources":["../../src/core/autopilot-gate.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,8 +11,14 @@
|
|
|
11
11
|
* (which runs `main()` at import time).
|
|
12
12
|
*/
|
|
13
13
|
import type { Message } from "@kenkaiiii/gg-ai";
|
|
14
|
+
import { type WorkflowCommandSpec } from "./autopilot-gate.js";
|
|
14
15
|
/** How many of the most recent build-session messages to inline verbatim. */
|
|
15
16
|
export declare const KEN_RECENT_MESSAGE_LIMIT = 20;
|
|
17
|
+
/** Label for a user-role message that was actually injected by Autopilot Ken.
|
|
18
|
+
* Without it, multi-round cycles render Ken's own fix prompts as `**User:**`
|
|
19
|
+
* and he starts reviewing against his own last prompt instead of the user's
|
|
20
|
+
* original ask. Referenced by the autopilot system prompt — keep in sync. */
|
|
21
|
+
export declare const INJECTED_PROMPT_LABEL = "**Ken autopilot (injected):**";
|
|
16
22
|
export interface KenDigestInput {
|
|
17
23
|
/** The user's `@Ken …` text (already stripped of the mention). */
|
|
18
24
|
question: string;
|
|
@@ -26,6 +32,17 @@ export interface KenDigestInput {
|
|
|
26
32
|
platform?: string;
|
|
27
33
|
/** Override the recent-message cap (tests). */
|
|
28
34
|
recentLimit?: number;
|
|
35
|
+
/** The user prompt that started the turn under review (autopilot). Pinned in
|
|
36
|
+
* its own section so it can never scroll out of the rolling recent-activity
|
|
37
|
+
* window during multi-round cycles. */
|
|
38
|
+
originalRequest?: string;
|
|
39
|
+
/** Prompt bodies Autopilot Ken injected into the build session. Matching
|
|
40
|
+
* user messages render under {@link INJECTED_PROMPT_LABEL}, not `**User:**`. */
|
|
41
|
+
injectedPrompts?: readonly string[];
|
|
42
|
+
/** Known workflow commands (built-in + custom). Expanded template bodies in
|
|
43
|
+
* the transcript render as a short `[ran workflow command /name]` note
|
|
44
|
+
* instead of hundreds of template lines masquerading as a user ask. */
|
|
45
|
+
workflowCommands?: readonly WorkflowCommandSpec[];
|
|
29
46
|
}
|
|
30
47
|
/**
|
|
31
48
|
* Fixed instruction fed into the digest's `question` slot in autopilot mode.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ken-context.d.ts","sourceRoot":"","sources":["../../src/core/ken-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,EAAE,OAAO,EAA2B,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"ken-context.d.ts","sourceRoot":"","sources":["../../src/core/ken-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,EAAE,OAAO,EAA2B,MAAM,kBAAkB,CAAC;AACzE,OAAO,EAAwB,KAAK,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAErF,6EAA6E;AAC7E,eAAO,MAAM,wBAAwB,KAAK,CAAC;AAa3C;;;8EAG8E;AAC9E,eAAO,MAAM,qBAAqB,kCAAkC,CAAC;AAErE,MAAM,WAAW,cAAc;IAC7B,kEAAkE;IAClE,QAAQ,EAAE,MAAM,CAAC;IACjB,6EAA6E;IAC7E,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,6DAA6D;IAC7D,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,sDAAsD;IACtD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,+CAA+C;IAC/C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;4CAEwC;IACxC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;qFACiF;IACjF,eAAe,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC;;4EAEwE;IACxE,gBAAgB,CAAC,EAAE,SAAS,mBAAmB,EAAE,CAAC;CACnD;AAiGD;;;;;;GAMG;AACH,eAAO,MAAM,4BAA4B,QAOH,CAAC;AAEvC;;mCAEmC;AACnC,MAAM,MAAM,wBAAwB,GAAG,IAAI,CAAC,cAAc,EAAE,UAAU,CAAC,CAAC;AAExE;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,wBAAwB,GAAG,MAAM,CAEhF;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,CAyE5D"}
|
package/dist/core/ken-context.js
CHANGED
|
@@ -1,9 +1,19 @@
|
|
|
1
|
+
import { matchExpandedCommand } from "./autopilot-gate.js";
|
|
1
2
|
/** How many of the most recent build-session messages to inline verbatim. */
|
|
2
3
|
export const KEN_RECENT_MESSAGE_LIMIT = 20;
|
|
3
4
|
/** Marker the compactor prepends to its summary user-message. */
|
|
4
5
|
const COMPACTION_SUMMARY_MARKER = "[Previous conversation summary]";
|
|
5
6
|
/** Max chars of any single message's rendered text in the digest. */
|
|
6
7
|
const MESSAGE_CHAR_CAP = 1500;
|
|
8
|
+
/** Softer cap for the pinned original-request section: the ask under review
|
|
9
|
+
* must never be judged against a mid-sentence truncation, so it gets far more
|
|
10
|
+
* room than a recent-activity line. */
|
|
11
|
+
const ORIGINAL_REQUEST_CAP = 4000;
|
|
12
|
+
/** Label for a user-role message that was actually injected by Autopilot Ken.
|
|
13
|
+
* Without it, multi-round cycles render Ken's own fix prompts as `**User:**`
|
|
14
|
+
* and he starts reviewing against his own last prompt instead of the user's
|
|
15
|
+
* original ask. Referenced by the autopilot system prompt — keep in sync. */
|
|
16
|
+
export const INJECTED_PROMPT_LABEL = "**Ken autopilot (injected):**";
|
|
7
17
|
/** Truncate long text and note how much was dropped. */
|
|
8
18
|
function cap(text, max = MESSAGE_CHAR_CAP) {
|
|
9
19
|
if (text.length <= max)
|
|
@@ -22,10 +32,26 @@ function summarizeToolCall(name, args) {
|
|
|
22
32
|
const arg = typeof primary === "string" ? cap(primary, 80) : "";
|
|
23
33
|
return arg ? `${name}(${arg})` : `${name}()`;
|
|
24
34
|
}
|
|
35
|
+
/** Render one user-role message body with provenance-aware labeling:
|
|
36
|
+
* autopilot-injected prompts and workflow-command expansions are labeled as
|
|
37
|
+
* what they ARE, so Ken never mistakes either for a user-authored ask. */
|
|
38
|
+
function renderUserText(text, opts) {
|
|
39
|
+
if (!text)
|
|
40
|
+
return null;
|
|
41
|
+
if (opts.injectedPrompts.some((p) => p.trim() === text.trim())) {
|
|
42
|
+
return `${INJECTED_PROMPT_LABEL} ${cap(text)}`;
|
|
43
|
+
}
|
|
44
|
+
const expanded = matchExpandedCommand(text, opts.workflowCommands);
|
|
45
|
+
if (expanded) {
|
|
46
|
+
const head = `**User:** [ran workflow command /${expanded.command.name}]`;
|
|
47
|
+
return expanded.args ? `${head} with instructions: ${cap(expanded.args, 400)}` : head;
|
|
48
|
+
}
|
|
49
|
+
return `**User:** ${cap(text)}`;
|
|
50
|
+
}
|
|
25
51
|
/** Render one message's role-tagged text, stripping image/blob payloads and
|
|
26
52
|
* summarizing tool calls/results to short lines. Returns null for empty/noise
|
|
27
53
|
* messages (e.g. a tool result that was only an image). */
|
|
28
|
-
function renderMessage(msg) {
|
|
54
|
+
function renderMessage(msg, opts) {
|
|
29
55
|
if (msg.role === "user") {
|
|
30
56
|
const text = typeof msg.content === "string"
|
|
31
57
|
? msg.content
|
|
@@ -33,7 +59,7 @@ function renderMessage(msg) {
|
|
|
33
59
|
.map((p) => (p.type === "text" ? p.text : `[${p.type}]`))
|
|
34
60
|
.join(" ")
|
|
35
61
|
.trim();
|
|
36
|
-
return text
|
|
62
|
+
return renderUserText(text, opts);
|
|
37
63
|
}
|
|
38
64
|
if (msg.role === "assistant") {
|
|
39
65
|
if (typeof msg.content === "string") {
|
|
@@ -86,9 +112,12 @@ function renderMessage(msg) {
|
|
|
86
112
|
* the transcript and demands the machine-parseable answer.
|
|
87
113
|
*/
|
|
88
114
|
export const AUTOPILOT_REVIEW_INSTRUCTION = "GG Coder just finished a turn. Review its work against the user's original " +
|
|
89
|
-
"
|
|
90
|
-
"
|
|
91
|
-
"
|
|
115
|
+
"ask (the 'Original user request' section above; lines labeled 'Ken " +
|
|
116
|
+
"autopilot (injected)' are your own earlier fix prompts, NOT user asks). " +
|
|
117
|
+
"Reply with your verdict ONLY — the first line must be exactly PROMPT, " +
|
|
118
|
+
"ALL_CLEAR, IGNORE, or HUMAN, with the payload after. If GG Coder ended by " +
|
|
119
|
+
"asking the user a question or presenting options, the verdict is HUMAN. " +
|
|
120
|
+
"No greetings, no mentorship prose.";
|
|
92
121
|
/**
|
|
93
122
|
* Build the autopilot-review digest: identical to a normal Ken digest but with
|
|
94
123
|
* the fixed {@link AUTOPILOT_REVIEW_INSTRUCTION} as the trailing question, so
|
|
@@ -120,9 +149,15 @@ export function buildKenDigest(input) {
|
|
|
120
149
|
}
|
|
121
150
|
// Recent conversation = messages after the summary (or the tail), skipping
|
|
122
151
|
// the system message and the summary message itself.
|
|
152
|
+
const renderOpts = {
|
|
153
|
+
injectedPrompts: input.injectedPrompts ?? [],
|
|
154
|
+
workflowCommands: input.workflowCommands ?? [],
|
|
155
|
+
};
|
|
123
156
|
const afterSummary = input.messages.slice(summaryIndex + 1).filter((m) => m.role !== "system");
|
|
124
157
|
const recent = afterSummary.slice(-recentLimit);
|
|
125
|
-
const renderedRecent = recent
|
|
158
|
+
const renderedRecent = recent
|
|
159
|
+
.map((m) => renderMessage(m, renderOpts))
|
|
160
|
+
.filter((l) => l !== null);
|
|
126
161
|
const sections = [];
|
|
127
162
|
sections.push(`## Who you are\nYou are Ken Kai, mentoring the user inside GG Coder. Your persona is in your system prompt. Below is what GG Coder and the user are working on.`);
|
|
128
163
|
const building = [];
|
|
@@ -133,6 +168,12 @@ export function buildKenDigest(input) {
|
|
|
133
168
|
if (summaryText) {
|
|
134
169
|
sections.push(`## Story so far\n${cap(summaryText, 4000)}`);
|
|
135
170
|
}
|
|
171
|
+
// Pinned so multi-round autopilot cycles can never lose the ask under review
|
|
172
|
+
// to the rolling recent-activity window (the drift that made Ken judge his
|
|
173
|
+
// own injected prompt as "the user's request").
|
|
174
|
+
if (input.originalRequest?.trim()) {
|
|
175
|
+
sections.push(`## Original user request (the turn under review)\n${cap(input.originalRequest.trim(), ORIGINAL_REQUEST_CAP)}`);
|
|
176
|
+
}
|
|
136
177
|
sections.push(`## Recent activity (GG Coder and user)\n${renderedRecent.length > 0 ? renderedRecent.join("\n\n") : "(no conversation yet)"}`);
|
|
137
178
|
sections.push(`## They just asked you\n${input.question.trim()}`);
|
|
138
179
|
return sections.join("\n\n");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ken-context.js","sourceRoot":"","sources":["../../src/core/ken-context.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ken-context.js","sourceRoot":"","sources":["../../src/core/ken-context.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { describe, it, expect } from "vitest";
|
|
2
2
|
import os from "node:os";
|
|
3
|
-
import { buildKenDigest, buildKenAutopilotContext, AUTOPILOT_REVIEW_INSTRUCTION, KEN_RECENT_MESSAGE_LIMIT, } from "./ken-context.js";
|
|
3
|
+
import { buildKenDigest, buildKenAutopilotContext, AUTOPILOT_REVIEW_INSTRUCTION, KEN_RECENT_MESSAGE_LIMIT, INJECTED_PROMPT_LABEL, } from "./ken-context.js";
|
|
4
|
+
import { USER_INSTRUCTIONS_HEADER } from "./autopilot-gate.js";
|
|
5
|
+
import { PROMPT_COMMANDS } from "./prompt-commands.js";
|
|
4
6
|
import { createTools } from "../tools/index.js";
|
|
5
7
|
// Mirror the sidecar's Ken allow-list so the filter test tracks the real set.
|
|
6
8
|
const KEN_ALLOWED_TOOLS = [
|
|
@@ -122,6 +124,14 @@ describe("buildKenDigest", () => {
|
|
|
122
124
|
expect(digest).toContain("ALL_CLEAR");
|
|
123
125
|
expect(digest).toContain("HUMAN");
|
|
124
126
|
});
|
|
127
|
+
it("autopilot review instruction covers the ask-the-user and injected-prompt rules", () => {
|
|
128
|
+
// GG Coder ending with a question/options must resolve to HUMAN, and Ken
|
|
129
|
+
// must be told injected lines are his own — these are leak regressions.
|
|
130
|
+
expect(AUTOPILOT_REVIEW_INSTRUCTION).toContain("asking the user a question");
|
|
131
|
+
expect(AUTOPILOT_REVIEW_INSTRUCTION).toContain("HUMAN");
|
|
132
|
+
expect(AUTOPILOT_REVIEW_INSTRUCTION).toContain("Original user request");
|
|
133
|
+
expect(AUTOPILOT_REVIEW_INSTRUCTION).toContain("Ken autopilot (injected)");
|
|
134
|
+
});
|
|
125
135
|
it("uses the latest compaction summary as the story-so-far base", () => {
|
|
126
136
|
const messages = [
|
|
127
137
|
{ role: "user", content: "old turn that should be summarized away" },
|
|
@@ -137,4 +147,115 @@ describe("buildKenDigest", () => {
|
|
|
137
147
|
expect(digest).toContain("Added the header.");
|
|
138
148
|
});
|
|
139
149
|
});
|
|
150
|
+
describe("buildKenDigest — original request pinning", () => {
|
|
151
|
+
const base = {
|
|
152
|
+
question: "review it",
|
|
153
|
+
projectContext: [],
|
|
154
|
+
cwd: "/tmp/proj",
|
|
155
|
+
gitBranch: "main",
|
|
156
|
+
platform: "darwin",
|
|
157
|
+
};
|
|
158
|
+
it("pins the original request in its own section", () => {
|
|
159
|
+
const digest = buildKenDigest({
|
|
160
|
+
...base,
|
|
161
|
+
messages: [],
|
|
162
|
+
originalRequest: "build a login form with validation",
|
|
163
|
+
});
|
|
164
|
+
expect(digest).toContain("## Original user request (the turn under review)");
|
|
165
|
+
expect(digest).toContain("build a login form with validation");
|
|
166
|
+
});
|
|
167
|
+
it("keeps the original request even when it scrolled out of recent activity", () => {
|
|
168
|
+
// The drift bug: multi-round cycles push the real ask out of the rolling
|
|
169
|
+
// 20-message window. The pinned section must survive that.
|
|
170
|
+
const messages = [{ role: "user", content: "THE-REAL-ASK: add dark mode" }];
|
|
171
|
+
for (let i = 0; i < KEN_RECENT_MESSAGE_LIMIT + 5; i++) {
|
|
172
|
+
messages.push({ role: "assistant", content: `working… step ${i}` });
|
|
173
|
+
}
|
|
174
|
+
const digest = buildKenDigest({
|
|
175
|
+
...base,
|
|
176
|
+
messages,
|
|
177
|
+
originalRequest: "THE-REAL-ASK: add dark mode",
|
|
178
|
+
});
|
|
179
|
+
// Scrolled out of recent activity…
|
|
180
|
+
expect(digest.split("## Original user request")[0]).not.toContain("THE-REAL-ASK");
|
|
181
|
+
// …but pinned in its own section.
|
|
182
|
+
expect(digest.split("## Original user request")[1]).toContain("THE-REAL-ASK: add dark mode");
|
|
183
|
+
});
|
|
184
|
+
it("gives the pinned request far more room than a recent-activity line", () => {
|
|
185
|
+
// Recent-activity lines truncate at 1500 chars; the ask under review must
|
|
186
|
+
// not be judged against a mid-sentence cut, so its cap is 4000.
|
|
187
|
+
const longAsk = "requirement " + "x".repeat(3000);
|
|
188
|
+
const digest = buildKenDigest({ ...base, messages: [], originalRequest: longAsk });
|
|
189
|
+
const pinned = digest.split("## Original user request")[1];
|
|
190
|
+
expect(pinned).toContain("x".repeat(3000));
|
|
191
|
+
});
|
|
192
|
+
it("omits the section when there is no original request (chat Ken)", () => {
|
|
193
|
+
const digest = buildKenDigest({ ...base, messages: [] });
|
|
194
|
+
expect(digest).not.toContain("## Original user request");
|
|
195
|
+
});
|
|
196
|
+
});
|
|
197
|
+
describe("buildKenDigest — injected-prompt labeling", () => {
|
|
198
|
+
const base = {
|
|
199
|
+
question: "review it",
|
|
200
|
+
projectContext: [],
|
|
201
|
+
cwd: "/tmp/proj",
|
|
202
|
+
gitBranch: null,
|
|
203
|
+
platform: "darwin",
|
|
204
|
+
};
|
|
205
|
+
it("labels autopilot-injected prompts as Ken's, never **User:**", () => {
|
|
206
|
+
const injected = "Fix the failing auth test and prove it by running it.";
|
|
207
|
+
const messages = [
|
|
208
|
+
{ role: "user", content: "add auth" },
|
|
209
|
+
{ role: "assistant", content: "Added auth." },
|
|
210
|
+
{ role: "user", content: injected },
|
|
211
|
+
{ role: "assistant", content: "Fixed the test." },
|
|
212
|
+
];
|
|
213
|
+
const digest = buildKenDigest({ ...base, messages, injectedPrompts: [injected] });
|
|
214
|
+
expect(digest).toContain(`${INJECTED_PROMPT_LABEL} ${injected}`);
|
|
215
|
+
expect(digest).not.toContain(`**User:** ${injected}`);
|
|
216
|
+
// Real user asks keep the normal label.
|
|
217
|
+
expect(digest).toContain("**User:** add auth");
|
|
218
|
+
});
|
|
219
|
+
it("matches injected prompts through whitespace drift", () => {
|
|
220
|
+
const injected = "Fix the failing test.";
|
|
221
|
+
const messages = [{ role: "user", content: ` ${injected} ` }];
|
|
222
|
+
const digest = buildKenDigest({ ...base, messages, injectedPrompts: [injected] });
|
|
223
|
+
expect(digest).toContain(INJECTED_PROMPT_LABEL);
|
|
224
|
+
});
|
|
225
|
+
});
|
|
226
|
+
describe("buildKenDigest — workflow-command labeling", () => {
|
|
227
|
+
const base = {
|
|
228
|
+
question: "review it",
|
|
229
|
+
projectContext: [],
|
|
230
|
+
cwd: "/tmp/proj",
|
|
231
|
+
gitBranch: null,
|
|
232
|
+
platform: "darwin",
|
|
233
|
+
};
|
|
234
|
+
const compare = PROMPT_COMMANDS.find((c) => c.name === "compare");
|
|
235
|
+
it("renders an expanded template as a short command note, not a user ask", () => {
|
|
236
|
+
// AgentSession.prompt() stores the EXPANDED template as a plain user
|
|
237
|
+
// message; the digest must not present 400 template lines as **User:**.
|
|
238
|
+
const messages = [
|
|
239
|
+
{ role: "user", content: compare.prompt },
|
|
240
|
+
{ role: "assistant", content: "Compared against 12 repos, all aligned." },
|
|
241
|
+
];
|
|
242
|
+
const digest = buildKenDigest({ ...base, messages, workflowCommands: PROMPT_COMMANDS });
|
|
243
|
+
expect(digest).toContain("**User:** [ran workflow command /compare]");
|
|
244
|
+
// The template body itself never leaks into the digest.
|
|
245
|
+
expect(digest).not.toContain("Compare the code you just created or modified");
|
|
246
|
+
});
|
|
247
|
+
it("keeps the user's own args from an expanded command", () => {
|
|
248
|
+
const messages = [
|
|
249
|
+
{ role: "user", content: `${compare.prompt}${USER_INSTRUCTIONS_HEADER}only src/auth.ts` },
|
|
250
|
+
];
|
|
251
|
+
const digest = buildKenDigest({ ...base, messages, workflowCommands: PROMPT_COMMANDS });
|
|
252
|
+
expect(digest).toContain("[ran workflow command /compare]");
|
|
253
|
+
expect(digest).toContain("only src/auth.ts");
|
|
254
|
+
});
|
|
255
|
+
it("leaves ordinary user text untouched when specs are provided", () => {
|
|
256
|
+
const messages = [{ role: "user", content: "please compare my two branches" }];
|
|
257
|
+
const digest = buildKenDigest({ ...base, messages, workflowCommands: PROMPT_COMMANDS });
|
|
258
|
+
expect(digest).toContain("**User:** please compare my two branches");
|
|
259
|
+
});
|
|
260
|
+
});
|
|
140
261
|
//# sourceMappingURL=ken-context.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ken-context.test.js","sourceRoot":"","sources":["../../src/core/ken-context.test.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ken-context.test.js","sourceRoot":"","sources":["../../src/core/ken-context.test.ts"],"names":[],"mappings":"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"}
|