@alvin0/ai-agent-sdk-core 0.1.9 → 0.1.10

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/README.md CHANGED
@@ -22,7 +22,7 @@ import {
22
22
  const runtime = await createAgentRuntime({ providers: [provider] })
23
23
  const definition = defineAgent({ id: 'assistant', instructions: 'Be concise.' })
24
24
  const logger: SdkLogger = runtime.logger({ fields: { component: 'assistant' } })
25
- const agent = runtime.agent({ ...definition, model: { provider: 'openai', id: 'gpt-5.4' } })
25
+ const agent = runtime.agent({ ...definition, model: { provider: 'openai', id: 'gpt-6-luna' } })
26
26
  logger.info('agent ready')
27
27
  ```
28
28
 
@@ -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.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};
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.10`,...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 +1 @@
1
- {"version":3,"file":"bus.js","names":[],"sources":["../../src/observability/bus.ts"],"sourcesContent":["import {\n SDK_VERSION,\n deepFreeze,\n} from '../primitives/index.ts'\nimport {\n createCoreSpan,\n createObservationRunScope,\n createOperationId,\n safeErrorRecord,\n snapshotObservationSpan,\n type CaptureReceipt,\n type ObservationBoundary,\n type ObservationEvent,\n type ObservationResource,\n type ObservationSpan,\n type OpenObservationSpanInput,\n type SafeErrorRecord,\n} from '../observation/index.ts'\nimport { createBusLogger } from './logger.ts'\nimport { sanitizeObservationEvent, serializedEventBytes } from './privacy.ts'\nimport type {\n ExportAck,\n FlushResult,\n LoggerContext,\n LogLevel,\n ObservationBatch,\n ObservationExporterRegistration,\n ObservationHealthSnapshot,\n ObservationProcessor,\n Observability,\n ObservabilityOptions,\n SdkLogger,\n} from './types.ts'\n\nconst DEFAULT_MAX_QUEUE_EVENTS = 10_000\nconst DEFAULT_MAX_QUEUE_BYTES = 16 * 1024 * 1024\nconst DEFAULT_MAX_BATCH_EVENTS = 256\nconst DEFAULT_MAX_BATCH_BYTES = 512 * 1024\nconst DEFAULT_FLUSH_TIMEOUT_MS = 10_000\nconst DEFAULT_SHUTDOWN_TIMEOUT_MS = 30_000\n\ninterface QueueEntry {\n readonly event: ObservationEvent\n readonly bytes: number\n readonly pending: Set<string>\n readonly protected: boolean\n}\n\ninterface MutableHealth {\n accepted: number\n exported: number\n droppedVerbose: number\n droppedNormal: number\n criticalRejected: number\n processorFailures: number\n exporterFailures: number\n flushTimeouts: number\n lastExportAt?: string\n lastFailure?: SafeErrorRecord\n requiredFailure: boolean\n}\n\ninterface FlushOutcome extends FlushResult {\n readonly requiredComplete: boolean\n}\n\nconst BOUNDARY_RANK: Readonly<Record<ObservationBoundary, number>> = {\n none: 0, 'local-durable': 1, 'remote-acknowledged': 2,\n}\nconst SAFE_FAILURE_CODES = new Set([\n 'ABORT_ERR', 'ECONNREFUSED', 'ECONNRESET', 'EHOSTUNREACH', 'ENETUNREACH',\n 'ETIMEDOUT', 'OBSERVABILITY_EXPORT_FAILED', 'OBSERVABILITY_FLUSH_TIMEOUT',\n 'OBSERVABILITY_PROCESSOR_FAILED', 'OTEL_PROVIDER_UNCONFIGURED',\n])\nconst COMPONENT_ID_PATTERN = /^[A-Za-z0-9](?:[A-Za-z0-9._-]{0,63})$/\nconst CONTENT_POLICIES = new Set(['none', 'metadata', 'redacted', 'full'])\nconst LOG_LEVELS = new Set(['trace', 'debug', 'info', 'warn', 'error', 'fatal'])\n\nfunction positiveSafeInteger(value: number, field: string): number {\n if (!Number.isSafeInteger(value) || value < 1) throw new RangeError(`${field} must be a positive safe integer`)\n return value\n}\n\nfunction safeFailure(error: unknown, message: string): SafeErrorRecord {\n const source = safeErrorRecord(error)\n return deepFreeze({\n type: ['AbortError', 'Error', 'RangeError', 'TypeError'].includes(source.type) ? source.type : 'Error',\n message,\n ...source.code !== undefined && SAFE_FAILURE_CODES.has(source.code) ? { code: source.code } : {},\n ...source.retryable === undefined ? {} : { retryable: source.retryable },\n ...source.status === undefined ? {} : { status: source.status },\n })\n}\n\nfunction receipt(\n eventId: string,\n status: CaptureReceipt['status'],\n boundary: ObservationBoundary = 'none',\n reason?: CaptureReceipt['reason'],\n): CaptureReceipt {\n return Object.freeze({\n eventId, status, durable: status === 'accepted' && boundary !== 'none', boundary,\n ...reason === undefined ? {} : { reason },\n })\n}\n\nfunction eventIdOf(event: unknown): string {\n try {\n const value = Reflect.get(event as object, 'eventId')\n return typeof value === 'string' && value.length > 0 ? value : createOperationId()\n } catch { return createOperationId() }\n}\n\nfunction requiredBoundary(registrations: readonly ObservationExporterRegistration[]): ObservationBoundary {\n let result: ObservationBoundary = 'none'\n for (const registration of registrations) {\n if (registration.requirement === 'required'\n && BOUNDARY_RANK[registration.boundary] > BOUNDARY_RANK[result]) result = registration.boundary\n }\n return result\n}\n\nfunction validateRegistrations(\n mode: Observability['mode'],\n registrations: readonly ObservationExporterRegistration[],\n): readonly ObservationExporterRegistration[] {\n const ids = new Set<string>()\n for (const registration of registrations) {\n const id = registration.exporter?.id\n if (typeof id !== 'string' || !COMPONENT_ID_PATTERN.test(id)) {\n throw new TypeError('observation exporter id must be a safe 1-64 character identifier')\n }\n if (ids.has(id)) throw new TypeError(`duplicate observation exporter id: ${id}`)\n ids.add(id)\n if (registration.requirement !== 'required' && registration.requirement !== 'best-effort') {\n throw new TypeError(`observation exporter ${id} has an invalid requirement`)\n }\n if (!(registration.boundary in BOUNDARY_RANK)) throw new TypeError(`observation exporter ${id} has an invalid boundary`)\n const supported = registration.exporter.supportedBoundaries ?? ['none']\n if (typeof registration.exporter.export !== 'function') {\n throw new TypeError(`observation exporter ${id} has no export function`)\n }\n if (!supported.includes(registration.boundary)) {\n throw new TypeError(`observation exporter ${id} does not support ${registration.boundary}`)\n }\n if (mode === 'operational' && registration.requirement === 'required') {\n throw new TypeError('operational observation exporters must be best-effort')\n }\n }\n if (mode !== 'operational' && !registrations.some(registration => (\n registration.requirement === 'required' && registration.boundary !== 'none'\n ))) throw new TypeError(`${mode} observability requires a durable required exporter`)\n return Object.freeze(registrations.map(registration => Object.freeze({ ...registration })))\n}\n\nfunction deadlineSignal(timeoutMs: number, external?: AbortSignal): { signal: AbortSignal; clear(): void } {\n const controller = new AbortController()\n const timeout = setTimeout(() => controller.abort(new DOMException('observation deadline exceeded', 'TimeoutError')), timeoutMs)\n const abort = () => controller.abort(external?.reason ?? new DOMException('observation aborted', 'AbortError'))\n if (external?.aborted === true) abort()\n else external?.addEventListener('abort', abort, { once: true })\n return {\n signal: controller.signal,\n clear() { clearTimeout(timeout); external?.removeEventListener('abort', abort) },\n }\n}\n\nfunction raceAbort<T>(pending: Promise<T>, signal: AbortSignal): Promise<T> {\n if (signal.aborted) return Promise.reject(signal.reason ?? new Error('observation aborted'))\n return new Promise<T>((resolve, reject) => {\n const abort = () => { cleanup(); reject(signal.reason ?? new Error('observation aborted')) }\n const cleanup = () => signal.removeEventListener('abort', abort)\n signal.addEventListener('abort', abort, { once: true })\n void pending.then(\n value => { cleanup(); resolve(value) },\n error => { cleanup(); reject(error) },\n )\n })\n}\n\nfunction isTimeoutAbort(signal: AbortSignal): boolean {\n try {\n const reason = signal.reason\n return typeof reason === 'object' && reason !== null\n && Reflect.get(reason, 'name') === 'TimeoutError'\n } catch { return false }\n}\n\nfunction publicFlushResult(outcome: FlushOutcome): FlushResult {\n return Object.freeze({\n complete: outcome.complete,\n exportedEvents: outcome.exportedEvents,\n pendingEvents: outcome.pendingEvents,\n rejectedCritical: outcome.rejectedCritical,\n timedOut: outcome.timedOut,\n })\n}\n\nfunction sameEnvelope(left: ObservationEvent, right: ObservationEvent): boolean {\n return left.eventId === right.eventId && left.sequence === right.sequence\n && left.name === right.name && left.phase === right.phase\n && left.occurredAt === right.occurredAt && left.monotonicMs === right.monotonicMs\n && left.priority === right.priority\n && JSON.stringify(left.resource) === JSON.stringify(right.resource)\n && JSON.stringify(left.correlation) === JSON.stringify(right.correlation)\n}\n\nclass ObservationBus implements Observability {\n readonly mode: Observability['mode']\n readonly resource: ObservationResource\n private readonly registrations: readonly ObservationExporterRegistration[]\n private readonly processors: readonly ObservationProcessor[]\n private readonly options: Required<Pick<ObservabilityOptions,\n 'content' | 'includeErrorStacks' | 'minimumLogLevel' | 'maxQueueEvents' | 'maxQueueBytes'\n | 'maxBatchEvents' | 'maxBatchBytes' | 'flushTimeoutMs' | 'shutdownTimeoutMs'>>\n & Pick<ObservabilityOptions, 'redactors' | 'onHealthChange' | 'openSpan'>\n private readonly queue: QueueEntry[] = []\n private queueBytes = 0\n private closing = false\n private closed = false\n private shutdownPromise: Promise<FlushResult> | undefined\n private flushChain: Promise<void> = Promise.resolve()\n private readonly protectedFailures = new Set<string>()\n private readonly healthScope = createObservationRunScope()\n private readonly healthRunId = createOperationId()\n private readonly healthCorrelation = createCoreSpan({\n name: 'sdk.integration.request', runId: this.healthRunId,\n startedAt: new Date().toISOString(), monotonicMs: this.healthScope.monotonicMs(),\n }).correlation\n private readonly counters: MutableHealth = {\n accepted: 0, exported: 0, droppedVerbose: 0, droppedNormal: 0,\n criticalRejected: 0, processorFailures: 0, exporterFailures: 0,\n flushTimeouts: 0, requiredFailure: false,\n }\n\n constructor(input: ObservabilityOptions) {\n this.mode = input.mode ?? 'operational'\n if (!['operational', 'reliable', 'audit'].includes(this.mode)) throw new TypeError('invalid observation mode')\n this.resource = deepFreeze({\n sdkName: 'ai-agent-sdk',\n sdkVersion: input.resource?.sdkVersion ?? SDK_VERSION,\n ...input.resource?.serviceName === undefined ? {} : { serviceName: input.resource.serviceName },\n ...input.resource?.serviceVersion === undefined ? {} : { serviceVersion: input.resource.serviceVersion },\n runtime: input.resource?.runtime ?? 'unknown',\n })\n this.registrations = validateRegistrations(this.mode, input.exporters ?? [])\n const processorIds = new Set<string>()\n for (const processor of input.processors ?? []) {\n if (typeof processor.id !== 'string' || !COMPONENT_ID_PATTERN.test(processor.id)) {\n throw new TypeError('processor id must be a safe 1-64 character identifier')\n }\n if (processorIds.has(processor.id)) throw new TypeError(`duplicate observation processor id: ${processor.id}`)\n if (typeof processor.transform !== 'function') throw new TypeError(`observation processor ${processor.id} is invalid`)\n processorIds.add(processor.id)\n }\n this.processors = Object.freeze([...(input.processors ?? [])])\n if (!CONTENT_POLICIES.has(input.content ?? 'none')) throw new TypeError('invalid observation content policy')\n if (!LOG_LEVELS.has(input.minimumLogLevel ?? 'info')) throw new TypeError('invalid minimum log level')\n const redactorIds = new Set<string>()\n for (const redactor of input.redactors ?? []) {\n if (typeof redactor.id !== 'string' || !COMPONENT_ID_PATTERN.test(redactor.id)\n || typeof redactor.redact !== 'function') throw new TypeError('invalid observation content redactor')\n if (redactorIds.has(redactor.id)) throw new TypeError(`duplicate observation redactor id: ${redactor.id}`)\n redactorIds.add(redactor.id)\n }\n this.options = {\n content: input.content ?? 'none',\n includeErrorStacks: input.includeErrorStacks ?? false,\n minimumLogLevel: input.minimumLogLevel ?? 'info',\n maxQueueEvents: positiveSafeInteger(input.maxQueueEvents ?? DEFAULT_MAX_QUEUE_EVENTS, 'maxQueueEvents'),\n maxQueueBytes: positiveSafeInteger(input.maxQueueBytes ?? DEFAULT_MAX_QUEUE_BYTES, 'maxQueueBytes'),\n maxBatchEvents: positiveSafeInteger(input.maxBatchEvents ?? DEFAULT_MAX_BATCH_EVENTS, 'maxBatchEvents'),\n maxBatchBytes: positiveSafeInteger(input.maxBatchBytes ?? DEFAULT_MAX_BATCH_BYTES, 'maxBatchBytes'),\n flushTimeoutMs: positiveSafeInteger(input.flushTimeoutMs ?? DEFAULT_FLUSH_TIMEOUT_MS, 'flushTimeoutMs'),\n shutdownTimeoutMs: positiveSafeInteger(input.shutdownTimeoutMs ?? DEFAULT_SHUTDOWN_TIMEOUT_MS, 'shutdownTimeoutMs'),\n redactors: Object.freeze([...(input.redactors ?? [])]),\n ...input.onHealthChange === undefined ? {} : { onHealthChange: input.onHealthChange },\n ...input.openSpan === undefined ? {} : { openSpan: input.openSpan },\n }\n }\n\n openSpan(input: OpenObservationSpanInput): ObservationSpan {\n const backend = this.options.openSpan\n if (backend === undefined) return createCoreSpan(input)\n try {\n const span = snapshotObservationSpan(backend(input))\n if (span !== undefined) return span\n this.counters.processorFailures++\n this.recordFailure('span:invalid', new TypeError('invalid span'), 'observation span backend returned an invalid span', false)\n } catch (error) {\n this.counters.processorFailures++\n this.recordFailure('span:throw', error, 'observation span backend failed', false)\n }\n return createCoreSpan(input)\n }\n\n capture(event: ObservationEvent): CaptureReceipt {\n const eventId = eventIdOf(event)\n if (this.closing || this.closed) return receipt(eventId, 'rejected', 'none', 'closed')\n let processed: ObservationEvent\n try {\n processed = this.prepareEvent(event, false)\n } catch (error) {\n this.counters.processorFailures++\n this.counters.lastFailure = safeFailure(error, 'observation processor failed')\n this.notifyHealth()\n this.recordFailure('processor:capture', error, 'observation processor failed', true)\n return receipt(eventId, 'rejected', 'none', 'processor-failed')\n }\n const captured = this.enqueue(processed, false)\n if (captured.status !== 'accepted') return captured\n return this.stageExporters(processed, captured)\n }\n\n async checkpoint(event: ObservationEvent, signal?: AbortSignal): Promise<CaptureReceipt> {\n const captured = this.capture(event)\n if (captured.status !== 'accepted') return captured\n if (this.mode === 'operational') return captured\n const terminal = this.queue.find(entry => entry.event.eventId === captured.eventId)?.event\n if (terminal === undefined) return receipt(captured.eventId, 'rejected', 'none', 'exporter-unavailable')\n const targetIds = new Set(this.queue\n .filter(entry => entry.event.priority === 'critical'\n && entry.event.correlation.runId === terminal.correlation.runId\n && entry.event.sequence <= terminal.sequence)\n .map(entry => entry.event.eventId))\n const outcome = await this.scheduleFlush(targetIds, this.options.flushTimeoutMs, signal)\n if (!outcome.requiredComplete) return receipt(captured.eventId, 'rejected', 'none', 'exporter-unavailable')\n return receipt(captured.eventId, 'accepted', requiredBoundary(this.registrations))\n }\n\n logger(context?: LoggerContext): SdkLogger {\n return createBusLogger({\n minimumLevel: this.options.minimumLogLevel as LogLevel,\n resource: this.resource,\n emit: event => { this.capture(event) },\n }, context)\n }\n\n health(): ObservationHealthSnapshot {\n const state: ObservationHealthSnapshot['state'] = this.closed\n ? 'closed'\n : this.counters.requiredFailure || this.counters.criticalRejected > 0 || this.counters.flushTimeouts > 0\n ? 'failed'\n : this.counters.processorFailures > 0 || this.counters.exporterFailures > 0\n || this.counters.droppedVerbose > 0 || this.counters.droppedNormal > 0\n ? 'degraded'\n : 'healthy'\n return deepFreeze({\n state,\n queuedEvents: this.queue.length,\n queuedBytes: this.queueBytes,\n accepted: this.counters.accepted,\n exported: this.counters.exported,\n droppedVerbose: this.counters.droppedVerbose,\n droppedNormal: this.counters.droppedNormal,\n criticalRejected: this.counters.criticalRejected,\n processorFailures: this.counters.processorFailures,\n exporterFailures: this.counters.exporterFailures,\n flushTimeouts: this.counters.flushTimeouts,\n ...this.counters.lastExportAt === undefined ? {} : { lastExportAt: this.counters.lastExportAt },\n ...this.counters.lastFailure === undefined ? {} : { lastFailure: this.counters.lastFailure },\n })\n }\n\n flush(signal?: AbortSignal): Promise<FlushResult> {\n if (this.closed || this.closing) throw new TypeError('observability is closed')\n return this.scheduleFlush(\n new Set(this.queue.map(entry => entry.event.eventId)), this.options.flushTimeoutMs, signal,\n ).then(publicFlushResult)\n }\n\n shutdown(signal?: AbortSignal): Promise<FlushResult> {\n if (this.shutdownPromise !== undefined) return this.shutdownPromise\n this.closing = true\n const targetIds = new Set(this.queue.map(entry => entry.event.eventId))\n this.shutdownPromise = (async () => {\n const deadline = deadlineSignal(this.options.shutdownTimeoutMs, signal)\n let result: FlushResult\n try {\n result = publicFlushResult(await this.scheduleFlush(\n targetIds, this.options.shutdownTimeoutMs, deadline.signal,\n ))\n for (const registration of [...this.registrations].reverse()) {\n const shutdown = registration.exporter.shutdown\n if (shutdown === undefined) continue\n try { await raceAbort(Promise.resolve(shutdown.call(registration.exporter, deadline.signal)), deadline.signal) }\n catch (error) {\n this.recordExporterFailure(registration, error, false)\n result = Object.freeze({ ...result, complete: false })\n }\n }\n } finally {\n deadline.clear()\n this.closed = true\n this.notifyHealth()\n }\n return result\n })()\n return this.shutdownPromise\n }\n\n private prepareEvent(event: ObservationEvent, protectedPath: boolean): ObservationEvent {\n const privacy = {\n content: this.options.content,\n redactors: this.options.redactors ?? [],\n includeErrorStacks: this.options.includeErrorStacks,\n }\n let current = sanitizeObservationEvent(event, privacy)\n if (protectedPath) return current\n for (const processor of this.processors) {\n const next = processor.transform(current)\n if (next === undefined) throw new TypeError(`observation processor ${processor.id} returned undefined`)\n const sanitized = sanitizeObservationEvent(next, privacy)\n if (!sameEnvelope(current, sanitized)) {\n throw new TypeError(`observation processor ${processor.id} changed the immutable event envelope`)\n }\n current = sanitized\n }\n return current\n }\n\n private enqueue(event: ObservationEvent, protectedPath: boolean): CaptureReceipt {\n const bytes = serializedEventBytes(event)\n if (bytes > this.options.maxBatchBytes || bytes > this.options.maxQueueBytes\n || !this.makeCapacity(bytes, protectedPath)) {\n if (!protectedPath && event.priority === 'critical') this.counters.criticalRejected++\n if (!protectedPath) {\n this.counters.lastFailure = safeFailure(new RangeError('capacity'), 'observation queue capacity exhausted')\n this.notifyHealth()\n }\n return receipt(event.eventId, 'rejected', 'none', 'capacity')\n }\n this.queue.push({\n event, bytes, protected: protectedPath,\n pending: new Set(this.registrations.map(registration => registration.exporter.id)),\n })\n this.queueBytes += bytes\n this.counters.accepted++\n this.notifyHealth()\n return receipt(event.eventId, 'accepted')\n }\n\n private stageExporters(event: ObservationEvent, captured: CaptureReceipt): CaptureReceipt {\n const entry = this.queue.find(candidate => candidate.event.eventId === event.eventId)\n if (entry === undefined) return receipt(event.eventId, 'rejected', 'none', 'exporter-unavailable')\n let removedPending = false\n for (const registration of this.registrations) {\n const stage = registration.exporter.stage\n if (stage === undefined) continue\n try {\n const pending = stage.call(registration.exporter, event)\n if (pending !== undefined) void Promise.resolve(pending).catch(() => undefined)\n } catch (error) {\n this.recordExporterFailure(registration, error, false)\n entry.pending.delete(registration.exporter.id)\n removedPending = true\n if (registration.requirement === 'required') {\n this.removeEntry(entry, false)\n if (event.priority === 'critical') this.counters.criticalRejected++\n this.notifyHealth()\n return receipt(event.eventId, 'rejected', 'none', 'exporter-unavailable')\n }\n }\n }\n if (removedPending && entry.pending.size === 0) this.removeEntry(entry, false)\n return captured\n }\n\n private makeCapacity(incomingBytes: number, protectedPath: boolean): boolean {\n while (this.queue.length + 1 > this.options.maxQueueEvents\n || this.queueBytes + incomingBytes > this.options.maxQueueBytes) {\n let index = this.queue.findIndex(entry => entry.event.priority === 'verbose')\n if (index === -1) index = this.queue.findIndex(entry => entry.event.priority === 'normal')\n if (index === -1) return false\n const [removed] = this.queue.splice(index, 1)\n if (removed === undefined) return false\n this.queueBytes -= removed.bytes\n if (!protectedPath) {\n if (removed.event.priority === 'verbose') this.counters.droppedVerbose++\n else this.counters.droppedNormal++\n }\n }\n return true\n }\n\n private scheduleFlush(targetIds: ReadonlySet<string>, timeoutMs: number, signal?: AbortSignal): Promise<FlushOutcome> {\n let resolveResult!: (result: FlushOutcome) => void\n let rejectResult!: (error: unknown) => void\n const result = new Promise<FlushOutcome>((resolve, reject) => { resolveResult = resolve; rejectResult = reject })\n const task = async () => {\n try { resolveResult(await this.flushInternal(targetIds, timeoutMs, signal)) }\n catch (error) { rejectResult(error) }\n }\n this.flushChain = this.flushChain.then(task, task)\n return result\n }\n\n private async flushInternal(\n targetIds: ReadonlySet<string>,\n timeoutMs: number,\n external?: AbortSignal,\n ): Promise<FlushOutcome> {\n const beforeExported = this.counters.exported\n const deadline = deadlineSignal(timeoutMs, external)\n let failed = false\n let timedOut = false\n try {\n if (this.registrations.length === 0) {\n for (const entry of [...this.queue]) if (targetIds.has(entry.event.eventId)) this.removeEntry(entry, false)\n }\n for (const registration of this.registrations) {\n while (true) {\n const candidates = this.queue.filter(entry => (\n targetIds.has(entry.event.eventId) && entry.pending.has(registration.exporter.id)\n ))\n if (candidates.length === 0) break\n const entries: QueueEntry[] = []\n let bytes = 0\n for (const entry of candidates) {\n if (entries.length >= this.options.maxBatchEvents || bytes + entry.bytes > this.options.maxBatchBytes) break\n entries.push(entry)\n bytes += entry.bytes\n }\n if (entries.length === 0) break\n const batch: ObservationBatch = deepFreeze({\n schemaVersion: 1,\n batchId: createOperationId(),\n createdAt: new Date().toISOString(),\n events: entries.map(entry => entry.event),\n })\n let ack: ExportAck\n try {\n ack = await raceAbort(Promise.resolve(registration.exporter.export(batch, deadline.signal)), deadline.signal)\n if (ack.batchId !== batch.batchId || ack.accepted !== true) {\n throw new TypeError(`observation exporter ${registration.exporter.id} returned an invalid acknowledgment`)\n }\n } catch (error) {\n failed = true\n timedOut ||= isTimeoutAbort(deadline.signal)\n this.recordExporterFailure(registration, error, true)\n if (registration.requirement === 'best-effort') {\n for (const entry of entries) {\n entry.pending.delete(registration.exporter.id)\n if (entry.pending.size === 0) this.removeEntry(entry, false)\n }\n }\n break\n }\n this.counters.lastExportAt = new Date().toISOString()\n for (const entry of entries) {\n entry.pending.delete(registration.exporter.id)\n if (entry.pending.size === 0) this.removeEntry(entry, true)\n }\n this.notifyHealth()\n }\n }\n } finally {\n if (isTimeoutAbort(deadline.signal)) {\n timedOut = true\n this.counters.flushTimeouts++\n this.counters.lastFailure = safeFailure(deadline.signal.reason, 'observation flush timed out')\n this.notifyHealth()\n }\n deadline.clear()\n }\n const pendingEntries = this.queue.filter(entry => targetIds.has(entry.event.eventId))\n const requiredIds = this.registrations\n .filter(registration => registration.requirement === 'required')\n .map(registration => registration.exporter.id)\n const requiredComplete = pendingEntries.every(entry => requiredIds.every(id => !entry.pending.has(id)))\n return Object.freeze({\n complete: !failed && !timedOut && pendingEntries.length === 0,\n requiredComplete,\n exportedEvents: this.counters.exported - beforeExported,\n pendingEvents: pendingEntries.length,\n rejectedCritical: this.counters.criticalRejected,\n timedOut,\n })\n }\n\n private removeEntry(entry: QueueEntry, exported: boolean): void {\n const index = this.queue.indexOf(entry)\n if (index === -1) return\n this.queue.splice(index, 1)\n this.queueBytes -= entry.bytes\n if (exported) this.counters.exported++\n }\n\n private recordExporterFailure(\n registration: ObservationExporterRegistration,\n error: unknown,\n emitProtected: boolean,\n ): void {\n this.counters.exporterFailures++\n if (registration.requirement === 'required') this.counters.requiredFailure = true\n this.counters.lastFailure = safeFailure(error, 'observation exporter failed')\n this.notifyHealth()\n if (emitProtected) this.recordFailure(\n `exporter:${registration.exporter.id}`, error, 'observation exporter failed', true,\n )\n }\n\n private recordFailure(key: string, error: unknown, message: string, emit: boolean): void {\n this.counters.lastFailure = safeFailure(error, message)\n this.notifyHealth()\n if (!emit || this.protectedFailures.has(key) || this.closing || this.closed) return\n this.protectedFailures.add(key)\n try {\n const event = this.prepareEvent({\n schemaVersion: 1,\n eventId: createOperationId(),\n sequence: this.healthScope.nextSequence(),\n name: 'sdk.observer.failure',\n phase: 'point',\n occurredAt: new Date().toISOString(),\n monotonicMs: this.healthScope.monotonicMs(),\n priority: 'critical',\n resource: this.resource,\n correlation: this.healthCorrelation,\n data: {\n observerId: key,\n failureKind: 'contained',\n count: 1,\n error: { ...this.counters.lastFailure },\n },\n }, true)\n this.enqueue(event, true)\n } catch { /* health counters are the final protected path */ }\n }\n\n private notifyHealth(): void {\n const callback = this.options.onHealthChange\n if (callback === undefined) return\n try { callback(this.health()) } catch { /* emergency callback is separately contained */ }\n }\n}\n\n/** Create one Universal observation bus. Construction validates every durability claim. */\nexport function createObservability(options: ObservabilityOptions = {}): Observability {\n return new ObservationBus(options)\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"bus.js","names":[],"sources":["../../src/observability/bus.ts"],"sourcesContent":["import {\n SDK_VERSION,\n deepFreeze,\n} from '../primitives/index.ts'\nimport {\n createCoreSpan,\n createObservationRunScope,\n createOperationId,\n safeErrorRecord,\n snapshotObservationSpan,\n type CaptureReceipt,\n type ObservationBoundary,\n type ObservationEvent,\n type ObservationResource,\n type ObservationSpan,\n type OpenObservationSpanInput,\n type SafeErrorRecord,\n} from '../observation/index.ts'\nimport { createBusLogger } from './logger.ts'\nimport { sanitizeObservationEvent, serializedEventBytes } from './privacy.ts'\nimport type {\n ExportAck,\n FlushResult,\n LoggerContext,\n LogLevel,\n ObservationBatch,\n ObservationExporterRegistration,\n ObservationHealthSnapshot,\n ObservationProcessor,\n Observability,\n ObservabilityOptions,\n SdkLogger,\n} from './types.ts'\n\nconst DEFAULT_MAX_QUEUE_EVENTS = 10_000\nconst DEFAULT_MAX_QUEUE_BYTES = 16 * 1024 * 1024\nconst DEFAULT_MAX_BATCH_EVENTS = 256\nconst DEFAULT_MAX_BATCH_BYTES = 512 * 1024\nconst DEFAULT_FLUSH_TIMEOUT_MS = 10_000\nconst DEFAULT_SHUTDOWN_TIMEOUT_MS = 30_000\n\ninterface QueueEntry {\n readonly event: ObservationEvent\n readonly bytes: number\n readonly pending: Set<string>\n readonly protected: boolean\n}\n\ninterface MutableHealth {\n accepted: number\n exported: number\n droppedVerbose: number\n droppedNormal: number\n criticalRejected: number\n processorFailures: number\n exporterFailures: number\n flushTimeouts: number\n lastExportAt?: string\n lastFailure?: SafeErrorRecord\n requiredFailure: boolean\n}\n\ninterface FlushOutcome extends FlushResult {\n readonly requiredComplete: boolean\n}\n\nconst BOUNDARY_RANK: Readonly<Record<ObservationBoundary, number>> = {\n none: 0, 'local-durable': 1, 'remote-acknowledged': 2,\n}\nconst SAFE_FAILURE_CODES = new Set([\n 'ABORT_ERR', 'ECONNREFUSED', 'ECONNRESET', 'EHOSTUNREACH', 'ENETUNREACH',\n 'ETIMEDOUT', 'OBSERVABILITY_EXPORT_FAILED', 'OBSERVABILITY_FLUSH_TIMEOUT',\n 'OBSERVABILITY_PROCESSOR_FAILED', 'OTEL_PROVIDER_UNCONFIGURED',\n])\nconst COMPONENT_ID_PATTERN = /^[A-Za-z0-9](?:[A-Za-z0-9._-]{0,63})$/\nconst CONTENT_POLICIES = new Set(['none', 'metadata', 'redacted', 'full'])\nconst LOG_LEVELS = new Set(['trace', 'debug', 'info', 'warn', 'error', 'fatal'])\n\nfunction positiveSafeInteger(value: number, field: string): number {\n if (!Number.isSafeInteger(value) || value < 1) throw new RangeError(`${field} must be a positive safe integer`)\n return value\n}\n\nfunction safeFailure(error: unknown, message: string): SafeErrorRecord {\n const source = safeErrorRecord(error)\n return deepFreeze({\n type: ['AbortError', 'Error', 'RangeError', 'TypeError'].includes(source.type) ? source.type : 'Error',\n message,\n ...source.code !== undefined && SAFE_FAILURE_CODES.has(source.code) ? { code: source.code } : {},\n ...source.retryable === undefined ? {} : { retryable: source.retryable },\n ...source.status === undefined ? {} : { status: source.status },\n })\n}\n\nfunction receipt(\n eventId: string,\n status: CaptureReceipt['status'],\n boundary: ObservationBoundary = 'none',\n reason?: CaptureReceipt['reason'],\n): CaptureReceipt {\n return Object.freeze({\n eventId, status, durable: status === 'accepted' && boundary !== 'none', boundary,\n ...reason === undefined ? {} : { reason },\n })\n}\n\nfunction eventIdOf(event: unknown): string {\n try {\n const value = Reflect.get(event as object, 'eventId')\n return typeof value === 'string' && value.length > 0 ? value : createOperationId()\n } catch { return createOperationId() }\n}\n\nfunction requiredBoundary(registrations: readonly ObservationExporterRegistration[]): ObservationBoundary {\n let result: ObservationBoundary = 'none'\n for (const registration of registrations) {\n if (registration.requirement === 'required'\n && BOUNDARY_RANK[registration.boundary] > BOUNDARY_RANK[result]) result = registration.boundary\n }\n return result\n}\n\nfunction validateRegistrations(\n mode: Observability['mode'],\n registrations: readonly ObservationExporterRegistration[],\n): readonly ObservationExporterRegistration[] {\n const ids = new Set<string>()\n for (const registration of registrations) {\n const id = registration.exporter?.id\n if (typeof id !== 'string' || !COMPONENT_ID_PATTERN.test(id)) {\n throw new TypeError('observation exporter id must be a safe 1-64 character identifier')\n }\n if (ids.has(id)) throw new TypeError(`duplicate observation exporter id: ${id}`)\n ids.add(id)\n if (registration.requirement !== 'required' && registration.requirement !== 'best-effort') {\n throw new TypeError(`observation exporter ${id} has an invalid requirement`)\n }\n if (!(registration.boundary in BOUNDARY_RANK)) throw new TypeError(`observation exporter ${id} has an invalid boundary`)\n const supported = registration.exporter.supportedBoundaries ?? ['none']\n if (typeof registration.exporter.export !== 'function') {\n throw new TypeError(`observation exporter ${id} has no export function`)\n }\n if (!supported.includes(registration.boundary)) {\n throw new TypeError(`observation exporter ${id} does not support ${registration.boundary}`)\n }\n if (mode === 'operational' && registration.requirement === 'required') {\n throw new TypeError('operational observation exporters must be best-effort')\n }\n }\n if (mode !== 'operational' && !registrations.some(registration => (\n registration.requirement === 'required' && registration.boundary !== 'none'\n ))) throw new TypeError(`${mode} observability requires a durable required exporter`)\n return Object.freeze(registrations.map(registration => Object.freeze({ ...registration })))\n}\n\nfunction deadlineSignal(timeoutMs: number, external?: AbortSignal): { signal: AbortSignal; clear(): void } {\n const controller = new AbortController()\n const timeout = setTimeout(() => controller.abort(new DOMException('observation deadline exceeded', 'TimeoutError')), timeoutMs)\n const abort = () => controller.abort(external?.reason ?? new DOMException('observation aborted', 'AbortError'))\n if (external?.aborted === true) abort()\n else external?.addEventListener('abort', abort, { once: true })\n return {\n signal: controller.signal,\n clear() { clearTimeout(timeout); external?.removeEventListener('abort', abort) },\n }\n}\n\nfunction raceAbort<T>(pending: Promise<T>, signal: AbortSignal): Promise<T> {\n if (signal.aborted) return Promise.reject(signal.reason ?? new Error('observation aborted'))\n return new Promise<T>((resolve, reject) => {\n const abort = () => { cleanup(); reject(signal.reason ?? new Error('observation aborted')) }\n const cleanup = () => signal.removeEventListener('abort', abort)\n signal.addEventListener('abort', abort, { once: true })\n void pending.then(\n value => { cleanup(); resolve(value) },\n error => { cleanup(); reject(error) },\n )\n })\n}\n\nfunction isTimeoutAbort(signal: AbortSignal): boolean {\n try {\n const reason = signal.reason\n return typeof reason === 'object' && reason !== null\n && Reflect.get(reason, 'name') === 'TimeoutError'\n } catch { return false }\n}\n\nfunction publicFlushResult(outcome: FlushOutcome): FlushResult {\n return Object.freeze({\n complete: outcome.complete,\n exportedEvents: outcome.exportedEvents,\n pendingEvents: outcome.pendingEvents,\n rejectedCritical: outcome.rejectedCritical,\n timedOut: outcome.timedOut,\n })\n}\n\nfunction sameEnvelope(left: ObservationEvent, right: ObservationEvent): boolean {\n return left.eventId === right.eventId && left.sequence === right.sequence\n && left.name === right.name && left.phase === right.phase\n && left.occurredAt === right.occurredAt && left.monotonicMs === right.monotonicMs\n && left.priority === right.priority\n && JSON.stringify(left.resource) === JSON.stringify(right.resource)\n && JSON.stringify(left.correlation) === JSON.stringify(right.correlation)\n}\n\nclass ObservationBus implements Observability {\n readonly mode: Observability['mode']\n readonly resource: ObservationResource\n private readonly registrations: readonly ObservationExporterRegistration[]\n private readonly processors: readonly ObservationProcessor[]\n private readonly options: Required<Pick<ObservabilityOptions,\n 'content' | 'includeErrorStacks' | 'minimumLogLevel' | 'maxQueueEvents' | 'maxQueueBytes'\n | 'maxBatchEvents' | 'maxBatchBytes' | 'flushTimeoutMs' | 'shutdownTimeoutMs'>>\n & Pick<ObservabilityOptions, 'redactors' | 'onHealthChange' | 'openSpan'>\n private readonly queue: QueueEntry[] = []\n private queueBytes = 0\n private closing = false\n private closed = false\n private shutdownPromise: Promise<FlushResult> | undefined\n private flushChain: Promise<void> = Promise.resolve()\n private readonly protectedFailures = new Set<string>()\n private readonly healthScope = createObservationRunScope()\n private readonly healthRunId = createOperationId()\n private readonly healthCorrelation = createCoreSpan({\n name: 'sdk.integration.request', runId: this.healthRunId,\n startedAt: new Date().toISOString(), monotonicMs: this.healthScope.monotonicMs(),\n }).correlation\n private readonly counters: MutableHealth = {\n accepted: 0, exported: 0, droppedVerbose: 0, droppedNormal: 0,\n criticalRejected: 0, processorFailures: 0, exporterFailures: 0,\n flushTimeouts: 0, requiredFailure: false,\n }\n\n constructor(input: ObservabilityOptions) {\n this.mode = input.mode ?? 'operational'\n if (!['operational', 'reliable', 'audit'].includes(this.mode)) throw new TypeError('invalid observation mode')\n this.resource = deepFreeze({\n sdkName: 'ai-agent-sdk',\n sdkVersion: input.resource?.sdkVersion ?? SDK_VERSION,\n ...input.resource?.serviceName === undefined ? {} : { serviceName: input.resource.serviceName },\n ...input.resource?.serviceVersion === undefined ? {} : { serviceVersion: input.resource.serviceVersion },\n runtime: input.resource?.runtime ?? 'unknown',\n })\n this.registrations = validateRegistrations(this.mode, input.exporters ?? [])\n const processorIds = new Set<string>()\n for (const processor of input.processors ?? []) {\n if (typeof processor.id !== 'string' || !COMPONENT_ID_PATTERN.test(processor.id)) {\n throw new TypeError('processor id must be a safe 1-64 character identifier')\n }\n if (processorIds.has(processor.id)) throw new TypeError(`duplicate observation processor id: ${processor.id}`)\n if (typeof processor.transform !== 'function') throw new TypeError(`observation processor ${processor.id} is invalid`)\n processorIds.add(processor.id)\n }\n this.processors = Object.freeze([...(input.processors ?? [])])\n if (!CONTENT_POLICIES.has(input.content ?? 'none')) throw new TypeError('invalid observation content policy')\n if (!LOG_LEVELS.has(input.minimumLogLevel ?? 'info')) throw new TypeError('invalid minimum log level')\n const redactorIds = new Set<string>()\n for (const redactor of input.redactors ?? []) {\n if (typeof redactor.id !== 'string' || !COMPONENT_ID_PATTERN.test(redactor.id)\n || typeof redactor.redact !== 'function') throw new TypeError('invalid observation content redactor')\n if (redactorIds.has(redactor.id)) throw new TypeError(`duplicate observation redactor id: ${redactor.id}`)\n redactorIds.add(redactor.id)\n }\n this.options = {\n content: input.content ?? 'none',\n includeErrorStacks: input.includeErrorStacks ?? false,\n minimumLogLevel: input.minimumLogLevel ?? 'info',\n maxQueueEvents: positiveSafeInteger(input.maxQueueEvents ?? DEFAULT_MAX_QUEUE_EVENTS, 'maxQueueEvents'),\n maxQueueBytes: positiveSafeInteger(input.maxQueueBytes ?? DEFAULT_MAX_QUEUE_BYTES, 'maxQueueBytes'),\n maxBatchEvents: positiveSafeInteger(input.maxBatchEvents ?? DEFAULT_MAX_BATCH_EVENTS, 'maxBatchEvents'),\n maxBatchBytes: positiveSafeInteger(input.maxBatchBytes ?? DEFAULT_MAX_BATCH_BYTES, 'maxBatchBytes'),\n flushTimeoutMs: positiveSafeInteger(input.flushTimeoutMs ?? DEFAULT_FLUSH_TIMEOUT_MS, 'flushTimeoutMs'),\n shutdownTimeoutMs: positiveSafeInteger(input.shutdownTimeoutMs ?? DEFAULT_SHUTDOWN_TIMEOUT_MS, 'shutdownTimeoutMs'),\n redactors: Object.freeze([...(input.redactors ?? [])]),\n ...input.onHealthChange === undefined ? {} : { onHealthChange: input.onHealthChange },\n ...input.openSpan === undefined ? {} : { openSpan: input.openSpan },\n }\n }\n\n openSpan(input: OpenObservationSpanInput): ObservationSpan {\n const backend = this.options.openSpan\n if (backend === undefined) return createCoreSpan(input)\n try {\n const span = snapshotObservationSpan(backend(input))\n if (span !== undefined) return span\n this.counters.processorFailures++\n this.recordFailure('span:invalid', new TypeError('invalid span'), 'observation span backend returned an invalid span', false)\n } catch (error) {\n this.counters.processorFailures++\n this.recordFailure('span:throw', error, 'observation span backend failed', false)\n }\n return createCoreSpan(input)\n }\n\n capture(event: ObservationEvent): CaptureReceipt {\n const eventId = eventIdOf(event)\n if (this.closing || this.closed) return receipt(eventId, 'rejected', 'none', 'closed')\n let processed: ObservationEvent\n try {\n processed = this.prepareEvent(event, false)\n } catch (error) {\n this.counters.processorFailures++\n this.counters.lastFailure = safeFailure(error, 'observation processor failed')\n this.notifyHealth()\n this.recordFailure('processor:capture', error, 'observation processor failed', true)\n return receipt(eventId, 'rejected', 'none', 'processor-failed')\n }\n const captured = this.enqueue(processed, false)\n if (captured.status !== 'accepted') return captured\n return this.stageExporters(processed, captured)\n }\n\n async checkpoint(event: ObservationEvent, signal?: AbortSignal): Promise<CaptureReceipt> {\n const captured = this.capture(event)\n if (captured.status !== 'accepted') return captured\n if (this.mode === 'operational') return captured\n const terminal = this.queue.find(entry => entry.event.eventId === captured.eventId)?.event\n if (terminal === undefined) return receipt(captured.eventId, 'rejected', 'none', 'exporter-unavailable')\n const targetIds = new Set(this.queue\n .filter(entry => entry.event.priority === 'critical'\n && entry.event.correlation.runId === terminal.correlation.runId\n && entry.event.sequence <= terminal.sequence)\n .map(entry => entry.event.eventId))\n const outcome = await this.scheduleFlush(targetIds, this.options.flushTimeoutMs, signal)\n if (!outcome.requiredComplete) return receipt(captured.eventId, 'rejected', 'none', 'exporter-unavailable')\n return receipt(captured.eventId, 'accepted', requiredBoundary(this.registrations))\n }\n\n logger(context?: LoggerContext): SdkLogger {\n return createBusLogger({\n minimumLevel: this.options.minimumLogLevel as LogLevel,\n resource: this.resource,\n emit: event => { this.capture(event) },\n }, context)\n }\n\n health(): ObservationHealthSnapshot {\n const state: ObservationHealthSnapshot['state'] = this.closed\n ? 'closed'\n : this.counters.requiredFailure || this.counters.criticalRejected > 0 || this.counters.flushTimeouts > 0\n ? 'failed'\n : this.counters.processorFailures > 0 || this.counters.exporterFailures > 0\n || this.counters.droppedVerbose > 0 || this.counters.droppedNormal > 0\n ? 'degraded'\n : 'healthy'\n return deepFreeze({\n state,\n queuedEvents: this.queue.length,\n queuedBytes: this.queueBytes,\n accepted: this.counters.accepted,\n exported: this.counters.exported,\n droppedVerbose: this.counters.droppedVerbose,\n droppedNormal: this.counters.droppedNormal,\n criticalRejected: this.counters.criticalRejected,\n processorFailures: this.counters.processorFailures,\n exporterFailures: this.counters.exporterFailures,\n flushTimeouts: this.counters.flushTimeouts,\n ...this.counters.lastExportAt === undefined ? {} : { lastExportAt: this.counters.lastExportAt },\n ...this.counters.lastFailure === undefined ? {} : { lastFailure: this.counters.lastFailure },\n })\n }\n\n flush(signal?: AbortSignal): Promise<FlushResult> {\n if (this.closed || this.closing) throw new TypeError('observability is closed')\n return this.scheduleFlush(\n new Set(this.queue.map(entry => entry.event.eventId)), this.options.flushTimeoutMs, signal,\n ).then(publicFlushResult)\n }\n\n shutdown(signal?: AbortSignal): Promise<FlushResult> {\n if (this.shutdownPromise !== undefined) return this.shutdownPromise\n this.closing = true\n const targetIds = new Set(this.queue.map(entry => entry.event.eventId))\n this.shutdownPromise = (async () => {\n const deadline = deadlineSignal(this.options.shutdownTimeoutMs, signal)\n let result: FlushResult\n try {\n result = publicFlushResult(await this.scheduleFlush(\n targetIds, this.options.shutdownTimeoutMs, deadline.signal,\n ))\n for (const registration of [...this.registrations].reverse()) {\n const shutdown = registration.exporter.shutdown\n if (shutdown === undefined) continue\n try { await raceAbort(Promise.resolve(shutdown.call(registration.exporter, deadline.signal)), deadline.signal) }\n catch (error) {\n this.recordExporterFailure(registration, error, false)\n result = Object.freeze({ ...result, complete: false })\n }\n }\n } finally {\n deadline.clear()\n this.closed = true\n this.notifyHealth()\n }\n return result\n })()\n return this.shutdownPromise\n }\n\n private prepareEvent(event: ObservationEvent, protectedPath: boolean): ObservationEvent {\n const privacy = {\n content: this.options.content,\n redactors: this.options.redactors ?? [],\n includeErrorStacks: this.options.includeErrorStacks,\n }\n let current = sanitizeObservationEvent(event, privacy)\n if (protectedPath) return current\n for (const processor of this.processors) {\n const next = processor.transform(current)\n if (next === undefined) throw new TypeError(`observation processor ${processor.id} returned undefined`)\n const sanitized = sanitizeObservationEvent(next, privacy)\n if (!sameEnvelope(current, sanitized)) {\n throw new TypeError(`observation processor ${processor.id} changed the immutable event envelope`)\n }\n current = sanitized\n }\n return current\n }\n\n private enqueue(event: ObservationEvent, protectedPath: boolean): CaptureReceipt {\n const bytes = serializedEventBytes(event)\n if (bytes > this.options.maxBatchBytes || bytes > this.options.maxQueueBytes\n || !this.makeCapacity(bytes, protectedPath)) {\n if (!protectedPath && event.priority === 'critical') this.counters.criticalRejected++\n if (!protectedPath) {\n this.counters.lastFailure = safeFailure(new RangeError('capacity'), 'observation queue capacity exhausted')\n this.notifyHealth()\n }\n return receipt(event.eventId, 'rejected', 'none', 'capacity')\n }\n this.queue.push({\n event, bytes, protected: protectedPath,\n pending: new Set(this.registrations.map(registration => registration.exporter.id)),\n })\n this.queueBytes += bytes\n this.counters.accepted++\n this.notifyHealth()\n return receipt(event.eventId, 'accepted')\n }\n\n private stageExporters(event: ObservationEvent, captured: CaptureReceipt): CaptureReceipt {\n const entry = this.queue.find(candidate => candidate.event.eventId === event.eventId)\n if (entry === undefined) return receipt(event.eventId, 'rejected', 'none', 'exporter-unavailable')\n let removedPending = false\n for (const registration of this.registrations) {\n const stage = registration.exporter.stage\n if (stage === undefined) continue\n try {\n const pending = stage.call(registration.exporter, event)\n if (pending !== undefined) void Promise.resolve(pending).catch(() => undefined)\n } catch (error) {\n this.recordExporterFailure(registration, error, false)\n entry.pending.delete(registration.exporter.id)\n removedPending = true\n if (registration.requirement === 'required') {\n this.removeEntry(entry, false)\n if (event.priority === 'critical') this.counters.criticalRejected++\n this.notifyHealth()\n return receipt(event.eventId, 'rejected', 'none', 'exporter-unavailable')\n }\n }\n }\n if (removedPending && entry.pending.size === 0) this.removeEntry(entry, false)\n return captured\n }\n\n private makeCapacity(incomingBytes: number, protectedPath: boolean): boolean {\n while (this.queue.length + 1 > this.options.maxQueueEvents\n || this.queueBytes + incomingBytes > this.options.maxQueueBytes) {\n let index = this.queue.findIndex(entry => entry.event.priority === 'verbose')\n if (index === -1) index = this.queue.findIndex(entry => entry.event.priority === 'normal')\n if (index === -1) return false\n const [removed] = this.queue.splice(index, 1)\n if (removed === undefined) return false\n this.queueBytes -= removed.bytes\n if (!protectedPath) {\n if (removed.event.priority === 'verbose') this.counters.droppedVerbose++\n else this.counters.droppedNormal++\n }\n }\n return true\n }\n\n private scheduleFlush(targetIds: ReadonlySet<string>, timeoutMs: number, signal?: AbortSignal): Promise<FlushOutcome> {\n let resolveResult!: (result: FlushOutcome) => void\n let rejectResult!: (error: unknown) => void\n const result = new Promise<FlushOutcome>((resolve, reject) => { resolveResult = resolve; rejectResult = reject })\n const task = async () => {\n try { resolveResult(await this.flushInternal(targetIds, timeoutMs, signal)) }\n catch (error) { rejectResult(error) }\n }\n this.flushChain = this.flushChain.then(task, task)\n return result\n }\n\n private async flushInternal(\n targetIds: ReadonlySet<string>,\n timeoutMs: number,\n external?: AbortSignal,\n ): Promise<FlushOutcome> {\n const beforeExported = this.counters.exported\n const deadline = deadlineSignal(timeoutMs, external)\n let failed = false\n let timedOut = false\n try {\n if (this.registrations.length === 0) {\n for (const entry of [...this.queue]) if (targetIds.has(entry.event.eventId)) this.removeEntry(entry, false)\n }\n for (const registration of this.registrations) {\n while (true) {\n const candidates = this.queue.filter(entry => (\n targetIds.has(entry.event.eventId) && entry.pending.has(registration.exporter.id)\n ))\n if (candidates.length === 0) break\n const entries: QueueEntry[] = []\n let bytes = 0\n for (const entry of candidates) {\n if (entries.length >= this.options.maxBatchEvents || bytes + entry.bytes > this.options.maxBatchBytes) break\n entries.push(entry)\n bytes += entry.bytes\n }\n if (entries.length === 0) break\n const batch: ObservationBatch = deepFreeze({\n schemaVersion: 1,\n batchId: createOperationId(),\n createdAt: new Date().toISOString(),\n events: entries.map(entry => entry.event),\n })\n let ack: ExportAck\n try {\n ack = await raceAbort(Promise.resolve(registration.exporter.export(batch, deadline.signal)), deadline.signal)\n if (ack.batchId !== batch.batchId || ack.accepted !== true) {\n throw new TypeError(`observation exporter ${registration.exporter.id} returned an invalid acknowledgment`)\n }\n } catch (error) {\n failed = true\n timedOut ||= isTimeoutAbort(deadline.signal)\n this.recordExporterFailure(registration, error, true)\n if (registration.requirement === 'best-effort') {\n for (const entry of entries) {\n entry.pending.delete(registration.exporter.id)\n if (entry.pending.size === 0) this.removeEntry(entry, false)\n }\n }\n break\n }\n this.counters.lastExportAt = new Date().toISOString()\n for (const entry of entries) {\n entry.pending.delete(registration.exporter.id)\n if (entry.pending.size === 0) this.removeEntry(entry, true)\n }\n this.notifyHealth()\n }\n }\n } finally {\n if (isTimeoutAbort(deadline.signal)) {\n timedOut = true\n this.counters.flushTimeouts++\n this.counters.lastFailure = safeFailure(deadline.signal.reason, 'observation flush timed out')\n this.notifyHealth()\n }\n deadline.clear()\n }\n const pendingEntries = this.queue.filter(entry => targetIds.has(entry.event.eventId))\n const requiredIds = this.registrations\n .filter(registration => registration.requirement === 'required')\n .map(registration => registration.exporter.id)\n const requiredComplete = pendingEntries.every(entry => requiredIds.every(id => !entry.pending.has(id)))\n return Object.freeze({\n complete: !failed && !timedOut && pendingEntries.length === 0,\n requiredComplete,\n exportedEvents: this.counters.exported - beforeExported,\n pendingEvents: pendingEntries.length,\n rejectedCritical: this.counters.criticalRejected,\n timedOut,\n })\n }\n\n private removeEntry(entry: QueueEntry, exported: boolean): void {\n const index = this.queue.indexOf(entry)\n if (index === -1) return\n this.queue.splice(index, 1)\n this.queueBytes -= entry.bytes\n if (exported) this.counters.exported++\n }\n\n private recordExporterFailure(\n registration: ObservationExporterRegistration,\n error: unknown,\n emitProtected: boolean,\n ): void {\n this.counters.exporterFailures++\n if (registration.requirement === 'required') this.counters.requiredFailure = true\n this.counters.lastFailure = safeFailure(error, 'observation exporter failed')\n this.notifyHealth()\n if (emitProtected) this.recordFailure(\n `exporter:${registration.exporter.id}`, error, 'observation exporter failed', true,\n )\n }\n\n private recordFailure(key: string, error: unknown, message: string, emit: boolean): void {\n this.counters.lastFailure = safeFailure(error, message)\n this.notifyHealth()\n if (!emit || this.protectedFailures.has(key) || this.closing || this.closed) return\n this.protectedFailures.add(key)\n try {\n const event = this.prepareEvent({\n schemaVersion: 1,\n eventId: createOperationId(),\n sequence: this.healthScope.nextSequence(),\n name: 'sdk.observer.failure',\n phase: 'point',\n occurredAt: new Date().toISOString(),\n monotonicMs: this.healthScope.monotonicMs(),\n priority: 'critical',\n resource: this.resource,\n correlation: this.healthCorrelation,\n data: {\n observerId: key,\n failureKind: 'contained',\n count: 1,\n error: { ...this.counters.lastFailure },\n },\n }, true)\n this.enqueue(event, true)\n } catch { /* health counters are the final protected path */ }\n }\n\n private notifyHealth(): void {\n const callback = this.options.onHealthChange\n if (callback === undefined) return\n try { callback(this.health()) } catch { /* emergency callback is separately contained */ }\n }\n}\n\n/** Create one Universal observation bus. Construction validates every durability claim. */\nexport function createObservability(options: ObservabilityOptions = {}): Observability {\n return new ObservationBus(options)\n}\n"],"mappings":"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"}
@@ -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.9";
3
+ declare const SDK_VERSION = "0.1.10";
4
4
  //#endregion
5
5
  export { SDK_VERSION };
6
6
  //# sourceMappingURL=version.d.ts.map
@@ -1,2 +1,2 @@
1
- const e=`0.1.9`;export{e as SDK_VERSION};
1
+ const e=`0.1.10`;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.9'\n"],"mappings":"AACA,MAAa,EAAc"}
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.10'\n"],"mappings":"AACA,MAAa,EAAc"}
@@ -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.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};
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.10`,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
@@ -1 +1 @@
1
- {"version":3,"file":"registry.js","names":[],"sources":["../../src/runtime/registry.ts"],"sourcesContent":["/**\n * The adapter registry and the streaming call API.\n *\n * This is the deepseek-harness `LlmRuntime` with its dependency-injection\n * framework removed: a plain `Map` for routes, an ordered array for the\n * interception point that was a cordis waterfall, and a listener set for the\n * topology event. What is kept is everything that made it trustworthy  E * all-or-nothing validating registration, an atomic route swap, prepare/dispatch\n * generation binding, and a single failure funnel at the adapter boundary.\n *\n * @module ai-agent-sdk/core/runtime/registry\n */\n\nimport type { ModelAdapter } from '../contract/adapter.ts'\nimport {\n callConfigEquals,\n type CallConfig,\n type CallConfigAdapterDefaults,\n} from '../contract/call-config.ts'\nimport type { GenerateOptions } from '../contract/generate-options.ts'\nimport type {\n ModelContext,\n ModelCatalogOptions,\n ModelCatalogSnapshot,\n ModelInfo,\n ModelModality,\n ProviderInfo,\n ResolvedModelInfo,\n RuntimeDefaults,\n} from '../contract/model-info.ts'\nimport { resolveRetryPolicy, type ResolvedRetryPolicy } from '../contract/retry-policy.ts'\nimport { ModelError, REGISTRY_ERROR_CODES } from '../errors/model-error.ts'\nimport { deepFreeze } from '../primitives/freeze.ts'\nimport { SDK_VERSION } from '../primitives/version.ts'\nimport type { ObservationResource } from '../observation/event.ts'\nimport type { ObservationPort } from '../observation/port.ts'\nimport type { ModelCallHandle, ModelInvocationContext } from '../observation/report.ts'\nimport type { StreamChunk } from '../stream/chunk.ts'\nimport { createModelCallHandle } from './model-call-handle.ts'\nimport { normalizeResolvedModelInfo, resolveCallWithModelInfo,\n validateCatalogModels, validateModelCatalogSnapshot } from './model-metadata.ts'\nimport { streamAdapter, type PreparedDispatch,\n type RuntimeAdapterRegistration } from './model-stream.ts'\nimport {\n PLUGIN_ERROR_CODES,\n PluginError,\n type AdapterRegistrationHandle,\n type ModelProviderPlugin,\n type ModelProviderRegistrar,\n type PluginRegistrationHandle,\n type StreamMiddleware,\n} from '../plugin/provider-plugin.ts'\n\nexport type { AdapterRegistrationHandle, StreamMiddleware } from '../plugin/provider-plugin.ts'\n\n/**\n * Wraps every streaming model call. Call `next()` to reach the adapter, or yield\n * your own chunks to short-circuit it entirely.\n *\n * This is the extension point for retry, caching, request logging, replay, and\n * test doubles. Middleware registered EARLIER sits further out.\n */\n/** One call whose configuration and adapter registration were resolved together. */\nexport interface PreparedCall {\n /** Detached, deep-frozen config with any adapter-owned default materialized. */\n readonly config: CallConfig\n /** Immutable retry policy captured with the adapter registration. */\n readonly retryPolicy: ResolvedRetryPolicy\n /** Context capacity resolved with the registration-bound call. */\n readonly context?: ModelContext\n /** Exact model modalities captured with the dispatch generation. */\n readonly inputModalities?: readonly ModelModality[]\n /** Complete validated capability snapshot bound to this adapter generation. */\n readonly model: ResolvedModelInfo\n /** Which config fields the adapter supplied rather than the caller. */\n readonly adapterDefaults: CallConfigAdapterDefaults\n /**\n * Dispatch this call ONCE, through the registration captured at preparation.\n * @param options - the assembled request, carrying the prepared config.\n * @returns the chunk stream, including middleware.\n */\n stream(options: GenerateOptions, context?: ModelInvocationContext): ModelCallHandle\n}\n\nexport interface ModelRegistryOptions {\n /** Maximum model rows accepted from one adapter catalog. Defaults to 2,048. */\n readonly maxCatalogModels?: number\n /** Maximum serialized bytes accepted from a catalog or model-info record. Defaults to 4 MiB. */\n readonly maxCatalogBytes?: number\n /** Default observation port; a per-call invocation context may override it. */\n readonly observation?: ObservationPort\n /** Safe SDK/service/runtime identity copied onto observation events. */\n readonly observationResource?: ObservationResource\n /**\n * SDK-wide fallbacks (context window, output cap, accepted modalities) used\n * only when neither a model nor its route names one. See {@link RuntimeDefaults}.\n */\n readonly defaults?: RuntimeDefaults\n}\n\ntype AdapterRegistration = RuntimeAdapterRegistration\n\ninterface InstalledPlugin {\n readonly routes: ReadonlySet<string>\n readonly registrations: readonly AdapterRegistration[]\n readonly middleware: readonly StreamMiddleware[]\n readonly cleanup?: () => void\n}\n\n\nfunction containThenable(value: unknown): boolean {\n if ((typeof value !== 'object' || value === null) && typeof value !== 'function') return false\n let then: unknown\n try {\n then = Reflect.get(value, 'then')\n } catch {\n return true\n }\n if (typeof then !== 'function') return false\n try { void Promise.resolve(value).catch(() => {}) } catch { /* hostile thenable contained */ }\n return true\n}\n\nfunction synchronousCleanupFailure(cleanup: () => void): unknown | undefined {\n try {\n const result: unknown = cleanup()\n return containThenable(result) ? new TypeError('plugin cleanup must be synchronous') : undefined\n } catch (error) {\n return error\n }\n}\n\n\n/**\n * Routes model calls to registered adapters.\n *\n * Construct one per application or isolated runtime scope, register the adapters\n * you use, then call {@link stream} or {@link prepareCall}.\n */\nexport class ModelRegistry {\n private adapters = new Map<string, AdapterRegistration>()\n private middleware: StreamMiddleware[] = []\n private listeners = new Set<() => void>()\n private plugins = new Map<string, InstalledPlugin>()\n private readonly maxCatalogModels: number\n private readonly maxCatalogBytes: number\n private readonly observation: ObservationPort | undefined\n private readonly observationResource: ObservationResource\n private readonly defaults: RuntimeDefaults\n\n constructor(options: ModelRegistryOptions = {}) {\n this.maxCatalogModels = positiveSafeInteger(options.maxCatalogModels ?? 2_048, 'maxCatalogModels')\n this.maxCatalogBytes = positiveSafeInteger(options.maxCatalogBytes ?? 4 * 1024 * 1024, 'maxCatalogBytes')\n this.observation = options.observation\n this.defaults = validateRuntimeDefaults(options.defaults ?? {})\n this.observationResource = deepFreeze(options.observationResource ?? {\n sdkName: 'ai-agent-sdk',\n sdkVersion: SDK_VERSION,\n runtime: 'unknown',\n })\n }\n\n /** Install one provider plugin as a single synchronous topology transaction. */\n install(plugin: ModelProviderPlugin): PluginRegistrationHandle {\n const pluginId = typeof plugin?.id === 'string' ? plugin.id : ''\n const fail = (message: string, cause?: unknown, cleanupFailures: readonly unknown[] = []): never => {\n const causes = [...cause === undefined ? [] : [cause], ...cleanupFailures]\n const wrappedCause = causes.length <= 1 ? causes[0] : new AggregateError(causes, `plugin ${pluginId} install cleanup failed`)\n throw new PluginError(message, PLUGIN_ERROR_CODES.INSTALL_FAILED, pluginId, wrappedCause === undefined ? undefined : { cause: wrappedCause })\n }\n if (pluginId.trim().length === 0 || pluginId !== pluginId.trim()) fail('plugin id must be a non-empty trimmed string')\n if (this.plugins.has(pluginId)) fail(`plugin \"${pluginId}\" is already installed`)\n if (typeof plugin.displayName !== 'string' || plugin.displayName.trim().length === 0) fail(`plugin \"${pluginId}\" displayName must be non-empty`)\n if (typeof plugin.setup !== 'function') fail(`plugin \"${pluginId}\" setup must be a function`)\n const family = plugin.family ?? pluginId\n if (typeof family !== 'string' || family.trim().length === 0 || family !== family.trim()) {\n fail(`plugin \"${pluginId}\" family must be a non-empty trimmed string`)\n }\n const owner = Object.freeze({ pluginId, family })\n\n interface StagedAdapter {\n active: boolean\n routes: string[]\n readonly adapter: ModelAdapter\n }\n interface StagedMiddleware { active: boolean; readonly middleware: StreamMiddleware }\n const stagedAdapters: StagedAdapter[] = []\n const stagedMiddleware: StagedMiddleware[] = []\n let staging = true\n\n const registrar: ModelProviderRegistrar = {\n registerAdapter: (routes, adapter) => {\n if (!staging) fail(`plugin \"${pluginId}\" staging registrar is closed`)\n if (routes.length === 0) throw new ModelError('an adapter must register at least one provider route', REGISTRY_ERROR_CODES.INVALID_ADAPTER)\n const item: StagedAdapter = { active: true, routes: [...routes], adapter }\n // Validate metadata and conflicts without mutating live routes.\n const occupied = new Set(stagedAdapters.filter(value => value.active).flatMap(value => value.routes))\n for (const route of routes) if (occupied.has(route)) {\n throw new ModelError(`an adapter for provider route \"${route}\" is already staged`, REGISTRY_ERROR_CODES.DUPLICATE_ADAPTER)\n }\n this.prepareRoutes(routes, adapter, new Set(), owner)\n stagedAdapters.push(item)\n const handle = (() => {\n if (staging) item.active = false\n }) as AdapterRegistrationHandle\n handle.replace = (next) => {\n if (!staging || !item.active) throw new ModelError('a disposed staged registration cannot replace routes', REGISTRY_ERROR_CODES.REGISTRATION_DISPOSED)\n const occupiedByOthers = new Set(stagedAdapters.filter(value => value.active && value !== item).flatMap(value => value.routes))\n for (const route of next) if (occupiedByOthers.has(route)) {\n throw new ModelError(`an adapter for provider route \"${route}\" is already staged`, REGISTRY_ERROR_CODES.DUPLICATE_ADAPTER)\n }\n this.prepareRoutes(next, adapter, new Set(), owner)\n item.routes = [...next]\n }\n return handle\n },\n use: (middleware) => {\n if (!staging) fail(`plugin \"${pluginId}\" staging registrar is closed`)\n if (typeof middleware !== 'function') throw new TypeError('plugin middleware must be a function')\n const item: StagedMiddleware = { active: true, middleware }\n stagedMiddleware.push(item)\n return () => { if (staging) item.active = false }\n },\n }\n\n let cleanup: (() => void) | undefined\n try {\n const result = plugin.setup(registrar)\n if (containThenable(result)) fail(`plugin \"${pluginId}\" setup must be synchronous`)\n if (result !== undefined && typeof result !== 'function') fail(`plugin \"${pluginId}\" setup must be synchronous and return void or cleanup`)\n cleanup = typeof result === 'function' ? result : undefined\n } catch (error) {\n if (error instanceof PluginError && error.code === PLUGIN_ERROR_CODES.INSTALL_FAILED) throw error\n fail(`plugin \"${pluginId}\" setup failed`, error)\n } finally {\n staging = false\n }\n\n const registrations: AdapterRegistration[] = []\n const routeNames = new Set<string>()\n try {\n for (const item of stagedAdapters) {\n if (!item.active) continue\n for (const route of item.routes) {\n if (routeNames.has(route)) throw new ModelError(`an adapter for provider route \"${route}\" is already staged`, REGISTRY_ERROR_CODES.DUPLICATE_ADAPTER)\n routeNames.add(route)\n }\n registrations.push(...this.prepareRoutes(item.routes, item.adapter, new Set(), owner))\n }\n } catch (error) {\n const cleanupFailures: unknown[] = []\n if (cleanup) {\n const cleanupFailure = synchronousCleanupFailure(cleanup)\n if (cleanupFailure !== undefined) cleanupFailures.push(cleanupFailure)\n }\n fail(`plugin \"${pluginId}\" commit validation failed`, error, cleanupFailures)\n }\n\n const committedMiddleware = stagedMiddleware.filter(item => item.active).map(item => item.middleware)\n for (const registration of registrations) this.adapters.set(registration.provider.id, registration)\n this.middleware.push(...committedMiddleware)\n const installed: InstalledPlugin = {\n routes: routeNames,\n registrations,\n middleware: committedMiddleware,\n ...(cleanup === undefined ? {} : { cleanup }),\n }\n this.plugins.set(pluginId, installed)\n this.emitAdaptersUpdated()\n\n let disposed = false\n const dispose = (() => {\n if (disposed) return\n disposed = true\n this.plugins.delete(pluginId)\n for (const registration of installed.registrations) {\n if (this.adapters.get(registration.provider.id) === registration) this.adapters.delete(registration.provider.id)\n }\n for (let index = installed.middleware.length - 1; index >= 0; index--) {\n const middleware = installed.middleware[index]\n const liveIndex = middleware === undefined ? -1 : this.middleware.lastIndexOf(middleware)\n if (liveIndex >= 0) this.middleware.splice(liveIndex, 1)\n }\n this.emitAdaptersUpdated()\n const failures: unknown[] = []\n if (installed.cleanup) {\n const cleanupFailure = synchronousCleanupFailure(installed.cleanup)\n if (cleanupFailure !== undefined) failures.push(cleanupFailure)\n }\n if (failures.length > 0) {\n throw new PluginError(\n `plugin \"${pluginId}\" cleanup failed`,\n PLUGIN_ERROR_CODES.CLEANUP_FAILED,\n pluginId,\n { cause: new AggregateError(failures, `plugin \"${pluginId}\" cleanup failed`) },\n )\n }\n }) as PluginRegistrationHandle\n Object.defineProperty(dispose, 'pluginId', { value: pluginId, enumerable: true })\n return dispose\n }\n\n /**\n * Register an adapter for the given routes.\n *\n * All-or-nothing: if ANY route conflicts, nothing is registered. A partial\n * registration would leave the caller believing a route exists when it does not.\n * @param providers - every route this adapter should serve; must be non-empty.\n * @param adapter - the adapter that streams calls for those routes.\n * @returns the disposer, carrying {@link AdapterRegistrationHandle.replace}.\n */\n registerAdapter(\n providers: readonly string[],\n adapter: ModelAdapter,\n ): AdapterRegistrationHandle {\n if (providers.length === 0) {\n throw new ModelError(\n 'an adapter must register at least one provider route',\n REGISTRY_ERROR_CODES.INVALID_ADAPTER,\n )\n }\n /** Routes this registration currently holds; `replace` rewrites it. */\n const owned = new Set<string>()\n // `owned` being empty cannot signal disposal on its own, because\n // `replace([])` legally leaves a live registration holding no routes.\n let released = false\n\n this.commitRoutes(owned, this.prepareRoutes(providers, adapter, owned))\n\n const handle = (() => {\n if (released) return\n released = true\n for (const provider of owned) this.adapters.delete(provider)\n owned.clear()\n this.emitAdaptersUpdated()\n }) as AdapterRegistrationHandle\n\n handle.replace = (next: readonly string[]): void => {\n // Registering after disposal would leak: nothing remains to release what\n // this call would put back into the map.\n if (released) {\n throw new ModelError(\n 'a disposed adapter registration cannot replace its routes',\n REGISTRY_ERROR_CODES.REGISTRATION_DISPOSED,\n )\n }\n this.commitRoutes(owned, this.prepareRoutes(next, adapter, owned))\n }\n return handle\n }\n\n /**\n * Validate one candidate route set, treating routes this registration already\n * holds as available. Mutates nothing  Ea rejected candidate leaves the registry\n * exactly as it was.\n */\n private prepareRoutes(\n providers: readonly string[],\n adapter: ModelAdapter,\n owned: ReadonlySet<string>,\n owner?: Readonly<{ pluginId: string; family: string }>,\n ): AdapterRegistration[] {\n const unique = new Set<string>()\n const registrations: AdapterRegistration[] = []\n for (const provider of providers) {\n if (typeof provider !== 'string' || provider.length === 0) {\n throw new ModelError(\n 'adapter provider route names must be non-empty strings',\n REGISTRY_ERROR_CODES.INVALID_ADAPTER,\n )\n }\n if (unique.has(provider) || (this.adapters.has(provider) && !owned.has(provider))) {\n throw new ModelError(\n `an adapter for provider route \"${provider}\" is already registered`,\n REGISTRY_ERROR_CODES.DUPLICATE_ADAPTER,\n )\n }\n const info = adapter.providerInfo(provider)\n if (typeof info.id !== 'string' || info.id !== provider\n || typeof info.name !== 'string' || info.name.length === 0) {\n throw new ModelError(\n `adapter metadata for route \"${provider}\" must preserve its id and carry a non-empty name`,\n REGISTRY_ERROR_CODES.INVALID_ADAPTER,\n )\n }\n unique.add(provider)\n registrations.push({\n adapter,\n provider: { id: info.id, name: info.name },\n ...(owner === undefined ? {} : owner),\n // Captured at REGISTRATION time, not per call. An adapter whose policy\n // follows mutable configuration re-registers via `handle.replace`.\n retryPolicy: adapter.providerRetryPolicy(provider)\n ?? resolveRetryPolicy(undefined, `provider \"${provider}\" retryPolicy`),\n })\n }\n return registrations\n }\n\n /**\n * Swap this registration's routes in ONE synchronous section, so no caller can\n * observe the registry between the release and the re-registration.\n */\n private commitRoutes(\n owned: Set<string>,\n registrations: readonly AdapterRegistration[],\n ): void {\n for (const provider of owned) this.adapters.delete(provider)\n owned.clear()\n for (const registration of registrations) {\n this.adapters.set(registration.provider.id, registration)\n owned.add(registration.provider.id)\n }\n this.emitAdaptersUpdated()\n }\n\n /**\n * Install streaming middleware.\n * @param middleware - wrapper invoked around every call; earlier registrations sit further out.\n * @returns a disposer that removes exactly this middleware.\n */\n use(middleware: StreamMiddleware): () => void {\n this.middleware.push(middleware)\n return () => {\n const index = this.middleware.indexOf(middleware)\n if (index >= 0) this.middleware.splice(index, 1)\n }\n }\n\n /**\n * Observe route-topology changes (registration, replacement, disposal).\n * @param listener - payload-free notification; re-read `listProviders()` for new state.\n * @returns a disposer that removes the listener.\n */\n onAdaptersUpdated(listener: () => void): () => void {\n this.listeners.add(listener)\n return () => void this.listeners.delete(listener)\n }\n\n /**\n * Notify topology observers.\n *\n * Each listener is contained independently: a topology notification is not a\n * veto, so one broken observer must not starve the others or roll back a\n * registration that already happened.\n */\n private emitAdaptersUpdated(): void {\n for (const listener of [...this.listeners]) {\n try {\n listener()\n } catch {\n // Contained deliberately; see above.\n }\n }\n }\n\n /**\n * Describe every route with a registered adapter.\n * @returns detached provider metadata, in registration order.\n */\n listProviders(): ProviderInfo[] {\n return [...this.adapters.values()].map(({ provider }) => ({ ...provider }))\n }\n\n /**\n * List the models one route advertises.\n *\n * Re-validated here rather than trusted, because a malformed catalog entry\n * surfaces in a caller's model picker where its origin is far from obvious.\n * @param provider - a registered route.\n * @returns detached, validated model metadata.\n */\n async listModels(provider: string, signal?: AbortSignal): Promise<ModelInfo[]> {\n const registration = this.registration(provider)\n const models = await registration.adapter.listModels(provider, signal)\n return validateCatalogModels(provider, models, this.maxCatalogModels, this.maxCatalogBytes)\n }\n\n /** Resolve and validate one uncached adapter-level catalog generation. */\n async modelCatalog(provider: string, options: ModelCatalogOptions = {}): Promise<ModelCatalogSnapshot> {\n const registration = this.registration(provider)\n const snapshot = await registration.adapter.modelCatalog(provider, options)\n return validateModelCatalogSnapshot(provider, snapshot, this.maxCatalogModels, this.maxCatalogBytes)\n }\n\n /**\n * Resolve metadata for one exact model.\n * @param provider - a registered route.\n * @param model - exact model id.\n * @param signal - cancellation for adapter-side resolution.\n * @returns validated, detached metadata.\n */\n async resolveModelInfo(\n provider: string,\n model: string,\n signal?: AbortSignal,\n ): Promise<ResolvedModelInfo> {\n const registration = this.registration(provider)\n const resolved = await registration.adapter.resolveModel(provider, model, signal)\n return normalizeResolvedModelInfo(registration.provider.id, model, resolved, this.maxCatalogBytes, this.defaults)\n }\n\n /** The retry policy captured for one route. */\n retryPolicy(provider: string): ResolvedRetryPolicy {\n return this.registration(provider).retryPolicy\n }\n\n /**\n * Resolve one call under its CURRENT adapter registration, returning a one-shot\n * handle that keeps that registration through to dispatch.\n * @param config - route, model, and optional request controls.\n * @param signal - cancellation for adapter-side capability lookup.\n * @returns the prepared config and its registration-bound stream entry point.\n */\n async prepareCall(\n config: CallConfig,\n signal?: AbortSignal,\n invocationContext?: ModelInvocationContext,\n ): Promise<PreparedCall> {\n const registration = this.registration(config.provider)\n const adapterCall = await registration.adapter.prepareCall(config.provider, config.model, signal, invocationContext)\n const modelInfo = normalizeResolvedModelInfo(\n registration.provider.id, config.model, adapterCall.model, this.maxCatalogBytes, this.defaults,\n )\n const resolved = resolveCallWithModelInfo(config, modelInfo, this.defaults)\n const resolvedConfig = deepFreeze(structuredClone(resolved.config))\n const context = resolved.context === undefined\n ? undefined\n : deepFreeze(structuredClone(resolved.context))\n const adapterDefaults = deepFreeze<CallConfigAdapterDefaults>({\n ...config.maxTokens === undefined && resolvedConfig.maxTokens !== undefined\n ? { maxTokens: true as const }\n : {},\n })\n\n let dispatched = false\n const model = deepFreeze(structuredClone(modelInfo))\n return Object.freeze({\n config: resolvedConfig,\n model,\n retryPolicy: registration.retryPolicy,\n adapterDefaults,\n ...context === undefined ? {} : { context },\n ...resolved.inputModalities === undefined\n ? {}\n : { inputModalities: Object.freeze([...resolved.inputModalities]) },\n stream: (options: GenerateOptions, context = invocationContext): ModelCallHandle => {\n // Both guards below exist so a stale handle fails loudly instead of\n // quietly dispatching against a configuration nobody vetted.\n if (dispatched) {\n throw new ModelError(\n 'a prepared call can only be dispatched once',\n REGISTRY_ERROR_CODES.INVALID_PREPARED_CALL,\n )\n }\n if (!callConfigEquals(options, resolvedConfig)) {\n throw new ModelError(\n 'prepared call config changed before adapter dispatch',\n REGISTRY_ERROR_CODES.INVALID_PREPARED_CALL,\n )\n }\n dispatched = true\n return this.dispatch(options, context, {\n registration,\n config: resolvedConfig,\n modelInfo,\n dispatch: (request, activeContext) => adapterCall.stream(request, activeContext),\n })\n },\n })\n }\n\n /**\n * Stream one model call as raw chunks.\n *\n * Adapter selection, dispatch, and iteration failures become terminal `error` or\n * `aborted` finish chunks. Middleware and consumer failures stay THROWN  Ethose\n * are bugs in code the caller controls, and converting them to a finish reason\n * would hide them.\n * @param options - the full request; `options.provider` selects the adapter.\n * @returns the chunk stream, wrapped by any installed middleware.\n */\n stream(options: GenerateOptions, context?: ModelInvocationContext): ModelCallHandle {\n return this.dispatch(options, context)\n }\n\n private dispatch(\n options: GenerateOptions,\n context?: ModelInvocationContext,\n prepared?: PreparedDispatch,\n ): ModelCallHandle {\n let dispatchState: 'not-sent' | 'unknown' = 'not-sent'\n const registration = prepared?.registration ?? this.adapters.get(options.provider)\n return createModelCallHandle({\n options,\n ...(registration?.family === undefined ? {} : { providerFamily: registration.family }),\n ...(registration?.pluginId === undefined ? {} : { providerPluginId: registration.pluginId }),\n ...(registration === undefined ? {} : { isRetryable: (code: string) => (\n registration.retryPolicy.mode === 'always'\n || registration.retryPolicy.retryableCodes.includes(code)\n ) }),\n ...(context === undefined ? {} : { context }),\n ...(this.observation === undefined ? {} : { defaultObservation: this.observation }),\n resource: this.observationResource,\n routePresent: prepared !== undefined || this.adapters.has(options.provider),\n dispatchState: () => dispatchState,\n stream: activeContext => this.dispatchRaw(\n options,\n activeContext,\n () => { dispatchState = 'unknown' },\n prepared,\n ),\n })\n }\n\n /**\n * Compose installed middleware around the adapter boundary.\n *\n * Composition is deferred to the first iteration rather than done eagerly, so\n * that `stream()` ALWAYS returns an iterable and every failure — including a\n * middleware that throws synchronously — surfaces on the same path. Composing\n * eagerly would give callers two different error channels for the same class of\n * fault, and they would inevitably handle only one.\n *\n * The middleware list is snapshotted here so that installing or removing\n * middleware mid-stream cannot change the chain of a call already in flight.\n */\n private dispatchRaw(\n options: GenerateOptions,\n context: ModelInvocationContext,\n onDispatch: () => void,\n prepared?: PreparedDispatch,\n ): AsyncIterable<StreamChunk> {\n const chain = [...this.middleware]\n const run = (): AsyncIterable<StreamChunk> => {\n let next = (): AsyncIterable<StreamChunk> => streamAdapter({\n options, context, onDispatch, maxCatalogBytes: this.maxCatalogBytes, defaults: this.defaults,\n registration: provider => this.registration(provider),\n registeredAdapter: provider => this.adapters.get(provider)?.adapter,\n ...(prepared === undefined ? {} : { prepared }),\n })\n for (let index = chain.length - 1; index >= 0; index--) {\n const middleware = chain[index]\n if (middleware === undefined) continue\n const inner = next\n next = () => middleware(options, inner, context)\n }\n return next()\n }\n return {\n async * [Symbol.asyncIterator]() {\n yield* run()\n },\n }\n }\n\n private registration(provider: string): AdapterRegistration {\n const registration = this.adapters.get(provider)\n if (registration === undefined) {\n throw new ModelError(\n `no adapter registered for provider route \"${provider}\"`,\n REGISTRY_ERROR_CODES.NO_ADAPTER,\n )\n }\n return registration\n }\n\n}\n\nfunction positiveSafeInteger(value: number, label: string): number {\n if (!Number.isSafeInteger(value) || value < 1) {\n throw new RangeError(`ModelRegistry ${label} must be a positive safe integer`)\n }\n return value\n}\n\nfunction validateRuntimeDefaults(defaults: RuntimeDefaults): RuntimeDefaults {\n if (defaults.contextWindow !== undefined) positiveSafeInteger(defaults.contextWindow, 'defaults.contextWindow')\n if (defaults.maxTokens !== undefined) positiveSafeInteger(defaults.maxTokens, 'defaults.maxTokens')\n if (defaults.inputModalities !== undefined\n && (defaults.inputModalities.length === 0\n || new Set(defaults.inputModalities).size !== defaults.inputModalities.length)) {\n throw new RangeError('ModelRegistry defaults.inputModalities must be non-empty and unique')\n }\n return deepFreeze({\n ...(defaults.contextWindow === undefined ? {} : { contextWindow: defaults.contextWindow }),\n ...(defaults.maxTokens === undefined ? {} : { maxTokens: defaults.maxTokens }),\n ...(defaults.inputModalities === undefined ? {} : { inputModalities: [...defaults.inputModalities] }),\n })\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"registry.js","names":[],"sources":["../../src/runtime/registry.ts"],"sourcesContent":["/**\n * The adapter registry and the streaming call API.\n *\n * This is the deepseek-harness `LlmRuntime` with its dependency-injection\n * framework removed: a plain `Map` for routes, an ordered array for the\n * interception point that was a cordis waterfall, and a listener set for the\n * topology event. What is kept is everything that made it trustworthy  E * all-or-nothing validating registration, an atomic route swap, prepare/dispatch\n * generation binding, and a single failure funnel at the adapter boundary.\n *\n * @module ai-agent-sdk/core/runtime/registry\n */\n\nimport type { ModelAdapter } from '../contract/adapter.ts'\nimport {\n callConfigEquals,\n type CallConfig,\n type CallConfigAdapterDefaults,\n} from '../contract/call-config.ts'\nimport type { GenerateOptions } from '../contract/generate-options.ts'\nimport type {\n ModelContext,\n ModelCatalogOptions,\n ModelCatalogSnapshot,\n ModelInfo,\n ModelModality,\n ProviderInfo,\n ResolvedModelInfo,\n RuntimeDefaults,\n} from '../contract/model-info.ts'\nimport { resolveRetryPolicy, type ResolvedRetryPolicy } from '../contract/retry-policy.ts'\nimport { ModelError, REGISTRY_ERROR_CODES } from '../errors/model-error.ts'\nimport { deepFreeze } from '../primitives/freeze.ts'\nimport { SDK_VERSION } from '../primitives/version.ts'\nimport type { ObservationResource } from '../observation/event.ts'\nimport type { ObservationPort } from '../observation/port.ts'\nimport type { ModelCallHandle, ModelInvocationContext } from '../observation/report.ts'\nimport type { StreamChunk } from '../stream/chunk.ts'\nimport { createModelCallHandle } from './model-call-handle.ts'\nimport { normalizeResolvedModelInfo, resolveCallWithModelInfo,\n validateCatalogModels, validateModelCatalogSnapshot } from './model-metadata.ts'\nimport { streamAdapter, type PreparedDispatch,\n type RuntimeAdapterRegistration } from './model-stream.ts'\nimport {\n PLUGIN_ERROR_CODES,\n PluginError,\n type AdapterRegistrationHandle,\n type ModelProviderPlugin,\n type ModelProviderRegistrar,\n type PluginRegistrationHandle,\n type StreamMiddleware,\n} from '../plugin/provider-plugin.ts'\n\nexport type { AdapterRegistrationHandle, StreamMiddleware } from '../plugin/provider-plugin.ts'\n\n/**\n * Wraps every streaming model call. Call `next()` to reach the adapter, or yield\n * your own chunks to short-circuit it entirely.\n *\n * This is the extension point for retry, caching, request logging, replay, and\n * test doubles. Middleware registered EARLIER sits further out.\n */\n/** One call whose configuration and adapter registration were resolved together. */\nexport interface PreparedCall {\n /** Detached, deep-frozen config with any adapter-owned default materialized. */\n readonly config: CallConfig\n /** Immutable retry policy captured with the adapter registration. */\n readonly retryPolicy: ResolvedRetryPolicy\n /** Context capacity resolved with the registration-bound call. */\n readonly context?: ModelContext\n /** Exact model modalities captured with the dispatch generation. */\n readonly inputModalities?: readonly ModelModality[]\n /** Complete validated capability snapshot bound to this adapter generation. */\n readonly model: ResolvedModelInfo\n /** Which config fields the adapter supplied rather than the caller. */\n readonly adapterDefaults: CallConfigAdapterDefaults\n /**\n * Dispatch this call ONCE, through the registration captured at preparation.\n * @param options - the assembled request, carrying the prepared config.\n * @returns the chunk stream, including middleware.\n */\n stream(options: GenerateOptions, context?: ModelInvocationContext): ModelCallHandle\n}\n\nexport interface ModelRegistryOptions {\n /** Maximum model rows accepted from one adapter catalog. Defaults to 2,048. */\n readonly maxCatalogModels?: number\n /** Maximum serialized bytes accepted from a catalog or model-info record. Defaults to 4 MiB. */\n readonly maxCatalogBytes?: number\n /** Default observation port; a per-call invocation context may override it. */\n readonly observation?: ObservationPort\n /** Safe SDK/service/runtime identity copied onto observation events. */\n readonly observationResource?: ObservationResource\n /**\n * SDK-wide fallbacks (context window, output cap, accepted modalities) used\n * only when neither a model nor its route names one. See {@link RuntimeDefaults}.\n */\n readonly defaults?: RuntimeDefaults\n}\n\ntype AdapterRegistration = RuntimeAdapterRegistration\n\ninterface InstalledPlugin {\n readonly routes: ReadonlySet<string>\n readonly registrations: readonly AdapterRegistration[]\n readonly middleware: readonly StreamMiddleware[]\n readonly cleanup?: () => void\n}\n\n\nfunction containThenable(value: unknown): boolean {\n if ((typeof value !== 'object' || value === null) && typeof value !== 'function') return false\n let then: unknown\n try {\n then = Reflect.get(value, 'then')\n } catch {\n return true\n }\n if (typeof then !== 'function') return false\n try { void Promise.resolve(value).catch(() => {}) } catch { /* hostile thenable contained */ }\n return true\n}\n\nfunction synchronousCleanupFailure(cleanup: () => void): unknown | undefined {\n try {\n const result: unknown = cleanup()\n return containThenable(result) ? new TypeError('plugin cleanup must be synchronous') : undefined\n } catch (error) {\n return error\n }\n}\n\n\n/**\n * Routes model calls to registered adapters.\n *\n * Construct one per application or isolated runtime scope, register the adapters\n * you use, then call {@link stream} or {@link prepareCall}.\n */\nexport class ModelRegistry {\n private adapters = new Map<string, AdapterRegistration>()\n private middleware: StreamMiddleware[] = []\n private listeners = new Set<() => void>()\n private plugins = new Map<string, InstalledPlugin>()\n private readonly maxCatalogModels: number\n private readonly maxCatalogBytes: number\n private readonly observation: ObservationPort | undefined\n private readonly observationResource: ObservationResource\n private readonly defaults: RuntimeDefaults\n\n constructor(options: ModelRegistryOptions = {}) {\n this.maxCatalogModels = positiveSafeInteger(options.maxCatalogModels ?? 2_048, 'maxCatalogModels')\n this.maxCatalogBytes = positiveSafeInteger(options.maxCatalogBytes ?? 4 * 1024 * 1024, 'maxCatalogBytes')\n this.observation = options.observation\n this.defaults = validateRuntimeDefaults(options.defaults ?? {})\n this.observationResource = deepFreeze(options.observationResource ?? {\n sdkName: 'ai-agent-sdk',\n sdkVersion: SDK_VERSION,\n runtime: 'unknown',\n })\n }\n\n /** Install one provider plugin as a single synchronous topology transaction. */\n install(plugin: ModelProviderPlugin): PluginRegistrationHandle {\n const pluginId = typeof plugin?.id === 'string' ? plugin.id : ''\n const fail = (message: string, cause?: unknown, cleanupFailures: readonly unknown[] = []): never => {\n const causes = [...cause === undefined ? [] : [cause], ...cleanupFailures]\n const wrappedCause = causes.length <= 1 ? causes[0] : new AggregateError(causes, `plugin ${pluginId} install cleanup failed`)\n throw new PluginError(message, PLUGIN_ERROR_CODES.INSTALL_FAILED, pluginId, wrappedCause === undefined ? undefined : { cause: wrappedCause })\n }\n if (pluginId.trim().length === 0 || pluginId !== pluginId.trim()) fail('plugin id must be a non-empty trimmed string')\n if (this.plugins.has(pluginId)) fail(`plugin \"${pluginId}\" is already installed`)\n if (typeof plugin.displayName !== 'string' || plugin.displayName.trim().length === 0) fail(`plugin \"${pluginId}\" displayName must be non-empty`)\n if (typeof plugin.setup !== 'function') fail(`plugin \"${pluginId}\" setup must be a function`)\n const family = plugin.family ?? pluginId\n if (typeof family !== 'string' || family.trim().length === 0 || family !== family.trim()) {\n fail(`plugin \"${pluginId}\" family must be a non-empty trimmed string`)\n }\n const owner = Object.freeze({ pluginId, family })\n\n interface StagedAdapter {\n active: boolean\n routes: string[]\n readonly adapter: ModelAdapter\n }\n interface StagedMiddleware { active: boolean; readonly middleware: StreamMiddleware }\n const stagedAdapters: StagedAdapter[] = []\n const stagedMiddleware: StagedMiddleware[] = []\n let staging = true\n\n const registrar: ModelProviderRegistrar = {\n registerAdapter: (routes, adapter) => {\n if (!staging) fail(`plugin \"${pluginId}\" staging registrar is closed`)\n if (routes.length === 0) throw new ModelError('an adapter must register at least one provider route', REGISTRY_ERROR_CODES.INVALID_ADAPTER)\n const item: StagedAdapter = { active: true, routes: [...routes], adapter }\n // Validate metadata and conflicts without mutating live routes.\n const occupied = new Set(stagedAdapters.filter(value => value.active).flatMap(value => value.routes))\n for (const route of routes) if (occupied.has(route)) {\n throw new ModelError(`an adapter for provider route \"${route}\" is already staged`, REGISTRY_ERROR_CODES.DUPLICATE_ADAPTER)\n }\n this.prepareRoutes(routes, adapter, new Set(), owner)\n stagedAdapters.push(item)\n const handle = (() => {\n if (staging) item.active = false\n }) as AdapterRegistrationHandle\n handle.replace = (next) => {\n if (!staging || !item.active) throw new ModelError('a disposed staged registration cannot replace routes', REGISTRY_ERROR_CODES.REGISTRATION_DISPOSED)\n const occupiedByOthers = new Set(stagedAdapters.filter(value => value.active && value !== item).flatMap(value => value.routes))\n for (const route of next) if (occupiedByOthers.has(route)) {\n throw new ModelError(`an adapter for provider route \"${route}\" is already staged`, REGISTRY_ERROR_CODES.DUPLICATE_ADAPTER)\n }\n this.prepareRoutes(next, adapter, new Set(), owner)\n item.routes = [...next]\n }\n return handle\n },\n use: (middleware) => {\n if (!staging) fail(`plugin \"${pluginId}\" staging registrar is closed`)\n if (typeof middleware !== 'function') throw new TypeError('plugin middleware must be a function')\n const item: StagedMiddleware = { active: true, middleware }\n stagedMiddleware.push(item)\n return () => { if (staging) item.active = false }\n },\n }\n\n let cleanup: (() => void) | undefined\n try {\n const result = plugin.setup(registrar)\n if (containThenable(result)) fail(`plugin \"${pluginId}\" setup must be synchronous`)\n if (result !== undefined && typeof result !== 'function') fail(`plugin \"${pluginId}\" setup must be synchronous and return void or cleanup`)\n cleanup = typeof result === 'function' ? result : undefined\n } catch (error) {\n if (error instanceof PluginError && error.code === PLUGIN_ERROR_CODES.INSTALL_FAILED) throw error\n fail(`plugin \"${pluginId}\" setup failed`, error)\n } finally {\n staging = false\n }\n\n const registrations: AdapterRegistration[] = []\n const routeNames = new Set<string>()\n try {\n for (const item of stagedAdapters) {\n if (!item.active) continue\n for (const route of item.routes) {\n if (routeNames.has(route)) throw new ModelError(`an adapter for provider route \"${route}\" is already staged`, REGISTRY_ERROR_CODES.DUPLICATE_ADAPTER)\n routeNames.add(route)\n }\n registrations.push(...this.prepareRoutes(item.routes, item.adapter, new Set(), owner))\n }\n } catch (error) {\n const cleanupFailures: unknown[] = []\n if (cleanup) {\n const cleanupFailure = synchronousCleanupFailure(cleanup)\n if (cleanupFailure !== undefined) cleanupFailures.push(cleanupFailure)\n }\n fail(`plugin \"${pluginId}\" commit validation failed`, error, cleanupFailures)\n }\n\n const committedMiddleware = stagedMiddleware.filter(item => item.active).map(item => item.middleware)\n for (const registration of registrations) this.adapters.set(registration.provider.id, registration)\n this.middleware.push(...committedMiddleware)\n const installed: InstalledPlugin = {\n routes: routeNames,\n registrations,\n middleware: committedMiddleware,\n ...(cleanup === undefined ? {} : { cleanup }),\n }\n this.plugins.set(pluginId, installed)\n this.emitAdaptersUpdated()\n\n let disposed = false\n const dispose = (() => {\n if (disposed) return\n disposed = true\n this.plugins.delete(pluginId)\n for (const registration of installed.registrations) {\n if (this.adapters.get(registration.provider.id) === registration) this.adapters.delete(registration.provider.id)\n }\n for (let index = installed.middleware.length - 1; index >= 0; index--) {\n const middleware = installed.middleware[index]\n const liveIndex = middleware === undefined ? -1 : this.middleware.lastIndexOf(middleware)\n if (liveIndex >= 0) this.middleware.splice(liveIndex, 1)\n }\n this.emitAdaptersUpdated()\n const failures: unknown[] = []\n if (installed.cleanup) {\n const cleanupFailure = synchronousCleanupFailure(installed.cleanup)\n if (cleanupFailure !== undefined) failures.push(cleanupFailure)\n }\n if (failures.length > 0) {\n throw new PluginError(\n `plugin \"${pluginId}\" cleanup failed`,\n PLUGIN_ERROR_CODES.CLEANUP_FAILED,\n pluginId,\n { cause: new AggregateError(failures, `plugin \"${pluginId}\" cleanup failed`) },\n )\n }\n }) as PluginRegistrationHandle\n Object.defineProperty(dispose, 'pluginId', { value: pluginId, enumerable: true })\n return dispose\n }\n\n /**\n * Register an adapter for the given routes.\n *\n * All-or-nothing: if ANY route conflicts, nothing is registered. A partial\n * registration would leave the caller believing a route exists when it does not.\n * @param providers - every route this adapter should serve; must be non-empty.\n * @param adapter - the adapter that streams calls for those routes.\n * @returns the disposer, carrying {@link AdapterRegistrationHandle.replace}.\n */\n registerAdapter(\n providers: readonly string[],\n adapter: ModelAdapter,\n ): AdapterRegistrationHandle {\n if (providers.length === 0) {\n throw new ModelError(\n 'an adapter must register at least one provider route',\n REGISTRY_ERROR_CODES.INVALID_ADAPTER,\n )\n }\n /** Routes this registration currently holds; `replace` rewrites it. */\n const owned = new Set<string>()\n // `owned` being empty cannot signal disposal on its own, because\n // `replace([])` legally leaves a live registration holding no routes.\n let released = false\n\n this.commitRoutes(owned, this.prepareRoutes(providers, adapter, owned))\n\n const handle = (() => {\n if (released) return\n released = true\n for (const provider of owned) this.adapters.delete(provider)\n owned.clear()\n this.emitAdaptersUpdated()\n }) as AdapterRegistrationHandle\n\n handle.replace = (next: readonly string[]): void => {\n // Registering after disposal would leak: nothing remains to release what\n // this call would put back into the map.\n if (released) {\n throw new ModelError(\n 'a disposed adapter registration cannot replace its routes',\n REGISTRY_ERROR_CODES.REGISTRATION_DISPOSED,\n )\n }\n this.commitRoutes(owned, this.prepareRoutes(next, adapter, owned))\n }\n return handle\n }\n\n /**\n * Validate one candidate route set, treating routes this registration already\n * holds as available. Mutates nothing  Ea rejected candidate leaves the registry\n * exactly as it was.\n */\n private prepareRoutes(\n providers: readonly string[],\n adapter: ModelAdapter,\n owned: ReadonlySet<string>,\n owner?: Readonly<{ pluginId: string; family: string }>,\n ): AdapterRegistration[] {\n const unique = new Set<string>()\n const registrations: AdapterRegistration[] = []\n for (const provider of providers) {\n if (typeof provider !== 'string' || provider.length === 0) {\n throw new ModelError(\n 'adapter provider route names must be non-empty strings',\n REGISTRY_ERROR_CODES.INVALID_ADAPTER,\n )\n }\n if (unique.has(provider) || (this.adapters.has(provider) && !owned.has(provider))) {\n throw new ModelError(\n `an adapter for provider route \"${provider}\" is already registered`,\n REGISTRY_ERROR_CODES.DUPLICATE_ADAPTER,\n )\n }\n const info = adapter.providerInfo(provider)\n if (typeof info.id !== 'string' || info.id !== provider\n || typeof info.name !== 'string' || info.name.length === 0) {\n throw new ModelError(\n `adapter metadata for route \"${provider}\" must preserve its id and carry a non-empty name`,\n REGISTRY_ERROR_CODES.INVALID_ADAPTER,\n )\n }\n unique.add(provider)\n registrations.push({\n adapter,\n provider: { id: info.id, name: info.name },\n ...(owner === undefined ? {} : owner),\n // Captured at REGISTRATION time, not per call. An adapter whose policy\n // follows mutable configuration re-registers via `handle.replace`.\n retryPolicy: adapter.providerRetryPolicy(provider)\n ?? resolveRetryPolicy(undefined, `provider \"${provider}\" retryPolicy`),\n })\n }\n return registrations\n }\n\n /**\n * Swap this registration's routes in ONE synchronous section, so no caller can\n * observe the registry between the release and the re-registration.\n */\n private commitRoutes(\n owned: Set<string>,\n registrations: readonly AdapterRegistration[],\n ): void {\n for (const provider of owned) this.adapters.delete(provider)\n owned.clear()\n for (const registration of registrations) {\n this.adapters.set(registration.provider.id, registration)\n owned.add(registration.provider.id)\n }\n this.emitAdaptersUpdated()\n }\n\n /**\n * Install streaming middleware.\n * @param middleware - wrapper invoked around every call; earlier registrations sit further out.\n * @returns a disposer that removes exactly this middleware.\n */\n use(middleware: StreamMiddleware): () => void {\n this.middleware.push(middleware)\n return () => {\n const index = this.middleware.indexOf(middleware)\n if (index >= 0) this.middleware.splice(index, 1)\n }\n }\n\n /**\n * Observe route-topology changes (registration, replacement, disposal).\n * @param listener - payload-free notification; re-read `listProviders()` for new state.\n * @returns a disposer that removes the listener.\n */\n onAdaptersUpdated(listener: () => void): () => void {\n this.listeners.add(listener)\n return () => void this.listeners.delete(listener)\n }\n\n /**\n * Notify topology observers.\n *\n * Each listener is contained independently: a topology notification is not a\n * veto, so one broken observer must not starve the others or roll back a\n * registration that already happened.\n */\n private emitAdaptersUpdated(): void {\n for (const listener of [...this.listeners]) {\n try {\n listener()\n } catch {\n // Contained deliberately; see above.\n }\n }\n }\n\n /**\n * Describe every route with a registered adapter.\n * @returns detached provider metadata, in registration order.\n */\n listProviders(): ProviderInfo[] {\n return [...this.adapters.values()].map(({ provider }) => ({ ...provider }))\n }\n\n /**\n * List the models one route advertises.\n *\n * Re-validated here rather than trusted, because a malformed catalog entry\n * surfaces in a caller's model picker where its origin is far from obvious.\n * @param provider - a registered route.\n * @returns detached, validated model metadata.\n */\n async listModels(provider: string, signal?: AbortSignal): Promise<ModelInfo[]> {\n const registration = this.registration(provider)\n const models = await registration.adapter.listModels(provider, signal)\n return validateCatalogModels(provider, models, this.maxCatalogModels, this.maxCatalogBytes)\n }\n\n /** Resolve and validate one uncached adapter-level catalog generation. */\n async modelCatalog(provider: string, options: ModelCatalogOptions = {}): Promise<ModelCatalogSnapshot> {\n const registration = this.registration(provider)\n const snapshot = await registration.adapter.modelCatalog(provider, options)\n return validateModelCatalogSnapshot(provider, snapshot, this.maxCatalogModels, this.maxCatalogBytes)\n }\n\n /**\n * Resolve metadata for one exact model.\n * @param provider - a registered route.\n * @param model - exact model id.\n * @param signal - cancellation for adapter-side resolution.\n * @returns validated, detached metadata.\n */\n async resolveModelInfo(\n provider: string,\n model: string,\n signal?: AbortSignal,\n ): Promise<ResolvedModelInfo> {\n const registration = this.registration(provider)\n const resolved = await registration.adapter.resolveModel(provider, model, signal)\n return normalizeResolvedModelInfo(registration.provider.id, model, resolved, this.maxCatalogBytes, this.defaults)\n }\n\n /** The retry policy captured for one route. */\n retryPolicy(provider: string): ResolvedRetryPolicy {\n return this.registration(provider).retryPolicy\n }\n\n /**\n * Resolve one call under its CURRENT adapter registration, returning a one-shot\n * handle that keeps that registration through to dispatch.\n * @param config - route, model, and optional request controls.\n * @param signal - cancellation for adapter-side capability lookup.\n * @returns the prepared config and its registration-bound stream entry point.\n */\n async prepareCall(\n config: CallConfig,\n signal?: AbortSignal,\n invocationContext?: ModelInvocationContext,\n ): Promise<PreparedCall> {\n const registration = this.registration(config.provider)\n const adapterCall = await registration.adapter.prepareCall(config.provider, config.model, signal, invocationContext)\n const modelInfo = normalizeResolvedModelInfo(\n registration.provider.id, config.model, adapterCall.model, this.maxCatalogBytes, this.defaults,\n )\n const resolved = resolveCallWithModelInfo(config, modelInfo, this.defaults)\n const resolvedConfig = deepFreeze(structuredClone(resolved.config))\n const context = resolved.context === undefined\n ? undefined\n : deepFreeze(structuredClone(resolved.context))\n const adapterDefaults = deepFreeze<CallConfigAdapterDefaults>({\n ...config.maxTokens === undefined && resolvedConfig.maxTokens !== undefined\n ? { maxTokens: true as const }\n : {},\n })\n\n let dispatched = false\n const model = deepFreeze(structuredClone(modelInfo))\n return Object.freeze({\n config: resolvedConfig,\n model,\n retryPolicy: registration.retryPolicy,\n adapterDefaults,\n ...context === undefined ? {} : { context },\n ...resolved.inputModalities === undefined\n ? {}\n : { inputModalities: Object.freeze([...resolved.inputModalities]) },\n stream: (options: GenerateOptions, context = invocationContext): ModelCallHandle => {\n // Both guards below exist so a stale handle fails loudly instead of\n // quietly dispatching against a configuration nobody vetted.\n if (dispatched) {\n throw new ModelError(\n 'a prepared call can only be dispatched once',\n REGISTRY_ERROR_CODES.INVALID_PREPARED_CALL,\n )\n }\n if (!callConfigEquals(options, resolvedConfig)) {\n throw new ModelError(\n 'prepared call config changed before adapter dispatch',\n REGISTRY_ERROR_CODES.INVALID_PREPARED_CALL,\n )\n }\n dispatched = true\n return this.dispatch(options, context, {\n registration,\n config: resolvedConfig,\n modelInfo,\n dispatch: (request, activeContext) => adapterCall.stream(request, activeContext),\n })\n },\n })\n }\n\n /**\n * Stream one model call as raw chunks.\n *\n * Adapter selection, dispatch, and iteration failures become terminal `error` or\n * `aborted` finish chunks. Middleware and consumer failures stay THROWN  Ethose\n * are bugs in code the caller controls, and converting them to a finish reason\n * would hide them.\n * @param options - the full request; `options.provider` selects the adapter.\n * @returns the chunk stream, wrapped by any installed middleware.\n */\n stream(options: GenerateOptions, context?: ModelInvocationContext): ModelCallHandle {\n return this.dispatch(options, context)\n }\n\n private dispatch(\n options: GenerateOptions,\n context?: ModelInvocationContext,\n prepared?: PreparedDispatch,\n ): ModelCallHandle {\n let dispatchState: 'not-sent' | 'unknown' = 'not-sent'\n const registration = prepared?.registration ?? this.adapters.get(options.provider)\n return createModelCallHandle({\n options,\n ...(registration?.family === undefined ? {} : { providerFamily: registration.family }),\n ...(registration?.pluginId === undefined ? {} : { providerPluginId: registration.pluginId }),\n ...(registration === undefined ? {} : { isRetryable: (code: string) => (\n registration.retryPolicy.mode === 'always'\n || registration.retryPolicy.retryableCodes.includes(code)\n ) }),\n ...(context === undefined ? {} : { context }),\n ...(this.observation === undefined ? {} : { defaultObservation: this.observation }),\n resource: this.observationResource,\n routePresent: prepared !== undefined || this.adapters.has(options.provider),\n dispatchState: () => dispatchState,\n stream: activeContext => this.dispatchRaw(\n options,\n activeContext,\n () => { dispatchState = 'unknown' },\n prepared,\n ),\n })\n }\n\n /**\n * Compose installed middleware around the adapter boundary.\n *\n * Composition is deferred to the first iteration rather than done eagerly, so\n * that `stream()` ALWAYS returns an iterable and every failure — including a\n * middleware that throws synchronously — surfaces on the same path. Composing\n * eagerly would give callers two different error channels for the same class of\n * fault, and they would inevitably handle only one.\n *\n * The middleware list is snapshotted here so that installing or removing\n * middleware mid-stream cannot change the chain of a call already in flight.\n */\n private dispatchRaw(\n options: GenerateOptions,\n context: ModelInvocationContext,\n onDispatch: () => void,\n prepared?: PreparedDispatch,\n ): AsyncIterable<StreamChunk> {\n const chain = [...this.middleware]\n const run = (): AsyncIterable<StreamChunk> => {\n let next = (): AsyncIterable<StreamChunk> => streamAdapter({\n options, context, onDispatch, maxCatalogBytes: this.maxCatalogBytes, defaults: this.defaults,\n registration: provider => this.registration(provider),\n registeredAdapter: provider => this.adapters.get(provider)?.adapter,\n ...(prepared === undefined ? {} : { prepared }),\n })\n for (let index = chain.length - 1; index >= 0; index--) {\n const middleware = chain[index]\n if (middleware === undefined) continue\n const inner = next\n next = () => middleware(options, inner, context)\n }\n return next()\n }\n return {\n async * [Symbol.asyncIterator]() {\n yield* run()\n },\n }\n }\n\n private registration(provider: string): AdapterRegistration {\n const registration = this.adapters.get(provider)\n if (registration === undefined) {\n throw new ModelError(\n `no adapter registered for provider route \"${provider}\"`,\n REGISTRY_ERROR_CODES.NO_ADAPTER,\n )\n }\n return registration\n }\n\n}\n\nfunction positiveSafeInteger(value: number, label: string): number {\n if (!Number.isSafeInteger(value) || value < 1) {\n throw new RangeError(`ModelRegistry ${label} must be a positive safe integer`)\n }\n return value\n}\n\nfunction validateRuntimeDefaults(defaults: RuntimeDefaults): RuntimeDefaults {\n if (defaults.contextWindow !== undefined) positiveSafeInteger(defaults.contextWindow, 'defaults.contextWindow')\n if (defaults.maxTokens !== undefined) positiveSafeInteger(defaults.maxTokens, 'defaults.maxTokens')\n if (defaults.inputModalities !== undefined\n && (defaults.inputModalities.length === 0\n || new Set(defaults.inputModalities).size !== defaults.inputModalities.length)) {\n throw new RangeError('ModelRegistry defaults.inputModalities must be non-empty and unique')\n }\n return deepFreeze({\n ...(defaults.contextWindow === undefined ? {} : { contextWindow: defaults.contextWindow }),\n ...(defaults.maxTokens === undefined ? {} : { maxTokens: defaults.maxTokens }),\n ...(defaults.inputModalities === undefined ? {} : { inputModalities: [...defaults.inputModalities] }),\n })\n}\n"],"mappings":"qoBA6GA,SAAS,EAAgB,EAAyB,CAChD,IAAK,OAAO,GAAU,WAAY,IAAmB,OAAO,GAAU,WAAY,MAAO,GACzF,IAAI,EACJ,GAAI,CACF,EAAO,QAAQ,IAAI,EAAO,MAAM,CAClC,MAAQ,CACN,MAAO,EACT,CACA,GAAI,OAAO,GAAS,WAAY,MAAO,GACvC,GAAI,CAAE,QAAa,QAAQ,CAAK,CAAC,CAAC,UAAY,CAAC,CAAC,CAAE,MAAQ,CAAmC,CAC7F,MAAO,EACT,CAEA,SAAS,EAA0B,EAA0C,CAC3E,GAAI,CAEF,OAAO,EADiB,EACI,CAAC,EAAQ,UAAU,oCAAoC,EAAI,IAAA,EACzF,OAAS,EAAO,CACd,OAAO,CACT,CACF,CASA,IAAa,EAAb,KAA2B,CACzB,SAAmB,IAAI,IACvB,WAAyC,CAAC,EAC1C,UAAoB,IAAI,IACxB,QAAkB,IAAI,IACtB,iBACA,gBACA,YACA,oBACA,SAEA,YAAY,EAAgC,CAAC,EAAG,CAC9C,KAAK,iBAAmB,EAAoB,EAAQ,kBAAoB,KAAO,kBAAkB,EACjG,KAAK,gBAAkB,EAAoB,EAAQ,iBAAmB,QAAiB,iBAAiB,EACxG,KAAK,YAAc,EAAQ,YAC3B,KAAK,SAAW,EAAwB,EAAQ,UAAY,CAAC,CAAC,EAC9D,KAAK,oBAAsB,EAAW,EAAQ,qBAAuB,CACnE,QAAS,eACT,WAAA,SACA,QAAS,SACX,CAAC,CACH,CAGA,QAAQ,EAAuD,CAC7D,IAAM,EAAW,OAAO,GAAQ,IAAO,SAAW,EAAO,GAAK,GACxD,GAAQ,EAAiB,EAAiB,EAAsC,CAAC,IAAa,CAClG,IAAM,EAAS,CAAC,GAAG,IAAU,IAAA,GAAY,CAAC,EAAI,CAAC,CAAK,EAAG,GAAG,CAAe,EACnE,EAAe,EAAO,QAAU,EAAI,EAAO,GAAS,eAAe,EAAQ,UAAU,EAAS,wBAAwB,EAC5H,MAAM,IAAI,EAAY,EAAS,EAAmB,eAAgB,EAAU,IAAiB,IAAA,GAAY,IAAA,GAAY,CAAE,MAAO,CAAa,CAAC,CAC9I,GACI,EAAS,KAAK,CAAC,CAAC,SAAW,GAAK,IAAa,EAAS,KAAK,IAAG,EAAK,8CAA8C,EACjH,KAAK,QAAQ,IAAI,CAAQ,GAAG,EAAK,WAAW,EAAS,uBAAuB,GAC5E,OAAO,EAAO,aAAgB,UAAY,EAAO,YAAY,KAAK,CAAC,CAAC,SAAW,IAAG,EAAK,WAAW,EAAS,gCAAgC,EAC3I,OAAO,EAAO,OAAU,YAAY,EAAK,WAAW,EAAS,2BAA2B,EAC5F,IAAM,EAAS,EAAO,QAAU,GAC5B,OAAO,GAAW,UAAY,EAAO,KAAK,CAAC,CAAC,SAAW,GAAK,IAAW,EAAO,KAAK,IACrF,EAAK,WAAW,EAAS,4CAA4C,EAEvE,IAAM,EAAQ,OAAO,OAAO,CAAE,WAAU,QAAO,CAAC,EAQ1C,EAAkC,CAAC,EACnC,EAAuC,CAAC,EAC1C,EAAU,GAER,EAAoC,CACxC,iBAAkB,EAAQ,IAAY,CAEpC,GADK,GAAS,EAAK,WAAW,EAAS,8BAA8B,EACjE,EAAO,SAAW,EAAG,MAAM,IAAI,EAAW,uDAAwD,EAAqB,eAAe,EAC1I,IAAM,EAAsB,CAAE,OAAQ,GAAM,OAAQ,CAAC,GAAG,CAAM,EAAG,SAAQ,EAEnE,EAAW,IAAI,IAAI,EAAe,OAAO,GAAS,EAAM,MAAM,CAAC,CAAC,QAAQ,GAAS,EAAM,MAAM,CAAC,EACpG,IAAK,IAAM,KAAS,EAAQ,GAAI,EAAS,IAAI,CAAK,EAChD,MAAM,IAAI,EAAW,kCAAkC,EAAM,qBAAsB,EAAqB,iBAAiB,EAE3H,KAAK,cAAc,EAAQ,EAAS,IAAI,IAAO,CAAK,EACpD,EAAe,KAAK,CAAI,EACxB,IAAM,OAAgB,CAChB,IAAS,EAAK,OAAS,GAC7B,GAUA,MATA,GAAO,QAAW,GAAS,CACzB,GAAI,CAAC,GAAW,CAAC,EAAK,OAAQ,MAAM,IAAI,EAAW,uDAAwD,EAAqB,qBAAqB,EACrJ,IAAM,EAAmB,IAAI,IAAI,EAAe,OAAO,GAAS,EAAM,QAAU,IAAU,CAAI,CAAC,CAAC,QAAQ,GAAS,EAAM,MAAM,CAAC,EAC9H,IAAK,IAAM,KAAS,EAAM,GAAI,EAAiB,IAAI,CAAK,EACtD,MAAM,IAAI,EAAW,kCAAkC,EAAM,qBAAsB,EAAqB,iBAAiB,EAE3H,KAAK,cAAc,EAAM,EAAS,IAAI,IAAO,CAAK,EAClD,EAAK,OAAS,CAAC,GAAG,CAAI,CACxB,EACO,CACT,EACA,IAAM,GAAe,CAEnB,GADK,GAAS,EAAK,WAAW,EAAS,8BAA8B,EACjE,OAAO,GAAe,WAAY,MAAU,UAAU,sCAAsC,EAChG,IAAM,EAAyB,CAAE,OAAQ,GAAM,YAAW,EAE1D,OADA,EAAiB,KAAK,CAAI,MACb,CAAM,IAAS,EAAK,OAAS,GAAM,CAClD,CACF,EAEI,EACJ,GAAI,CACF,IAAM,EAAS,EAAO,MAAM,CAAS,EACjC,EAAgB,CAAM,GAAG,EAAK,WAAW,EAAS,4BAA4B,EAC9E,IAAW,IAAA,IAAa,OAAO,GAAW,YAAY,EAAK,WAAW,EAAS,uDAAuD,EAC1I,EAAU,OAAO,GAAW,WAAa,EAAS,IAAA,EACpD,OAAS,EAAO,CACd,GAAI,aAAiB,GAAe,EAAM,OAAS,EAAmB,eAAgB,MAAM,EAC5F,EAAK,WAAW,EAAS,gBAAiB,CAAK,CACjD,QAAU,CACR,EAAU,EACZ,CAEA,IAAM,EAAuC,CAAC,EACxC,EAAa,IAAI,IACvB,GAAI,CACF,IAAK,IAAM,KAAQ,EACZ,KAAK,OACV,KAAK,IAAM,KAAS,EAAK,OAAQ,CAC/B,GAAI,EAAW,IAAI,CAAK,EAAG,MAAM,IAAI,EAAW,kCAAkC,EAAM,qBAAsB,EAAqB,iBAAiB,EACpJ,EAAW,IAAI,CAAK,CACtB,CACA,EAAc,KAAK,GAAG,KAAK,cAAc,EAAK,OAAQ,EAAK,QAAS,IAAI,IAAO,CAAK,CAAC,CADrF,CAGJ,OAAS,EAAO,CACd,IAAM,EAA6B,CAAC,EACpC,GAAI,EAAS,CACX,IAAM,EAAiB,EAA0B,CAAO,EACpD,IAAmB,IAAA,IAAW,EAAgB,KAAK,CAAc,CACvE,CACA,EAAK,WAAW,EAAS,4BAA6B,EAAO,CAAe,CAC9E,CAEA,IAAM,EAAsB,EAAiB,OAAO,GAAQ,EAAK,MAAM,CAAC,CAAC,IAAI,GAAQ,EAAK,UAAU,EACpG,IAAK,IAAM,KAAgB,EAAe,KAAK,SAAS,IAAI,EAAa,SAAS,GAAI,CAAY,EAClG,KAAK,WAAW,KAAK,GAAG,CAAmB,EAC3C,IAAM,EAA6B,CACjC,OAAQ,EACR,gBACA,WAAY,EACZ,GAAI,IAAY,IAAA,GAAY,CAAC,EAAI,CAAE,SAAQ,CAC7C,EACA,KAAK,QAAQ,IAAI,EAAU,CAAS,EACpC,KAAK,oBAAoB,EAEzB,IAAI,EAAW,GACT,OAAiB,CACrB,GAAI,EAAU,OACd,EAAW,GACX,KAAK,QAAQ,OAAO,CAAQ,EAC5B,IAAK,IAAM,KAAgB,EAAU,cAC/B,KAAK,SAAS,IAAI,EAAa,SAAS,EAAE,IAAM,GAAc,KAAK,SAAS,OAAO,EAAa,SAAS,EAAE,EAEjH,IAAK,IAAI,EAAQ,EAAU,WAAW,OAAS,EAAG,GAAS,EAAG,IAAS,CACrE,IAAM,EAAa,EAAU,WAAW,GAClC,EAAY,IAAe,IAAA,GAAY,GAAK,KAAK,WAAW,YAAY,CAAU,EACpF,GAAa,GAAG,KAAK,WAAW,OAAO,EAAW,CAAC,CACzD,CACA,KAAK,oBAAoB,EACzB,IAAM,EAAsB,CAAC,EAC7B,GAAI,EAAU,QAAS,CACrB,IAAM,EAAiB,EAA0B,EAAU,OAAO,EAC9D,IAAmB,IAAA,IAAW,EAAS,KAAK,CAAc,CAChE,CACA,GAAI,EAAS,OAAS,EACpB,MAAM,IAAI,EACR,WAAW,EAAS,kBACpB,EAAmB,eACnB,EACA,CAAE,MAAW,eAAe,EAAU,WAAW,EAAS,iBAAiB,CAAE,CAC/E,CAEJ,GAEA,OADA,OAAO,eAAe,EAAS,WAAY,CAAE,MAAO,EAAU,WAAY,EAAK,CAAC,EACzE,CACT,CAWA,gBACE,EACA,EAC2B,CAC3B,GAAI,EAAU,SAAW,EACvB,MAAM,IAAI,EACR,uDACA,EAAqB,eACvB,EAGF,IAAM,EAAQ,IAAI,IAGd,EAAW,GAEf,KAAK,aAAa,EAAO,KAAK,cAAc,EAAW,EAAS,CAAK,CAAC,EAEtE,IAAM,OAAgB,CAChB,MACJ,GAAW,GACX,IAAK,IAAM,KAAY,EAAO,KAAK,SAAS,OAAO,CAAQ,EAC3D,EAAM,MAAM,EACZ,KAAK,oBAAoB,CAHd,CAIb,GAaA,MAXA,GAAO,QAAW,GAAkC,CAGlD,GAAI,EACF,MAAM,IAAI,EACR,4DACA,EAAqB,qBACvB,EAEF,KAAK,aAAa,EAAO,KAAK,cAAc,EAAM,EAAS,CAAK,CAAC,CACnE,EACO,CACT,CAOA,cACE,EACA,EACA,EACA,EACuB,CACvB,IAAM,EAAS,IAAI,IACb,EAAuC,CAAC,EAC9C,IAAK,IAAM,KAAY,EAAW,CAChC,GAAI,OAAO,GAAa,UAAY,EAAS,SAAW,EACtD,MAAM,IAAI,EACR,yDACA,EAAqB,eACvB,EAEF,GAAI,EAAO,IAAI,CAAQ,GAAM,KAAK,SAAS,IAAI,CAAQ,GAAK,CAAC,EAAM,IAAI,CAAQ,EAC7E,MAAM,IAAI,EACR,kCAAkC,EAAS,yBAC3C,EAAqB,iBACvB,EAEF,IAAM,EAAO,EAAQ,aAAa,CAAQ,EAC1C,GAAI,OAAO,EAAK,IAAO,UAAY,EAAK,KAAO,GAC1C,OAAO,EAAK,MAAS,UAAY,EAAK,KAAK,SAAW,EACzD,MAAM,IAAI,EACR,+BAA+B,EAAS,mDACxC,EAAqB,eACvB,EAEF,EAAO,IAAI,CAAQ,EACnB,EAAc,KAAK,CACjB,UACA,SAAU,CAAE,GAAI,EAAK,GAAI,KAAM,EAAK,IAAK,EACzC,GAAI,IAAU,IAAA,GAAY,CAAC,EAAI,EAG/B,YAAa,EAAQ,oBAAoB,CAAQ,GAC5C,EAAmB,IAAA,GAAW,aAAa,EAAS,cAAc,CACzE,CAAC,CACH,CACA,OAAO,CACT,CAMA,aACE,EACA,EACM,CACN,IAAK,IAAM,KAAY,EAAO,KAAK,SAAS,OAAO,CAAQ,EAC3D,EAAM,MAAM,EACZ,IAAK,IAAM,KAAgB,EACzB,KAAK,SAAS,IAAI,EAAa,SAAS,GAAI,CAAY,EACxD,EAAM,IAAI,EAAa,SAAS,EAAE,EAEpC,KAAK,oBAAoB,CAC3B,CAOA,IAAI,EAA0C,CAE5C,OADA,KAAK,WAAW,KAAK,CAAU,MAClB,CACX,IAAM,EAAQ,KAAK,WAAW,QAAQ,CAAU,EAC5C,GAAS,GAAG,KAAK,WAAW,OAAO,EAAO,CAAC,CACjD,CACF,CAOA,kBAAkB,EAAkC,CAElD,OADA,KAAK,UAAU,IAAI,CAAQ,MACd,KAAK,KAAK,UAAU,OAAO,CAAQ,CAClD,CASA,qBAAoC,CAClC,IAAK,IAAM,IAAY,CAAC,GAAG,KAAK,SAAS,EACvC,GAAI,CACF,EAAS,CACX,MAAQ,CAER,CAEJ,CAMA,eAAgC,CAC9B,MAAO,CAAC,GAAG,KAAK,SAAS,OAAO,CAAC,CAAC,CAAC,KAAK,CAAE,eAAgB,CAAE,GAAG,CAAS,EAAE,CAC5E,CAUA,MAAM,WAAW,EAAkB,EAA4C,CAE7E,IAAM,EAAS,MADM,KAAK,aAAa,CACP,CAAC,CAAC,QAAQ,WAAW,EAAU,CAAM,EACrE,OAAO,EAAsB,EAAU,EAAQ,KAAK,iBAAkB,KAAK,eAAe,CAC5F,CAGA,MAAM,aAAa,EAAkB,EAA+B,CAAC,EAAkC,CAErG,IAAM,EAAW,MADI,KAAK,aAAa,CACL,CAAC,CAAC,QAAQ,aAAa,EAAU,CAAO,EAC1E,OAAO,EAA6B,EAAU,EAAU,KAAK,iBAAkB,KAAK,eAAe,CACrG,CASA,MAAM,iBACJ,EACA,EACA,EAC4B,CAC5B,IAAM,EAAe,KAAK,aAAa,CAAQ,EACzC,EAAW,MAAM,EAAa,QAAQ,aAAa,EAAU,EAAO,CAAM,EAChF,OAAO,EAA2B,EAAa,SAAS,GAAI,EAAO,EAAU,KAAK,gBAAiB,KAAK,QAAQ,CAClH,CAGA,YAAY,EAAuC,CACjD,OAAO,KAAK,aAAa,CAAQ,CAAC,CAAC,WACrC,CASA,MAAM,YACJ,EACA,EACA,EACuB,CACvB,IAAM,EAAe,KAAK,aAAa,EAAO,QAAQ,EAChD,EAAc,MAAM,EAAa,QAAQ,YAAY,EAAO,SAAU,EAAO,MAAO,EAAQ,CAAiB,EAC7G,EAAY,EAChB,EAAa,SAAS,GAAI,EAAO,MAAO,EAAY,MAAO,KAAK,gBAAiB,KAAK,QACxF,EACM,EAAW,EAAyB,EAAQ,EAAW,KAAK,QAAQ,EACpE,EAAiB,EAAW,gBAAgB,EAAS,MAAM,CAAC,EAC5D,EAAU,EAAS,UAAY,IAAA,GACjC,IAAA,GACA,EAAW,gBAAgB,EAAS,OAAO,CAAC,EAC1C,EAAkB,EAAsC,CAC5D,GAAG,EAAO,YAAc,IAAA,IAAa,EAAe,YAAc,IAAA,GAC9D,CAAE,UAAW,EAAc,EAC3B,CAAC,CACP,CAAC,EAEG,EAAa,GACX,EAAQ,EAAW,gBAAgB,CAAS,CAAC,EACnD,OAAO,OAAO,OAAO,CACnB,OAAQ,EACR,QACA,YAAa,EAAa,YAC1B,kBACA,GAAG,IAAY,IAAA,GAAY,CAAC,EAAI,CAAE,SAAQ,EAC1C,GAAG,EAAS,kBAAoB,IAAA,GAC5B,CAAC,EACD,CAAE,gBAAiB,OAAO,OAAO,CAAC,GAAG,EAAS,eAAe,CAAC,CAAE,EACpE,QAAS,EAA0B,EAAU,IAAuC,CAGlF,GAAI,EACF,MAAM,IAAI,EACR,8CACA,EAAqB,qBACvB,EAEF,GAAI,CAAC,EAAiB,EAAS,CAAc,EAC3C,MAAM,IAAI,EACR,uDACA,EAAqB,qBACvB,EAGF,MADA,GAAa,GACN,KAAK,SAAS,EAAS,EAAS,CACrC,eACA,OAAQ,EACR,YACA,UAAW,EAAS,IAAkB,EAAY,OAAO,EAAS,CAAa,CACjF,CAAC,CACH,CACF,CAAC,CACH,CAYA,OAAO,EAA0B,EAAmD,CAClF,OAAO,KAAK,SAAS,EAAS,CAAO,CACvC,CAEA,SACE,EACA,EACA,EACiB,CACjB,IAAI,EAAwC,WACtC,EAAe,GAAU,cAAgB,KAAK,SAAS,IAAI,EAAQ,QAAQ,EACjF,OAAO,EAAsB,CAC3B,UACA,GAAI,GAAc,SAAW,IAAA,GAAY,CAAC,EAAI,CAAE,eAAgB,EAAa,MAAO,EACpF,GAAI,GAAc,WAAa,IAAA,GAAY,CAAC,EAAI,CAAE,iBAAkB,EAAa,QAAS,EAC1F,GAAI,IAAiB,IAAA,GAAY,CAAC,EAAI,CAAE,YAAc,GACpD,EAAa,YAAY,OAAS,UAC7B,EAAa,YAAY,eAAe,SAAS,CAAI,CAC1D,EACF,GAAI,IAAY,IAAA,GAAY,CAAC,EAAI,CAAE,SAAQ,EAC3C,GAAI,KAAK,cAAgB,IAAA,GAAY,CAAC,EAAI,CAAE,mBAAoB,KAAK,WAAY,EACjF,SAAU,KAAK,oBACf,aAAc,IAAa,IAAA,IAAa,KAAK,SAAS,IAAI,EAAQ,QAAQ,EAC1E,kBAAqB,EACrB,OAAQ,GAAiB,KAAK,YAC5B,EACA,MACM,CAAE,EAAgB,SAAU,EAClC,CACF,CACF,CAAC,CACH,CAcA,YACE,EACA,EACA,EACA,EAC4B,CAC5B,IAAM,EAAQ,CAAC,GAAG,KAAK,UAAU,EAC3B,MAAwC,CAC5C,IAAI,MAAyC,EAAc,CACzD,UAAS,UAAS,aAAY,gBAAiB,KAAK,gBAAiB,SAAU,KAAK,SACpF,aAAc,GAAY,KAAK,aAAa,CAAQ,EACpD,kBAAmB,GAAY,KAAK,SAAS,IAAI,CAAQ,CAAC,EAAE,QAC5D,GAAI,IAAa,IAAA,GAAY,CAAC,EAAI,CAAE,UAAS,CAC/C,CAAC,EACD,IAAK,IAAI,EAAQ,EAAM,OAAS,EAAG,GAAS,EAAG,IAAS,CACtD,IAAM,EAAa,EAAM,GACzB,GAAI,IAAe,IAAA,GAAW,SAC9B,IAAM,EAAQ,EACd,MAAa,EAAW,EAAS,EAAO,CAAO,CACjD,CACA,OAAO,EAAK,CACd,EACA,MAAO,CACL,OAAS,OAAO,gBAAiB,CAC/B,MAAO,EAAI,CACb,CACF,CACF,CAEA,aAAqB,EAAuC,CAC1D,IAAM,EAAe,KAAK,SAAS,IAAI,CAAQ,EAC/C,GAAI,IAAiB,IAAA,GACnB,MAAM,IAAI,EACR,6CAA6C,EAAS,GACtD,EAAqB,UACvB,EAEF,OAAO,CACT,CAEF,EAEA,SAAS,EAAoB,EAAe,EAAuB,CACjE,GAAI,CAAC,OAAO,cAAc,CAAK,GAAK,EAAQ,EAC1C,MAAU,WAAW,iBAAiB,EAAM,iCAAiC,EAE/E,OAAO,CACT,CAEA,SAAS,EAAwB,EAA4C,CAG3E,GAFI,EAAS,gBAAkB,IAAA,IAAW,EAAoB,EAAS,cAAe,wBAAwB,EAC1G,EAAS,YAAc,IAAA,IAAW,EAAoB,EAAS,UAAW,oBAAoB,EAC9F,EAAS,kBAAoB,IAAA,KAC3B,EAAS,gBAAgB,SAAW,GACnC,IAAI,IAAI,EAAS,eAAe,CAAC,CAAC,OAAS,EAAS,gBAAgB,QACzE,MAAU,WAAW,qEAAqE,EAE5F,OAAO,EAAW,CAChB,GAAI,EAAS,gBAAkB,IAAA,GAAY,CAAC,EAAI,CAAE,cAAe,EAAS,aAAc,EACxF,GAAI,EAAS,YAAc,IAAA,GAAY,CAAC,EAAI,CAAE,UAAW,EAAS,SAAU,EAC5E,GAAI,EAAS,kBAAoB,IAAA,GAAY,CAAC,EAAI,CAAE,gBAAiB,CAAC,GAAG,EAAS,eAAe,CAAE,CACrG,CAAC,CACH"}
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "name": "alvin0 - chaulamdinhai",
5
5
  "email": "chaulamdinhai@gmail.com"
6
6
  },
7
- "version": "0.1.9",
7
+ "version": "0.1.10",
8
8
  "description": "Universal contracts and runtime primitives for ai-agent-sdk",
9
9
  "license": "MIT",
10
10
  "repository": {