@codemieai/code 0.4.1 → 0.5.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 (167) hide show
  1. package/README.md +7 -1
  2. package/bin/codemie-kimi-acp.js +18 -0
  3. package/bin/codemie-kimi.js +18 -0
  4. package/dist/agents/core/AgentCLI.d.ts.map +1 -1
  5. package/dist/agents/core/AgentCLI.js +4 -0
  6. package/dist/agents/core/AgentCLI.js.map +1 -1
  7. package/dist/agents/core/BaseAgentAdapter.d.ts.map +1 -1
  8. package/dist/agents/core/BaseAgentAdapter.js +26 -6
  9. package/dist/agents/core/BaseAgentAdapter.js.map +1 -1
  10. package/dist/agents/core/metrics/types.d.ts +4 -1
  11. package/dist/agents/core/metrics/types.d.ts.map +1 -1
  12. package/dist/agents/core/session/BaseProcessor.d.ts +2 -0
  13. package/dist/agents/core/session/BaseProcessor.d.ts.map +1 -1
  14. package/dist/agents/core/session/BaseSessionAdapter.d.ts +10 -0
  15. package/dist/agents/core/session/BaseSessionAdapter.d.ts.map +1 -1
  16. package/dist/agents/core/types.d.ts +30 -0
  17. package/dist/agents/core/types.d.ts.map +1 -1
  18. package/dist/agents/plugins/claude/claude.plugin.js +3 -3
  19. package/dist/agents/plugins/claude/claude.session.d.ts.map +1 -1
  20. package/dist/agents/plugins/claude/claude.session.js +29 -7
  21. package/dist/agents/plugins/claude/claude.session.js.map +1 -1
  22. package/dist/agents/plugins/claude/session/claude-named-invocations.d.ts +28 -0
  23. package/dist/agents/plugins/claude/session/claude-named-invocations.d.ts.map +1 -0
  24. package/dist/agents/plugins/claude/session/claude-named-invocations.js +78 -0
  25. package/dist/agents/plugins/claude/session/claude-named-invocations.js.map +1 -0
  26. package/dist/agents/plugins/claude/session/processors/claude.metrics-processor.d.ts.map +1 -1
  27. package/dist/agents/plugins/claude/session/processors/claude.metrics-processor.js +10 -1
  28. package/dist/agents/plugins/claude/session/processors/claude.metrics-processor.js.map +1 -1
  29. package/dist/agents/plugins/gemini/gemini.plugin.js.map +1 -1
  30. package/dist/agents/plugins/gemini/session/processors/gemini.metrics-processor.d.ts.map +1 -1
  31. package/dist/agents/plugins/gemini/session/processors/gemini.metrics-processor.js +3 -0
  32. package/dist/agents/plugins/gemini/session/processors/gemini.metrics-processor.js.map +1 -1
  33. package/dist/agents/plugins/kimi/extension/SKILL.md +6 -0
  34. package/dist/agents/plugins/kimi/extension/manifest.json +8 -0
  35. package/dist/agents/plugins/kimi/kimi-acp.plugin.d.ts +7 -0
  36. package/dist/agents/plugins/kimi/kimi-acp.plugin.d.ts.map +1 -0
  37. package/dist/agents/plugins/kimi/kimi-acp.plugin.js +28 -0
  38. package/dist/agents/plugins/kimi/kimi-acp.plugin.js.map +1 -0
  39. package/dist/agents/plugins/kimi/kimi.extension-installer.d.ts +56 -0
  40. package/dist/agents/plugins/kimi/kimi.extension-installer.d.ts.map +1 -0
  41. package/dist/agents/plugins/kimi/kimi.extension-installer.js +79 -0
  42. package/dist/agents/plugins/kimi/kimi.extension-installer.js.map +1 -0
  43. package/dist/agents/plugins/kimi/kimi.hook-config-injector.d.ts +34 -0
  44. package/dist/agents/plugins/kimi/kimi.hook-config-injector.d.ts.map +1 -0
  45. package/dist/agents/plugins/kimi/kimi.hook-config-injector.js +158 -0
  46. package/dist/agents/plugins/kimi/kimi.hook-config-injector.js.map +1 -0
  47. package/dist/agents/plugins/kimi/kimi.hook-transformer.d.ts +23 -0
  48. package/dist/agents/plugins/kimi/kimi.hook-transformer.d.ts.map +1 -0
  49. package/dist/agents/plugins/kimi/kimi.hook-transformer.js +46 -0
  50. package/dist/agents/plugins/kimi/kimi.hook-transformer.js.map +1 -0
  51. package/dist/agents/plugins/kimi/kimi.models.d.ts +8 -0
  52. package/dist/agents/plugins/kimi/kimi.models.d.ts.map +1 -0
  53. package/dist/agents/plugins/kimi/kimi.models.js +174 -0
  54. package/dist/agents/plugins/kimi/kimi.models.js.map +1 -0
  55. package/dist/agents/plugins/kimi/kimi.paths.d.ts +65 -0
  56. package/dist/agents/plugins/kimi/kimi.paths.d.ts.map +1 -0
  57. package/dist/agents/plugins/kimi/kimi.paths.js +95 -0
  58. package/dist/agents/plugins/kimi/kimi.paths.js.map +1 -0
  59. package/dist/agents/plugins/kimi/kimi.plugin.d.ts +37 -0
  60. package/dist/agents/plugins/kimi/kimi.plugin.d.ts.map +1 -0
  61. package/dist/agents/plugins/kimi/kimi.plugin.js +318 -0
  62. package/dist/agents/plugins/kimi/kimi.plugin.js.map +1 -0
  63. package/dist/agents/plugins/kimi/kimi.session.d.ts +40 -0
  64. package/dist/agents/plugins/kimi/kimi.session.d.ts.map +1 -0
  65. package/dist/agents/plugins/kimi/kimi.session.js +191 -0
  66. package/dist/agents/plugins/kimi/kimi.session.js.map +1 -0
  67. package/dist/agents/plugins/kimi/session/processors/kimi.metrics-processor.d.ts +43 -0
  68. package/dist/agents/plugins/kimi/session/processors/kimi.metrics-processor.d.ts.map +1 -0
  69. package/dist/agents/plugins/kimi/session/processors/kimi.metrics-processor.js +421 -0
  70. package/dist/agents/plugins/kimi/session/processors/kimi.metrics-processor.js.map +1 -0
  71. package/dist/agents/plugins/kimi/session/types.d.ts +81 -0
  72. package/dist/agents/plugins/kimi/session/types.d.ts.map +1 -0
  73. package/dist/agents/plugins/kimi/session/types.js +5 -0
  74. package/dist/agents/plugins/kimi/session/types.js.map +1 -0
  75. package/dist/agents/registry.d.ts.map +1 -1
  76. package/dist/agents/registry.js +4 -0
  77. package/dist/agents/registry.js.map +1 -1
  78. package/dist/cli/commands/analytics/aggregator.d.ts +14 -0
  79. package/dist/cli/commands/analytics/aggregator.d.ts.map +1 -1
  80. package/dist/cli/commands/analytics/aggregator.js +81 -1
  81. package/dist/cli/commands/analytics/aggregator.js.map +1 -1
  82. package/dist/cli/commands/analytics/cost/cost-calculator.d.ts +10 -0
  83. package/dist/cli/commands/analytics/cost/cost-calculator.d.ts.map +1 -1
  84. package/dist/cli/commands/analytics/cost/cost-calculator.js +9 -5
  85. package/dist/cli/commands/analytics/cost/cost-calculator.js.map +1 -1
  86. package/dist/cli/commands/analytics/cost/cost-enricher.d.ts +9 -1
  87. package/dist/cli/commands/analytics/cost/cost-enricher.d.ts.map +1 -1
  88. package/dist/cli/commands/analytics/cost/cost-enricher.js +141 -7
  89. package/dist/cli/commands/analytics/cost/cost-enricher.js.map +1 -1
  90. package/dist/cli/commands/analytics/cost/dispatch-extractor.d.ts +17 -0
  91. package/dist/cli/commands/analytics/cost/dispatch-extractor.d.ts.map +1 -0
  92. package/dist/cli/commands/analytics/cost/dispatch-extractor.js +78 -0
  93. package/dist/cli/commands/analytics/cost/dispatch-extractor.js.map +1 -0
  94. package/dist/cli/commands/analytics/cost/pricing.json +9 -2
  95. package/dist/cli/commands/analytics/cost/types.d.ts +33 -0
  96. package/dist/cli/commands/analytics/cost/types.d.ts.map +1 -1
  97. package/dist/cli/commands/analytics/cost/types.js +4 -1
  98. package/dist/cli/commands/analytics/cost/types.js.map +1 -1
  99. package/dist/cli/commands/analytics/cost/usage-readers.d.ts +22 -1
  100. package/dist/cli/commands/analytics/cost/usage-readers.d.ts.map +1 -1
  101. package/dist/cli/commands/analytics/cost/usage-readers.js +147 -21
  102. package/dist/cli/commands/analytics/cost/usage-readers.js.map +1 -1
  103. package/dist/cli/commands/analytics/model-normalizer.d.ts +2 -0
  104. package/dist/cli/commands/analytics/model-normalizer.d.ts.map +1 -1
  105. package/dist/cli/commands/analytics/model-normalizer.js +8 -0
  106. package/dist/cli/commands/analytics/model-normalizer.js.map +1 -1
  107. package/dist/cli/commands/analytics/native-loader.d.ts.map +1 -1
  108. package/dist/cli/commands/analytics/native-loader.js +35 -0
  109. package/dist/cli/commands/analytics/native-loader.js.map +1 -1
  110. package/dist/cli/commands/analytics/report/client/app.js +685 -53
  111. package/dist/cli/commands/analytics/report/payload-builder.d.ts.map +1 -1
  112. package/dist/cli/commands/analytics/report/payload-builder.js +13 -0
  113. package/dist/cli/commands/analytics/report/payload-builder.js.map +1 -1
  114. package/dist/cli/commands/analytics/report/template.html +108 -8
  115. package/dist/cli/commands/analytics/report/types.d.ts +13 -2
  116. package/dist/cli/commands/analytics/report/types.d.ts.map +1 -1
  117. package/dist/cli/commands/analytics/types.d.ts +18 -0
  118. package/dist/cli/commands/analytics/types.d.ts.map +1 -1
  119. package/dist/cli/commands/hook.d.ts.map +1 -1
  120. package/dist/cli/commands/hook.js +24 -7
  121. package/dist/cli/commands/hook.js.map +1 -1
  122. package/dist/migrations/004-skills-assistants-top-level.migration.d.ts.map +1 -1
  123. package/dist/migrations/004-skills-assistants-top-level.migration.js +8 -5
  124. package/dist/migrations/004-skills-assistants-top-level.migration.js.map +1 -1
  125. package/dist/migrations/005-skill-slug-format.migration.d.ts.map +1 -1
  126. package/dist/migrations/005-skill-slug-format.migration.js +14 -11
  127. package/dist/migrations/005-skill-slug-format.migration.js.map +1 -1
  128. package/dist/providers/index.d.ts +2 -0
  129. package/dist/providers/index.d.ts.map +1 -1
  130. package/dist/providers/index.js +2 -0
  131. package/dist/providers/index.js.map +1 -1
  132. package/dist/providers/plugins/moonshot-subscription/index.d.ts +9 -0
  133. package/dist/providers/plugins/moonshot-subscription/index.d.ts.map +1 -0
  134. package/dist/providers/plugins/moonshot-subscription/index.js +9 -0
  135. package/dist/providers/plugins/moonshot-subscription/index.js.map +1 -0
  136. package/dist/providers/plugins/moonshot-subscription/moonshot-subscription.setup-steps.d.ts +8 -0
  137. package/dist/providers/plugins/moonshot-subscription/moonshot-subscription.setup-steps.d.ts.map +1 -0
  138. package/dist/providers/plugins/moonshot-subscription/moonshot-subscription.setup-steps.js +80 -0
  139. package/dist/providers/plugins/moonshot-subscription/moonshot-subscription.setup-steps.js.map +1 -0
  140. package/dist/providers/plugins/moonshot-subscription/moonshot-subscription.template.d.ts +11 -0
  141. package/dist/providers/plugins/moonshot-subscription/moonshot-subscription.template.d.ts.map +1 -0
  142. package/dist/providers/plugins/moonshot-subscription/moonshot-subscription.template.js +111 -0
  143. package/dist/providers/plugins/moonshot-subscription/moonshot-subscription.template.js.map +1 -0
  144. package/dist/providers/plugins/sso/proxy/plugins/index.d.ts +2 -1
  145. package/dist/providers/plugins/sso/proxy/plugins/index.d.ts.map +1 -1
  146. package/dist/providers/plugins/sso/proxy/plugins/index.js +3 -1
  147. package/dist/providers/plugins/sso/proxy/plugins/index.js.map +1 -1
  148. package/dist/providers/plugins/sso/proxy/plugins/kimi-request-normalizer.plugin.d.ts +18 -0
  149. package/dist/providers/plugins/sso/proxy/plugins/kimi-request-normalizer.plugin.d.ts.map +1 -0
  150. package/dist/providers/plugins/sso/proxy/plugins/kimi-request-normalizer.plugin.js +56 -0
  151. package/dist/providers/plugins/sso/proxy/plugins/kimi-request-normalizer.plugin.js.map +1 -0
  152. package/dist/providers/plugins/sso/session/processors/conversations/constants.d.ts +1 -1
  153. package/dist/providers/plugins/sso/session/processors/conversations/constants.js +1 -1
  154. package/dist/providers/plugins/sso/sso.auth.d.ts +5 -0
  155. package/dist/providers/plugins/sso/sso.auth.d.ts.map +1 -1
  156. package/dist/providers/plugins/sso/sso.auth.js +23 -1
  157. package/dist/providers/plugins/sso/sso.auth.js.map +1 -1
  158. package/dist/utils/config.d.ts +24 -0
  159. package/dist/utils/config.d.ts.map +1 -1
  160. package/dist/utils/config.js +83 -8
  161. package/dist/utils/config.js.map +1 -1
  162. package/dist/utils/native-installer.d.ts.map +1 -1
  163. package/dist/utils/native-installer.js +6 -3
  164. package/dist/utils/native-installer.js.map +1 -1
  165. package/package.json +5 -1
  166. package/scripts/copy-plugins.js +5 -0
  167. package/scripts/test-desktop-telemetry.js +1 -1
