@@ -31,6 +31,7 @@ import {
3131 type ClaudeSettings ,
3232 EventId ,
3333 MessageId ,
34+ type ModelCapabilities ,
3435 type ModelSelection ,
3536 type ProviderApprovalDecision ,
3637 ProviderDriverKind ,
@@ -47,6 +48,7 @@ import {
4748 type ThreadTokenUsageSnapshot ,
4849 type ProviderUserInputAnswers ,
4950 type RuntimeSessionExitKind ,
51+ type ServerProviderModel ,
5052 type RuntimeContentStreamKind ,
5153 RuntimeItemId ,
5254 RuntimeRequestId ,
@@ -387,6 +389,11 @@ export interface ClaudeAdapterLiveOptions {
387389 readonly prompt : AsyncIterable < SDKUserMessage > ;
388390 readonly options : ClaudeQueryOptions ;
389391 } ) => ClaudeQueryRuntime ;
392+ readonly resolveModelMetadata ?: (
393+ model : string ,
394+ ) => Effect . Effect <
395+ Pick < ServerProviderModel , "capabilities" | "supportedRuntimeModes" > | undefined
396+ > ;
390397 readonly nativeEventLogPath ?: string ;
391398 readonly nativeEventLogger ?: EventNdjsonLogger ;
392399 /**
@@ -495,11 +502,11 @@ interface ClaudeFlagSettingsSnapshot {
495502
496503function deriveClaudeFlagSettings (
497504 modelSelection : ModelSelection | undefined ,
505+ capabilities : ModelCapabilities ,
498506) : ClaudeFlagSettingsSnapshot {
499- const caps = getClaudeModelCapabilities ( modelSelection ?. model ) ;
500- const descriptors = getProviderOptionDescriptors ( { caps } ) ;
507+ const descriptors = getProviderOptionDescriptors ( { caps : capabilities } ) ;
501508 const rawEffort = getModelSelectionStringOptionValue ( modelSelection , "effort" ) ;
502- const effort = resolveClaudeEffort ( caps , rawEffort ) ?? null ;
509+ const effort = resolveClaudeEffort ( capabilities , rawEffort ) ?? null ;
503510 const fastModeSupported = descriptors . some (
504511 ( descriptor ) => descriptor . type === "boolean" && descriptor . id === "fastMode" ,
505512 ) ;
@@ -1935,28 +1942,35 @@ function capTranscriptText(value: string, maxChars: number): string {
19351942 */
19361943export function mapClaudeSubagentTranscript (
19371944 jsonl : string ,
1938- options ?: { readonly limit ?: number } ,
1945+ options ?: {
1946+ readonly limit ?: number ;
1947+ readonly offset ?: number ;
1948+ readonly fromEnd ?: boolean ;
1949+ } ,
19391950) : ProviderSubagentTranscriptResult {
19401951 const limit =
19411952 options ?. limit !== undefined && options . limit > 0
19421953 ? options . limit
19431954 : SUBAGENT_TRANSCRIPT_DEFAULT_LIMIT ;
1955+ const requestedOffset = options ?. offset ?? 0 ;
19441956 const entries : Array < ProviderSubagentTranscriptEntry > = [ ] ;
1945- let truncated = false ;
1946-
1947- const push = ( entry : ProviderSubagentTranscriptEntry ) : boolean => {
1948- if ( entries . length >= limit ) {
1949- truncated = true ;
1950- return false ;
1957+ let totalEntries = 0 ;
1958+ const push = ( entry : ProviderSubagentTranscriptEntry ) : void => {
1959+ const entryIndex = totalEntries ;
1960+ totalEntries += 1 ;
1961+ if ( options ?. fromEnd ) {
1962+ entries . push ( entry ) ;
1963+ if ( entries . length > limit ) {
1964+ entries . shift ( ) ;
1965+ }
1966+ return ;
1967+ }
1968+ if ( entryIndex >= requestedOffset && entries . length < limit ) {
1969+ entries . push ( entry ) ;
19511970 }
1952- entries . push ( entry ) ;
1953- return true ;
19541971 } ;
19551972
19561973 for ( const line of jsonl . split ( "\n" ) ) {
1957- if ( truncated ) {
1958- break ;
1959- }
19601974 const record = line . trim ( ) ;
19611975 if ( record . length === 0 ) {
19621976 continue ;
@@ -2053,7 +2067,15 @@ export function mapClaudeSubagentTranscript(
20532067 }
20542068 }
20552069
2056- return { entries, truncated } ;
2070+ const offset = options ?. fromEnd
2071+ ? Math . max ( 0 , totalEntries - limit )
2072+ : Math . min ( requestedOffset , totalEntries ) ;
2073+ return {
2074+ entries,
2075+ truncated : offset > 0 || offset + entries . length < totalEntries ,
2076+ offset,
2077+ totalEntries,
2078+ } ;
20572079}
20582080
20592081/** Non-null `parent_tool_use_id` marks a message forwarded from inside a
@@ -2519,6 +2541,12 @@ export const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (
25192541 prompt : input . prompt ,
25202542 options : input . options ,
25212543 } ) as ClaudeQueryRuntime ) ;
2544+ const resolveModelMetadata =
2545+ options ?. resolveModelMetadata ??
2546+ ( ( ) =>
2547+ Effect . succeed <
2548+ Pick < ServerProviderModel , "capabilities" | "supportedRuntimeModes" > | undefined
2549+ > ( undefined ) ) ;
25222550
25232551 const sessions = new Map < ThreadId , ClaudeSessionContext > ( ) ;
25242552 const runtimeEventQueue = yield * Queue . unbounded < ProviderRuntimeEvent > ( ) ;
@@ -5397,13 +5425,20 @@ export const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (
53975425 const extraArgs = parseCliArgs ( claudeSettings . launchArgs ) . flags ;
53985426 const modelSelection =
53995427 input . modelSelection ?. instanceId === boundInstanceId ? input . modelSelection : undefined ;
5400- const apiModelId = modelSelection ? resolveClaudeApiModelId ( modelSelection ) : undefined ;
5428+ const modelMetadata = modelSelection
5429+ ? yield * resolveModelMetadata ( modelSelection . model )
5430+ : undefined ;
5431+ const modelCapabilities =
5432+ modelMetadata ?. capabilities ?? getClaudeModelCapabilities ( modelSelection ?. model ) ;
5433+ const apiModelId = modelSelection
5434+ ? resolveClaudeApiModelId ( modelSelection , modelCapabilities )
5435+ : undefined ;
54015436 const fallbackModel = resolveClaudeFallbackModelOption ( claudeSettings . fallbackModel , [
54025437 modelSelection ?. model ,
54035438 apiModelId ,
54045439 ] ) ;
54055440 const fallbackModelIds = splitClaudeFallbackModelOption ( fallbackModel ) ;
5406- const flagSettings = deriveClaudeFlagSettings ( modelSelection ) ;
5441+ const flagSettings = deriveClaudeFlagSettings ( modelSelection , modelCapabilities ) ;
54075442 const effectiveEffort = flagSettings . effortLevel ;
54085443 const runtimeModeToPermission : Record < string , PermissionMode > = {
54095444 "auto-accept-edits" : "acceptEdits" ,
@@ -5416,7 +5451,9 @@ export const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (
54165451 // else falls back to in-app approval prompts instead of erroring.
54175452 const autoModeClamped =
54185453 requestedPermissionMode === "auto" &&
5419- ! claudeModelSupportsAutoRuntimeMode ( modelSelection ?. model ) ;
5454+ ! ( modelMetadata
5455+ ? ( modelMetadata . supportedRuntimeModes ?. includes ( "auto" ) ?? true )
5456+ : claudeModelSupportsAutoRuntimeMode ( modelSelection ?. model ) ) ;
54205457 const permissionMode = autoModeClamped ? "acceptEdits" : requestedPermissionMode ;
54215458 const settings = {
54225459 ...( flagSettings . alwaysThinkingEnabled !== null
@@ -5668,6 +5705,11 @@ export const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (
56685705 input . modelSelection !== undefined && input . modelSelection . instanceId === boundInstanceId
56695706 ? input . modelSelection
56705707 : undefined ;
5708+ const modelMetadata = modelSelection
5709+ ? yield * resolveModelMetadata ( modelSelection . model )
5710+ : undefined ;
5711+ const modelCapabilities =
5712+ modelMetadata ?. capabilities ?? getClaudeModelCapabilities ( modelSelection ?. model ) ;
56715713
56725714 if ( context . turnState ) {
56735715 // Auto-close a stale synthetic turn (from background agent responses
@@ -5676,7 +5718,7 @@ export const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (
56765718 }
56775719
56785720 if ( modelSelection ?. model ) {
5679- const apiModelId = resolveClaudeApiModelId ( modelSelection ) ;
5721+ const apiModelId = resolveClaudeApiModelId ( modelSelection , modelCapabilities ) ;
56805722 if ( context . currentApiModelId !== apiModelId ) {
56815723 yield * Effect . tryPromise ( {
56825724 try : ( ) => context . query . setModel ( apiModelId ) ,
@@ -5695,7 +5737,7 @@ export const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (
56955737 // apply must not block the user's turn, and an un-updated snapshot means
56965738 // the next turn retries.
56975739 if ( modelSelection !== undefined ) {
5698- const desiredFlagSettings = deriveClaudeFlagSettings ( modelSelection ) ;
5740+ const desiredFlagSettings = deriveClaudeFlagSettings ( modelSelection , modelCapabilities ) ;
56995741 if ( ! claudeFlagSettingsEqual ( desiredFlagSettings , context . currentFlagSettings ) ) {
57005742 const applyFlagSettings = context . query . applyFlagSettings ?. bind ( context . query ) ;
57015743 if ( applyFlagSettings === undefined ) {
@@ -5952,10 +5994,11 @@ export const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (
59525994 requestError ( `Failed to read the subagent transcript: ${ cause . message } ` ) ,
59535995 ) ,
59545996 ) ;
5955- return mapClaudeSubagentTranscript (
5956- transcript ,
5957- input . limit !== undefined ? { limit : input . limit } : { } ,
5958- ) ;
5997+ return mapClaudeSubagentTranscript ( transcript , {
5998+ ...( input . limit !== undefined ? { limit : input . limit } : { } ) ,
5999+ ...( input . offset !== undefined ? { offset : input . offset } : { } ) ,
6000+ ...( input . fromEnd !== undefined ? { fromEnd : input . fromEnd } : { } ) ,
6001+ } ) ;
59596002 } ) ;
59606003
59616004 const rewindFilesForRollback = Effect . fn ( "rewindFilesForRollback" ) ( function * (
0 commit comments