@workbench-ai/agent-driver-anthropic-claude-code 0.0.44 → 0.0.46
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/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/local-traces.d.ts +3 -0
- package/dist/local-traces.d.ts.map +1 -0
- package/dist/local-traces.js +397 -0
- package/package.json +2 -7
package/dist/index.d.ts
CHANGED
|
@@ -139,6 +139,7 @@ export declare const claudeHarnessProvider: HarnessProvider<ClaudeSessionState,
|
|
|
139
139
|
}>;
|
|
140
140
|
export { projectClaudeGlobalSkills, syncClaudeGlobalSkills, } from "./global-skills.js";
|
|
141
141
|
export { CLAUDE_CODE_OAUTH_TOKEN_ENV, claudeWorkbenchProviderAuth, collectClaudeWorkbenchBedrockEnv, parseClaudeSetupTokenOutput, type ClaudeWorkbenchBedrockEnvCollection, type ClaudeWorkbenchProviderAuthEnvVar, } from "./workbench-auth.js";
|
|
142
|
+
export { claudeLocalTraceAdapter, } from "./local-traces.js";
|
|
142
143
|
export declare function claudeCodeHarness(options?: {
|
|
143
144
|
executable?: string;
|
|
144
145
|
}): HarnessProvider<ClaudeSessionState, {
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAS,KAAK,8BAA8B,EAAE,MAAM,oBAAoB,CAAC;AAChF,OAAO,QAAQ,MAAM,eAAe,CAAC;AAErC,OAAO,EAGL,KAAK,cAAc,EACnB,KAAK,oBAAoB,EACzB,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,yBAAyB,EAC9B,KAAK,gBAAgB,EAGrB,KAAK,UAAU,EACf,KAAK,SAAS,EAkBd,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,EACzB,KAAK,yBAAyB,EAC9B,KAAK,kBAAkB,EACvB,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAEnB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AA8BxB,eAAO,MAAM,uBAAuB;;;;;;;;gCAIlC,CAAC;AAEH,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;kBAiB3B,CAAC;AAEZ,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AACxE,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAE5E,wBAAgB,6BAA6B,CAC3C,OAAO,GAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAA;CAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yBAsBR,yBAAyB;;;;EAiBvD;AAED,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yBAnBL,yBAAyB;;;;CAmBc,CAAC;AACvE,eAAO,MAAM,qBAAqB,EAAE,eAEnC,CAAC;AAEF,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;EAAsB,CAAC;AAEzD,OAAO,EACL,yBAAyB,EACzB,sBAAsB,GACvB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,2BAA2B,EAC3B,2BAA2B,EAC3B,gCAAgC,EAChC,2BAA2B,EAC3B,KAAK,mCAAmC,EACxC,KAAK,iCAAiC,GACvC,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -84,6 +84,7 @@ export const claudeHarnessManifest = createCliHarnessManifest(claudeHarnessDefin
|
|
|
84
84
|
export const claudeHarnessProvider = claudeCodeHarness();
|
|
85
85
|
export { projectClaudeGlobalSkills, syncClaudeGlobalSkills, } from "./global-skills.js";
|
|
86
86
|
export { CLAUDE_CODE_OAUTH_TOKEN_ENV, claudeWorkbenchProviderAuth, collectClaudeWorkbenchBedrockEnv, parseClaudeSetupTokenOutput, } from "./workbench-auth.js";
|
|
87
|
+
export { claudeLocalTraceAdapter, } from "./local-traces.js";
|
|
87
88
|
export function claudeCodeHarness(options = {}) {
|
|
88
89
|
const definition = createClaudeHarnessDefinition(options);
|
|
89
90
|
return defineHarnessProvider({
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local-traces.d.ts","sourceRoot":"","sources":["../src/local-traces.ts"],"names":[],"mappings":"AAGA,OAAO,EAuBL,KAAK,iBAAiB,EAKvB,MAAM,4BAA4B,CAAC;AAgBpC,eAAO,MAAM,uBAAuB,EAAE,iBAgIrC,CAAC"}
|
|
@@ -0,0 +1,397 @@
|
|
|
1
|
+
import { promises as fs } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { appendUnique, buildAgentReadableTraceDigest, collectTraceToolArtifacts, createEmptyTraceArtifacts, expandLocalTraceHomePath, localTraceHomeDir, localTraceRefIsAtOrAfter, localTraceRefMatchesWorkspace, localTraceShortHash, mergeLocalTraceRawType, mergeLocalTraceTimelineTool, normalizeTraceText, readLocalTraceJsonLines, sortLocalTraceRefs, traceJsonArray, traceJsonObject, traceString, truncateTraceJsonValue, truncateTraceText, } from "@workbench-ai/agent-driver";
|
|
4
|
+
const CLAUDE_LOCAL_TRACE_PROVIDER = "claude";
|
|
5
|
+
const CLAUDE_LOCAL_TRACE_DISPLAY = "Anthropic Claude Code";
|
|
6
|
+
export const claudeLocalTraceAdapter = {
|
|
7
|
+
id: CLAUDE_LOCAL_TRACE_PROVIDER,
|
|
8
|
+
displayName: CLAUDE_LOCAL_TRACE_DISPLAY,
|
|
9
|
+
async discoverLocalTraces(context = {}) {
|
|
10
|
+
const requested = parseClaudeTraceId(context.traceId);
|
|
11
|
+
if (context.traceId && !requested) {
|
|
12
|
+
return [];
|
|
13
|
+
}
|
|
14
|
+
const homeRoot = resolveClaudeHomeRoot(context.env);
|
|
15
|
+
const projectsRoot = path.join(homeRoot, ".claude", "projects");
|
|
16
|
+
const summaries = await readClaudeSessionSummaries(projectsRoot);
|
|
17
|
+
const refs = [];
|
|
18
|
+
for (const summary of summaries) {
|
|
19
|
+
if (requested &&
|
|
20
|
+
(summary.sessionId !== requested.sessionId ||
|
|
21
|
+
localTraceShortHash(summary.sourcePath) !== requested.sourceHash)) {
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
const ref = claudeSummaryToRef(homeRoot, summary);
|
|
25
|
+
if (!localTraceRefMatchesWorkspace(ref, context.workspaceRoot)) {
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
if (context.since && !localTraceRefIsAtOrAfter(ref, context.since)) {
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
refs.push(ref);
|
|
32
|
+
if (requested) {
|
|
33
|
+
break;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
const sorted = sortLocalTraceRefs(refs);
|
|
37
|
+
return typeof context.limit === "number" && context.limit > 0
|
|
38
|
+
? sorted.slice(0, context.limit)
|
|
39
|
+
: sorted;
|
|
40
|
+
},
|
|
41
|
+
async readLocalTraceDigest(ref, context = {}) {
|
|
42
|
+
const records = await readLocalTraceJsonLines(ref.sourcePath);
|
|
43
|
+
const maxTextChars = context.maxTextChars ?? 4_000;
|
|
44
|
+
const maxToolOutputChars = context.maxToolOutputChars ?? Math.min(maxTextChars, 1_000);
|
|
45
|
+
const timeline = [];
|
|
46
|
+
const toolEntryById = new Map();
|
|
47
|
+
const artifacts = createEmptyTraceArtifacts();
|
|
48
|
+
let goal;
|
|
49
|
+
const pushEntry = (entry) => {
|
|
50
|
+
const timelineEntry = {
|
|
51
|
+
index: timeline.length,
|
|
52
|
+
...entry,
|
|
53
|
+
};
|
|
54
|
+
timeline.push(timelineEntry);
|
|
55
|
+
return timelineEntry;
|
|
56
|
+
};
|
|
57
|
+
const pushToolEntry = (tool, at, rawType) => {
|
|
58
|
+
collectTraceToolArtifacts(artifacts, tool);
|
|
59
|
+
const existing = tool.id ? toolEntryById.get(tool.id) : undefined;
|
|
60
|
+
if (existing?.tool) {
|
|
61
|
+
existing.tool = mergeLocalTraceTimelineTool(existing.tool, tool);
|
|
62
|
+
existing.raw = { type: mergeLocalTraceRawType(existing.raw?.type, rawType) };
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
const entry = pushEntry({
|
|
66
|
+
type: "tool",
|
|
67
|
+
...(at ? { at } : {}),
|
|
68
|
+
tool,
|
|
69
|
+
raw: { type: rawType },
|
|
70
|
+
});
|
|
71
|
+
if (tool.id) {
|
|
72
|
+
toolEntryById.set(tool.id, entry);
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
for (const record of records) {
|
|
76
|
+
const type = traceString(record.type);
|
|
77
|
+
const at = traceString(record.timestamp);
|
|
78
|
+
if (type === "user" || type === "assistant") {
|
|
79
|
+
const message = traceJsonObject(record.message);
|
|
80
|
+
const role = traceString(message?.role);
|
|
81
|
+
if (role !== "user" && role !== "assistant") {
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
const text = truncateTraceText(extractClaudeMessageText(message), maxTextChars);
|
|
85
|
+
if (text) {
|
|
86
|
+
if (role === "user" && !goal) {
|
|
87
|
+
goal = truncateTraceText(text, 300) ?? undefined;
|
|
88
|
+
}
|
|
89
|
+
pushEntry({
|
|
90
|
+
type: role,
|
|
91
|
+
...(at ? { at } : {}),
|
|
92
|
+
text,
|
|
93
|
+
raw: { type },
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
for (const tool of extractClaudeTools(message, role, maxTextChars, maxToolOutputChars)) {
|
|
97
|
+
pushToolEntry(tool, at, type);
|
|
98
|
+
}
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
if (type === "system" && traceString(record.subtype) === "error") {
|
|
102
|
+
const message = truncateTraceText(traceString(record.message), maxTextChars);
|
|
103
|
+
if (message) {
|
|
104
|
+
appendUnique(artifacts.errors, message);
|
|
105
|
+
pushEntry({
|
|
106
|
+
type: "error",
|
|
107
|
+
...(at ? { at } : {}),
|
|
108
|
+
text: message,
|
|
109
|
+
raw: { type: "system.error" },
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return buildAgentReadableTraceDigest({
|
|
115
|
+
provider: CLAUDE_LOCAL_TRACE_PROVIDER,
|
|
116
|
+
ref,
|
|
117
|
+
...(goal ? { goal } : {}),
|
|
118
|
+
timeline,
|
|
119
|
+
artifacts,
|
|
120
|
+
});
|
|
121
|
+
},
|
|
122
|
+
};
|
|
123
|
+
function parseClaudeTraceId(traceId) {
|
|
124
|
+
if (!traceId) {
|
|
125
|
+
return null;
|
|
126
|
+
}
|
|
127
|
+
const [provider, sessionId, sourceHash, ...extra] = traceId.split(":");
|
|
128
|
+
if (provider !== CLAUDE_LOCAL_TRACE_PROVIDER ||
|
|
129
|
+
!sessionId ||
|
|
130
|
+
!sourceHash ||
|
|
131
|
+
extra.length > 0) {
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
return { sessionId, sourceHash };
|
|
135
|
+
}
|
|
136
|
+
function resolveClaudeHomeRoot(env = process.env) {
|
|
137
|
+
const explicit = env.AGENT_RUNTIME_CLAUDE_HOME?.trim();
|
|
138
|
+
if (explicit) {
|
|
139
|
+
return path.resolve(expandLocalTraceHomePath(explicit, env));
|
|
140
|
+
}
|
|
141
|
+
return localTraceHomeDir(env);
|
|
142
|
+
}
|
|
143
|
+
async function readClaudeSessionSummaries(projectsRoot) {
|
|
144
|
+
const projectEntries = await fs.readdir(projectsRoot, { withFileTypes: true }).catch(() => []);
|
|
145
|
+
const summaries = [];
|
|
146
|
+
const seenPaths = new Set();
|
|
147
|
+
for (const entry of projectEntries) {
|
|
148
|
+
if (!entry.isDirectory()) {
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
151
|
+
const projectRoot = path.join(projectsRoot, entry.name);
|
|
152
|
+
const indexPath = path.join(projectRoot, "sessions-index.json");
|
|
153
|
+
for (const summary of await readClaudeIndexSummaries(indexPath)) {
|
|
154
|
+
if (seenPaths.has(summary.sourcePath)) {
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
seenPaths.add(summary.sourcePath);
|
|
158
|
+
summaries.push(summary);
|
|
159
|
+
}
|
|
160
|
+
const direct = await summarizeClaudeProjectJsonlFiles(projectRoot, seenPaths);
|
|
161
|
+
summaries.push(...direct);
|
|
162
|
+
}
|
|
163
|
+
return summaries;
|
|
164
|
+
}
|
|
165
|
+
async function readClaudeIndexSummaries(indexPath) {
|
|
166
|
+
const raw = await fs.readFile(indexPath, "utf8").catch(() => null);
|
|
167
|
+
if (!raw) {
|
|
168
|
+
return [];
|
|
169
|
+
}
|
|
170
|
+
let parsed;
|
|
171
|
+
try {
|
|
172
|
+
parsed = JSON.parse(raw);
|
|
173
|
+
}
|
|
174
|
+
catch {
|
|
175
|
+
return [];
|
|
176
|
+
}
|
|
177
|
+
const entries = normalizeClaudeIndexEntries(parsed);
|
|
178
|
+
const summaries = [];
|
|
179
|
+
for (const entry of entries) {
|
|
180
|
+
const sessionId = traceString(entry.sessionId);
|
|
181
|
+
const sourcePath = traceString(entry.fullPath);
|
|
182
|
+
if (!sessionId || !sourcePath || !(await pathExists(sourcePath))) {
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
185
|
+
const title = truncateTraceText(traceString(entry.summary), 96) ??
|
|
186
|
+
truncateTraceText(traceString(entry.firstPrompt), 96) ??
|
|
187
|
+
undefined;
|
|
188
|
+
summaries.push({
|
|
189
|
+
sessionId,
|
|
190
|
+
sourcePath,
|
|
191
|
+
indexPath,
|
|
192
|
+
...(title ? { title } : {}),
|
|
193
|
+
...(traceString(entry.projectPath) ? { workspaceRoot: path.resolve(traceString(entry.projectPath)) } : {}),
|
|
194
|
+
...(traceString(entry.created) ? { startedAt: traceString(entry.created) } : {}),
|
|
195
|
+
...(traceString(entry.modified) ?? traceString(entry.created) ? { updatedAt: (traceString(entry.modified) ?? traceString(entry.created)) } : {}),
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
return summaries;
|
|
199
|
+
}
|
|
200
|
+
function normalizeClaudeIndexEntries(value) {
|
|
201
|
+
if (Array.isArray(value)) {
|
|
202
|
+
return value.flatMap((entry) => {
|
|
203
|
+
const record = traceJsonObject(entry);
|
|
204
|
+
return record ? [record] : [];
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
const record = traceJsonObject(value);
|
|
208
|
+
return traceJsonArray(record?.entries).flatMap((entry) => {
|
|
209
|
+
const item = traceJsonObject(entry);
|
|
210
|
+
return item ? [item] : [];
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
async function summarizeClaudeProjectJsonlFiles(projectRoot, seenPaths) {
|
|
214
|
+
const entries = await fs.readdir(projectRoot, { withFileTypes: true }).catch(() => []);
|
|
215
|
+
const summaries = [];
|
|
216
|
+
for (const entry of entries) {
|
|
217
|
+
if (!entry.isFile() || !entry.name.endsWith(".jsonl")) {
|
|
218
|
+
continue;
|
|
219
|
+
}
|
|
220
|
+
const sourcePath = path.join(projectRoot, entry.name);
|
|
221
|
+
if (seenPaths.has(sourcePath)) {
|
|
222
|
+
continue;
|
|
223
|
+
}
|
|
224
|
+
const summary = await summarizeClaudeSessionFile(sourcePath);
|
|
225
|
+
if (!summary) {
|
|
226
|
+
continue;
|
|
227
|
+
}
|
|
228
|
+
seenPaths.add(sourcePath);
|
|
229
|
+
summaries.push(summary);
|
|
230
|
+
}
|
|
231
|
+
return summaries;
|
|
232
|
+
}
|
|
233
|
+
async function summarizeClaudeSessionFile(sourcePath) {
|
|
234
|
+
const records = await readLocalTraceJsonLines(sourcePath).catch(() => []);
|
|
235
|
+
let sessionId;
|
|
236
|
+
let workspaceRoot;
|
|
237
|
+
let title;
|
|
238
|
+
let startedAt;
|
|
239
|
+
let endedAt;
|
|
240
|
+
for (const record of records) {
|
|
241
|
+
sessionId ??= traceString(record.sessionId) ?? undefined;
|
|
242
|
+
const cwd = traceString(record.cwd);
|
|
243
|
+
if (!workspaceRoot && cwd) {
|
|
244
|
+
workspaceRoot = path.resolve(cwd);
|
|
245
|
+
}
|
|
246
|
+
const timestamp = traceString(record.timestamp);
|
|
247
|
+
if (timestamp) {
|
|
248
|
+
startedAt ??= timestamp;
|
|
249
|
+
endedAt = timestamp;
|
|
250
|
+
}
|
|
251
|
+
if (title) {
|
|
252
|
+
continue;
|
|
253
|
+
}
|
|
254
|
+
if (traceString(record.type) === "last-prompt") {
|
|
255
|
+
title = truncateTraceText(traceString(record.lastPrompt), 96) ?? undefined;
|
|
256
|
+
continue;
|
|
257
|
+
}
|
|
258
|
+
if (traceString(record.type) !== "user") {
|
|
259
|
+
continue;
|
|
260
|
+
}
|
|
261
|
+
const message = traceJsonObject(record.message);
|
|
262
|
+
if (traceString(message?.role) !== "user") {
|
|
263
|
+
continue;
|
|
264
|
+
}
|
|
265
|
+
title = truncateTraceText(extractClaudeMessageText(message), 96) ?? undefined;
|
|
266
|
+
}
|
|
267
|
+
sessionId ??= path.basename(sourcePath, ".jsonl");
|
|
268
|
+
const fallbackUpdatedAt = await fs.stat(sourcePath)
|
|
269
|
+
.then((stat) => stat.mtime.toISOString())
|
|
270
|
+
.catch(() => undefined);
|
|
271
|
+
return {
|
|
272
|
+
sessionId,
|
|
273
|
+
sourcePath,
|
|
274
|
+
...(title ? { title } : {}),
|
|
275
|
+
...(workspaceRoot ? { workspaceRoot } : {}),
|
|
276
|
+
...(startedAt ? { startedAt } : {}),
|
|
277
|
+
...(endedAt ? { endedAt } : {}),
|
|
278
|
+
updatedAt: endedAt ?? fallbackUpdatedAt,
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
async function pathExists(filePath) {
|
|
282
|
+
return await fs.stat(filePath)
|
|
283
|
+
.then(() => true)
|
|
284
|
+
.catch(() => false);
|
|
285
|
+
}
|
|
286
|
+
function claudeSummaryToRef(homeRoot, summary) {
|
|
287
|
+
return {
|
|
288
|
+
provider: CLAUDE_LOCAL_TRACE_PROVIDER,
|
|
289
|
+
traceId: `claude:${summary.sessionId}:${localTraceShortHash(summary.sourcePath)}`,
|
|
290
|
+
sourcePath: summary.sourcePath,
|
|
291
|
+
profileRoot: homeRoot,
|
|
292
|
+
sessionId: summary.sessionId,
|
|
293
|
+
...(summary.indexPath ? { indexPath: summary.indexPath } : {}),
|
|
294
|
+
...(summary.title ? { title: summary.title } : {}),
|
|
295
|
+
...(summary.workspaceRoot ? { workspaceRoot: summary.workspaceRoot } : {}),
|
|
296
|
+
...(summary.startedAt ? { startedAt: summary.startedAt } : {}),
|
|
297
|
+
...(summary.endedAt ? { endedAt: summary.endedAt } : {}),
|
|
298
|
+
...(summary.updatedAt ? { updatedAt: summary.updatedAt } : {}),
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
function extractClaudeMessageText(message) {
|
|
302
|
+
if (!message) {
|
|
303
|
+
return null;
|
|
304
|
+
}
|
|
305
|
+
const direct = normalizeTraceText(traceString(message.content));
|
|
306
|
+
if (direct) {
|
|
307
|
+
return direct;
|
|
308
|
+
}
|
|
309
|
+
const chunks = [];
|
|
310
|
+
for (const block of traceJsonArray(message.content)) {
|
|
311
|
+
const item = traceJsonObject(block);
|
|
312
|
+
if (traceString(item?.type) !== "text") {
|
|
313
|
+
continue;
|
|
314
|
+
}
|
|
315
|
+
const text = normalizeTraceText(traceString(item?.text));
|
|
316
|
+
if (text) {
|
|
317
|
+
chunks.push(text);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
return chunks.length > 0 ? chunks.join("\n\n") : null;
|
|
321
|
+
}
|
|
322
|
+
function extractClaudeTools(message, role, maxTextChars, maxToolOutputChars) {
|
|
323
|
+
if (!message) {
|
|
324
|
+
return [];
|
|
325
|
+
}
|
|
326
|
+
const tools = [];
|
|
327
|
+
for (const block of traceJsonArray(message.content)) {
|
|
328
|
+
const item = traceJsonObject(block);
|
|
329
|
+
const type = traceString(item?.type);
|
|
330
|
+
if (role === "assistant" && type === "tool_use") {
|
|
331
|
+
const rawInput = item?.input;
|
|
332
|
+
const input = rawInput === undefined
|
|
333
|
+
? undefined
|
|
334
|
+
: truncateTraceJsonValue(rawInput, { maxTextChars });
|
|
335
|
+
const command = readToolCommand(rawInput);
|
|
336
|
+
tools.push({
|
|
337
|
+
status: "started",
|
|
338
|
+
...(traceString(item?.id) ? { id: traceString(item?.id) } : {}),
|
|
339
|
+
...(traceString(item?.name) ? { name: traceString(item?.name) } : {}),
|
|
340
|
+
...(input !== undefined ? { input } : {}),
|
|
341
|
+
...(command ? { command } : {}),
|
|
342
|
+
...(readToolCwd(input) ? { cwd: readToolCwd(input) } : {}),
|
|
343
|
+
});
|
|
344
|
+
continue;
|
|
345
|
+
}
|
|
346
|
+
if (role === "user" && type === "tool_result") {
|
|
347
|
+
const output = truncateTraceText(extractClaudeToolResultText(item), maxToolOutputChars);
|
|
348
|
+
const isError = item?.is_error === true || item?.isError === true;
|
|
349
|
+
tools.push({
|
|
350
|
+
status: "completed",
|
|
351
|
+
...(traceString(item?.tool_use_id) ?? traceString(item?.toolUseId)
|
|
352
|
+
? { id: (traceString(item?.tool_use_id) ?? traceString(item?.toolUseId)) }
|
|
353
|
+
: {}),
|
|
354
|
+
...(output ? { output } : {}),
|
|
355
|
+
...(isError && output ? { error: output } : {}),
|
|
356
|
+
});
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
return tools;
|
|
360
|
+
}
|
|
361
|
+
function extractClaudeToolResultText(item) {
|
|
362
|
+
if (!item) {
|
|
363
|
+
return null;
|
|
364
|
+
}
|
|
365
|
+
const direct = normalizeTraceText(traceString(item.content));
|
|
366
|
+
if (direct) {
|
|
367
|
+
return direct;
|
|
368
|
+
}
|
|
369
|
+
const chunks = [];
|
|
370
|
+
for (const block of traceJsonArray(item.content)) {
|
|
371
|
+
const record = traceJsonObject(block);
|
|
372
|
+
if (traceString(record?.type) !== "text") {
|
|
373
|
+
continue;
|
|
374
|
+
}
|
|
375
|
+
const text = normalizeTraceText(traceString(record?.text));
|
|
376
|
+
if (text) {
|
|
377
|
+
chunks.push(text);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
return chunks.length > 0 ? chunks.join("\n\n") : null;
|
|
381
|
+
}
|
|
382
|
+
function readToolCommand(input) {
|
|
383
|
+
const record = traceJsonObject(input);
|
|
384
|
+
if (!record) {
|
|
385
|
+
return undefined;
|
|
386
|
+
}
|
|
387
|
+
return traceString(record.command) ?? traceString(record.cmd) ?? undefined;
|
|
388
|
+
}
|
|
389
|
+
function readToolCwd(input) {
|
|
390
|
+
const record = traceJsonObject(input);
|
|
391
|
+
if (!record) {
|
|
392
|
+
return undefined;
|
|
393
|
+
}
|
|
394
|
+
return traceString(record.cwd) ??
|
|
395
|
+
traceString(record.workdir) ??
|
|
396
|
+
undefined;
|
|
397
|
+
}
|
package/package.json
CHANGED
|
@@ -1,12 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@workbench-ai/agent-driver-anthropic-claude-code",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.46",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"repository": {
|
|
6
|
-
"type": "git",
|
|
7
|
-
"url": "git+https://github.com/workbench-ai/workbench-monorepo.git",
|
|
8
|
-
"directory": "products/agent-drivers/packages/anthropic-claude-code"
|
|
9
|
-
},
|
|
10
5
|
"publishConfig": {
|
|
11
6
|
"registry": "https://registry.npmjs.org/",
|
|
12
7
|
"access": "public"
|
|
@@ -28,7 +23,7 @@
|
|
|
28
23
|
],
|
|
29
24
|
"dependencies": {
|
|
30
25
|
"zod": "^4.1.5",
|
|
31
|
-
"@workbench-ai/agent-driver": "0.0.
|
|
26
|
+
"@workbench-ai/agent-driver": "0.0.46"
|
|
32
27
|
},
|
|
33
28
|
"devDependencies": {
|
|
34
29
|
"@types/node": "^24.3.1",
|