@prestyj/cli 4.11.4 → 4.12.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 (100) hide show
  1. package/dist/app-sidecar.js +386 -55
  2. package/dist/app-sidecar.js.map +1 -1
  3. package/dist/cli.d.ts.map +1 -1
  4. package/dist/cli.js +5 -3
  5. package/dist/cli.js.map +1 -1
  6. package/dist/config.d.ts +5 -0
  7. package/dist/config.d.ts.map +1 -1
  8. package/dist/config.js +3 -0
  9. package/dist/config.js.map +1 -1
  10. package/dist/core/agent-session.d.ts +53 -11
  11. package/dist/core/agent-session.d.ts.map +1 -1
  12. package/dist/core/agent-session.js +150 -35
  13. package/dist/core/agent-session.js.map +1 -1
  14. package/dist/core/api-benchmark.d.ts +64 -0
  15. package/dist/core/api-benchmark.d.ts.map +1 -0
  16. package/dist/core/api-benchmark.js +381 -0
  17. package/dist/core/api-benchmark.js.map +1 -0
  18. package/dist/core/mcp/client.d.ts +21 -0
  19. package/dist/core/mcp/client.d.ts.map +1 -1
  20. package/dist/core/mcp/client.js +167 -5
  21. package/dist/core/mcp/client.js.map +1 -1
  22. package/dist/core/mcp/index.d.ts +3 -1
  23. package/dist/core/mcp/index.d.ts.map +1 -1
  24. package/dist/core/mcp/index.js +2 -0
  25. package/dist/core/mcp/index.js.map +1 -1
  26. package/dist/core/mcp/oauth-provider.d.ts +51 -0
  27. package/dist/core/mcp/oauth-provider.d.ts.map +1 -0
  28. package/dist/core/mcp/oauth-provider.js +95 -0
  29. package/dist/core/mcp/oauth-provider.js.map +1 -0
  30. package/dist/core/mcp/oauth-store.d.ts +39 -0
  31. package/dist/core/mcp/oauth-store.d.ts.map +1 -0
  32. package/dist/core/mcp/oauth-store.js +63 -0
  33. package/dist/core/mcp/oauth-store.js.map +1 -0
  34. package/dist/core/mcp/oauth-store.test.d.ts +2 -0
  35. package/dist/core/mcp/oauth-store.test.d.ts.map +1 -0
  36. package/dist/core/mcp/oauth-store.test.js +94 -0
  37. package/dist/core/mcp/oauth-store.test.js.map +1 -0
  38. package/dist/core/process-manager.d.ts.map +1 -1
  39. package/dist/core/process-manager.js +5 -1
  40. package/dist/core/process-manager.js.map +1 -1
  41. package/dist/core/prompt-commands.d.ts.map +1 -1
  42. package/dist/core/prompt-commands.js +112 -0
  43. package/dist/core/prompt-commands.js.map +1 -1
  44. package/dist/core/prompt-commands.test.js +22 -0
  45. package/dist/core/prompt-commands.test.js.map +1 -1
  46. package/dist/core/settings-manager.d.ts +4 -0
  47. package/dist/core/settings-manager.d.ts.map +1 -1
  48. package/dist/core/settings-manager.js +5 -0
  49. package/dist/core/settings-manager.js.map +1 -1
  50. package/dist/core/shell.d.ts +51 -0
  51. package/dist/core/shell.d.ts.map +1 -0
  52. package/dist/core/shell.js +82 -0
  53. package/dist/core/shell.js.map +1 -0
  54. package/dist/core/shell.test.d.ts +2 -0
  55. package/dist/core/shell.test.d.ts.map +1 -0
  56. package/dist/core/shell.test.js +87 -0
  57. package/dist/core/shell.test.js.map +1 -0
  58. package/dist/core/speed-benchmark.d.ts +133 -0
  59. package/dist/core/speed-benchmark.d.ts.map +1 -0
  60. package/dist/core/speed-benchmark.js +410 -0
  61. package/dist/core/speed-benchmark.js.map +1 -0
  62. package/dist/core/speed-benchmark.test.d.ts +2 -0
  63. package/dist/core/speed-benchmark.test.d.ts.map +1 -0
  64. package/dist/core/speed-benchmark.test.js +97 -0
  65. package/dist/core/speed-benchmark.test.js.map +1 -0
  66. package/dist/interactive.d.ts.map +1 -1
  67. package/dist/interactive.js +4 -3
  68. package/dist/interactive.js.map +1 -1
  69. package/dist/tools/bash.d.ts.map +1 -1
  70. package/dist/tools/bash.js +17 -1
  71. package/dist/tools/bash.js.map +1 -1
  72. package/dist/tools/generate-image.d.ts +39 -0
  73. package/dist/tools/generate-image.d.ts.map +1 -0
  74. package/dist/tools/generate-image.js +301 -0
  75. package/dist/tools/generate-image.js.map +1 -0
  76. package/dist/tools/generate-image.test.d.ts +2 -0
  77. package/dist/tools/generate-image.test.d.ts.map +1 -0
  78. package/dist/tools/generate-image.test.js +223 -0
  79. package/dist/tools/generate-image.test.js.map +1 -0
  80. package/dist/tools/index.d.ts +12 -1
  81. package/dist/tools/index.d.ts.map +1 -1
  82. package/dist/tools/index.js +16 -1
  83. package/dist/tools/index.js.map +1 -1
  84. package/dist/tools/plan-mode.test.js +5 -5
  85. package/dist/tools/plan-mode.test.js.map +1 -1
  86. package/dist/tools/prompt-hints.d.ts.map +1 -1
  87. package/dist/tools/prompt-hints.js +2 -0
  88. package/dist/tools/prompt-hints.js.map +1 -1
  89. package/dist/tools/safe-env.d.ts.map +1 -1
  90. package/dist/tools/safe-env.js +27 -0
  91. package/dist/tools/safe-env.js.map +1 -1
  92. package/dist/ui/App.d.ts +1 -1
  93. package/dist/ui/App.d.ts.map +1 -1
  94. package/dist/ui/hooks/usePixelFixFlow.d.ts +1 -1
  95. package/dist/ui/hooks/usePixelFixFlow.d.ts.map +1 -1
  96. package/dist/ui/hooks/usePixelFixFlow.js +1 -1
  97. package/dist/ui/hooks/usePixelFixFlow.js.map +1 -1
  98. package/dist/ui/render.d.ts +1 -1
  99. package/dist/ui/render.d.ts.map +1 -1
  100. package/package.json +5 -5
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Real-API speed benchmark — sends actual requests to a live provider and
3
+ * measures TTFT, output throughput, cache behavior, and wall-clock latency.
4
+ *
5
+ * Unlike the mock benchmark, this hits real endpoints and produces
6
+ * production-representative numbers. Uses gg's own AuthStorage to resolve
7
+ * credentials (same path as a real session).
8
+ *
9
+ * Usage:
10
+ * npx tsx src/core/api-benchmark.ts
11
+ *
12
+ * Environment overrides:
13
+ * GG_BENCH_PROVIDER — provider name (default: "glm")
14
+ * GG_BENCH_MODEL — model id (default: "glm-5.2")
15
+ * GG_BENCH_TURNS — number of turns (default: 5)
16
+ */
17
+ export interface ApiTurnMetrics {
18
+ turn: number;
19
+ prompt: string;
20
+ ttftMs: number;
21
+ outputTokens: number;
22
+ outputDurationMs: number;
23
+ tokensPerSecond: number;
24
+ wallClockMs: number;
25
+ inputTokens: number;
26
+ cacheRead: number;
27
+ cacheWrite: number;
28
+ cacheHit: boolean;
29
+ stopReason: string;
30
+ }
31
+ export interface ApiBenchmarkResult {
32
+ provider: string;
33
+ model: string;
34
+ turns: ApiTurnMetrics[];
35
+ totalWallClockMs: number;
36
+ totalTtftMs: number;
37
+ totalOutputTokens: number;
38
+ avgTokensPerSecond: number;
39
+ avgTtftMs: number;
40
+ cacheHits: number;
41
+ cacheHitRate: number;
42
+ }
43
+ export declare function runApiBenchmark(config: {
44
+ provider: string;
45
+ model: string;
46
+ apiKey: string;
47
+ baseUrl?: string;
48
+ accountId?: string;
49
+ cacheRetention?: "short" | "long";
50
+ promptCacheKey?: string;
51
+ turns?: number;
52
+ }): Promise<ApiBenchmarkResult>;
53
+ export declare function formatApiResult(result: ApiBenchmarkResult): string;
54
+ export interface ApiComparisonResult {
55
+ baseline: ApiBenchmarkResult;
56
+ optimized: ApiBenchmarkResult;
57
+ ttftImprovement: number;
58
+ throughputImprovement: number;
59
+ wallClockImprovement: number;
60
+ cacheHitRateDelta: number;
61
+ }
62
+ /** Format an A/B comparison between two API benchmark runs. */
63
+ export declare function formatApiComparison(c: ApiComparisonResult): string;
64
+ //# sourceMappingURL=api-benchmark.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-benchmark.d.ts","sourceRoot":"","sources":["../../src/core/api-benchmark.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAOH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;CACtB;AAwDD,wBAAsB,eAAe,CAAC,MAAM,EAAE;IAC5C,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAClC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CA0I9B;AAID,wBAAgB,eAAe,CAAC,MAAM,EAAE,kBAAkB,GAAG,MAAM,CAsClE;AAeD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,SAAS,EAAE,kBAAkB,CAAC;IAC9B,eAAe,EAAE,MAAM,CAAC;IACxB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED,+DAA+D;AAC/D,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,mBAAmB,GAAG,MAAM,CAiClE"}
@@ -0,0 +1,381 @@
1
+ /**
2
+ * Real-API speed benchmark — sends actual requests to a live provider and
3
+ * measures TTFT, output throughput, cache behavior, and wall-clock latency.
4
+ *
5
+ * Unlike the mock benchmark, this hits real endpoints and produces
6
+ * production-representative numbers. Uses gg's own AuthStorage to resolve
7
+ * credentials (same path as a real session).
8
+ *
9
+ * Usage:
10
+ * npx tsx src/core/api-benchmark.ts
11
+ *
12
+ * Environment overrides:
13
+ * GG_BENCH_PROVIDER — provider name (default: "glm")
14
+ * GG_BENCH_MODEL — model id (default: "glm-5.2")
15
+ * GG_BENCH_TURNS — number of turns (default: 5)
16
+ */
17
+ import { stream } from "@prestyj/ai";
18
+ import { AuthStorage } from "./auth-storage.js";
19
+ // ── System prompt (realistic coding-agent prefix) ──────────
20
+ function buildSystemPrompt() {
21
+ return [
22
+ "You are EZ Coder — a coding agent that works directly in the user's codebase.",
23
+ "You explore, understand, change, and verify code — completing tasks end-to-end",
24
+ "rather than just suggesting edits.",
25
+ "",
26
+ "## How to Talk",
27
+ "Don't narrate tool calls. Stay silent between tools unless you have a decision.",
28
+ "Final replies: 1-3 sentences, hard cap 5.",
29
+ "",
30
+ "## How to Work",
31
+ "- Read before edit/write; re-read after formatters or codegen.",
32
+ "- Compute in bash; write with edit/write so read-tracking stays intact.",
33
+ "- Keep edits small; plan multi-file work first.",
34
+ "- Choose targeted verification appropriate to the change.",
35
+ "",
36
+ "## Tools",
37
+ "- read: Read file contents",
38
+ "- write: Write file contents",
39
+ "- edit: Replace text in a file via search-replace blocks",
40
+ "- bash: Execute shell commands",
41
+ "- grep: Search file contents using regex",
42
+ "- find: Find files matching a glob pattern",
43
+ "",
44
+ "## Code Quality",
45
+ "Intent-revealing names; reuse existing deps. Types first; handle I/O and errors.",
46
+ "No dead/commented code, placeholders, or unasked refactors.",
47
+ "",
48
+ "## Environment",
49
+ "- Working directory: /home/user/my-project",
50
+ "- Platform: linux",
51
+ "",
52
+ "<!-- uncached -->",
53
+ "Today's date: 20 June 2026",
54
+ ].join("\n");
55
+ }
56
+ // ── Conversation turns ──────────────────────────────────────
57
+ /** Prompts designed to produce 100-300 token responses so throughput
58
+ * measurement is meaningful (the simple one-liners gave 8-13 tokens
59
+ * which made tok/s unreliable). */
60
+ const CONVERSATION_TURNS = [
61
+ "Write a TypeScript function `rateLimit(opts: { maxAttempts: number; windowMs: number })` that returns an Express middleware. Include the full implementation with comments, error handling, and an in-memory store. Make it production quality.",
62
+ "Now write a test file for that rate limiter using vitest. Cover the happy path, rate limit exceeded, window reset, and multiple IPs. Include at least 4 test cases with full implementations.",
63
+ "Refactor the rate limiter to support a Redis backend as an alternative to the in-memory store. Show the interface, both implementations, and a factory function. Keep it backward compatible.",
64
+ "Write a README section documenting the rate limiter API: installation, usage examples for both backends, configuration options, and a comparison table of in-memory vs Redis.",
65
+ "Review the entire rate limiter module for security issues, edge cases, and performance. Write a brief analysis with specific findings and recommended fixes for each issue.",
66
+ ];
67
+ // ── Benchmark runner ────────────────────────────────────────
68
+ export async function runApiBenchmark(config) {
69
+ const { provider, model, apiKey, baseUrl, accountId, cacheRetention = "long", promptCacheKey = `bench-${Date.now()}`, turns = 5, } = config;
70
+ const messages = [{ role: "system", content: buildSystemPrompt() }];
71
+ const turnMetrics = [];
72
+ for (let i = 0; i < turns; i++) {
73
+ const userPrompt = CONVERSATION_TURNS[i % CONVERSATION_TURNS.length];
74
+ messages.push({ role: "user", content: userPrompt });
75
+ const turnStart = Date.now();
76
+ let ttftMs = 0;
77
+ let firstToken = true;
78
+ const result = stream({
79
+ provider: provider,
80
+ model,
81
+ messages: [...messages],
82
+ maxTokens: 1024,
83
+ apiKey,
84
+ baseUrl,
85
+ accountId,
86
+ cacheRetention,
87
+ promptCacheKey,
88
+ });
89
+ let response;
90
+ try {
91
+ // Consume the stream, measuring TTFT on first event.
92
+ for await (const event of result) {
93
+ if (firstToken && (event.type === "text_delta" || event.type === "thinking_delta")) {
94
+ ttftMs = Date.now() - turnStart;
95
+ firstToken = false;
96
+ }
97
+ if (event.type === "text_delta") {
98
+ // Output counting happens via usage.outputTokens from the response.
99
+ }
100
+ }
101
+ response = await result.response;
102
+ }
103
+ catch (err) {
104
+ const errMsg = err instanceof Error ? err.message : String(err);
105
+ console.error(` Turn ${i + 1} FAILED: ${errMsg.slice(0, 200)}`);
106
+ turnMetrics.push({
107
+ turn: i + 1,
108
+ prompt: userPrompt.slice(0, 50),
109
+ ttftMs: 0,
110
+ outputTokens: 0,
111
+ outputDurationMs: 0,
112
+ tokensPerSecond: 0,
113
+ wallClockMs: Date.now() - turnStart,
114
+ inputTokens: 0,
115
+ cacheRead: 0,
116
+ cacheWrite: 0,
117
+ cacheHit: false,
118
+ stopReason: "error",
119
+ });
120
+ // Don't continue — conversation context is broken after an error
121
+ break;
122
+ }
123
+ const wallClockMs = Date.now() - turnStart;
124
+ const outputTokens = response.usage.outputTokens;
125
+ const outputDurationMs = wallClockMs - ttftMs;
126
+ const tokensPerSecond = outputDurationMs > 0 ? (outputTokens / outputDurationMs) * 1000 : 0;
127
+ const cacheRead = response.usage.cacheRead ?? 0;
128
+ turnMetrics.push({
129
+ turn: i + 1,
130
+ prompt: userPrompt.slice(0, 50),
131
+ ttftMs,
132
+ outputTokens,
133
+ outputDurationMs,
134
+ tokensPerSecond,
135
+ wallClockMs,
136
+ inputTokens: response.usage.inputTokens,
137
+ cacheRead,
138
+ cacheWrite: response.usage.cacheWrite ?? 0,
139
+ cacheHit: cacheRead > 0,
140
+ stopReason: response.stopReason,
141
+ });
142
+ // Append assistant reply for next turn.
143
+ const assistantContent = typeof response.message.content === "string"
144
+ ? response.message.content
145
+ : response.message.content
146
+ .filter((p) => p.type === "text")
147
+ .map((p) => p.text ?? "")
148
+ .join("");
149
+ messages.push({ role: "assistant", content: assistantContent });
150
+ // Brief pause between turns (realistic user think time).
151
+ if (i < turns - 1) {
152
+ await sleep(2000);
153
+ }
154
+ // Progress output.
155
+ process.stdout.write(` Turn ${i + 1}/${turns}: TTFT ${ttftMs}ms | ${tokensPerSecond.toFixed(0)} tok/s | ` +
156
+ `${outputTokens} out | cache ${cacheRead > 0 ? "HIT" : "miss"}` +
157
+ `${cacheRead > 0 ? ` (${cacheRead} tok)` : ""}\n`);
158
+ }
159
+ const totalWallClockMs = turnMetrics.reduce((s, t) => s + t.wallClockMs, 0);
160
+ const totalTtftMs = turnMetrics.reduce((s, t) => s + t.ttftMs, 0);
161
+ const totalOutputTokens = turnMetrics.reduce((s, t) => s + t.outputTokens, 0);
162
+ const cacheHits = turnMetrics.filter((t) => t.cacheHit).length;
163
+ const validTurns = turnMetrics.filter((t) => t.stopReason !== "error");
164
+ const avgTokensPerSecond = validTurns.length > 0
165
+ ? validTurns.reduce((s, t) => s + t.tokensPerSecond, 0) / validTurns.length
166
+ : 0;
167
+ const avgTtftMs = validTurns.length > 0 ? totalTtftMs / validTurns.length : 0;
168
+ return {
169
+ provider,
170
+ model,
171
+ turns: turnMetrics,
172
+ totalWallClockMs,
173
+ totalTtftMs,
174
+ totalOutputTokens,
175
+ avgTokensPerSecond,
176
+ avgTtftMs,
177
+ cacheHits,
178
+ cacheHitRate: turnMetrics.length > 0 ? cacheHits / turnMetrics.length : 0,
179
+ };
180
+ }
181
+ // ── Formatting ──────────────────────────────────────────────
182
+ export function formatApiResult(result) {
183
+ const lines = [];
184
+ lines.push("");
185
+ lines.push("╔══════════════════════════════════════════════════════════════╗");
186
+ lines.push(`║ API BENCHMARK: ${result.provider} / ${result.model}`.padEnd(63) + "║");
187
+ lines.push("╠══════════════════════════════════════════════════════════════╣");
188
+ lines.push("");
189
+ lines.push("┌──────┬────────────┬──────────┬───────────┬────────┬──────────┐");
190
+ lines.push("│ Turn │ TTFT │ Output │ Tok/s │ Cache │ Wall │");
191
+ lines.push("├──────┼────────────┼──────────┼───────────┼────────┼──────────┤");
192
+ for (const t of result.turns) {
193
+ const cacheLabel = t.cacheHit ? " HIT " : "miss";
194
+ lines.push(`│ ${String(t.turn).padStart(4)} │ ${fmt(t.ttftMs).padStart(10)} │ ` +
195
+ `${String(t.outputTokens).padStart(8)} │ ${t.tokensPerSecond.toFixed(0).padStart(9)} │ ` +
196
+ `${cacheLabel} │ ${fmt(t.wallClockMs).padStart(8)} │`);
197
+ }
198
+ lines.push("└──────┴────────────┴──────────┴───────────┴────────┴──────────┘");
199
+ lines.push("");
200
+ lines.push("┌─────────────────────────────┬──────────────────────────────┐");
201
+ lines.push("│ Metric │ Value │");
202
+ lines.push("├─────────────────────────────┼──────────────────────────────┤");
203
+ lines.push(`│ Avg TTFT │ ${fmt(result.avgTtftMs).padStart(28)} │`);
204
+ lines.push(`│ Avg output throughput │ ${result.avgTokensPerSecond.toFixed(0).padStart(22)} tok/s │`);
205
+ lines.push(`│ Total output tokens │ ${String(result.totalOutputTokens).padStart(28)} │`);
206
+ lines.push(`│ Total wall-clock │ ${fmt(result.totalWallClockMs).padStart(28)} │`);
207
+ lines.push(`│ Cache hits │ ${String(result.cacheHits).padStart(28)} │`);
208
+ lines.push(`│ Cache hit rate │ ${(result.cacheHitRate * 100).toFixed(0).padStart(27)}% │`);
209
+ lines.push("└─────────────────────────────┴──────────────────────────────┘");
210
+ lines.push("");
211
+ return lines.join("\n");
212
+ }
213
+ function fmt(ms) {
214
+ if (ms < 1000)
215
+ return `${Math.round(ms)}ms`;
216
+ return `${(ms / 1000).toFixed(2)}s`;
217
+ }
218
+ function sleep(ms) {
219
+ return new Promise((resolve) => setTimeout(resolve, ms));
220
+ }
221
+ /** Format an A/B comparison between two API benchmark runs. */
222
+ export function formatApiComparison(c) {
223
+ const lines = [];
224
+ lines.push("");
225
+ lines.push("╔══════════════════════════════════════════════════════════════╗");
226
+ lines.push("║ REAL API A/B: BASELINE vs OPTIMIZED ║");
227
+ lines.push("╚══════════════════════════════════════════════════════════════╝");
228
+ lines.push("");
229
+ lines.push(formatApiResult(c.baseline));
230
+ lines.push(formatApiResult(c.optimized));
231
+ lines.push("┌─────────────────────────────┬──────────────┬──────────────┬───────────┐");
232
+ lines.push("│ Metric │ Baseline │ Optimized │ Delta │");
233
+ lines.push("├─────────────────────────────┼──────────────┼──────────────┼───────────┤");
234
+ // TTFT/wall-clock: delta = (baseline - optimized), positive = faster = show -X%.
235
+ const pctDown = (delta) => `${delta >= 0 ? "-" : "+"}${Math.abs(delta).toFixed(1).padStart(5)}%`;
236
+ // Throughput: delta = (optimized - baseline), positive = faster = show +X%.
237
+ const pctUp = (delta) => `${delta >= 0 ? "+" : "-"}${Math.abs(delta).toFixed(1).padStart(5)}%`;
238
+ lines.push(`│ Avg TTFT │ ${fmt(c.baseline.avgTtftMs).padStart(11)} │ ${fmt(c.optimized.avgTtftMs).padStart(11)} │ ${pctDown(c.ttftImprovement).padStart(8)} │`);
239
+ lines.push(`│ Avg throughput (tok/s) │ ${String(c.baseline.avgTokensPerSecond.toFixed(0)).padStart(11)} │ ${String(c.optimized.avgTokensPerSecond.toFixed(0)).padStart(11)} │ ${pctUp(c.throughputImprovement).padStart(8)} │`);
240
+ lines.push(`│ Total wall-clock │ ${fmt(c.baseline.totalWallClockMs).padStart(11)} │ ${fmt(c.optimized.totalWallClockMs).padStart(11)} │ ${pctDown(c.wallClockImprovement).padStart(8)} │`);
241
+ lines.push(`│ Cache hit rate │ ${(c.baseline.cacheHitRate * 100).toFixed(0).padStart(10)}% │ ${(c.optimized.cacheHitRate * 100).toFixed(0).padStart(10)}% │ ${c.cacheHitRateDelta >= 0 ? "+" : ""}${c.cacheHitRateDelta.toFixed(0).padStart(5)}pp │`);
242
+ lines.push("└─────────────────────────────┴──────────────┴──────────────┴───────────┘");
243
+ lines.push("");
244
+ return lines.join("\n");
245
+ }
246
+ async function main() {
247
+ const provider = process.env.GG_BENCH_PROVIDER ?? "glm";
248
+ const model = process.env.GG_BENCH_MODEL ?? "glm-5.2";
249
+ const turns = parseInt(process.env.GG_BENCH_TURNS ?? "5", 10);
250
+ const mode = process.env.GG_BENCH_MODE ?? "compare"; // "single" or "compare"
251
+ // Resolve credentials using gg's AuthStorage (same path as a real session).
252
+ const authStorage = new AuthStorage();
253
+ await authStorage.load();
254
+ let apiKey;
255
+ let baseUrl;
256
+ let accountId;
257
+ try {
258
+ const creds = await authStorage.resolveCredentials(provider);
259
+ apiKey = creds.accessToken;
260
+ baseUrl = creds.baseUrl;
261
+ accountId = creds.accountId;
262
+ }
263
+ catch (err) {
264
+ console.error(`❌ Could not resolve credentials for "${provider}". ` +
265
+ `Make sure you're logged in: run \`ezcoder login\` and choose ${provider}.\n` +
266
+ ` Error: ${err instanceof Error ? err.message : String(err)}`);
267
+ process.exit(1);
268
+ }
269
+ if (!apiKey) {
270
+ console.error(`❌ Resolved credentials for "${provider}" but accessToken is empty.`);
271
+ process.exit(1);
272
+ }
273
+ console.log(`\n🔍 API Benchmark: ${provider}/${model} — mode: ${mode} (${turns} turns)`);
274
+ console.log(` API key: ${apiKey.slice(0, 8)}...${apiKey.slice(-4)}`);
275
+ console.log(` Base URL: ${baseUrl ?? "(provider default)"}`);
276
+ if (accountId)
277
+ console.log(` Account ID: ${accountId}`);
278
+ console.log("");
279
+ if (mode === "single") {
280
+ const result = await runApiBenchmark({
281
+ provider,
282
+ model,
283
+ apiKey,
284
+ baseUrl,
285
+ accountId,
286
+ cacheRetention: "long",
287
+ promptCacheKey: `bench-${provider}-${Date.now()}`,
288
+ turns,
289
+ });
290
+ console.log(formatApiResult(result));
291
+ return;
292
+ }
293
+ // A/B comparison mode.
294
+ console.log("━".repeat(50));
295
+ console.log("▶ BASELINE: cacheRetention=short, no prewarm");
296
+ console.log("━".repeat(50));
297
+ const baseline = await runApiBenchmark({
298
+ provider,
299
+ model,
300
+ apiKey,
301
+ baseUrl,
302
+ accountId,
303
+ cacheRetention: "short",
304
+ promptCacheKey: `bench-base-${provider}-${Date.now()}`,
305
+ turns,
306
+ });
307
+ // Cool-down between runs so the second run isn't affected by connection warming.
308
+ console.log("\n⏳ Cooling down 5s between runs...\n");
309
+ await sleep(5000);
310
+ console.log("━".repeat(50));
311
+ console.log("▶ OPTIMIZED: cacheRetention=long + prewarm");
312
+ console.log("━".repeat(50));
313
+ // Fire a prewarm request before the optimized run (same as AgentSession does).
314
+ if (provider === "anthropic") {
315
+ const { prewarmAnthropicCache } = await import("@prestyj/ai");
316
+ await prewarmAnthropicCache({
317
+ apiKey,
318
+ model,
319
+ system: buildSystemPrompt(),
320
+ cacheRetention: "long",
321
+ baseUrl,
322
+ }).catch(() => { });
323
+ console.log(" (prewarm sent)");
324
+ }
325
+ else {
326
+ // For non-Anthropic providers, fire a minimal warm-up request to prime
327
+ // the provider's prefix cache (GLM, OpenAI, etc. auto-cache on first hit).
328
+ console.log(" (warm-up request for prefix cache)");
329
+ await runApiBenchmark({
330
+ provider,
331
+ model,
332
+ apiKey,
333
+ baseUrl,
334
+ accountId,
335
+ cacheRetention: "long",
336
+ promptCacheKey: `bench-warm-${provider}-${Date.now()}`,
337
+ turns: 1,
338
+ }).catch(() => { });
339
+ }
340
+ const optimized = await runApiBenchmark({
341
+ provider,
342
+ model,
343
+ apiKey,
344
+ baseUrl,
345
+ accountId,
346
+ cacheRetention: "long",
347
+ promptCacheKey: `bench-opt-${provider}-${Date.now()}`,
348
+ turns,
349
+ });
350
+ const ttftImprovement = baseline.avgTtftMs > 0
351
+ ? ((baseline.avgTtftMs - optimized.avgTtftMs) / baseline.avgTtftMs) * 100
352
+ : 0;
353
+ const throughputImprovement = baseline.avgTokensPerSecond > 0
354
+ ? ((optimized.avgTokensPerSecond - baseline.avgTokensPerSecond) /
355
+ baseline.avgTokensPerSecond) *
356
+ 100
357
+ : 0;
358
+ const wallClockImprovement = baseline.totalWallClockMs > 0
359
+ ? ((baseline.totalWallClockMs - optimized.totalWallClockMs) / baseline.totalWallClockMs) * 100
360
+ : 0;
361
+ const comparison = {
362
+ baseline,
363
+ optimized,
364
+ ttftImprovement,
365
+ throughputImprovement,
366
+ wallClockImprovement,
367
+ cacheHitRateDelta: (optimized.cacheHitRate - baseline.cacheHitRate) * 100,
368
+ };
369
+ console.log(formatApiComparison(comparison));
370
+ }
371
+ // Run when executed directly (not when imported by tests).
372
+ const isDirectRun = process.argv[1]?.endsWith("api-benchmark.ts") ||
373
+ process.argv[1]?.endsWith("api-benchmark.js") ||
374
+ process.argv[1]?.endsWith("api-benchmark");
375
+ if (isDirectRun) {
376
+ main().catch((err) => {
377
+ console.error("Benchmark failed:", err);
378
+ process.exit(1);
379
+ });
380
+ }
381
+ //# sourceMappingURL=api-benchmark.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-benchmark.js","sourceRoot":"","sources":["../../src/core/api-benchmark.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,MAAM,EAA8C,MAAM,aAAa,CAAC;AACjF,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAgChD,8DAA8D;AAE9D,SAAS,iBAAiB;IACxB,OAAO;QACL,+EAA+E;QAC/E,gFAAgF;QAChF,oCAAoC;QACpC,EAAE;QACF,gBAAgB;QAChB,iFAAiF;QACjF,2CAA2C;QAC3C,EAAE;QACF,gBAAgB;QAChB,gEAAgE;QAChE,yEAAyE;QACzE,iDAAiD;QACjD,2DAA2D;QAC3D,EAAE;QACF,UAAU;QACV,4BAA4B;QAC5B,8BAA8B;QAC9B,0DAA0D;QAC1D,gCAAgC;QAChC,0CAA0C;QAC1C,4CAA4C;QAC5C,EAAE;QACF,iBAAiB;QACjB,kFAAkF;QAClF,6DAA6D;QAC7D,EAAE;QACF,gBAAgB;QAChB,4CAA4C;QAC5C,mBAAmB;QACnB,EAAE;QACF,mBAAmB;QACnB,4BAA4B;KAC7B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED,+DAA+D;AAE/D;;oCAEoC;AACpC,MAAM,kBAAkB,GAAG;IACzB,iPAAiP;IACjP,+LAA+L;IAC/L,+LAA+L;IAC/L,+KAA+K;IAC/K,6KAA6K;CAC9K,CAAC;AAEF,+DAA+D;AAE/D,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,MASrC;IACC,MAAM,EACJ,QAAQ,EACR,KAAK,EACL,MAAM,EACN,OAAO,EACP,SAAS,EACT,cAAc,GAAG,MAAM,EACvB,cAAc,GAAG,SAAS,IAAI,CAAC,GAAG,EAAE,EAAE,EACtC,KAAK,GAAG,CAAC,GACV,GAAG,MAAM,CAAC;IAEX,MAAM,QAAQ,GAAc,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,iBAAiB,EAAE,EAAE,CAAC,CAAC;IAE/E,MAAM,WAAW,GAAqB,EAAE,CAAC;IAEzC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;QAC/B,MAAM,UAAU,GAAG,kBAAkB,CAAC,CAAC,GAAG,kBAAkB,CAAC,MAAM,CAAE,CAAC;QACtE,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC;QAErD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC7B,IAAI,MAAM,GAAG,CAAC,CAAC;QACf,IAAI,UAAU,GAAG,IAAI,CAAC;QAEtB,MAAM,MAAM,GAAG,MAAM,CAAC;YACpB,QAAQ,EAAE,QAAiB;YAC3B,KAAK;YACL,QAAQ,EAAE,CAAC,GAAG,QAAQ,CAAC;YACvB,SAAS,EAAE,IAAI;YACf,MAAM;YACN,OAAO;YACP,SAAS;YACT,cAAc;YACd,cAAc;SACf,CAAC,CAAC;QAEH,IAAI,QAAgE,CAAC;QAErE,IAAI,CAAC;YACH,qDAAqD;YACrD,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,MAAoC,EAAE,CAAC;gBAC/D,IAAI,UAAU,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,YAAY,IAAI,KAAK,CAAC,IAAI,KAAK,gBAAgB,CAAC,EAAE,CAAC;oBACnF,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;oBAChC,UAAU,GAAG,KAAK,CAAC;gBACrB,CAAC;gBACD,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;oBAChC,oEAAoE;gBACtE,CAAC;YACH,CAAC;YACD,QAAQ,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC;QACnC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,MAAM,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAChE,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,YAAY,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;YACjE,WAAW,CAAC,IAAI,CAAC;gBACf,IAAI,EAAE,CAAC,GAAG,CAAC;gBACX,MAAM,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;gBAC/B,MAAM,EAAE,CAAC;gBACT,YAAY,EAAE,CAAC;gBACf,gBAAgB,EAAE,CAAC;gBACnB,eAAe,EAAE,CAAC;gBAClB,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;gBACnC,WAAW,EAAE,CAAC;gBACd,SAAS,EAAE,CAAC;gBACZ,UAAU,EAAE,CAAC;gBACb,QAAQ,EAAE,KAAK;gBACf,UAAU,EAAE,OAAO;aACpB,CAAC,CAAC;YACH,iEAAiE;YACjE,MAAM;QACR,CAAC;QAED,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;QAC3C,MAAM,YAAY,GAAG,QAAQ,CAAC,KAAK,CAAC,YAAY,CAAC;QACjD,MAAM,gBAAgB,GAAG,WAAW,GAAG,MAAM,CAAC;QAC9C,MAAM,eAAe,GAAG,gBAAgB,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,GAAG,gBAAgB,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5F,MAAM,SAAS,GAAG,QAAQ,CAAC,KAAK,CAAC,SAAS,IAAI,CAAC,CAAC;QAEhD,WAAW,CAAC,IAAI,CAAC;YACf,IAAI,EAAE,CAAC,GAAG,CAAC;YACX,MAAM,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;YAC/B,MAAM;YACN,YAAY;YACZ,gBAAgB;YAChB,eAAe;YACf,WAAW;YACX,WAAW,EAAE,QAAQ,CAAC,KAAK,CAAC,WAAW;YACvC,SAAS;YACT,UAAU,EAAE,QAAQ,CAAC,KAAK,CAAC,UAAU,IAAI,CAAC;YAC1C,QAAQ,EAAE,SAAS,GAAG,CAAC;YACvB,UAAU,EAAE,QAAQ,CAAC,UAAU;SAChC,CAAC,CAAC;QAEH,wCAAwC;QACxC,MAAM,gBAAgB,GACpB,OAAO,QAAQ,CAAC,OAAO,CAAC,OAAO,KAAK,QAAQ;YAC1C,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO;YAC1B,CAAC,CAAE,QAAQ,CAAC,OAAO,CAAC,OAAkD;iBACjE,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC;iBAChC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;iBACxB,IAAI,CAAC,EAAE,CAAC,CAAC;QAClB,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,gBAAgB,EAAE,CAAC,CAAC;QAEhE,yDAAyD;QACzD,IAAI,CAAC,GAAG,KAAK,GAAG,CAAC,EAAE,CAAC;YAClB,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC;QACpB,CAAC;QAED,mBAAmB;QACnB,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,UAAU,MAAM,QAAQ,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW;YACnF,GAAG,YAAY,gBAAgB,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE;YAC/D,GAAG,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,SAAS,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,CACpD,CAAC;IACJ,CAAC;IAED,MAAM,gBAAgB,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;IAC5E,MAAM,WAAW,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAClE,MAAM,iBAAiB,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC;IAC9E,MAAM,SAAS,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC;IAC/D,MAAM,UAAU,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,OAAO,CAAC,CAAC;IACvE,MAAM,kBAAkB,GACtB,UAAU,CAAC,MAAM,GAAG,CAAC;QACnB,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,eAAe,EAAE,CAAC,CAAC,GAAG,UAAU,CAAC,MAAM;QAC3E,CAAC,CAAC,CAAC,CAAC;IACR,MAAM,SAAS,GAAG,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IAE9E,OAAO;QACL,QAAQ;QACR,KAAK;QACL,KAAK,EAAE,WAAW;QAClB,gBAAgB;QAChB,WAAW;QACX,iBAAiB;QACjB,kBAAkB;QAClB,SAAS;QACT,SAAS;QACT,YAAY,EAAE,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;KAC1E,CAAC;AACJ,CAAC;AAED,+DAA+D;AAE/D,MAAM,UAAU,eAAe,CAAC,MAA0B;IACxD,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,kEAAkE,CAAC,CAAC;IAC/E,KAAK,CAAC,IAAI,CAAC,qBAAqB,MAAM,CAAC,QAAQ,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC;IACtF,KAAK,CAAC,IAAI,CAAC,kEAAkE,CAAC,CAAC;IAC/E,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,kEAAkE,CAAC,CAAC;IAC/E,KAAK,CAAC,IAAI,CAAC,kEAAkE,CAAC,CAAC;IAC/E,KAAK,CAAC,IAAI,CAAC,kEAAkE,CAAC,CAAC;IAE/E,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QAC7B,MAAM,UAAU,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;QACjD,KAAK,CAAC,IAAI,CACR,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK;YAClE,GAAG,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK;YACxF,GAAG,UAAU,MAAM,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CACxD,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,kEAAkE,CAAC,CAAC;IAC/E,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,gEAAgE,CAAC,CAAC;IAC7E,KAAK,CAAC,IAAI,CAAC,gEAAgE,CAAC,CAAC;IAC7E,KAAK,CAAC,IAAI,CAAC,gEAAgE,CAAC,CAAC;IAC7E,KAAK,CAAC,IAAI,CAAC,mCAAmC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;IACtF,KAAK,CAAC,IAAI,CACR,mCAAmC,MAAM,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,UAAU,CAC/F,CAAC;IACF,KAAK,CAAC,IAAI,CAAC,mCAAmC,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;IACjG,KAAK,CAAC,IAAI,CAAC,mCAAmC,GAAG,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;IAC7F,KAAK,CAAC,IAAI,CAAC,mCAAmC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;IACzF,KAAK,CAAC,IAAI,CACR,mCAAmC,CAAC,MAAM,CAAC,YAAY,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,CAC5F,CAAC;IACF,KAAK,CAAC,IAAI,CAAC,gEAAgE,CAAC,CAAC;IAC7E,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,SAAS,GAAG,CAAC,EAAU;IACrB,IAAI,EAAE,GAAG,IAAI;QAAE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC;IAC5C,OAAO,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;AACtC,CAAC;AAED,SAAS,KAAK,CAAC,EAAU;IACvB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAC3D,CAAC;AAeD,+DAA+D;AAC/D,MAAM,UAAU,mBAAmB,CAAC,CAAsB;IACxD,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,kEAAkE,CAAC,CAAC;IAC/E,KAAK,CAAC,IAAI,CAAC,gEAAgE,CAAC,CAAC;IAC7E,KAAK,CAAC,IAAI,CAAC,kEAAkE,CAAC,CAAC;IAC/E,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;IACxC,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;IACzC,KAAK,CAAC,IAAI,CAAC,2EAA2E,CAAC,CAAC;IACxF,KAAK,CAAC,IAAI,CAAC,2EAA2E,CAAC,CAAC;IACxF,KAAK,CAAC,IAAI,CAAC,2EAA2E,CAAC,CAAC;IACxF,iFAAiF;IACjF,MAAM,OAAO,GAAG,CAAC,KAAa,EAAE,EAAE,CAChC,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC;IACxE,4EAA4E;IAC5E,MAAM,KAAK,GAAG,CAAC,KAAa,EAAE,EAAE,CAC9B,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC;IACxE,KAAK,CAAC,IAAI,CACR,mCAAmC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,MAAM,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CACvK,CAAC;IACF,KAAK,CAAC,IAAI,CACR,mCAAmC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,MAAM,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CACzN,CAAC;IACF,KAAK,CAAC,IAAI,CACR,mCAAmC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,MAAM,OAAO,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAC1L,CAAC;IACF,KAAK,CAAC,IAAI,CACR,mCAAmC,CAAC,CAAC,CAAC,QAAQ,CAAC,YAAY,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,YAAY,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,iBAAiB,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CACvP,CAAC;IACF,KAAK,CAAC,IAAI,CAAC,2EAA2E,CAAC,CAAC;IACxF,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,KAAK,CAAC;IACxD,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,SAAS,CAAC;IACtD,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,GAAG,EAAE,EAAE,CAAC,CAAC;IAC9D,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,SAAS,CAAC,CAAC,wBAAwB;IAE7E,4EAA4E;IAC5E,MAAM,WAAW,GAAG,IAAI,WAAW,EAAE,CAAC;IACtC,MAAM,WAAW,CAAC,IAAI,EAAE,CAAC;IAEzB,IAAI,MAAc,CAAC;IACnB,IAAI,OAA2B,CAAC;IAChC,IAAI,SAA6B,CAAC;IAElC,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,WAAW,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC;QAC7D,MAAM,GAAG,KAAK,CAAC,WAAW,CAAC;QAC3B,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;QACxB,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC;IAC9B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CACX,wCAAwC,QAAQ,KAAK;YACnD,gEAAgE,QAAQ,KAAK;YAC7E,aAAa,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAClE,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,CAAC,KAAK,CAAC,+BAA+B,QAAQ,6BAA6B,CAAC,CAAC;QACpF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,uBAAuB,QAAQ,IAAI,KAAK,YAAY,IAAI,KAAK,KAAK,SAAS,CAAC,CAAC;IACzF,OAAO,CAAC,GAAG,CAAC,eAAe,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACvE,OAAO,CAAC,GAAG,CAAC,gBAAgB,OAAO,IAAI,oBAAoB,EAAE,CAAC,CAAC;IAC/D,IAAI,SAAS;QAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB,SAAS,EAAE,CAAC,CAAC;IAC1D,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtB,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC;YACnC,QAAQ;YACR,KAAK;YACL,MAAM;YACN,OAAO;YACP,SAAS;YACT,cAAc,EAAE,MAAM;YACtB,cAAc,EAAE,SAAS,QAAQ,IAAI,IAAI,CAAC,GAAG,EAAE,EAAE;YACjD,KAAK;SACN,CAAC,CAAC;QACH,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC;QACrC,OAAO;IACT,CAAC;IAED,uBAAuB;IACvB,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;IAC5B,OAAO,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAC;IAC5D,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;IAC5B,MAAM,QAAQ,GAAG,MAAM,eAAe,CAAC;QACrC,QAAQ;QACR,KAAK;QACL,MAAM;QACN,OAAO;QACP,SAAS;QACT,cAAc,EAAE,OAAO;QACvB,cAAc,EAAE,cAAc,QAAQ,IAAI,IAAI,CAAC,GAAG,EAAE,EAAE;QACtD,KAAK;KACN,CAAC,CAAC;IAEH,iFAAiF;IACjF,OAAO,CAAC,GAAG,CAAC,uCAAuC,CAAC,CAAC;IACrD,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC;IAElB,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;IAC5B,OAAO,CAAC,GAAG,CAAC,4CAA4C,CAAC,CAAC;IAC1D,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;IAE5B,+EAA+E;IAC/E,IAAI,QAAQ,KAAK,WAAW,EAAE,CAAC;QAC7B,MAAM,EAAE,qBAAqB,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;QAC9D,MAAM,qBAAqB,CAAC;YAC1B,MAAM;YACN,KAAK;YACL,MAAM,EAAE,iBAAiB,EAAE;YAC3B,cAAc,EAAE,MAAM;YACtB,OAAO;SACR,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QACnB,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;IACnC,CAAC;SAAM,CAAC;QACN,uEAAuE;QACvE,2EAA2E;QAC3E,OAAO,CAAC,GAAG,CAAC,uCAAuC,CAAC,CAAC;QACrD,MAAM,eAAe,CAAC;YACpB,QAAQ;YACR,KAAK;YACL,MAAM;YACN,OAAO;YACP,SAAS;YACT,cAAc,EAAE,MAAM;YACtB,cAAc,EAAE,cAAc,QAAQ,IAAI,IAAI,CAAC,GAAG,EAAE,EAAE;YACtD,KAAK,EAAE,CAAC;SACT,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IACrB,CAAC;IAED,MAAM,SAAS,GAAG,MAAM,eAAe,CAAC;QACtC,QAAQ;QACR,KAAK;QACL,MAAM;QACN,OAAO;QACP,SAAS;QACT,cAAc,EAAE,MAAM;QACtB,cAAc,EAAE,aAAa,QAAQ,IAAI,IAAI,CAAC,GAAG,EAAE,EAAE;QACrD,KAAK;KACN,CAAC,CAAC;IAEH,MAAM,eAAe,GACnB,QAAQ,CAAC,SAAS,GAAG,CAAC;QACpB,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,GAAG,SAAS,CAAC,SAAS,CAAC,GAAG,QAAQ,CAAC,SAAS,CAAC,GAAG,GAAG;QACzE,CAAC,CAAC,CAAC,CAAC;IACR,MAAM,qBAAqB,GACzB,QAAQ,CAAC,kBAAkB,GAAG,CAAC;QAC7B,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,kBAAkB,GAAG,QAAQ,CAAC,kBAAkB,CAAC;YAC3D,QAAQ,CAAC,kBAAkB,CAAC;YAC9B,GAAG;QACL,CAAC,CAAC,CAAC,CAAC;IACR,MAAM,oBAAoB,GACxB,QAAQ,CAAC,gBAAgB,GAAG,CAAC;QAC3B,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,gBAAgB,GAAG,SAAS,CAAC,gBAAgB,CAAC,GAAG,QAAQ,CAAC,gBAAgB,CAAC,GAAG,GAAG;QAC9F,CAAC,CAAC,CAAC,CAAC;IAER,MAAM,UAAU,GAAwB;QACtC,QAAQ;QACR,SAAS;QACT,eAAe;QACf,qBAAqB;QACrB,oBAAoB;QACpB,iBAAiB,EAAE,CAAC,SAAS,CAAC,YAAY,GAAG,QAAQ,CAAC,YAAY,CAAC,GAAG,GAAG;KAC1E,CAAC;IAEF,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,UAAU,CAAC,CAAC,CAAC;AAC/C,CAAC;AAED,2DAA2D;AAC3D,MAAM,WAAW,GACf,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,kBAAkB,CAAC;IAC7C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,kBAAkB,CAAC;IAC7C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,eAAe,CAAC,CAAC;AAE7C,IAAI,WAAW,EAAE,CAAC;IAChB,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;QACnB,OAAO,CAAC,KAAK,CAAC,mBAAmB,EAAE,GAAG,CAAC,CAAC;QACxC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -7,6 +7,15 @@ export interface MCPConnectResult {
7
7
  toolCount: number;