@@ -0,0 +1,191 @@
1
+ /**
2
+ * Kimi Session Adapter
3
+ *
4
+ * Parses Kimi Code `wire.jsonl` session transcripts into the unified
5
+ * ParsedSession format used by CodeMie processors.
6
+ *
7
+ * Wire file path:
8
+ * ${KIMI_CODE_HOME}/sessions/{workDirKey}/{sessionId}/agents/main/wire.jsonl
9
+ */
10
+ import { readJSONLTolerant } from '../../core/session/utils/jsonl-reader.js';
11
+ import { logger } from '../../../utils/logger.js';
12
+ import { KimiMetricsProcessor } from './session/processors/kimi.metrics-processor.js';
13
+ export class KimiSessionAdapter {
14
+ metadata;
15
+ agentName = 'kimi';
16
+ processors = [];
17
+ constructor(metadata) {
18
+ this.metadata = metadata;
19
+ // Register processors now, but execution is currently orchestrated externally
20
+ // until processSession is implemented.
21
+ this.initializeProcessors();
22
+ }
23
+ initializeProcessors() {
24
+ this.registerProcessor(new KimiMetricsProcessor());
25
+ logger.debug(`[kimi-adapter] Initialized ${this.processors.length} processors`);
26
+ }
27
+ registerProcessor(processor) {
28
+ this.processors.push(processor);
29
+ this.processors.sort((a, b) => a.priority - b.priority);
30
+ logger.debug(`[kimi-adapter] Registered processor: ${processor.name} (priority: ${processor.priority})`);
31
+ }
32
+ /**
33
+ * Discover native Kimi sessions (placeholder).
34
+ */
35
+ async discoverSessions(_options) {
36
+ logger.debug('[kimi-adapter] discoverSessions is not implemented yet');
37
+ return [];
38
+ }
39
+ /**
40
+ * Parse a Kimi `wire.jsonl` file into the unified ParsedSession format.
41
+ */
42
+ async parseSessionFile(filePath, sessionId) {
43
+ try {
44
+ const events = await readJSONLTolerant(filePath, '[kimi-adapter]');
45
+ if (events.length === 0) {
46
+ logger.debug(`[kimi-adapter] Session file is empty or unreadable: ${filePath}`);
47
+ return this.createMinimalSession(sessionId);
48
+ }
49
+ const model = this.extractModel(events);
50
+ const { createdAt, updatedAt } = this.extractTimestamps(events);
51
+ logger.debug(`[kimi-adapter] Parsed session ${sessionId}: ${events.length} events, ` +
52
+ `model=${model ?? 'unknown'}`);
53
+ const metadata = {
54
+ projectPath: filePath,
55
+ createdAt,
56
+ updatedAt,
57
+ model,
58
+ };
59
+ return {
60
+ sessionId,
61
+ agentName: this.metadata.displayName || 'Kimi Code',
62
+ metadata,
63
+ messages: events,
64
+ };
65
+ }
66
+ catch (error) {
67
+ logger.warn(`[kimi-adapter] Failed to parse session file ${filePath}:`, error);
68
+ return this.createMinimalSession(sessionId);
69
+ }
70
+ }
71
+ /**
72
+ * Process a Kimi session file with all registered processors.
73
+ *
74
+ * Parses the wire.jsonl file once, runs each registered processor in priority
75
+ * order, and returns an aggregated result. This is the entry point used by
76
+ * `codemie hook` during incremental sync.
77
+ */
78
+ async processSession(filePath, sessionId, context) {
79
+ try {
80
+ logger.debug(`[kimi-adapter] Processing session ${sessionId} with ${this.processors.length} processor${this.processors.length !== 1 ? 's' : ''}`);
81
+ const parsedSession = await this.parseSessionFile(filePath, sessionId);
82
+ // Enrich parsed session with hook-time context that is not in the native transcript.
83
+ if (context.gitBranch) {
84
+ parsedSession.metadata = {
85
+ ...parsedSession.metadata,
86
+ gitBranch: context.gitBranch,
87
+ };
88
+ }
89
+ const processorResults = {};
90
+ const failedProcessors = [];
91
+ let totalRecords = 0;
92
+ for (const processor of this.processors) {
93
+ try {
94
+ if (!processor.shouldProcess(parsedSession)) {
95
+ logger.debug(`[kimi-adapter] Processor ${processor.name} skipped (shouldProcess returned false)`);
96
+ continue;
97
+ }
98
+ logger.debug(`[kimi-adapter] Running processor: ${processor.name}`);
99
+ const result = await processor.process(parsedSession, context);
100
+ processorResults[processor.name] = {
101
+ success: result.success,
102
+ message: result.message,
103
+ recordsProcessed: result.metadata?.recordsProcessed,
104
+ };
105
+ if (!result.success) {
106
+ failedProcessors.push(processor.name);
107
+ logger.warn(`[kimi-adapter] Processor ${processor.name} failed: ${result.message}`);
108
+ }
109
+ else {
110
+ logger.debug(`[kimi-adapter] Processor ${processor.name} succeeded: ${result.message}`);
111
+ }
112
+ const recordsProcessed = result.metadata?.recordsProcessed;
113
+ if (typeof recordsProcessed === 'number') {
114
+ totalRecords += recordsProcessed;
115
+ }
116
+ }
117
+ catch (error) {
118
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
119
+ logger.error(`[kimi-adapter] Processor ${processor.name} threw error:`, error);
120
+ processorResults[processor.name] = {
121
+ success: false,
122
+ message: errorMessage,
123
+ };
124
+ failedProcessors.push(processor.name);
125
+ }
126
+ }
127
+ const result = {
128
+ success: failedProcessors.length === 0,
129
+ processors: processorResults,
130
+ totalRecords,
131
+ failedProcessors,
132
+ };
133
+ logger.debug(`[kimi-adapter] Processing complete: ${result.success ? 'SUCCESS' : 'FAILED'} ` +
134
+ `(${totalRecords} records, ${failedProcessors.length} failed processors)`);
135
+ return result;
136
+ }
137
+ catch (error) {
138
+ logger.error(`[kimi-adapter] Session processing failed:`, error);
139
+ throw error;
140
+ }
141
+ }
142
+ createMinimalSession(sessionId) {
143
+ const metadata = {
144
+ createdAt: undefined,
145
+ updatedAt: undefined,
146
+ model: undefined,
147
+ };
148
+ return {
149
+ sessionId,
150
+ agentName: this.metadata.displayName || 'Kimi Code',
151
+ metadata,
152
+ messages: [],
153
+ };
154
+ }
155
+ extractModel(events) {
156
+ for (const event of events) {
157
+ if (event.type === 'config.update' && event.modelAlias) {
158
+ return event.modelAlias;
159
+ }
160
+ }
161
+ for (const event of events) {
162
+ if (event.type === 'usage.record' && event.model) {
163
+ return event.model;
164
+ }
165
+ }
166
+ return undefined;
167
+ }
168
+ extractTimestamps(events) {
169
+ let createdAt;
170
+ let updatedAt;
171
+ for (const event of events) {
172
+ if (typeof event.time === 'number') {
173
+ createdAt = new Date(event.time).toISOString();
174
+ break;
175
+ }
176
+ if (typeof event.created_at === 'number') {
177
+ createdAt = new Date(event.created_at).toISOString();
178
+ break;
179
+ }
180
+ }
181
+ for (let i = events.length - 1; i >= 0; i--) {
182
+ const event = events[i];
183
+ if (typeof event.time === 'number') {
184
+ updatedAt = new Date(event.time).toISOString();
185
+ break;
186
+ }
187
+ }
188
+ return { createdAt, updatedAt };
189
+ }
190
+ }
191
+ //# sourceMappingURL=kimi.session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kimi.session.js","sourceRoot":"","sources":["../../../../src/agents/plugins/kimi/kimi.session.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAWH,OAAO,EAAE,iBAAiB,EAAE,MAAM,0CAA0C,CAAC;AAC7E,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAClD,OAAO,EAAE,oBAAoB,EAAE,MAAM,gDAAgD,CAAC;AAGtF,MAAM,OAAO,kBAAkB;IAIA;IAHpB,SAAS,GAAG,MAAM,CAAC;IACpB,UAAU,GAAuB,EAAE,CAAC;IAE5C,YAA6B,QAAuB;QAAvB,aAAQ,GAAR,QAAQ,CAAe;QAClD,8EAA8E;QAC9E,uCAAuC;QACvC,IAAI,CAAC,oBAAoB,EAAE,CAAC;IAC9B,CAAC;IAEO,oBAAoB;QAC1B,IAAI,CAAC,iBAAiB,CAAC,IAAI,oBAAoB,EAAE,CAAC,CAAC;QACnD,MAAM,CAAC,KAAK,CAAC,8BAA8B,IAAI,CAAC,UAAU,CAAC,MAAM,aAAa,CAAC,CAAC;IAClF,CAAC;IAED,iBAAiB,CAAC,SAA2B;QAC3C,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAChC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC;QACxD,MAAM,CAAC,KAAK,CAAC,wCAAwC,SAAS,CAAC,IAAI,eAAe,SAAS,CAAC,QAAQ,GAAG,CAAC,CAAC;IAC3G,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,gBAAgB,CAAC,QAAkC;QACvD,MAAM,CAAC,KAAK,CAAC,wDAAwD,CAAC,CAAC;QACvE,OAAO,EAAE,CAAC;IACZ,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,gBAAgB,CAAC,QAAgB,EAAE,SAAiB;QACxD,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAgB,QAAQ,EAAE,gBAAgB,CAAC,CAAC;YAElF,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACxB,MAAM,CAAC,KAAK,CAAC,uDAAuD,QAAQ,EAAE,CAAC,CAAC;gBAChF,OAAO,IAAI,CAAC,oBAAoB,CAAC,SAAS,CAAC,CAAC;YAC9C,CAAC;YAED,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;YACxC,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;YAEhE,MAAM,CAAC,KAAK,CACV,iCAAiC,SAAS,KAAK,MAAM,CAAC,MAAM,WAAW;gBACvE,SAAS,KAAK,IAAI,SAAS,EAAE,CAC9B,CAAC;YAEF,MAAM,QAAQ,GAAG;gBACf,WAAW,EAAE,QAAQ;gBACrB,SAAS;gBACT,SAAS;gBACT,KAAK;aACN,CAAC;YAEF,OAAO;gBACL,SAAS;gBACT,SAAS,EAAE,IAAI,CAAC,QAAQ,CAAC,WAAW,IAAI,WAAW;gBACnD,QAAQ;gBACR,QAAQ,EAAE,MAAM;aACjB,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,IAAI,CAAC,+CAA+C,QAAQ,GAAG,EAAE,KAAK,CAAC,CAAC;YAC/E,OAAO,IAAI,CAAC,oBAAoB,CAAC,SAAS,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,cAAc,CAClB,QAAgB,EAChB,SAAiB,EACjB,OAA0B;QAE1B,IAAI,CAAC;YACH,MAAM,CAAC,KAAK,CACV,qCAAqC,SAAS,SAAS,IAAI,CAAC,UAAU,CAAC,MAAM,aAAa,IAAI,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CACpI,CAAC;YAEF,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;YAEvE,qFAAqF;YACrF,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;gBACtB,aAAa,CAAC,QAAQ,GAAG;oBACvB,GAAG,aAAa,CAAC,QAAQ;oBACzB,SAAS,EAAE,OAAO,CAAC,SAAS;iBAC7B,CAAC;YACJ,CAAC;YAED,MAAM,gBAAgB,GAIjB,EAAE,CAAC;YACR,MAAM,gBAAgB,GAAa,EAAE,CAAC;YACtC,IAAI,YAAY,GAAG,CAAC,CAAC;YAErB,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;gBACxC,IAAI,CAAC;oBACH,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,aAAa,CAAC,EAAE,CAAC;wBAC5C,MAAM,CAAC,KAAK,CAAC,4BAA4B,SAAS,CAAC,IAAI,yCAAyC,CAAC,CAAC;wBAClG,SAAS;oBACX,CAAC;oBAED,MAAM,CAAC,KAAK,CAAC,qCAAqC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC;oBAEpE,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;oBAE/D,gBAAgB,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG;wBACjC,OAAO,EAAE,MAAM,CAAC,OAAO;wBACvB,OAAO,EAAE,MAAM,CAAC,OAAO;wBACvB,gBAAgB,EAAE,MAAM,CAAC,QAAQ,EAAE,gBAAsC;qBAC1E,CAAC;oBAEF,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;wBACpB,gBAAgB,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;wBACtC,MAAM,CAAC,IAAI,CAAC,4BAA4B,SAAS,CAAC,IAAI,YAAY,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;oBACtF,CAAC;yBAAM,CAAC;wBACN,MAAM,CAAC,KAAK,CAAC,4BAA4B,SAAS,CAAC,IAAI,eAAe,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;oBAC1F,CAAC;oBAED,MAAM,gBAAgB,GAAG,MAAM,CAAC,QAAQ,EAAE,gBAAsC,CAAC;oBACjF,IAAI,OAAO,gBAAgB,KAAK,QAAQ,EAAE,CAAC;wBACzC,YAAY,IAAI,gBAAgB,CAAC;oBACnC,CAAC;gBACH,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,MAAM,YAAY,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;oBAC9E,MAAM,CAAC,KAAK,CAAC,4BAA4B,SAAS,CAAC,IAAI,eAAe,EAAE,KAAK,CAAC,CAAC;oBAE/E,gBAAgB,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG;wBACjC,OAAO,EAAE,KAAK;wBACd,OAAO,EAAE,YAAY;qBACtB,CAAC;oBACF,gBAAgB,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;gBACxC,CAAC;YACH,CAAC;YAED,MAAM,MAAM,GAAqB;gBAC/B,OAAO,EAAE,gBAAgB,CAAC,MAAM,KAAK,CAAC;gBACtC,UAAU,EAAE,gBAAgB;gBAC5B,YAAY;gBACZ,gBAAgB;aACjB,CAAC;YAEF,MAAM,CAAC,KAAK,CACV,uCAAuC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,GAAG;gBAC/E,IAAI,YAAY,aAAa,gBAAgB,CAAC,MAAM,qBAAqB,CAC1E,CAAC;YAEF,OAAO,MAAM,CAAC;QAChB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,CAAC,2CAA2C,EAAE,KAAK,CAAC,CAAC;YACjE,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAEO,oBAAoB,CAAC,SAAiB;QAC5C,MAAM,QAAQ,GAAG;YACf,SAAS,EAAE,SAAS;YACpB,SAAS,EAAE,SAAS;YACpB,KAAK,EAAE,SAAS;SACjB,CAAC;QAEF,OAAO;YACL,SAAS;YACT,SAAS,EAAE,IAAI,CAAC,QAAQ,CAAC,WAAW,IAAI,WAAW;YACnD,QAAQ;YACR,QAAQ,EAAE,EAAE;SACb,CAAC;IACJ,CAAC;IAEO,YAAY,CAAC,MAAuB;QAC1C,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,IAAI,KAAK,CAAC,IAAI,KAAK,eAAe,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;gBACvD,OAAO,KAAK,CAAC,UAAU,CAAC;YAC1B,CAAC;QACH,CAAC;QAED,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;gBACjD,OAAO,KAAK,CAAC,KAAK,CAAC;YACrB,CAAC;QACH,CAAC;QAED,OAAO,SAAS,CAAC;IACnB,CAAC;IAEO,iBAAiB,CAAC,MAAuB;QAI/C,IAAI,SAA6B,CAAC;QAClC,IAAI,SAA6B,CAAC;QAElC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACnC,SAAS,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;gBAC/C,MAAM;YACR,CAAC;YACD,IAAI,OAAO,KAAK,CAAC,UAAU,KAAK,QAAQ,EAAE,CAAC;gBACzC,SAAS,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,WAAW,EAAE,CAAC;gBACrD,MAAM;YACR,CAAC;QACH,CAAC;QAED,KAAK,IAAI,CAAC,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC5C,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;YACxB,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACnC,SAAS,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;gBAC/C,MAAM;YACR,CAAC;QACH,CAAC;QAED,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC;IAClC,CAAC;CAEF"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Kimi Metrics Processor
3
+ *
4
+ * Extracts metrics from Kimi Code session wire events and writes them as
5
+ * incremental MetricDelta records to the shared session metrics JSONL store.
6
+ *
7
+ * Unlike the previous one-delta-per-session implementation, this processor emits
8
+ * one delta per completed assistant step, matching the per-message granularity
9
+ * used by the Claude metrics processor. The shared analytics aggregator sums
10
+ * these deltas into session/branch/project totals.
11
+ *
12
+ * Responsibilities:
13
+ * - Detect Kimi Code sessions
14
+ * - Emit one MetricDelta per completed step (identified by step.end event uuid)
15
+ * - Count tool calls and results within each step
16
+ * - Track file operations from display metadata nested inside loop events
17
+ * - Capture user prompts, skill/agent invocations, and branch info
18
+ * - Write incremental metric deltas to ~/.codemie/sessions/{sessionId}_metrics.jsonl
19
+ */
20
+ import type { SessionProcessor, ProcessingContext, ProcessingResult } from '../../../../core/session/BaseProcessor.js';
21
+ import type { ParsedSession } from '../../../../core/session/BaseSessionAdapter.js';
22
+ export declare class KimiMetricsProcessor implements SessionProcessor {
23
+ readonly name = "kimi-metrics";
24
+ readonly priority = 1;
25
+ shouldProcess(session: ParsedSession): boolean;
26
+ process(session: ParsedSession, context: ProcessingContext): Promise<ProcessingResult>;
27
+ private extractSteps;
28
+ private extractTurnPrompts;
29
+ private turnPromptToArray;
30
+ private buildStepMetrics;
31
+ private buildStepNamedInvocations;
32
+ private buildStepCommandInvocations;
33
+ private inferAgentType;
34
+ private extractTextContent;
35
+ private extractTextContentFromMessage;
36
+ private extractSlashCommand;
37
+ private resolveDisplay;
38
+ private deriveLanguage;
39
+ private deriveFormat;
40
+ private computeLineChanges;
41
+ private splitLines;
42
+ }
43
+ //# sourceMappingURL=kimi.metrics-processor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kimi.metrics-processor.d.ts","sourceRoot":"","sources":["../../../../../../src/agents/plugins/kimi/session/processors/kimi.metrics-processor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,2CAA2C,CAAC;AACvH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gDAAgD,CAAC;AAepF,qBAAa,oBAAqB,YAAW,gBAAgB;IAC3D,QAAQ,CAAC,IAAI,kBAAkB;IAC/B,QAAQ,CAAC,QAAQ,KAAK;IAEtB,aAAa,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO;IAIxC,OAAO,CAAC,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAqH5F,OAAO,CAAC,YAAY;IAuEpB,OAAO,CAAC,kBAAkB;IA+B1B,OAAO,CAAC,iBAAiB;IAIzB,OAAO,CAAC,gBAAgB;IA6ExB,OAAO,CAAC,yBAAyB;IA6BjC,OAAO,CAAC,2BAA2B;IAanC,OAAO,CAAC,cAAc;IAStB,OAAO,CAAC,kBAAkB;IAY1B,OAAO,CAAC,6BAA6B;IAerC,OAAO,CAAC,mBAAmB;IAK3B,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,cAAc;IA4BtB,OAAO,CAAC,YAAY;IAKpB,OAAO,CAAC,kBAAkB;IAuB1B,OAAO,CAAC,UAAU;CAOnB"}
@@ -0,0 +1,421 @@
1
+ /**
2
+ * Kimi Metrics Processor
3
+ *
4
+ * Extracts metrics from Kimi Code session wire events and writes them as
5
+ * incremental MetricDelta records to the shared session metrics JSONL store.
6
+ *
7
+ * Unlike the previous one-delta-per-session implementation, this processor emits
8
+ * one delta per completed assistant step, matching the per-message granularity
9
+ * used by the Claude metrics processor. The shared analytics aggregator sums
10
+ * these deltas into session/branch/project totals.
11
+ *
12
+ * Responsibilities:
13
+ * - Detect Kimi Code sessions
14
+ * - Emit one MetricDelta per completed step (identified by step.end event uuid)
15
+ * - Count tool calls and results within each step
16
+ * - Track file operations from display metadata nested inside loop events
17
+ * - Capture user prompts, skill/agent invocations, and branch info
18
+ * - Write incremental metric deltas to ~/.codemie/sessions/{sessionId}_metrics.jsonl
19
+ */
20
+ import { logger } from '../../../../../utils/logger.js';
21
+ export class KimiMetricsProcessor {
22
+ name = 'kimi-metrics';
23
+ priority = 1;
24
+ shouldProcess(session) {
25
+ return session.agentName === 'Kimi Code';
26
+ }
27
+ async process(session, context) {
28
+ try {
29
+ const messages = session.messages;
30
+ if (messages.length === 0) {
31
+ logger.debug(`[${this.name}] No wire events to process for session ${session.sessionId}`);
32
+ return { success: true, message: 'No wire events to process' };
33
+ }
34
+ const { MetricsWriter } = await import('../../../../../providers/plugins/sso/session/processors/metrics/MetricsWriter.js');
35
+ const writer = new MetricsWriter(session.sessionId);
36
+ let existingDeltas = [];
37
+ try {
38
+ existingDeltas = await writer.readAll();
39
+ }
40
+ catch (error) {
41
+ logger.debug(`[${this.name}] Could not read existing deltas: ${error instanceof Error ? error.message : String(error)}`);
42
+ }
43
+ const processedStepUuids = new Set(existingDeltas.map((d) => d.recordId));
44
+ const steps = this.extractSteps(messages);
45
+ const turnPrompts = this.extractTurnPrompts(messages);
46
+ const sessionModel = session.metadata.model;
47
+ const gitBranch = session.metadata?.gitBranch ?? session.metadata?.branch;
48
+ const newDeltas = [];
49
+ const promptedTurns = new Set();
50
+ for (const step of steps) {
51
+ if (processedStepUuids.has(step.uuid)) {
52
+ continue;
53
+ }
54
+ const { tools, toolStatus, fileOperations } = this.buildStepMetrics(step);
55
+ const isFirstStepOfTurn = !promptedTurns.has(step.turnId);
56
+ const userPrompts = isFirstStepOfTurn
57
+ ? this.turnPromptToArray(turnPrompts.get(step.turnId))
58
+ : [];
59
+ if (userPrompts.length > 0) {
60
+ promptedTurns.add(step.turnId);
61
+ }
62
+ const { skillInvocations, agentInvocations } = this.buildStepNamedInvocations(step);
63
+ const commandInvocations = isFirstStepOfTurn
64
+ ? this.buildStepCommandInvocations(step, turnPrompts.get(step.turnId))
65
+ : {};
66
+ const delta = {
67
+ recordId: step.uuid,
68
+ sessionId: session.sessionId,
69
+ agentSessionId: context.agentSessionId || session.sessionId,
70
+ timestamp: step.timestamp,
71
+ ...(gitBranch && { gitBranch }),
72
+ ...(Object.keys(tools).length > 0 && { tools }),
73
+ ...(Object.keys(toolStatus).length > 0 && { toolStatus }),
74
+ ...(fileOperations.length > 0 && { fileOperations }),
75
+ ...(userPrompts.length > 0 && { userPrompts }),
76
+ ...(Object.keys(skillInvocations).length > 0 && { skillInvocations }),
77
+ ...(Object.keys(agentInvocations).length > 0 && { agentInvocations }),
78
+ ...(Object.keys(commandInvocations).length > 0 && { commandInvocations }),
79
+ ...(sessionModel && { models: [sessionModel] }),
80
+ };
81
+ newDeltas.push(delta);
82
+ }
83
+ for (const delta of newDeltas) {
84
+ await writer.appendDelta(delta);
85
+ }
86
+ // Preserve in-memory summary of the latest step for callers/tests.
87
+ const lastStep = steps[steps.length - 1];
88
+ if (lastStep) {
89
+ const { tools, toolStatus, fileOperations } = this.buildStepMetrics(lastStep);
90
+ const lastIsFirstStepOfTurn = lastStep.step === Math.min(...steps.filter((s) => s.turnId === lastStep.turnId).map((s) => s.step));
91
+ session.metrics = {
92
+ tools,
93
+ toolStatus,
94
+ fileOperations,
95
+ userPrompts: lastIsFirstStepOfTurn ? this.turnPromptToArray(turnPrompts.get(lastStep.turnId)) : [],
96
+ ...this.buildStepNamedInvocations(lastStep),
97
+ commandInvocations: lastIsFirstStepOfTurn
98
+ ? this.buildStepCommandInvocations(lastStep, turnPrompts.get(lastStep.turnId))
99
+ : {},
100
+ };
101
+ }
102
+ logger.info(`[${this.name}] Wrote ${newDeltas.length} metric delta(s) for session ${session.sessionId}`);
103
+ logger.debug(`[${this.name}] Metrics file: ${writer.getFilePath()}`);
104
+ return {
105
+ success: true,
106
+ message: `Generated ${newDeltas.length} delta(s)`,
107
+ metadata: {
108
+ recordsProcessed: messages.length,
109
+ deltasWritten: newDeltas.length,
110
+ syncUpdates: {
111
+ metrics: {
112
+ processedRecordIds: newDeltas.map((d) => d.recordId),
113
+ lastProcessedTimestamp: Date.now(),
114
+ totalDeltas: newDeltas.length
115
+ }
116
+ }
117
+ }
118
+ };
119
+ }
120
+ catch (error) {
121
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
122
+ logger.error(`[${this.name}] Processing failed:`, error);
123
+ return {
124
+ success: false,
125
+ message: `Metrics processing failed: ${errorMessage}`
126
+ };
127
+ }
128
+ }
129
+ extractSteps(events) {
130
+ const stepEnds = [];
131
+ const toolCalls = [];
132
+ const toolResults = [];
133
+ const displays = [];
134
+ const stepBeginUuids = new Map();
135
+ for (const event of events) {
136
+ if (event.type !== 'context.append_loop_event' || !event.event) {
137
+ continue;
138
+ }
139
+ const ev = event.event;
140
+ if (ev.type === 'step.begin' && typeof ev.uuid === 'string') {
141
+ stepBeginUuids.set(ev.uuid, { turnId: String(ev.turnId ?? '0'), step: Number(ev.step ?? 0) });
142
+ }
143
+ if (ev.type === 'tool.call' &&
144
+ typeof ev.toolCallId === 'string' &&
145
+ typeof ev.name === 'string') {
146
+ toolCalls.push(event);
147
+ }
148
+ if (ev.type === 'tool.result' && ev.result) {
149
+ toolResults.push(event);
150
+ }
151
+ const display = this.resolveDisplay(event);
152
+ if (display) {
153
+ displays.push({ stepUuid: ev.stepUuid, display });
154
+ }
155
+ }
156
+ // Build buckets from step.end events, matching related events by stepUuid.
157
+ for (const event of events) {
158
+ if (event.type !== 'context.append_loop_event' ||
159
+ event.event?.type !== 'step.end' ||
160
+ typeof event.event.uuid !== 'string') {
161
+ continue;
162
+ }
163
+ const stepUuid = event.event.uuid;
164
+ const beginInfo = stepBeginUuids.get(stepUuid);
165
+ const turnId = beginInfo?.turnId ?? String(event.event.turnId ?? '0');
166
+ const stepNumber = beginInfo?.step ?? Number(event.event.step ?? 0);
167
+ const bucket = {
168
+ uuid: stepUuid,
169
+ turnId,
170
+ step: stepNumber,
171
+ timestamp: typeof event.time === 'number' ? event.time : Date.now(),
172
+ toolCalls: toolCalls.filter((tc) => tc.event.stepUuid === stepUuid),
173
+ toolResults: toolResults.filter((tr) => tr.event?.stepUuid === stepUuid),
174
+ displays: displays
175
+ .filter((d) => d.stepUuid === stepUuid)
176
+ .map((d) => d.display),
177
+ };
178
+ stepEnds.push(bucket);
179
+ }
180
+ // Preserve chronological order by timestamp.
181
+ stepEnds.sort((a, b) => a.timestamp - b.timestamp);
182
+ return stepEnds;
183
+ }
184
+ extractTurnPrompts(events) {
185
+ const map = new Map();
186
+ let currentTurnId = '0';
187
+ for (const event of events) {
188
+ if (event.type === 'turn.prompt') {
189
+ if (typeof event.event?.turnId === 'string') {
190
+ currentTurnId = event.event.turnId;
191
+ }
192
+ const text = this.extractTextContent(event);
193
+ if (text) {
194
+ map.set(currentTurnId, text);
195
+ }
196
+ }
197
+ if (event.type === 'context.append_message' && event.message?.role === 'user') {
198
+ const origin = event.message.origin;
199
+ if (origin?.kind === 'user') {
200
+ const text = this.extractTextContentFromMessage(event.message);
201
+ if (text) {
202
+ // Prefer the explicit turnId on the message when available.
203
+ const turnId = event.event?.turnId ? String(event.event.turnId) : currentTurnId;
204
+ map.set(turnId, text);
205
+ }
206
+ }
207
+ }
208
+ }
209
+ return map;
210
+ }
211
+ turnPromptToArray(text) {
212
+ return text ? [{ count: 1, text }] : [];
213
+ }
214
+ buildStepMetrics(step) {
215
+ const tools = {};
216
+ const toolStatus = {};
217
+ const fileOperations = [];
218
+ const toolCallById = new Map();
219
+ for (const toolCall of step.toolCalls) {
220
+ const toolName = toolCall.event.name;
221
+ tools[toolName] = (tools[toolName] || 0) + 1;
222
+ if (!toolStatus[toolName]) {
223
+ toolStatus[toolName] = { success: 0, failure: 0 };
224
+ }
225
+ toolCallById.set(toolCall.event.toolCallId, toolCall);
226
+ if (typeof toolCall.event.uuid === 'string') {
227
+ toolCallById.set(toolCall.event.uuid, toolCall);
228
+ }
229
+ }
230
+ for (const resultEvent of step.toolResults) {
231
+ const ev = resultEvent.event;
232
+ if (!ev)
233
+ continue;
234
+ const matchedToolCall = (typeof ev.toolCallId === 'string' && toolCallById.get(ev.toolCallId)) ||
235
+ (typeof ev.parentUuid === 'string' && toolCallById.get(ev.parentUuid));
236
+ if (!matchedToolCall) {
237
+ continue;
238
+ }
239
+ const toolName = matchedToolCall.event.name;
240
+ const isError = ev.result?.isError === true;
241
+ if (isError) {
242
+ toolStatus[toolName].failure++;
243
+ }
244
+ else {
245
+ toolStatus[toolName].success++;
246
+ }
247
+ }
248
+ for (const display of step.displays) {
249
+ if (display.kind !== 'file_io') {
250
+ continue;
251
+ }
252
+ const operation = display.operation;
253
+ if (operation !== 'read' && operation !== 'write' && operation !== 'edit' && operation !== 'delete') {
254
+ continue;
255
+ }
256
+ const fileOp = {
257
+ type: operation,
258
+ path: typeof display.path === 'string' ? display.path : undefined,
259
+ };
260
+ if (fileOp.path) {
261
+ const language = this.deriveLanguage(fileOp.path);
262
+ const format = this.deriveFormat(fileOp.path);
263
+ if (language)
264
+ fileOp.language = language;
265
+ if (format)
266
+ fileOp.format = format;
267
+ }
268
+ if (typeof display.before === 'string' && typeof display.after === 'string') {
269
+ const lineStats = this.computeLineChanges(display.before, display.after);
270
+ fileOp.linesAdded = lineStats.linesAdded;
271
+ fileOp.linesRemoved = lineStats.linesRemoved;
272
+ fileOp.linesModified = lineStats.linesModified;
273
+ }
274
+ fileOperations.push(fileOp);
275
+ }
276
+ return { tools, toolStatus, fileOperations };
277
+ }
278
+ buildStepNamedInvocations(step) {
279
+ const skillInvocations = {};
280
+ const agentInvocations = {};
281
+ for (const toolCall of step.toolCalls) {
282
+ const args = toolCall.event.args;
283
+ if (!args || typeof args !== 'object') {
284
+ continue;
285
+ }
286
+ const toolName = toolCall.event.name;
287
+ if (toolName === 'Skill' && typeof args.skill === 'string') {
288
+ skillInvocations[args.skill] = (skillInvocations[args.skill] || 0) + 1;
289
+ }
290
+ else if ((toolName === 'Agent' || toolName === 'AgentSwarm') && typeof args.subagent_type === 'string') {
291
+ agentInvocations[args.subagent_type] = (agentInvocations[args.subagent_type] || 0) + 1;
292
+ }
293
+ else if (toolName === 'Agent' && typeof args.description === 'string') {
294
+ const agentType = this.inferAgentType(args.description);
295
+ if (agentType) {
296
+ agentInvocations[agentType] = (agentInvocations[agentType] || 0) + 1;
297
+ }
298
+ }
299
+ }
300
+ return { skillInvocations, agentInvocations };
301
+ }
302
+ buildStepCommandInvocations(step, turnPrompt) {
303
+ const commandInvocations = {};
304
+ if (turnPrompt) {
305
+ const command = this.extractSlashCommand(turnPrompt);
306
+ if (command) {
307
+ commandInvocations[command] = (commandInvocations[command] || 0) + 1;
308
+ }
309
+ }
310
+ return commandInvocations;
311
+ }
312
+ inferAgentType(description) {
313
+ const lower = description.toLowerCase();
314
+ if (lower.includes('explore'))
315
+ return 'explore';
316
+ if (lower.includes('plan'))
317
+ return 'plan';
318
+ if (lower.includes('coder'))
319
+ return 'coder';
320
+ if (lower.includes('review'))
321
+ return 'review';
322
+ return undefined;
323
+ }
324
+ extractTextContent(event) {
325
+ const input = event.input;
326
+ if (Array.isArray(input)) {
327
+ for (const part of input) {
328
+ if (part && part.type === 'text' && typeof part.text === 'string') {
329
+ return part.text;
330
+ }
331
+ }
332
+ }
333
+ return undefined;
334
+ }
335
+ extractTextContentFromMessage(message) {
336
+ const content = message.content;
337
+ if (Array.isArray(content)) {
338
+ for (const part of content) {
339
+ if (part && part.type === 'text' && typeof part.text === 'string') {
340
+ return part.text;
341
+ }
342
+ }
343
+ }
344
+ if (typeof content === 'string') {
345
+ return content;
346
+ }
347
+ return undefined;
348
+ }
349
+ extractSlashCommand(text) {
350
+ const match = text.trim().match(/^\/([a-zA-Z0-9_-]+)/);
351
+ return match ? match[1] : undefined;
352
+ }
353
+ resolveDisplay(event) {
354
+ return event.event?.display ?? event.display;
355
+ }
356
+ deriveLanguage(path) {
357
+ const ext = path.split('.').pop()?.toLowerCase();
358
+ switch (ext) {
359
+ case 'ts': return 'typescript';
360
+ case 'tsx': return 'typescript';
361
+ case 'js': return 'javascript';
362
+ case 'jsx': return 'javascript';
363
+ case 'py': return 'python';
364
+ case 'go': return 'go';
365
+ case 'rs': return 'rust';
366
+ case 'java': return 'java';
367
+ case 'kt': return 'kotlin';
368
+ case 'rb': return 'ruby';
369
+ case 'php': return 'php';
370
+ case 'c': return 'c';
371
+ case 'cpp':
372
+ case 'cc':
373
+ case 'cxx': return 'cpp';
374
+ case 'h':
375
+ case 'hpp': return 'cpp';
376
+ case 'cs': return 'csharp';
377
+ case 'swift': return 'swift';
378
+ case 'md': return 'markdown';
379
+ case 'json': return 'json';
380
+ case 'yaml':
381
+ case 'yml': return 'yaml';
382
+ case 'toml': return 'toml';
383
+ case 'sh': return 'shell';
384
+ default: return undefined;
385
+ }
386
+ }
387
+ deriveFormat(path) {
388
+ const ext = path.split('.').pop()?.toLowerCase();
389
+ return ext || undefined;
390
+ }
391
+ computeLineChanges(before, after) {
392
+ const beforeLines = this.splitLines(before);
393
+ const afterLines = this.splitLines(after);
394
+ const maxLen = Math.max(beforeLines.length, afterLines.length);
395
+ let linesAdded = 0;
396
+ let linesRemoved = 0;
397
+ let linesModified = 0;
398
+ for (let i = 0; i < maxLen; i++) {
399
+ const b = beforeLines[i];
400
+ const a = afterLines[i];
401
+ if (b === undefined && a !== undefined) {
402
+ linesAdded++;
403
+ }
404
+ else if (b !== undefined && a === undefined) {
405
+ linesRemoved++;
406
+ }
407
+ else if (b !== a) {
408
+ linesModified++;
409
+ }
410
+ }
411
+ return { linesAdded, linesRemoved, linesModified };
412
+ }
413
+ splitLines(text) {
414
+ const lines = text.split('\n');
415
+ if (lines.length > 0 && lines[lines.length - 1] === '') {
416
+ lines.pop();
417
+ }
418
+ return lines;
419
+ }
420
+ }
421
+ //# sourceMappingURL=kimi.metrics-processor.js.map