88 */
99
1010import { Agent } from '@mariozechner/pi-agent-core'
11- import { getModel } from '@mariozechner/pi-ai'
11+ import { getModel , streamSimple } from '@mariozechner/pi-ai'
1212import { createOutboundBridge } from './outbound-bridge'
1313import { MOONSHOT_PROVIDER , getMoonshotModel } from './moonshot-models'
1414import { runtimeLog } from './log'
15+ import {
16+ ModelProviderError ,
17+ toModelProviderError ,
18+ } from './model-provider-error'
1519import type { OutboundIdSeed } from './outbound-bridge'
1620import type { ChangeEvent } from '@durable-streams/state'
1721import type {
@@ -42,8 +46,13 @@ export interface PiAdapterOptions {
4246 provider : string
4347 ) => Promise < string | undefined > | string | undefined
4448 onPayload ?: SimpleStreamOptions [ `onPayload`]
49+ modelTimeoutMs ?: number
50+ modelMaxRetries ?: number
4551}
4652
53+ const DEFAULT_MODEL_TIMEOUT_MS = 30_000
54+ const DEFAULT_MODEL_MAX_RETRIES = 0
55+
4756interface PiAgentAdapterConfig {
4857 entityUrl : string
4958 epoch : number
@@ -227,18 +236,32 @@ export function createPiAgentAdapter(
227236 model : opts . model ,
228237 ...( opts . provider && { provider : opts . provider } ) ,
229238 } )
239+ const modelTimeoutMs = opts . modelTimeoutMs ?? DEFAULT_MODEL_TIMEOUT_MS
240+ const modelMaxRetries = opts . modelMaxRetries ?? DEFAULT_MODEL_MAX_RETRIES
241+
242+ const baseStreamFn = opts . streamFn ?? streamSimple
243+ const streamFn : StreamFn = ( streamModel , context , streamOptions ) =>
244+ baseStreamFn ( streamModel , context , {
245+ ...streamOptions ,
246+ timeoutMs : modelTimeoutMs ,
247+ maxRetries : modelMaxRetries ,
248+ } )
230249
231- const agent = new Agent ( {
250+ const agentOptions = {
232251 initialState : {
233252 systemPrompt : opts . systemPrompt ,
234253 tools : opts . tools as Array < never > ,
235254 messages : history as Array < never > ,
236255 model,
237256 } ,
238- ... ( opts . streamFn && { streamFn : opts . streamFn } ) ,
257+ streamFn,
239258 ...( opts . getApiKey && { getApiKey : opts . getApiKey } ) ,
240259 ...( opts . onPayload && { onPayload : opts . onPayload } ) ,
241- } )
260+ }
261+
262+ const agent = new Agent (
263+ agentOptions as ConstructorParameters < typeof Agent > [ 0 ]
264+ )
242265
243266 function processAgentEvents (
244267 resolveWhenDone : ( ) => void ,
@@ -409,8 +432,11 @@ export function createPiAgentAdapter(
409432 } )
410433
411434 if ( isError ) {
412- throw new Error (
413- `pi-agent message_end error: ${ msg . errorMessage ?? `unknown error` } (stopReason=${ msg . stopReason ?? `none` } )`
435+ throw toModelProviderError (
436+ new Error (
437+ `pi-agent message_end error: ${ msg . errorMessage ?? `unknown error` } (stopReason=${ msg . stopReason ?? `none` } )`
438+ ) ,
439+ { provider : model . provider , model : model . id }
414440 )
415441 }
416442 break
@@ -436,6 +462,20 @@ export function createPiAgentAdapter(
436462 }
437463
438464 case `agent_end` : {
465+ const messages = ( event as Record < string , unknown > ) . messages as
466+ | Array < { stopReason ?: string ; errorMessage ?: string } >
467+ | undefined
468+ const errorMessage = messages ?. find (
469+ ( message ) =>
470+ message . stopReason === `error` && ! ! message . errorMessage
471+ ) ?. errorMessage
472+ if ( errorMessage ) {
473+ throw toModelProviderError (
474+ new Error ( `pi-agent agent_end error: ${ errorMessage } ` ) ,
475+ { provider : model . provider , model : model . id }
476+ )
477+ }
478+
439479 bridge . onRunEnd ( {
440480 finishReason : abortedRun ? `aborted` : `stop` ,
441481 } )
@@ -499,6 +539,17 @@ export function createPiAgentAdapter(
499539 unsubscribe ( )
500540 bridge . onRunEnd ( { finishReason } )
501541 }
542+ const failWithProviderError = ( err : unknown ) : ModelProviderError => {
543+ const providerError = toModelProviderError ( err , {
544+ provider : model . provider ,
545+ model : model . id ,
546+ } )
547+ bridge . onError ( {
548+ errorCode : providerError . code ,
549+ message : providerError . message ,
550+ } )
551+ return providerError
552+ }
502553 const abortRun = ( ) : void => {
503554 if ( settled ) return
504555 abortedRun = true
@@ -524,8 +575,9 @@ export function createPiAgentAdapter(
524575 } ,
525576 ( err ) => {
526577 if ( settled ) return
578+ const providerError = failWithProviderError ( err )
527579 finish ( `error` )
528- reject ( err )
580+ reject ( providerError )
529581 }
530582 )
531583
@@ -539,8 +591,9 @@ export function createPiAgentAdapter(
539591 Promise . resolve ( runPromise ) . catch ( ( err : Error ) => {
540592 if ( settled ) return
541593 if ( abortedRun ) return
594+ const providerError = failWithProviderError ( err )
542595 finish ( `error` )
543- reject ( err )
596+ reject ( providerError )
544597 } )
545598 } )
546599 } ,
0 commit comments