8
8
  tools: AgentTool[];
9
9
  error?: string;
10
+ /** True when the server returned 401/Unauthorized and an OAuth login is
11
+ * required before it can connect. The UI surfaces this as "requires login". */
12
+ requiresAuth?: boolean;
13
+ }
14
+ /** Outcome of an interactive remote-MCP OAuth login. */
15
+ export interface MCPLoginResult {
16
+ ok: boolean;
17
+ toolCount: number;
18
+ error?: string;
10
19
  }
11
20
  export declare class MCPClientManager {
12
21
  private servers;
@@ -23,6 +32,18 @@ export declare class MCPClientManager {
23
32
  * server before persisting it.
24
33
  */
25
34
  probe(config: MCPServerConfig): Promise<MCPConnectResult>;
35
+ /**
36
+ * Run the interactive OAuth login for one remote MCP server end-to-end:
37
+ * start a loopback callback server, let the SDK open the browser via
38
+ * `onAuthorizationUrl`, capture the redirect, exchange the code, then verify
39
+ * the authorized connection by listing tools. Tokens are persisted by the
40
+ * provider so later (non-interactive) connects succeed silently.
41
+ *
42
+ * `onAuthorizationUrl` is invoked with the authorize URL so the host can open
43
+ * it (the ezcoder-app broadcasts it to the webview, which opens the system
44
+ * browser; the CLI prints it). Never throws — returns `{ ok:false, error }`.
45
+ */
46
+ login(config: MCPServerConfig, onAuthorizationUrl: (url: string) => void, timeoutMs?: number): Promise<MCPLoginResult>;
26
47
  private connectServer;
27
48
  dispose(): Promise<void>;
28
49
  }
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/core/mcp/client.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAIhD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AASlD,8EAA8E;AAC9E,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,OAAO,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,OAAO,CAAyB;IAElC,UAAU,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAKlE;;;;OAIG;IACG,kBAAkB,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAsBjF;;;;OAIG;IACG,KAAK,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,gBAAgB,CAAC;YAmBjD,aAAa;IAsHrB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAU/B"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/core/mcp/client.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAKhD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAelD,8EAA8E;AAC9E,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,OAAO,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;oFACgF;IAChF,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,wDAAwD;AACxD,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,OAAO,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,OAAO,CAAyB;IAElC,UAAU,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAKlE;;;;OAIG;IACG,kBAAkB,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAuBjF;;;;OAIG;IACG,KAAK,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAoB/D;;;;;;;;;;OAUG;IACG,KAAK,CACT,MAAM,EAAE,eAAe,EACvB,kBAAkB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,EACzC,SAAS,SAAU,GAClB,OAAO,CAAC,cAAc,CAAC;YAwHZ,aAAa;IA+HrB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAU/B"}