claudia-orchestrator 0.1.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.
- package/LICENSE +201 -0
- package/README.md +109 -0
- package/dist/cli-parser.d.ts +11 -0
- package/dist/cli-parser.d.ts.map +1 -0
- package/dist/cli-parser.js +57 -0
- package/dist/cli-parser.js.map +1 -0
- package/dist/cui-server.d.ts +69 -0
- package/dist/cui-server.d.ts.map +1 -0
- package/dist/cui-server.js +705 -0
- package/dist/cui-server.js.map +1 -0
- package/dist/mcp-server/claudia-tools.d.ts +15 -0
- package/dist/mcp-server/claudia-tools.d.ts.map +1 -0
- package/dist/mcp-server/claudia-tools.js +366 -0
- package/dist/mcp-server/claudia-tools.js.map +1 -0
- package/dist/mcp-server/index.d.ts +3 -0
- package/dist/mcp-server/index.d.ts.map +1 -0
- package/dist/mcp-server/index.js +176 -0
- package/dist/mcp-server/index.js.map +1 -0
- package/dist/middleware/auth.d.ts +18 -0
- package/dist/middleware/auth.d.ts.map +1 -0
- package/dist/middleware/auth.js +136 -0
- package/dist/middleware/auth.js.map +1 -0
- package/dist/middleware/cors-setup.d.ts +7 -0
- package/dist/middleware/cors-setup.d.ts.map +1 -0
- package/dist/middleware/cors-setup.js +8 -0
- package/dist/middleware/cors-setup.js.map +1 -0
- package/dist/middleware/error-handler.d.ts +4 -0
- package/dist/middleware/error-handler.d.ts.map +1 -0
- package/dist/middleware/error-handler.js +27 -0
- package/dist/middleware/error-handler.js.map +1 -0
- package/dist/middleware/query-parser.d.ts +11 -0
- package/dist/middleware/query-parser.d.ts.map +1 -0
- package/dist/middleware/query-parser.js +68 -0
- package/dist/middleware/query-parser.js.map +1 -0
- package/dist/middleware/request-logger.d.ts +4 -0
- package/dist/middleware/request-logger.d.ts.map +1 -0
- package/dist/middleware/request-logger.js +29 -0
- package/dist/middleware/request-logger.js.map +1 -0
- package/dist/process-daemon/index.d.ts +14 -0
- package/dist/process-daemon/index.d.ts.map +1 -0
- package/dist/process-daemon/index.js +51 -0
- package/dist/process-daemon/index.js.map +1 -0
- package/dist/process-daemon/process-daemon.d.ts +78 -0
- package/dist/process-daemon/process-daemon.d.ts.map +1 -0
- package/dist/process-daemon/process-daemon.js +568 -0
- package/dist/process-daemon/process-daemon.js.map +1 -0
- package/dist/process-daemon/process-manager-client.d.ts +108 -0
- package/dist/process-daemon/process-manager-client.d.ts.map +1 -0
- package/dist/process-daemon/process-manager-client.js +314 -0
- package/dist/process-daemon/process-manager-client.js.map +1 -0
- package/dist/process-daemon/process-manager-interface.d.ts +47 -0
- package/dist/process-daemon/process-manager-interface.d.ts.map +1 -0
- package/dist/process-daemon/process-manager-interface.js +8 -0
- package/dist/process-daemon/process-manager-interface.js.map +1 -0
- package/dist/process-daemon/test-daemon.d.ts +12 -0
- package/dist/process-daemon/test-daemon.d.ts.map +1 -0
- package/dist/process-daemon/test-daemon.js +81 -0
- package/dist/process-daemon/test-daemon.js.map +1 -0
- package/dist/process-daemon/types.d.ts +85 -0
- package/dist/process-daemon/types.d.ts.map +1 -0
- package/dist/process-daemon/types.js +8 -0
- package/dist/process-daemon/types.js.map +1 -0
- package/dist/routes/claudia.routes.d.ts +10 -0
- package/dist/routes/claudia.routes.d.ts.map +1 -0
- package/dist/routes/claudia.routes.js +123 -0
- package/dist/routes/claudia.routes.js.map +1 -0
- package/dist/routes/config.routes.d.ts +4 -0
- package/dist/routes/config.routes.d.ts.map +1 -0
- package/dist/routes/config.routes.js +27 -0
- package/dist/routes/config.routes.js.map +1 -0
- package/dist/routes/conversation.routes.d.ts +8 -0
- package/dist/routes/conversation.routes.d.ts.map +1 -0
- package/dist/routes/conversation.routes.js +870 -0
- package/dist/routes/conversation.routes.js.map +1 -0
- package/dist/routes/filesystem.routes.d.ts +4 -0
- package/dist/routes/filesystem.routes.d.ts.map +1 -0
- package/dist/routes/filesystem.routes.js +86 -0
- package/dist/routes/filesystem.routes.js.map +1 -0
- package/dist/routes/gemini.routes.d.ts +4 -0
- package/dist/routes/gemini.routes.d.ts.map +1 -0
- package/dist/routes/gemini.routes.js +93 -0
- package/dist/routes/gemini.routes.js.map +1 -0
- package/dist/routes/insights.routes.d.ts +17 -0
- package/dist/routes/insights.routes.d.ts.map +1 -0
- package/dist/routes/insights.routes.js +417 -0
- package/dist/routes/insights.routes.js.map +1 -0
- package/dist/routes/license.routes.d.ts +3 -0
- package/dist/routes/license.routes.d.ts.map +1 -0
- package/dist/routes/license.routes.js +111 -0
- package/dist/routes/license.routes.js.map +1 -0
- package/dist/routes/log.routes.d.ts +3 -0
- package/dist/routes/log.routes.d.ts.map +1 -0
- package/dist/routes/log.routes.js +65 -0
- package/dist/routes/log.routes.js.map +1 -0
- package/dist/routes/notifications.routes.d.ts +4 -0
- package/dist/routes/notifications.routes.d.ts.map +1 -0
- package/dist/routes/notifications.routes.js +71 -0
- package/dist/routes/notifications.routes.js.map +1 -0
- package/dist/routes/permission.routes.d.ts +4 -0
- package/dist/routes/permission.routes.d.ts.map +1 -0
- package/dist/routes/permission.routes.js +116 -0
- package/dist/routes/permission.routes.js.map +1 -0
- package/dist/routes/question.routes.d.ts +8 -0
- package/dist/routes/question.routes.d.ts.map +1 -0
- package/dist/routes/question.routes.js +82 -0
- package/dist/routes/question.routes.js.map +1 -0
- package/dist/routes/streaming.routes.d.ts +4 -0
- package/dist/routes/streaming.routes.d.ts.map +1 -0
- package/dist/routes/streaming.routes.js +28 -0
- package/dist/routes/streaming.routes.js.map +1 -0
- package/dist/routes/system.routes.d.ts +5 -0
- package/dist/routes/system.routes.d.ts.map +1 -0
- package/dist/routes/system.routes.js +103 -0
- package/dist/routes/system.routes.js.map +1 -0
- package/dist/routes/working-directories.routes.d.ts +4 -0
- package/dist/routes/working-directories.routes.d.ts.map +1 -0
- package/dist/routes/working-directories.routes.js +25 -0
- package/dist/routes/working-directories.routes.js.map +1 -0
- package/dist/server.d.ts +3 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +34 -0
- package/dist/server.js.map +1 -0
- package/dist/services/ToolMetricsService.d.ts +53 -0
- package/dist/services/ToolMetricsService.d.ts.map +1 -0
- package/dist/services/ToolMetricsService.js +230 -0
- package/dist/services/ToolMetricsService.js.map +1 -0
- package/dist/services/anthropic-service.d.ts +186 -0
- package/dist/services/anthropic-service.d.ts.map +1 -0
- package/dist/services/anthropic-service.js +1132 -0
- package/dist/services/anthropic-service.js.map +1 -0
- package/dist/services/claude-history-reader.d.ts +126 -0
- package/dist/services/claude-history-reader.d.ts.map +1 -0
- package/dist/services/claude-history-reader.js +717 -0
- package/dist/services/claude-history-reader.js.map +1 -0
- package/dist/services/claude-process-manager.d.ts +108 -0
- package/dist/services/claude-process-manager.d.ts.map +1 -0
- package/dist/services/claude-process-manager.js +909 -0
- package/dist/services/claude-process-manager.js.map +1 -0
- package/dist/services/claude-router-service.d.ts +19 -0
- package/dist/services/claude-router-service.d.ts.map +1 -0
- package/dist/services/claude-router-service.js +160 -0
- package/dist/services/claude-router-service.js.map +1 -0
- package/dist/services/claudia-service.d.ts +77 -0
- package/dist/services/claudia-service.d.ts.map +1 -0
- package/dist/services/claudia-service.js +194 -0
- package/dist/services/claudia-service.js.map +1 -0
- package/dist/services/commands-service.d.ts +18 -0
- package/dist/services/commands-service.d.ts.map +1 -0
- package/dist/services/commands-service.js +76 -0
- package/dist/services/commands-service.js.map +1 -0
- package/dist/services/config-service.d.ts +68 -0
- package/dist/services/config-service.d.ts.map +1 -0
- package/dist/services/config-service.js +429 -0
- package/dist/services/config-service.js.map +1 -0
- package/dist/services/conversation-cache.d.ts +86 -0
- package/dist/services/conversation-cache.d.ts.map +1 -0
- package/dist/services/conversation-cache.js +235 -0
- package/dist/services/conversation-cache.js.map +1 -0
- package/dist/services/conversation-status-manager.d.ts +98 -0
- package/dist/services/conversation-status-manager.d.ts.map +1 -0
- package/dist/services/conversation-status-manager.js +295 -0
- package/dist/services/conversation-status-manager.js.map +1 -0
- package/dist/services/cost-tracker.d.ts +87 -0
- package/dist/services/cost-tracker.d.ts.map +1 -0
- package/dist/services/cost-tracker.js +335 -0
- package/dist/services/cost-tracker.js.map +1 -0
- package/dist/services/file-system-service.d.ts +61 -0
- package/dist/services/file-system-service.d.ts.map +1 -0
- package/dist/services/file-system-service.js +348 -0
- package/dist/services/file-system-service.js.map +1 -0
- package/dist/services/gemini-service.d.ts +72 -0
- package/dist/services/gemini-service.d.ts.map +1 -0
- package/dist/services/gemini-service.js +431 -0
- package/dist/services/gemini-service.js.map +1 -0
- package/dist/services/insight-queue.d.ts +99 -0
- package/dist/services/insight-queue.d.ts.map +1 -0
- package/dist/services/insight-queue.js +277 -0
- package/dist/services/insight-queue.js.map +1 -0
- package/dist/services/insights-service.d.ts +102 -0
- package/dist/services/insights-service.d.ts.map +1 -0
- package/dist/services/insights-service.js +1152 -0
- package/dist/services/insights-service.js.map +1 -0
- package/dist/services/json-lines-parser.d.ts +19 -0
- package/dist/services/json-lines-parser.d.ts.map +1 -0
- package/dist/services/json-lines-parser.js +56 -0
- package/dist/services/json-lines-parser.js.map +1 -0
- package/dist/services/license-service.d.ts +69 -0
- package/dist/services/license-service.d.ts.map +1 -0
- package/dist/services/license-service.js +330 -0
- package/dist/services/license-service.js.map +1 -0
- package/dist/services/log-formatter.d.ts +5 -0
- package/dist/services/log-formatter.d.ts.map +1 -0
- package/dist/services/log-formatter.js +77 -0
- package/dist/services/log-formatter.js.map +1 -0
- package/dist/services/log-stream-buffer.d.ts +11 -0
- package/dist/services/log-stream-buffer.d.ts.map +1 -0
- package/dist/services/log-stream-buffer.js +36 -0
- package/dist/services/log-stream-buffer.js.map +1 -0
- package/dist/services/logger.d.ts +71 -0
- package/dist/services/logger.d.ts.map +1 -0
- package/dist/services/logger.js +215 -0
- package/dist/services/logger.js.map +1 -0
- package/dist/services/mcp-config-generator.d.ts +32 -0
- package/dist/services/mcp-config-generator.d.ts.map +1 -0
- package/dist/services/mcp-config-generator.js +126 -0
- package/dist/services/mcp-config-generator.js.map +1 -0
- package/dist/services/message-filter.d.ts +22 -0
- package/dist/services/message-filter.d.ts.map +1 -0
- package/dist/services/message-filter.js +57 -0
- package/dist/services/message-filter.js.map +1 -0
- package/dist/services/notification-service.d.ts +45 -0
- package/dist/services/notification-service.d.ts.map +1 -0
- package/dist/services/notification-service.js +184 -0
- package/dist/services/notification-service.js.map +1 -0
- package/dist/services/permission-tracker.d.ts +67 -0
- package/dist/services/permission-tracker.d.ts.map +1 -0
- package/dist/services/permission-tracker.js +161 -0
- package/dist/services/permission-tracker.js.map +1 -0
- package/dist/services/process-manager-factory.d.ts +81 -0
- package/dist/services/process-manager-factory.d.ts.map +1 -0
- package/dist/services/process-manager-factory.js +211 -0
- package/dist/services/process-manager-factory.js.map +1 -0
- package/dist/services/question-tracker.d.ts +47 -0
- package/dist/services/question-tracker.d.ts.map +1 -0
- package/dist/services/question-tracker.js +105 -0
- package/dist/services/question-tracker.js.map +1 -0
- package/dist/services/session-activity-watcher.d.ts +33 -0
- package/dist/services/session-activity-watcher.d.ts.map +1 -0
- package/dist/services/session-activity-watcher.js +194 -0
- package/dist/services/session-activity-watcher.js.map +1 -0
- package/dist/services/session-info-service.d.ts +228 -0
- package/dist/services/session-info-service.d.ts.map +1 -0
- package/dist/services/session-info-service.js +920 -0
- package/dist/services/session-info-service.js.map +1 -0
- package/dist/services/session-insights-service.d.ts +119 -0
- package/dist/services/session-insights-service.d.ts.map +1 -0
- package/dist/services/session-insights-service.js +889 -0
- package/dist/services/session-insights-service.js.map +1 -0
- package/dist/services/stream-manager.d.ts +62 -0
- package/dist/services/stream-manager.d.ts.map +1 -0
- package/dist/services/stream-manager.js +239 -0
- package/dist/services/stream-manager.js.map +1 -0
- package/dist/services/web-push-service.d.ts +48 -0
- package/dist/services/web-push-service.d.ts.map +1 -0
- package/dist/services/web-push-service.js +186 -0
- package/dist/services/web-push-service.js.map +1 -0
- package/dist/services/working-directories-service.d.ts +19 -0
- package/dist/services/working-directories-service.d.ts.map +1 -0
- package/dist/services/working-directories-service.js +103 -0
- package/dist/services/working-directories-service.js.map +1 -0
- package/dist/types/config.d.ts +111 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +14 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/express.d.ts +5 -0
- package/dist/types/express.d.ts.map +1 -0
- package/dist/types/express.js +2 -0
- package/dist/types/express.js.map +1 -0
- package/dist/types/index.d.ts +325 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +18 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/insights.d.ts +99 -0
- package/dist/types/insights.d.ts.map +1 -0
- package/dist/types/insights.js +7 -0
- package/dist/types/insights.js.map +1 -0
- package/dist/types/license.d.ts +70 -0
- package/dist/types/license.d.ts.map +1 -0
- package/dist/types/license.js +5 -0
- package/dist/types/license.js.map +1 -0
- package/dist/types/router-config.d.ts +13 -0
- package/dist/types/router-config.d.ts.map +1 -0
- package/dist/types/router-config.js +2 -0
- package/dist/types/router-config.js.map +1 -0
- package/dist/utils/constants.d.ts +26 -0
- package/dist/utils/constants.d.ts.map +1 -0
- package/dist/utils/constants.js +28 -0
- package/dist/utils/constants.js.map +1 -0
- package/dist/utils/machine-id.d.ts +7 -0
- package/dist/utils/machine-id.d.ts.map +1 -0
- package/dist/utils/machine-id.js +76 -0
- package/dist/utils/machine-id.js.map +1 -0
- package/dist/utils/server-startup.d.ts +13 -0
- package/dist/utils/server-startup.d.ts.map +1 -0
- package/dist/utils/server-startup.js +20 -0
- package/dist/utils/server-startup.js.map +1 -0
- package/dist/web/assets/main-DAc2rjJ2.css +1 -0
- package/dist/web/assets/main-DvlZ02mT.js +137 -0
- package/dist/web/favicon.png +0 -0
- package/dist/web/favicon.svg +22 -0
- package/dist/web/icon-192x192.png +0 -0
- package/dist/web/icon-512x512.png +0 -0
- package/dist/web/index.html +36 -0
- package/dist/web/manifest.json +61 -0
- package/package.json +174 -0
- package/scripts/postinstall.js +30 -0
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CostTracker - Tracks LLM API costs for insights generation.
|
|
3
|
+
*
|
|
4
|
+
* Provides:
|
|
5
|
+
* - Per-call cost logging with session, operation, model, tokens
|
|
6
|
+
* - Summary queries (today, this week, by operation, by model)
|
|
7
|
+
* - Cost estimation using current Anthropic pricing
|
|
8
|
+
*
|
|
9
|
+
* Design decisions:
|
|
10
|
+
* - Separate table from session insights for clean separation
|
|
11
|
+
* - Uses same database file for simplicity
|
|
12
|
+
* - Costs stored in USD for consistency
|
|
13
|
+
*/
|
|
14
|
+
export type InsightOperationType = 'GENERATE' | 'PATCH' | 'REFRESH' | 'QUICK_CHECK' | 'MERGE_DECISION' | 'PROPOSITIONS' | 'FAST_PATCH';
|
|
15
|
+
export interface LLMCallRecord {
|
|
16
|
+
sessionId: string;
|
|
17
|
+
operation: InsightOperationType;
|
|
18
|
+
model: string;
|
|
19
|
+
inputTokens: number;
|
|
20
|
+
outputTokens: number;
|
|
21
|
+
durationMs: number;
|
|
22
|
+
traceId?: string;
|
|
23
|
+
}
|
|
24
|
+
export interface CostSummary {
|
|
25
|
+
calls: number;
|
|
26
|
+
inputTokens: number;
|
|
27
|
+
outputTokens: number;
|
|
28
|
+
totalTokens: number;
|
|
29
|
+
estimatedCostUsd: number;
|
|
30
|
+
}
|
|
31
|
+
export interface CostSummaryResponse {
|
|
32
|
+
today: CostSummary;
|
|
33
|
+
thisWeek: CostSummary;
|
|
34
|
+
thisMonth: CostSummary;
|
|
35
|
+
allTime: CostSummary;
|
|
36
|
+
byOperation: Record<string, CostSummary>;
|
|
37
|
+
byModel: Record<string, CostSummary>;
|
|
38
|
+
recentCalls: Array<{
|
|
39
|
+
sessionId: string;
|
|
40
|
+
operation: string;
|
|
41
|
+
model: string;
|
|
42
|
+
inputTokens: number;
|
|
43
|
+
outputTokens: number;
|
|
44
|
+
estimatedCostUsd: number;
|
|
45
|
+
durationMs: number;
|
|
46
|
+
createdAt: string;
|
|
47
|
+
}>;
|
|
48
|
+
}
|
|
49
|
+
export declare class CostTracker {
|
|
50
|
+
private logger;
|
|
51
|
+
private db;
|
|
52
|
+
private isInitialized;
|
|
53
|
+
private dbPath;
|
|
54
|
+
private configDir;
|
|
55
|
+
private insertStmt;
|
|
56
|
+
private summaryStmt;
|
|
57
|
+
constructor(testDbPath?: string);
|
|
58
|
+
initialize(): Promise<void>;
|
|
59
|
+
private prepareStatements;
|
|
60
|
+
/**
|
|
61
|
+
* Calculate cost in USD for a given model and token counts.
|
|
62
|
+
*/
|
|
63
|
+
private calculateCost;
|
|
64
|
+
/**
|
|
65
|
+
* Log an LLM API call with its cost.
|
|
66
|
+
*/
|
|
67
|
+
log(record: LLMCallRecord): void;
|
|
68
|
+
/**
|
|
69
|
+
* Get cost summary for different time periods.
|
|
70
|
+
*/
|
|
71
|
+
getSummary(): CostSummaryResponse;
|
|
72
|
+
/**
|
|
73
|
+
* Get costs for a specific session.
|
|
74
|
+
*/
|
|
75
|
+
getSessionCosts(sessionId: string): CostSummary & {
|
|
76
|
+
recentCalls: any[];
|
|
77
|
+
};
|
|
78
|
+
private emptySummary;
|
|
79
|
+
private emptySummaryResponse;
|
|
80
|
+
/**
|
|
81
|
+
* Close the database connection.
|
|
82
|
+
*/
|
|
83
|
+
close(): void;
|
|
84
|
+
}
|
|
85
|
+
export declare function getCostTracker(): CostTracker;
|
|
86
|
+
export declare function resetCostTracker(): void;
|
|
87
|
+
//# sourceMappingURL=cost-tracker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cost-tracker.d.ts","sourceRoot":"","sources":["../../src/services/cost-tracker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAwBH,MAAM,MAAM,oBAAoB,GAAG,UAAU,GAAG,OAAO,GAAG,SAAS,GAAG,aAAa,GAAG,gBAAgB,GAAG,cAAc,GAAG,YAAY,CAAC;AAEvI,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,oBAAoB,CAAC;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,WAAW,CAAC;IACnB,QAAQ,EAAE,WAAW,CAAC;IACtB,SAAS,EAAE,WAAW,CAAC;IACvB,OAAO,EAAE,WAAW,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACzC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACrC,WAAW,EAAE,KAAK,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,KAAK,EAAE,MAAM,CAAC;QACd,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC;QACrB,gBAAgB,EAAE,MAAM,CAAC;QACzB,UAAU,EAAE,MAAM,CAAC;QACnB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC,CAAC;CACJ;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,EAAE,CAAkC;IAC5C,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,SAAS,CAAS;IAG1B,OAAO,CAAC,UAAU,CAAmC;IACrD,OAAO,CAAC,WAAW,CAAmC;gBAE1C,UAAU,CAAC,EAAE,MAAM;IAYzB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IA0CjC,OAAO,CAAC,iBAAiB;IASzB;;OAEG;IACH,OAAO,CAAC,aAAa;IAOrB;;OAEG;IACH,GAAG,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI;IAiChC;;OAEG;IACH,UAAU,IAAI,mBAAmB;IAiHjC;;OAEG;IACH,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,WAAW,GAAG;QAAE,WAAW,EAAE,GAAG,EAAE,CAAA;KAAE;IA2CxE,OAAO,CAAC,YAAY;IAUpB,OAAO,CAAC,oBAAoB;IAa5B;;OAEG;IACH,KAAK,IAAI,IAAI;CAOd;AAKD,wBAAgB,cAAc,IAAI,WAAW,CAK5C;AAGD,wBAAgB,gBAAgB,IAAI,IAAI,CAKvC"}
|
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CostTracker - Tracks LLM API costs for insights generation.
|
|
3
|
+
*
|
|
4
|
+
* Provides:
|
|
5
|
+
* - Per-call cost logging with session, operation, model, tokens
|
|
6
|
+
* - Summary queries (today, this week, by operation, by model)
|
|
7
|
+
* - Cost estimation using current Anthropic pricing
|
|
8
|
+
*
|
|
9
|
+
* Design decisions:
|
|
10
|
+
* - Separate table from session insights for clean separation
|
|
11
|
+
* - Uses same database file for simplicity
|
|
12
|
+
* - Costs stored in USD for consistency
|
|
13
|
+
*/
|
|
14
|
+
import Database from 'better-sqlite3';
|
|
15
|
+
import path from 'path';
|
|
16
|
+
import fs from 'fs';
|
|
17
|
+
import { createLogger } from './logger.js';
|
|
18
|
+
import { CONFIG_DIR } from '../utils/constants.js';
|
|
19
|
+
// Anthropic pricing as of Jan 2026 (per 1M tokens)
|
|
20
|
+
const PRICING = {
|
|
21
|
+
// Claude 4.5 models
|
|
22
|
+
'claude-opus-4-5-20251101': { input: 15.0, output: 75.0 },
|
|
23
|
+
'claude-opus-4-5': { input: 15.0, output: 75.0 },
|
|
24
|
+
'claude-sonnet-4-5-20250929': { input: 3.0, output: 15.0 },
|
|
25
|
+
'claude-sonnet-4-5': { input: 3.0, output: 15.0 },
|
|
26
|
+
'claude-haiku-4-5-20251001': { input: 0.80, output: 4.0 },
|
|
27
|
+
'claude-haiku-4-5': { input: 0.80, output: 4.0 },
|
|
28
|
+
// Legacy models (fallback)
|
|
29
|
+
'claude-3-haiku-20240307': { input: 0.25, output: 1.25 },
|
|
30
|
+
};
|
|
31
|
+
// Default pricing for unknown models
|
|
32
|
+
const DEFAULT_PRICING = { input: 3.0, output: 15.0 };
|
|
33
|
+
export class CostTracker {
|
|
34
|
+
logger;
|
|
35
|
+
db = null;
|
|
36
|
+
isInitialized = false;
|
|
37
|
+
dbPath;
|
|
38
|
+
configDir;
|
|
39
|
+
// Prepared statements for performance
|
|
40
|
+
insertStmt = null;
|
|
41
|
+
summaryStmt = null;
|
|
42
|
+
constructor(testDbPath) {
|
|
43
|
+
this.logger = createLogger('CostTracker');
|
|
44
|
+
if (testDbPath) {
|
|
45
|
+
this.configDir = path.dirname(testDbPath);
|
|
46
|
+
this.dbPath = testDbPath;
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
this.configDir = CONFIG_DIR;
|
|
50
|
+
this.dbPath = path.join(this.configDir, 'session-info.db');
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
async initialize() {
|
|
54
|
+
if (this.isInitialized) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
try {
|
|
58
|
+
if (this.dbPath !== ':memory:' && !fs.existsSync(this.configDir)) {
|
|
59
|
+
fs.mkdirSync(this.configDir, { recursive: true });
|
|
60
|
+
}
|
|
61
|
+
this.db = new Database(this.dbPath);
|
|
62
|
+
this.db.pragma('journal_mode = WAL');
|
|
63
|
+
// Create llm_costs table
|
|
64
|
+
this.db.exec(`
|
|
65
|
+
CREATE TABLE IF NOT EXISTS llm_costs (
|
|
66
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
67
|
+
session_id TEXT NOT NULL,
|
|
68
|
+
operation TEXT NOT NULL,
|
|
69
|
+
model TEXT NOT NULL,
|
|
70
|
+
input_tokens INTEGER NOT NULL,
|
|
71
|
+
output_tokens INTEGER NOT NULL,
|
|
72
|
+
estimated_cost_usd REAL NOT NULL,
|
|
73
|
+
duration_ms INTEGER NOT NULL,
|
|
74
|
+
trace_id TEXT,
|
|
75
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
CREATE INDEX IF NOT EXISTS idx_llm_costs_session ON llm_costs(session_id);
|
|
79
|
+
CREATE INDEX IF NOT EXISTS idx_llm_costs_created ON llm_costs(created_at);
|
|
80
|
+
CREATE INDEX IF NOT EXISTS idx_llm_costs_operation ON llm_costs(operation);
|
|
81
|
+
`);
|
|
82
|
+
this.prepareStatements();
|
|
83
|
+
this.isInitialized = true;
|
|
84
|
+
this.logger.info('Cost tracker initialized');
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
this.logger.error('Failed to initialize cost tracker', { error });
|
|
88
|
+
throw error;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
prepareStatements() {
|
|
92
|
+
if (!this.db)
|
|
93
|
+
return;
|
|
94
|
+
this.insertStmt = this.db.prepare(`
|
|
95
|
+
INSERT INTO llm_costs (session_id, operation, model, input_tokens, output_tokens, estimated_cost_usd, duration_ms, trace_id, created_at)
|
|
96
|
+
VALUES (@sessionId, @operation, @model, @inputTokens, @outputTokens, @estimatedCostUsd, @durationMs, @traceId, datetime('now'))
|
|
97
|
+
`);
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Calculate cost in USD for a given model and token counts.
|
|
101
|
+
*/
|
|
102
|
+
calculateCost(model, inputTokens, outputTokens) {
|
|
103
|
+
const pricing = PRICING[model] || DEFAULT_PRICING;
|
|
104
|
+
const inputCost = (inputTokens / 1_000_000) * pricing.input;
|
|
105
|
+
const outputCost = (outputTokens / 1_000_000) * pricing.output;
|
|
106
|
+
return inputCost + outputCost;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Log an LLM API call with its cost.
|
|
110
|
+
*/
|
|
111
|
+
log(record) {
|
|
112
|
+
if (!this.isInitialized || !this.insertStmt) {
|
|
113
|
+
this.logger.warn('Cost tracker not initialized, skipping log');
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
const estimatedCostUsd = this.calculateCost(record.model, record.inputTokens, record.outputTokens);
|
|
117
|
+
try {
|
|
118
|
+
this.insertStmt.run({
|
|
119
|
+
sessionId: record.sessionId,
|
|
120
|
+
operation: record.operation,
|
|
121
|
+
model: record.model,
|
|
122
|
+
inputTokens: record.inputTokens,
|
|
123
|
+
outputTokens: record.outputTokens,
|
|
124
|
+
estimatedCostUsd,
|
|
125
|
+
durationMs: record.durationMs,
|
|
126
|
+
traceId: record.traceId || null,
|
|
127
|
+
});
|
|
128
|
+
this.logger.debug('Cost logged', {
|
|
129
|
+
sessionId: record.sessionId.slice(0, 8),
|
|
130
|
+
operation: record.operation,
|
|
131
|
+
model: record.model.split('-').slice(-2).join('-'), // Just version part
|
|
132
|
+
tokens: `${record.inputTokens}/${record.outputTokens}`,
|
|
133
|
+
cost: `$${estimatedCostUsd.toFixed(4)}`,
|
|
134
|
+
durationMs: record.durationMs,
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
catch (error) {
|
|
138
|
+
this.logger.error('Failed to log cost', { error, record });
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Get cost summary for different time periods.
|
|
143
|
+
*/
|
|
144
|
+
getSummary() {
|
|
145
|
+
if (!this.isInitialized || !this.db) {
|
|
146
|
+
return this.emptySummaryResponse();
|
|
147
|
+
}
|
|
148
|
+
const now = new Date();
|
|
149
|
+
const todayStart = new Date(now.getFullYear(), now.getMonth(), now.getDate()).toISOString();
|
|
150
|
+
const weekStart = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000).toISOString();
|
|
151
|
+
const monthStart = new Date(now.getFullYear(), now.getMonth(), 1).toISOString();
|
|
152
|
+
// Helper to query summary for a date range
|
|
153
|
+
const querySummary = (startDate) => {
|
|
154
|
+
const sql = startDate
|
|
155
|
+
? `SELECT
|
|
156
|
+
COUNT(*) as calls,
|
|
157
|
+
COALESCE(SUM(input_tokens), 0) as inputTokens,
|
|
158
|
+
COALESCE(SUM(output_tokens), 0) as outputTokens,
|
|
159
|
+
COALESCE(SUM(estimated_cost_usd), 0) as estimatedCostUsd
|
|
160
|
+
FROM llm_costs
|
|
161
|
+
WHERE created_at >= ?`
|
|
162
|
+
: `SELECT
|
|
163
|
+
COUNT(*) as calls,
|
|
164
|
+
COALESCE(SUM(input_tokens), 0) as inputTokens,
|
|
165
|
+
COALESCE(SUM(output_tokens), 0) as outputTokens,
|
|
166
|
+
COALESCE(SUM(estimated_cost_usd), 0) as estimatedCostUsd
|
|
167
|
+
FROM llm_costs`;
|
|
168
|
+
const row = startDate
|
|
169
|
+
? this.db.prepare(sql).get(startDate)
|
|
170
|
+
: this.db.prepare(sql).get();
|
|
171
|
+
return {
|
|
172
|
+
calls: row.calls || 0,
|
|
173
|
+
inputTokens: row.inputTokens || 0,
|
|
174
|
+
outputTokens: row.outputTokens || 0,
|
|
175
|
+
totalTokens: (row.inputTokens || 0) + (row.outputTokens || 0),
|
|
176
|
+
estimatedCostUsd: row.estimatedCostUsd || 0,
|
|
177
|
+
};
|
|
178
|
+
};
|
|
179
|
+
// Query by operation
|
|
180
|
+
const byOperationRows = this.db.prepare(`
|
|
181
|
+
SELECT
|
|
182
|
+
operation,
|
|
183
|
+
COUNT(*) as calls,
|
|
184
|
+
COALESCE(SUM(input_tokens), 0) as inputTokens,
|
|
185
|
+
COALESCE(SUM(output_tokens), 0) as outputTokens,
|
|
186
|
+
COALESCE(SUM(estimated_cost_usd), 0) as estimatedCostUsd
|
|
187
|
+
FROM llm_costs
|
|
188
|
+
GROUP BY operation
|
|
189
|
+
`).all();
|
|
190
|
+
const byOperation = {};
|
|
191
|
+
for (const row of byOperationRows) {
|
|
192
|
+
byOperation[row.operation] = {
|
|
193
|
+
calls: row.calls,
|
|
194
|
+
inputTokens: row.inputTokens,
|
|
195
|
+
outputTokens: row.outputTokens,
|
|
196
|
+
totalTokens: row.inputTokens + row.outputTokens,
|
|
197
|
+
estimatedCostUsd: row.estimatedCostUsd,
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
// Query by model
|
|
201
|
+
const byModelRows = this.db.prepare(`
|
|
202
|
+
SELECT
|
|
203
|
+
model,
|
|
204
|
+
COUNT(*) as calls,
|
|
205
|
+
COALESCE(SUM(input_tokens), 0) as inputTokens,
|
|
206
|
+
COALESCE(SUM(output_tokens), 0) as outputTokens,
|
|
207
|
+
COALESCE(SUM(estimated_cost_usd), 0) as estimatedCostUsd
|
|
208
|
+
FROM llm_costs
|
|
209
|
+
GROUP BY model
|
|
210
|
+
`).all();
|
|
211
|
+
const byModel = {};
|
|
212
|
+
for (const row of byModelRows) {
|
|
213
|
+
byModel[row.model] = {
|
|
214
|
+
calls: row.calls,
|
|
215
|
+
inputTokens: row.inputTokens,
|
|
216
|
+
outputTokens: row.outputTokens,
|
|
217
|
+
totalTokens: row.inputTokens + row.outputTokens,
|
|
218
|
+
estimatedCostUsd: row.estimatedCostUsd,
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
// Get recent calls for debugging/visibility
|
|
222
|
+
const recentCalls = this.db.prepare(`
|
|
223
|
+
SELECT
|
|
224
|
+
session_id as sessionId,
|
|
225
|
+
operation,
|
|
226
|
+
model,
|
|
227
|
+
input_tokens as inputTokens,
|
|
228
|
+
output_tokens as outputTokens,
|
|
229
|
+
estimated_cost_usd as estimatedCostUsd,
|
|
230
|
+
duration_ms as durationMs,
|
|
231
|
+
created_at as createdAt
|
|
232
|
+
FROM llm_costs
|
|
233
|
+
ORDER BY created_at DESC
|
|
234
|
+
LIMIT 20
|
|
235
|
+
`).all();
|
|
236
|
+
return {
|
|
237
|
+
today: querySummary(todayStart),
|
|
238
|
+
thisWeek: querySummary(weekStart),
|
|
239
|
+
thisMonth: querySummary(monthStart),
|
|
240
|
+
allTime: querySummary(),
|
|
241
|
+
byOperation,
|
|
242
|
+
byModel,
|
|
243
|
+
recentCalls,
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Get costs for a specific session.
|
|
248
|
+
*/
|
|
249
|
+
getSessionCosts(sessionId) {
|
|
250
|
+
if (!this.isInitialized || !this.db) {
|
|
251
|
+
return {
|
|
252
|
+
...this.emptySummary(),
|
|
253
|
+
recentCalls: [],
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
const summary = this.db.prepare(`
|
|
257
|
+
SELECT
|
|
258
|
+
COUNT(*) as calls,
|
|
259
|
+
COALESCE(SUM(input_tokens), 0) as inputTokens,
|
|
260
|
+
COALESCE(SUM(output_tokens), 0) as outputTokens,
|
|
261
|
+
COALESCE(SUM(estimated_cost_usd), 0) as estimatedCostUsd
|
|
262
|
+
FROM llm_costs
|
|
263
|
+
WHERE session_id = ?
|
|
264
|
+
`).get(sessionId);
|
|
265
|
+
const recentCalls = this.db.prepare(`
|
|
266
|
+
SELECT
|
|
267
|
+
operation,
|
|
268
|
+
model,
|
|
269
|
+
input_tokens as inputTokens,
|
|
270
|
+
output_tokens as outputTokens,
|
|
271
|
+
estimated_cost_usd as estimatedCostUsd,
|
|
272
|
+
duration_ms as durationMs,
|
|
273
|
+
created_at as createdAt
|
|
274
|
+
FROM llm_costs
|
|
275
|
+
WHERE session_id = ?
|
|
276
|
+
ORDER BY created_at DESC
|
|
277
|
+
LIMIT 10
|
|
278
|
+
`).all(sessionId);
|
|
279
|
+
return {
|
|
280
|
+
calls: summary?.calls || 0,
|
|
281
|
+
inputTokens: summary?.inputTokens || 0,
|
|
282
|
+
outputTokens: summary?.outputTokens || 0,
|
|
283
|
+
totalTokens: (summary?.inputTokens || 0) + (summary?.outputTokens || 0),
|
|
284
|
+
estimatedCostUsd: summary?.estimatedCostUsd || 0,
|
|
285
|
+
recentCalls,
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
emptySummary() {
|
|
289
|
+
return {
|
|
290
|
+
calls: 0,
|
|
291
|
+
inputTokens: 0,
|
|
292
|
+
outputTokens: 0,
|
|
293
|
+
totalTokens: 0,
|
|
294
|
+
estimatedCostUsd: 0,
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
emptySummaryResponse() {
|
|
298
|
+
const empty = this.emptySummary();
|
|
299
|
+
return {
|
|
300
|
+
today: empty,
|
|
301
|
+
thisWeek: empty,
|
|
302
|
+
thisMonth: empty,
|
|
303
|
+
allTime: empty,
|
|
304
|
+
byOperation: {},
|
|
305
|
+
byModel: {},
|
|
306
|
+
recentCalls: [],
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Close the database connection.
|
|
311
|
+
*/
|
|
312
|
+
close() {
|
|
313
|
+
if (this.db) {
|
|
314
|
+
this.db.close();
|
|
315
|
+
this.db = null;
|
|
316
|
+
this.isInitialized = false;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
// Singleton instance
|
|
321
|
+
let instance = null;
|
|
322
|
+
export function getCostTracker() {
|
|
323
|
+
if (!instance) {
|
|
324
|
+
instance = new CostTracker();
|
|
325
|
+
}
|
|
326
|
+
return instance;
|
|
327
|
+
}
|
|
328
|
+
// For testing
|
|
329
|
+
export function resetCostTracker() {
|
|
330
|
+
if (instance) {
|
|
331
|
+
instance.close();
|
|
332
|
+
instance = null;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
//# sourceMappingURL=cost-tracker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cost-tracker.js","sourceRoot":"","sources":["../../src/services/cost-tracker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { FileSystemEntry } from '../types/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Service for secure file system operations
|
|
4
|
+
*/
|
|
5
|
+
export declare class FileSystemService {
|
|
6
|
+
private logger;
|
|
7
|
+
private maxFileSize;
|
|
8
|
+
private allowedBasePaths;
|
|
9
|
+
constructor(maxFileSize?: number, allowedBasePaths?: string[]);
|
|
10
|
+
/**
|
|
11
|
+
* List directory contents with security checks
|
|
12
|
+
*/
|
|
13
|
+
listDirectory(requestedPath: string, recursive?: boolean, respectGitignore?: boolean): Promise<{
|
|
14
|
+
path: string;
|
|
15
|
+
entries: FileSystemEntry[];
|
|
16
|
+
total: number;
|
|
17
|
+
}>;
|
|
18
|
+
/**
|
|
19
|
+
* Read file contents with security checks
|
|
20
|
+
*/
|
|
21
|
+
readFile(requestedPath: string): Promise<{
|
|
22
|
+
path: string;
|
|
23
|
+
content: string;
|
|
24
|
+
size: number;
|
|
25
|
+
lastModified: string;
|
|
26
|
+
encoding: string;
|
|
27
|
+
}>;
|
|
28
|
+
/**
|
|
29
|
+
* Validate and normalize a path to prevent path traversal attacks
|
|
30
|
+
*/
|
|
31
|
+
private validatePath;
|
|
32
|
+
/**
|
|
33
|
+
* Check if content appears to be valid UTF-8 text
|
|
34
|
+
*/
|
|
35
|
+
private isValidUtf8;
|
|
36
|
+
/**
|
|
37
|
+
* List directory contents without recursion
|
|
38
|
+
*/
|
|
39
|
+
private listDirectoryFlat;
|
|
40
|
+
/**
|
|
41
|
+
* List directory contents recursively
|
|
42
|
+
*/
|
|
43
|
+
private listDirectoryRecursive;
|
|
44
|
+
/**
|
|
45
|
+
* Load gitignore patterns from a directory and its parents
|
|
46
|
+
*/
|
|
47
|
+
private loadGitignore;
|
|
48
|
+
/**
|
|
49
|
+
* Check if a directory is a git repository
|
|
50
|
+
*/
|
|
51
|
+
isGitRepository(dirPath: string): Promise<boolean>;
|
|
52
|
+
/**
|
|
53
|
+
* Get current git HEAD commit hash
|
|
54
|
+
*/
|
|
55
|
+
getCurrentGitHead(dirPath: string): Promise<string | null>;
|
|
56
|
+
/**
|
|
57
|
+
* Validate that an executable exists and has executable permissions
|
|
58
|
+
*/
|
|
59
|
+
validateExecutable(executablePath: string): Promise<void>;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=file-system-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-system-service.d.ts","sourceRoot":"","sources":["../../src/services/file-system-service.ts"],"names":[],"mappings":"AAMA,OAAO,EAAY,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAM7D;;GAEG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,WAAW,CAA4B;IAC/C,OAAO,CAAC,gBAAgB,CAAgB;gBAE5B,WAAW,CAAC,EAAE,MAAM,EAAE,gBAAgB,CAAC,EAAE,MAAM,EAAE;IAU7D;;OAEG;IACG,aAAa,CACjB,aAAa,EAAE,MAAM,EACrB,SAAS,GAAE,OAAe,EAC1B,gBAAgB,GAAE,OAAe,GAChC,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,eAAe,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IA6DvE;;OAEG;IACG,QAAQ,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IA2DvI;;OAEG;YACW,YAAY;IA2E1B;;OAEG;IACH,OAAO,CAAC,WAAW;IAqBnB;;OAEG;YACW,iBAAiB;IA0B/B;;OAEG;YACW,sBAAsB;IAuCpC;;OAEG;YACW,aAAa;IAuB3B;;OAEG;IACG,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAUxD;;OAEG;IACG,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAUhE;;OAEG;IACG,kBAAkB,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAsChE"}
|