context-lens 0.3.2 → 0.4.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 (126) hide show
  1. package/README.md +52 -16
  2. package/dist/analysis/ingest.d.ts +13 -0
  3. package/dist/analysis/ingest.d.ts.map +1 -0
  4. package/dist/analysis/ingest.js +75 -0
  5. package/dist/analysis/ingest.js.map +1 -0
  6. package/dist/analysis/server.d.ts +10 -0
  7. package/dist/analysis/server.d.ts.map +1 -0
  8. package/dist/analysis/server.js +95 -0
  9. package/dist/analysis/server.js.map +1 -0
  10. package/dist/analysis/watcher.d.ts +55 -0
  11. package/dist/analysis/watcher.d.ts.map +1 -0
  12. package/dist/analysis/watcher.js +170 -0
  13. package/dist/analysis/watcher.js.map +1 -0
  14. package/dist/cli-utils.d.ts +16 -0
  15. package/dist/cli-utils.d.ts.map +1 -1
  16. package/dist/cli-utils.js +185 -3
  17. package/dist/cli-utils.js.map +1 -1
  18. package/dist/cli.js +629 -88
  19. package/dist/cli.js.map +1 -1
  20. package/dist/core/conversation.d.ts +8 -1
  21. package/dist/core/conversation.d.ts.map +1 -1
  22. package/dist/core/conversation.js +38 -12
  23. package/dist/core/conversation.js.map +1 -1
  24. package/dist/core/parse.d.ts.map +1 -1
  25. package/dist/core/parse.js +17 -1
  26. package/dist/core/parse.js.map +1 -1
  27. package/dist/core/session-analysis.d.ts +100 -0
  28. package/dist/core/session-analysis.d.ts.map +1 -0
  29. package/dist/core/session-analysis.js +435 -0
  30. package/dist/core/session-analysis.js.map +1 -0
  31. package/dist/core/session-format.d.ts +20 -0
  32. package/dist/core/session-format.d.ts.map +1 -0
  33. package/dist/core/session-format.js +298 -0
  34. package/dist/core/session-format.js.map +1 -0
  35. package/dist/core.d.ts +4 -0
  36. package/dist/core.d.ts.map +1 -1
  37. package/dist/core.js +2 -0
  38. package/dist/core.js.map +1 -1
  39. package/dist/lhar/reader.d.ts +22 -0
  40. package/dist/lhar/reader.d.ts.map +1 -0
  41. package/dist/lhar/reader.js +43 -0
  42. package/dist/lhar/reader.js.map +1 -0
  43. package/dist/lhar/record.d.ts.map +1 -1
  44. package/dist/lhar/record.js +3 -0
  45. package/dist/lhar/record.js.map +1 -1
  46. package/dist/lhar/response.d.ts +8 -0
  47. package/dist/lhar/response.d.ts.map +1 -1
  48. package/dist/lhar/response.js +44 -0
  49. package/dist/lhar/response.js.map +1 -1
  50. package/dist/lhar/tools.d.ts +17 -0
  51. package/dist/lhar/tools.d.ts.map +1 -0
  52. package/dist/lhar/tools.js +48 -0
  53. package/dist/lhar/tools.js.map +1 -0
  54. package/dist/lhar-types.generated.d.ts +34 -0
  55. package/dist/lhar-types.generated.d.ts.map +1 -1
  56. package/dist/lhar.d.ts +4 -1
  57. package/dist/lhar.d.ts.map +1 -1
  58. package/dist/lhar.js +5 -1
  59. package/dist/lhar.js.map +1 -1
  60. package/dist/proxy/capture.d.ts +40 -0
  61. package/dist/proxy/capture.d.ts.map +1 -0
  62. package/dist/proxy/capture.js +56 -0
  63. package/dist/proxy/capture.js.map +1 -0
  64. package/dist/proxy/config.d.ts +16 -0
  65. package/dist/proxy/config.d.ts.map +1 -0
  66. package/dist/proxy/config.js +34 -0
  67. package/dist/proxy/config.js.map +1 -0
  68. package/dist/proxy/forward.d.ts +20 -0
  69. package/dist/proxy/forward.d.ts.map +1 -0
  70. package/dist/proxy/forward.js +210 -0
  71. package/dist/proxy/forward.js.map +1 -0
  72. package/dist/proxy/headers.d.ts +16 -0
  73. package/dist/proxy/headers.d.ts.map +1 -0
  74. package/dist/proxy/headers.js +37 -0
  75. package/dist/proxy/headers.js.map +1 -0
  76. package/dist/proxy/routing.d.ts +44 -0
  77. package/dist/proxy/routing.d.ts.map +1 -0
  78. package/dist/proxy/routing.js +114 -0
  79. package/dist/proxy/routing.js.map +1 -0
  80. package/dist/proxy/server.d.ts +27 -0
  81. package/dist/proxy/server.d.ts.map +1 -0
  82. package/dist/proxy/server.js +55 -0
  83. package/dist/proxy/server.js.map +1 -0
  84. package/dist/schemas.d.ts +328 -0
  85. package/dist/schemas.d.ts.map +1 -0
  86. package/dist/schemas.js +249 -0
  87. package/dist/schemas.js.map +1 -0
  88. package/dist/server/api.d.ts +3 -4
  89. package/dist/server/api.d.ts.map +1 -1
  90. package/dist/server/api.js +195 -220
  91. package/dist/server/api.js.map +1 -1
  92. package/dist/server/store.d.ts +23 -7
  93. package/dist/server/store.d.ts.map +1 -1
  94. package/dist/server/store.js +141 -50
  95. package/dist/server/store.js.map +1 -1
  96. package/dist/server/webui.d.ts +5 -2
  97. package/dist/server/webui.d.ts.map +1 -1
  98. package/dist/server/webui.js +32 -13
  99. package/dist/server/webui.js.map +1 -1
  100. package/dist/server-utils.d.ts +1 -2
  101. package/dist/server-utils.d.ts.map +1 -1
  102. package/dist/server-utils.js +0 -2
  103. package/dist/server-utils.js.map +1 -1
  104. package/dist/types.d.ts +1 -1
  105. package/dist/types.d.ts.map +1 -1
  106. package/dist/version.generated.d.ts +1 -1
  107. package/dist/version.generated.js +1 -1
  108. package/mitm_addon.py +99 -28
  109. package/package.json +12 -5
  110. package/schema/lhar.schema.json +50 -0
  111. package/dist/server/config.d.ts +0 -13
  112. package/dist/server/config.d.ts.map +0 -1
  113. package/dist/server/config.js +0 -36
  114. package/dist/server/config.js.map +0 -1
  115. package/dist/server/proxy.d.ts +0 -13
  116. package/dist/server/proxy.d.ts.map +0 -1
  117. package/dist/server/proxy.js +0 -218
  118. package/dist/server/proxy.js.map +0 -1
  119. package/dist/server/static.d.ts +0 -9
  120. package/dist/server/static.d.ts.map +0 -1
  121. package/dist/server/static.js +0 -78
  122. package/dist/server/static.js.map +0 -1
  123. package/dist/server.d.ts +0 -3
  124. package/dist/server.d.ts.map +0 -1
  125. package/dist/server.js +0 -43
  126. package/dist/server.js.map +0 -1
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Request routing for the proxy.
3
+ *
4
+ * Detects which LLM provider a request targets, extracts source tool tags,
5
+ * and resolves the upstream URL. Zero external dependencies.
6
+ */
7
+ export type Provider = "anthropic" | "openai" | "chatgpt" | "gemini" | "unknown";
8
+ export type ApiFormat = "anthropic-messages" | "chatgpt-backend" | "responses" | "chat-completions" | "gemini" | "raw" | "unknown";
9
+ export interface Upstreams {
10
+ openai: string;
11
+ anthropic: string;
12
+ chatgpt: string;
13
+ gemini: string;
14
+ geminiCodeAssist: string;
15
+ }
16
+ export interface ExtractSourceResult {
17
+ source: string | null;
18
+ cleanPath: string;
19
+ }
20
+ export interface ResolveTargetResult {
21
+ targetUrl: string;
22
+ provider: Provider;
23
+ }
24
+ /**
25
+ * Classify an incoming request into `{ provider, apiFormat }`.
26
+ *
27
+ * All path/format heuristics live here to avoid drift between
28
+ * routing and detection.
29
+ */
30
+ export declare function classifyRequest(pathname: string, headers: Record<string, string | undefined>): {
31
+ provider: Provider;
32
+ apiFormat: ApiFormat;
33
+ };
34
+ /**
35
+ * Extract a "source tool" tag from a request path.
36
+ *
37
+ * Example: `/claude/v1/messages` => `{ source: 'claude', cleanPath: '/v1/messages' }`.
38
+ */
39
+ export declare function extractSource(pathname: string): ExtractSourceResult;
40
+ /**
41
+ * Determine the final upstream target URL for a request.
42
+ */
43
+ export declare function resolveTargetUrl(pathname: string, search: string | null, headers: Record<string, string | undefined>, upstreams: Upstreams): ResolveTargetResult;
44
+ //# sourceMappingURL=routing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routing.d.ts","sourceRoot":"","sources":["../../src/proxy/routing.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,MAAM,MAAM,QAAQ,GAChB,WAAW,GACX,QAAQ,GACR,SAAS,GACT,QAAQ,GACR,SAAS,CAAC;AAEd,MAAM,MAAM,SAAS,GACjB,oBAAoB,GACpB,iBAAiB,GACjB,WAAW,GACX,kBAAkB,GAClB,QAAQ,GACR,KAAK,GACL,SAAS,CAAC;AAEd,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,QAAQ,CAAC;CACpB;AAsBD;;;;;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;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,mBAAmB,CAmBnE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,GAAG,IAAI,EACrB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,EAC3C,SAAS,EAAE,SAAS,GACnB,mBAAmB,CAsBrB"}
@@ -0,0 +1,114 @@
1
+ /**
2
+ * Request routing for the proxy.
3
+ *
4
+ * Detects which LLM provider a request targets, extracts source tool tags,
5
+ * and resolves the upstream URL. Zero external dependencies.
6
+ */
7
+ // --- Implementation ---
8
+ /**
9
+ * URL path segments that represent API resources rather than "source tool" prefixes.
10
+ *
11
+ * Example: `/v1/messages` should not treat `v1` as a source tag.
12
+ */
13
+ const API_PATH_SEGMENTS = new Set([
14
+ "v1",
15
+ "v1beta",
16
+ "v1alpha",
17
+ "v1internal",
18
+ "responses",
19
+ "chat",
20
+ "models",
21
+ "embeddings",
22
+ "backend-api",
23
+ "api",
24
+ ]);
25
+ /**
26
+ * Classify an incoming request into `{ provider, apiFormat }`.
27
+ *
28
+ * All path/format heuristics live here to avoid drift between
29
+ * routing and detection.
30
+ */
31
+ export function classifyRequest(pathname, headers) {
32
+ // ChatGPT backend traffic (Codex subscription)
33
+ if (pathname.match(/^\/(api|backend-api)\//))
34
+ return { provider: "chatgpt", apiFormat: "chatgpt-backend" };
35
+ // Anthropic Messages API
36
+ if (pathname.includes("/v1/messages"))
37
+ return { provider: "anthropic", apiFormat: "anthropic-messages" };
38
+ if (pathname.includes("/v1/complete"))
39
+ return { provider: "anthropic", apiFormat: "unknown" };
40
+ if (headers["anthropic-version"])
41
+ return { provider: "anthropic", apiFormat: "unknown" };
42
+ // Gemini: must come BEFORE openai catch-all (which matches /models/)
43
+ const isGeminiPath = pathname.includes(":generateContent") ||
44
+ pathname.includes(":streamGenerateContent") ||
45
+ pathname.match(/\/v1(beta|alpha)\/models\//) ||
46
+ pathname.includes("/v1internal:");
47
+ if (isGeminiPath || headers["x-goog-api-key"])
48
+ return { provider: "gemini", apiFormat: "gemini" };
49
+ // OpenAI
50
+ if (pathname.includes("/responses"))
51
+ return { provider: "openai", apiFormat: "responses" };
52
+ if (pathname.includes("/chat/completions"))
53
+ return { provider: "openai", apiFormat: "chat-completions" };
54
+ if (pathname.match(/\/(models|embeddings)/))
55
+ return { provider: "openai", apiFormat: "unknown" };
56
+ if (headers.authorization?.startsWith("Bearer sk-"))
57
+ return { provider: "openai", apiFormat: "unknown" };
58
+ return { provider: "unknown", apiFormat: "unknown" };
59
+ }
60
+ /**
61
+ * Extract a "source tool" tag from a request path.
62
+ *
63
+ * Example: `/claude/v1/messages` => `{ source: 'claude', cleanPath: '/v1/messages' }`.
64
+ */
65
+ export function extractSource(pathname) {
66
+ const match = pathname.match(/^\/([^/]+)(\/.*)?$/);
67
+ if (match?.[2] && !API_PATH_SEGMENTS.has(match[1])) {
68
+ let decoded = match[1];
69
+ try {
70
+ decoded = decodeURIComponent(match[1]);
71
+ }
72
+ catch {
73
+ decoded = match[1];
74
+ }
75
+ if (decoded.includes("/") ||
76
+ decoded.includes("\\") ||
77
+ decoded.includes("..")) {
78
+ return { source: null, cleanPath: pathname };
79
+ }
80
+ return { source: decoded, cleanPath: match[2] || "/" };
81
+ }
82
+ return { source: null, cleanPath: pathname };
83
+ }
84
+ /**
85
+ * Determine the final upstream target URL for a request.
86
+ */
87
+ export function resolveTargetUrl(pathname, search, headers, upstreams) {
88
+ const provider = classifyRequest(pathname, headers).provider;
89
+ const qs = search || "";
90
+ let targetUrl = headers["x-target-url"];
91
+ if (!targetUrl) {
92
+ if (provider === "chatgpt") {
93
+ targetUrl = upstreams.chatgpt + pathname + qs;
94
+ }
95
+ else if (provider === "anthropic") {
96
+ targetUrl = upstreams.anthropic + pathname + qs;
97
+ }
98
+ else if (provider === "gemini") {
99
+ const isCodeAssist = pathname.includes("/v1internal");
100
+ targetUrl =
101
+ (isCodeAssist ? upstreams.geminiCodeAssist : upstreams.gemini) +
102
+ pathname +
103
+ qs;
104
+ }
105
+ else {
106
+ targetUrl = upstreams.openai + pathname + qs;
107
+ }
108
+ }
109
+ else if (!targetUrl.startsWith("http")) {
110
+ targetUrl = targetUrl + pathname + qs;
111
+ }
112
+ return { targetUrl, provider };
113
+ }
114
+ //# sourceMappingURL=routing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routing.js","sourceRoot":"","sources":["../../src/proxy/routing.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Context Lens Proxy — standalone entry point.
4
+ *
5
+ * A minimal HTTP proxy that forwards LLM API requests to their upstream
6
+ * providers and writes raw captures to disk for analysis.
7
+ *
8
+ * ZERO DEPENDENCIES CONSTRAINT
9
+ * ============================
10
+ * This proxy (everything under src/proxy/) must stay zero external
11
+ * dependencies. Only Node.js built-in modules (node:http, node:https,
12
+ * node:fs, node:path, node:os, node:url) are allowed. No npm packages.
13
+ *
14
+ * Why: users route their API keys through this proxy. Keeping the code
15
+ * small and dependency-free means the entire proxy can be audited by
16
+ * reading a single directory. No transitive supply-chain risk.
17
+ *
18
+ * The analysis server, CLI, and web UI are separate processes that
19
+ * communicate via capture files on disk, and those are free to use
20
+ * whatever dependencies they need.
21
+ *
22
+ * Capture files are written to CONTEXT_LENS_CAPTURE_DIR (default:
23
+ * ~/.context-lens/captures/) as atomic JSON files. A separate analysis
24
+ * server watches that directory and provides the web UI.
25
+ */
26
+ export {};
27
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/proxy/server.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;;;;;;;;;;;;GAuBG"}
@@ -0,0 +1,55 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Context Lens Proxy — standalone entry point.
4
+ *
5
+ * A minimal HTTP proxy that forwards LLM API requests to their upstream
6
+ * providers and writes raw captures to disk for analysis.
7
+ *
8
+ * ZERO DEPENDENCIES CONSTRAINT
9
+ * ============================
10
+ * This proxy (everything under src/proxy/) must stay zero external
11
+ * dependencies. Only Node.js built-in modules (node:http, node:https,
12
+ * node:fs, node:path, node:os, node:url) are allowed. No npm packages.
13
+ *
14
+ * Why: users route their API keys through this proxy. Keeping the code
15
+ * small and dependency-free means the entire proxy can be audited by
16
+ * reading a single directory. No transitive supply-chain risk.
17
+ *
18
+ * The analysis server, CLI, and web UI are separate processes that
19
+ * communicate via capture files on disk, and those are free to use
20
+ * whatever dependencies they need.
21
+ *
22
+ * Capture files are written to CONTEXT_LENS_CAPTURE_DIR (default:
23
+ * ~/.context-lens/captures/) as atomic JSON files. A separate analysis
24
+ * server watches that directory and provides the web UI.
25
+ */
26
+ import http from "node:http";
27
+ import { createCaptureWriter } from "./capture.js";
28
+ import { loadProxyConfig } from "./config.js";
29
+ import { createProxyHandler } from "./forward.js";
30
+ const config = loadProxyConfig();
31
+ const captureWriter = createCaptureWriter(config.captureDir);
32
+ const server = http.createServer(createProxyHandler({
33
+ upstreams: config.upstreams,
34
+ allowTargetOverride: config.allowTargetOverride,
35
+ onCapture: (capture) => {
36
+ captureWriter.write(capture);
37
+ },
38
+ }));
39
+ server.on("error", (err) => {
40
+ if (err.code === "EADDRINUSE") {
41
+ console.log(`🔍 Context Lens Proxy already running on port ${config.port}`);
42
+ process.exit(0);
43
+ }
44
+ throw err;
45
+ });
46
+ server.listen(config.port, config.bindHost, () => {
47
+ console.log(`🔍 Context Lens Proxy running on http://${config.bindHost}:${config.port}`);
48
+ console.log(`📁 Captures → ${config.captureDir}`);
49
+ if (!process.env.CONTEXT_LENS_CLI) {
50
+ console.log(`\nUpstream: OpenAI → ${config.upstreams.openai}`);
51
+ console.log(` Anthropic → ${config.upstreams.anthropic}`);
52
+ console.log(` Gemini → ${config.upstreams.gemini}`);
53
+ }
54
+ });
55
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/proxy/server.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAElD,MAAM,MAAM,GAAG,eAAe,EAAE,CAAC;AACjC,MAAM,aAAa,GAAG,mBAAmB,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;AAE7D,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAC9B,kBAAkB,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC,SAAS;IAC3B,mBAAmB,EAAE,MAAM,CAAC,mBAAmB;IAC/C,SAAS,EAAE,CAAC,OAAO,EAAE,EAAE;QACrB,aAAa,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC;CACF,CAAC,CACH,CAAC;AAEF,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAA0B,EAAE,EAAE;IAChD,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;QAC9B,OAAO,CAAC,GAAG,CAAC,iDAAiD,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QAC5E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,MAAM,GAAG,CAAC;AACZ,CAAC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,QAAQ,EAAE,GAAG,EAAE;IAC/C,OAAO,CAAC,GAAG,CACT,2CAA2C,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,IAAI,EAAE,CAC5E,CAAC;IACF,OAAO,CAAC,GAAG,CAAC,iBAAiB,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC;IAClD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QAClC,OAAO,CAAC,GAAG,CAAC,wBAAwB,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC;QAC/D,OAAO,CAAC,GAAG,CAAC,wBAAwB,MAAM,CAAC,SAAS,CAAC,SAAS,EAAE,CAAC,CAAC;QAClE,OAAO,CAAC,GAAG,CAAC,qBAAqB,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC;IAC9D,CAAC;AACH,CAAC,CAAC,CAAC"}
@@ -0,0 +1,328 @@
1
+ /**
2
+ * Valibot schemas for runtime validation of persisted and ingested data.
3
+ *
4
+ * These schemas validate data at trust boundaries:
5
+ * - State file (state.jsonl) loaded from disk
6
+ * - Ingest API (POST /api/ingest) from mitmproxy addon
7
+ * - Capture files from the proxy
8
+ *
9
+ * The TypeScript interfaces in types.ts remain the source of truth for
10
+ * in-memory types. These schemas validate external data before it enters
11
+ * the system.
12
+ */
13
+ import * as v from "valibot";
14
+ export declare const ConversationLineSchema: v.ObjectSchema<{
15
+ readonly type: v.LiteralSchema<"conversation", undefined>;
16
+ readonly data: v.ObjectSchema<{
17
+ readonly id: v.StringSchema<undefined>;
18
+ readonly label: v.StringSchema<undefined>;
19
+ readonly source: v.StringSchema<undefined>;
20
+ readonly workingDirectory: v.NullableSchema<v.StringSchema<undefined>, undefined>;
21
+ readonly firstSeen: v.StringSchema<undefined>;
22
+ readonly sessionId: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, undefined>;
23
+ }, undefined>;
24
+ }, undefined>;
25
+ /**
26
+ * Schema for an entry line in state.jsonl.
27
+ *
28
+ * Uses looseObject for `response` because the compacted response shape
29
+ * varies (streaming chunks, raw markers, parsed usage objects). We only
30
+ * need the usage fields to survive; the rest is best-effort.
31
+ */
32
+ export declare const EntryLineSchema: v.ObjectSchema<{
33
+ readonly type: v.LiteralSchema<"entry", undefined>;
34
+ readonly data: v.ObjectSchema<{
35
+ readonly id: v.NumberSchema<undefined>;
36
+ readonly timestamp: v.StringSchema<undefined>;
37
+ readonly contextInfo: v.ObjectSchema<{
38
+ readonly provider: v.StringSchema<undefined>;
39
+ readonly apiFormat: v.StringSchema<undefined>;
40
+ readonly model: v.StringSchema<undefined>;
41
+ readonly systemTokens: v.NumberSchema<undefined>;
42
+ readonly toolsTokens: v.NumberSchema<undefined>;
43
+ readonly messagesTokens: v.NumberSchema<undefined>;
44
+ readonly totalTokens: v.NumberSchema<undefined>;
45
+ readonly systemPrompts: v.ArraySchema<v.ObjectSchema<{
46
+ readonly content: v.StringSchema<undefined>;
47
+ }, undefined>, undefined>;
48
+ readonly tools: v.ArraySchema<v.UnknownSchema, undefined>;
49
+ readonly messages: v.ArraySchema<v.ObjectSchema<{
50
+ readonly role: v.StringSchema<undefined>;
51
+ readonly content: v.StringSchema<undefined>;
52
+ readonly contentBlocks: v.OptionalSchema<v.NullableSchema<v.ArraySchema<v.UnionSchema<[v.ObjectSchema<{
53
+ readonly type: v.LiteralSchema<"text", undefined>;
54
+ readonly text: v.StringSchema<undefined>;
55
+ }, undefined>, v.ObjectSchema<{
56
+ readonly type: v.LiteralSchema<"tool_use", undefined>;
57
+ readonly id: v.StringSchema<undefined>;
58
+ readonly name: v.StringSchema<undefined>;
59
+ readonly input: v.RecordSchema<v.StringSchema<undefined>, v.UnknownSchema, undefined>;
60
+ }, undefined>, v.ObjectSchema<{
61
+ readonly type: v.LiteralSchema<"tool_result", undefined>;
62
+ readonly tool_use_id: v.StringSchema<undefined>;
63
+ readonly content: v.UnionSchema<[v.StringSchema<undefined>, v.ArraySchema<v.LooseObjectSchema<{
64
+ readonly type: v.StringSchema<undefined>;
65
+ }, undefined>, undefined>], undefined>;
66
+ }, undefined>, v.ObjectSchema<{
67
+ readonly type: v.LiteralSchema<"image", undefined>;
68
+ }, undefined>, v.ObjectSchema<{
69
+ readonly type: v.LiteralSchema<"input_text", undefined>;
70
+ readonly text: v.StringSchema<undefined>;
71
+ }, undefined>, v.LooseObjectSchema<{
72
+ readonly type: v.StringSchema<undefined>;
73
+ }, undefined>], undefined>, undefined>, undefined>, undefined>;
74
+ readonly tokens: v.NumberSchema<undefined>;
75
+ }, undefined>, undefined>;
76
+ }, undefined>;
77
+ readonly response: v.UnknownSchema;
78
+ readonly contextLimit: v.NumberSchema<undefined>;
79
+ readonly source: v.StringSchema<undefined>;
80
+ readonly conversationId: v.NullableSchema<v.StringSchema<undefined>, undefined>;
81
+ readonly agentKey: v.NullableSchema<v.StringSchema<undefined>, undefined>;
82
+ readonly agentLabel: v.StringSchema<undefined>;
83
+ readonly httpStatus: v.NullableSchema<v.NumberSchema<undefined>, undefined>;
84
+ readonly timings: v.NullableSchema<v.ObjectSchema<{
85
+ readonly send_ms: v.NumberSchema<undefined>;
86
+ readonly wait_ms: v.NumberSchema<undefined>;
87
+ readonly receive_ms: v.NumberSchema<undefined>;
88
+ readonly total_ms: v.NumberSchema<undefined>;
89
+ readonly tokens_per_second: v.NullableSchema<v.NumberSchema<undefined>, undefined>;
90
+ }, undefined>, undefined>;
91
+ readonly requestBytes: v.NumberSchema<undefined>;
92
+ readonly responseBytes: v.NumberSchema<undefined>;
93
+ readonly targetUrl: v.NullableSchema<v.StringSchema<undefined>, undefined>;
94
+ readonly composition: v.ArraySchema<v.ObjectSchema<{
95
+ readonly category: v.PicklistSchema<["system_prompt", "tool_definitions", "tool_results", "tool_calls", "assistant_text", "user_text", "thinking", "system_injections", "images", "cache_markers", "other"], undefined>;
96
+ readonly tokens: v.NumberSchema<undefined>;
97
+ readonly pct: v.NumberSchema<undefined>;
98
+ readonly count: v.NumberSchema<undefined>;
99
+ }, undefined>, undefined>;
100
+ readonly costUsd: v.NullableSchema<v.NumberSchema<undefined>, undefined>;
101
+ readonly healthScore: v.NullableSchema<v.ObjectSchema<{
102
+ readonly overall: v.NumberSchema<undefined>;
103
+ readonly rating: v.PicklistSchema<["good", "needs-work", "poor"], undefined>;
104
+ readonly audits: v.ArraySchema<v.ObjectSchema<{
105
+ readonly id: v.StringSchema<undefined>;
106
+ readonly name: v.StringSchema<undefined>;
107
+ readonly score: v.NumberSchema<undefined>;
108
+ readonly weight: v.NumberSchema<undefined>;
109
+ readonly description: v.StringSchema<undefined>;
110
+ }, undefined>, undefined>;
111
+ }, undefined>, undefined>;
112
+ readonly securityAlerts: v.OptionalSchema<v.ArraySchema<v.ObjectSchema<{
113
+ readonly messageIndex: v.NumberSchema<undefined>;
114
+ readonly role: v.StringSchema<undefined>;
115
+ readonly toolName: v.NullableSchema<v.StringSchema<undefined>, undefined>;
116
+ readonly severity: v.PicklistSchema<["high", "medium", "info"], undefined>;
117
+ readonly pattern: v.StringSchema<undefined>;
118
+ readonly match: v.StringSchema<undefined>;
119
+ readonly offset: v.NumberSchema<undefined>;
120
+ readonly length: v.NumberSchema<undefined>;
121
+ }, undefined>, undefined>, undefined>;
122
+ readonly usage: v.OptionalSchema<v.NullableSchema<v.ObjectSchema<{
123
+ readonly inputTokens: v.NumberSchema<undefined>;
124
+ readonly outputTokens: v.NumberSchema<undefined>;
125
+ readonly cacheReadTokens: v.NumberSchema<undefined>;
126
+ readonly cacheWriteTokens: v.NumberSchema<undefined>;
127
+ }, undefined>, undefined>, undefined>;
128
+ readonly responseModel: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, undefined>;
129
+ readonly stopReason: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, undefined>;
130
+ }, undefined>;
131
+ }, undefined>;
132
+ /**
133
+ * A single line in state.jsonl is either a conversation or an entry.
134
+ */
135
+ export declare const StateLineSchema: v.VariantSchema<"type", [v.ObjectSchema<{
136
+ readonly type: v.LiteralSchema<"conversation", undefined>;
137
+ readonly data: v.ObjectSchema<{
138
+ readonly id: v.StringSchema<undefined>;
139
+ readonly label: v.StringSchema<undefined>;
140
+ readonly source: v.StringSchema<undefined>;
141
+ readonly workingDirectory: v.NullableSchema<v.StringSchema<undefined>, undefined>;
142
+ readonly firstSeen: v.StringSchema<undefined>;
143
+ readonly sessionId: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, undefined>;
144
+ }, undefined>;
145
+ }, undefined>, v.ObjectSchema<{
146
+ readonly type: v.LiteralSchema<"entry", undefined>;
147
+ readonly data: v.ObjectSchema<{
148
+ readonly id: v.NumberSchema<undefined>;
149
+ readonly timestamp: v.StringSchema<undefined>;
150
+ readonly contextInfo: v.ObjectSchema<{
151
+ readonly provider: v.StringSchema<undefined>;
152
+ readonly apiFormat: v.StringSchema<undefined>;
153
+ readonly model: v.StringSchema<undefined>;
154
+ readonly systemTokens: v.NumberSchema<undefined>;
155
+ readonly toolsTokens: v.NumberSchema<undefined>;
156
+ readonly messagesTokens: v.NumberSchema<undefined>;
157
+ readonly totalTokens: v.NumberSchema<undefined>;
158
+ readonly systemPrompts: v.ArraySchema<v.ObjectSchema<{
159
+ readonly content: v.StringSchema<undefined>;
160
+ }, undefined>, undefined>;
161
+ readonly tools: v.ArraySchema<v.UnknownSchema, undefined>;
162
+ readonly messages: v.ArraySchema<v.ObjectSchema<{
163
+ readonly role: v.StringSchema<undefined>;
164
+ readonly content: v.StringSchema<undefined>;
165
+ readonly contentBlocks: v.OptionalSchema<v.NullableSchema<v.ArraySchema<v.UnionSchema<[v.ObjectSchema<{
166
+ readonly type: v.LiteralSchema<"text", undefined>;
167
+ readonly text: v.StringSchema<undefined>;
168
+ }, undefined>, v.ObjectSchema<{
169
+ readonly type: v.LiteralSchema<"tool_use", undefined>;
170
+ readonly id: v.StringSchema<undefined>;
171
+ readonly name: v.StringSchema<undefined>;
172
+ readonly input: v.RecordSchema<v.StringSchema<undefined>, v.UnknownSchema, undefined>;
173
+ }, undefined>, v.ObjectSchema<{
174
+ readonly type: v.LiteralSchema<"tool_result", undefined>;
175
+ readonly tool_use_id: v.StringSchema<undefined>;
176
+ readonly content: v.UnionSchema<[v.StringSchema<undefined>, v.ArraySchema<v.LooseObjectSchema<{
177
+ readonly type: v.StringSchema<undefined>;
178
+ }, undefined>, undefined>], undefined>;
179
+ }, undefined>, v.ObjectSchema<{
180
+ readonly type: v.LiteralSchema<"image", undefined>;
181
+ }, undefined>, v.ObjectSchema<{
182
+ readonly type: v.LiteralSchema<"input_text", undefined>;
183
+ readonly text: v.StringSchema<undefined>;
184
+ }, undefined>, v.LooseObjectSchema<{
185
+ readonly type: v.StringSchema<undefined>;
186
+ }, undefined>], undefined>, undefined>, undefined>, undefined>;
187
+ readonly tokens: v.NumberSchema<undefined>;
188
+ }, undefined>, undefined>;
189
+ }, undefined>;
190
+ readonly response: v.UnknownSchema;
191
+ readonly contextLimit: v.NumberSchema<undefined>;
192
+ readonly source: v.StringSchema<undefined>;
193
+ readonly conversationId: v.NullableSchema<v.StringSchema<undefined>, undefined>;
194
+ readonly agentKey: v.NullableSchema<v.StringSchema<undefined>, undefined>;
195
+ readonly agentLabel: v.StringSchema<undefined>;
196
+ readonly httpStatus: v.NullableSchema<v.NumberSchema<undefined>, undefined>;
197
+ readonly timings: v.NullableSchema<v.ObjectSchema<{
198
+ readonly send_ms: v.NumberSchema<undefined>;
199
+ readonly wait_ms: v.NumberSchema<undefined>;
200
+ readonly receive_ms: v.NumberSchema<undefined>;
201
+ readonly total_ms: v.NumberSchema<undefined>;
202
+ readonly tokens_per_second: v.NullableSchema<v.NumberSchema<undefined>, undefined>;
203
+ }, undefined>, undefined>;
204
+ readonly requestBytes: v.NumberSchema<undefined>;
205
+ readonly responseBytes: v.NumberSchema<undefined>;
206
+ readonly targetUrl: v.NullableSchema<v.StringSchema<undefined>, undefined>;
207
+ readonly composition: v.ArraySchema<v.ObjectSchema<{
208
+ readonly category: v.PicklistSchema<["system_prompt", "tool_definitions", "tool_results", "tool_calls", "assistant_text", "user_text", "thinking", "system_injections", "images", "cache_markers", "other"], undefined>;
209
+ readonly tokens: v.NumberSchema<undefined>;
210
+ readonly pct: v.NumberSchema<undefined>;
211
+ readonly count: v.NumberSchema<undefined>;
212
+ }, undefined>, undefined>;
213
+ readonly costUsd: v.NullableSchema<v.NumberSchema<undefined>, undefined>;
214
+ readonly healthScore: v.NullableSchema<v.ObjectSchema<{
215
+ readonly overall: v.NumberSchema<undefined>;
216
+ readonly rating: v.PicklistSchema<["good", "needs-work", "poor"], undefined>;
217
+ readonly audits: v.ArraySchema<v.ObjectSchema<{
218
+ readonly id: v.StringSchema<undefined>;
219
+ readonly name: v.StringSchema<undefined>;
220
+ readonly score: v.NumberSchema<undefined>;
221
+ readonly weight: v.NumberSchema<undefined>;
222
+ readonly description: v.StringSchema<undefined>;
223
+ }, undefined>, undefined>;
224
+ }, undefined>, undefined>;
225
+ readonly securityAlerts: v.OptionalSchema<v.ArraySchema<v.ObjectSchema<{
226
+ readonly messageIndex: v.NumberSchema<undefined>;
227
+ readonly role: v.StringSchema<undefined>;
228
+ readonly toolName: v.NullableSchema<v.StringSchema<undefined>, undefined>;
229
+ readonly severity: v.PicklistSchema<["high", "medium", "info"], undefined>;
230
+ readonly pattern: v.StringSchema<undefined>;
231
+ readonly match: v.StringSchema<undefined>;
232
+ readonly offset: v.NumberSchema<undefined>;
233
+ readonly length: v.NumberSchema<undefined>;
234
+ }, undefined>, undefined>, undefined>;
235
+ readonly usage: v.OptionalSchema<v.NullableSchema<v.ObjectSchema<{
236
+ readonly inputTokens: v.NumberSchema<undefined>;
237
+ readonly outputTokens: v.NumberSchema<undefined>;
238
+ readonly cacheReadTokens: v.NumberSchema<undefined>;
239
+ readonly cacheWriteTokens: v.NumberSchema<undefined>;
240
+ }, undefined>, undefined>, undefined>;
241
+ readonly responseModel: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, undefined>;
242
+ readonly stopReason: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, undefined>;
243
+ }, undefined>;
244
+ }, undefined>], undefined>;
245
+ /**
246
+ * Legacy ingest format (provider + body + response).
247
+ */
248
+ export declare const IngestLegacyPayloadSchema: v.ObjectSchema<{
249
+ readonly provider: v.OptionalSchema<v.StringSchema<undefined>, "unknown">;
250
+ readonly apiFormat: v.OptionalSchema<v.StringSchema<undefined>, "unknown">;
251
+ readonly source: v.OptionalSchema<v.StringSchema<undefined>, "unknown">;
252
+ readonly body: v.OptionalSchema<v.RecordSchema<v.StringSchema<undefined>, v.UnknownSchema, undefined>, {}>;
253
+ readonly response: v.OptionalSchema<v.RecordSchema<v.StringSchema<undefined>, v.UnknownSchema, undefined>, {}>;
254
+ }, undefined>;
255
+ /**
256
+ * Capture-format ingest (same shape as proxy CaptureData).
257
+ * Sent by the mitmproxy addon. Includes headers, timings, streaming body.
258
+ */
259
+ export declare const IngestCapturePayloadSchema: v.ObjectSchema<{
260
+ readonly timestamp: v.StringSchema<undefined>;
261
+ readonly method: v.OptionalSchema<v.StringSchema<undefined>, "POST">;
262
+ readonly path: v.StringSchema<undefined>;
263
+ readonly source: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, "unknown">;
264
+ readonly provider: v.StringSchema<undefined>;
265
+ readonly apiFormat: v.OptionalSchema<v.StringSchema<undefined>, "unknown">;
266
+ readonly targetUrl: v.OptionalSchema<v.StringSchema<undefined>, "">;
267
+ readonly requestHeaders: v.OptionalSchema<v.RecordSchema<v.StringSchema<undefined>, v.StringSchema<undefined>, undefined>, {}>;
268
+ readonly requestBody: v.OptionalSchema<v.NullableSchema<v.RecordSchema<v.StringSchema<undefined>, v.UnknownSchema, undefined>, undefined>, null>;
269
+ readonly requestBytes: v.OptionalSchema<v.NumberSchema<undefined>, 0>;
270
+ readonly responseStatus: v.OptionalSchema<v.NumberSchema<undefined>, 200>;
271
+ readonly responseHeaders: v.OptionalSchema<v.RecordSchema<v.StringSchema<undefined>, v.StringSchema<undefined>, undefined>, {}>;
272
+ readonly responseBody: v.OptionalSchema<v.StringSchema<undefined>, "">;
273
+ readonly responseIsStreaming: v.OptionalSchema<v.BooleanSchema<undefined>, false>;
274
+ readonly responseBytes: v.OptionalSchema<v.NumberSchema<undefined>, 0>;
275
+ readonly timings: v.OptionalSchema<v.ObjectSchema<{
276
+ readonly send_ms: v.NumberSchema<undefined>;
277
+ readonly wait_ms: v.NumberSchema<undefined>;
278
+ readonly receive_ms: v.NumberSchema<undefined>;
279
+ readonly total_ms: v.NumberSchema<undefined>;
280
+ }, undefined>, {
281
+ readonly send_ms: 0;
282
+ readonly wait_ms: 0;
283
+ readonly receive_ms: 0;
284
+ readonly total_ms: 0;
285
+ }>;
286
+ }, undefined>;
287
+ /**
288
+ * Union: accept either capture-format or legacy format.
289
+ */
290
+ export declare const IngestPayloadSchema: v.UnionSchema<[v.ObjectSchema<{
291
+ readonly timestamp: v.StringSchema<undefined>;
292
+ readonly method: v.OptionalSchema<v.StringSchema<undefined>, "POST">;
293
+ readonly path: v.StringSchema<undefined>;
294
+ readonly source: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, "unknown">;
295
+ readonly provider: v.StringSchema<undefined>;
296
+ readonly apiFormat: v.OptionalSchema<v.StringSchema<undefined>, "unknown">;
297
+ readonly targetUrl: v.OptionalSchema<v.StringSchema<undefined>, "">;
298
+ readonly requestHeaders: v.OptionalSchema<v.RecordSchema<v.StringSchema<undefined>, v.StringSchema<undefined>, undefined>, {}>;
299
+ readonly requestBody: v.OptionalSchema<v.NullableSchema<v.RecordSchema<v.StringSchema<undefined>, v.UnknownSchema, undefined>, undefined>, null>;
300
+ readonly requestBytes: v.OptionalSchema<v.NumberSchema<undefined>, 0>;
301
+ readonly responseStatus: v.OptionalSchema<v.NumberSchema<undefined>, 200>;
302
+ readonly responseHeaders: v.OptionalSchema<v.RecordSchema<v.StringSchema<undefined>, v.StringSchema<undefined>, undefined>, {}>;
303
+ readonly responseBody: v.OptionalSchema<v.StringSchema<undefined>, "">;
304
+ readonly responseIsStreaming: v.OptionalSchema<v.BooleanSchema<undefined>, false>;
305
+ readonly responseBytes: v.OptionalSchema<v.NumberSchema<undefined>, 0>;
306
+ readonly timings: v.OptionalSchema<v.ObjectSchema<{
307
+ readonly send_ms: v.NumberSchema<undefined>;
308
+ readonly wait_ms: v.NumberSchema<undefined>;
309
+ readonly receive_ms: v.NumberSchema<undefined>;
310
+ readonly total_ms: v.NumberSchema<undefined>;
311
+ }, undefined>, {
312
+ readonly send_ms: 0;
313
+ readonly wait_ms: 0;
314
+ readonly receive_ms: 0;
315
+ readonly total_ms: 0;
316
+ }>;
317
+ }, undefined>, v.ObjectSchema<{
318
+ readonly provider: v.OptionalSchema<v.StringSchema<undefined>, "unknown">;
319
+ readonly apiFormat: v.OptionalSchema<v.StringSchema<undefined>, "unknown">;
320
+ readonly source: v.OptionalSchema<v.StringSchema<undefined>, "unknown">;
321
+ readonly body: v.OptionalSchema<v.RecordSchema<v.StringSchema<undefined>, v.UnknownSchema, undefined>, {}>;
322
+ readonly response: v.OptionalSchema<v.RecordSchema<v.StringSchema<undefined>, v.UnknownSchema, undefined>, {}>;
323
+ }, undefined>], undefined>;
324
+ export type StateLineData = v.InferOutput<typeof StateLineSchema>;
325
+ export type ConversationLineData = v.InferOutput<typeof ConversationLineSchema>;
326
+ export type EntryLineData = v.InferOutput<typeof EntryLineSchema>;
327
+ export type IngestPayloadData = v.InferOutput<typeof IngestPayloadSchema>;
328
+ //# sourceMappingURL=schemas.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../src/schemas.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,CAAC,MAAM,SAAS,CAAC;AAqK7B,eAAO,MAAM,sBAAsB;;;;;;;;;;aAUjC,CAAC;AAEH;;;;;;GAMG;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAyB1B,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0BAG1B,CAAC;AAMH;;GAEG;AACH,eAAO,MAAM,yBAAyB;;;;;;aAMpC,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;aAyBrC,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0BAG9B,CAAC;AAMH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,eAAe,CAAC,CAAC;AAClE,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAChF,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,eAAe,CAAC,CAAC;AAClE,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,mBAAmB,CAAC,CAAC"}