@kenkaiiii/ggcoder 5.74.3 → 5.75.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.
Files changed (215) hide show
  1. package/README.md +1 -1
  2. package/assets/skills/bulletproof/SKILL.md +1 -1
  3. package/assets/skills/clarify/SKILL.md +1 -1
  4. package/assets/skills/code-review/SKILL.md +1 -1
  5. package/assets/skills/compliance-guard/SKILL.md +1 -1
  6. package/assets/skills/durable/SKILL.md +1 -1
  7. package/assets/skills/evidence-led-ui/SKILL.md +1 -1
  8. package/assets/skills/lean/SKILL.md +1 -1
  9. package/assets/skills/refactoring/SKILL.md +1 -1
  10. package/assets/skills/root-cause/SKILL.md +1 -1
  11. package/assets/skills/shared-language/SKILL.md +1 -1
  12. package/assets/skills/tdd/SKILL.md +1 -1
  13. package/dist/app-sidecar/app-settings.d.ts +65 -0
  14. package/dist/app-sidecar/app-settings.js +147 -0
  15. package/dist/app-sidecar/app-settings.js.map +1 -0
  16. package/dist/app-sidecar/attachments.d.ts +11 -0
  17. package/dist/app-sidecar/attachments.js +47 -0
  18. package/dist/app-sidecar/attachments.js.map +1 -0
  19. package/dist/app-sidecar/auth-routes.d.ts +3 -0
  20. package/dist/app-sidecar/auth-routes.js +290 -0
  21. package/dist/app-sidecar/auth-routes.js.map +1 -0
  22. package/dist/app-sidecar/autopilot-runner.d.ts +61 -0
  23. package/dist/app-sidecar/autopilot-runner.js +367 -0
  24. package/dist/app-sidecar/autopilot-runner.js.map +1 -0
  25. package/dist/app-sidecar/file-search.d.ts +15 -0
  26. package/dist/app-sidecar/file-search.js +103 -0
  27. package/dist/app-sidecar/file-search.js.map +1 -0
  28. package/dist/app-sidecar/hf-pull-manager.d.ts +20 -0
  29. package/dist/app-sidecar/hf-pull-manager.js +224 -0
  30. package/dist/app-sidecar/hf-pull-manager.js.map +1 -0
  31. package/dist/app-sidecar/history-routes.d.ts +3 -0
  32. package/dist/app-sidecar/history-routes.js +375 -0
  33. package/dist/app-sidecar/history-routes.js.map +1 -0
  34. package/dist/app-sidecar/history.d.ts +67 -0
  35. package/dist/app-sidecar/history.js +23 -0
  36. package/dist/app-sidecar/history.js.map +1 -0
  37. package/dist/app-sidecar/http.d.ts +5 -0
  38. package/dist/app-sidecar/http.js +27 -0
  39. package/dist/app-sidecar/http.js.map +1 -0
  40. package/dist/app-sidecar/integration-routes.d.ts +3 -0
  41. package/dist/app-sidecar/integration-routes.js +286 -0
  42. package/dist/app-sidecar/integration-routes.js.map +1 -0
  43. package/dist/app-sidecar/json-mode.d.ts +10 -0
  44. package/dist/app-sidecar/json-mode.js +73 -0
  45. package/dist/app-sidecar/json-mode.js.map +1 -0
  46. package/dist/app-sidecar/keep-awake.d.ts +4 -0
  47. package/dist/app-sidecar/keep-awake.js +5 -0
  48. package/dist/app-sidecar/keep-awake.js.map +1 -0
  49. package/dist/app-sidecar/ken-context.d.ts +20 -0
  50. package/dist/app-sidecar/ken-context.js +55 -0
  51. package/dist/app-sidecar/ken-context.js.map +1 -0
  52. package/dist/app-sidecar/mcp-routes.d.ts +3 -0
  53. package/dist/app-sidecar/mcp-routes.js +185 -0
  54. package/dist/app-sidecar/mcp-routes.js.map +1 -0
  55. package/dist/app-sidecar/mcp-rows.d.ts +31 -0
  56. package/dist/app-sidecar/mcp-rows.js +77 -0
  57. package/dist/app-sidecar/mcp-rows.js.map +1 -0
  58. package/dist/app-sidecar/progress-manager.d.ts +10 -0
  59. package/dist/app-sidecar/progress-manager.js +116 -0
  60. package/dist/app-sidecar/progress-manager.js.map +1 -0
  61. package/dist/app-sidecar/prompt-routes.d.ts +3 -0
  62. package/dist/app-sidecar/prompt-routes.js +354 -0
  63. package/dist/app-sidecar/prompt-routes.js.map +1 -0
  64. package/dist/app-sidecar/repo-polls.d.ts +15 -0
  65. package/dist/app-sidecar/repo-polls.js +25 -0
  66. package/dist/app-sidecar/repo-polls.js.map +1 -0
  67. package/dist/app-sidecar/route-context.d.ts +145 -0
  68. package/dist/app-sidecar/route-context.js +2 -0
  69. package/dist/app-sidecar/route-context.js.map +1 -0
  70. package/dist/app-sidecar/run-control-routes.d.ts +3 -0
  71. package/dist/app-sidecar/run-control-routes.js +430 -0
  72. package/dist/app-sidecar/run-control-routes.js.map +1 -0
  73. package/dist/app-sidecar/session-routes.d.ts +3 -0
  74. package/dist/app-sidecar/session-routes.js +115 -0
  75. package/dist/app-sidecar/session-routes.js.map +1 -0
  76. package/dist/app-sidecar/session-types.d.ts +39 -0
  77. package/dist/app-sidecar/session-types.js +5 -0
  78. package/dist/app-sidecar/session-types.js.map +1 -0
  79. package/dist/app-sidecar/task-routes.d.ts +3 -0
  80. package/dist/app-sidecar/task-routes.js +149 -0
  81. package/dist/app-sidecar/task-routes.js.map +1 -0
  82. package/dist/app-sidecar/usage.d.ts +19 -0
  83. package/dist/app-sidecar/usage.js +153 -0
  84. package/dist/app-sidecar/usage.js.map +1 -0
  85. package/dist/app-sidecar/workspace-routes.d.ts +3 -0
  86. package/dist/app-sidecar/workspace-routes.js +244 -0
  87. package/dist/app-sidecar/workspace-routes.js.map +1 -0
  88. package/dist/app-sidecar.js +467 -3775
  89. package/dist/app-sidecar.js.map +1 -1
  90. package/dist/cli.js +2 -2
  91. package/dist/cli.js.map +1 -1
  92. package/dist/config.js +1 -1
  93. package/dist/core/acceptance-checks.js +3 -9
  94. package/dist/core/acceptance-checks.js.map +1 -1
  95. package/dist/core/agent-session/helpers.d.ts +26 -0
  96. package/dist/core/agent-session/helpers.js +47 -0
  97. package/dist/core/agent-session/helpers.js.map +1 -0
  98. package/dist/core/agent-session/mcp-tools.d.ts +68 -0
  99. package/dist/core/agent-session/mcp-tools.js +195 -0
  100. package/dist/core/agent-session/mcp-tools.js.map +1 -0
  101. package/dist/core/agent-session/run-loop-monitor.d.ts +63 -0
  102. package/dist/core/agent-session/run-loop-monitor.js +164 -0
  103. package/dist/core/agent-session/run-loop-monitor.js.map +1 -0
  104. package/dist/core/agent-session/transcript-markers.d.ts +57 -0
  105. package/dist/core/agent-session/transcript-markers.js +166 -0
  106. package/dist/core/agent-session/transcript-markers.js.map +1 -0
  107. package/dist/core/agent-session/verification-tracker.d.ts +46 -0
  108. package/dist/core/agent-session/verification-tracker.js +246 -0
  109. package/dist/core/agent-session/verification-tracker.js.map +1 -0
  110. package/dist/core/agent-session.d.ts +21 -87
  111. package/dist/core/agent-session.js +141 -712
  112. package/dist/core/agent-session.js.map +1 -1
  113. package/dist/core/auth-providers.js +3 -3
  114. package/dist/core/auth-providers.js.map +1 -1
  115. package/dist/core/bundled-agents.js +6 -6
  116. package/dist/core/bundled-agents.js.map +1 -1
  117. package/dist/core/checklist-git.d.ts +19 -0
  118. package/dist/core/checklist-git.js +54 -0
  119. package/dist/core/checklist-git.js.map +1 -0
  120. package/dist/core/checklist-items.d.ts +10 -1
  121. package/dist/core/checklist-items.js +22 -0
  122. package/dist/core/checklist-items.js.map +1 -1
  123. package/dist/core/checklist-prompt.d.ts +5 -1
  124. package/dist/core/checklist-prompt.js +16 -5
  125. package/dist/core/checklist-prompt.js.map +1 -1
  126. package/dist/core/checklist-snapshot.d.ts +5 -1
  127. package/dist/core/checklist-snapshot.js +19 -2
  128. package/dist/core/checklist-snapshot.js.map +1 -1
  129. package/dist/core/context-limits.js +1 -1
  130. package/dist/core/context-limits.js.map +1 -1
  131. package/dist/core/skills.js +6 -9
  132. package/dist/core/skills.js.map +1 -1
  133. package/dist/core/style-packs/index.js +2 -11
  134. package/dist/core/style-packs/index.js.map +1 -1
  135. package/dist/core/style-packs/packs.d.ts +3 -12
  136. package/dist/core/style-packs/packs.js +132 -173
  137. package/dist/core/style-packs/packs.js.map +1 -1
  138. package/dist/system-prompt.js +55 -78
  139. package/dist/system-prompt.js.map +1 -1
  140. package/dist/tools/ask-user.js +13 -74
  141. package/dist/tools/ask-user.js.map +1 -1
  142. package/dist/tools/bash.js +13 -78
  143. package/dist/tools/bash.js.map +1 -1
  144. package/dist/tools/checklist.d.ts +2 -10
  145. package/dist/tools/checklist.js +7 -39
  146. package/dist/tools/checklist.js.map +1 -1
  147. package/dist/tools/code-nav.js +7 -29
  148. package/dist/tools/code-nav.js.map +1 -1
  149. package/dist/tools/edit.d.ts +3 -9
  150. package/dist/tools/edit.js +92 -65
  151. package/dist/tools/edit.js.map +1 -1
  152. package/dist/tools/enter-plan.js +2 -7
  153. package/dist/tools/enter-plan.js.map +1 -1
  154. package/dist/tools/exit-plan.js +2 -3
  155. package/dist/tools/exit-plan.js.map +1 -1
  156. package/dist/tools/find.js +3 -4
  157. package/dist/tools/find.js.map +1 -1
  158. package/dist/tools/grep.js +6 -18
  159. package/dist/tools/grep.js.map +1 -1
  160. package/dist/tools/ls.js +3 -3
  161. package/dist/tools/ls.js.map +1 -1
  162. package/dist/tools/prompt-hints.js +34 -47
  163. package/dist/tools/prompt-hints.js.map +1 -1
  164. package/dist/tools/read.js +8 -20
  165. package/dist/tools/read.js.map +1 -1
  166. package/dist/tools/search-code.js +4 -12
  167. package/dist/tools/search-code.js.map +1 -1
  168. package/dist/tools/skill.js +13 -7
  169. package/dist/tools/skill.js.map +1 -1
  170. package/dist/tools/subagent-control.js +7 -22
  171. package/dist/tools/subagent-control.js.map +1 -1
  172. package/dist/tools/subagent.js +4 -7
  173. package/dist/tools/subagent.js.map +1 -1
  174. package/dist/tools/task-output.js +4 -15
  175. package/dist/tools/task-output.js.map +1 -1
  176. package/dist/tools/task-send.js +5 -17
  177. package/dist/tools/task-send.js.map +1 -1
  178. package/dist/tools/task-stop.js +2 -2
  179. package/dist/tools/task-stop.js.map +1 -1
  180. package/dist/tools/tool-search.js +2 -7
  181. package/dist/tools/tool-search.js.map +1 -1
  182. package/dist/tools/tool-tiers.d.ts +17 -4
  183. package/dist/tools/tool-tiers.js +38 -15
  184. package/dist/tools/tool-tiers.js.map +1 -1
  185. package/dist/tools/web-fetch.js +7 -33
  186. package/dist/tools/web-fetch.js.map +1 -1
  187. package/dist/tools/write.js +3 -4
  188. package/dist/tools/write.js.map +1 -1
  189. package/dist/ui/components/Footer.js +1 -2
  190. package/dist/ui/components/Footer.js.map +1 -1
  191. package/dist/utils/shared-poll.d.ts +37 -0
  192. package/dist/utils/shared-poll.js +104 -0
  193. package/dist/utils/shared-poll.js.map +1 -0
  194. package/package.json +7 -4
  195. package/dist/core/api-benchmark.d.ts +0 -63
  196. package/dist/core/api-benchmark.js +0 -381
  197. package/dist/core/api-benchmark.js.map +0 -1
  198. package/dist/core/bash-spawn-benchmark.d.ts +0 -1
  199. package/dist/core/bash-spawn-benchmark.js +0 -139
  200. package/dist/core/bash-spawn-benchmark.js.map +0 -1
  201. package/dist/core/cache-warm-benchmark.d.ts +0 -21
  202. package/dist/core/cache-warm-benchmark.js +0 -170
  203. package/dist/core/cache-warm-benchmark.js.map +0 -1
  204. package/dist/core/fast-apply-benchmark.d.ts +0 -25
  205. package/dist/core/fast-apply-benchmark.js +0 -284
  206. package/dist/core/fast-apply-benchmark.js.map +0 -1
  207. package/dist/core/hashline-edit-benchmark.d.ts +0 -88
  208. package/dist/core/hashline-edit-benchmark.js +0 -518
  209. package/dist/core/hashline-edit-benchmark.js.map +0 -1
  210. package/dist/core/semantic-search-benchmark.d.ts +0 -36
  211. package/dist/core/semantic-search-benchmark.js +0 -211
  212. package/dist/core/semantic-search-benchmark.js.map +0 -1
  213. package/dist/core/speed-benchmark.d.ts +0 -132
  214. package/dist/core/speed-benchmark.js +0 -410
  215. package/dist/core/speed-benchmark.js.map +0 -1
