@codemieai/code 0.10.0 → 0.11.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/dist/agents/core/AgentCLI.d.ts.map +1 -1
- package/dist/agents/core/AgentCLI.js +11 -3
- package/dist/agents/core/AgentCLI.js.map +1 -1
- package/dist/agents/core/BaseAgentAdapter.d.ts +3 -1
- package/dist/agents/core/BaseAgentAdapter.d.ts.map +1 -1
- package/dist/agents/core/BaseAgentAdapter.js +34 -2
- package/dist/agents/core/BaseAgentAdapter.js.map +1 -1
- package/dist/agents/core/config-redaction.d.ts +7 -0
- package/dist/agents/core/config-redaction.d.ts.map +1 -0
- package/dist/agents/core/config-redaction.js +20 -0
- package/dist/agents/core/config-redaction.js.map +1 -0
- package/dist/agents/core/print-config.d.ts +8 -0
- package/dist/agents/core/print-config.d.ts.map +1 -0
- package/dist/agents/core/print-config.js +17 -0
- package/dist/agents/core/print-config.js.map +1 -0
- package/dist/agents/core/session/BaseSessionAdapter.d.ts +5 -1
- package/dist/agents/core/session/BaseSessionAdapter.d.ts.map +1 -1
- package/dist/agents/core/types.d.ts +34 -4
- package/dist/agents/core/types.d.ts.map +1 -1
- package/dist/agents/plugins/claude/claude.plugin.d.ts.map +1 -1
- package/dist/agents/plugins/claude/claude.plugin.js +73 -0
- package/dist/agents/plugins/claude/claude.plugin.js.map +1 -1
- package/dist/agents/plugins/claude/session/processors/claude.conversations-processor.d.ts.map +1 -1
- package/dist/agents/plugins/claude/session/processors/claude.conversations-processor.js +115 -32
- package/dist/agents/plugins/claude/session/processors/claude.conversations-processor.js.map +1 -1
- package/dist/agents/plugins/claude/settings-conflict.d.ts +8 -0
- package/dist/agents/plugins/claude/settings-conflict.d.ts.map +1 -0
- package/dist/agents/plugins/claude/settings-conflict.js +35 -0
- package/dist/agents/plugins/claude/settings-conflict.js.map +1 -0
- package/dist/agents/plugins/codemie-code-hooks/shell-hooks-source.d.ts +14 -2
- package/dist/agents/plugins/codemie-code-hooks/shell-hooks-source.d.ts.map +1 -1
- package/dist/agents/plugins/codemie-code-hooks/shell-hooks-source.js +218 -263
- package/dist/agents/plugins/codemie-code-hooks/shell-hooks-source.js.map +1 -1
- package/dist/agents/plugins/opencode/opencode-message-types.d.ts +13 -0
- package/dist/agents/plugins/opencode/opencode-message-types.d.ts.map +1 -1
- package/dist/agents/plugins/opencode/opencode-message-types.js.map +1 -1
- package/dist/agents/plugins/opencode/opencode.incremental-sync.d.ts +38 -0
- package/dist/agents/plugins/opencode/opencode.incremental-sync.d.ts.map +1 -0
- package/dist/agents/plugins/opencode/opencode.incremental-sync.js +153 -0
- package/dist/agents/plugins/opencode/opencode.incremental-sync.js.map +1 -0
- package/dist/agents/plugins/opencode/opencode.paths.d.ts +18 -2
- package/dist/agents/plugins/opencode/opencode.paths.d.ts.map +1 -1
- package/dist/agents/plugins/opencode/opencode.paths.js +39 -6
- package/dist/agents/plugins/opencode/opencode.paths.js.map +1 -1
- package/dist/agents/plugins/opencode/opencode.plugin.d.ts.map +1 -1
- package/dist/agents/plugins/opencode/opencode.plugin.js +241 -75
- package/dist/agents/plugins/opencode/opencode.plugin.js.map +1 -1
- package/dist/agents/plugins/opencode/opencode.session.d.ts +18 -1
- package/dist/agents/plugins/opencode/opencode.session.d.ts.map +1 -1
- package/dist/agents/plugins/opencode/opencode.session.js +58 -17
- package/dist/agents/plugins/opencode/opencode.session.js.map +1 -1
- package/dist/agents/plugins/opencode/opencode.sqlite-reader.d.ts +8 -2
- package/dist/agents/plugins/opencode/opencode.sqlite-reader.d.ts.map +1 -1
- package/dist/agents/plugins/opencode/opencode.sqlite-reader.js +67 -42
- package/dist/agents/plugins/opencode/opencode.sqlite-reader.js.map +1 -1
- package/dist/agents/plugins/opencode/opencode.storage-utils.d.ts +19 -0
- package/dist/agents/plugins/opencode/opencode.storage-utils.d.ts.map +1 -1
- package/dist/agents/plugins/opencode/opencode.storage-utils.js +51 -0
- package/dist/agents/plugins/opencode/opencode.storage-utils.js.map +1 -1
- package/dist/agents/plugins/opencode/session/processors/opencode.conversations-processor.d.ts +13 -19
- package/dist/agents/plugins/opencode/session/processors/opencode.conversations-processor.d.ts.map +1 -1
- package/dist/agents/plugins/opencode/session/processors/opencode.conversations-processor.js +339 -82
- package/dist/agents/plugins/opencode/session/processors/opencode.conversations-processor.js.map +1 -1
- package/dist/agents/plugins/opencode/session/processors/opencode.metrics-processor.d.ts +37 -33
- package/dist/agents/plugins/opencode/session/processors/opencode.metrics-processor.d.ts.map +1 -1
- package/dist/agents/plugins/opencode/session/processors/opencode.metrics-processor.js +204 -246
- package/dist/agents/plugins/opencode/session/processors/opencode.metrics-processor.js.map +1 -1
- package/dist/cli/commands/proxy/connectors/desktop.d.ts.map +1 -1
- package/dist/cli/commands/proxy/connectors/desktop.js +6 -0
- package/dist/cli/commands/proxy/connectors/desktop.js.map +1 -1
- package/dist/cli/commands/proxy/connectors/vscode-models.d.ts +21 -0
- package/dist/cli/commands/proxy/connectors/vscode-models.d.ts.map +1 -0
- package/dist/cli/commands/proxy/connectors/vscode-models.js +286 -0
- package/dist/cli/commands/proxy/connectors/vscode-models.js.map +1 -0
- package/dist/cli/commands/proxy/connectors/vscode.d.ts +2 -2
- package/dist/cli/commands/proxy/connectors/vscode.d.ts.map +1 -1
- package/dist/cli/commands/proxy/connectors/vscode.js +47 -66
- package/dist/cli/commands/proxy/connectors/vscode.js.map +1 -1
- package/dist/cli/commands/proxy/health-check.d.ts.map +1 -1
- package/dist/cli/commands/proxy/health-check.js +9 -0
- package/dist/cli/commands/proxy/health-check.js.map +1 -1
- package/dist/cli/commands/proxy/index.d.ts.map +1 -1
- package/dist/cli/commands/proxy/index.js +10 -13
- package/dist/cli/commands/proxy/index.js.map +1 -1
- package/dist/cli/commands/setup.d.ts +31 -0
- package/dist/cli/commands/setup.d.ts.map +1 -1
- package/dist/cli/commands/setup.js +137 -45
- package/dist/cli/commands/setup.js.map +1 -1
- package/dist/providers/core/types.d.ts +12 -1
- package/dist/providers/core/types.d.ts.map +1 -1
- package/dist/providers/core/types.js.map +1 -1
- package/dist/providers/plugins/bedrock/bedrock.template.d.ts.map +1 -1
- package/dist/providers/plugins/bedrock/bedrock.template.js +21 -2
- package/dist/providers/plugins/bedrock/bedrock.template.js.map +1 -1
- package/dist/providers/plugins/litellm/litellm.setup-steps.d.ts.map +1 -1
- package/dist/providers/plugins/litellm/litellm.setup-steps.js +21 -5
- package/dist/providers/plugins/litellm/litellm.setup-steps.js.map +1 -1
- package/dist/providers/plugins/sso/proxy/plugins/codex-encrypted-content-sanitizer.plugin.d.ts +7 -6
- package/dist/providers/plugins/sso/proxy/plugins/codex-encrypted-content-sanitizer.plugin.d.ts.map +1 -1
- package/dist/providers/plugins/sso/proxy/plugins/codex-encrypted-content-sanitizer.plugin.js +13 -7
- package/dist/providers/plugins/sso/proxy/plugins/codex-encrypted-content-sanitizer.plugin.js.map +1 -1
- package/dist/providers/plugins/sso/proxy/plugins/index.d.ts +2 -1
- package/dist/providers/plugins/sso/proxy/plugins/index.d.ts.map +1 -1
- package/dist/providers/plugins/sso/proxy/plugins/index.js +4 -2
- package/dist/providers/plugins/sso/proxy/plugins/index.js.map +1 -1
- package/dist/providers/plugins/sso/proxy/plugins/vscode-request-normalizer.plugin.d.ts +22 -0
- package/dist/providers/plugins/sso/proxy/plugins/vscode-request-normalizer.plugin.d.ts.map +1 -0
- package/dist/providers/plugins/sso/proxy/plugins/vscode-request-normalizer.plugin.js +69 -0
- package/dist/providers/plugins/sso/proxy/plugins/vscode-request-normalizer.plugin.js.map +1 -0
- package/dist/providers/plugins/sso/session/processors/conversations/syncProcessor.js +3 -0
- package/dist/providers/plugins/sso/session/processors/conversations/syncProcessor.js.map +1 -1
- package/dist/utils/config.d.ts +6 -2
- package/dist/utils/config.d.ts.map +1 -1
- package/dist/utils/config.js +30 -8
- package/dist/utils/config.js.map +1 -1
- package/dist/utils/extensions-scan.d.ts.map +1 -1
- package/dist/utils/extensions-scan.js +59 -22
- package/dist/utils/extensions-scan.js.map +1 -1
- package/dist/utils/mcp-config.d.ts.map +1 -1
- package/dist/utils/mcp-config.js +11 -6
- package/dist/utils/mcp-config.js.map +1 -1
- package/package.json +2 -1
|
@@ -1,118 +1,375 @@
|
|
|
1
|
-
|
|
2
|
-
import { logger } from '../../../../../utils/logger.js';
|
|
1
|
+
// src/agents/plugins/opencode/session/processors/opencode.conversations-processor.ts
|
|
3
2
|
/**
|
|
4
3
|
* OpenCode Conversations Processor
|
|
5
4
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* Transforms OpenCode messages and parts into incremental CodeMie conversation
|
|
6
|
+
* payloads and queues them in {sessionId}_conversation.jsonl, where the shared
|
|
7
|
+
* conversation-sync processor picks them up and PUTs them to
|
|
8
|
+
* /v1/conversations/{id}/history.
|
|
9
|
+
*
|
|
10
|
+
* Shape matches the other agents: the visible history holds the user prompt and
|
|
11
|
+
* the assistant's reply, while tool calls and reasoning are attached as
|
|
12
|
+
* `thoughts` on the assistant entry.
|
|
13
|
+
*
|
|
14
|
+
* Structurally modelled on codex.conversations-processor.ts — same checkpoint
|
|
15
|
+
* sentinel, turn-continuation handling and syncUpdates contract.
|
|
8
16
|
*/
|
|
17
|
+
import { isTextPart, isToolPart, isReasoningPart, } from '../../opencode-message-types.js';
|
|
18
|
+
import { CONVERSATION_SYNC_STATUS } from '../../../../../providers/plugins/sso/session/processors/conversations/types.js';
|
|
19
|
+
import { CODEMIE_ASSISTANT_ID } from '../../../../../providers/plugins/sso/session/processors/conversations/constants.js';
|
|
20
|
+
import { getSessionConversationPath } from '../../../../core/session/session-config.js';
|
|
21
|
+
import { loadPartsForMessage } from '../../opencode.storage-utils.js';
|
|
22
|
+
import { logger } from '../../../../../utils/logger.js';
|
|
23
|
+
/**
|
|
24
|
+
* The conversation folder these payloads are filed under in CodeMie.
|
|
25
|
+
* Set explicitly so the payload does not depend on the sync processor's
|
|
26
|
+
* client-type fallback, which defaults to 'Claude Desktop'.
|
|
27
|
+
*/
|
|
28
|
+
const OPENCODE_CONVERSATION_FOLDER = 'opencode';
|
|
9
29
|
export class OpenCodeConversationsProcessor {
|
|
10
30
|
name = 'opencode-conversations';
|
|
11
31
|
priority = 2; // Run after metrics
|
|
12
|
-
/**
|
|
13
|
-
* Check if session has data to process
|
|
14
|
-
*/
|
|
15
32
|
shouldProcess(session) {
|
|
16
33
|
if (process.env.CODEMIE_CONV_SYNC_DISABLED === '1')
|
|
17
34
|
return false;
|
|
18
35
|
return session.messages.length > 0;
|
|
19
36
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
37
|
+
// _context is intentionally unused: conversation identity comes from
|
|
38
|
+
// session.metadata.openCodeSessionId, never from context.agentSessionId,
|
|
39
|
+
// which differs between the timer/Stop and in-process SessionEnd paths.
|
|
23
40
|
async process(session, _context) {
|
|
24
41
|
try {
|
|
25
|
-
const
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
role: message.role,
|
|
34
|
-
content: '', // Would be populated from text parts (AC-EXT-1)
|
|
35
|
-
// UPDATED (GPT-5.9): Convert numeric timestamp to ISO string
|
|
36
|
-
timestamp: message.time?.created
|
|
37
|
-
? new Date(message.time.created).toISOString()
|
|
38
|
-
: new Date().toISOString(),
|
|
39
|
-
// UPDATED (GPT-5.9): modelID is on assistant messages only
|
|
40
|
-
model: message.role === 'assistant'
|
|
41
|
-
? message.modelID
|
|
42
|
-
: undefined,
|
|
43
|
-
agent: message.role === 'assistant'
|
|
44
|
-
? message.agent
|
|
45
|
-
: undefined
|
|
42
|
+
const metadata = session.metadata;
|
|
43
|
+
const openCodeSessionId = metadata?.openCodeSessionId;
|
|
44
|
+
const storagePath = metadata?.storagePath;
|
|
45
|
+
if (!openCodeSessionId || !storagePath) {
|
|
46
|
+
return {
|
|
47
|
+
success: false,
|
|
48
|
+
message: 'Missing openCodeSessionId or storagePath in session.metadata',
|
|
49
|
+
metadata: { failureReason: 'NO_OPENCODE_SESSION_ID' }
|
|
46
50
|
};
|
|
47
|
-
normalizedMessages.push(normalized);
|
|
48
51
|
}
|
|
49
|
-
|
|
52
|
+
const messages = session.messages;
|
|
53
|
+
const events = await normalizeEvents(messages, storagePath, openCodeSessionId, metadata?.partsMap);
|
|
54
|
+
logger.debug(`[opencode-conversations] Normalised ${events.length} events from ${messages.length} messages`);
|
|
55
|
+
if (events.length === 0) {
|
|
56
|
+
return { success: true, message: 'No conversation events generated', metadata: { recordsProcessed: 0 } };
|
|
57
|
+
}
|
|
58
|
+
const { SessionStore } = await import('../../../../core/session/SessionStore.js');
|
|
59
|
+
const sessionStore = new SessionStore();
|
|
60
|
+
const sessionMetadata = await sessionStore.loadSession(session.sessionId);
|
|
61
|
+
const persistedHistoryIndex = sessionMetadata?.sync?.conversations?.lastSyncedHistoryIndex ?? -1;
|
|
62
|
+
const lastSyncedSourceIndex = parseLastSyncedSourceIndex(sessionMetadata?.sync?.conversations?.lastSyncedMessageUuid, persistedHistoryIndex);
|
|
63
|
+
const conversationsPath = getSessionConversationPath(session.sessionId);
|
|
64
|
+
const { readJSONL } = await import('../../../../../providers/plugins/sso/session/utils/jsonl-reader.js');
|
|
65
|
+
const existingPayloads = await readJSONL(conversationsPath);
|
|
66
|
+
// Payloads already queued but not yet uploaded also advance the watermark,
|
|
67
|
+
// otherwise every tick re-queues the same turn.
|
|
68
|
+
const queuedCheckpoint = getQueuedCheckpoint(existingPayloads);
|
|
69
|
+
const effectiveSourceIndex = Math.max(lastSyncedSourceIndex, queuedCheckpoint.sourceIndex);
|
|
70
|
+
const effectiveHistoryIndex = Math.max(persistedHistoryIndex, queuedCheckpoint.historyIndex);
|
|
71
|
+
const turn = buildIncrementalTurn(events, effectiveSourceIndex, effectiveHistoryIndex);
|
|
72
|
+
if (!turn) {
|
|
73
|
+
logger.debug(`[opencode-conversations] No complete turn past source index ${effectiveSourceIndex} for ${openCodeSessionId}`);
|
|
74
|
+
return { success: true, message: 'No new conversation messages', metadata: { recordsProcessed: 0 } };
|
|
75
|
+
}
|
|
76
|
+
const newTurnEvents = turn.events.filter(event => event.sourceIndex > effectiveSourceIndex);
|
|
77
|
+
const endSourceIndex = Math.max(...newTurnEvents.map(event => event.sourceIndex));
|
|
78
|
+
const sentinel = `${openCodeSessionId}@${endSourceIndex}`;
|
|
79
|
+
if (existingPayloads.some(payload => payload.lastProcessedMessageUuid === sentinel)) {
|
|
80
|
+
logger.debug(`[opencode-conversations] Window ${sentinel} already queued, skipping`);
|
|
81
|
+
return { success: true, message: 'Window already queued', metadata: { recordsProcessed: 0 } };
|
|
82
|
+
}
|
|
83
|
+
const history = turnToHistory(turn, effectiveSourceIndex);
|
|
84
|
+
if (history.length === 0) {
|
|
85
|
+
logger.debug(`[opencode-conversations] Turn resolved but produced no visible history for ${sentinel}`);
|
|
86
|
+
return { success: true, message: 'No visible history generated', metadata: { recordsProcessed: 0 } };
|
|
87
|
+
}
|
|
88
|
+
const { appendFile, mkdir } = await import('fs/promises');
|
|
89
|
+
const { dirname } = await import('path');
|
|
90
|
+
await mkdir(dirname(conversationsPath), { recursive: true });
|
|
91
|
+
const payloadRecord = {
|
|
92
|
+
payloadId: sentinel,
|
|
93
|
+
timestamp: Date.now(),
|
|
94
|
+
isTurnContinuation: turn.isTurnContinuation,
|
|
95
|
+
historyIndices: history.map(entry => entry.history_index),
|
|
96
|
+
messageCount: history.length,
|
|
97
|
+
lastProcessedMessageUuid: sentinel,
|
|
98
|
+
payload: {
|
|
99
|
+
// Always the opencode ses_* id, never context.agentSessionId. That
|
|
100
|
+
// field carries ses_* on the timer and Stop paths but the CodeMie UUID
|
|
101
|
+
// on the in-process SessionEnd path, and conversationId is the PUT
|
|
102
|
+
// path id — so keying off it filed a session's final turn under a
|
|
103
|
+
// second conversation and split the history in two. The checkpoint
|
|
104
|
+
// sentinel already keys on openCodeSessionId, so this is the identity
|
|
105
|
+
// the rest of the pipeline is built around.
|
|
106
|
+
conversationId: openCodeSessionId,
|
|
107
|
+
assistantId: CODEMIE_ASSISTANT_ID,
|
|
108
|
+
folder: OPENCODE_CONVERSATION_FOLDER,
|
|
109
|
+
llmModel: resolveTurnModel(turn.events),
|
|
110
|
+
history,
|
|
111
|
+
},
|
|
112
|
+
status: CONVERSATION_SYNC_STATUS.PENDING,
|
|
113
|
+
};
|
|
114
|
+
await appendFile(conversationsPath, JSON.stringify(payloadRecord) + '\n', 'utf-8');
|
|
50
115
|
return {
|
|
51
116
|
success: true,
|
|
52
|
-
message: `
|
|
117
|
+
message: `Generated 1 conversation payload from ${newTurnEvents.length} new events`,
|
|
53
118
|
metadata: {
|
|
54
|
-
recordsProcessed:
|
|
55
|
-
userMessages:
|
|
56
|
-
assistantMessages:
|
|
119
|
+
recordsProcessed: newTurnEvents.length,
|
|
120
|
+
userMessages: history.filter(entry => entry.role === 'User').length,
|
|
121
|
+
assistantMessages: history.filter(entry => entry.role === 'Assistant').length,
|
|
122
|
+
syncUpdates: {
|
|
123
|
+
conversations: {
|
|
124
|
+
lastSyncedMessageUuid: sentinel,
|
|
125
|
+
lastSyncedHistoryIndex: turn.historyIndex,
|
|
126
|
+
// Same identity as payload.conversationId above — see the note there.
|
|
127
|
+
conversationId: openCodeSessionId,
|
|
128
|
+
totalMessagesSynced: history.length,
|
|
129
|
+
totalSyncAttempts: 1,
|
|
130
|
+
lastSyncAt: Date.now(),
|
|
131
|
+
},
|
|
132
|
+
},
|
|
57
133
|
}
|
|
58
134
|
};
|
|
59
135
|
}
|
|
60
136
|
catch (error) {
|
|
61
137
|
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
62
|
-
logger.error(
|
|
63
|
-
return {
|
|
64
|
-
success: false,
|
|
65
|
-
message: `Conversations processing failed: ${errorMessage}`
|
|
66
|
-
};
|
|
138
|
+
logger.error('[opencode-conversations] Processing failed:', error);
|
|
139
|
+
return { success: false, message: `Conversations processing failed: ${errorMessage}` };
|
|
67
140
|
}
|
|
68
141
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Flatten messages and their parts into a single ordered event stream.
|
|
145
|
+
*
|
|
146
|
+
* `sourceIndex` counts across the flattened (message, part) sequence. OpenCode
|
|
147
|
+
* only ever appends — new parts land on the newest message, new messages at the
|
|
148
|
+
* end — so an index already emitted keeps its position on later ticks, which is
|
|
149
|
+
* what makes it usable as a sync watermark.
|
|
150
|
+
*/
|
|
151
|
+
async function normalizeEvents(messages, storagePath, openCodeSessionId, partsMap) {
|
|
152
|
+
const events = [];
|
|
153
|
+
let sourceIndex = 0;
|
|
154
|
+
for (const message of messages) {
|
|
155
|
+
const date = toIsoDate(message.time?.created);
|
|
156
|
+
const parts = await loadPartsForMessage(storagePath, message.id, openCodeSessionId, partsMap);
|
|
157
|
+
if (message.role === 'user') {
|
|
158
|
+
// Burn the index unconditionally, exactly as the assistant branch does.
|
|
159
|
+
// A user message whose parts have not flushed yet yields no text on this
|
|
160
|
+
// tick but will on the next one; consuming the index only when text is
|
|
161
|
+
// present would shift every later sourceIndex by one between ticks and
|
|
162
|
+
// silently move the checkpoint onto a different event.
|
|
163
|
+
const index = sourceIndex++;
|
|
164
|
+
const text = parts
|
|
165
|
+
.filter(part => isTextPart(part) && !isIgnoredPart(part))
|
|
166
|
+
.map(part => part.text)
|
|
167
|
+
.filter(value => value?.trim())
|
|
168
|
+
.join('\n');
|
|
169
|
+
if (text) {
|
|
170
|
+
events.push({ kind: 'user_prompt', sourceIndex: index, date, text });
|
|
171
|
+
}
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
const assistant = message;
|
|
175
|
+
// Bare model id, consistent with the metrics pipeline.
|
|
176
|
+
const model = assistant.modelID?.trim() || undefined;
|
|
82
177
|
for (const part of parts) {
|
|
83
|
-
|
|
84
|
-
if (
|
|
85
|
-
|
|
178
|
+
const index = sourceIndex++;
|
|
179
|
+
if (isReasoningPart(part)) {
|
|
180
|
+
if (part.text?.trim()) {
|
|
181
|
+
events.push({ kind: 'reasoning', sourceIndex: index, date, text: part.text, model });
|
|
182
|
+
}
|
|
183
|
+
continue;
|
|
86
184
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
185
|
+
if (isToolPart(part)) {
|
|
186
|
+
events.push({
|
|
187
|
+
kind: 'tool_call',
|
|
188
|
+
sourceIndex: index,
|
|
189
|
+
date,
|
|
190
|
+
callId: part.callID || part.id,
|
|
191
|
+
toolName: part.tool,
|
|
192
|
+
inputText: stringify(part.state.input),
|
|
193
|
+
text: part.state.status === 'error'
|
|
194
|
+
? (part.state.error ?? '')
|
|
195
|
+
: stringify(part.state.output),
|
|
196
|
+
error: part.state.status === 'error',
|
|
197
|
+
model,
|
|
93
198
|
});
|
|
199
|
+
continue;
|
|
94
200
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
// Use url or construct reference from filename
|
|
98
|
-
if (part.url) {
|
|
99
|
-
fileReferences.push(part.url);
|
|
100
|
-
}
|
|
101
|
-
else if (part.filename) {
|
|
102
|
-
fileReferences.push(part.filename);
|
|
103
|
-
}
|
|
201
|
+
if (isTextPart(part) && !isIgnoredPart(part) && part.text?.trim()) {
|
|
202
|
+
events.push({ kind: 'assistant_reply', sourceIndex: index, date, text: part.text, model });
|
|
104
203
|
}
|
|
105
|
-
|
|
106
|
-
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
return events;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Resolve the window of events to publish next.
|
|
210
|
+
*
|
|
211
|
+
* A turn runs from a user prompt to the next user prompt. When new events land
|
|
212
|
+
* inside a turn that was already partially published, the turn is re-emitted as
|
|
213
|
+
* a continuation under its original history index so the backend appends rather
|
|
214
|
+
* than duplicating.
|
|
215
|
+
*/
|
|
216
|
+
function buildIncrementalTurn(events, effectiveSourceIndex, effectiveHistoryIndex) {
|
|
217
|
+
const firstNewEvent = events.find(event => event.sourceIndex > effectiveSourceIndex);
|
|
218
|
+
if (!firstNewEvent)
|
|
219
|
+
return null;
|
|
220
|
+
const userEvents = events.filter(event => event.kind === 'user_prompt');
|
|
221
|
+
let userEvent;
|
|
222
|
+
let historyIndex = effectiveHistoryIndex;
|
|
223
|
+
let isTurnContinuation = false;
|
|
224
|
+
if (firstNewEvent.kind === 'user_prompt') {
|
|
225
|
+
userEvent = firstNewEvent;
|
|
226
|
+
historyIndex = effectiveHistoryIndex + 1;
|
|
227
|
+
}
|
|
228
|
+
else {
|
|
229
|
+
for (let index = userEvents.length - 1; index >= 0; index -= 1) {
|
|
230
|
+
if (userEvents[index].sourceIndex < firstNewEvent.sourceIndex) {
|
|
231
|
+
userEvent = userEvents[index];
|
|
232
|
+
break;
|
|
107
233
|
}
|
|
108
|
-
// step-finish parts are skipped (metadata only - tokens/cost handled by metrics)
|
|
109
234
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
235
|
+
if (!userEvent || effectiveHistoryIndex < 0)
|
|
236
|
+
return null;
|
|
237
|
+
historyIndex = effectiveHistoryIndex;
|
|
238
|
+
isTurnContinuation = true;
|
|
239
|
+
}
|
|
240
|
+
const nextUserEvent = userEvents.find(event => event.sourceIndex > userEvent.sourceIndex);
|
|
241
|
+
const turnEndExclusive = nextUserEvent?.sourceIndex ?? Number.MAX_SAFE_INTEGER;
|
|
242
|
+
const turnEvents = events.filter(event => event.sourceIndex >= userEvent.sourceIndex && event.sourceIndex < turnEndExclusive);
|
|
243
|
+
const hasNewReply = turnEvents.some(event => event.kind === 'assistant_reply' && event.sourceIndex > effectiveSourceIndex);
|
|
244
|
+
const shouldEmitUser = userEvent.sourceIndex > effectiveSourceIndex;
|
|
245
|
+
// Hold the turn back until the assistant has actually said something —
|
|
246
|
+
// publishing a prompt with no reply would leave a dangling history entry.
|
|
247
|
+
if (!shouldEmitUser && !hasNewReply)
|
|
248
|
+
return null;
|
|
249
|
+
return { user: userEvent, events: turnEvents, historyIndex, isTurnContinuation };
|
|
250
|
+
}
|
|
251
|
+
function turnToHistory(turn, effectiveSourceIndex) {
|
|
252
|
+
const history = [];
|
|
253
|
+
const finalReply = getFinalReply(turn.events);
|
|
254
|
+
if (turn.user.sourceIndex > effectiveSourceIndex) {
|
|
255
|
+
history.push({
|
|
256
|
+
role: 'User',
|
|
257
|
+
message: turn.user.text,
|
|
258
|
+
message_raw: turn.user.text,
|
|
259
|
+
date: turn.user.date,
|
|
260
|
+
history_index: turn.historyIndex,
|
|
261
|
+
file_names: [],
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
if (finalReply && finalReply.sourceIndex > effectiveSourceIndex) {
|
|
265
|
+
const thoughts = buildThoughts(turn.events, turn.historyIndex);
|
|
266
|
+
history.push({
|
|
267
|
+
role: 'Assistant',
|
|
268
|
+
message: finalReply.text,
|
|
269
|
+
message_raw: finalReply.text,
|
|
270
|
+
date: finalReply.date,
|
|
271
|
+
history_index: turn.historyIndex,
|
|
272
|
+
response_time: calculateResponseTime(turn.user.date, finalReply.date),
|
|
273
|
+
assistant_id: CODEMIE_ASSISTANT_ID,
|
|
274
|
+
...(thoughts.length > 0 && { thoughts }),
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
return history;
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Build the thought tree hung off the assistant entry: one node per tool call
|
|
281
|
+
* (input and output together, since OpenCode keeps both on the same part) and
|
|
282
|
+
* one per reasoning block.
|
|
283
|
+
*/
|
|
284
|
+
function buildThoughts(events, historyIndex) {
|
|
285
|
+
const thoughts = [];
|
|
286
|
+
for (const event of events) {
|
|
287
|
+
if (event.kind === 'user_prompt' || event.kind === 'assistant_reply')
|
|
288
|
+
continue;
|
|
289
|
+
const isTool = event.kind === 'tool_call';
|
|
290
|
+
thoughts.push({
|
|
291
|
+
id: isTool
|
|
292
|
+
? (event.callId || `opencode-tool-${historyIndex}-${event.sourceIndex}`)
|
|
293
|
+
: `opencode-reasoning-${historyIndex}-${event.sourceIndex}`,
|
|
294
|
+
parent_id: null,
|
|
295
|
+
metadata: {
|
|
296
|
+
timestamp: event.date,
|
|
297
|
+
source_index: event.sourceIndex,
|
|
298
|
+
event_kind: event.kind,
|
|
299
|
+
...(isTool && { call_id: event.callId }),
|
|
300
|
+
},
|
|
301
|
+
in_progress: false,
|
|
302
|
+
input_text: event.inputText ?? '',
|
|
303
|
+
message: event.text || (isTool ? '' : '[reasoning]'),
|
|
304
|
+
author_type: isTool ? 'Tool' : 'Agent',
|
|
305
|
+
author_name: isTool ? (event.toolName || 'Unknown Tool') : 'OpenCode Reasoning',
|
|
306
|
+
output_format: 'text',
|
|
307
|
+
error: event.error === true,
|
|
308
|
+
interrupted: false,
|
|
309
|
+
aborted: false,
|
|
310
|
+
children: [],
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
return thoughts;
|
|
314
|
+
}
|
|
315
|
+
function getFinalReply(events) {
|
|
316
|
+
for (let index = events.length - 1; index >= 0; index -= 1) {
|
|
317
|
+
if (events[index].kind === 'assistant_reply')
|
|
318
|
+
return events[index];
|
|
319
|
+
}
|
|
320
|
+
return undefined;
|
|
321
|
+
}
|
|
322
|
+
function resolveTurnModel(events) {
|
|
323
|
+
for (let index = events.length - 1; index >= 0; index -= 1) {
|
|
324
|
+
if (events[index].model)
|
|
325
|
+
return events[index].model;
|
|
326
|
+
}
|
|
327
|
+
return undefined;
|
|
328
|
+
}
|
|
329
|
+
/** Parts OpenCode marks as ignored or synthetic are not user-authored content. */
|
|
330
|
+
function isIgnoredPart(part) {
|
|
331
|
+
const flags = part;
|
|
332
|
+
return flags.ignored === true || flags.synthetic === true;
|
|
333
|
+
}
|
|
334
|
+
function stringify(value) {
|
|
335
|
+
if (value === undefined || value === null)
|
|
336
|
+
return '';
|
|
337
|
+
if (typeof value === 'string')
|
|
338
|
+
return value;
|
|
339
|
+
try {
|
|
340
|
+
return JSON.stringify(value);
|
|
341
|
+
}
|
|
342
|
+
catch {
|
|
343
|
+
return String(value);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
function toIsoDate(timestamp) {
|
|
347
|
+
return new Date(typeof timestamp === 'number' && timestamp > 0 ? timestamp : Date.now()).toISOString();
|
|
348
|
+
}
|
|
349
|
+
function parseLastSyncedSourceIndex(value, fallback) {
|
|
350
|
+
if (typeof value === 'string') {
|
|
351
|
+
const index = Number.parseInt(value.slice(value.lastIndexOf('@') + 1), 10);
|
|
352
|
+
if (Number.isFinite(index))
|
|
353
|
+
return index;
|
|
354
|
+
}
|
|
355
|
+
return fallback;
|
|
356
|
+
}
|
|
357
|
+
function getQueuedCheckpoint(payloads) {
|
|
358
|
+
let sourceIndex = -1;
|
|
359
|
+
let historyIndex = -1;
|
|
360
|
+
for (const payload of payloads) {
|
|
361
|
+
sourceIndex = Math.max(sourceIndex, parseLastSyncedSourceIndex(payload.lastProcessedMessageUuid, -1));
|
|
362
|
+
if (payload.historyIndices.length > 0) {
|
|
363
|
+
historyIndex = Math.max(historyIndex, Math.max(...payload.historyIndices));
|
|
364
|
+
}
|
|
116
365
|
}
|
|
366
|
+
return { sourceIndex, historyIndex };
|
|
367
|
+
}
|
|
368
|
+
function calculateResponseTime(start, end) {
|
|
369
|
+
const startMs = new Date(start).getTime();
|
|
370
|
+
const endMs = new Date(end).getTime();
|
|
371
|
+
if (Number.isNaN(startMs) || Number.isNaN(endMs))
|
|
372
|
+
return undefined;
|
|
373
|
+
return Math.max(0, Math.round(((endMs - startMs) / 1000) * 100) / 100);
|
|
117
374
|
}
|
|
118
375
|
//# sourceMappingURL=opencode.conversations-processor.js.map
|
package/dist/agents/plugins/opencode/session/processors/opencode.conversations-processor.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"opencode.conversations-processor.js","sourceRoot":"","sources":["../../../../../../src/agents/plugins/opencode/session/processors/opencode.conversations-processor.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"opencode.conversations-processor.js","sourceRoot":"","sources":["../../../../../../src/agents/plugins/opencode/session/processors/opencode.conversations-processor.ts"],"names":[],"mappings":"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"}
|
|
@@ -13,6 +13,17 @@
|
|
|
13
13
|
*/
|
|
14
14
|
import type { SessionProcessor, ProcessingContext, ProcessingResult } from '../../../../core/session/BaseProcessor.js';
|
|
15
15
|
import type { ParsedSession } from '../../../../core/session/BaseSessionAdapter.js';
|
|
16
|
+
/**
|
|
17
|
+
* Count added/removed lines in a unified diff.
|
|
18
|
+
*
|
|
19
|
+
* OpenCode reports edits as patch text (`state.metadata.filediff.patch`,
|
|
20
|
+
* `state.metadata.diff`, `apply_patch` per-file `patch`); unlike Claude it never
|
|
21
|
+
* emits numeric additions/deletions, so the counts have to come from the diff.
|
|
22
|
+
*/
|
|
23
|
+
export declare function countDiffLines(patch: unknown): {
|
|
24
|
+
linesAdded: number;
|
|
25
|
+
linesRemoved: number;
|
|
26
|
+
};
|
|
16
27
|
/**
|
|
17
28
|
* OpenCode Metrics Processor
|
|
18
29
|
*
|
|
@@ -22,8 +33,6 @@ import type { ParsedSession } from '../../../../core/session/BaseSessionAdapter.
|
|
|
22
33
|
export declare class OpenCodeMetricsProcessor implements SessionProcessor {
|
|
23
34
|
readonly name = "opencode-metrics";
|
|
24
35
|
readonly priority = 1;
|
|
25
|
-
private readonly cacheDir;
|
|
26
|
-
constructor();
|
|
27
36
|
/**
|
|
28
37
|
* Check if session has data to process
|
|
29
38
|
*/
|
|
@@ -33,36 +42,34 @@ export declare class OpenCodeMetricsProcessor implements SessionProcessor {
|
|
|
33
42
|
*
|
|
34
43
|
* Per tech spec ADR-1/G2: Validate metadata at START before any processing
|
|
35
44
|
*/
|
|
36
|
-
process(session: ParsedSession,
|
|
37
|
-
/**
|
|
38
|
-
* Check if session should be processed (cooldown check per ADR-18)
|
|
39
|
-
*/
|
|
40
|
-
private shouldProcessSession;
|
|
45
|
+
process(session: ParsedSession, context: ProcessingContext): Promise<ProcessingResult>;
|
|
41
46
|
/**
|
|
42
|
-
*
|
|
47
|
+
* Resolve the git branch every delta in this batch is attributed to.
|
|
48
|
+
*
|
|
49
|
+
* Mirrors codex.metrics-processor's resolveBranch: prefer the branch the CLI
|
|
50
|
+
* already resolved (BaseAgentAdapter sets CODEMIE_GIT_BRANCH before spawning),
|
|
51
|
+
* then the value the adapter overlaid onto session metadata, then detect it.
|
|
43
52
|
*/
|
|
44
|
-
private
|
|
53
|
+
private resolveBranch;
|
|
45
54
|
/**
|
|
46
|
-
* Transform messages to MetricDelta records
|
|
55
|
+
* Transform messages to MetricDelta records.
|
|
56
|
+
*
|
|
57
|
+
* One delta per tool call (`{messageId}:{callID}`), per user prompt
|
|
58
|
+
* (`{messageId}:prompt`) and per failed turn (`{messageId}:error`).
|
|
47
59
|
*
|
|
48
|
-
*
|
|
60
|
+
* Granularity matters: when the recordId was the bare assistant message id,
|
|
61
|
+
* the first incremental tick claimed the message and every tool that message
|
|
62
|
+
* accumulated afterwards was deduped away and never reported.
|
|
49
63
|
*/
|
|
50
64
|
private transformMessagesToDeltas;
|
|
51
65
|
/**
|
|
52
|
-
*
|
|
66
|
+
* Build a single-tool delta, or undefined when the tool is still in flight.
|
|
53
67
|
*/
|
|
54
|
-
private
|
|
68
|
+
private buildToolDelta;
|
|
55
69
|
/**
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
* When partsMap is provided (SQLite-backed sessions), uses pre-loaded parts
|
|
59
|
-
* directly instead of reading from the filesystem.
|
|
60
|
-
*/
|
|
61
|
-
private loadPartsForMessage;
|
|
62
|
-
/**
|
|
63
|
-
* Extract tool metrics from parts (ADR-8, ADR-14)
|
|
70
|
+
* Resolve timestamp with fallback chain (ADR-13 G4)
|
|
64
71
|
*/
|
|
65
|
-
private
|
|
72
|
+
private resolveTimestamp;
|
|
66
73
|
/**
|
|
67
74
|
* Map tool status to success/failure/skip (ADR-14)
|
|
68
75
|
*/
|
|
@@ -72,25 +79,22 @@ export declare class OpenCodeMetricsProcessor implements SessionProcessor {
|
|
|
72
79
|
* Only emits allowed file operation types.
|
|
73
80
|
*/
|
|
74
81
|
private extractFileOperation;
|
|
75
|
-
/**
|
|
76
|
-
* Extract user prompts from messages (ADR-10, ADR-20)
|
|
77
|
-
*/
|
|
78
|
-
private extractUserPrompts;
|
|
79
82
|
/**
|
|
80
83
|
* Extract user prompt text from message (ADR-10, ADR-20)
|
|
81
84
|
*/
|
|
82
85
|
private extractUserPromptText;
|
|
83
86
|
/**
|
|
84
|
-
* Get existing record IDs for deduplication (ADR-5)
|
|
85
|
-
*
|
|
87
|
+
* Get existing record IDs for deduplication (ADR-5).
|
|
88
|
+
* Single tolerant read of the JSONL — corrupted lines are skipped.
|
|
86
89
|
*/
|
|
87
90
|
private getExistingRecordIds;
|
|
88
91
|
/**
|
|
89
|
-
*
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
*
|
|
92
|
+
* Get valid model string (ADR-6).
|
|
93
|
+
*
|
|
94
|
+
* Returns the BARE model id. codemie-claude reports `llm_model` without a
|
|
95
|
+
* provider prefix, so emitting `codemie-proxy/<model>` here would split the
|
|
96
|
+
* same model into two buckets in backend analytics. The provider stays on
|
|
97
|
+
* session metadata for local traceability.
|
|
94
98
|
*/
|
|
95
99
|
private getValidModelString;
|
|
96
100
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"opencode.metrics-processor.d.ts","sourceRoot":"","sources":["../../../../../../src/agents/plugins/opencode/session/processors/opencode.metrics-processor.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,2CAA2C,CAAC;AACvH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gDAAgD,CAAC;
|
|
1
|
+
{"version":3,"file":"opencode.metrics-processor.d.ts","sourceRoot":"","sources":["../../../../../../src/agents/plugins/opencode/session/processors/opencode.metrics-processor.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,2CAA2C,CAAC;AACvH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gDAAgD,CAAC;AAwCpF;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAoB3F;AAED;;;;;GAKG;AACH,qBAAa,wBAAyB,YAAW,gBAAgB;IAC/D,QAAQ,CAAC,IAAI,sBAAsB;IACnC,QAAQ,CAAC,QAAQ,KAAK;IAEtB;;OAEG;IACH,aAAa,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO;IAI9C;;;;OAIG;IACG,OAAO,CAAC,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IA0G5F;;;;;;OAMG;YACW,aAAa;IAgB3B;;;;;;;;;OASG;YACW,yBAAyB;IA0FvC;;OAEG;IACH,OAAO,CAAC,cAAc;IA8BtB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAuBxB;;OAEG;IACH,OAAO,CAAC,aAAa;IAerB;;;OAGG;IACH,OAAO,CAAC,oBAAoB;IAkG5B;;OAEG;YACW,qBAAqB;IAuCnC;;;OAGG;YACW,oBAAoB;IAiBlC;;;;;;;OAOG;IACH,OAAO,CAAC,mBAAmB;CAI5B"}
|