Skip to content

Commit 086c6c6

Browse files
authored
Merge pull request #2 from tmsdnl/main
fix(claude-adapter): handle wrapped stream_event messages
2 parents 720c5fb + 6860eed commit 086c6c6

File tree

1 file changed

+71
-21
lines changed

1 file changed

+71
-21
lines changed

packages/claude-adapter/src/index.ts

Lines changed: 71 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,9 @@ export class ClaudeAdapter implements HeadlessCoder {
400400
}
401401

402402
private captureSessionId(state: ClaudeThreadState, handle: ThreadHandle, message: SDKMessage): void {
403-
const sessionId = (message as any)?.session_id;
403+
const sessionId =
404+
(message as any)?.session_id ??
405+
((message as any)?.type === 'stream_event' ? (message as any)?.event?.session_id : undefined);
404406
if (sessionId && sessionId !== state.sessionId) {
405407
state.sessionId = sessionId;
406408
state.resume = true;
@@ -413,18 +415,66 @@ function normalizeClaudeStreamMessage(message: any, threadId?: string): CoderStr
413415
const ts = now();
414416
const provider: Provider = CODER_NAME;
415417
const events: CoderStreamEvent[] = [];
416-
const typeValue = message?.type ?? message?.label ?? '';
418+
const base =
419+
message?.type === 'stream_event' && message?.event
420+
? {
421+
...message.event,
422+
session_id: message.session_id ?? message.event?.session_id,
423+
model: message.model ?? message.event?.model,
424+
}
425+
: message;
426+
427+
if (base?.type === 'content_block_delta' && base?.delta?.type === 'text_delta') {
428+
return [
429+
{
430+
type: 'message',
431+
provider,
432+
role: 'assistant',
433+
text: extractClaudeAssistantText(base),
434+
delta: true,
435+
ts,
436+
originalItem: message,
437+
},
438+
];
439+
}
440+
441+
if (base?.type === 'content_block_start' && base?.content_block?.type === 'tool_use') {
442+
return [
443+
{
444+
type: 'tool_use',
445+
provider,
446+
name: base.content_block?.name,
447+
callId: base.content_block?.id,
448+
args: base.content_block?.input,
449+
ts,
450+
originalItem: message,
451+
},
452+
];
453+
}
454+
455+
if (base?.type === 'message_delta') {
456+
if (base?.usage) {
457+
events.push({ type: 'usage', provider, stats: base.usage, ts, originalItem: message });
458+
}
459+
if (events.length) return events;
460+
}
461+
462+
if (base?.type === 'message_stop') {
463+
return [{ type: 'done', provider, ts, originalItem: message }];
464+
}
465+
466+
const typeValue = base?.type ?? base?.label ?? '';
417467
const typeText = typeof typeValue === 'string' ? typeValue : String(typeValue ?? '');
418468
const typeLower = typeText.toLowerCase();
419469
const includes = (token: string) => typeLower.includes(token);
420470

421-
if (typeLower === 'sdkinit' || typeLower === 'system' || message?.session_id) {
471+
if (typeLower === 'sdkinit' || typeLower === 'system') {
422472
return [
423473
{
424474
type: 'init',
425475
provider,
426-
threadId: message?.session_id ?? threadId,
427-
model: message?.model,
476+
threadId: base?.session_id ?? threadId,
477+
model: base?.model,
428478
ts,
429479
originalItem: message,
430480
},
@@ -437,7 +487,7 @@ function normalizeClaudeStreamMessage(message: any, threadId?: string): CoderStr
437487
type: 'message',
438488
provider,
439489
role: 'assistant',
440-
text: (message as any).text ?? (message as any).content ?? extractClaudeAssistantText(message),
490+
text: (base as any).text ?? (base as any).content ?? extractClaudeAssistantText(base),
441491
delta: true,
442492
ts,
443493
originalItem: message,
@@ -451,7 +501,7 @@ function normalizeClaudeStreamMessage(message: any, threadId?: string): CoderStr
451501
type: 'message',
452502
provider,
453503
role: 'assistant',
454-
text: extractClaudeAssistantText(message),
504+
text: extractClaudeAssistantText(base),
455505
ts,
456506
originalItem: message,
457507
},
@@ -463,9 +513,9 @@ function normalizeClaudeStreamMessage(message: any, threadId?: string): CoderStr
463513
{
464514
type: 'tool_use',
465515
provider,
466-
name: (message as any).name ?? (message as any).tool_name ?? (message as any).tool,
467-
callId: (message as any).id,
468-
args: (message as any).input,
516+
name: (base as any).name ?? (base as any).tool_name ?? (base as any).tool,
517+
callId: (base as any).id,
518+
args: (base as any).input,
469519
ts,
470520
originalItem: message,
471521
},
@@ -477,9 +527,9 @@ function normalizeClaudeStreamMessage(message: any, threadId?: string): CoderStr
477527
{
478528
type: 'tool_result',
479529
provider,
480-
name: (message as any).name ?? (message as any).tool_name ?? (message as any).tool,
481-
callId: (message as any).tool_use_id ?? (message as any).id,
482-
result: (message as any).output,
530+
name: (base as any).name ?? (base as any).tool_name ?? (base as any).tool,
531+
callId: (base as any).tool_use_id ?? (base as any).id,
532+
result: (base as any).output,
483533
ts,
484534
originalItem: message,
485535
},
@@ -491,36 +541,36 @@ function normalizeClaudeStreamMessage(message: any, threadId?: string): CoderStr
491541
{
492542
type: 'permission',
493543
provider,
494-
request: (message as any).request,
495-
decision: (message as any).decision,
544+
request: (base as any).request,
545+
decision: (base as any).decision,
496546
ts,
497547
originalItem: message,
498548
},
499549
];
500550
}
501551

502552
if (includes('result')) {
503-
if (claudeResultIndicatesError(message)) {
553+
if (claudeResultIndicatesError(base)) {
504554
return [
505555
{
506556
type: 'error',
507557
provider,
508-
message: buildClaudeResultErrorMessage(message),
558+
message: buildClaudeResultErrorMessage(base),
509559
ts,
510560
originalItem: message,
511561
},
512562
];
513563
}
514-
if (message?.usage) {
515-
events.push({ type: 'usage', provider, stats: message.usage, ts, originalItem: message });
564+
if (base?.usage) {
565+
events.push({ type: 'usage', provider, stats: base.usage, ts, originalItem: message });
516566
}
517567
events.push({ type: 'done', provider, ts, originalItem: message });
518568
return events;
519569
}
520570

521571
if (includes('completed') || includes('final')) {
522-
if (message?.usage) {
523-
events.push({ type: 'usage', provider, stats: message.usage, ts, originalItem: message });
572+
if (base?.usage) {
573+
events.push({ type: 'usage', provider, stats: base.usage, ts, originalItem: message });
524574
}
525575
events.push({ type: 'done', provider, ts, originalItem: message });
526576
return events;

0 commit comments

Comments
 (0)