@@ -1,170 +0,0 @@
1
- /**
2
- * Prompt-cache warming micro-benchmark — isolates the cache effect.
3
- *
4
- * The existing api-benchmark grows the conversation each turn and uses a tiny
5
- * (~250 token) system prompt, which is BELOW Anthropic's minimum cacheable
6
- * prefix (1024 tok Sonnet/Opus, 2048 Haiku) — so caching never engages and the
7
- * A/B is dominated by turn-to-turn throughput variance.
8
- *
9
- * This test uses a large, FIXED prefix (well above the min) and a tiny variable
10
- * suffix, then measures, per arm:
11
- * COLD — fresh cache key, first hit (cache WRITE, no read).
12
- * WARM — prewarm the prefix, then measure the next call's cache_read + TTFT.
13
- *
14
- * It reports cache_read tokens and TTFT directly, so the cache effect is visible
15
- * regardless of throughput noise.
16
- *
17
- * Usage: npx tsx src/core/cache-warm-benchmark.ts
18
- * Env: GG_CW_PROVIDER (default anthropic), GG_CW_MODEL (default claude-haiku-4-5-20251001),
19
- * GG_CW_REPS (default 4)
20
- */
21
- import { stream } from "@kenkaiiii/gg-ai";
22
- import { AuthStorage } from "./auth-storage.js";
23
- /** Build a large, realistic coding-agent system prompt (~well above 2048 tok). */
24
- function bigPrefix() {
25
- const toolDoc = (name, desc) => `### ${name}\n${desc}\nParameters are validated with a Zod schema and converted to JSON Schema at the provider boundary. ` +
26
- `Errors are returned as structured tool results so the agent can self-correct in the same turn. `;
27
- const tools = [
28
- toolDoc("read", "Read a file's contents with cat -n style numbered lines, truncated to 2000 lines or 50KB."),
29
- toolDoc("write", "Write content to a file, creating parent directories. Existing files must be read first."),
30
- toolDoc("edit", "Replace text via search/replace blocks applied sequentially with a fuzzy fallback ladder."),
31
- toolDoc("bash", "Execute a shell command in a non-interactive bash shell with combined stdout/stderr."),
32
- toolDoc("grep", "Search file contents using regex, returning filepath:line:content matches."),
33
- toolDoc("find", "Find files matching a glob pattern, respecting .gitignore."),
34
- toolDoc("ls", "List directory contents with file types and sizes."),
35
- toolDoc("web_fetch", "Fetch and read web page content as Markdown, extracting main content."),
36
- toolDoc("subagent", "Spawn an isolated sub-agent with its own context window for a focused task."),
37
- toolDoc("task_output", "Read new output from a background process by id."),
38
- ];
39
- // Repeat the tool block several times so the prefix clears Anthropic's
40
- // minimum cacheable size (1024 tok Sonnet/Opus, 2048 Haiku) with headroom.
41
- const bulkTools = [];
42
- for (let r = 0; r < 22; r++)
43
- bulkTools.push(...tools, `<!-- tool block repetition ${r} for prefix sizing -->`);
44
- return [
45
- "You are GG Coder — a coding agent that works directly in the user's codebase.",
46
- "You explore, understand, change, and verify code end-to-end.",
47
- "",
48
- "## How to Talk",
49
- "Lead with the outcome. One idea per line. Bottom line first. No preamble or recap.",
50
- "Stay silent between tool calls unless you hit a decision, tradeoff, or question.",
51
- "",
52
- "## How to Work",
53
- "Read before edit/write; re-read after formatters, codegen, or any disk mutator.",
54
- "Match neighbouring code style. Keep edits small; plan multi-file work first.",
55
- "Choose targeted verification appropriate to the change; read and fix failures.",
56
- "Do not assume APIs, CLI flags, config schema, or error wording — verify against source.",
57
- "",
58
- "## Tools",
59
- ...bulkTools,
60
- "",
61
- "## Code Quality",
62
- "Intent-revealing names; reuse existing deps. Types first; handle I/O, input, and external API errors.",
63
- "No dead or commented-out code, placeholders, or unasked refactors.",
64
- "",
65
- "## Environment",
66
- "Working directory: /home/user/project. Platform: darwin.",
67
- ].join("\n");
68
- }
69
- async function call(cfg, system, user, promptCacheKey, cacheRetention) {
70
- const messages = [
71
- { role: "system", content: system },
72
- { role: "user", content: user },
73
- ];
74
- const start = Date.now();
75
- let ttftMs = 0;
76
- let first = true;
77
- const result = stream({
78
- provider: cfg.provider,
79
- model: cfg.model,
80
- messages,
81
- maxTokens: 16,
82
- apiKey: cfg.apiKey,
83
- baseUrl: cfg.baseUrl,
84
- accountId: cfg.accountId,
85
- promptCacheKey,
86
- cacheRetention,
87
- });
88
- for await (const event of result) {
89
- if (first && (event.type === "text_delta" || event.type === "thinking_delta")) {
90
- ttftMs = Date.now() - start;
91
- first = false;
92
- }
93
- }
94
- const response = await result.response;
95
- return {
96
- ttftMs: ttftMs || Date.now() - start,
97
- wallMs: Date.now() - start,
98
- inputTokens: response.usage.inputTokens,
99
- cacheRead: response.usage.cacheRead ?? 0,
100
- cacheWrite: response.usage.cacheWrite ?? 0,
101
- outputTokens: response.usage.outputTokens,
102
- };
103
- }
104
- function sleep(ms) {
105
- return new Promise((r) => setTimeout(r, ms));
106
- }
107
- async function main() {
108
- const provider = process.env.GG_CW_PROVIDER ?? "anthropic";
109
- const model = process.env.GG_CW_MODEL ?? "claude-haiku-4-5-20251001";
110
- const reps = parseInt(process.env.GG_CW_REPS ?? "4", 10);
111
- const auth = new AuthStorage();
112
- await auth.load();
113
- const c = await auth.resolveCredentials(provider);
114
- const cfg = {
115
- provider,
116
- model,
117
- apiKey: c.accessToken,
118
- baseUrl: c.baseUrl,
119
- accountId: c.accountId,
120
- };
121
- const system = bigPrefix();
122
- // Rough token size of the prefix (chars/3.3) for context.
123
- console.log(`\n🔥 Cache-warm micro-benchmark: ${provider}/${model}`);
124
- console.log(` Prefix ~${Math.round(system.length / 3.3)} tokens, ${reps} reps per arm\n`);
125
- // ── COLD arm: every rep uses a UNIQUE cache key → never reads cache ──
126
- console.log("▶ COLD (no warming — fresh cache key each call):");
127
- // Each cold rep gets UNIQUE prefix content (Anthropic caches by content, not
128
- // by key) so every call is a true cache miss — otherwise rep 2+ would read
129
- // rep 1's cache and pollute the cold baseline.
130
- const cold = [];
131
- for (let i = 0; i < reps; i++) {
132
- const uniqueSystem = `<!-- cold-sample-${Date.now()}-${i} -->\n${system}`;
133
- const m = await call(cfg, uniqueSystem, `Question ${i}: name one tool.`, `cold-${Date.now()}-${i}`, "short");
134
- cold.push(m);
135
- console.log(` rep ${i + 1}: TTFT ${m.ttftMs}ms | in ${m.inputTokens} | cacheRead ${m.cacheRead} | cacheWrite ${m.cacheWrite}`);
136
- await sleep(1500);
137
- }
138
- await sleep(3000);
139
- // ── WARM arm: prewarm a SHARED key, then measure subsequent calls (cache reads) ──
140
- console.log("\n▶ WARM (prewarm shared prefix, then measure cache reads):");
141
- const warmKey = `warm-${Date.now()}`;
142
- // Prewarm: a throwaway call that writes the cache.
143
- const pw = await call(cfg, system, "warm.", warmKey, "long");
144
- console.log(` prewarm: cacheWrite ${pw.cacheWrite} (cache primed)`);
145
- await sleep(1500);
146
- const warm = [];
147
- for (let i = 0; i < reps; i++) {
148
- const m = await call(cfg, system, `Question ${i}: name one tool.`, warmKey, "long");
149
- warm.push(m);
150
- console.log(` rep ${i + 1}: TTFT ${m.ttftMs}ms | in ${m.inputTokens} | cacheRead ${m.cacheRead} | cacheWrite ${m.cacheWrite}`);
151
- await sleep(1500);
152
- }
153
- const avg = (xs, f) => xs.reduce((s, m) => s + f(m), 0) / xs.length;
154
- const coldTtft = avg(cold, (m) => m.ttftMs);
155
- const warmTtft = avg(warm, (m) => m.ttftMs);
156
- const coldRead = avg(cold, (m) => m.cacheRead);
157
- const warmRead = avg(warm, (m) => m.cacheRead);
158
- console.log("\n══════════════════════ RESULTS ══════════════════════");
159
- console.log(`Avg cacheRead tokens : cold ${coldRead.toFixed(0)} → warm ${warmRead.toFixed(0)}`);
160
- console.log(`Avg TTFT : cold ${coldTtft.toFixed(0)}ms → warm ${warmTtft.toFixed(0)}ms ` +
161
- `(${coldTtft > warmTtft ? "-" : "+"}${Math.abs(((coldTtft - warmTtft) / coldTtft) * 100).toFixed(0)}%)`);
162
- const warmHitRate = warm.filter((m) => m.cacheRead > 0).length / warm.length;
163
- console.log(`Warm cache hit rate : ${(warmHitRate * 100).toFixed(0)}%`);
164
- console.log(`Verdict: ${warmRead > 0 ? "caching ENGAGES when prefix exceeds the min — warming converts cold writes to reads" : "caching did NOT engage (prefix below provider minimum, or OAuth path strips cache_control)"}`);
165
- }
166
- main().catch((err) => {
167
- console.error("Benchmark failed:", err);
168
- process.exit(1);
169
- });
170
- //# sourceMappingURL=cache-warm-benchmark.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"cache-warm-benchmark.js","sourceRoot":"","sources":["../../src/core/cache-warm-benchmark.ts"],"names":[],"mappings":"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"}
@@ -1,25 +0,0 @@
1
- /**
2
- * Fast-apply vs current-edit benchmark — real-API measurement.
3
- *
4
- * Two strategies for the same edit task, measured end-to-end against live models:
5
- *
6
- * BASELINE (what ggcoder does today): the frontier model emits full
7
- * search/replace edit blocks (old_text + new_text, verbatim context). Our
8
- * edit tool then applies them LOCALLY and instantly (no apply model).
9
- *
10
- * FAST-APPLY (the proposed feature): the frontier model emits a terse "lazy"
11
- * edit using `// ... existing code ...` markers (far fewer output tokens), and
12
- * a cheap/fast "apply" model merges that lazy edit into the full file —
13
- * regenerating the whole file as output.
14
- *
15
- * We measure, per task: frontier output tokens + time, apply-model output tokens
16
- * + time, total wall-clock, and an anchor-based correctness check.
17
- *
18
- * Usage:
19
- * npx tsx src/core/fast-apply-benchmark.ts
20
- *
21
- * Env overrides:
22
- * GG_FA_FRONTIER_PROVIDER / GG_FA_FRONTIER_MODEL (default openai / gpt-6.1-sol)
23
- * GG_FA_APPLY_PROVIDER / GG_FA_APPLY_MODEL (default gemini / gemini-3.1-flash-lite)
24
- */
25
- export {};
@@ -1,284 +0,0 @@
1
- /**
2
- * Fast-apply vs current-edit benchmark — real-API measurement.
3
- *
4
- * Two strategies for the same edit task, measured end-to-end against live models:
5
- *
6
- * BASELINE (what ggcoder does today): the frontier model emits full
7
- * search/replace edit blocks (old_text + new_text, verbatim context). Our
8
- * edit tool then applies them LOCALLY and instantly (no apply model).
9
- *
10
- * FAST-APPLY (the proposed feature): the frontier model emits a terse "lazy"
11
- * edit using `// ... existing code ...` markers (far fewer output tokens), and
12
- * a cheap/fast "apply" model merges that lazy edit into the full file —
13
- * regenerating the whole file as output.
14
- *
15
- * We measure, per task: frontier output tokens + time, apply-model output tokens
16
- * + time, total wall-clock, and an anchor-based correctness check.
17
- *
18
- * Usage:
19
- * npx tsx src/core/fast-apply-benchmark.ts
20
- *
21
- * Env overrides:
22
- * GG_FA_FRONTIER_PROVIDER / GG_FA_FRONTIER_MODEL (default openai / gpt-6.1-sol)
23
- * GG_FA_APPLY_PROVIDER / GG_FA_APPLY_MODEL (default gemini / gemini-3.1-flash-lite)
24
- */
25
- import { stream } from "@kenkaiiii/gg-ai";
26
- import { AuthStorage } from "./auth-storage.js";
27
- function genFile(lines) {
28
- // Build a realistic-ish TS module with many small functions so the edit
29
- // target sits in the middle and most of the file is "untouched context".
30
- const head = [
31
- `import { EventEmitter } from "node:events";`,
32
- `import { performance } from "node:perf_hooks";`,
33
- ``,
34
- `/** Auto-generated module with ${lines} lines for benchmarking. */`,
35
- `export interface Config {`,
36
- ` retries: number;`,
37
- ` timeoutMs: number;`,
38
- ` label: string;`,
39
- `}`,
40
- ``,
41
- `const DEFAULT_TIMEOUT = 3000;`,
42
- ``,
43
- ];
44
- const body = [];
45
- let n = 0;
46
- while (head.length + body.length < lines - 12) {
47
- body.push(`export function task${n}(x: number): number {`, ` // step ${n}`, ` const y = x * ${n + 1} + DEFAULT_TIMEOUT;`, ` return y - ${n};`, `}`, ``);
48
- n++;
49
- }
50
- const tail = [
51
- `export function computeTimeout(cfg: Config): number {`,
52
- ` return cfg.timeoutMs > 0 ? cfg.timeoutMs : DEFAULT_TIMEOUT;`,
53
- `}`,
54
- ``,
55
- `export const SENTINEL_TAIL = "anchor_${lines}_end";`,
56
- ``,
57
- ];
58
- return [...head, ...body, ...tail].join("\n");
59
- }
60
- function buildTasks() {
61
- const sizes = [
62
- { name: "small", lines: 40 },
63
- { name: "medium", lines: 160 },
64
- { name: "large", lines: 420 },
65
- ];
66
- return sizes.map((s) => ({
67
- name: s.name,
68
- approxLines: s.lines,
69
- file: genFile(s.lines),
70
- instruction: "Change `computeTimeout` so that when `cfg.retries` is greater than 0 it returns " +
71
- "`cfg.timeoutMs * cfg.retries` (capped at 30000), otherwise it keeps the existing behaviour. " +
72
- "Also add a one-line JSDoc comment above the function describing it.",
73
- mustContain: ["cfg.timeoutMs * cfg.retries", "30000", "computeTimeout"],
74
- mustPreserve: ["DEFAULT_TIMEOUT = 3000", `SENTINEL_TAIL = "anchor_${s.lines}_end"`, "task0"],
75
- }));
76
- }
77
- // ── Prompts ──────────────────────────────────────────────────
78
- function baselinePrompt(file, instruction) {
79
- return [
80
- {
81
- role: "system",
82
- content: "You are a coding agent's edit engine. Output ONLY search/replace edit blocks " +
83
- "in this exact format, nothing else:\n" +
84
- "<<<<<<< SEARCH\n(exact text from the file)\n=======\n(replacement text)\n>>>>>>> REPLACE\n" +
85
- "The SEARCH text must be copied verbatim from the file including surrounding context " +
86
- "so it matches uniquely. Do not output explanations.",
87
- },
88
- {
89
- role: "user",
90
- content: `FILE:\n\`\`\`ts\n${file}\n\`\`\`\n\nEDIT INSTRUCTION: ${instruction}`,
91
- },
92
- ];
93
- }
94
- function lazyEditPrompt(file, instruction) {
95
- return [
96
- {
97
- role: "system",
98
- content: "You are a coding agent. Output ONLY a concise 'lazy' edit snippet that shows the " +
99
- "change, using `// ... existing code ...` to elide all unchanged regions. " +
100
- "Show just enough surrounding context to locate the change unambiguously. " +
101
- "Do not reproduce the whole file. Do not explain.",
102
- },
103
- {
104
- role: "user",
105
- content: `FILE:\n\`\`\`ts\n${file}\n\`\`\`\n\nEDIT INSTRUCTION: ${instruction}`,
106
- },
107
- ];
108
- }
109
- function applyPrompt(file, lazyEdit) {
110
- return [
111
- {
112
- role: "system",
113
- content: "You merge a lazy edit into a source file. Given the ORIGINAL file and an EDIT " +
114
- "snippet that uses `// ... existing code ...` markers, output the COMPLETE final file " +
115
- "with the edit applied. Output ONLY the raw file contents — no markdown fences, no commentary.",
116
- },
117
- {
118
- role: "user",
119
- content: `ORIGINAL FILE:\n${file}\n\nEDIT:\n${lazyEdit}`,
120
- },
121
- ];
122
- }
123
- function sleep(ms) {
124
- return new Promise((r) => setTimeout(r, ms));
125
- }
126
- async function call(provider, model, apiKey, baseUrl, accountId, messages, maxTokens) {
127
- // Retry transient provider errors (429/500) with exponential backoff so a
128
- // flaky cheap model doesn't abort the whole benchmark.
129
- let lastErr;
130
- for (let attempt = 0; attempt < 4; attempt++) {
131
- try {
132
- return await callOnce(provider, model, apiKey, baseUrl, accountId, messages, maxTokens);
133
- }
134
- catch (err) {
135
- lastErr = err;
136
- await sleep(2000 * (attempt + 1));
137
- }
138
- }
139
- throw lastErr;
140
- }
141
- async function callOnce(provider, model, apiKey, baseUrl, accountId, messages, maxTokens) {
142
- const start = Date.now();
143
- let ttftMs = 0;
144
- let first = true;
145
- let text = "";
146
- const result = stream({
147
- provider: provider,
148
- model,
149
- messages,
150
- maxTokens,
151
- apiKey,
152
- baseUrl,
153
- accountId,
154
- });
155
- for await (const event of result) {
156
- if (first && (event.type === "text_delta" || event.type === "thinking_delta")) {
157
- ttftMs = Date.now() - start;
158
- first = false;
159
- }
160
- if (event.type === "text_delta")
161
- text += event.text;
162
- }
163
- const response = await result.response;
164
- const wallMs = Date.now() - start;
165
- const content = response.message.content;
166
- const finalText = typeof content === "string"
167
- ? content
168
- : content
169
- .filter((p) => p.type === "text")
170
- .map((p) => p.text ?? "")
171
- .join("");
172
- return {
173
- text: finalText || text,
174
- outputTokens: response.usage.outputTokens,
175
- inputTokens: response.usage.inputTokens,
176
- cacheRead: response.usage.cacheRead ?? 0,
177
- ttftMs,
178
- wallMs,
179
- };
180
- }
181
- // ── Correctness ─────────────────────────────────────────────
182
- function checkAnchors(finalFile, task) {
183
- for (const s of task.mustContain)
184
- if (!finalFile.includes(s))
185
- return false;
186
- for (const s of task.mustPreserve)
187
- if (!finalFile.includes(s))
188
- return false;
189
- return true;
190
- }
191
- async function main() {
192
- const frontierProvider = process.env.GG_FA_FRONTIER_PROVIDER ?? "openai";
193
- const frontierModel = process.env.GG_FA_FRONTIER_MODEL ?? "gpt-6.1-sol";
194
- const applyProvider = process.env.GG_FA_APPLY_PROVIDER ?? "gemini";
195
- const applyModel = process.env.GG_FA_APPLY_MODEL ?? "gemini-3.1-flash-lite";
196
- const auth = new AuthStorage();
197
- await auth.load();
198
- const resolve = async (p) => {
199
- const c = await auth.resolveCredentials(p);
200
- return { apiKey: c.accessToken, baseUrl: c.baseUrl, accountId: c.accountId };
201
- };
202
- const fc = await resolve(frontierProvider);
203
- const ac = await resolve(applyProvider);
204
- console.log(`\n⚡ Fast-apply benchmark`);
205
- console.log(` Frontier: ${frontierProvider}/${frontierModel}`);
206
- console.log(` Apply: ${applyProvider}/${applyModel}\n`);
207
- const tasks = buildTasks();
208
- const rows = [];
209
- for (const task of tasks) {
210
- process.stdout.write(`▶ ${task.name} (${task.approxLines} lines)\n`);
211
- await sleep(2500); // space out calls to avoid cheap-model rate limits
212
- // ── BASELINE: frontier emits full search/replace blocks (local apply = ~0ms) ──
213
- const baseStart = Date.now();
214
- const baseFrontier = await call(frontierProvider, frontierModel, fc.apiKey, fc.baseUrl, fc.accountId, baselinePrompt(task.file, task.instruction), 4096);
215
- // Local apply is deterministic & instant; correctness = did the model produce
216
- // a SEARCH block whose target text actually exists in the file?
217
- const searchBlocks = [
218
- ...baseFrontier.text.matchAll(/<<<<<<< SEARCH\n([\s\S]*?)\n=======/g),
219
- ].map((m) => m[1]);
220
- const replaceBlocks = [
221
- ...baseFrontier.text.matchAll(/=======\n([\s\S]*?)\n>>>>>>> REPLACE/g),
222
- ].map((m) => m[1]);
223
- let baseFile = task.file;
224
- let baseApplied = searchBlocks.length > 0;
225
- for (let i = 0; i < searchBlocks.length; i++) {
226
- if (baseFile.includes(searchBlocks[i])) {
227
- baseFile = baseFile.replace(searchBlocks[i], replaceBlocks[i] ?? "");
228
- }
229
- else {
230
- baseApplied = false; // search text didn't match verbatim → would fail/retry
231
- }
232
- }
233
- const baseTotalMs = Date.now() - baseStart;
234
- const baseOk = baseApplied && checkAnchors(baseFile, task);
235
- process.stdout.write(` baseline: frontier ${baseFrontier.outputTokens} out tok, ${(baseFrontier.wallMs / 1000).toFixed(1)}s | apply ~0s | ${baseOk ? "OK" : "FAIL"}\n`);
236
- // ── FAST-APPLY: frontier emits lazy edit, apply model merges whole file ──
237
- const faStart = Date.now();
238
- const faFrontier = await call(frontierProvider, frontierModel, fc.apiKey, fc.baseUrl, fc.accountId, lazyEditPrompt(task.file, task.instruction), 2048);
239
- const apply = await call(applyProvider, applyModel, ac.apiKey, ac.baseUrl, ac.accountId, applyPrompt(task.file, faFrontier.text), 8192);
240
- const faTotalMs = Date.now() - faStart;
241
- const faFile = apply.text.replace(/^```[a-z]*\n?/i, "").replace(/\n?```$/i, "");
242
- const faOk = checkAnchors(faFile, task);
243
- process.stdout.write(` fast-apply: frontier ${faFrontier.outputTokens} out tok, ${(faFrontier.wallMs / 1000).toFixed(1)}s | apply ${apply.outputTokens} out tok, ${(apply.wallMs / 1000).toFixed(1)}s | ${faOk ? "OK" : "FAIL"}\n\n`);
244
- rows.push({
245
- task: task.name,
246
- lines: task.approxLines,
247
- baseFrontierTokens: baseFrontier.outputTokens,
248
- baseFrontierMs: baseFrontier.wallMs,
249
- baseTotalMs,
250
- baseOk,
251
- faFrontierTokens: faFrontier.outputTokens,
252
- faFrontierMs: faFrontier.wallMs,
253
- faApplyTokens: apply.outputTokens,
254
- faApplyMs: apply.wallMs,
255
- faTotalMs,
256
- faOk,
257
- });
258
- }
259
- // ── Report ──
260
- console.log("\n══════════════════════ RESULTS ══════════════════════\n");
261
- console.log("Task Lines | BASELINE total | FAST-APPLY total | Δ wall | base/fa frontier-out-tok | OK");
262
- for (const r of rows) {
263
- const delta = ((r.baseTotalMs - r.faTotalMs) / r.baseTotalMs) * 100;
264
- console.log(`${r.task.padEnd(7)} ${String(r.lines).padStart(4)} | ` +
265
- `${(r.baseTotalMs / 1000).toFixed(1).padStart(11)}s | ` +
266
- `${(r.faTotalMs / 1000).toFixed(1).padStart(13)}s | ` +
267
- `${(delta >= 0 ? "-" : "+") + Math.abs(delta).toFixed(0) + "%"}`.padStart(8) +
268
- ` | ${String(r.baseFrontierTokens).padStart(5)} / ${String(r.faFrontierTokens).padStart(5)}` +
269
- ` | ${r.baseOk ? "B" : "b"}${r.faOk ? "F" : "f"}`);
270
- }
271
- const sum = (f) => rows.reduce((s, r) => s + f(r), 0);
272
- const baseTot = sum((r) => r.baseTotalMs);
273
- const faTot = sum((r) => r.faTotalMs);
274
- console.log(`\nTotals: baseline ${(baseTot / 1000).toFixed(1)}s vs fast-apply ${(faTot / 1000).toFixed(1)}s ` +
275
- `→ ${baseTot > faTot ? "fast-apply faster" : "baseline faster"} by ${Math.abs(((baseTot - faTot) / baseTot) * 100).toFixed(0)}%`);
276
- console.log(`Frontier output tokens: baseline ${sum((r) => r.baseFrontierTokens)} vs fast-apply ${sum((r) => r.faFrontierTokens)} ` +
277
- `(${(((sum((r) => r.baseFrontierTokens) - sum((r) => r.faFrontierTokens)) / sum((r) => r.baseFrontierTokens)) * 100).toFixed(0)}% fewer)`);
278
- console.log(`Correctness: baseline ${rows.filter((r) => r.baseOk).length}/${rows.length}, fast-apply ${rows.filter((r) => r.faOk).length}/${rows.length}`);
279
- }
280
- main().catch((err) => {
281
- console.error("Benchmark failed:", err);
282
- process.exit(1);
283
- });
284
- //# sourceMappingURL=fast-apply-benchmark.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"fast-apply-benchmark.js","sourceRoot":"","sources":["../../src/core/fast-apply-benchmark.ts"],"names":[],"mappings":"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"}
@@ -1,88 +0,0 @@
1
- /**
2
- * Hashline (hash-anchored edits) vs current string-match edit — real-API
3
- * measurement of whether Feature #2 is worth building.
4
- *
5
- * Two strategies produce the SAME edit against the SAME file, measured against
6
- * live gpt-5.5:
7
- *
8
- * BASELINE (what ggcoder does today): the model emits { old_text, new_text }
9
- * edits where old_text must be copied VERBATIM from the file with enough
10
- * surrounding context to match uniquely (this is exactly our edit tool's
11
- * contract — see tools/edit.ts). The reproduced context is what costs output
12
- * tokens, and a non-unique / drifted old_text is what causes apply failures.
13
- *
14
- * HASHLINE (the proposed feature): every line is shown with a short content-
15
- * hash anchor (`a3f1│<line>`). The model references anchors instead of
16
- * reproducing text — it emits { from, to, lines } where from/to are anchors.
17
- * Anchors are unique by construction, so an edit either resolves exactly or is
18
- * rejected (never silently corrupts), and the model writes far fewer tokens.
19
- *
20
- * We measure, per task: model OUTPUT tokens (the headline -61% claim), whether
21
- * the edit applied cleanly + produced the correct file, and an anchor-uniqueness
22
- * / safety check. Edits are graded deterministically — no second model needed.
23
- *
24
- * The BASELINE apply path runs ggcoder's REAL edit ladder (fuzzy match +
25
- * indent-flex + blank-edge strip + dotdotdots — the same edit-diff functions
26
- * tools/edit.ts uses), so baseline numbers reflect what our tool actually
27
- * recovers, not a naive exact-replace.
28
- *
29
- * Usage:
30
- * npx tsx src/core/hashline-edit-benchmark.ts
31
- *
32
- * Env overrides:
33
- * GG_HL_PROVIDER / GG_HL_MODEL (default anthropic / claude-sonnet-5)
34
- * GG_HL_AUTH_KEY (auth.json key when it differs from the provider name,
35
- * e.g. `xiaomi-credits` for provider `xiaomi`)
36
- * GG_HL_REPEAT (runs per task, default 1 — raise to average noise)
37
- */
38
- import { type AnchoredFile } from "./hashline.js";
39
- export interface EditTask {
40
- name: string;
41
- approxLines: number;
42
- file: string;
43
- instruction: string;
44
- /** Substrings that MUST appear in the correctly-edited file. */
45
- mustContain: string[];
46
- /** Substrings that MUST still be present (unchanged anchors far from the edit). */
47
- mustPreserve: string[];
48
- /** Optional extra validator for tasks where substring checks are too weak. */
49
- validate?: (file: string) => boolean;
50
- }
51
- export declare function genFile(lines: number): string;
52
- /** Near-identical handler blocks — uniqueness pressure for string matching. */
53
- export declare function genRepetitiveFile(blocks: number): string;
54
- export declare function buildTasks(): EditTask[];
55
- export interface ApplyOutcome {
56
- applied: boolean;
57
- correct: boolean;
58
- /** edits whose locator was non-unique / unresolvable (would error in the real tool). */
59
- ambiguousEdits: number;
60
- parsedEdits: number;
61
- }
62
- export declare function stripFence(s: string): string;
63
- /**
64
- * Parse the model's JSON envelope, tolerating literal (unescaped) newlines and
65
- * tabs inside string values. In production, edits arrive as STRUCTURED
66
- * tool-call arguments — the JSON envelope is a benchmark artifact — so both
67
- * strategies get the same repair to keep the comparison about the EDIT FORMAT,
68
- * not about JSON string-escaping discipline.
69
- */
70
- export declare function parseEnvelope<T>(raw: string): T | null;
71
- export declare function checkAnchors(file: string, task: EditTask): boolean;
72
- /**
73
- * ggcoder's REAL apply ladder, mirroring tools/edit.ts:
74
- * 1. exact + smart-quote/dash fuzzy
75
- * 2. indent-flex
76
- * 3. blank-edge strip, retry 1+2
77
- * 4. dotdotdots elision
78
- * Returns the new working buffer or a failure reason.
79
- */
80
- export declare function applyLadder(working: string, oldText: string, newText: string): {
81
- ok: true;
82
- working: string;
83
- } | {
84
- ok: false;
85
- reason: "not_found" | "ambiguous";
86
- };
87
- export declare function applyBaseline(raw: string, task: EditTask): ApplyOutcome;
88
- export declare function applyHashline(raw: string, task: EditTask, anchored: AnchoredFile): ApplyOutcome;