@@ -46,27 +46,22 @@ import { KNOWN_CLAUDE_MODELS, extractVersion } from '../models.js';
4646import { AnthropicConfigSchema , type ClaudeRunnerParams } from '../types.js' ;
4747import { removeUndefinedProperties } from '../utils.js' ;
4848import { BaseRunner } from './base.js' ;
49+ import {
50+ betaServerToolUseBlockToPart ,
51+ unsupportedServerToolError ,
52+ } from './converters/beta.js' ;
53+ import {
54+ inputJsonDeltaError ,
55+ redactedThinkingBlockToPart ,
56+ textBlockToPart ,
57+ textDeltaToPart ,
58+ thinkingBlockToPart ,
59+ thinkingDeltaToPart ,
60+ toolUseBlockToPart ,
61+ webSearchToolResultBlockToPart ,
62+ } from './converters/shared.js' ;
4963import { RunnerTypes } from './types.js' ;
5064
51- /**
52- * Server-managed tool blocks emitted by the beta API that Genkit cannot yet
53- * interpret. We fail fast on these so callers do not accidentally treat them as
54- * locally executable tool invocations.
55- */
56- /**
57- * Server tool types that exist in beta but are not yet supported.
58- * Note: server_tool_use and web_search_tool_result ARE supported (same as stable API).
59- */
60- const BETA_UNSUPPORTED_SERVER_TOOL_BLOCK_TYPES = new Set < string > ( [
61- 'web_fetch_tool_result' ,
62- 'code_execution_tool_result' ,
63- 'bash_code_execution_tool_result' ,
64- 'text_editor_code_execution_tool_result' ,
65- 'mcp_tool_result' ,
66- 'mcp_tool_use' ,
67- 'container_upload' ,
68- ] ) ;
69-
7065const BETA_APIS = [
7166 // 'message-batches-2024-09-24',
7267 // 'prompt-caching-2024-07-31',
@@ -118,9 +113,6 @@ function toAnthropicSchema(
118113 return out ;
119114}
120115
121- const unsupportedServerToolError = ( blockType : string ) : string =>
122- `Anthropic beta runner does not yet support server-managed tool block '${ blockType } '. Please retry against the stable API or wait for dedicated support.` ;
123-
124116interface BetaRunnerTypes extends RunnerTypes {
125117 Message : BetaMessage ;
126118 Stream : BetaMessageStream ;
@@ -167,7 +159,7 @@ export class BetaRunner extends BaseRunner<BetaRunnerTypes> {
167159 const signature = this . getThinkingSignature ( part ) ;
168160 if ( ! signature ) {
169161 throw new Error (
170- 'Anthropic thinking parts require a signature when sending back to the API. Preserve the `custom.anthropicThinking.signature ` value from the original response.'
162+ 'Anthropic thinking parts require a signature when sending back to the API. Preserve the `metadata.thoughtSignature ` value from the original response.'
171163 ) ;
172164 }
173165 return {
@@ -462,89 +454,64 @@ export class BetaRunner extends BaseRunner<BetaRunnerTypes> {
462454
463455 protected toGenkitPart ( event : BetaRawMessageStreamEvent ) : Part | undefined {
464456 if ( event . type === 'content_block_start' ) {
465- const blockType = ( event . content_block as { type ?: string } ) . type ;
466- if (
467- blockType &&
468- BETA_UNSUPPORTED_SERVER_TOOL_BLOCK_TYPES . has ( blockType )
469- ) {
470- throw new Error ( unsupportedServerToolError ( blockType ) ) ;
471- }
472457 return this . fromBetaContentBlock ( event . content_block ) ;
473458 }
474459 if ( event . type === 'content_block_delta' ) {
475460 if ( event . delta . type === 'text_delta' ) {
476- return { text : event . delta . text } ;
461+ return textDeltaToPart ( event . delta ) ;
477462 }
478463 if ( event . delta . type === 'thinking_delta' ) {
479- return { reasoning : event . delta . thinking } ;
464+ return thinkingDeltaToPart ( event . delta ) ;
480465 }
481- // server/client tool input_json_delta not supported yet
466+ if ( event . delta . type === 'input_json_delta' ) {
467+ throw inputJsonDeltaError ( ) ;
468+ }
469+ // signature_delta - ignore
482470 return undefined ;
483471 }
484472 return undefined ;
485473 }
486474
487475 private fromBetaContentBlock ( contentBlock : BetaContentBlock ) : Part {
488476 switch ( contentBlock . type ) {
489- case 'tool_use' : {
490- return {
491- toolRequest : {
492- ref : contentBlock . id ,
493- name : contentBlock . name ?? 'unknown_tool' ,
494- input : contentBlock . input ,
495- } ,
496- } ;
497- }
498-
499- case 'mcp_tool_use' :
500- throw new Error ( unsupportedServerToolError ( contentBlock . type ) ) ;
501-
502- case 'server_tool_use' : {
503- const baseName = contentBlock . name ?? 'unknown_tool' ;
504- const serverToolName =
505- 'server_name' in contentBlock && contentBlock . server_name
506- ? `${ contentBlock . server_name } /${ baseName } `
507- : baseName ;
508- return {
509- text : `[Anthropic server tool ${ serverToolName } ] input: ${ JSON . stringify ( contentBlock . input ) } ` ,
510- custom : {
511- anthropicServerToolUse : {
512- id : contentBlock . id ,
513- name : serverToolName ,
514- input : contentBlock . input ,
515- } ,
516- } ,
517- } ;
518- }
477+ case 'text' :
478+ return textBlockToPart ( contentBlock ) ;
519479
520- case 'web_search_tool_result' :
521- return this . toWebSearchToolResultPart ( {
522- type : contentBlock . type ,
523- toolUseId : contentBlock . tool_use_id ,
524- content : contentBlock . content ,
480+ case 'tool_use' :
481+ // Beta API may have undefined name, fallback to 'unknown_tool'
482+ return toolUseBlockToPart ( {
483+ id : contentBlock . id ,
484+ name : contentBlock . name ?? 'unknown_tool' ,
485+ input : contentBlock . input ,
525486 } ) ;
526487
527- case 'text' :
528- return { text : contentBlock . text } ;
529-
530488 case 'thinking' :
531- return this . createThinkingPart (
532- contentBlock . thinking ,
533- contentBlock . signature
534- ) ;
489+ return thinkingBlockToPart ( contentBlock ) ;
535490
536491 case 'redacted_thinking' :
537- return { custom : { redactedThinking : contentBlock . data } } ;
492+ return redactedThinkingBlockToPart ( contentBlock ) ;
493+
494+ case 'server_tool_use' :
495+ return betaServerToolUseBlockToPart ( contentBlock ) ;
496+
497+ case 'web_search_tool_result' :
498+ return webSearchToolResultBlockToPart ( contentBlock ) ;
499+
500+ // Unsupported beta server tool types
501+ case 'mcp_tool_use' :
502+ case 'mcp_tool_result' :
503+ case 'web_fetch_tool_result' :
504+ case 'code_execution_tool_result' :
505+ case 'bash_code_execution_tool_result' :
506+ case 'text_editor_code_execution_tool_result' :
507+ case 'container_upload' :
508+ case 'tool_search_tool_result' :
509+ throw new Error ( unsupportedServerToolError ( contentBlock . type ) ) ;
538510
539511 default : {
540- if ( BETA_UNSUPPORTED_SERVER_TOOL_BLOCK_TYPES . has ( contentBlock . type ) ) {
541- throw new Error ( unsupportedServerToolError ( contentBlock . type ) ) ;
542- }
543512 const unknownType = ( contentBlock as { type : string } ) . type ;
544513 logger . warn (
545- `Unexpected Anthropic beta content block type: ${ unknownType } . Returning empty text. Content block: ${ JSON . stringify (
546- contentBlock
547- ) } `
514+ `Unexpected Anthropic beta content block type: ${ unknownType } . Returning empty text. Content block: ${ JSON . stringify ( contentBlock ) } `
548515 ) ;
549516 return { text : '' } ;
550517 }
0 commit comments