@alvin0/ai-agent-sdk-core 0.1.8 → 0.1.9
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/agent/define/session/config.js +1 -1
- package/dist/agent/define/session/config.js.map +1 -1
- package/dist/agent/define/session/types.d.ts +14 -0
- package/dist/agent/define/session/types.d.ts.map +1 -1
- package/dist/agent/define/session.d.ts.map +1 -1
- package/dist/agent/define/session.js +1 -1
- package/dist/agent/define/session.js.map +1 -1
- package/dist/agent/loop/events.d.ts +24 -1
- package/dist/agent/loop/events.d.ts.map +1 -1
- package/dist/agent/loop/run-turn.js +1 -1
- package/dist/agent/loop/run-turn.js.map +1 -1
- package/dist/agent/loop/schedule.d.ts.map +1 -1
- package/dist/agent/loop/schedule.js +1 -1
- package/dist/agent/loop/schedule.js.map +1 -1
- package/dist/agent/loop/turn/config.js +1 -1
- package/dist/agent/loop/turn/config.js.map +1 -1
- package/dist/agent/loop/turn/model-request-boundary.js +1 -1
- package/dist/agent/loop/turn/model-request-boundary.js.map +1 -1
- package/dist/agent/loop/turn/model-round.js +1 -1
- package/dist/agent/loop/turn/model-round.js.map +1 -1
- package/dist/agent/loop/turn/types.d.ts +35 -2
- package/dist/agent/loop/turn/types.d.ts.map +1 -1
- package/dist/agent/loop/types.d.ts +16 -0
- package/dist/agent/loop/types.d.ts.map +1 -1
- package/dist/agent/mode/run-agent.d.ts +9 -0
- package/dist/agent/mode/run-agent.d.ts.map +1 -1
- package/dist/agent/mode/run-agent.js +2 -2
- package/dist/agent/mode/run-agent.js.map +1 -1
- package/dist/agent/mode/user-input.d.ts.map +1 -1
- package/dist/agent/mode/user-input.js +1 -1
- package/dist/agent/mode/user-input.js.map +1 -1
- package/dist/agent/team/managed.d.ts.map +1 -1
- package/dist/agent/team/managed.js +1 -1
- package/dist/agent/team/managed.js.map +1 -1
- package/dist/agent/tool/capture.js +1 -1
- package/dist/agent/tool/capture.js.map +1 -1
- package/dist/agent/tool/definition.d.ts +7 -0
- package/dist/agent/tool/definition.d.ts.map +1 -1
- package/dist/agent/tool/definition.js.map +1 -1
- package/dist/agent.js +1 -1
- package/dist/composition/agent/public-event.d.ts +19 -0
- package/dist/composition/agent/public-event.d.ts.map +1 -0
- package/dist/composition/agent/public-event.js +2 -0
- package/dist/composition/agent/public-event.js.map +1 -0
- package/dist/composition/agent/session.js +1 -1
- package/dist/composition/agent/session.js.map +1 -1
- package/dist/composition/agent/types.d.ts +11 -1
- package/dist/composition/agent/types.d.ts.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +1 -1
- package/dist/observability/bus.js +1 -1
- package/dist/primitives/version.d.ts +1 -1
- package/dist/primitives/version.js +1 -1
- package/dist/primitives/version.js.map +1 -1
- package/dist/runtime/registry.js +1 -1
- package/dist/runtime/with-retry.d.ts +15 -0
- package/dist/runtime/with-retry.d.ts.map +1 -1
- package/dist/runtime/with-retry.js +1 -1
- package/dist/runtime/with-retry.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{MessageId as e,ProviderRequestId as t,ReasoningEffortId as n,ToolCallId as r}from"./primitives/brand.js";import{deepFreeze as i}from"./primitives/freeze.js";import{isJsonValue as a}from"./primitives/json.js";import{assertNever as o}from"./primitives/never.js";import{detachedFrozen as s}from"./primitives/snapshot.js";import{SDK_VERSION as c}from"./primitives/version.js";import{waitForSettlement as l}from"./async/settlement.js";import{createObservationRunScope as u,createOperationId as d,createSpanId as f,createTraceId as p,freezeCorrelation as m,isSpanId as h,isTraceId as g,traceparent as _}from"./observation/context.js";import{safeErrorRecord as v}from"./observation/event.js";import{NOOP_OBSERVATION_PORT as y,createCoreSpan as b,disabledDeliverySummary as x,snapshotObservationSpan as S,validObservationSpan as C,validateCaptureReceipt as w}from"./observation/port.js";import{AgentSdkError as T,CONTEXT_WINDOW_EXCEEDED_CODE as E,EMPTY_RESPONSE_CODE as D,INVALID_CREDENTIAL_CODE as O,MISSING_CREDENTIAL_CODE as k,QUOTA_EXCEEDED_CODE as A,errorChain as j,isAgentSdkError as M,isContextWindowExceededError as N,isQuotaExceededError as P}from"./errors/agent-sdk-error.js";import{ModelCallObservationError as F,OBSERVATION_ERROR_CODES as I}from"./observation/report.js";import{addUsageCounters as L,classifyUsageCoverage as R,hasUsageCounters as z,possiblyBilledAttemptsWithoutUsage as B,validateUsageCounters as V}from"./observation/usage.js";import{PLUGIN_ERROR_CODES as H,PluginError as U}from"./plugin/provider-plugin.js";import{MODEL_ERROR_CODES as W,ModelError as G,REGISTRY_ERROR_CODES as K}from"./errors/model-error.js";import{normalizeModelFailure as q}from"./errors/failure.js";import{createAssistantMessage as J,createMessage as Y,createTextMessage as X,createToolResultMessage as Z,createUserMessage as Q,freezeMessage as $}from"./message/message.js";import{contentHasDocument as ee,contentHasImage as te,projectDocumentsForTextModel as ne,projectImagesForTextModel as re,textOnlyDocumentText as ie,textOnlyImageText as ae}from"./message/projection.js";import{BlockAssembler as oe}from"./stream/assembler.js";import{withIdleTimeout as se}from"./stream/idle-timeout.js";import{ModelAdapter as ce}from"./contract/adapter.js";import{callConfigEquals as le}from"./contract/call-config.js";import{MAX_TIMER_DELAY_MS as ue,backoffDelayMs as de,isRetryable as fe,resolveRetryPolicy as pe}from"./contract/retry-policy.js";import{isNativeToolSchema as me}from"./contract/tool.js";import{ModelRegistry as he}from"./runtime/registry.js";import{withRetry as ge}from"./runtime/with-retry.js";import{assertUsableApiKey as _e,normalizeApiKey as ve}from"./http/api-key.js";import{APP_IDENTITY as ye,attributionHeaders as be,userAgent as xe}from"./http/attribution.js";import{AgentMemory as Se,resolveMemoryConfig as Ce}from"./agent/memory/memory.js";import{estimateContextTokens as we,estimateMessageTokens as Te}from"./agent/memory/token-estimator.js";import{selectCompactablePrefix as Ee}from"./agent/memory/surface-compaction.js";import{COMPACTION_INSTRUCTION as De,ContextCompactor as Oe}from"./agent/memory/compaction.js";import{resolveCompactionConfig as ke}from"./agent/memory/compaction-config.js";import{defineTool as Ae}from"./agent/tool/definition.js";import{createContextOptimizer as je}from"./agent/memory/context-optimizer.js";import{MEMORY_ERROR_CODES as Me,MEMORY_STORE_API_VERSION as Ne}from"./composition/memory/config.js";import{defineMemoryStore as Pe}from"./composition/memory/definition.js";import{MAX_SKILL_DESCRIPTION_CHARS as Fe,MAX_SKILL_ID_CHARS as Ie,MAX_SKILL_INSTRUCTIONS_CHARS as Le,MAX_SKILL_NAME_CHARS as Re,MAX_SKILL_RESOURCE_CHARS as ze,MAX_SKILL_RESOURCE_PATH_CHARS as Be,SKILL_ID_PATTERN as Ve,defineSkill as He,defineSkillProvider as Ue,validateCandidate as We,validateSkillId as Ge,validateSkillResourcePath as Ke,validateSkillSource as qe}from"./agent/skill/definition.js";import{SKILL_ERROR_CODES as Je,SKILL_PROVIDER_API_VERSION as Ye}from"./agent/skill/provider/config.js";import{defineSkillProviderPlugin as Xe}from"./agent/skill/provider/definition.js";import{SkillCatalog as Ze}from"./agent/skill/catalog.js";import{SKILL_TOOL_NAMES as Qe,createSkillTools as $e,renderSkillCatalog as et,resolveSkillOptions as tt}from"./agent/skill/tools.js";import{OBSERVATION_EXPORTER_API_VERSION as nt}from"./composition/exporter/types.js";import{CONTEXT_SECTION_ID_PATTERN as rt,CONTEXT_SECTION_INVALID as it,MAX_CONTEXT_SECTION_TEXT_BYTES as at,defineContextSection as ot}from"./agent/context/section.js";import{createApprovalBroker as st,createApprovalRequest as ct,fixedApprovalBroker as lt,withApprovalPersistence as ut}from"./agent/tool/approval.js";import{
|
|
1
|
+
import{MessageId as e,ProviderRequestId as t,ReasoningEffortId as n,ToolCallId as r}from"./primitives/brand.js";import{deepFreeze as i}from"./primitives/freeze.js";import{isJsonValue as a}from"./primitives/json.js";import{assertNever as o}from"./primitives/never.js";import{detachedFrozen as s}from"./primitives/snapshot.js";import{SDK_VERSION as c}from"./primitives/version.js";import{waitForSettlement as l}from"./async/settlement.js";import{createObservationRunScope as u,createOperationId as d,createSpanId as f,createTraceId as p,freezeCorrelation as m,isSpanId as h,isTraceId as g,traceparent as _}from"./observation/context.js";import{safeErrorRecord as v}from"./observation/event.js";import{NOOP_OBSERVATION_PORT as y,createCoreSpan as b,disabledDeliverySummary as x,snapshotObservationSpan as S,validObservationSpan as C,validateCaptureReceipt as w}from"./observation/port.js";import{AgentSdkError as T,CONTEXT_WINDOW_EXCEEDED_CODE as E,EMPTY_RESPONSE_CODE as D,INVALID_CREDENTIAL_CODE as O,MISSING_CREDENTIAL_CODE as k,QUOTA_EXCEEDED_CODE as A,errorChain as j,isAgentSdkError as M,isContextWindowExceededError as N,isQuotaExceededError as P}from"./errors/agent-sdk-error.js";import{ModelCallObservationError as F,OBSERVATION_ERROR_CODES as I}from"./observation/report.js";import{addUsageCounters as L,classifyUsageCoverage as R,hasUsageCounters as z,possiblyBilledAttemptsWithoutUsage as B,validateUsageCounters as V}from"./observation/usage.js";import{PLUGIN_ERROR_CODES as H,PluginError as U}from"./plugin/provider-plugin.js";import{MODEL_ERROR_CODES as W,ModelError as G,REGISTRY_ERROR_CODES as K}from"./errors/model-error.js";import{normalizeModelFailure as q}from"./errors/failure.js";import{createAssistantMessage as J,createMessage as Y,createTextMessage as X,createToolResultMessage as Z,createUserMessage as Q,freezeMessage as $}from"./message/message.js";import{contentHasDocument as ee,contentHasImage as te,projectDocumentsForTextModel as ne,projectImagesForTextModel as re,textOnlyDocumentText as ie,textOnlyImageText as ae}from"./message/projection.js";import{BlockAssembler as oe}from"./stream/assembler.js";import{withIdleTimeout as se}from"./stream/idle-timeout.js";import{ModelAdapter as ce}from"./contract/adapter.js";import{callConfigEquals as le}from"./contract/call-config.js";import{MAX_TIMER_DELAY_MS as ue,backoffDelayMs as de,isRetryable as fe,resolveRetryPolicy as pe}from"./contract/retry-policy.js";import{isNativeToolSchema as me}from"./contract/tool.js";import{ModelRegistry as he}from"./runtime/registry.js";import{withRetry as ge}from"./runtime/with-retry.js";import{assertUsableApiKey as _e,normalizeApiKey as ve}from"./http/api-key.js";import{APP_IDENTITY as ye,attributionHeaders as be,userAgent as xe}from"./http/attribution.js";import{AgentMemory as Se,resolveMemoryConfig as Ce}from"./agent/memory/memory.js";import{estimateContextTokens as we,estimateMessageTokens as Te}from"./agent/memory/token-estimator.js";import{selectCompactablePrefix as Ee}from"./agent/memory/surface-compaction.js";import{COMPACTION_INSTRUCTION as De,ContextCompactor as Oe}from"./agent/memory/compaction.js";import{resolveCompactionConfig as ke}from"./agent/memory/compaction-config.js";import{defineTool as Ae}from"./agent/tool/definition.js";import{createContextOptimizer as je}from"./agent/memory/context-optimizer.js";import{MEMORY_ERROR_CODES as Me,MEMORY_STORE_API_VERSION as Ne}from"./composition/memory/config.js";import{defineMemoryStore as Pe}from"./composition/memory/definition.js";import{MAX_SKILL_DESCRIPTION_CHARS as Fe,MAX_SKILL_ID_CHARS as Ie,MAX_SKILL_INSTRUCTIONS_CHARS as Le,MAX_SKILL_NAME_CHARS as Re,MAX_SKILL_RESOURCE_CHARS as ze,MAX_SKILL_RESOURCE_PATH_CHARS as Be,SKILL_ID_PATTERN as Ve,defineSkill as He,defineSkillProvider as Ue,validateCandidate as We,validateSkillId as Ge,validateSkillResourcePath as Ke,validateSkillSource as qe}from"./agent/skill/definition.js";import{SKILL_ERROR_CODES as Je,SKILL_PROVIDER_API_VERSION as Ye}from"./agent/skill/provider/config.js";import{defineSkillProviderPlugin as Xe}from"./agent/skill/provider/definition.js";import{SkillCatalog as Ze}from"./agent/skill/catalog.js";import{SKILL_TOOL_NAMES as Qe,createSkillTools as $e,renderSkillCatalog as et,resolveSkillOptions as tt}from"./agent/skill/tools.js";import{OBSERVATION_EXPORTER_API_VERSION as nt}from"./composition/exporter/types.js";import{CONTEXT_SECTION_ID_PATTERN as rt,CONTEXT_SECTION_INVALID as it,MAX_CONTEXT_SECTION_TEXT_BYTES as at,defineContextSection as ot}from"./agent/context/section.js";import{createApprovalBroker as st,createApprovalRequest as ct,fixedApprovalBroker as lt,withApprovalPersistence as ut}from"./agent/tool/approval.js";import{createUserInputBroker as dt,fixedUserInputBroker as ft}from"./agent/mode/user-input.js";import{createAgentRuntime as pt}from"./composition/runtime/public.js";import{withoutRunReport as mt}from"./composition/agent/public-event.js";import{cloneAgent as ht,defineAgent as gt}from"./composition/agent/author.js";import{defineObservationExporter as _t}from"./composition/exporter/definition.js";import{defineToolFromSchema as vt}from"./agent/tool/schema.js";import{createToolExecutionInterceptor as yt,localToolExecutionBackend as bt}from"./agent/tool/execution.js";export{ye as APP_IDENTITY,Se as AgentMemory,T as AgentSdkError,oe as BlockAssembler,De as COMPACTION_INSTRUCTION,rt as CONTEXT_SECTION_ID_PATTERN,it as CONTEXT_SECTION_INVALID,E as CONTEXT_WINDOW_EXCEEDED_CODE,Oe as ContextCompactor,D as EMPTY_RESPONSE_CODE,O as INVALID_CREDENTIAL_CODE,at as MAX_CONTEXT_SECTION_TEXT_BYTES,Fe as MAX_SKILL_DESCRIPTION_CHARS,Ie as MAX_SKILL_ID_CHARS,Le as MAX_SKILL_INSTRUCTIONS_CHARS,Re as MAX_SKILL_NAME_CHARS,ze as MAX_SKILL_RESOURCE_CHARS,Be as MAX_SKILL_RESOURCE_PATH_CHARS,ue as MAX_TIMER_DELAY_MS,Me as MEMORY_ERROR_CODES,Ne as MEMORY_STORE_API_VERSION,k as MISSING_CREDENTIAL_CODE,W as MODEL_ERROR_CODES,e as MessageId,ce as ModelAdapter,F as ModelCallObservationError,G as ModelError,he as ModelRegistry,y as NOOP_OBSERVATION_PORT,I as OBSERVATION_ERROR_CODES,nt as OBSERVATION_EXPORTER_API_VERSION,H as PLUGIN_ERROR_CODES,U as PluginError,t as ProviderRequestId,A as QUOTA_EXCEEDED_CODE,K as REGISTRY_ERROR_CODES,n as ReasoningEffortId,c as SDK_VERSION,Je as SKILL_ERROR_CODES,Ve as SKILL_ID_PATTERN,Ye as SKILL_PROVIDER_API_VERSION,Qe as SKILL_TOOL_NAMES,Ze as SkillCatalog,r as ToolCallId,L as addUsageCounters,o as assertNever,_e as assertUsableApiKey,be as attributionHeaders,de as backoffDelayMs,le as callConfigEquals,R as classifyUsageCoverage,ht as cloneAgent,ee as contentHasDocument,te as contentHasImage,pt as createAgentRuntime,st as createApprovalBroker,ct as createApprovalRequest,J as createAssistantMessage,je as createContextOptimizer,b as createCoreSpan,Y as createMessage,u as createObservationRunScope,d as createOperationId,$e as createSkillTools,f as createSpanId,X as createTextMessage,yt as createToolExecutionInterceptor,Z as createToolResultMessage,p as createTraceId,dt as createUserInputBroker,Q as createUserMessage,i as deepFreeze,gt as defineAgent,ot as defineContextSection,Pe as defineMemoryStore,_t as defineObservationExporter,He as defineSkill,Ue as defineSkillProvider,Xe as defineSkillProviderPlugin,Ae as defineTool,vt as defineToolFromSchema,s as detachedFrozen,x as disabledDeliverySummary,j as errorChain,we as estimateContextTokens,Te as estimateMessageTokens,lt as fixedApprovalBroker,ft as fixedUserInputBroker,m as freezeCorrelation,$ as freezeMessage,z as hasUsageCounters,M as isAgentSdkError,N as isContextWindowExceededError,a as isJsonValue,me as isNativeToolSchema,P as isQuotaExceededError,fe as isRetryable,h as isSpanId,g as isTraceId,bt as localToolExecutionBackend,ve as normalizeApiKey,q as normalizeModelFailure,B as possiblyBilledAttemptsWithoutUsage,ne as projectDocumentsForTextModel,re as projectImagesForTextModel,et as renderSkillCatalog,ke as resolveCompactionConfig,Ce as resolveMemoryConfig,pe as resolveRetryPolicy,tt as resolveSkillOptions,v as safeErrorRecord,Ee as selectCompactablePrefix,S as snapshotObservationSpan,ie as textOnlyDocumentText,ae as textOnlyImageText,_ as traceparent,xe as userAgent,C as validObservationSpan,We as validateCandidate,w as validateCaptureReceipt,Ge as validateSkillId,Ke as validateSkillResourcePath,qe as validateSkillSource,V as validateUsageCounters,l as waitForSettlement,ut as withApprovalPersistence,se as withIdleTimeout,ge as withRetry,mt as withoutRunReport};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{deepFreeze as e}from"../primitives/freeze.js";import"../primitives/version.js";import{createObservationRunScope as t,createOperationId as n}from"../observation/context.js";import{safeErrorRecord as r}from"../observation/event.js";import{createCoreSpan as i,snapshotObservationSpan as a}from"../observation/port.js";import{sanitizeObservationEvent as o,serializedEventBytes as s}from"../observation/privacy.js";import{createBusLogger as c}from"./logger.js";const l={none:0,"local-durable":1,"remote-acknowledged":2},u=new Set([`ABORT_ERR`,`ECONNREFUSED`,`ECONNRESET`,`EHOSTUNREACH`,`ENETUNREACH`,`ETIMEDOUT`,`OBSERVABILITY_EXPORT_FAILED`,`OBSERVABILITY_FLUSH_TIMEOUT`,`OBSERVABILITY_PROCESSOR_FAILED`,`OTEL_PROVIDER_UNCONFIGURED`]),d=/^[A-Za-z0-9](?:[A-Za-z0-9._-]{0,63})$/,f=new Set([`none`,`metadata`,`redacted`,`full`]),p=new Set([`trace`,`debug`,`info`,`warn`,`error`,`fatal`]);function m(e,t){if(!Number.isSafeInteger(e)||e<1)throw RangeError(`${t} must be a positive safe integer`);return e}function h(t,n){let i=r(t);return e({type:[`AbortError`,`Error`,`RangeError`,`TypeError`].includes(i.type)?i.type:`Error`,message:n,...i.code!==void 0&&u.has(i.code)?{code:i.code}:{},...i.retryable===void 0?{}:{retryable:i.retryable},...i.status===void 0?{}:{status:i.status}})}function g(e,t,n=`none`,r){return Object.freeze({eventId:e,status:t,durable:t===`accepted`&&n!==`none`,boundary:n,...r===void 0?{}:{reason:r}})}function _(e){try{let t=Reflect.get(e,`eventId`);return typeof t==`string`&&t.length>0?t:n()}catch{return n()}}function v(e){let t=`none`;for(let n of e)n.requirement===`required`&&l[n.boundary]>l[t]&&(t=n.boundary);return t}function y(e,t){let n=new Set;for(let r of t){let t=r.exporter?.id;if(typeof t!=`string`||!d.test(t))throw TypeError(`observation exporter id must be a safe 1-64 character identifier`);if(n.has(t))throw TypeError(`duplicate observation exporter id: ${t}`);if(n.add(t),r.requirement!==`required`&&r.requirement!==`best-effort`)throw TypeError(`observation exporter ${t} has an invalid requirement`);if(!(r.boundary in l))throw TypeError(`observation exporter ${t} has an invalid boundary`);let i=r.exporter.supportedBoundaries??[`none`];if(typeof r.exporter.export!=`function`)throw TypeError(`observation exporter ${t} has no export function`);if(!i.includes(r.boundary))throw TypeError(`observation exporter ${t} does not support ${r.boundary}`);if(e===`operational`&&r.requirement===`required`)throw TypeError(`operational observation exporters must be best-effort`)}if(e!==`operational`&&!t.some(e=>e.requirement===`required`&&e.boundary!==`none`))throw TypeError(`${e} observability requires a durable required exporter`);return Object.freeze(t.map(e=>Object.freeze({...e})))}function b(e,t){let n=new AbortController,r=setTimeout(()=>n.abort(new DOMException(`observation deadline exceeded`,`TimeoutError`)),e),i=()=>n.abort(t?.reason??new DOMException(`observation aborted`,`AbortError`));return t?.aborted===!0?i():t?.addEventListener(`abort`,i,{once:!0}),{signal:n.signal,clear(){clearTimeout(r),t?.removeEventListener(`abort`,i)}}}function x(e,t){return t.aborted?Promise.reject(t.reason??Error(`observation aborted`)):new Promise((n,r)=>{let i=()=>{a(),r(t.reason??Error(`observation aborted`))},a=()=>t.removeEventListener(`abort`,i);t.addEventListener(`abort`,i,{once:!0}),e.then(e=>{a(),n(e)},e=>{a(),r(e)})})}function S(e){try{let t=e.reason;return typeof t==`object`&&!!t&&Reflect.get(t,`name`)===`TimeoutError`}catch{return!1}}function C(e){return Object.freeze({complete:e.complete,exportedEvents:e.exportedEvents,pendingEvents:e.pendingEvents,rejectedCritical:e.rejectedCritical,timedOut:e.timedOut})}function w(e,t){return e.eventId===t.eventId&&e.sequence===t.sequence&&e.name===t.name&&e.phase===t.phase&&e.occurredAt===t.occurredAt&&e.monotonicMs===t.monotonicMs&&e.priority===t.priority&&JSON.stringify(e.resource)===JSON.stringify(t.resource)&&JSON.stringify(e.correlation)===JSON.stringify(t.correlation)}var T=class{mode;resource;registrations;processors;options;queue=[];queueBytes=0;closing=!1;closed=!1;shutdownPromise;flushChain=Promise.resolve();protectedFailures=new Set;healthScope=t();healthRunId=n();healthCorrelation=i({name:`sdk.integration.request`,runId:this.healthRunId,startedAt:new Date().toISOString(),monotonicMs:this.healthScope.monotonicMs()}).correlation;counters={accepted:0,exported:0,droppedVerbose:0,droppedNormal:0,criticalRejected:0,processorFailures:0,exporterFailures:0,flushTimeouts:0,requiredFailure:!1};constructor(t){if(this.mode=t.mode??`operational`,![`operational`,`reliable`,`audit`].includes(this.mode))throw TypeError(`invalid observation mode`);this.resource=e({sdkName:`ai-agent-sdk`,sdkVersion:t.resource?.sdkVersion??`0.1.8`,...t.resource?.serviceName===void 0?{}:{serviceName:t.resource.serviceName},...t.resource?.serviceVersion===void 0?{}:{serviceVersion:t.resource.serviceVersion},runtime:t.resource?.runtime??`unknown`}),this.registrations=y(this.mode,t.exporters??[]);let n=new Set;for(let e of t.processors??[]){if(typeof e.id!=`string`||!d.test(e.id))throw TypeError(`processor id must be a safe 1-64 character identifier`);if(n.has(e.id))throw TypeError(`duplicate observation processor id: ${e.id}`);if(typeof e.transform!=`function`)throw TypeError(`observation processor ${e.id} is invalid`);n.add(e.id)}if(this.processors=Object.freeze([...t.processors??[]]),!f.has(t.content??`none`))throw TypeError(`invalid observation content policy`);if(!p.has(t.minimumLogLevel??`info`))throw TypeError(`invalid minimum log level`);let r=new Set;for(let e of t.redactors??[]){if(typeof e.id!=`string`||!d.test(e.id)||typeof e.redact!=`function`)throw TypeError(`invalid observation content redactor`);if(r.has(e.id))throw TypeError(`duplicate observation redactor id: ${e.id}`);r.add(e.id)}this.options={content:t.content??`none`,includeErrorStacks:t.includeErrorStacks??!1,minimumLogLevel:t.minimumLogLevel??`info`,maxQueueEvents:m(t.maxQueueEvents??1e4,`maxQueueEvents`),maxQueueBytes:m(t.maxQueueBytes??16777216,`maxQueueBytes`),maxBatchEvents:m(t.maxBatchEvents??256,`maxBatchEvents`),maxBatchBytes:m(t.maxBatchBytes??524288,`maxBatchBytes`),flushTimeoutMs:m(t.flushTimeoutMs??1e4,`flushTimeoutMs`),shutdownTimeoutMs:m(t.shutdownTimeoutMs??3e4,`shutdownTimeoutMs`),redactors:Object.freeze([...t.redactors??[]]),...t.onHealthChange===void 0?{}:{onHealthChange:t.onHealthChange},...t.openSpan===void 0?{}:{openSpan:t.openSpan}}}openSpan(e){let t=this.options.openSpan;if(t===void 0)return i(e);try{let n=a(t(e));if(n!==void 0)return n;this.counters.processorFailures++,this.recordFailure(`span:invalid`,TypeError(`invalid span`),`observation span backend returned an invalid span`,!1)}catch(e){this.counters.processorFailures++,this.recordFailure(`span:throw`,e,`observation span backend failed`,!1)}return i(e)}capture(e){let t=_(e);if(this.closing||this.closed)return g(t,`rejected`,`none`,`closed`);let n;try{n=this.prepareEvent(e,!1)}catch(e){return this.counters.processorFailures++,this.counters.lastFailure=h(e,`observation processor failed`),this.notifyHealth(),this.recordFailure(`processor:capture`,e,`observation processor failed`,!0),g(t,`rejected`,`none`,`processor-failed`)}let r=this.enqueue(n,!1);return r.status===`accepted`?this.stageExporters(n,r):r}async checkpoint(e,t){let n=this.capture(e);if(n.status!==`accepted`||this.mode===`operational`)return n;let r=this.queue.find(e=>e.event.eventId===n.eventId)?.event;if(r===void 0)return g(n.eventId,`rejected`,`none`,`exporter-unavailable`);let i=new Set(this.queue.filter(e=>e.event.priority===`critical`&&e.event.correlation.runId===r.correlation.runId&&e.event.sequence<=r.sequence).map(e=>e.event.eventId));return(await this.scheduleFlush(i,this.options.flushTimeoutMs,t)).requiredComplete?g(n.eventId,`accepted`,v(this.registrations)):g(n.eventId,`rejected`,`none`,`exporter-unavailable`)}logger(e){return c({minimumLevel:this.options.minimumLogLevel,resource:this.resource,emit:e=>{this.capture(e)}},e)}health(){let t=this.closed?`closed`:this.counters.requiredFailure||this.counters.criticalRejected>0||this.counters.flushTimeouts>0?`failed`:this.counters.processorFailures>0||this.counters.exporterFailures>0||this.counters.droppedVerbose>0||this.counters.droppedNormal>0?`degraded`:`healthy`;return e({state:t,queuedEvents:this.queue.length,queuedBytes:this.queueBytes,accepted:this.counters.accepted,exported:this.counters.exported,droppedVerbose:this.counters.droppedVerbose,droppedNormal:this.counters.droppedNormal,criticalRejected:this.counters.criticalRejected,processorFailures:this.counters.processorFailures,exporterFailures:this.counters.exporterFailures,flushTimeouts:this.counters.flushTimeouts,...this.counters.lastExportAt===void 0?{}:{lastExportAt:this.counters.lastExportAt},...this.counters.lastFailure===void 0?{}:{lastFailure:this.counters.lastFailure}})}flush(e){if(this.closed||this.closing)throw TypeError(`observability is closed`);return this.scheduleFlush(new Set(this.queue.map(e=>e.event.eventId)),this.options.flushTimeoutMs,e).then(C)}shutdown(e){if(this.shutdownPromise!==void 0)return this.shutdownPromise;this.closing=!0;let t=new Set(this.queue.map(e=>e.event.eventId));return this.shutdownPromise=(async()=>{let n=b(this.options.shutdownTimeoutMs,e),r;try{r=C(await this.scheduleFlush(t,this.options.shutdownTimeoutMs,n.signal));for(let e of[...this.registrations].reverse()){let t=e.exporter.shutdown;if(t!==void 0)try{await x(Promise.resolve(t.call(e.exporter,n.signal)),n.signal)}catch(t){this.recordExporterFailure(e,t,!1),r=Object.freeze({...r,complete:!1})}}}finally{n.clear(),this.closed=!0,this.notifyHealth()}return r})(),this.shutdownPromise}prepareEvent(e,t){let n={content:this.options.content,redactors:this.options.redactors??[],includeErrorStacks:this.options.includeErrorStacks},r=o(e,n);if(t)return r;for(let e of this.processors){let t=e.transform(r);if(t===void 0)throw TypeError(`observation processor ${e.id} returned undefined`);let i=o(t,n);if(!w(r,i))throw TypeError(`observation processor ${e.id} changed the immutable event envelope`);r=i}return r}enqueue(e,t){let n=s(e);return n>this.options.maxBatchBytes||n>this.options.maxQueueBytes||!this.makeCapacity(n,t)?(!t&&e.priority===`critical`&&this.counters.criticalRejected++,t||(this.counters.lastFailure=h(RangeError(`capacity`),`observation queue capacity exhausted`),this.notifyHealth()),g(e.eventId,`rejected`,`none`,`capacity`)):(this.queue.push({event:e,bytes:n,protected:t,pending:new Set(this.registrations.map(e=>e.exporter.id))}),this.queueBytes+=n,this.counters.accepted++,this.notifyHealth(),g(e.eventId,`accepted`))}stageExporters(e,t){let n=this.queue.find(t=>t.event.eventId===e.eventId);if(n===void 0)return g(e.eventId,`rejected`,`none`,`exporter-unavailable`);let r=!1;for(let t of this.registrations){let i=t.exporter.stage;if(i!==void 0)try{let n=i.call(t.exporter,e);n!==void 0&&Promise.resolve(n).catch(()=>void 0)}catch(i){if(this.recordExporterFailure(t,i,!1),n.pending.delete(t.exporter.id),r=!0,t.requirement===`required`)return this.removeEntry(n,!1),e.priority===`critical`&&this.counters.criticalRejected++,this.notifyHealth(),g(e.eventId,`rejected`,`none`,`exporter-unavailable`)}}return r&&n.pending.size===0&&this.removeEntry(n,!1),t}makeCapacity(e,t){for(;this.queue.length+1>this.options.maxQueueEvents||this.queueBytes+e>this.options.maxQueueBytes;){let e=this.queue.findIndex(e=>e.event.priority===`verbose`);if(e===-1&&(e=this.queue.findIndex(e=>e.event.priority===`normal`)),e===-1)return!1;let[n]=this.queue.splice(e,1);if(n===void 0)return!1;this.queueBytes-=n.bytes,t||(n.event.priority===`verbose`?this.counters.droppedVerbose++:this.counters.droppedNormal++)}return!0}scheduleFlush(e,t,n){let r,i,a=new Promise((e,t)=>{r=e,i=t}),o=async()=>{try{r(await this.flushInternal(e,t,n))}catch(e){i(e)}};return this.flushChain=this.flushChain.then(o,o),a}async flushInternal(t,r,i){let a=this.counters.exported,o=b(r,i),s=!1,c=!1;try{if(this.registrations.length===0)for(let e of[...this.queue])t.has(e.event.eventId)&&this.removeEntry(e,!1);for(let r of this.registrations)for(;;){let i=this.queue.filter(e=>t.has(e.event.eventId)&&e.pending.has(r.exporter.id));if(i.length===0)break;let a=[],l=0;for(let e of i){if(a.length>=this.options.maxBatchEvents||l+e.bytes>this.options.maxBatchBytes)break;a.push(e),l+=e.bytes}if(a.length===0)break;let u=e({schemaVersion:1,batchId:n(),createdAt:new Date().toISOString(),events:a.map(e=>e.event)}),d;try{if(d=await x(Promise.resolve(r.exporter.export(u,o.signal)),o.signal),d.batchId!==u.batchId||d.accepted!==!0)throw TypeError(`observation exporter ${r.exporter.id} returned an invalid acknowledgment`)}catch(e){if(s=!0,c||=S(o.signal),this.recordExporterFailure(r,e,!0),r.requirement===`best-effort`)for(let e of a)e.pending.delete(r.exporter.id),e.pending.size===0&&this.removeEntry(e,!1);break}this.counters.lastExportAt=new Date().toISOString();for(let e of a)e.pending.delete(r.exporter.id),e.pending.size===0&&this.removeEntry(e,!0);this.notifyHealth()}}finally{S(o.signal)&&(c=!0,this.counters.flushTimeouts++,this.counters.lastFailure=h(o.signal.reason,`observation flush timed out`),this.notifyHealth()),o.clear()}let l=this.queue.filter(e=>t.has(e.event.eventId)),u=this.registrations.filter(e=>e.requirement===`required`).map(e=>e.exporter.id),d=l.every(e=>u.every(t=>!e.pending.has(t)));return Object.freeze({complete:!s&&!c&&l.length===0,requiredComplete:d,exportedEvents:this.counters.exported-a,pendingEvents:l.length,rejectedCritical:this.counters.criticalRejected,timedOut:c})}removeEntry(e,t){let n=this.queue.indexOf(e);n!==-1&&(this.queue.splice(n,1),this.queueBytes-=e.bytes,t&&this.counters.exported++)}recordExporterFailure(e,t,n){this.counters.exporterFailures++,e.requirement===`required`&&(this.counters.requiredFailure=!0),this.counters.lastFailure=h(t,`observation exporter failed`),this.notifyHealth(),n&&this.recordFailure(`exporter:${e.exporter.id}`,t,`observation exporter failed`,!0)}recordFailure(e,t,r,i){if(this.counters.lastFailure=h(t,r),this.notifyHealth(),!(!i||this.protectedFailures.has(e)||this.closing||this.closed)){this.protectedFailures.add(e);try{let t=this.prepareEvent({schemaVersion:1,eventId:n(),sequence:this.healthScope.nextSequence(),name:`sdk.observer.failure`,phase:`point`,occurredAt:new Date().toISOString(),monotonicMs:this.healthScope.monotonicMs(),priority:`critical`,resource:this.resource,correlation:this.healthCorrelation,data:{observerId:e,failureKind:`contained`,count:1,error:{...this.counters.lastFailure}}},!0);this.enqueue(t,!0)}catch{}}}notifyHealth(){let e=this.options.onHealthChange;if(e!==void 0)try{e(this.health())}catch{}}};function E(e={}){return new T(e)}export{E as createObservability};
|
|
1
|
+
import{deepFreeze as e}from"../primitives/freeze.js";import"../primitives/version.js";import{createObservationRunScope as t,createOperationId as n}from"../observation/context.js";import{safeErrorRecord as r}from"../observation/event.js";import{createCoreSpan as i,snapshotObservationSpan as a}from"../observation/port.js";import{sanitizeObservationEvent as o,serializedEventBytes as s}from"../observation/privacy.js";import{createBusLogger as c}from"./logger.js";const l={none:0,"local-durable":1,"remote-acknowledged":2},u=new Set([`ABORT_ERR`,`ECONNREFUSED`,`ECONNRESET`,`EHOSTUNREACH`,`ENETUNREACH`,`ETIMEDOUT`,`OBSERVABILITY_EXPORT_FAILED`,`OBSERVABILITY_FLUSH_TIMEOUT`,`OBSERVABILITY_PROCESSOR_FAILED`,`OTEL_PROVIDER_UNCONFIGURED`]),d=/^[A-Za-z0-9](?:[A-Za-z0-9._-]{0,63})$/,f=new Set([`none`,`metadata`,`redacted`,`full`]),p=new Set([`trace`,`debug`,`info`,`warn`,`error`,`fatal`]);function m(e,t){if(!Number.isSafeInteger(e)||e<1)throw RangeError(`${t} must be a positive safe integer`);return e}function h(t,n){let i=r(t);return e({type:[`AbortError`,`Error`,`RangeError`,`TypeError`].includes(i.type)?i.type:`Error`,message:n,...i.code!==void 0&&u.has(i.code)?{code:i.code}:{},...i.retryable===void 0?{}:{retryable:i.retryable},...i.status===void 0?{}:{status:i.status}})}function g(e,t,n=`none`,r){return Object.freeze({eventId:e,status:t,durable:t===`accepted`&&n!==`none`,boundary:n,...r===void 0?{}:{reason:r}})}function _(e){try{let t=Reflect.get(e,`eventId`);return typeof t==`string`&&t.length>0?t:n()}catch{return n()}}function v(e){let t=`none`;for(let n of e)n.requirement===`required`&&l[n.boundary]>l[t]&&(t=n.boundary);return t}function y(e,t){let n=new Set;for(let r of t){let t=r.exporter?.id;if(typeof t!=`string`||!d.test(t))throw TypeError(`observation exporter id must be a safe 1-64 character identifier`);if(n.has(t))throw TypeError(`duplicate observation exporter id: ${t}`);if(n.add(t),r.requirement!==`required`&&r.requirement!==`best-effort`)throw TypeError(`observation exporter ${t} has an invalid requirement`);if(!(r.boundary in l))throw TypeError(`observation exporter ${t} has an invalid boundary`);let i=r.exporter.supportedBoundaries??[`none`];if(typeof r.exporter.export!=`function`)throw TypeError(`observation exporter ${t} has no export function`);if(!i.includes(r.boundary))throw TypeError(`observation exporter ${t} does not support ${r.boundary}`);if(e===`operational`&&r.requirement===`required`)throw TypeError(`operational observation exporters must be best-effort`)}if(e!==`operational`&&!t.some(e=>e.requirement===`required`&&e.boundary!==`none`))throw TypeError(`${e} observability requires a durable required exporter`);return Object.freeze(t.map(e=>Object.freeze({...e})))}function b(e,t){let n=new AbortController,r=setTimeout(()=>n.abort(new DOMException(`observation deadline exceeded`,`TimeoutError`)),e),i=()=>n.abort(t?.reason??new DOMException(`observation aborted`,`AbortError`));return t?.aborted===!0?i():t?.addEventListener(`abort`,i,{once:!0}),{signal:n.signal,clear(){clearTimeout(r),t?.removeEventListener(`abort`,i)}}}function x(e,t){return t.aborted?Promise.reject(t.reason??Error(`observation aborted`)):new Promise((n,r)=>{let i=()=>{a(),r(t.reason??Error(`observation aborted`))},a=()=>t.removeEventListener(`abort`,i);t.addEventListener(`abort`,i,{once:!0}),e.then(e=>{a(),n(e)},e=>{a(),r(e)})})}function S(e){try{let t=e.reason;return typeof t==`object`&&!!t&&Reflect.get(t,`name`)===`TimeoutError`}catch{return!1}}function C(e){return Object.freeze({complete:e.complete,exportedEvents:e.exportedEvents,pendingEvents:e.pendingEvents,rejectedCritical:e.rejectedCritical,timedOut:e.timedOut})}function w(e,t){return e.eventId===t.eventId&&e.sequence===t.sequence&&e.name===t.name&&e.phase===t.phase&&e.occurredAt===t.occurredAt&&e.monotonicMs===t.monotonicMs&&e.priority===t.priority&&JSON.stringify(e.resource)===JSON.stringify(t.resource)&&JSON.stringify(e.correlation)===JSON.stringify(t.correlation)}var T=class{mode;resource;registrations;processors;options;queue=[];queueBytes=0;closing=!1;closed=!1;shutdownPromise;flushChain=Promise.resolve();protectedFailures=new Set;healthScope=t();healthRunId=n();healthCorrelation=i({name:`sdk.integration.request`,runId:this.healthRunId,startedAt:new Date().toISOString(),monotonicMs:this.healthScope.monotonicMs()}).correlation;counters={accepted:0,exported:0,droppedVerbose:0,droppedNormal:0,criticalRejected:0,processorFailures:0,exporterFailures:0,flushTimeouts:0,requiredFailure:!1};constructor(t){if(this.mode=t.mode??`operational`,![`operational`,`reliable`,`audit`].includes(this.mode))throw TypeError(`invalid observation mode`);this.resource=e({sdkName:`ai-agent-sdk`,sdkVersion:t.resource?.sdkVersion??`0.1.9`,...t.resource?.serviceName===void 0?{}:{serviceName:t.resource.serviceName},...t.resource?.serviceVersion===void 0?{}:{serviceVersion:t.resource.serviceVersion},runtime:t.resource?.runtime??`unknown`}),this.registrations=y(this.mode,t.exporters??[]);let n=new Set;for(let e of t.processors??[]){if(typeof e.id!=`string`||!d.test(e.id))throw TypeError(`processor id must be a safe 1-64 character identifier`);if(n.has(e.id))throw TypeError(`duplicate observation processor id: ${e.id}`);if(typeof e.transform!=`function`)throw TypeError(`observation processor ${e.id} is invalid`);n.add(e.id)}if(this.processors=Object.freeze([...t.processors??[]]),!f.has(t.content??`none`))throw TypeError(`invalid observation content policy`);if(!p.has(t.minimumLogLevel??`info`))throw TypeError(`invalid minimum log level`);let r=new Set;for(let e of t.redactors??[]){if(typeof e.id!=`string`||!d.test(e.id)||typeof e.redact!=`function`)throw TypeError(`invalid observation content redactor`);if(r.has(e.id))throw TypeError(`duplicate observation redactor id: ${e.id}`);r.add(e.id)}this.options={content:t.content??`none`,includeErrorStacks:t.includeErrorStacks??!1,minimumLogLevel:t.minimumLogLevel??`info`,maxQueueEvents:m(t.maxQueueEvents??1e4,`maxQueueEvents`),maxQueueBytes:m(t.maxQueueBytes??16777216,`maxQueueBytes`),maxBatchEvents:m(t.maxBatchEvents??256,`maxBatchEvents`),maxBatchBytes:m(t.maxBatchBytes??524288,`maxBatchBytes`),flushTimeoutMs:m(t.flushTimeoutMs??1e4,`flushTimeoutMs`),shutdownTimeoutMs:m(t.shutdownTimeoutMs??3e4,`shutdownTimeoutMs`),redactors:Object.freeze([...t.redactors??[]]),...t.onHealthChange===void 0?{}:{onHealthChange:t.onHealthChange},...t.openSpan===void 0?{}:{openSpan:t.openSpan}}}openSpan(e){let t=this.options.openSpan;if(t===void 0)return i(e);try{let n=a(t(e));if(n!==void 0)return n;this.counters.processorFailures++,this.recordFailure(`span:invalid`,TypeError(`invalid span`),`observation span backend returned an invalid span`,!1)}catch(e){this.counters.processorFailures++,this.recordFailure(`span:throw`,e,`observation span backend failed`,!1)}return i(e)}capture(e){let t=_(e);if(this.closing||this.closed)return g(t,`rejected`,`none`,`closed`);let n;try{n=this.prepareEvent(e,!1)}catch(e){return this.counters.processorFailures++,this.counters.lastFailure=h(e,`observation processor failed`),this.notifyHealth(),this.recordFailure(`processor:capture`,e,`observation processor failed`,!0),g(t,`rejected`,`none`,`processor-failed`)}let r=this.enqueue(n,!1);return r.status===`accepted`?this.stageExporters(n,r):r}async checkpoint(e,t){let n=this.capture(e);if(n.status!==`accepted`||this.mode===`operational`)return n;let r=this.queue.find(e=>e.event.eventId===n.eventId)?.event;if(r===void 0)return g(n.eventId,`rejected`,`none`,`exporter-unavailable`);let i=new Set(this.queue.filter(e=>e.event.priority===`critical`&&e.event.correlation.runId===r.correlation.runId&&e.event.sequence<=r.sequence).map(e=>e.event.eventId));return(await this.scheduleFlush(i,this.options.flushTimeoutMs,t)).requiredComplete?g(n.eventId,`accepted`,v(this.registrations)):g(n.eventId,`rejected`,`none`,`exporter-unavailable`)}logger(e){return c({minimumLevel:this.options.minimumLogLevel,resource:this.resource,emit:e=>{this.capture(e)}},e)}health(){let t=this.closed?`closed`:this.counters.requiredFailure||this.counters.criticalRejected>0||this.counters.flushTimeouts>0?`failed`:this.counters.processorFailures>0||this.counters.exporterFailures>0||this.counters.droppedVerbose>0||this.counters.droppedNormal>0?`degraded`:`healthy`;return e({state:t,queuedEvents:this.queue.length,queuedBytes:this.queueBytes,accepted:this.counters.accepted,exported:this.counters.exported,droppedVerbose:this.counters.droppedVerbose,droppedNormal:this.counters.droppedNormal,criticalRejected:this.counters.criticalRejected,processorFailures:this.counters.processorFailures,exporterFailures:this.counters.exporterFailures,flushTimeouts:this.counters.flushTimeouts,...this.counters.lastExportAt===void 0?{}:{lastExportAt:this.counters.lastExportAt},...this.counters.lastFailure===void 0?{}:{lastFailure:this.counters.lastFailure}})}flush(e){if(this.closed||this.closing)throw TypeError(`observability is closed`);return this.scheduleFlush(new Set(this.queue.map(e=>e.event.eventId)),this.options.flushTimeoutMs,e).then(C)}shutdown(e){if(this.shutdownPromise!==void 0)return this.shutdownPromise;this.closing=!0;let t=new Set(this.queue.map(e=>e.event.eventId));return this.shutdownPromise=(async()=>{let n=b(this.options.shutdownTimeoutMs,e),r;try{r=C(await this.scheduleFlush(t,this.options.shutdownTimeoutMs,n.signal));for(let e of[...this.registrations].reverse()){let t=e.exporter.shutdown;if(t!==void 0)try{await x(Promise.resolve(t.call(e.exporter,n.signal)),n.signal)}catch(t){this.recordExporterFailure(e,t,!1),r=Object.freeze({...r,complete:!1})}}}finally{n.clear(),this.closed=!0,this.notifyHealth()}return r})(),this.shutdownPromise}prepareEvent(e,t){let n={content:this.options.content,redactors:this.options.redactors??[],includeErrorStacks:this.options.includeErrorStacks},r=o(e,n);if(t)return r;for(let e of this.processors){let t=e.transform(r);if(t===void 0)throw TypeError(`observation processor ${e.id} returned undefined`);let i=o(t,n);if(!w(r,i))throw TypeError(`observation processor ${e.id} changed the immutable event envelope`);r=i}return r}enqueue(e,t){let n=s(e);return n>this.options.maxBatchBytes||n>this.options.maxQueueBytes||!this.makeCapacity(n,t)?(!t&&e.priority===`critical`&&this.counters.criticalRejected++,t||(this.counters.lastFailure=h(RangeError(`capacity`),`observation queue capacity exhausted`),this.notifyHealth()),g(e.eventId,`rejected`,`none`,`capacity`)):(this.queue.push({event:e,bytes:n,protected:t,pending:new Set(this.registrations.map(e=>e.exporter.id))}),this.queueBytes+=n,this.counters.accepted++,this.notifyHealth(),g(e.eventId,`accepted`))}stageExporters(e,t){let n=this.queue.find(t=>t.event.eventId===e.eventId);if(n===void 0)return g(e.eventId,`rejected`,`none`,`exporter-unavailable`);let r=!1;for(let t of this.registrations){let i=t.exporter.stage;if(i!==void 0)try{let n=i.call(t.exporter,e);n!==void 0&&Promise.resolve(n).catch(()=>void 0)}catch(i){if(this.recordExporterFailure(t,i,!1),n.pending.delete(t.exporter.id),r=!0,t.requirement===`required`)return this.removeEntry(n,!1),e.priority===`critical`&&this.counters.criticalRejected++,this.notifyHealth(),g(e.eventId,`rejected`,`none`,`exporter-unavailable`)}}return r&&n.pending.size===0&&this.removeEntry(n,!1),t}makeCapacity(e,t){for(;this.queue.length+1>this.options.maxQueueEvents||this.queueBytes+e>this.options.maxQueueBytes;){let e=this.queue.findIndex(e=>e.event.priority===`verbose`);if(e===-1&&(e=this.queue.findIndex(e=>e.event.priority===`normal`)),e===-1)return!1;let[n]=this.queue.splice(e,1);if(n===void 0)return!1;this.queueBytes-=n.bytes,t||(n.event.priority===`verbose`?this.counters.droppedVerbose++:this.counters.droppedNormal++)}return!0}scheduleFlush(e,t,n){let r,i,a=new Promise((e,t)=>{r=e,i=t}),o=async()=>{try{r(await this.flushInternal(e,t,n))}catch(e){i(e)}};return this.flushChain=this.flushChain.then(o,o),a}async flushInternal(t,r,i){let a=this.counters.exported,o=b(r,i),s=!1,c=!1;try{if(this.registrations.length===0)for(let e of[...this.queue])t.has(e.event.eventId)&&this.removeEntry(e,!1);for(let r of this.registrations)for(;;){let i=this.queue.filter(e=>t.has(e.event.eventId)&&e.pending.has(r.exporter.id));if(i.length===0)break;let a=[],l=0;for(let e of i){if(a.length>=this.options.maxBatchEvents||l+e.bytes>this.options.maxBatchBytes)break;a.push(e),l+=e.bytes}if(a.length===0)break;let u=e({schemaVersion:1,batchId:n(),createdAt:new Date().toISOString(),events:a.map(e=>e.event)}),d;try{if(d=await x(Promise.resolve(r.exporter.export(u,o.signal)),o.signal),d.batchId!==u.batchId||d.accepted!==!0)throw TypeError(`observation exporter ${r.exporter.id} returned an invalid acknowledgment`)}catch(e){if(s=!0,c||=S(o.signal),this.recordExporterFailure(r,e,!0),r.requirement===`best-effort`)for(let e of a)e.pending.delete(r.exporter.id),e.pending.size===0&&this.removeEntry(e,!1);break}this.counters.lastExportAt=new Date().toISOString();for(let e of a)e.pending.delete(r.exporter.id),e.pending.size===0&&this.removeEntry(e,!0);this.notifyHealth()}}finally{S(o.signal)&&(c=!0,this.counters.flushTimeouts++,this.counters.lastFailure=h(o.signal.reason,`observation flush timed out`),this.notifyHealth()),o.clear()}let l=this.queue.filter(e=>t.has(e.event.eventId)),u=this.registrations.filter(e=>e.requirement===`required`).map(e=>e.exporter.id),d=l.every(e=>u.every(t=>!e.pending.has(t)));return Object.freeze({complete:!s&&!c&&l.length===0,requiredComplete:d,exportedEvents:this.counters.exported-a,pendingEvents:l.length,rejectedCritical:this.counters.criticalRejected,timedOut:c})}removeEntry(e,t){let n=this.queue.indexOf(e);n!==-1&&(this.queue.splice(n,1),this.queueBytes-=e.bytes,t&&this.counters.exported++)}recordExporterFailure(e,t,n){this.counters.exporterFailures++,e.requirement===`required`&&(this.counters.requiredFailure=!0),this.counters.lastFailure=h(t,`observation exporter failed`),this.notifyHealth(),n&&this.recordFailure(`exporter:${e.exporter.id}`,t,`observation exporter failed`,!0)}recordFailure(e,t,r,i){if(this.counters.lastFailure=h(t,r),this.notifyHealth(),!(!i||this.protectedFailures.has(e)||this.closing||this.closed)){this.protectedFailures.add(e);try{let t=this.prepareEvent({schemaVersion:1,eventId:n(),sequence:this.healthScope.nextSequence(),name:`sdk.observer.failure`,phase:`point`,occurredAt:new Date().toISOString(),monotonicMs:this.healthScope.monotonicMs(),priority:`critical`,resource:this.resource,correlation:this.healthCorrelation,data:{observerId:e,failureKind:`contained`,count:1,error:{...this.counters.lastFailure}}},!0);this.enqueue(t,!0)}catch{}}}notifyHealth(){let e=this.options.onHealthChange;if(e!==void 0)try{e(this.health())}catch{}}};function E(e={}){return new T(e)}export{E as createObservability};
|
|
2
2
|
//# sourceMappingURL=bus.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
//#region src/primitives/version.d.ts
|
|
2
2
|
/** Package version injected as a Web-standard literal; release tooling updates this file. */
|
|
3
|
-
declare const SDK_VERSION = "0.1.
|
|
3
|
+
declare const SDK_VERSION = "0.1.9";
|
|
4
4
|
//#endregion
|
|
5
5
|
export { SDK_VERSION };
|
|
6
6
|
//# sourceMappingURL=version.d.ts.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=`0.1.
|
|
1
|
+
const e=`0.1.9`;export{e as SDK_VERSION};
|
|
2
2
|
//# sourceMappingURL=version.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.js","names":[],"sources":["../../src/primitives/version.ts"],"sourcesContent":["/** Package version injected as a Web-standard literal; release tooling updates this file. */\nexport const SDK_VERSION = '0.1.
|
|
1
|
+
{"version":3,"file":"version.js","names":[],"sources":["../../src/primitives/version.ts"],"sourcesContent":["/** Package version injected as a Web-standard literal; release tooling updates this file. */\nexport const SDK_VERSION = '0.1.9'\n"],"mappings":"AACA,MAAa,EAAc"}
|
package/dist/runtime/registry.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{deepFreeze as e}from"../primitives/freeze.js";import"../primitives/version.js";import{PLUGIN_ERROR_CODES as t,PluginError as n}from"../plugin/provider-plugin.js";import{ModelError as r,REGISTRY_ERROR_CODES as i}from"../errors/model-error.js";import{callConfigEquals as a}from"../contract/call-config.js";import{resolveRetryPolicy as o}from"../contract/retry-policy.js";import{createModelCallHandle as s}from"./model-call-handle.js";import{normalizeResolvedModelInfo as c,resolveCallWithModelInfo as l,validateCatalogModels as u,validateModelCatalogSnapshot as d}from"./model-metadata.js";import{streamAdapter as f}from"./model-stream.js";function p(e){if((typeof e!=`object`||!e)&&typeof e!=`function`)return!1;let t;try{t=Reflect.get(e,`then`)}catch{return!0}if(typeof t!=`function`)return!1;try{Promise.resolve(e).catch(()=>{})}catch{}return!0}function m(e){try{return p(e())?TypeError(`plugin cleanup must be synchronous`):void 0}catch(e){return e}}var h=class{adapters=new Map;middleware=[];listeners=new Set;plugins=new Map;maxCatalogModels;maxCatalogBytes;observation;observationResource;defaults;constructor(t={}){this.maxCatalogModels=g(t.maxCatalogModels??2048,`maxCatalogModels`),this.maxCatalogBytes=g(t.maxCatalogBytes??4194304,`maxCatalogBytes`),this.observation=t.observation,this.defaults=_(t.defaults??{}),this.observationResource=e(t.observationResource??{sdkName:`ai-agent-sdk`,sdkVersion:`0.1.
|
|
1
|
+
import{deepFreeze as e}from"../primitives/freeze.js";import"../primitives/version.js";import{PLUGIN_ERROR_CODES as t,PluginError as n}from"../plugin/provider-plugin.js";import{ModelError as r,REGISTRY_ERROR_CODES as i}from"../errors/model-error.js";import{callConfigEquals as a}from"../contract/call-config.js";import{resolveRetryPolicy as o}from"../contract/retry-policy.js";import{createModelCallHandle as s}from"./model-call-handle.js";import{normalizeResolvedModelInfo as c,resolveCallWithModelInfo as l,validateCatalogModels as u,validateModelCatalogSnapshot as d}from"./model-metadata.js";import{streamAdapter as f}from"./model-stream.js";function p(e){if((typeof e!=`object`||!e)&&typeof e!=`function`)return!1;let t;try{t=Reflect.get(e,`then`)}catch{return!0}if(typeof t!=`function`)return!1;try{Promise.resolve(e).catch(()=>{})}catch{}return!0}function m(e){try{return p(e())?TypeError(`plugin cleanup must be synchronous`):void 0}catch(e){return e}}var h=class{adapters=new Map;middleware=[];listeners=new Set;plugins=new Map;maxCatalogModels;maxCatalogBytes;observation;observationResource;defaults;constructor(t={}){this.maxCatalogModels=g(t.maxCatalogModels??2048,`maxCatalogModels`),this.maxCatalogBytes=g(t.maxCatalogBytes??4194304,`maxCatalogBytes`),this.observation=t.observation,this.defaults=_(t.defaults??{}),this.observationResource=e(t.observationResource??{sdkName:`ai-agent-sdk`,sdkVersion:`0.1.9`,runtime:`unknown`})}install(e){let a=typeof e?.id==`string`?e.id:``,o=(e,r,i=[])=>{let o=[...r===void 0?[]:[r],...i],s=o.length<=1?o[0]:AggregateError(o,`plugin ${a} install cleanup failed`);throw new n(e,t.INSTALL_FAILED,a,s===void 0?void 0:{cause:s})};(a.trim().length===0||a!==a.trim())&&o(`plugin id must be a non-empty trimmed string`),this.plugins.has(a)&&o(`plugin "${a}" is already installed`),(typeof e.displayName!=`string`||e.displayName.trim().length===0)&&o(`plugin "${a}" displayName must be non-empty`),typeof e.setup!=`function`&&o(`plugin "${a}" setup must be a function`);let s=e.family??a;(typeof s!=`string`||s.trim().length===0||s!==s.trim())&&o(`plugin "${a}" family must be a non-empty trimmed string`);let c=Object.freeze({pluginId:a,family:s}),l=[],u=[],d=!0,f={registerAdapter:(e,t)=>{if(d||o(`plugin "${a}" staging registrar is closed`),e.length===0)throw new r(`an adapter must register at least one provider route`,i.INVALID_ADAPTER);let n={active:!0,routes:[...e],adapter:t},s=new Set(l.filter(e=>e.active).flatMap(e=>e.routes));for(let t of e)if(s.has(t))throw new r(`an adapter for provider route "${t}" is already staged`,i.DUPLICATE_ADAPTER);this.prepareRoutes(e,t,new Set,c),l.push(n);let u=(()=>{d&&(n.active=!1)});return u.replace=e=>{if(!d||!n.active)throw new r(`a disposed staged registration cannot replace routes`,i.REGISTRATION_DISPOSED);let a=new Set(l.filter(e=>e.active&&e!==n).flatMap(e=>e.routes));for(let t of e)if(a.has(t))throw new r(`an adapter for provider route "${t}" is already staged`,i.DUPLICATE_ADAPTER);this.prepareRoutes(e,t,new Set,c),n.routes=[...e]},u},use:e=>{if(d||o(`plugin "${a}" staging registrar is closed`),typeof e!=`function`)throw TypeError(`plugin middleware must be a function`);let t={active:!0,middleware:e};return u.push(t),()=>{d&&(t.active=!1)}}},h;try{let t=e.setup(f);p(t)&&o(`plugin "${a}" setup must be synchronous`),t!==void 0&&typeof t!=`function`&&o(`plugin "${a}" setup must be synchronous and return void or cleanup`),h=typeof t==`function`?t:void 0}catch(e){if(e instanceof n&&e.code===t.INSTALL_FAILED)throw e;o(`plugin "${a}" setup failed`,e)}finally{d=!1}let g=[],_=new Set;try{for(let e of l)if(e.active){for(let t of e.routes){if(_.has(t))throw new r(`an adapter for provider route "${t}" is already staged`,i.DUPLICATE_ADAPTER);_.add(t)}g.push(...this.prepareRoutes(e.routes,e.adapter,new Set,c))}}catch(e){let t=[];if(h){let e=m(h);e!==void 0&&t.push(e)}o(`plugin "${a}" commit validation failed`,e,t)}let v=u.filter(e=>e.active).map(e=>e.middleware);for(let e of g)this.adapters.set(e.provider.id,e);this.middleware.push(...v);let y={routes:_,registrations:g,middleware:v,...h===void 0?{}:{cleanup:h}};this.plugins.set(a,y),this.emitAdaptersUpdated();let b=!1,x=(()=>{if(b)return;b=!0,this.plugins.delete(a);for(let e of y.registrations)this.adapters.get(e.provider.id)===e&&this.adapters.delete(e.provider.id);for(let e=y.middleware.length-1;e>=0;e--){let t=y.middleware[e],n=t===void 0?-1:this.middleware.lastIndexOf(t);n>=0&&this.middleware.splice(n,1)}this.emitAdaptersUpdated();let e=[];if(y.cleanup){let t=m(y.cleanup);t!==void 0&&e.push(t)}if(e.length>0)throw new n(`plugin "${a}" cleanup failed`,t.CLEANUP_FAILED,a,{cause:AggregateError(e,`plugin "${a}" cleanup failed`)})});return Object.defineProperty(x,"pluginId",{value:a,enumerable:!0}),x}registerAdapter(e,t){if(e.length===0)throw new r(`an adapter must register at least one provider route`,i.INVALID_ADAPTER);let n=new Set,a=!1;this.commitRoutes(n,this.prepareRoutes(e,t,n));let o=(()=>{if(!a){a=!0;for(let e of n)this.adapters.delete(e);n.clear(),this.emitAdaptersUpdated()}});return o.replace=e=>{if(a)throw new r(`a disposed adapter registration cannot replace its routes`,i.REGISTRATION_DISPOSED);this.commitRoutes(n,this.prepareRoutes(e,t,n))},o}prepareRoutes(e,t,n,a){let s=new Set,c=[];for(let l of e){if(typeof l!=`string`||l.length===0)throw new r(`adapter provider route names must be non-empty strings`,i.INVALID_ADAPTER);if(s.has(l)||this.adapters.has(l)&&!n.has(l))throw new r(`an adapter for provider route "${l}" is already registered`,i.DUPLICATE_ADAPTER);let e=t.providerInfo(l);if(typeof e.id!=`string`||e.id!==l||typeof e.name!=`string`||e.name.length===0)throw new r(`adapter metadata for route "${l}" must preserve its id and carry a non-empty name`,i.INVALID_ADAPTER);s.add(l),c.push({adapter:t,provider:{id:e.id,name:e.name},...a===void 0?{}:a,retryPolicy:t.providerRetryPolicy(l)??o(void 0,`provider "${l}" retryPolicy`)})}return c}commitRoutes(e,t){for(let t of e)this.adapters.delete(t);e.clear();for(let n of t)this.adapters.set(n.provider.id,n),e.add(n.provider.id);this.emitAdaptersUpdated()}use(e){return this.middleware.push(e),()=>{let t=this.middleware.indexOf(e);t>=0&&this.middleware.splice(t,1)}}onAdaptersUpdated(e){return this.listeners.add(e),()=>void this.listeners.delete(e)}emitAdaptersUpdated(){for(let e of[...this.listeners])try{e()}catch{}}listProviders(){return[...this.adapters.values()].map(({provider:e})=>({...e}))}async listModels(e,t){let n=await this.registration(e).adapter.listModels(e,t);return u(e,n,this.maxCatalogModels,this.maxCatalogBytes)}async modelCatalog(e,t={}){let n=await this.registration(e).adapter.modelCatalog(e,t);return d(e,n,this.maxCatalogModels,this.maxCatalogBytes)}async resolveModelInfo(e,t,n){let r=this.registration(e),i=await r.adapter.resolveModel(e,t,n);return c(r.provider.id,t,i,this.maxCatalogBytes,this.defaults)}retryPolicy(e){return this.registration(e).retryPolicy}async prepareCall(t,n,o){let s=this.registration(t.provider),u=await s.adapter.prepareCall(t.provider,t.model,n,o),d=c(s.provider.id,t.model,u.model,this.maxCatalogBytes,this.defaults),f=l(t,d,this.defaults),p=e(structuredClone(f.config)),m=f.context===void 0?void 0:e(structuredClone(f.context)),h=e({...t.maxTokens===void 0&&p.maxTokens!==void 0?{maxTokens:!0}:{}}),g=!1,_=e(structuredClone(d));return Object.freeze({config:p,model:_,retryPolicy:s.retryPolicy,adapterDefaults:h,...m===void 0?{}:{context:m},...f.inputModalities===void 0?{}:{inputModalities:Object.freeze([...f.inputModalities])},stream:(e,t=o)=>{if(g)throw new r(`a prepared call can only be dispatched once`,i.INVALID_PREPARED_CALL);if(!a(e,p))throw new r(`prepared call config changed before adapter dispatch`,i.INVALID_PREPARED_CALL);return g=!0,this.dispatch(e,t,{registration:s,config:p,modelInfo:d,dispatch:(e,t)=>u.stream(e,t)})}})}stream(e,t){return this.dispatch(e,t)}dispatch(e,t,n){let r=`not-sent`,i=n?.registration??this.adapters.get(e.provider);return s({options:e,...i?.family===void 0?{}:{providerFamily:i.family},...i?.pluginId===void 0?{}:{providerPluginId:i.pluginId},...i===void 0?{}:{isRetryable:e=>i.retryPolicy.mode===`always`||i.retryPolicy.retryableCodes.includes(e)},...t===void 0?{}:{context:t},...this.observation===void 0?{}:{defaultObservation:this.observation},resource:this.observationResource,routePresent:n!==void 0||this.adapters.has(e.provider),dispatchState:()=>r,stream:t=>this.dispatchRaw(e,t,()=>{r=`unknown`},n)})}dispatchRaw(e,t,n,r){let i=[...this.middleware],a=()=>{let a=()=>f({options:e,context:t,onDispatch:n,maxCatalogBytes:this.maxCatalogBytes,defaults:this.defaults,registration:e=>this.registration(e),registeredAdapter:e=>this.adapters.get(e)?.adapter,...r===void 0?{}:{prepared:r}});for(let n=i.length-1;n>=0;n--){let r=i[n];if(r===void 0)continue;let o=a;a=()=>r(e,o,t)}return a()};return{async*[Symbol.asyncIterator](){yield*a()}}}registration(e){let t=this.adapters.get(e);if(t===void 0)throw new r(`no adapter registered for provider route "${e}"`,i.NO_ADAPTER);return t}};function g(e,t){if(!Number.isSafeInteger(e)||e<1)throw RangeError(`ModelRegistry ${t} must be a positive safe integer`);return e}function _(t){if(t.contextWindow!==void 0&&g(t.contextWindow,`defaults.contextWindow`),t.maxTokens!==void 0&&g(t.maxTokens,`defaults.maxTokens`),t.inputModalities!==void 0&&(t.inputModalities.length===0||new Set(t.inputModalities).size!==t.inputModalities.length))throw RangeError(`ModelRegistry defaults.inputModalities must be non-empty and unique`);return e({...t.contextWindow===void 0?{}:{contextWindow:t.contextWindow},...t.maxTokens===void 0?{}:{maxTokens:t.maxTokens},...t.inputModalities===void 0?{}:{inputModalities:[...t.inputModalities]}})}export{h as ModelRegistry};
|
|
2
2
|
//# sourceMappingURL=registry.js.map
|
|
@@ -28,6 +28,21 @@ interface WithRetryOptions {
|
|
|
28
28
|
onRetry?: (attempt: RetryAttempt) => void;
|
|
29
29
|
/** Maximum wait while closing an unsuccessful attempt. Defaults to 30s. */
|
|
30
30
|
teardownTimeoutMs?: number;
|
|
31
|
+
/**
|
|
32
|
+
* Keep an attempt retryable while it has only streamed reasoning.
|
|
33
|
+
*
|
|
34
|
+
* Reasoning models open a reasoning block before any answer, so by default
|
|
35
|
+
* the retry window closes there and a provider failure while the model is
|
|
36
|
+
* still thinking cannot be retried. With this on, reasoning chunks are held
|
|
37
|
+
* back until the first answer or tool chunk (or the end), then released in
|
|
38
|
+
* order; a failure before that discards them and retries cleanly, so the
|
|
39
|
+
* consumer never sees a failed attempt's reasoning twice. The cost is that
|
|
40
|
+
* reasoning is not shown live. `true` holds up to 4096 chunks; past the cap
|
|
41
|
+
* the attempt is forwarded as usual and retry stops applying.
|
|
42
|
+
*/
|
|
43
|
+
bufferReasoningPrefix?: boolean | {
|
|
44
|
+
readonly maxChunks: number;
|
|
45
|
+
};
|
|
31
46
|
}
|
|
32
47
|
/**
|
|
33
48
|
* Wrap an adapter so eligible transient failures are retried with bounded
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"with-retry.d.ts","names":[],"sources":["../../src/runtime/with-retry.ts"],"mappings":";;;;;UAkCiB;;WAEN;;WAEA;;WAEA;;WAEA,SAAS;;WAET;;;UAIM;;;;;EAKf,SAAS;;EAET;;EAEA,WAAW,SAAS;;EAEpB
|
|
1
|
+
{"version":3,"file":"with-retry.d.ts","names":[],"sources":["../../src/runtime/with-retry.ts"],"mappings":";;;;;UAkCiB;;WAEN;;WAEA;;WAEA;;WAEA,SAAS;;WAET;;;UAIM;;;;;EAKf,SAAS;;EAET;;EAEA,WAAW,SAAS;;EAEpB;;;;;;;;;;;;;EAaA;aAA6C;;;;;;;;;;;;;iBA+W/B,UAAU,SAAS,cAAc,UAAS,mBAAwB"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{waitForSettlement as e}from"../async/settlement.js";import{MODEL_ERROR_CODES as t,ModelError as n}from"../errors/model-error.js";import{normalizeModelFailure as r}from"../errors/failure.js";import{ModelAdapter as i}from"../contract/adapter.js";import{backoffDelayMs as a,resolveRetryPolicy as o}from"../contract/retry-policy.js";function s(e,t,n,r){let i=t.providerRetryAfterMs;return i!==void 0&&Number.isFinite(i)&&i>0?i<=e.maxDelayMs?i:e.mode===`always`?a(e,n,r):`give-up`:a(e,n,r)}function c(e,t){return t?.aborted===!0?Promise.resolve(!1):new Promise(n=>{let r=()=>{clearTimeout(i),n(!1)},i=setTimeout(()=>{t?.removeEventListener(`abort`,r),n(!0)},e);t?.addEventListener(`abort`,r,{once:!0})})}var l=class extends i{inner;options;constructor(e,t){super(),this.inner=e,this.options=t}providerInfo(e){return this.inner.providerInfo(e)}providerRetryPolicy(e){return this.inner.providerRetryPolicy(e)}listModels(e){return this.inner.listModels(e)}resolveModel(e,t,n){return this.inner.resolveModel(e,t,n)}async prepareCall(e,t,n,r){let i=await this.inner.prepareCall(e,t,n,r),a=this.policyFor(e);return{model:i.model,stream:(e,t=r)=>this.retryStream(e,e=>i.stream(e,t),a,t)}}stream(e,t){return this.retryStream(e,e=>this.inner.stream(e,t),this.policyFor(e.provider),t)}policyFor(e){return this.options.policy===void 0?this.inner.providerRetryPolicy(e)??o(void 0,`withRetry("${e}").policy`):o(this.options.policy,`withRetry("${e}").policy`)}async*retryStream(e,n,r,i){if(r.mode===`always`&&e.signal===void 0){yield{type:`finish`,reason:{kind:`error`,failure:{message:`an always retry policy requires an AbortSignal or deadline`,code:t.INVALID_REQUEST}}};return}let a=this.options.random??Math.random,o=0;for(;;){let l=yield*this.runAttempt(e,n);if(l.kind===`forward`){yield*l.chunks;return}let u=l.failure;if(e.signal?.aborted===!0||u.code===t.ABORTED){yield{type:`finish`,reason:{kind:`aborted`,failure:u}};return}if(!(r.mode===`always`||r.retryableCodes.includes(u.code)&&o<r.maxRetries)){yield{type:`finish`,reason:{kind:`error`,failure:u}};return}let d=s(r,u,o+1,a);if(d===`give-up`){yield{type:`finish`,reason:{kind:`error`,failure:u}};return}o+=1,i?.recordProviderRetry?.({nextAttemptNumber:o+1,delayMs:d,failureCode:u.code});try{this.options.onRetry?.({provider:e.provider,attempt:o,maxRetries:r.mode===`normal`?r.maxRetries:void 0,failure:u,delayMs:d})}catch{}if(!await c(d,e.signal)){yield{type:`finish`,reason:{kind:`aborted`,failure:{message:`model call aborted while waiting to retry`,code:t.ABORTED}}};return}}}async*runAttempt(e,n){let i;try{
|
|
1
|
+
import{waitForSettlement as e}from"../async/settlement.js";import{MODEL_ERROR_CODES as t,ModelError as n}from"../errors/model-error.js";import{normalizeModelFailure as r}from"../errors/failure.js";import{ModelAdapter as i}from"../contract/adapter.js";import{backoffDelayMs as a,resolveRetryPolicy as o}from"../contract/retry-policy.js";function s(e,t,n,r){let i=t.providerRetryAfterMs;return i!==void 0&&Number.isFinite(i)&&i>0?i<=e.maxDelayMs?i:e.mode===`always`?a(e,n,r):`give-up`:a(e,n,r)}function c(e,t){return t?.aborted===!0?Promise.resolve(!1):new Promise(n=>{let r=()=>{clearTimeout(i),n(!1)},i=setTimeout(()=>{t?.removeEventListener(`abort`,r),n(!0)},e);t?.addEventListener(`abort`,r,{once:!0})})}var l=class extends i{inner;options;constructor(e,t){super(),this.inner=e,this.options=t}providerInfo(e){return this.inner.providerInfo(e)}providerRetryPolicy(e){return this.inner.providerRetryPolicy(e)}listModels(e){return this.inner.listModels(e)}resolveModel(e,t,n){return this.inner.resolveModel(e,t,n)}async prepareCall(e,t,n,r){let i=await this.inner.prepareCall(e,t,n,r),a=this.policyFor(e);return{model:i.model,stream:(e,t=r)=>this.retryStream(e,e=>i.stream(e,t),a,t)}}stream(e,t){return this.retryStream(e,e=>this.inner.stream(e,t),this.policyFor(e.provider),t)}policyFor(e){return this.options.policy===void 0?this.inner.providerRetryPolicy(e)??o(void 0,`withRetry("${e}").policy`):o(this.options.policy,`withRetry("${e}").policy`)}async*retryStream(e,n,r,i){if(r.mode===`always`&&e.signal===void 0){yield{type:`finish`,reason:{kind:`error`,failure:{message:`an always retry policy requires an AbortSignal or deadline`,code:t.INVALID_REQUEST}}};return}let a=this.options.random??Math.random,o=0;for(;;){let l=yield*this.runAttempt(e,n);if(l.kind===`forward`){yield*l.chunks;return}let u=l.failure;if(e.signal?.aborted===!0||u.code===t.ABORTED){yield{type:`finish`,reason:{kind:`aborted`,failure:u}};return}if(!(r.mode===`always`||r.retryableCodes.includes(u.code)&&o<r.maxRetries)){yield{type:`finish`,reason:{kind:`error`,failure:u}};return}let d=s(r,u,o+1,a);if(d===`give-up`){yield{type:`finish`,reason:{kind:`error`,failure:u}};return}o+=1,i?.recordProviderRetry?.({nextAttemptNumber:o+1,delayMs:d,failureCode:u.code});try{this.options.onRetry?.({provider:e.provider,attempt:o,maxRetries:r.mode===`normal`?r.maxRetries:void 0,failure:u,delayMs:d})}catch{}if(!await c(d,e.signal)){yield{type:`finish`,reason:{kind:`aborted`,failure:{message:`model call aborted while waiting to retry`,code:t.ABORTED}}};return}}}async*runAttempt(e,n){let i=d(this.options.bufferReasoningPrefix),a;try{a=n(e)[Symbol.asyncIterator]()}catch(e){return{kind:`retryable`,failure:r(e)}}let o;try{for(o=await a.next();!o.done&&o.value.type===`usage-progress`;){let e=!1;try{yield o.value,e=!0}finally{e||await m(a,this.options.teardownTimeoutMs??3e4)}o=await a.next()}}catch(e){return await m(a,this.options.teardownTimeoutMs??3e4),{kind:`retryable`,failure:r(e)}}if(o.done===!0)return{kind:`retryable`,failure:{message:`the adapter produced no chunks`,code:t.UNKNOWN}};let s=o.value;if(s.type===`finish`&&s.reason.kind===`error`)return await m(a,this.options.teardownTimeoutMs??3e4),{kind:`retryable`,failure:s.reason.failure};let c=[];if(i>0){let e=new Set,t=!1;try{for(;f(s,e)&&c.length<i;){c.push(s);let e=await a.next();for(;!e.done&&e.value.type===`usage-progress`;){let t=!1;try{yield e.value,t=!0}finally{t||await m(a,this.options.teardownTimeoutMs??3e4)}e=await a.next()}if(e.done===!0){t=!0;break}if(s=e.value,s.type===`finish`&&s.reason.kind===`error`)return await m(a,this.options.teardownTimeoutMs??3e4),{kind:`retryable`,failure:s.reason.failure}}}catch(e){return await m(a,this.options.teardownTimeoutMs??3e4),{kind:`retryable`,failure:r(e)}}if(t)return{kind:`forward`,chunks:p(c,void 0,a,this.options.teardownTimeoutMs??3e4)}}return{kind:`forward`,chunks:p(c,s,a,this.options.teardownTimeoutMs??3e4)}}};function u(e,t){if(!Number.isFinite(e)||e<=0)throw RangeError(`${t} must be a positive finite number`);return e}function d(e){if(e===void 0||e===!1)return 0;if(e===!0)return 4096;if(!Number.isSafeInteger(e.maxChunks)||e.maxChunks<1)throw RangeError(`bufferReasoningPrefix.maxChunks must be a positive safe integer`);return e.maxChunks}function f(e,t){return e.type===`reasoning-delta`?!0:e.type===`block-start`&&e.blockType===`reasoning`?(t.add(e.index),!0):e.type===`block-end`&&(e.block.type===`reasoning`||t.has(e.index))}async function*p(e,t,n,r){let i=!1;try{for(let t of e)yield t;for(t!==void 0&&(yield t);;){let e=await n.next();if(e.done===!0){i=!0;return}yield e.value}}finally{i||await m(n,r)}}async function m(r,i){let a=r.return?.();if(a!==void 0&&!await e(Promise.resolve(a),u(i,`withRetry teardownTimeoutMs`)))throw new n(`retry attempt teardown exceeded ${i}ms`,t.TEARDOWN_TIMEOUT)}function h(e,t={}){return new l(e,t)}export{h as withRetry};
|
|
2
2
|
//# sourceMappingURL=with-retry.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"with-retry.js","names":[],"sources":["../../src/runtime/with-retry.ts"],"sourcesContent":["/**\n * Retry as an adapter DECORATOR.\n *\n * In deepseek-harness this was a plugin on the agent loop's failed-step hook,\n * which let it restart a whole step and recover its attempt count from a durable\n * session log. A standalone SDK has neither, so retry moves down to the adapter\n * and holds its attempt count in the call's own closure.\n *\n * That relocation brings one hard constraint, and it is the thing to understand\n * about this module: a retry may only happen before response content is yielded.\n * Provisional usage snapshots are the only exception. Once a text delta has reached the consumer, re-running the\n * request would replay those tokens and the consumer would render them twice.\n * So a failure that arrives mid-stream is forwarded, not retried Erecovering\n * from it requires re-running the whole turn, which only the caller can decide.\n *\n * @module ai-agent-sdk/core/runtime/with-retry\n */\n\nimport { ModelAdapter, type PreparedAdapterCall } from '../contract/adapter.ts'\nimport type { GenerateOptions } from '../contract/generate-options.ts'\nimport type { ModelInfo, ResolvedModelInfo } from '../contract/model-info.ts'\nimport {\n backoffDelayMs,\n resolveRetryPolicy,\n type ResolvedRetryPolicy,\n type RetryPolicyConfig,\n} from '../contract/retry-policy.ts'\nimport { normalizeModelFailure, type ModelFailure } from '../errors/failure.ts'\nimport { MODEL_ERROR_CODES, ModelError } from '../errors/model-error.ts'\nimport type { StreamChunk } from '../stream/chunk.ts'\nimport type { ModelInvocationContext } from '../observation/report.ts'\nimport { waitForSettlement } from '../async/settlement.ts'\n\n/** One retry that is about to be waited out. */\nexport interface RetryAttempt {\n /** The route whose call failed. */\n readonly provider: string\n /** 1-based retry number. */\n readonly attempt: number\n /** Retry ceiling, or `undefined` under an `always` policy. */\n readonly maxRetries: number | undefined\n /** The failure being recovered from. */\n readonly failure: ModelFailure\n /** How long the decorator will wait before re-dispatching. */\n readonly delayMs: number\n}\n\n/** Options for {@link withRetry}. */\nexport interface WithRetryOptions {\n /**\n * Policy to apply. Omission uses the wrapped adapter's own per-route policy,\n * falling back to the shared defaults.\n */\n policy?: RetryPolicyConfig\n /** Sample in `[0, 1)` for jitter; injectable so tests can be deterministic. */\n random?: () => number\n /** Observe each scheduled retry Ethe hook for logging and metrics. */\n onRetry?: (attempt: RetryAttempt) => void\n /** Maximum wait while closing an unsuccessful attempt. Defaults to 30s. */\n teardownTimeoutMs?: number\n}\n\n/** Resolve a delay that honours a provider-requested `retry-after` when sane. */\nfunction delayFor(\n policy: ResolvedRetryPolicy,\n failure: ModelFailure,\n attempt: number,\n random: () => number,\n): number | 'give-up' {\n const requested = failure.providerRetryAfterMs\n if (requested !== undefined && Number.isFinite(requested) && requested > 0) {\n if (requested <= policy.maxDelayMs) return requested\n // The provider asked for longer than this policy is willing to wait. Under a\n // bounded policy that is a refusal: sleeping less than asked would just earn\n // another rate-limit response. An `always` policy has nowhere to give up to,\n // so it falls back to local backoff and keeps trying.\n return policy.mode === 'always' ? backoffDelayMs(policy, attempt, random) : 'give-up'\n }\n return backoffDelayMs(policy, attempt, random)\n}\n\n/** Sleep, resolving early and reporting false if the signal aborts first. */\nfunction cancellableDelay(delayMs: number, signal?: AbortSignal): Promise<boolean> {\n if (signal?.aborted === true) return Promise.resolve(false)\n return new Promise((resolve) => {\n const onAbort = (): void => {\n clearTimeout(timer)\n resolve(false)\n }\n const timer = setTimeout(() => {\n signal?.removeEventListener('abort', onAbort)\n resolve(true)\n }, delayMs)\n signal?.addEventListener('abort', onAbort, { once: true })\n })\n}\n\nclass RetryingAdapter extends ModelAdapter {\n private readonly inner: ModelAdapter\n private readonly options: WithRetryOptions\n\n // Explicit fields rather than constructor parameter properties: Node's\n // strip-only TypeScript mode rejects those, and this package is meant to run\n // under `node file.ts` without a build step.\n constructor(inner: ModelAdapter, options: WithRetryOptions) {\n super()\n this.inner = inner\n this.options = options\n }\n\n override providerInfo(provider: string): ReturnType<ModelAdapter['providerInfo']> {\n return this.inner.providerInfo(provider)\n }\n\n override providerRetryPolicy(provider: string): ResolvedRetryPolicy | undefined {\n return this.inner.providerRetryPolicy(provider)\n }\n\n override listModels(provider: string): Promise<readonly ModelInfo[]> {\n return this.inner.listModels(provider)\n }\n\n override resolveModel(\n provider: string,\n model: string,\n signal?: AbortSignal,\n ): Promise<ResolvedModelInfo> {\n return this.inner.resolveModel(provider, model, signal)\n }\n\n override async prepareCall(\n provider: string,\n model: string,\n signal?: AbortSignal,\n context?: ModelInvocationContext,\n ): Promise<PreparedAdapterCall> {\n const prepared = await this.inner.prepareCall(provider, model, signal, context)\n const policy = this.policyFor(provider)\n return {\n model: prepared.model,\n // Retries reuse the SAME prepared generation. Re-preparing mid-retry could\n // pair a fresh endpoint with capabilities resolved against the old one,\n // which is exactly what the prepare/dispatch binding exists to prevent.\n stream: (options, invocation = context) => this.retryStream(options, request => prepared.stream(request, invocation), policy, invocation),\n }\n }\n\n stream(options: GenerateOptions, context?: ModelInvocationContext): AsyncIterable<StreamChunk> {\n return this.retryStream(\n options,\n request => this.inner.stream(request, context),\n this.policyFor(options.provider),\n context,\n )\n }\n\n private policyFor(provider: string): ResolvedRetryPolicy {\n if (this.options.policy !== undefined) {\n return resolveRetryPolicy(this.options.policy, `withRetry(\"${provider}\").policy`)\n }\n return this.inner.providerRetryPolicy(provider)\n ?? resolveRetryPolicy(undefined, `withRetry(\"${provider}\").policy`)\n }\n\n private async * retryStream(\n options: GenerateOptions,\n dispatch: (request: GenerateOptions) => AsyncIterable<StreamChunk>,\n policy: ResolvedRetryPolicy,\n context?: ModelInvocationContext,\n ): AsyncGenerator<StreamChunk> {\n if (policy.mode === 'always' && options.signal === undefined) {\n yield {\n type: 'finish',\n reason: {\n kind: 'error',\n failure: {\n message: 'an always retry policy requires an AbortSignal or deadline',\n code: MODEL_ERROR_CODES.INVALID_REQUEST,\n },\n },\n }\n return\n }\n const random = this.options.random ?? Math.random\n let retries = 0\n\n while (true) {\n const attempt = yield* this.runAttempt(options, dispatch)\n if (attempt.kind === 'forward') {\n yield* attempt.chunks\n return\n }\n\n const failure = attempt.failure\n // An abort is the caller's decision, never a transient fault.\n if (options.signal?.aborted === true || failure.code === MODEL_ERROR_CODES.ABORTED) {\n yield { type: 'finish', reason: { kind: 'aborted', failure } }\n return\n }\n\n const eligible = policy.mode === 'always'\n || (policy.retryableCodes.includes(failure.code) && retries < policy.maxRetries)\n if (!eligible) {\n yield { type: 'finish', reason: { kind: 'error', failure } }\n return\n }\n\n const delayMs = delayFor(policy, failure, retries + 1, random)\n if (delayMs === 'give-up') {\n yield { type: 'finish', reason: { kind: 'error', failure } }\n return\n }\n\n retries += 1\n context?.recordProviderRetry?.({\n nextAttemptNumber: retries + 1,\n delayMs,\n failureCode: failure.code,\n })\n try {\n this.options.onRetry?.({\n provider: options.provider,\n attempt: retries,\n maxRetries: policy.mode === 'normal' ? policy.maxRetries : undefined,\n failure,\n delayMs,\n })\n } catch {\n // Metrics/logging observers do not own request availability.\n }\n if (!await cancellableDelay(delayMs, options.signal)) {\n yield {\n type: 'finish',\n reason: {\n kind: 'aborted',\n failure: {\n message: 'model call aborted while waiting to retry',\n code: MODEL_ERROR_CODES.ABORTED,\n },\n },\n }\n return\n }\n }\n }\n\n /**\n * Run one attempt, forwarding only provisional usage before committing content.\n *\n * Buffering is what makes retry safe: until the attempt either produces its\n * first non-progress chunk or fails, no content has been committed. Once that\n * chunk exists the attempt is no longer retryable, so it switches to\n * `forward` and streams the rest through untouched.\n */\n private async *runAttempt(\n options: GenerateOptions,\n dispatch: (request: GenerateOptions) => AsyncIterable<StreamChunk>,\n ): AsyncGenerator<StreamChunk,\n | { kind: 'forward'; chunks: AsyncIterable<StreamChunk> }\n | { kind: 'retryable'; failure: ModelFailure }\n > {\n let iterator: AsyncIterator<StreamChunk>\n try {\n iterator = dispatch(options)[Symbol.asyncIterator]()\n } catch (error: unknown) {\n return { kind: 'retryable', failure: normalizeModelFailure(error) }\n }\n\n let first: IteratorResult<StreamChunk>\n try {\n first = await iterator.next()\n // Provisional accounting is not response content: preserve pre-content\n // retries while allowing the caller to observe usage as it arrives.\n while (!first.done && first.value.type === 'usage-progress') {\n let resumed = false\n try {\n yield first.value\n resumed = true\n } finally {\n if (!resumed) await closeIterator(iterator, this.options.teardownTimeoutMs ?? 30_000)\n }\n first = await iterator.next()\n }\n } catch (error: unknown) {\n await closeIterator(iterator, this.options.teardownTimeoutMs ?? 30_000)\n return { kind: 'retryable', failure: normalizeModelFailure(error) }\n }\n\n // A stream that ends with no chunks at all told us nothing; treat it as the\n // degenerate empty response rather than a silently successful turn.\n if (first.done === true) {\n return {\n kind: 'retryable',\n failure: {\n message: 'the adapter produced no chunks',\n code: MODEL_ERROR_CODES.UNKNOWN,\n },\n }\n }\n\n // An adapter behind the registry's funnel reports failure as a terminal\n // error finish rather than a throw. As the FIRST chunk, that is still a\n // clean nothing-emitted failure and remains retryable.\n const chunk = first.value\n if (chunk.type === 'finish' && chunk.reason.kind === 'error') {\n await closeIterator(iterator, this.options.teardownTimeoutMs ?? 30_000)\n return { kind: 'retryable', failure: chunk.reason.failure }\n }\n\n return {\n kind: 'forward',\n chunks: resume(chunk, iterator, this.options.teardownTimeoutMs ?? 30_000),\n }\n }\n}\n\nfunction positiveFinite(value: number, name: string): number {\n if (!Number.isFinite(value) || value <= 0) throw new RangeError(`${name} must be a positive finite number`)\n return value\n}\n\n/** Re-attach an already-read first chunk to the front of its iterator. */\nasync function* resume(\n first: StreamChunk,\n iterator: AsyncIterator<StreamChunk>,\n teardownTimeoutMs: number,\n): AsyncGenerator<StreamChunk> {\n let exhausted = false\n try {\n yield first\n while (true) {\n const next = await iterator.next()\n if (next.done === true) {\n exhausted = true\n return\n }\n yield next.value\n }\n } finally {\n if (!exhausted) await closeIterator(iterator, teardownTimeoutMs)\n }\n}\n\nasync function closeIterator(iterator: AsyncIterator<StreamChunk>, timeoutMs: number): Promise<void> {\n const closing = iterator.return?.()\n if (closing === undefined) return\n const settled = await waitForSettlement(\n Promise.resolve(closing),\n positiveFinite(timeoutMs, 'withRetry teardownTimeoutMs'),\n )\n if (!settled) {\n throw new ModelError(\n `retry attempt teardown exceeded ${timeoutMs}ms`,\n MODEL_ERROR_CODES.TEARDOWN_TIMEOUT,\n )\n }\n}\n\n/**\n * Wrap an adapter so eligible transient failures are retried with bounded\n * exponential backoff and jitter.\n *\n * Only failures that occur BEFORE the first chunk reaches the consumer are\n * retried; see the module note for why.\n * @param adapter - the adapter to wrap; its metadata methods are delegated unchanged.\n * @param options - policy, jitter source, and retry observer.\n * @returns a new adapter with retry behaviour; the original is unmodified.\n */\nexport function withRetry(adapter: ModelAdapter, options: WithRetryOptions = {}): ModelAdapter {\n return new RetryingAdapter(adapter, options)\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"with-retry.js","names":[],"sources":["../../src/runtime/with-retry.ts"],"sourcesContent":["/**\n * Retry as an adapter DECORATOR.\n *\n * In deepseek-harness this was a plugin on the agent loop's failed-step hook,\n * which let it restart a whole step and recover its attempt count from a durable\n * session log. A standalone SDK has neither, so retry moves down to the adapter\n * and holds its attempt count in the call's own closure.\n *\n * That relocation brings one hard constraint, and it is the thing to understand\n * about this module: a retry may only happen before response content is yielded.\n * Provisional usage snapshots are the only exception. Once a text delta has reached the consumer, re-running the\n * request would replay those tokens and the consumer would render them twice.\n * So a failure that arrives mid-stream is forwarded, not retried Erecovering\n * from it requires re-running the whole turn, which only the caller can decide.\n *\n * @module ai-agent-sdk/core/runtime/with-retry\n */\n\nimport { ModelAdapter, type PreparedAdapterCall } from '../contract/adapter.ts'\nimport type { GenerateOptions } from '../contract/generate-options.ts'\nimport type { ModelInfo, ResolvedModelInfo } from '../contract/model-info.ts'\nimport {\n backoffDelayMs,\n resolveRetryPolicy,\n type ResolvedRetryPolicy,\n type RetryPolicyConfig,\n} from '../contract/retry-policy.ts'\nimport { normalizeModelFailure, type ModelFailure } from '../errors/failure.ts'\nimport { MODEL_ERROR_CODES, ModelError } from '../errors/model-error.ts'\nimport type { StreamChunk } from '../stream/chunk.ts'\nimport type { ModelInvocationContext } from '../observation/report.ts'\nimport { waitForSettlement } from '../async/settlement.ts'\n\n/** One retry that is about to be waited out. */\nexport interface RetryAttempt {\n /** The route whose call failed. */\n readonly provider: string\n /** 1-based retry number. */\n readonly attempt: number\n /** Retry ceiling, or `undefined` under an `always` policy. */\n readonly maxRetries: number | undefined\n /** The failure being recovered from. */\n readonly failure: ModelFailure\n /** How long the decorator will wait before re-dispatching. */\n readonly delayMs: number\n}\n\n/** Options for {@link withRetry}. */\nexport interface WithRetryOptions {\n /**\n * Policy to apply. Omission uses the wrapped adapter's own per-route policy,\n * falling back to the shared defaults.\n */\n policy?: RetryPolicyConfig\n /** Sample in `[0, 1)` for jitter; injectable so tests can be deterministic. */\n random?: () => number\n /** Observe each scheduled retry Ethe hook for logging and metrics. */\n onRetry?: (attempt: RetryAttempt) => void\n /** Maximum wait while closing an unsuccessful attempt. Defaults to 30s. */\n teardownTimeoutMs?: number\n /**\n * Keep an attempt retryable while it has only streamed reasoning.\n *\n * Reasoning models open a reasoning block before any answer, so by default\n * the retry window closes there and a provider failure while the model is\n * still thinking cannot be retried. With this on, reasoning chunks are held\n * back until the first answer or tool chunk (or the end), then released in\n * order; a failure before that discards them and retries cleanly, so the\n * consumer never sees a failed attempt's reasoning twice. The cost is that\n * reasoning is not shown live. `true` holds up to 4096 chunks; past the cap\n * the attempt is forwarded as usual and retry stops applying.\n */\n bufferReasoningPrefix?: boolean | { readonly maxChunks: number }\n}\n\n/** Resolve a delay that honours a provider-requested `retry-after` when sane. */\nfunction delayFor(\n policy: ResolvedRetryPolicy,\n failure: ModelFailure,\n attempt: number,\n random: () => number,\n): number | 'give-up' {\n const requested = failure.providerRetryAfterMs\n if (requested !== undefined && Number.isFinite(requested) && requested > 0) {\n if (requested <= policy.maxDelayMs) return requested\n // The provider asked for longer than this policy is willing to wait. Under a\n // bounded policy that is a refusal: sleeping less than asked would just earn\n // another rate-limit response. An `always` policy has nowhere to give up to,\n // so it falls back to local backoff and keeps trying.\n return policy.mode === 'always' ? backoffDelayMs(policy, attempt, random) : 'give-up'\n }\n return backoffDelayMs(policy, attempt, random)\n}\n\n/** Sleep, resolving early and reporting false if the signal aborts first. */\nfunction cancellableDelay(delayMs: number, signal?: AbortSignal): Promise<boolean> {\n if (signal?.aborted === true) return Promise.resolve(false)\n return new Promise((resolve) => {\n const onAbort = (): void => {\n clearTimeout(timer)\n resolve(false)\n }\n const timer = setTimeout(() => {\n signal?.removeEventListener('abort', onAbort)\n resolve(true)\n }, delayMs)\n signal?.addEventListener('abort', onAbort, { once: true })\n })\n}\n\nclass RetryingAdapter extends ModelAdapter {\n private readonly inner: ModelAdapter\n private readonly options: WithRetryOptions\n\n // Explicit fields rather than constructor parameter properties: Node's\n // strip-only TypeScript mode rejects those, and this package is meant to run\n // under `node file.ts` without a build step.\n constructor(inner: ModelAdapter, options: WithRetryOptions) {\n super()\n this.inner = inner\n this.options = options\n }\n\n override providerInfo(provider: string): ReturnType<ModelAdapter['providerInfo']> {\n return this.inner.providerInfo(provider)\n }\n\n override providerRetryPolicy(provider: string): ResolvedRetryPolicy | undefined {\n return this.inner.providerRetryPolicy(provider)\n }\n\n override listModels(provider: string): Promise<readonly ModelInfo[]> {\n return this.inner.listModels(provider)\n }\n\n override resolveModel(\n provider: string,\n model: string,\n signal?: AbortSignal,\n ): Promise<ResolvedModelInfo> {\n return this.inner.resolveModel(provider, model, signal)\n }\n\n override async prepareCall(\n provider: string,\n model: string,\n signal?: AbortSignal,\n context?: ModelInvocationContext,\n ): Promise<PreparedAdapterCall> {\n const prepared = await this.inner.prepareCall(provider, model, signal, context)\n const policy = this.policyFor(provider)\n return {\n model: prepared.model,\n // Retries reuse the SAME prepared generation. Re-preparing mid-retry could\n // pair a fresh endpoint with capabilities resolved against the old one,\n // which is exactly what the prepare/dispatch binding exists to prevent.\n stream: (options, invocation = context) => this.retryStream(options, request => prepared.stream(request, invocation), policy, invocation),\n }\n }\n\n stream(options: GenerateOptions, context?: ModelInvocationContext): AsyncIterable<StreamChunk> {\n return this.retryStream(\n options,\n request => this.inner.stream(request, context),\n this.policyFor(options.provider),\n context,\n )\n }\n\n private policyFor(provider: string): ResolvedRetryPolicy {\n if (this.options.policy !== undefined) {\n return resolveRetryPolicy(this.options.policy, `withRetry(\"${provider}\").policy`)\n }\n return this.inner.providerRetryPolicy(provider)\n ?? resolveRetryPolicy(undefined, `withRetry(\"${provider}\").policy`)\n }\n\n private async * retryStream(\n options: GenerateOptions,\n dispatch: (request: GenerateOptions) => AsyncIterable<StreamChunk>,\n policy: ResolvedRetryPolicy,\n context?: ModelInvocationContext,\n ): AsyncGenerator<StreamChunk> {\n if (policy.mode === 'always' && options.signal === undefined) {\n yield {\n type: 'finish',\n reason: {\n kind: 'error',\n failure: {\n message: 'an always retry policy requires an AbortSignal or deadline',\n code: MODEL_ERROR_CODES.INVALID_REQUEST,\n },\n },\n }\n return\n }\n const random = this.options.random ?? Math.random\n let retries = 0\n\n while (true) {\n const attempt = yield* this.runAttempt(options, dispatch)\n if (attempt.kind === 'forward') {\n yield* attempt.chunks\n return\n }\n\n const failure = attempt.failure\n // An abort is the caller's decision, never a transient fault.\n if (options.signal?.aborted === true || failure.code === MODEL_ERROR_CODES.ABORTED) {\n yield { type: 'finish', reason: { kind: 'aborted', failure } }\n return\n }\n\n const eligible = policy.mode === 'always'\n || (policy.retryableCodes.includes(failure.code) && retries < policy.maxRetries)\n if (!eligible) {\n yield { type: 'finish', reason: { kind: 'error', failure } }\n return\n }\n\n const delayMs = delayFor(policy, failure, retries + 1, random)\n if (delayMs === 'give-up') {\n yield { type: 'finish', reason: { kind: 'error', failure } }\n return\n }\n\n retries += 1\n context?.recordProviderRetry?.({\n nextAttemptNumber: retries + 1,\n delayMs,\n failureCode: failure.code,\n })\n try {\n this.options.onRetry?.({\n provider: options.provider,\n attempt: retries,\n maxRetries: policy.mode === 'normal' ? policy.maxRetries : undefined,\n failure,\n delayMs,\n })\n } catch {\n // Metrics/logging observers do not own request availability.\n }\n if (!await cancellableDelay(delayMs, options.signal)) {\n yield {\n type: 'finish',\n reason: {\n kind: 'aborted',\n failure: {\n message: 'model call aborted while waiting to retry',\n code: MODEL_ERROR_CODES.ABORTED,\n },\n },\n }\n return\n }\n }\n }\n\n /**\n * Run one attempt, forwarding only provisional usage before committing content.\n *\n * Buffering is what makes retry safe: until the attempt either produces its\n * first non-progress chunk or fails, no content has been committed. Once that\n * chunk exists the attempt is no longer retryable, so it switches to\n * `forward` and streams the rest through untouched.\n */\n private async *runAttempt(\n options: GenerateOptions,\n dispatch: (request: GenerateOptions) => AsyncIterable<StreamChunk>,\n ): AsyncGenerator<StreamChunk,\n | { kind: 'forward'; chunks: AsyncIterable<StreamChunk> }\n | { kind: 'retryable'; failure: ModelFailure }\n > {\n const cap = reasoningBufferCap(this.options.bufferReasoningPrefix)\n let iterator: AsyncIterator<StreamChunk>\n try {\n iterator = dispatch(options)[Symbol.asyncIterator]()\n } catch (error: unknown) {\n return { kind: 'retryable', failure: normalizeModelFailure(error) }\n }\n\n let first: IteratorResult<StreamChunk>\n try {\n first = await iterator.next()\n // Provisional accounting is not response content: preserve pre-content\n // retries while allowing the caller to observe usage as it arrives.\n while (!first.done && first.value.type === 'usage-progress') {\n let resumed = false\n try {\n yield first.value\n resumed = true\n } finally {\n if (!resumed) await closeIterator(iterator, this.options.teardownTimeoutMs ?? 30_000)\n }\n first = await iterator.next()\n }\n } catch (error: unknown) {\n await closeIterator(iterator, this.options.teardownTimeoutMs ?? 30_000)\n return { kind: 'retryable', failure: normalizeModelFailure(error) }\n }\n\n // A stream that ends with no chunks at all told us nothing; treat it as the\n // degenerate empty response rather than a silently successful turn.\n if (first.done === true) {\n return {\n kind: 'retryable',\n failure: {\n message: 'the adapter produced no chunks',\n code: MODEL_ERROR_CODES.UNKNOWN,\n },\n }\n }\n\n // An adapter behind the registry's funnel reports failure as a terminal\n // error finish rather than a throw. As the FIRST chunk, that is still a\n // clean nothing-emitted failure and remains retryable.\n let chunk = first.value\n if (chunk.type === 'finish' && chunk.reason.kind === 'error') {\n await closeIterator(iterator, this.options.teardownTimeoutMs ?? 30_000)\n return { kind: 'retryable', failure: chunk.reason.failure }\n }\n\n const held: StreamChunk[] = []\n if (cap > 0) {\n const reasoningBlocks = new Set<number>()\n let ended = false\n try {\n while (isReasoningChunk(chunk, reasoningBlocks) && held.length < cap) {\n held.push(chunk)\n let next = await iterator.next()\n while (!next.done && next.value.type === 'usage-progress') {\n let resumed = false\n try {\n yield next.value\n resumed = true\n } finally {\n if (!resumed) await closeIterator(iterator, this.options.teardownTimeoutMs ?? 30_000)\n }\n next = await iterator.next()\n }\n if (next.done === true) { ended = true; break }\n chunk = next.value\n // Still only thinking when it failed: nothing was shown, so retry.\n if (chunk.type === 'finish' && chunk.reason.kind === 'error') {\n await closeIterator(iterator, this.options.teardownTimeoutMs ?? 30_000)\n return { kind: 'retryable', failure: chunk.reason.failure }\n }\n }\n } catch (error: unknown) {\n await closeIterator(iterator, this.options.teardownTimeoutMs ?? 30_000)\n return { kind: 'retryable', failure: normalizeModelFailure(error) }\n }\n // A stream that only reasoned and then ended releases what it held.\n if (ended) {\n return { kind: 'forward', chunks: resume(held, undefined, iterator, this.options.teardownTimeoutMs ?? 30_000) }\n }\n }\n\n return {\n kind: 'forward',\n chunks: resume(held, chunk, iterator, this.options.teardownTimeoutMs ?? 30_000),\n }\n }\n}\n\nfunction positiveFinite(value: number, name: string): number {\n if (!Number.isFinite(value) || value <= 0) throw new RangeError(`${name} must be a positive finite number`)\n return value\n}\n\nfunction reasoningBufferCap(option: WithRetryOptions['bufferReasoningPrefix']): number {\n if (option === undefined || option === false) return 0\n if (option === true) return 4096\n if (!Number.isSafeInteger(option.maxChunks) || option.maxChunks < 1) {\n throw new RangeError('bufferReasoningPrefix.maxChunks must be a positive safe integer')\n }\n return option.maxChunks\n}\n\n/** Whether a chunk only carries reasoning, tracking which block indexes are reasoning. */\nfunction isReasoningChunk(chunk: StreamChunk, reasoningBlocks: Set<number>): boolean {\n if (chunk.type === 'reasoning-delta') return true\n if (chunk.type === 'block-start' && chunk.blockType === 'reasoning') {\n reasoningBlocks.add(chunk.index)\n return true\n }\n return chunk.type === 'block-end' && (chunk.block.type === 'reasoning' || reasoningBlocks.has(chunk.index))\n}\n\n/** Re-attach already-read chunks to the front of their iterator. */\nasync function* resume(\n held: readonly StreamChunk[],\n first: StreamChunk | undefined,\n iterator: AsyncIterator<StreamChunk>,\n teardownTimeoutMs: number,\n): AsyncGenerator<StreamChunk> {\n let exhausted = false\n try {\n for (const chunk of held) yield chunk\n if (first !== undefined) yield first\n while (true) {\n const next = await iterator.next()\n if (next.done === true) {\n exhausted = true\n return\n }\n yield next.value\n }\n } finally {\n if (!exhausted) await closeIterator(iterator, teardownTimeoutMs)\n }\n}\n\nasync function closeIterator(iterator: AsyncIterator<StreamChunk>, timeoutMs: number): Promise<void> {\n const closing = iterator.return?.()\n if (closing === undefined) return\n const settled = await waitForSettlement(\n Promise.resolve(closing),\n positiveFinite(timeoutMs, 'withRetry teardownTimeoutMs'),\n )\n if (!settled) {\n throw new ModelError(\n `retry attempt teardown exceeded ${timeoutMs}ms`,\n MODEL_ERROR_CODES.TEARDOWN_TIMEOUT,\n )\n }\n}\n\n/**\n * Wrap an adapter so eligible transient failures are retried with bounded\n * exponential backoff and jitter.\n *\n * Only failures that occur BEFORE the first chunk reaches the consumer are\n * retried; see the module note for why.\n * @param adapter - the adapter to wrap; its metadata methods are delegated unchanged.\n * @param options - policy, jitter source, and retry observer.\n * @returns a new adapter with retry behaviour; the original is unmodified.\n */\nexport function withRetry(adapter: ModelAdapter, options: WithRetryOptions = {}): ModelAdapter {\n return new RetryingAdapter(adapter, options)\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED