context-lens 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/README.md +120 -25
  2. package/dist/cli-utils.d.ts +2 -1
  3. package/dist/cli-utils.d.ts.map +1 -1
  4. package/dist/cli-utils.js +40 -13
  5. package/dist/cli-utils.js.map +1 -1
  6. package/dist/cli.js +184 -68
  7. package/dist/cli.js.map +1 -1
  8. package/dist/core/conversation.d.ts +63 -0
  9. package/dist/core/conversation.d.ts.map +1 -0
  10. package/dist/core/conversation.js +305 -0
  11. package/dist/core/conversation.js.map +1 -0
  12. package/dist/core/health.d.ts +7 -0
  13. package/dist/core/health.d.ts.map +1 -0
  14. package/dist/core/health.js +311 -0
  15. package/dist/core/health.js.map +1 -0
  16. package/dist/core/models.d.ts +36 -0
  17. package/dist/core/models.d.ts.map +1 -0
  18. package/dist/core/models.js +111 -0
  19. package/dist/core/models.js.map +1 -0
  20. package/dist/core/parse.d.ts +17 -0
  21. package/dist/core/parse.d.ts.map +1 -0
  22. package/dist/core/parse.js +349 -0
  23. package/dist/core/parse.js.map +1 -0
  24. package/dist/core/routing.d.ts +47 -0
  25. package/dist/core/routing.d.ts.map +1 -0
  26. package/dist/core/routing.js +132 -0
  27. package/dist/core/routing.js.map +1 -0
  28. package/dist/core/security.d.ts +8 -0
  29. package/dist/core/security.d.ts.map +1 -0
  30. package/dist/core/security.js +222 -0
  31. package/dist/core/security.js.map +1 -0
  32. package/dist/core/source.d.ts +22 -0
  33. package/dist/core/source.d.ts.map +1 -0
  34. package/dist/core/source.js +56 -0
  35. package/dist/core/source.js.map +1 -0
  36. package/dist/core/tokens.d.ts +29 -0
  37. package/dist/core/tokens.d.ts.map +1 -0
  38. package/dist/core/tokens.js +163 -0
  39. package/dist/core/tokens.js.map +1 -0
  40. package/dist/core.d.ts +14 -22
  41. package/dist/core.d.ts.map +1 -1
  42. package/dist/core.js +14 -471
  43. package/dist/core.js.map +1 -1
  44. package/dist/http/headers.d.ts +25 -0
  45. package/dist/http/headers.d.ts.map +1 -0
  46. package/dist/http/headers.js +54 -0
  47. package/dist/http/headers.js.map +1 -0
  48. package/dist/lhar/composition.d.ts +12 -0
  49. package/dist/lhar/composition.d.ts.map +1 -0
  50. package/dist/lhar/composition.js +258 -0
  51. package/dist/lhar/composition.js.map +1 -0
  52. package/dist/lhar/export.d.ts +5 -0
  53. package/dist/lhar/export.d.ts.map +1 -0
  54. package/dist/lhar/export.js +59 -0
  55. package/dist/lhar/export.js.map +1 -0
  56. package/dist/lhar/record.d.ts +6 -0
  57. package/dist/lhar/record.d.ts.map +1 -0
  58. package/dist/lhar/record.js +216 -0
  59. package/dist/lhar/record.js.map +1 -0
  60. package/dist/lhar/response.d.ts +11 -0
  61. package/dist/lhar/response.d.ts.map +1 -0
  62. package/dist/lhar/response.js +132 -0
  63. package/dist/lhar/response.js.map +1 -0
  64. package/dist/lhar-types.generated.d.ts +24 -3
  65. package/dist/lhar-types.generated.d.ts.map +1 -1
  66. package/dist/lhar.d.ts +12 -19
  67. package/dist/lhar.d.ts.map +1 -1
  68. package/dist/lhar.js +16 -473
  69. package/dist/lhar.js.map +1 -1
  70. package/dist/server/api.d.ts +8 -0
  71. package/dist/server/api.d.ts.map +1 -0
  72. package/dist/server/api.js +292 -0
  73. package/dist/server/api.js.map +1 -0
  74. package/dist/server/config.d.ts +13 -0
  75. package/dist/server/config.d.ts.map +1 -0
  76. package/dist/server/config.js +36 -0
  77. package/dist/server/config.js.map +1 -0
  78. package/dist/server/projection.d.ts +9 -0
  79. package/dist/server/projection.d.ts.map +1 -0
  80. package/dist/server/projection.js +47 -0
  81. package/dist/server/projection.js.map +1 -0
  82. package/dist/server/proxy.d.ts +13 -0
  83. package/dist/server/proxy.d.ts.map +1 -0
  84. package/dist/server/proxy.js +218 -0
  85. package/dist/server/proxy.js.map +1 -0
  86. package/dist/server/static.d.ts +9 -0
  87. package/dist/server/static.d.ts.map +1 -0
  88. package/dist/server/static.js +78 -0
  89. package/dist/server/static.js.map +1 -0
  90. package/dist/server/store.d.ts +81 -0
  91. package/dist/server/store.d.ts.map +1 -0
  92. package/dist/server/store.js +632 -0
  93. package/dist/server/store.js.map +1 -0
  94. package/dist/server/webui.d.ts +5 -0
  95. package/dist/server/webui.d.ts.map +1 -0
  96. package/dist/server/webui.js +42 -0
  97. package/dist/server/webui.js.map +1 -0
  98. package/dist/server-utils.d.ts +2 -2
  99. package/dist/server-utils.d.ts.map +1 -1
  100. package/dist/server-utils.js +12 -21
  101. package/dist/server-utils.js.map +1 -1
  102. package/dist/server.js +31 -697
  103. package/dist/server.js.map +1 -1
  104. package/dist/types.d.ts +94 -10
  105. package/dist/types.d.ts.map +1 -1
  106. package/dist/version.generated.d.ts +2 -0
  107. package/dist/version.generated.d.ts.map +1 -0
  108. package/dist/version.generated.js +2 -0
  109. package/dist/version.generated.js.map +1 -0
  110. package/findings-screenshot.png +0 -0
  111. package/messages-screenshot.png +0 -0
  112. package/package.json +23 -10
  113. package/schema/lhar.schema.json +58 -4
  114. package/screenshot-overview.png +0 -0
  115. package/sessions-screenshot.png +0 -0
  116. package/timeline-screenshot.png +0 -0
  117. package/diff.png +0 -0
  118. package/overview-sidebar.png +0 -0
  119. package/public/index.html +0 -2804
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Known model context limits (tokens).
3
+ *
4
+ * Keys are ordered most-specific-first because `getContextLimit()` does substring matching.
5
+ */
6
+ export declare const CONTEXT_LIMITS: Record<string, number>;
7
+ /**
8
+ * Resolve an approximate context window size for a given model string.
9
+ *
10
+ * @param model - Model identifier (often includes version suffixes).
11
+ * @returns Context limit in tokens.
12
+ */
13
+ export declare function getContextLimit(model: string): number;
14
+ /**
15
+ * Model pricing: `[inputPerMTok, outputPerMTok]` in USD.
16
+ *
17
+ * Keys ordered most-specific-first to avoid substring false matches
18
+ * (e.g. `gpt-4o-mini` before `gpt-4o`).
19
+ */
20
+ export declare const MODEL_PRICING: Record<string, [number, number]>;
21
+ /**
22
+ * Estimate cost in USD for a request/response token pair using `MODEL_PRICING`.
23
+ *
24
+ * Cache pricing (Anthropic):
25
+ * - Cache reads: 10% of base input price (0.1x)
26
+ * - Cache writes: 25% of base input price (0.25x)
27
+ *
28
+ * @param model - Model identifier (substring matched against known keys).
29
+ * @param inputTokens - Input/prompt tokens (non-cached).
30
+ * @param outputTokens - Output/completion tokens.
31
+ * @param cacheReadTokens - Cache read tokens (charged at 10% for Anthropic).
32
+ * @param cacheWriteTokens - Cache write tokens (charged at 25% for Anthropic).
33
+ * @returns Cost in USD, rounded to 6 decimals; `null` if the model is unknown.
34
+ */
35
+ export declare function estimateCost(model: string, inputTokens: number, outputTokens: number, cacheReadTokens?: number, cacheWriteTokens?: number): number | null;
36
+ //# sourceMappingURL=models.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../../src/core/models.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAyBjD,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAKrD;AAED;;;;;GAKG;AACH,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CA4B1D,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EACpB,eAAe,SAAI,EACnB,gBAAgB,SAAI,GACnB,MAAM,GAAG,IAAI,CAqBf"}
@@ -0,0 +1,111 @@
1
+ /**
2
+ * Known model context limits (tokens).
3
+ *
4
+ * Keys are ordered most-specific-first because `getContextLimit()` does substring matching.
5
+ */
6
+ export const CONTEXT_LIMITS = {
7
+ // Anthropic
8
+ "claude-opus-4": 200000,
9
+ "claude-sonnet-4": 200000,
10
+ "claude-haiku-4": 200000,
11
+ "claude-3-5-sonnet": 200000,
12
+ "claude-3-5-haiku": 200000,
13
+ "claude-3-opus": 200000,
14
+ // OpenAI (specific before generic)
15
+ "gpt-4o-mini": 128000,
16
+ "gpt-4o": 128000,
17
+ "gpt-4-turbo": 128000,
18
+ "gpt-4": 8192,
19
+ "gpt-3.5-turbo": 16385,
20
+ "o4-mini": 200000,
21
+ "o3-mini": 200000,
22
+ o3: 200000,
23
+ "o1-mini": 128000,
24
+ o1: 200000,
25
+ // Gemini
26
+ "gemini-2.5-pro": 1048576,
27
+ "gemini-2.5-flash": 1048576,
28
+ "gemini-2.0-flash": 1048576,
29
+ "gemini-1.5-pro": 2097152,
30
+ "gemini-1.5-flash": 1048576,
31
+ };
32
+ /**
33
+ * Resolve an approximate context window size for a given model string.
34
+ *
35
+ * @param model - Model identifier (often includes version suffixes).
36
+ * @returns Context limit in tokens.
37
+ */
38
+ export function getContextLimit(model) {
39
+ for (const [key, limit] of Object.entries(CONTEXT_LIMITS)) {
40
+ if (model.includes(key))
41
+ return limit;
42
+ }
43
+ return 128000; // default fallback
44
+ }
45
+ /**
46
+ * Model pricing: `[inputPerMTok, outputPerMTok]` in USD.
47
+ *
48
+ * Keys ordered most-specific-first to avoid substring false matches
49
+ * (e.g. `gpt-4o-mini` before `gpt-4o`).
50
+ */
51
+ export const MODEL_PRICING = {
52
+ "claude-opus-4": [15, 75],
53
+ "claude-sonnet-4": [3, 15],
54
+ "claude-haiku-4": [0.8, 4],
55
+ "claude-3-5-sonnet": [3, 15],
56
+ "claude-3-5-haiku": [0.8, 4],
57
+ "claude-3-opus": [15, 75],
58
+ "gpt-4o-mini": [0.15, 0.6],
59
+ "gpt-4o": [2.5, 10],
60
+ "gpt-4-turbo": [10, 30],
61
+ "gpt-4": [30, 60],
62
+ "o4-mini": [1.1, 4.4],
63
+ "o3-mini": [1.1, 4.4],
64
+ o3: [10, 40],
65
+ "o1-mini": [3, 12],
66
+ o1: [15, 60],
67
+ // Codex (subscription estimate)
68
+ "gpt-5.3-codex": [1.75, 14],
69
+ "gpt-5.2-codex": [1.75, 14],
70
+ "gpt-5.1-codex-mini": [0.25, 2],
71
+ "gpt-5.1-codex": [1.25, 10],
72
+ "gpt-5-codex": [1.25, 10],
73
+ // Gemini
74
+ "gemini-2.5-pro": [1.25, 10],
75
+ "gemini-2.5-flash": [0.15, 0.6],
76
+ "gemini-2.0-flash": [0.1, 0.4],
77
+ "gemini-1.5-pro": [1.25, 5],
78
+ "gemini-1.5-flash": [0.075, 0.3],
79
+ };
80
+ /**
81
+ * Estimate cost in USD for a request/response token pair using `MODEL_PRICING`.
82
+ *
83
+ * Cache pricing (Anthropic):
84
+ * - Cache reads: 10% of base input price (0.1x)
85
+ * - Cache writes: 25% of base input price (0.25x)
86
+ *
87
+ * @param model - Model identifier (substring matched against known keys).
88
+ * @param inputTokens - Input/prompt tokens (non-cached).
89
+ * @param outputTokens - Output/completion tokens.
90
+ * @param cacheReadTokens - Cache read tokens (charged at 10% for Anthropic).
91
+ * @param cacheWriteTokens - Cache write tokens (charged at 25% for Anthropic).
92
+ * @returns Cost in USD, rounded to 6 decimals; `null` if the model is unknown.
93
+ */
94
+ export function estimateCost(model, inputTokens, outputTokens, cacheReadTokens = 0, cacheWriteTokens = 0) {
95
+ for (const [key, [inp, out]] of Object.entries(MODEL_PRICING)) {
96
+ if (model.includes(key)) {
97
+ // Anthropic models have cache pricing (10% for reads, 25% for writes)
98
+ const isClaude = key.startsWith("claude-");
99
+ const cacheReadCost = isClaude ? cacheReadTokens * inp * 0.1 : 0;
100
+ const cacheWriteCost = isClaude ? cacheWriteTokens * inp * 0.25 : 0;
101
+ return (Math.round(((inputTokens * inp +
102
+ outputTokens * out +
103
+ cacheReadCost +
104
+ cacheWriteCost) /
105
+ 1_000_000) *
106
+ 1_000_000) / 1_000_000);
107
+ }
108
+ }
109
+ return null;
110
+ }
111
+ //# sourceMappingURL=models.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"models.js","sourceRoot":"","sources":["../../src/core/models.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { ContextInfo } from "../types.js";
2
+ /**
3
+ * Parse a request body and extract normalized context information.
4
+ *
5
+ * This is the core "shape-normalizer" for Context Lens. It supports:
6
+ * - Anthropic Messages API
7
+ * - OpenAI Responses API and Chat Completions
8
+ * - ChatGPT backend schema (Codex subscription traffic)
9
+ * - Gemini (including Code Assist wrappers)
10
+ *
11
+ * @param provider - Provider inferred from routing (anthropic/openai/gemini/chatgpt/unknown).
12
+ * @param body - Parsed JSON request body.
13
+ * @param apiFormat - API schema family inferred from routing.
14
+ * @returns A `ContextInfo` with token estimates and normalized messages/blocks.
15
+ */
16
+ export declare function parseContextInfo(provider: string, body: Record<string, any>, apiFormat: string): ContextInfo;
17
+ //# sourceMappingURL=parse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../src/core/parse.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAgB,WAAW,EAAiB,MAAM,aAAa,CAAC;AA2J5E;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,SAAS,EAAE,MAAM,GAChB,WAAW,CAmMb"}
@@ -0,0 +1,349 @@
1
+ import { estimateTokens } from "./tokens.js";
2
+ /**
3
+ * Parse a single item from the OpenAI Responses API `input` array.
4
+ *
5
+ * Maps typed items (function_call, function_call_output, reasoning, output_text, etc.)
6
+ * to a normalized `ParsedMessage` with a stable `role` and optional `contentBlocks`.
7
+ */
8
+ function parseResponsesItem(item) {
9
+ const type = item.type || "";
10
+ // Standard message with role/content (e.g. {"type":"message","role":"user","content":[...]})
11
+ if (item.role) {
12
+ const isSystem = item.role === "system" || item.role === "developer";
13
+ let content;
14
+ let contentBlocks = null;
15
+ if (typeof item.content === "string") {
16
+ content = item.content;
17
+ }
18
+ else if (Array.isArray(item.content)) {
19
+ contentBlocks = item.content;
20
+ content = item.content.map((b) => b.text || "").join("\n");
21
+ }
22
+ else {
23
+ content = JSON.stringify(item.content || item);
24
+ }
25
+ const tokens = estimateTokens(item.content ?? content);
26
+ return {
27
+ message: { role: item.role, content, contentBlocks, tokens },
28
+ tokens,
29
+ isSystem,
30
+ content,
31
+ };
32
+ }
33
+ // function_call → assistant tool_use
34
+ if (type === "function_call" || type === "custom_tool_call") {
35
+ const name = item.name || "unknown";
36
+ const args = item.arguments || "";
37
+ const content = name +
38
+ "(" +
39
+ (typeof args === "string"
40
+ ? args.slice(0, 200)
41
+ : JSON.stringify(args).slice(0, 200)) +
42
+ ")";
43
+ const tokens = estimateTokens(item);
44
+ const block = {
45
+ type: "tool_use",
46
+ id: item.call_id || "",
47
+ name,
48
+ input: typeof args === "string" ? {} : args || {},
49
+ };
50
+ return {
51
+ message: { role: "assistant", content, contentBlocks: [block], tokens },
52
+ tokens,
53
+ isSystem: false,
54
+ content,
55
+ };
56
+ }
57
+ // function_call_output → user tool_result
58
+ if (type === "function_call_output" || type === "custom_tool_call_output") {
59
+ const output = typeof item.output === "string"
60
+ ? item.output
61
+ : JSON.stringify(item.output || "");
62
+ const tokens = estimateTokens(output);
63
+ const block = {
64
+ type: "tool_result",
65
+ tool_use_id: item.call_id || "",
66
+ content: output,
67
+ };
68
+ return {
69
+ message: {
70
+ role: "user",
71
+ content: output,
72
+ contentBlocks: [block],
73
+ tokens,
74
+ },
75
+ tokens,
76
+ isSystem: false,
77
+ content: output,
78
+ };
79
+ }
80
+ // reasoning → assistant thinking
81
+ if (type === "reasoning") {
82
+ const summary = Array.isArray(item.summary)
83
+ ? item.summary.map((s) => s.text || "").join("\n")
84
+ : "";
85
+ const content = summary || "[reasoning]";
86
+ const tokens = estimateTokens(item);
87
+ return {
88
+ message: {
89
+ role: "assistant",
90
+ content,
91
+ contentBlocks: [{ type: "thinking", thinking: content }],
92
+ tokens,
93
+ },
94
+ tokens,
95
+ isSystem: false,
96
+ content,
97
+ };
98
+ }
99
+ // output_text → assistant text
100
+ if (type === "output_text") {
101
+ const text = item.text || "";
102
+ const tokens = estimateTokens(text);
103
+ return {
104
+ message: {
105
+ role: "assistant",
106
+ content: text,
107
+ contentBlocks: [{ type: "text", text }],
108
+ tokens,
109
+ },
110
+ tokens,
111
+ isSystem: false,
112
+ content: text,
113
+ };
114
+ }
115
+ // input_text → user text
116
+ if (type === "input_text") {
117
+ const text = item.text || "";
118
+ const tokens = estimateTokens(text);
119
+ return {
120
+ message: {
121
+ role: "user",
122
+ content: text,
123
+ contentBlocks: [{ type: "text", text }],
124
+ tokens,
125
+ },
126
+ tokens,
127
+ isSystem: false,
128
+ content: text,
129
+ };
130
+ }
131
+ // Fallback: serialize the whole item
132
+ const content = JSON.stringify(item);
133
+ const tokens = estimateTokens(content);
134
+ return {
135
+ message: { role: item.role || "user", content, tokens },
136
+ tokens,
137
+ isSystem: false,
138
+ content,
139
+ };
140
+ }
141
+ /**
142
+ * Parse a request body and extract normalized context information.
143
+ *
144
+ * This is the core "shape-normalizer" for Context Lens. It supports:
145
+ * - Anthropic Messages API
146
+ * - OpenAI Responses API and Chat Completions
147
+ * - ChatGPT backend schema (Codex subscription traffic)
148
+ * - Gemini (including Code Assist wrappers)
149
+ *
150
+ * @param provider - Provider inferred from routing (anthropic/openai/gemini/chatgpt/unknown).
151
+ * @param body - Parsed JSON request body.
152
+ * @param apiFormat - API schema family inferred from routing.
153
+ * @returns A `ContextInfo` with token estimates and normalized messages/blocks.
154
+ */
155
+ export function parseContextInfo(provider, body, apiFormat) {
156
+ const info = {
157
+ provider,
158
+ apiFormat,
159
+ model: body.model || "unknown",
160
+ systemTokens: 0,
161
+ toolsTokens: 0,
162
+ messagesTokens: 0,
163
+ totalTokens: 0,
164
+ systemPrompts: [],
165
+ tools: [],
166
+ messages: [],
167
+ };
168
+ if (provider === "anthropic") {
169
+ if (body.system) {
170
+ const systemText = typeof body.system === "string"
171
+ ? body.system
172
+ : Array.isArray(body.system)
173
+ ? body.system.map((b) => b.text || "").join("\n")
174
+ : JSON.stringify(body.system);
175
+ info.systemPrompts.push({ content: systemText });
176
+ info.systemTokens = estimateTokens(systemText);
177
+ }
178
+ if (body.tools && Array.isArray(body.tools)) {
179
+ info.tools = body.tools;
180
+ info.toolsTokens = estimateTokens(JSON.stringify(body.tools));
181
+ }
182
+ if (body.messages && Array.isArray(body.messages)) {
183
+ info.messages = body.messages.map((msg) => {
184
+ const contentBlocks = Array.isArray(msg.content) ? msg.content : null;
185
+ return {
186
+ role: msg.role,
187
+ content: typeof msg.content === "string"
188
+ ? msg.content
189
+ : JSON.stringify(msg.content),
190
+ contentBlocks,
191
+ tokens: estimateTokens(msg.content),
192
+ };
193
+ });
194
+ info.messagesTokens = info.messages.reduce((sum, m) => sum + m.tokens, 0);
195
+ }
196
+ }
197
+ else if (apiFormat === "responses" || provider === "chatgpt") {
198
+ if (body.instructions) {
199
+ info.systemPrompts.push({ content: body.instructions });
200
+ info.systemTokens = estimateTokens(body.instructions);
201
+ }
202
+ if (body.system) {
203
+ const systemText = typeof body.system === "string"
204
+ ? body.system
205
+ : Array.isArray(body.system)
206
+ ? body.system.map((b) => b.text || "").join("\n")
207
+ : JSON.stringify(body.system);
208
+ info.systemPrompts.push({ content: systemText });
209
+ info.systemTokens += estimateTokens(systemText);
210
+ }
211
+ const msgs = body.input || body.messages;
212
+ if (msgs) {
213
+ if (typeof msgs === "string") {
214
+ info.messages.push({
215
+ role: "user",
216
+ content: msgs,
217
+ tokens: estimateTokens(msgs),
218
+ });
219
+ info.messagesTokens = estimateTokens(msgs);
220
+ }
221
+ else if (Array.isArray(msgs)) {
222
+ msgs.forEach((item) => {
223
+ const parsed = parseResponsesItem(item);
224
+ if (parsed.isSystem) {
225
+ info.systemPrompts.push({ content: parsed.content });
226
+ info.systemTokens += parsed.tokens;
227
+ }
228
+ else {
229
+ info.messages.push(parsed.message);
230
+ info.messagesTokens += parsed.tokens;
231
+ }
232
+ });
233
+ }
234
+ }
235
+ if (body.tools && Array.isArray(body.tools)) {
236
+ info.tools = body.tools;
237
+ info.toolsTokens = estimateTokens(JSON.stringify(body.tools));
238
+ }
239
+ }
240
+ else if (provider === "gemini" || apiFormat === "gemini") {
241
+ // Gemini API: contents[], systemInstruction, tools[{functionDeclarations}]
242
+ // Code Assist wraps everything inside body.request: {contents, systemInstruction, tools, ...}
243
+ const geminiBody = body.request || body;
244
+ if (geminiBody.systemInstruction) {
245
+ const parts = geminiBody.systemInstruction.parts || [];
246
+ const systemText = parts.map((p) => p.text || "").join("\n");
247
+ info.systemPrompts.push({ content: systemText });
248
+ info.systemTokens = estimateTokens(systemText);
249
+ }
250
+ if (geminiBody.tools && Array.isArray(geminiBody.tools)) {
251
+ const allDecls = geminiBody.tools.flatMap((t) => t.functionDeclarations || []);
252
+ info.tools = allDecls;
253
+ info.toolsTokens = estimateTokens(JSON.stringify(geminiBody.tools));
254
+ }
255
+ if (geminiBody.contents && Array.isArray(geminiBody.contents)) {
256
+ info.messages = geminiBody.contents.map((turn) => {
257
+ const role = turn.role || "user";
258
+ const parts = turn.parts || [];
259
+ const contentBlocks = [];
260
+ const textParts = [];
261
+ for (const part of parts) {
262
+ if (part.text) {
263
+ textParts.push(part.text);
264
+ contentBlocks.push({ type: "text", text: part.text });
265
+ }
266
+ else if (part.functionCall) {
267
+ contentBlocks.push({
268
+ type: "tool_use",
269
+ id: part.functionCall.id || "",
270
+ name: part.functionCall.name || "",
271
+ input: part.functionCall.args || {},
272
+ });
273
+ }
274
+ else if (part.functionResponse) {
275
+ const resp = part.functionResponse.response;
276
+ // Gemini CLI wraps tool output in {output: "..."} or {error: "..."}
277
+ const respText = typeof resp === "string"
278
+ ? resp
279
+ : typeof resp?.output === "string"
280
+ ? resp.output
281
+ : typeof resp?.error === "string"
282
+ ? resp.error
283
+ : JSON.stringify(resp || "");
284
+ contentBlocks.push({
285
+ type: "tool_result",
286
+ tool_use_id: part.functionResponse.id || "",
287
+ content: respText,
288
+ });
289
+ }
290
+ else if (part.inlineData) {
291
+ contentBlocks.push({ type: "image" });
292
+ }
293
+ else if (part.executableCode) {
294
+ contentBlocks.push({
295
+ type: "text",
296
+ text: part.executableCode.code || "",
297
+ });
298
+ }
299
+ else if (part.codeExecutionResult) {
300
+ contentBlocks.push({
301
+ type: "text",
302
+ text: part.codeExecutionResult.output || "",
303
+ });
304
+ }
305
+ }
306
+ const content = textParts.join("\n") || JSON.stringify(parts);
307
+ const tokens = estimateTokens(turn);
308
+ return {
309
+ role: role === "model" ? "assistant" : role,
310
+ content,
311
+ contentBlocks,
312
+ tokens,
313
+ };
314
+ });
315
+ info.messagesTokens = info.messages.reduce((sum, m) => sum + m.tokens, 0);
316
+ }
317
+ }
318
+ else if (provider === "openai") {
319
+ if (body.messages && Array.isArray(body.messages)) {
320
+ body.messages.forEach((msg) => {
321
+ if (msg.role === "system" || msg.role === "developer") {
322
+ info.systemPrompts.push({ content: msg.content });
323
+ info.systemTokens += estimateTokens(msg.content);
324
+ }
325
+ else {
326
+ info.messages.push({
327
+ role: msg.role,
328
+ content: typeof msg.content === "string"
329
+ ? msg.content
330
+ : JSON.stringify(msg.content),
331
+ tokens: estimateTokens(msg.content),
332
+ });
333
+ info.messagesTokens += estimateTokens(msg.content);
334
+ }
335
+ });
336
+ }
337
+ if (body.tools && Array.isArray(body.tools)) {
338
+ info.tools = body.tools;
339
+ info.toolsTokens = estimateTokens(JSON.stringify(body.tools));
340
+ }
341
+ else if (body.functions && Array.isArray(body.functions)) {
342
+ info.tools = body.functions;
343
+ info.toolsTokens = estimateTokens(JSON.stringify(body.functions));
344
+ }
345
+ }
346
+ info.totalTokens = info.systemTokens + info.toolsTokens + info.messagesTokens;
347
+ return info;
348
+ }
349
+ //# sourceMappingURL=parse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse.js","sourceRoot":"","sources":["../../src/core/parse.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C;;;;;GAKG;AACH,SAAS,kBAAkB,CAAC,IAAS;IAMnC,MAAM,IAAI,GAAW,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;IAErC,6FAA6F;IAC7F,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW,CAAC;QACrE,IAAI,OAAe,CAAC;QACpB,IAAI,aAAa,GAA0B,IAAI,CAAC;QAChD,IAAI,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;YACrC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;QACzB,CAAC;aAAM,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YACvC,aAAa,GAAG,IAAI,CAAC,OAAyB,CAAC;YAC/C,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClE,CAAC;aAAM,CAAC;YACN,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,CAAC;QACjD,CAAC;QACD,MAAM,MAAM,GAAG,cAAc,CAAC,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,CAAC;QACvD,OAAO;YACL,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE;YAC5D,MAAM;YACN,QAAQ;YACR,OAAO;SACR,CAAC;IACJ,CAAC;IAED,qCAAqC;IACrC,IAAI,IAAI,KAAK,eAAe,IAAI,IAAI,KAAK,kBAAkB,EAAE,CAAC;QAC5D,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,SAAS,CAAC;QACpC,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,IAAI,EAAE,CAAC;QAClC,MAAM,OAAO,GACX,IAAI;YACJ,GAAG;YACH,CAAC,OAAO,IAAI,KAAK,QAAQ;gBACvB,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC;gBACpB,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;YACvC,GAAG,CAAC;QACN,MAAM,MAAM,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;QACpC,MAAM,KAAK,GAAiB;YAC1B,IAAI,EAAE,UAAU;YAChB,EAAE,EAAE,IAAI,CAAC,OAAO,IAAI,EAAE;YACtB,IAAI;YACJ,KAAK,EAAE,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE;SAClD,CAAC;QACF,OAAO;YACL,OAAO,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,aAAa,EAAE,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE;YACvE,MAAM;YACN,QAAQ,EAAE,KAAK;YACf,OAAO;SACR,CAAC;IACJ,CAAC;IAED,0CAA0C;IAC1C,IAAI,IAAI,KAAK,sBAAsB,IAAI,IAAI,KAAK,yBAAyB,EAAE,CAAC;QAC1E,MAAM,MAAM,GACV,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ;YAC7B,CAAC,CAAC,IAAI,CAAC,MAAM;YACb,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC;QACxC,MAAM,MAAM,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;QACtC,MAAM,KAAK,GAAiB;YAC1B,IAAI,EAAE,aAAa;YACnB,WAAW,EAAE,IAAI,CAAC,OAAO,IAAI,EAAE;YAC/B,OAAO,EAAE,MAAM;SAChB,CAAC;QACF,OAAO;YACL,OAAO,EAAE;gBACP,IAAI,EAAE,MAAM;gBACZ,OAAO,EAAE,MAAM;gBACf,aAAa,EAAE,CAAC,KAAK,CAAC;gBACtB,MAAM;aACP;YACD,MAAM;YACN,QAAQ,EAAE,KAAK;YACf,OAAO,EAAE,MAAM;SAChB,CAAC;IACJ,CAAC;IAED,iCAAiC;IACjC,IAAI,IAAI,KAAK,WAAW,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC;YACzC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;YACvD,CAAC,CAAC,EAAE,CAAC;QACP,MAAM,OAAO,GAAG,OAAO,IAAI,aAAa,CAAC;QACzC,MAAM,MAAM,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;QACpC,OAAO;YACL,OAAO,EAAE;gBACP,IAAI,EAAE,WAAW;gBACjB,OAAO;gBACP,aAAa,EAAE,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAS,CAAC;gBAC/D,MAAM;aACP;YACD,MAAM;YACN,QAAQ,EAAE,KAAK;YACf,OAAO;SACR,CAAC;IACJ,CAAC;IAED,+BAA+B;IAC/B,IAAI,IAAI,KAAK,aAAa,EAAE,CAAC;QAC3B,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;QAC7B,MAAM,MAAM,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;QACpC,OAAO;YACL,OAAO,EAAE;gBACP,IAAI,EAAE,WAAW;gBACjB,OAAO,EAAE,IAAI;gBACb,aAAa,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;gBACvC,MAAM;aACP;YACD,MAAM;YACN,QAAQ,EAAE,KAAK;YACf,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;IAED,yBAAyB;IACzB,IAAI,IAAI,KAAK,YAAY,EAAE,CAAC;QAC1B,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;QAC7B,MAAM,MAAM,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;QACpC,OAAO;YACL,OAAO,EAAE;gBACP,IAAI,EAAE,MAAM;gBACZ,OAAO,EAAE,IAAI;gBACb,aAAa,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;gBACvC,MAAM;aACP;YACD,MAAM;YACN,QAAQ,EAAE,KAAK;YACf,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;IAED,qCAAqC;IACrC,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACrC,MAAM,MAAM,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;IACvC,OAAO;QACL,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE;QACvD,MAAM;QACN,QAAQ,EAAE,KAAK;QACf,OAAO;KACR,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,gBAAgB,CAC9B,QAAgB,EAChB,IAAyB,EACzB,SAAiB;IAEjB,MAAM,IAAI,GAAgB;QACxB,QAAQ;QACR,SAAS;QACT,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,SAAS;QAC9B,YAAY,EAAE,CAAC;QACf,WAAW,EAAE,CAAC;QACd,cAAc,EAAE,CAAC;QACjB,WAAW,EAAE,CAAC;QACd,aAAa,EAAE,EAAE;QACjB,KAAK,EAAE,EAAE;QACT,QAAQ,EAAE,EAAE;KACb,CAAC;IAEF,IAAI,QAAQ,KAAK,WAAW,EAAE,CAAC;QAC7B,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,MAAM,UAAU,GACd,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ;gBAC7B,CAAC,CAAC,IAAI,CAAC,MAAM;gBACb,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC;oBAC1B,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;oBACtD,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACpC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC;YACjD,IAAI,CAAC,YAAY,GAAG,cAAc,CAAC,UAAU,CAAC,CAAC;QACjD,CAAC;QAED,IAAI,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YAC5C,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;YACxB,IAAI,CAAC,WAAW,GAAG,cAAc,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QAChE,CAAC;QAED,IAAI,IAAI,CAAC,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;YAClD,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,GAAQ,EAAiB,EAAE;gBAC5D,MAAM,aAAa,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;gBACtE,OAAO;oBACL,IAAI,EAAE,GAAG,CAAC,IAAI;oBACd,OAAO,EACL,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ;wBAC7B,CAAC,CAAC,GAAG,CAAC,OAAO;wBACb,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC;oBACjC,aAAa;oBACb,MAAM,EAAE,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC;iBACpC,CAAC;YACJ,CAAC,CAAC,CAAC;YACH,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAC5E,CAAC;IACH,CAAC;SAAM,IAAI,SAAS,KAAK,WAAW,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC/D,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC;YACxD,IAAI,CAAC,YAAY,GAAG,cAAc,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACxD,CAAC;QACD,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,MAAM,UAAU,GACd,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ;gBAC7B,CAAC,CAAC,IAAI,CAAC,MAAM;gBACb,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC;oBAC1B,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;oBACtD,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACpC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC;YACjD,IAAI,CAAC,YAAY,IAAI,cAAc,CAAC,UAAU,CAAC,CAAC;QAClD,CAAC;QAED,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC;QACzC,IAAI,IAAI,EAAE,CAAC;YACT,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAC7B,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;oBACjB,IAAI,EAAE,MAAM;oBACZ,OAAO,EAAE,IAAI;oBACb,MAAM,EAAE,cAAc,CAAC,IAAI,CAAC;iBAC7B,CAAC,CAAC;gBACH,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;YAC7C,CAAC;iBAAM,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC/B,IAAI,CAAC,OAAO,CAAC,CAAC,IAAS,EAAE,EAAE;oBACzB,MAAM,MAAM,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC;oBACxC,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;wBACpB,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;wBACrD,IAAI,CAAC,YAAY,IAAI,MAAM,CAAC,MAAM,CAAC;oBACrC,CAAC;yBAAM,CAAC;wBACN,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;wBACnC,IAAI,CAAC,cAAc,IAAI,MAAM,CAAC,MAAM,CAAC;oBACvC,CAAC;gBACH,CAAC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,IAAI,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YAC5C,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;YACxB,IAAI,CAAC,WAAW,GAAG,cAAc,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QAChE,CAAC;IACH,CAAC;SAAM,IAAI,QAAQ,KAAK,QAAQ,IAAI,SAAS,KAAK,QAAQ,EAAE,CAAC;QAC3D,2EAA2E;QAC3E,8FAA8F;QAC9F,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC;QACxC,IAAI,UAAU,CAAC,iBAAiB,EAAE,CAAC;YACjC,MAAM,KAAK,GAAG,UAAU,CAAC,iBAAiB,CAAC,KAAK,IAAI,EAAE,CAAC;YACvD,MAAM,UAAU,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAClE,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC;YACjD,IAAI,CAAC,YAAY,GAAG,cAAc,CAAC,UAAU,CAAC,CAAC;QACjD,CAAC;QACD,IAAI,UAAU,CAAC,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;YACxD,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC,OAAO,CACvC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,oBAAoB,IAAI,EAAE,CACzC,CAAC;YACF,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAC;YACtB,IAAI,CAAC,WAAW,GAAG,cAAc,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;QACtE,CAAC;QACD,IAAI,UAAU,CAAC,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC9D,IAAI,CAAC,QAAQ,GAAG,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAS,EAAiB,EAAE;gBACnE,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,MAAM,CAAC;gBACjC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;gBAC/B,MAAM,aAAa,GAAmB,EAAE,CAAC;gBACzC,MAAM,SAAS,GAAa,EAAE,CAAC;gBAC/B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;oBACzB,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;wBACd,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;wBAC1B,aAAa,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;oBACxD,CAAC;yBAAM,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;wBAC7B,aAAa,CAAC,IAAI,CAAC;4BACjB,IAAI,EAAE,UAAU;4BAChB,EAAE,EAAE,IAAI,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE;4BAC9B,IAAI,EAAE,IAAI,CAAC,YAAY,CAAC,IAAI,IAAI,EAAE;4BAClC,KAAK,EAAE,IAAI,CAAC,YAAY,CAAC,IAAI,IAAI,EAAE;yBACpC,CAAC,CAAC;oBACL,CAAC;yBAAM,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;wBACjC,MAAM,IAAI,GAAG,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC;wBAC5C,oEAAoE;wBACpE,MAAM,QAAQ,GACZ,OAAO,IAAI,KAAK,QAAQ;4BACtB,CAAC,CAAC,IAAI;4BACN,CAAC,CAAC,OAAO,IAAI,EAAE,MAAM,KAAK,QAAQ;gCAChC,CAAC,CAAC,IAAI,CAAC,MAAM;gCACb,CAAC,CAAC,OAAO,IAAI,EAAE,KAAK,KAAK,QAAQ;oCAC/B,CAAC,CAAC,IAAI,CAAC,KAAK;oCACZ,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;wBACrC,aAAa,CAAC,IAAI,CAAC;4BACjB,IAAI,EAAE,aAAa;4BACnB,WAAW,EAAE,IAAI,CAAC,gBAAgB,CAAC,EAAE,IAAI,EAAE;4BAC3C,OAAO,EAAE,QAAQ;yBAClB,CAAC,CAAC;oBACL,CAAC;yBAAM,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;wBAC3B,aAAa,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;oBACxC,CAAC;yBAAM,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;wBAC/B,aAAa,CAAC,IAAI,CAAC;4BACjB,IAAI,EAAE,MAAM;4BACZ,IAAI,EAAE,IAAI,CAAC,cAAc,CAAC,IAAI,IAAI,EAAE;yBACrC,CAAC,CAAC;oBACL,CAAC;yBAAM,IAAI,IAAI,CAAC,mBAAmB,EAAE,CAAC;wBACpC,aAAa,CAAC,IAAI,CAAC;4BACjB,IAAI,EAAE,MAAM;4BACZ,IAAI,EAAE,IAAI,CAAC,mBAAmB,CAAC,MAAM,IAAI,EAAE;yBAC5C,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC;gBACD,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;gBAC9D,MAAM,MAAM,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;gBACpC,OAAO;oBACL,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI;oBAC3C,OAAO;oBACP,aAAa;oBACb,MAAM;iBACP,CAAC;YACJ,CAAC,CAAC,CAAC;YACH,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAC5E,CAAC;IACH,CAAC;SAAM,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACjC,IAAI,IAAI,CAAC,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;YAClD,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,GAAQ,EAAE,EAAE;gBACjC,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ,IAAI,GAAG,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;oBACtD,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;oBAClD,IAAI,CAAC,YAAY,IAAI,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;gBACnD,CAAC;qBAAM,CAAC;oBACN,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;wBACjB,IAAI,EAAE,GAAG,CAAC,IAAI;wBACd,OAAO,EACL,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ;4BAC7B,CAAC,CAAC,GAAG,CAAC,OAAO;4BACb,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC;wBACjC,MAAM,EAAE,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC;qBACpC,CAAC,CAAC;oBACH,IAAI,CAAC,cAAc,IAAI,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;gBACrD,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC;QAED,IAAI,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YAC5C,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;YACxB,IAAI,CAAC,WAAW,GAAG,cAAc,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QAChE,CAAC;aAAM,IAAI,IAAI,CAAC,SAAS,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;YAC3D,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC;YAC5B,IAAI,CAAC,WAAW,GAAG,cAAc,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;QACpE,CAAC;IACH,CAAC;IAED,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,cAAc,CAAC;IAC9E,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,47 @@
1
+ import type { ApiFormat, ExtractSourceResult, ParsedUrl, Provider, ResolveTargetResult, Upstreams } from "../types.js";
2
+ /**
3
+ * URL path segments that represent API resources rather than "source tool" prefixes.
4
+ *
5
+ * Example: `/v1/messages` should not treat `v1` as a source tag.
6
+ */
7
+ export declare const API_PATH_SEGMENTS: Set<string>;
8
+ /**
9
+ * Infer provider based on request path + headers.
10
+ *
11
+ * This is used for routing (choosing which upstream base URL to use) and parsing.
12
+ */
13
+ export declare function detectProvider(pathname: string, headers: Record<string, string | undefined>): Provider;
14
+ /**
15
+ * Infer the API "format" (schema family) from the request path.
16
+ *
17
+ * This is distinct from provider: e.g. OpenAI can be `responses` or `chat-completions`.
18
+ */
19
+ export declare function detectApiFormat(pathname: string): ApiFormat;
20
+ /**
21
+ * Classify an incoming request into `{ provider, apiFormat }`.
22
+ *
23
+ * Keep all path/format heuristics in one place to avoid drift between
24
+ * routing decisions and parsing decisions.
25
+ */
26
+ export declare function classifyRequest(pathname: string, headers: Record<string, string | undefined>): {
27
+ provider: Provider;
28
+ apiFormat: ApiFormat;
29
+ };
30
+ /**
31
+ * Extract a "source tool" tag from a request path.
32
+ *
33
+ * Example: `/claude/v1/messages` => `{ source: 'claude', cleanPath: '/v1/messages' }`.
34
+ *
35
+ * This tag is used for attribution in the UI/LHAR and for per-tool grouping.
36
+ */
37
+ export declare function extractSource(pathname: string): ExtractSourceResult;
38
+ /**
39
+ * Determine the final upstream target URL for a request.
40
+ *
41
+ * @param parsedUrl - Path + query extracted from the incoming request.
42
+ * @param headers - Headers used for detection and optional override.
43
+ * @param upstreams - Base URLs for each provider.
44
+ * @returns `{ targetUrl, provider }`.
45
+ */
46
+ export declare function resolveTargetUrl(parsedUrl: ParsedUrl, headers: Record<string, string | undefined>, upstreams: Upstreams): ResolveTargetResult;
47
+ //# sourceMappingURL=routing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routing.d.ts","sourceRoot":"","sources":["../../src/core/routing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,SAAS,EACT,mBAAmB,EACnB,SAAS,EACT,QAAQ,EACR,mBAAmB,EACnB,SAAS,EACV,MAAM,aAAa,CAAC;AAErB;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,aAW5B,CAAC;AAEH;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAC1C,QAAQ,CAEV;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAE3D;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAC1C;IAAE,QAAQ,EAAE,QAAQ,CAAC;IAAC,SAAS,EAAE,SAAS,CAAA;CAAE,CAiC9C;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,mBAAmB,CAqBnE;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,EAC3C,SAAS,EAAE,SAAS,GACnB,mBAAmB,CAsBrB"}