@od-oneapp/ai-platform 0.1.0
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 +235 -0
- package/dist/agents-base.d.mts +12 -0
- package/dist/agents-base.d.mts.map +1 -0
- package/dist/agents-base.mjs +20 -0
- package/dist/agents-base.mjs.map +1 -0
- package/dist/agents-control-flow.d.mts +115 -0
- package/dist/agents-control-flow.d.mts.map +1 -0
- package/dist/agents-control-flow.mjs +514 -0
- package/dist/agents-control-flow.mjs.map +1 -0
- package/dist/agents-coordinator.d.mts +11 -0
- package/dist/agents-coordinator.d.mts.map +1 -0
- package/dist/agents-coordinator.mjs +12 -0
- package/dist/agents-coordinator.mjs.map +1 -0
- package/dist/agents-experimental.d.mts +153 -0
- package/dist/agents-experimental.d.mts.map +1 -0
- package/dist/agents-experimental.mjs +580 -0
- package/dist/agents-experimental.mjs.map +1 -0
- package/dist/agents-fallback.d.mts +10 -0
- package/dist/agents-fallback.d.mts.map +1 -0
- package/dist/agents-fallback.mjs +15 -0
- package/dist/agents-fallback.mjs.map +1 -0
- package/dist/agents-multi-swarm.d.mts +9 -0
- package/dist/agents-multi-swarm.d.mts.map +1 -0
- package/dist/agents-multi-swarm.mjs +44 -0
- package/dist/agents-multi-swarm.mjs.map +1 -0
- package/dist/agents-multi.d.mts +10 -0
- package/dist/agents-multi.d.mts.map +1 -0
- package/dist/agents-multi.mjs +44 -0
- package/dist/agents-multi.mjs.map +1 -0
- package/dist/agents-observability.d.mts +161 -0
- package/dist/agents-observability.d.mts.map +1 -0
- package/dist/agents-observability.mjs +550 -0
- package/dist/agents-observability.mjs.map +1 -0
- package/dist/agents-patterns.d.mts +9 -0
- package/dist/agents-patterns.d.mts.map +1 -0
- package/dist/agents-patterns.mjs +18 -0
- package/dist/agents-patterns.mjs.map +1 -0
- package/dist/agents-persistence.d.mts +234 -0
- package/dist/agents-persistence.d.mts.map +1 -0
- package/dist/agents-persistence.mjs +447 -0
- package/dist/agents-persistence.mjs.map +1 -0
- package/dist/agents-triage.d.mts +11 -0
- package/dist/agents-triage.d.mts.map +1 -0
- package/dist/agents-triage.mjs +13 -0
- package/dist/agents-triage.mjs.map +1 -0
- package/dist/agents-workflows.d.mts +9 -0
- package/dist/agents-workflows.d.mts.map +1 -0
- package/dist/agents-workflows.mjs +9 -0
- package/dist/agents-workflows.mjs.map +1 -0
- package/dist/agents.d.mts +30 -0
- package/dist/agents.d.mts.map +1 -0
- package/dist/agents.mjs +50 -0
- package/dist/agents.mjs.map +1 -0
- package/dist/aggregation-8KJF1uzp.d.mts +276 -0
- package/dist/aggregation-8KJF1uzp.d.mts.map +1 -0
- package/dist/aggregation-BDop87kL.mjs +1180 -0
- package/dist/aggregation-BDop87kL.mjs.map +1 -0
- package/dist/ai-runtime-CDzQztTt.mjs +85 -0
- package/dist/ai-runtime-CDzQztTt.mjs.map +1 -0
- package/dist/ai-runtime-DIwOEc6g.d.mts +56 -0
- package/dist/ai-runtime-DIwOEc6g.d.mts.map +1 -0
- package/dist/ai-sdk-error-integration-D0GDqrM0.d.mts +553 -0
- package/dist/ai-sdk-error-integration-D0GDqrM0.d.mts.map +1 -0
- package/dist/approval-queue-BcDDQ4oQ.mjs +104 -0
- package/dist/approval-queue-BcDDQ4oQ.mjs.map +1 -0
- package/dist/approval-queue-CiKiFT9z.d.mts +21 -0
- package/dist/approval-queue-CiKiFT9z.d.mts.map +1 -0
- package/dist/audio-BzvN7r10.d.mts +79 -0
- package/dist/audio-BzvN7r10.d.mts.map +1 -0
- package/dist/audio-vBG_62ME.mjs +226 -0
- package/dist/audio-vBG_62ME.mjs.map +1 -0
- package/dist/audit-logger-Bb2JIcIk.d.mts +12 -0
- package/dist/audit-logger-Bb2JIcIk.d.mts.map +1 -0
- package/dist/audit-logger-CHIP8bRO.mjs +596 -0
- package/dist/audit-logger-CHIP8bRO.mjs.map +1 -0
- package/dist/auto-resume-BpUNbPtp.d.mts +160 -0
- package/dist/auto-resume-BpUNbPtp.d.mts.map +1 -0
- package/dist/auto-resume-BuFRNvAX.mjs +638 -0
- package/dist/auto-resume-BuFRNvAX.mjs.map +1 -0
- package/dist/budget-guard-C83KCH9V.d.mts +52 -0
- package/dist/budget-guard-C83KCH9V.d.mts.map +1 -0
- package/dist/budget-guard-d_b5rq4u.mjs +158 -0
- package/dist/budget-guard-d_b5rq4u.mjs.map +1 -0
- package/dist/budget-guard-gyhJS00s.mjs +234 -0
- package/dist/budget-guard-gyhJS00s.mjs.map +1 -0
- package/dist/buffer-BC8mvXHE.d.mts +98 -0
- package/dist/buffer-BC8mvXHE.d.mts.map +1 -0
- package/dist/buffer-CefJGbRy.mjs +289 -0
- package/dist/buffer-CefJGbRy.mjs.map +1 -0
- package/dist/caching-adapters.d.mts +5 -0
- package/dist/caching-adapters.mjs +3 -0
- package/dist/caching-strategies.d.mts +52 -0
- package/dist/caching-strategies.d.mts.map +1 -0
- package/dist/caching-strategies.mjs +703 -0
- package/dist/caching-strategies.mjs.map +1 -0
- package/dist/caching.d.mts +14 -0
- package/dist/caching.d.mts.map +1 -0
- package/dist/caching.mjs +15 -0
- package/dist/caching.mjs.map +1 -0
- package/dist/catalog.d.mts +19 -0
- package/dist/catalog.d.mts.map +1 -0
- package/dist/catalog.mjs +1114 -0
- package/dist/catalog.mjs.map +1 -0
- package/dist/chunk-CkzbjWQW.mjs +20 -0
- package/dist/circuit-breaker-DoKWPORd.mjs +262 -0
- package/dist/circuit-breaker-DoKWPORd.mjs.map +1 -0
- package/dist/circuit-breaker-Mey3E7tW.d.mts +64 -0
- package/dist/circuit-breaker-Mey3E7tW.d.mts.map +1 -0
- package/dist/citation-generator-C-9RpbHq.mjs +103 -0
- package/dist/citation-generator-C-9RpbHq.mjs.map +1 -0
- package/dist/citation-generator-CDSymDs_.d.mts +18 -0
- package/dist/citation-generator-CDSymDs_.d.mts.map +1 -0
- package/dist/client-CpacYDIE.mjs +882 -0
- package/dist/client-CpacYDIE.mjs.map +1 -0
- package/dist/client.d.mts +103 -0
- package/dist/client.d.mts.map +1 -0
- package/dist/client.mjs +470 -0
- package/dist/client.mjs.map +1 -0
- package/dist/compliance-approval-queue-DQGLojAm.mjs +172 -0
- package/dist/compliance-approval-queue-DQGLojAm.mjs.map +1 -0
- package/dist/compliance-approval-queue-IrMxFfSJ.d.mts +99 -0
- package/dist/compliance-approval-queue-IrMxFfSJ.d.mts.map +1 -0
- package/dist/compliance-wrapper-CrOMHhHN.mjs +528 -0
- package/dist/compliance-wrapper-CrOMHhHN.mjs.map +1 -0
- package/dist/conditions-DmQ6Y1Wt.mjs +179 -0
- package/dist/conditions-DmQ6Y1Wt.mjs.map +1 -0
- package/dist/conditions-zDrKfrc3.d.mts +42 -0
- package/dist/conditions-zDrKfrc3.d.mts.map +1 -0
- package/dist/console-BGMxxPZN.mjs +181 -0
- package/dist/console-BGMxxPZN.mjs.map +1 -0
- package/dist/console-DqEqZd4A.d.mts +76 -0
- package/dist/console-DqEqZd4A.d.mts.map +1 -0
- package/dist/controller-BOy3-xbC.mjs +501 -0
- package/dist/controller-BOy3-xbC.mjs.map +1 -0
- package/dist/controller-Y0NGosbJ.d.mts +104 -0
- package/dist/controller-Y0NGosbJ.d.mts.map +1 -0
- package/dist/coordinator-agent-BglqZLwo.d.mts +54 -0
- package/dist/coordinator-agent-BglqZLwo.d.mts.map +1 -0
- package/dist/coordinator-agent-WFWBRL-G.mjs +236 -0
- package/dist/coordinator-agent-WFWBRL-G.mjs.map +1 -0
- package/dist/crypto-8ABhc3TD.mjs +40 -0
- package/dist/crypto-8ABhc3TD.mjs.map +1 -0
- package/dist/environment-CSoJb0SW.mjs +255 -0
- package/dist/environment-CSoJb0SW.mjs.map +1 -0
- package/dist/error-handling-DNVkm6RY.mjs +1334 -0
- package/dist/error-handling-DNVkm6RY.mjs.map +1 -0
- package/dist/errors-CQ8tF4dP.mjs +985 -0
- package/dist/errors-CQ8tF4dP.mjs.map +1 -0
- package/dist/errors-CfYdVeum.d.mts +212 -0
- package/dist/errors-CfYdVeum.d.mts.map +1 -0
- package/dist/errors-Dtn-UeRi.mjs +61 -0
- package/dist/errors-Dtn-UeRi.mjs.map +1 -0
- package/dist/evaluator-Cs84qkr8.mjs +91 -0
- package/dist/evaluator-Cs84qkr8.mjs.map +1 -0
- package/dist/evaluator-optimizer-De67_mJC.mjs +1086 -0
- package/dist/evaluator-optimizer-De67_mJC.mjs.map +1 -0
- package/dist/evaluator-optimizer-pattern-B5939s2Z.mjs +367 -0
- package/dist/evaluator-optimizer-pattern-B5939s2Z.mjs.map +1 -0
- package/dist/evaluator-optimizer-pattern-D1AJrzBD.d.mts +72 -0
- package/dist/evaluator-optimizer-pattern-D1AJrzBD.d.mts.map +1 -0
- package/dist/factory-DP6VSl8C.mjs +307 -0
- package/dist/factory-DP6VSl8C.mjs.map +1 -0
- package/dist/generative-ui-catalog.d.mts +8 -0
- package/dist/generative-ui-catalog.d.mts.map +1 -0
- package/dist/generative-ui-catalog.mjs +679 -0
- package/dist/generative-ui-catalog.mjs.map +1 -0
- package/dist/generative-ui-registry.d.mts +195 -0
- package/dist/generative-ui-registry.d.mts.map +1 -0
- package/dist/generative-ui-registry.mjs +250 -0
- package/dist/generative-ui-registry.mjs.map +1 -0
- package/dist/generative-ui-stream.d.mts +23 -0
- package/dist/generative-ui-stream.d.mts.map +1 -0
- package/dist/generative-ui-stream.mjs +219 -0
- package/dist/generative-ui-stream.mjs.map +1 -0
- package/dist/generative-ui-types.d.mts +123 -0
- package/dist/generative-ui-types.d.mts.map +1 -0
- package/dist/generative-ui-types.mjs +1 -0
- package/dist/generative-ui.d.mts +13 -0
- package/dist/generative-ui.d.mts.map +1 -0
- package/dist/generative-ui.mjs +21 -0
- package/dist/generative-ui.mjs.map +1 -0
- package/dist/governance-audit.d.mts +3 -0
- package/dist/governance-audit.mjs +3 -0
- package/dist/governance-compliance.d.mts +5 -0
- package/dist/governance-compliance.mjs +4 -0
- package/dist/governance-policies.d.mts +4 -0
- package/dist/governance-policies.mjs +4 -0
- package/dist/governance-tenancy.d.mts +3 -0
- package/dist/governance-tenancy.mjs +3 -0
- package/dist/governance.d.mts +88 -0
- package/dist/governance.d.mts.map +1 -0
- package/dist/governance.mjs +432 -0
- package/dist/governance.mjs.map +1 -0
- package/dist/grounding-attribution.d.mts +63 -0
- package/dist/grounding-attribution.d.mts.map +1 -0
- package/dist/grounding-attribution.mjs +259 -0
- package/dist/grounding-attribution.mjs.map +1 -0
- package/dist/grounding-citation.d.mts +2 -0
- package/dist/grounding-citation.mjs +3 -0
- package/dist/grounding-context.d.mts +9 -0
- package/dist/grounding-context.d.mts.map +1 -0
- package/dist/grounding-context.mjs +19 -0
- package/dist/grounding-context.mjs.map +1 -0
- package/dist/grounding-embed.d.mts +102 -0
- package/dist/grounding-embed.d.mts.map +1 -0
- package/dist/grounding-embed.mjs +417 -0
- package/dist/grounding-embed.mjs.map +1 -0
- package/dist/grounding-hallucination.d.mts +44 -0
- package/dist/grounding-hallucination.d.mts.map +1 -0
- package/dist/grounding-hallucination.mjs +115 -0
- package/dist/grounding-hallucination.mjs.map +1 -0
- package/dist/grounding-proof-map.d.mts +9 -0
- package/dist/grounding-proof-map.d.mts.map +1 -0
- package/dist/grounding-proof-map.mjs +26 -0
- package/dist/grounding-proof-map.mjs.map +1 -0
- package/dist/grounding-rag.d.mts +10 -0
- package/dist/grounding-rag.d.mts.map +1 -0
- package/dist/grounding-rag.mjs +27 -0
- package/dist/grounding-rag.mjs.map +1 -0
- package/dist/grounding-verification.d.mts +48 -0
- package/dist/grounding-verification.d.mts.map +1 -0
- package/dist/grounding-verification.mjs +224 -0
- package/dist/grounding-verification.mjs.map +1 -0
- package/dist/grounding.d.mts +24 -0
- package/dist/grounding.d.mts.map +1 -0
- package/dist/grounding.mjs +77 -0
- package/dist/grounding.mjs.map +1 -0
- package/dist/hitl-active-learning.d.mts +41 -0
- package/dist/hitl-active-learning.d.mts.map +1 -0
- package/dist/hitl-active-learning.mjs +178 -0
- package/dist/hitl-active-learning.mjs.map +1 -0
- package/dist/hitl-annotation.d.mts +74 -0
- package/dist/hitl-annotation.d.mts.map +1 -0
- package/dist/hitl-annotation.mjs +170 -0
- package/dist/hitl-annotation.mjs.map +1 -0
- package/dist/hitl-approval.d.mts +2 -0
- package/dist/hitl-approval.mjs +3 -0
- package/dist/hitl-feedback.d.mts +59 -0
- package/dist/hitl-feedback.d.mts.map +1 -0
- package/dist/hitl-feedback.mjs +137 -0
- package/dist/hitl-feedback.mjs.map +1 -0
- package/dist/hitl-review.d.mts +2 -0
- package/dist/hitl-review.mjs +3 -0
- package/dist/hitl.d.mts +14 -0
- package/dist/hitl.d.mts.map +1 -0
- package/dist/hitl.mjs +22 -0
- package/dist/hitl.mjs.map +1 -0
- package/dist/index-B17HT-VL.d.mts +285 -0
- package/dist/index-B17HT-VL.d.mts.map +1 -0
- package/dist/index-BDwgsK9B.d.mts +101 -0
- package/dist/index-BDwgsK9B.d.mts.map +1 -0
- package/dist/index-BGgMn_Ev.d.mts +2615 -0
- package/dist/index-BGgMn_Ev.d.mts.map +1 -0
- package/dist/index-DOqe5r9G.d.mts +318 -0
- package/dist/index-DOqe5r9G.d.mts.map +1 -0
- package/dist/index-DotINT7o.d.mts +1004 -0
- package/dist/index-DotINT7o.d.mts.map +1 -0
- package/dist/index-URlW7aD1.d.mts +67 -0
- package/dist/index-URlW7aD1.d.mts.map +1 -0
- package/dist/index.d.mts +64 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +46 -0
- package/dist/index.mjs.map +1 -0
- package/dist/integrations-blob-storage.d.mts +25 -0
- package/dist/integrations-blob-storage.d.mts.map +1 -0
- package/dist/integrations-blob-storage.mjs +3 -0
- package/dist/integrations-notifications.d.mts +2 -0
- package/dist/integrations-notifications.mjs +3 -0
- package/dist/integrations-rate-limit.d.mts +27 -0
- package/dist/integrations-rate-limit.d.mts.map +1 -0
- package/dist/integrations-rate-limit.mjs +30 -0
- package/dist/integrations-rate-limit.mjs.map +1 -0
- package/dist/integrations-redis.d.mts +3 -0
- package/dist/integrations-redis.mjs +3 -0
- package/dist/integrations-stream.d.mts +14 -0
- package/dist/integrations-stream.d.mts.map +1 -0
- package/dist/integrations-stream.mjs +3 -0
- package/dist/integrations.d.mts +7 -0
- package/dist/integrations.mjs +7 -0
- package/dist/log-adapter-BLegSZtz.d.mts +16 -0
- package/dist/log-adapter-BLegSZtz.d.mts.map +1 -0
- package/dist/log-adapter-PPe_2Pwv.mjs +28 -0
- package/dist/log-adapter-PPe_2Pwv.mjs.map +1 -0
- package/dist/loop-BOYEtr2g.mjs +520 -0
- package/dist/loop-BOYEtr2g.mjs.map +1 -0
- package/dist/loop-C-tBBOqi.d.mts +219 -0
- package/dist/loop-C-tBBOqi.d.mts.map +1 -0
- package/dist/middleware-5wQ9bANW.mjs +306 -0
- package/dist/middleware-5wQ9bANW.mjs.map +1 -0
- package/dist/middleware-C1apSrj0.mjs +613 -0
- package/dist/middleware-C1apSrj0.mjs.map +1 -0
- package/dist/middleware-C7k0uItW.d.mts +9 -0
- package/dist/middleware-C7k0uItW.d.mts.map +1 -0
- package/dist/middleware-CZQCTHfl.mjs +366 -0
- package/dist/middleware-CZQCTHfl.mjs.map +1 -0
- package/dist/models.d.mts +11 -0
- package/dist/models.d.mts.map +1 -0
- package/dist/models.mjs +32 -0
- package/dist/models.mjs.map +1 -0
- package/dist/observability-analytics.d.mts +107 -0
- package/dist/observability-analytics.d.mts.map +1 -0
- package/dist/observability-analytics.mjs +409 -0
- package/dist/observability-analytics.mjs.map +1 -0
- package/dist/observability-cost.d.mts +10 -0
- package/dist/observability-cost.d.mts.map +1 -0
- package/dist/observability-cost.mjs +15 -0
- package/dist/observability-cost.mjs.map +1 -0
- package/dist/observability-telemetry.d.mts +111 -0
- package/dist/observability-telemetry.d.mts.map +1 -0
- package/dist/observability-telemetry.mjs +343 -0
- package/dist/observability-telemetry.mjs.map +1 -0
- package/dist/observability-tracing.d.mts +10 -0
- package/dist/observability-tracing.d.mts.map +1 -0
- package/dist/observability-tracing.mjs +17 -0
- package/dist/observability-tracing.mjs.map +1 -0
- package/dist/observability.d.mts +15 -0
- package/dist/observability.d.mts.map +1 -0
- package/dist/observability.mjs +17 -0
- package/dist/observability.mjs.map +1 -0
- package/dist/optimizer-DhXXpci6.mjs +97 -0
- package/dist/optimizer-DhXXpci6.mjs.map +1 -0
- package/dist/output-multimodal.d.mts +9 -0
- package/dist/output-multimodal.d.mts.map +1 -0
- package/dist/output-multimodal.mjs +18 -0
- package/dist/output-multimodal.mjs.map +1 -0
- package/dist/output.d.mts +11 -0
- package/dist/output.d.mts.map +1 -0
- package/dist/output.mjs +40 -0
- package/dist/output.mjs.map +1 -0
- package/dist/pii-filter-3AxmYSiu.d.mts +23 -0
- package/dist/pii-filter-3AxmYSiu.d.mts.map +1 -0
- package/dist/pipelines.d.mts +448 -0
- package/dist/pipelines.d.mts.map +1 -0
- package/dist/pipelines.mjs +1534 -0
- package/dist/pipelines.mjs.map +1 -0
- package/dist/prompt-injection-DQXchzsV.d.mts +8 -0
- package/dist/prompt-injection-DQXchzsV.d.mts.map +1 -0
- package/dist/prompt-injection-RpoLPwSa.mjs +52 -0
- package/dist/prompt-injection-RpoLPwSa.mjs.map +1 -0
- package/dist/prompts.d.mts +192 -0
- package/dist/prompts.d.mts.map +1 -0
- package/dist/prompts.mjs +732 -0
- package/dist/prompts.mjs.map +1 -0
- package/dist/protocol-DfBiEsnl.d.mts +112 -0
- package/dist/protocol-DfBiEsnl.d.mts.map +1 -0
- package/dist/quota-manager-0iPMkQWN.d.mts +62 -0
- package/dist/quota-manager-0iPMkQWN.d.mts.map +1 -0
- package/dist/quota-manager-D_N7FuQ2.mjs +180 -0
- package/dist/quota-manager-D_N7FuQ2.mjs.map +1 -0
- package/dist/redaction-utils-DcQwsiNh.mjs +438 -0
- package/dist/redaction-utils-DcQwsiNh.mjs.map +1 -0
- package/dist/redis-CpsSrF8K.mjs +102 -0
- package/dist/redis-CpsSrF8K.mjs.map +1 -0
- package/dist/redis-CwguYFGh.d.mts +33 -0
- package/dist/redis-CwguYFGh.d.mts.map +1 -0
- package/dist/registry-CsD3iTIx.mjs +190 -0
- package/dist/registry-CsD3iTIx.mjs.map +1 -0
- package/dist/registry-DVPWzkXR.d.mts +36 -0
- package/dist/registry-DVPWzkXR.d.mts.map +1 -0
- package/dist/reranking-BpWYhYzl.d.mts +72 -0
- package/dist/reranking-BpWYhYzl.d.mts.map +1 -0
- package/dist/reranking-Ck8aKZW7.mjs +331 -0
- package/dist/reranking-Ck8aKZW7.mjs.map +1 -0
- package/dist/resumable-adapter-CO1HtsgJ.mjs +21 -0
- package/dist/resumable-adapter-CO1HtsgJ.mjs.map +1 -0
- package/dist/review-trigger-DmAsiQlM.d.mts +24 -0
- package/dist/review-trigger-DmAsiQlM.d.mts.map +1 -0
- package/dist/review-trigger-DwXfpww9.mjs +112 -0
- package/dist/review-trigger-DwXfpww9.mjs.map +1 -0
- package/dist/safe-context-BynhkTKR.d.mts +54 -0
- package/dist/safe-context-BynhkTKR.d.mts.map +1 -0
- package/dist/safe-context-C5A3Wv3b.mjs +143 -0
- package/dist/safe-context-C5A3Wv3b.mjs.map +1 -0
- package/dist/schema-Bu2noOZ4.mjs +27 -0
- package/dist/schema-Bu2noOZ4.mjs.map +1 -0
- package/dist/schema-CwFvuCnA.mjs +97 -0
- package/dist/schema-CwFvuCnA.mjs.map +1 -0
- package/dist/schema-Wz-1-ro9.d.mts +37 -0
- package/dist/schema-Wz-1-ro9.d.mts.map +1 -0
- package/dist/schemas-CxQtxIga.mjs +62 -0
- package/dist/schemas-CxQtxIga.mjs.map +1 -0
- package/dist/schemas-DBOhxgW7.d.mts +32 -0
- package/dist/schemas-DBOhxgW7.d.mts.map +1 -0
- package/dist/schemas-Dp_OCqBt.d.mts +63 -0
- package/dist/schemas-Dp_OCqBt.d.mts.map +1 -0
- package/dist/schemas-SwCsnT0z.mjs +83 -0
- package/dist/schemas-SwCsnT0z.mjs.map +1 -0
- package/dist/sdk-errors.d.mts +2 -0
- package/dist/sdk-errors.mjs +3 -0
- package/dist/sdk-experimental.d.mts +59 -0
- package/dist/sdk-experimental.d.mts.map +1 -0
- package/dist/sdk-experimental.mjs +193 -0
- package/dist/sdk-experimental.mjs.map +1 -0
- package/dist/sdk-stop-conditions.d.mts +3 -0
- package/dist/sdk-stop-conditions.mjs +3 -0
- package/dist/sdk.d.mts +15 -0
- package/dist/sdk.d.mts.map +1 -0
- package/dist/sdk.mjs +50 -0
- package/dist/sdk.mjs.map +1 -0
- package/dist/security-guardrails.d.mts +3 -0
- package/dist/security-guardrails.mjs +3 -0
- package/dist/security-injection.d.mts +2 -0
- package/dist/security-injection.mjs +3 -0
- package/dist/security.d.mts +12 -0
- package/dist/security.d.mts.map +1 -0
- package/dist/security.mjs +18 -0
- package/dist/security.mjs.map +1 -0
- package/dist/server.d.mts +420 -0
- package/dist/server.d.mts.map +1 -0
- package/dist/server.mjs +2225 -0
- package/dist/server.mjs.map +1 -0
- package/dist/shared.d.mts +2 -0
- package/dist/shared.mjs +3 -0
- package/dist/streaming-control.d.mts +2 -0
- package/dist/streaming-control.mjs +4 -0
- package/dist/streaming-core.d.mts +4 -0
- package/dist/streaming-core.mjs +3 -0
- package/dist/streaming-infra-resilience.d.mts +120 -0
- package/dist/streaming-infra-resilience.d.mts.map +1 -0
- package/dist/streaming-infra-resilience.mjs +358 -0
- package/dist/streaming-infra-resilience.mjs.map +1 -0
- package/dist/streaming-infra-transport.d.mts +57 -0
- package/dist/streaming-infra-transport.d.mts.map +1 -0
- package/dist/streaming-infra-transport.mjs +488 -0
- package/dist/streaming-infra-transport.mjs.map +1 -0
- package/dist/streaming-infra.d.mts +5 -0
- package/dist/streaming-infra.mjs +5 -0
- package/dist/streaming.d.mts +17 -0
- package/dist/streaming.d.mts.map +1 -0
- package/dist/streaming.mjs +71 -0
- package/dist/streaming.mjs.map +1 -0
- package/dist/telemetry-2eKMojIb.mjs +1046 -0
- package/dist/telemetry-2eKMojIb.mjs.map +1 -0
- package/dist/telemetry-C2t03dwD.d.mts +59 -0
- package/dist/telemetry-C2t03dwD.d.mts.map +1 -0
- package/dist/tool-Btbththq.d.mts +253 -0
- package/dist/tool-Btbththq.d.mts.map +1 -0
- package/dist/tool-JSf8JXZ8.mjs +1150 -0
- package/dist/tool-JSf8JXZ8.mjs.map +1 -0
- package/dist/tool-safety-CZO8a4D4.d.mts +60 -0
- package/dist/tool-safety-CZO8a4D4.d.mts.map +1 -0
- package/dist/tool-safety-DXtYDXod.mjs +319 -0
- package/dist/tool-safety-DXtYDXod.mjs.map +1 -0
- package/dist/tools-BuS2Uv0q.mjs +1708 -0
- package/dist/tools-BuS2Uv0q.mjs.map +1 -0
- package/dist/tools-approval.d.mts +99 -0
- package/dist/tools-approval.d.mts.map +1 -0
- package/dist/tools-approval.mjs +395 -0
- package/dist/tools-approval.mjs.map +1 -0
- package/dist/tools-compliance.d.mts +67 -0
- package/dist/tools-compliance.d.mts.map +1 -0
- package/dist/tools-compliance.mjs +330 -0
- package/dist/tools-compliance.mjs.map +1 -0
- package/dist/tools-computer.d.mts +25 -0
- package/dist/tools-computer.d.mts.map +1 -0
- package/dist/tools-computer.mjs +64 -0
- package/dist/tools-computer.mjs.map +1 -0
- package/dist/tools-core.d.mts +3 -0
- package/dist/tools-core.mjs +3 -0
- package/dist/tools-mcp.d.mts +3 -0
- package/dist/tools-mcp.mjs +5 -0
- package/dist/tools-superpowers.d.mts +2 -0
- package/dist/tools-superpowers.mjs +3 -0
- package/dist/tools.d.mts +401 -0
- package/dist/tools.d.mts.map +1 -0
- package/dist/tools.mjs +1921 -0
- package/dist/tools.mjs.map +1 -0
- package/dist/transport-selector-D-Ib05X1.mjs +1936 -0
- package/dist/transport-selector-D-Ib05X1.mjs.map +1 -0
- package/dist/triage-agent-BEsXg5sw.d.mts +63 -0
- package/dist/triage-agent-BEsXg5sw.d.mts.map +1 -0
- package/dist/triage-agent-CBsfX-HW.mjs +167 -0
- package/dist/triage-agent-CBsfX-HW.mjs.map +1 -0
- package/dist/types-BPnq3GQo.d.mts +23 -0
- package/dist/types-BPnq3GQo.d.mts.map +1 -0
- package/dist/types-BjWgimpY.d.mts +16 -0
- package/dist/types-BjWgimpY.d.mts.map +1 -0
- package/dist/types-BxD-5btB.d.mts +41 -0
- package/dist/types-BxD-5btB.d.mts.map +1 -0
- package/dist/types-By-r93bE.d.mts +36 -0
- package/dist/types-By-r93bE.d.mts.map +1 -0
- package/dist/types-CLBWFRZN.d.mts +69 -0
- package/dist/types-CLBWFRZN.d.mts.map +1 -0
- package/dist/types-CQ0HFd0u.d.mts +62 -0
- package/dist/types-CQ0HFd0u.d.mts.map +1 -0
- package/dist/types-D3zJb59_.d.mts +47 -0
- package/dist/types-D3zJb59_.d.mts.map +1 -0
- package/dist/types-DJnugQX0.d.mts +80 -0
- package/dist/types-DJnugQX0.d.mts.map +1 -0
- package/dist/types-DbUfMCnT.d.mts +70 -0
- package/dist/types-DbUfMCnT.d.mts.map +1 -0
- package/dist/upstash-adapter-D96Caq2O.mjs +22 -0
- package/dist/upstash-adapter-D96Caq2O.mjs.map +1 -0
- package/dist/upstash-adapter-DD4433dx.d.mts +8 -0
- package/dist/upstash-adapter-DD4433dx.d.mts.map +1 -0
- package/dist/utils-BlYhcD6M.mjs +319 -0
- package/dist/utils-BlYhcD6M.mjs.map +1 -0
- package/dist/utils-DpJGOb3y.d.mts +120 -0
- package/dist/utils-DpJGOb3y.d.mts.map +1 -0
- package/dist/vercel-blob-adapter-CkOXLT2D.mjs +25 -0
- package/dist/vercel-blob-adapter-CkOXLT2D.mjs.map +1 -0
- package/dist/xai-CbV_dCnP.mjs +1600 -0
- package/dist/xai-CbV_dCnP.mjs.map +1 -0
- package/package.json +479 -0
- package/src/agents/base/factory.ts +382 -0
- package/src/agents/base/index.ts +8 -0
- package/src/agents/base/schemas.ts +117 -0
- package/src/agents/base/types.ts +192 -0
- package/src/agents/control-flow/index.ts +683 -0
- package/src/agents/coordinator/coordinator-agent.ts +381 -0
- package/src/agents/coordinator/index.ts +6 -0
- package/src/agents/default-agent.ts +211 -0
- package/src/agents/evaluator-optimizer/README.md +612 -0
- package/src/agents/evaluator-optimizer/evaluator-optimizer.example.ts +437 -0
- package/src/agents/evaluator-optimizer/evaluator.ts +282 -0
- package/src/agents/evaluator-optimizer/index.test.ts +416 -0
- package/src/agents/evaluator-optimizer/index.ts +519 -0
- package/src/agents/evaluator-optimizer/optimizer.ts +322 -0
- package/src/agents/evaluator-optimizer/schema.ts +302 -0
- package/src/agents/evaluator-optimizer/utils.ts +42 -0
- package/src/agents/experimental/index.ts +1095 -0
- package/src/agents/experimental/types.ts +212 -0
- package/src/agents/fallback/index.ts +18 -0
- package/src/agents/fallback/recovery/circuit-breaker.ts +166 -0
- package/src/agents/fallback/strategies/model-fallback.ts +192 -0
- package/src/agents/fallback/types.ts +87 -0
- package/src/agents/governance-agent.ts +446 -0
- package/src/agents/index.ts +79 -0
- package/src/agents/multi/coordination/index.ts +6 -0
- package/src/agents/multi/coordination/message-bus.ts +144 -0
- package/src/agents/multi/index.ts +6 -0
- package/src/agents/multi/state/index.ts +162 -0
- package/src/agents/multi/supervisor/index.ts +7 -0
- package/src/agents/multi/supervisor/supervisor.ts +254 -0
- package/src/agents/multi/swarm/aggregation.ts +466 -0
- package/src/agents/multi/swarm/communication.ts +388 -0
- package/src/agents/multi/swarm/coordination.ts +380 -0
- package/src/agents/multi/swarm/index.ts +73 -0
- package/src/agents/multi/swarm/swarm-executor.ts +479 -0
- package/src/agents/multi/types.ts +181 -0
- package/src/agents/observability/index.ts +914 -0
- package/src/agents/orchestrator.ts +218 -0
- package/src/agents/patterns/README.md +512 -0
- package/src/agents/patterns/evaluator-optimizer-pattern.example.ts +455 -0
- package/src/agents/patterns/evaluator-optimizer-pattern.ts +653 -0
- package/src/agents/patterns/index.ts +26 -0
- package/src/agents/persistence/index.ts +726 -0
- package/src/agents/tools/index.ts +291 -0
- package/src/agents/tools/mcp.ts +188 -0
- package/src/agents/triage/index.ts +6 -0
- package/src/agents/triage/triage-agent.ts +280 -0
- package/src/agents/workflows/index.ts +6 -0
- package/src/agents/workflows/interfaces.ts +36 -0
- package/src/agents/workflows/schema.ts +20 -0
- package/src/caching/adapters/index.ts +7 -0
- package/src/caching/adapters/memory.ts +77 -0
- package/src/caching/adapters/redis.ts +60 -0
- package/src/caching/index.ts +17 -0
- package/src/caching/middleware.ts +452 -0
- package/src/caching/strategies/index.ts +1008 -0
- package/src/caching/types.ts +47 -0
- package/src/catalog.ts +921 -0
- package/src/client/chat-usage.ts +53 -0
- package/src/client/hooks.ts +343 -0
- package/src/client/index.ts +36 -0
- package/src/client/message-utils.ts +29 -0
- package/src/client/use-generative-ui.ts +174 -0
- package/src/client/utils.ts +66 -0
- package/src/generative-ui/catalog.ts +653 -0
- package/src/generative-ui/index.ts +82 -0
- package/src/generative-ui/registry.ts +273 -0
- package/src/generative-ui/stream.ts +324 -0
- package/src/generative-ui/types.ts +376 -0
- package/src/governance/audit/audit-logger.ts +239 -0
- package/src/governance/audit/audit-schema.ts +82 -0
- package/src/governance/audit/index.ts +6 -0
- package/src/governance/compliance/abac/policy-engine.ts +175 -0
- package/src/governance/compliance/abac/types.ts +40 -0
- package/src/governance/compliance/approval/compliance-approval-queue.ts +217 -0
- package/src/governance/compliance/index.ts +16 -0
- package/src/governance/compliance/schemas.ts +68 -0
- package/src/governance/compliance/types.ts +143 -0
- package/src/governance/compliance/validators/phi-detector.ts +145 -0
- package/src/governance/compliance/validators/redaction-utils.ts +176 -0
- package/src/governance/compliance/validators/safe-harbor.ts +135 -0
- package/src/governance/entitlements/index.ts +585 -0
- package/src/governance/entitlements/middleware.ts +651 -0
- package/src/governance/entitlements/rate-limiter.ts +711 -0
- package/src/governance/index.ts +32 -0
- package/src/governance/policies/guardrails.ts +1121 -0
- package/src/governance/policies/index.ts +42 -0
- package/src/governance/policies/loop-controls.ts +136 -0
- package/src/governance/policies/telemetry.ts +63 -0
- package/src/governance/tenancy/index.ts +30 -0
- package/src/governance/tenancy/isolation/context.ts +92 -0
- package/src/governance/tenancy/isolation/index.ts +13 -0
- package/src/governance/tenancy/quotas/index.ts +11 -0
- package/src/governance/tenancy/quotas/quota-manager.ts +180 -0
- package/src/governance/tenancy/types.ts +66 -0
- package/src/governance/types.ts +16 -0
- package/src/governance/versioning/index.ts +573 -0
- package/src/grounding/attribution/index.ts +424 -0
- package/src/grounding/citation/citation-generator.ts +174 -0
- package/src/grounding/citation/index.ts +12 -0
- package/src/grounding/context/index.ts +32 -0
- package/src/grounding/context/safe-context.ts +116 -0
- package/src/grounding/context/types.ts +62 -0
- package/src/grounding/context-engineering/error-handling.ts +359 -0
- package/src/grounding/context-engineering/index.ts +23 -0
- package/src/grounding/context-engineering/memory.ts +559 -0
- package/src/grounding/context-engineering/tool-masking.ts +338 -0
- package/src/grounding/embed/index.ts +704 -0
- package/src/grounding/embed/reranking.ts +604 -0
- package/src/grounding/hallucination/index.ts +223 -0
- package/src/grounding/index.ts +82 -0
- package/src/grounding/proof-map/applyPatch.ts +172 -0
- package/src/grounding/proof-map/index.ts +41 -0
- package/src/grounding/proof-map/loop.ts +275 -0
- package/src/grounding/proof-map/schema.ts +217 -0
- package/src/grounding/rag/__tests__/pipeline.test.ts +274 -0
- package/src/grounding/rag/__tests__/tool.test.ts +202 -0
- package/src/grounding/rag/__tests__/trace.test.ts +229 -0
- package/src/grounding/rag/circuit-breaker.ts +152 -0
- package/src/grounding/rag/index.ts +64 -0
- package/src/grounding/rag/pipeline.ts +602 -0
- package/src/grounding/rag/tool.ts +281 -0
- package/src/grounding/rag/trace.ts +503 -0
- package/src/grounding/rag/types.ts +284 -0
- package/src/grounding/retrieval/in-memory-store.ts +107 -0
- package/src/grounding/sources/index.ts +943 -0
- package/src/grounding/tests/applyPatch.test.ts +194 -0
- package/src/grounding/tests/loop.test.ts +141 -0
- package/src/grounding/tests/schema.test.ts +160 -0
- package/src/grounding/types.ts +100 -0
- package/src/grounding/verification/index.ts +419 -0
- package/src/hitl/active-learning/index.ts +332 -0
- package/src/hitl/annotation/index.ts +362 -0
- package/src/hitl/approval/approval-queue.ts +132 -0
- package/src/hitl/approval/index.ts +5 -0
- package/src/hitl/feedback/index.ts +284 -0
- package/src/hitl/index.ts +69 -0
- package/src/hitl/review/index.ts +6 -0
- package/src/hitl/review/review-trigger.ts +162 -0
- package/src/hitl/types.ts +126 -0
- package/src/index.ts +125 -0
- package/src/integrations/blob-storage/index.ts +7 -0
- package/src/integrations/blob-storage/types.ts +28 -0
- package/src/integrations/blob-storage/vercel-blob-adapter.ts +35 -0
- package/src/integrations/index.ts +15 -0
- package/src/integrations/notifications/index.ts +7 -0
- package/src/integrations/notifications/log-adapter.ts +30 -0
- package/src/integrations/notifications/types.ts +27 -0
- package/src/integrations/rate-limit/index.ts +7 -0
- package/src/integrations/rate-limit/types.ts +26 -0
- package/src/integrations/rate-limit/upstash-adapter.ts +45 -0
- package/src/integrations/redis/index.ts +7 -0
- package/src/integrations/redis/types.ts +67 -0
- package/src/integrations/redis/upstash-adapter.ts +18 -0
- package/src/integrations/stream/index.ts +7 -0
- package/src/integrations/stream/resumable-adapter.ts +20 -0
- package/src/integrations/stream/types.ts +21 -0
- package/src/internal/__tests__/hallucination.test.ts +162 -0
- package/src/internal/__tests__/models.test.ts +104 -0
- package/src/internal/__tests__/sdk-errors.test.ts +201 -0
- package/src/internal/__tests__/stop-conditions.test.ts +210 -0
- package/src/internal/shared/ai-types.ts +942 -0
- package/src/internal/testing/evaluators.ts +575 -0
- package/src/internal/testing/index.ts +960 -0
- package/src/internal/ui/data-parts.ts +511 -0
- package/src/internal/ui/type-guards.ts +344 -0
- package/src/internal/ui-factories/__tests__/ui-factories.test.ts +548 -0
- package/src/internal/ui-factories/artifact-factory.ts +667 -0
- package/src/internal/ui-factories/index.ts +82 -0
- package/src/internal/ui-factories/shimmer-manager.ts +220 -0
- package/src/internal/ui-factories/status-helpers.ts +149 -0
- package/src/internal/ui-factories/tool-renderer.ts +167 -0
- package/src/internal/ui-factories/types.ts +235 -0
- package/src/models/capabilities.ts +88 -0
- package/src/models/index.ts +16 -0
- package/src/models/provider-factory.ts +229 -0
- package/src/models/providers/anthropic.ts +539 -0
- package/src/models/providers/google.ts +354 -0
- package/src/models/providers/index.ts +21 -0
- package/src/models/providers/openai.ts +346 -0
- package/src/models/providers/perplexity.ts +276 -0
- package/src/models/providers/shared.ts +90 -0
- package/src/models/providers/xai.ts +269 -0
- package/src/models/registry.ts +208 -0
- package/src/models/routing/index.ts +45 -0
- package/src/models/routing/intent-router.ts +143 -0
- package/src/models/routing/model-router.ts +300 -0
- package/src/models/routing/types.ts +106 -0
- package/src/models/types.ts +23 -0
- package/src/observability/analytics/index.ts +593 -0
- package/src/observability/cost/index.ts +16 -0
- package/src/observability/cost/tracking/budget-guard.ts +110 -0
- package/src/observability/cost/tracking/usage-tracker.ts +120 -0
- package/src/observability/cost/types.ts +85 -0
- package/src/observability/index.ts +17 -0
- package/src/observability/telemetry/index.ts +508 -0
- package/src/observability/tracing/index.ts +30 -0
- package/src/observability/tracing/otel/ai-instrumentation.ts +193 -0
- package/src/observability/tracing/otel/exporters/console.ts +58 -0
- package/src/observability/tracing/otel/exporters/index.ts +6 -0
- package/src/observability/tracing/provenance.ts +769 -0
- package/src/observability/tracing/types.ts +92 -0
- package/src/output/__tests__/output.test.ts +737 -0
- package/src/output/element-stream.ts +678 -0
- package/src/output/errors.ts +108 -0
- package/src/output/factories.ts +392 -0
- package/src/output/index.ts +98 -0
- package/src/output/multimodal/EXPORTS.md +306 -0
- package/src/output/multimodal/IMPLEMENTATION_SUMMARY.md +421 -0
- package/src/output/multimodal/README.md +349 -0
- package/src/output/multimodal/SETUP_GUIDE.md +472 -0
- package/src/output/multimodal/audio.ts +650 -0
- package/src/output/multimodal/image.ts +22 -0
- package/src/output/multimodal/index.ts +32 -0
- package/src/output/multimodal/providers.example.ts +375 -0
- package/src/output/validator.ts +495 -0
- package/src/pipelines/adapters/trace-storage-blob.ts +458 -0
- package/src/pipelines/adapters/trace-storage-memory.ts +319 -0
- package/src/pipelines/defaults.ts +109 -0
- package/src/pipelines/index.ts +24 -0
- package/src/pipelines/message-transforms.ts +107 -0
- package/src/pipelines/multi-step-wrapper.ts +433 -0
- package/src/pipelines/pipeline-presets.ts +339 -0
- package/src/pipelines/step-executor.ts +257 -0
- package/src/pipelines/storage-factory.ts +85 -0
- package/src/pipelines/trace-storage-interface.ts +216 -0
- package/src/pipelines/types.ts +255 -0
- package/src/pipelines/validation.ts +323 -0
- package/src/prompts/index.ts +271 -0
- package/src/prompts/model-variants.ts +410 -0
- package/src/prompts/templates.ts +327 -0
- package/src/sdk/errors/base.ts +296 -0
- package/src/sdk/errors/index.ts +31 -0
- package/src/sdk/errors/utils.ts +148 -0
- package/src/sdk/experimental/index.ts +286 -0
- package/src/sdk/index.ts +25 -0
- package/src/sdk/middleware/ai-middleware.ts +95 -0
- package/src/sdk/middleware/cache.ts +154 -0
- package/src/sdk/middleware/circuit-breaker.ts +388 -0
- package/src/sdk/middleware/compose.ts +81 -0
- package/src/sdk/middleware/deduplication.ts +307 -0
- package/src/sdk/middleware/index.ts +660 -0
- package/src/sdk/middleware/model-middleware.ts +200 -0
- package/src/sdk/stop-conditions/conditions.ts +209 -0
- package/src/sdk/stop-conditions/index.ts +35 -0
- package/src/sdk/stop-conditions/types.ts +59 -0
- package/src/security/guardrails/index.ts +6 -0
- package/src/security/guardrails/middleware.ts +465 -0
- package/src/security/guardrails/pii-filter.ts +396 -0
- package/src/security/index.ts +33 -0
- package/src/security/injection/index.ts +5 -0
- package/src/security/injection/prompt-injection.ts +64 -0
- package/src/security/types.ts +85 -0
- package/src/server/cache/crypto.ts +47 -0
- package/src/server/cache/performance.ts +79 -0
- package/src/server/error-handler.ts +93 -0
- package/src/server/errors.ts +73 -0
- package/src/server/helpers.ts +944 -0
- package/src/server/http.ts +156 -0
- package/src/server/index.ts +12 -0
- package/src/server/messages/__tests__/messages.test.ts +720 -0
- package/src/server/messages/converter.ts +245 -0
- package/src/server/messages/data-parts.ts +338 -0
- package/src/server/messages/extraction.ts +328 -0
- package/src/server/messages/index.ts +126 -0
- package/src/server/messages/types.ts +355 -0
- package/src/server/messages/window.ts +450 -0
- package/src/server/rate-limit/env.ts +8 -0
- package/src/server/rate-limit/rate-limit.ts +165 -0
- package/src/server/routes/HEALTH_CHECK.md +502 -0
- package/src/server/routes/IMPLEMENTATION_SUMMARY.md +432 -0
- package/src/server/routes/QUICK_START.md +327 -0
- package/src/server/routes/README.md +357 -0
- package/src/server/routes/__tests__/routes.test.ts +628 -0
- package/src/server/routes/agent-route.ts +224 -0
- package/src/server/routes/agent-routes.ts +191 -0
- package/src/server/routes/embed-config.ts +181 -0
- package/src/server/routes/health-check.example.ts +507 -0
- package/src/server/routes/health-check.test.ts +533 -0
- package/src/server/routes/health-check.ts +639 -0
- package/src/server/routes/health-check.types.ts +217 -0
- package/src/server/routes/index.ts +32 -0
- package/src/server/routes/types.ts +274 -0
- package/src/shared/__tests__/schemas.test.ts +317 -0
- package/src/shared/ai-runtime.ts +139 -0
- package/src/shared/ai-types.ts +133 -0
- package/src/shared/index.ts +30 -0
- package/src/shared/sdk-runtime.ts +198 -0
- package/src/shared/sdk-types.ts +301 -0
- package/src/streaming/control/__tests__/streaming-control.test.ts +708 -0
- package/src/streaming/control/budget-guard.ts +264 -0
- package/src/streaming/control/controller.ts +255 -0
- package/src/streaming/control/index.ts +105 -0
- package/src/streaming/control/smoothing.ts +201 -0
- package/src/streaming/control/step-limit.ts +215 -0
- package/src/streaming/control/types.ts +234 -0
- package/src/streaming/core/auto-resume.ts +276 -0
- package/src/streaming/core/index.ts +85 -0
- package/src/streaming/core/multi-step.ts +471 -0
- package/src/streaming/core/protocol.ts +194 -0
- package/src/streaming/core/types.ts +182 -0
- package/src/streaming/index.ts +97 -0
- package/src/streaming/infra/backpressure/buffer.ts +210 -0
- package/src/streaming/infra/backpressure/index.ts +6 -0
- package/src/streaming/infra/index.ts +75 -0
- package/src/streaming/infra/multiplexing/index.ts +311 -0
- package/src/streaming/infra/resilience/index.ts +684 -0
- package/src/streaming/infra/transform/index.ts +15 -0
- package/src/streaming/infra/transform/stream-transforms.ts +166 -0
- package/src/streaming/infra/transport/index.ts +774 -0
- package/src/streaming/infra/types.ts +118 -0
- package/src/streaming/infra-extra/types.ts +118 -0
- package/src/tools/advanced/caching.ts +299 -0
- package/src/tools/advanced/generator.ts +267 -0
- package/src/tools/advanced/hitl.ts +251 -0
- package/src/tools/advanced/index.ts +9 -0
- package/src/tools/advanced/llm-tool.ts +208 -0
- package/src/tools/approval/FILES.md +449 -0
- package/src/tools/approval/IMPLEMENTATION_SUMMARY.md +567 -0
- package/src/tools/approval/QUICK_START.md +362 -0
- package/src/tools/approval/README.md +514 -0
- package/src/tools/approval/advanced-approval-queue.ts +7 -0
- package/src/tools/approval/approval.example.ts +571 -0
- package/src/tools/approval/in-memory-queue.ts +405 -0
- package/src/tools/approval/index.ts +737 -0
- package/src/tools/approval/middleware.ts +590 -0
- package/src/tools/approval/queue-factory.ts +162 -0
- package/src/tools/approval/redis-queue.ts +327 -0
- package/src/tools/approval/testing.ts +493 -0
- package/src/tools/approval/types.ts +221 -0
- package/src/tools/approval/with-approval.ts +366 -0
- package/src/tools/artifacts/artifact-tools.ts +273 -0
- package/src/tools/artifacts/index.ts +6 -0
- package/src/tools/compliance/compliance-wrapper.ts +789 -0
- package/src/tools/compliance/create-compliant-stream.ts +226 -0
- package/src/tools/compliance/index.ts +8 -0
- package/src/tools/compliance/phi-redaction.ts +406 -0
- package/src/tools/compliance/tool-wrapper.ts +306 -0
- package/src/tools/computer/index.ts +99 -0
- package/src/tools/computer/types.ts +41 -0
- package/src/tools/core/abort.ts +202 -0
- package/src/tools/core/factory.ts +197 -0
- package/src/tools/core/index.ts +8 -0
- package/src/tools/core/tool-safety.ts +112 -0
- package/src/tools/generic/index.ts +9 -0
- package/src/tools/generic/json-schema-tool.ts +301 -0
- package/src/tools/generic/tiptap-context.ts +619 -0
- package/src/tools/generic/web-search-tool.ts +82 -0
- package/src/tools/generic/web-search.ts +142 -0
- package/src/tools/index.ts +36 -0
- package/src/tools/mcp/ai-sdk-error-integration.ts +401 -0
- package/src/tools/mcp/client.ts +988 -0
- package/src/tools/mcp/connection-manager.ts +380 -0
- package/src/tools/mcp/connection-pool.ts +408 -0
- package/src/tools/mcp/edge-runtime.ts +318 -0
- package/src/tools/mcp/environment.ts +310 -0
- package/src/tools/mcp/index.ts +20 -0
- package/src/tools/mcp/next-pattern.ts +401 -0
- package/src/tools/mcp/stream-lifecycle-integration.ts +617 -0
- package/src/tools/mcp/tool-cache.ts +359 -0
- package/src/tools/mcp/transport-selector.ts +492 -0
- package/src/tools/mcp/transports.ts +99 -0
- package/src/tools/simple-factory.ts +55 -0
- package/src/tools/superpowers/index.ts +122 -0
- package/src/tools/superpowers/prompts/index.ts +533 -0
- package/src/tools/superpowers/schemas/index.ts +701 -0
- package/src/tools/superpowers/tools/index.ts +721 -0
- package/src/tools/validation-wrapper.ts +97 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"middleware-C1apSrj0.mjs","names":[],"sources":["../src/security/types.ts","../src/security/guardrails/pii-filter.ts","../src/security/guardrails/middleware.ts"],"sourcesContent":["/**\n * Security module types\n */\n\n/**\n * PII filter configuration\n */\nexport interface PIIFilterConfig {\n /** Whether to mask detected PII */\n mask: boolean;\n /** Types of PII to detect */\n types: PIIType[];\n /** Action on detection */\n action: 'mask' | 'block' | 'warn';\n}\n\nexport type PIIType = 'email' | 'phone' | 'ssn' | 'credit_card' | 'name' | 'address';\n\n/**\n * Content filter configuration\n */\nexport interface ContentFilterConfig {\n /** Categories to filter */\n categories: ContentCategory[];\n /** Threshold for blocking (0-1) */\n threshold: number;\n}\n\nexport type ContentCategory = 'hate' | 'violence' | 'sexual' | 'self_harm' | 'illegal';\n\n/**\n * Topic filter configuration\n */\nexport interface TopicFilterConfig {\n /** Topics to block */\n blockedTopics: string[];\n /** Topics to allow (whitelist mode) */\n allowedTopics?: string[];\n}\n\n/**\n * Injection detection configuration\n */\nexport interface InjectionConfig {\n /** Enable prompt injection detection */\n enabled: boolean;\n /** Confidence threshold for blocking */\n threshold: number;\n /** Action on detection */\n action: 'block' | 'warn' | 'sanitize';\n}\n\n/**\n * Injection detection result\n */\nexport interface InjectionDetectionResult {\n detected: boolean;\n confidence: number;\n patterns: string[];\n originalText: string;\n}\n\n/**\n * Guardrail configuration\n */\nexport interface GuardrailConfig {\n pii?: PIIFilterConfig;\n content?: ContentFilterConfig;\n topics?: TopicFilterConfig;\n injection?: InjectionConfig;\n}\n\n/**\n * Guardrail violation error\n */\nexport class GuardrailViolationError extends Error {\n constructor(\n message: string,\n public readonly type: 'pii' | 'content' | 'topic' | 'injection',\n public readonly details?: Record<string, unknown>,\n ) {\n super(message);\n this.name = 'GuardrailViolationError';\n }\n}\n","/**\n * PII (Personally Identifiable Information) filtering\n */\n\nimport { logWarn } from '@repo/shared/logs';\n\nimport { GuardrailViolationError } from '../types';\n\nimport type { PIIFilterConfig, PIIType } from '../types';\n\n/**\n * PII detection patterns\n */\nconst PII_PATTERNS: Record<PIIType, RegExp | null> = {\n email: null,\n phone: null,\n ssn: /\\b\\d{3}[-\\s]?\\d{2}[-\\s]?\\d{4}\\b/g,\n credit_card: /\\b\\d{4}[-\\s]?\\d{4}[-\\s]?\\d{4}[-\\s]?\\d{4}\\b/g,\n name: /\\b[A-Z][a-z]+\\s+[A-Z][a-z]+\\b/g, // Simple name pattern\n address:\n /\\b\\d+\\s+[A-Za-z]+\\s+(?:Street|St|Avenue|Ave|Road|Rd|Boulevard|Blvd|Lane|Ln|Drive|Dr)\\b/gi,\n};\n\nconst SUPPORTED_PII_TYPES: ReadonlyArray<PIIType> = Object.keys(PII_PATTERNS) as PIIType[];\n\nconst EMAIL_TOKEN_START_TRIM = new Set(['(', '[', '{', '<', '\"', \"'\"]);\nconst EMAIL_TOKEN_END_TRIM = new Set([')', ']', '}', '>', '.', ',', ';', ':', '!', '?', '\"', \"'\"]);\n\nconst isAlphaNumeric = (char: string): boolean => {\n const code = char.charCodeAt(0);\n return (code >= 48 && code <= 57) || (code >= 65 && code <= 90) || (code >= 97 && code <= 122);\n};\n\nconst isDigit = (char: string): boolean => {\n const code = char.charCodeAt(0);\n return code >= 48 && code <= 57;\n};\n\nconst isEmailLocalChar = (char: string): boolean =>\n isAlphaNumeric(char) ||\n char === '.' ||\n char === '_' ||\n char === '%' ||\n char === '+' ||\n char === '-';\n\nconst isEmailDomainChar = (char: string): boolean =>\n isAlphaNumeric(char) || char === '.' || char === '-';\n\nconst trimEmailToken = (token: string): { value: string; offset: number } => {\n let start = 0;\n let end = token.length;\n\n while (start < end) {\n const char = token[start];\n if (!char || !EMAIL_TOKEN_START_TRIM.has(char)) break;\n start += 1;\n }\n\n while (end > start) {\n const char = token[end - 1];\n if (!char || !EMAIL_TOKEN_END_TRIM.has(char)) break;\n end -= 1;\n }\n\n return { value: token.slice(start, end), offset: start };\n};\n\nconst isValidEmailCandidate = (candidate: string): boolean => {\n if (candidate.length > 320) return false;\n\n const atIndex = candidate.indexOf('@');\n if (atIndex <= 0 || atIndex !== candidate.lastIndexOf('@')) return false;\n\n const local = candidate.slice(0, atIndex);\n const domain = candidate.slice(atIndex + 1);\n\n if (local.length === 0 || local.length > 64) return false;\n if (domain.length === 0 || domain.length > 255) return false;\n if (!domain.includes('.')) return false;\n if (local.startsWith('.') || local.endsWith('.')) return false;\n if (domain.startsWith('.') || domain.endsWith('.')) return false;\n if (local.includes('..') || domain.includes('..')) return false;\n\n for (const char of local) {\n if (!isEmailLocalChar(char)) return false;\n }\n\n for (const char of domain) {\n if (!isEmailDomainChar(char)) return false;\n }\n\n const labels = domain.split('.');\n if (labels.some(label => label.length === 0)) return false;\n\n return true;\n};\n\nconst findEmailMatches = (text: string): Array<{ value: string; index: number }> => {\n const matches: Array<{ value: string; index: number }> = [];\n const seen = new Set<string>();\n let searchIndex = 0;\n\n while (searchIndex < text.length) {\n const atIndex = text.indexOf('@', searchIndex);\n if (atIndex === -1) break;\n\n let start = atIndex - 1;\n while (start >= 0 && isEmailLocalChar(text[start] ?? '')) {\n start -= 1;\n }\n start += 1;\n\n let end = atIndex + 1;\n while (end < text.length && isEmailDomainChar(text[end] ?? '')) {\n end += 1;\n }\n\n const candidate = text.slice(start, end);\n if (isValidEmailCandidate(candidate)) {\n const key = `${start}:${candidate}`;\n if (!seen.has(key)) {\n matches.push({ value: candidate, index: start });\n seen.add(key);\n }\n } else {\n const trimmed = trimEmailToken(candidate);\n if (trimmed.value && isValidEmailCandidate(trimmed.value)) {\n const key = `${start + trimmed.offset}:${trimmed.value}`;\n if (!seen.has(key)) {\n matches.push({ value: trimmed.value, index: start + trimmed.offset });\n seen.add(key);\n }\n }\n }\n\n searchIndex = atIndex + 1;\n }\n\n return matches;\n};\n\nconst maskValue = (value: string): string => {\n if (value.length <= 4) return '****';\n return value.slice(0, 2) + '*'.repeat(value.length - 4) + value.slice(-2);\n};\n\nconst maskEmail = (text: string): string => {\n const matches = findEmailMatches(text);\n if (matches.length === 0) return text;\n\n const ordered = [...matches].sort((a, b) => b.index - a.index);\n let result = text;\n\n for (const match of ordered) {\n const masked = maskValue(match.value);\n result = result.slice(0, match.index) + masked + result.slice(match.index + match.value.length);\n }\n\n return result;\n};\n\nconst isPhoneChar = (char: string): boolean =>\n isDigit(char) ||\n char === '+' ||\n char === '-' ||\n char === '.' ||\n char === ' ' ||\n char === '(' ||\n char === ')';\n\nconst extractDigits = (value: string): string => {\n let digits = '';\n for (const char of value) {\n if (isDigit(char)) {\n digits += char;\n }\n }\n return digits;\n};\n\nconst isValidPhoneCandidate = (candidate: string): boolean => {\n const digits = extractDigits(candidate);\n if (digits.length === 10) return true;\n if (digits.length === 11 && digits.startsWith('1')) return true;\n return false;\n};\n\nconst findPhoneMatches = (text: string): Array<{ value: string; index: number }> => {\n const matches: Array<{ value: string; index: number }> = [];\n let index = 0;\n\n while (index < text.length) {\n const char = text[index];\n if (!char || (!isDigit(char) && char !== '+')) {\n index += 1;\n continue;\n }\n\n const prevChar = index > 0 ? text[index - 1] : undefined;\n if (prevChar && isAlphaNumeric(prevChar)) {\n index += 1;\n continue;\n }\n\n let startIndex = index;\n if (prevChar === '(') {\n startIndex = index - 1;\n }\n\n let end = index + 1;\n while (end < text.length) {\n const next = text[end];\n if (!next || !isPhoneChar(next)) break;\n end += 1;\n }\n\n let trimmedEnd = end;\n while (trimmedEnd > startIndex) {\n const trailing = text[trimmedEnd - 1];\n if (\n trailing === ' ' ||\n trailing === '.' ||\n trailing === ',' ||\n trailing === ';' ||\n trailing === ':'\n ) {\n trimmedEnd -= 1;\n continue;\n }\n break;\n }\n\n const nextChar = trimmedEnd < text.length ? text[trimmedEnd] : undefined;\n if (nextChar && isAlphaNumeric(nextChar)) {\n index = end;\n continue;\n }\n\n const candidate = text.slice(startIndex, trimmedEnd);\n if (isValidPhoneCandidate(candidate)) {\n matches.push({ value: candidate, index: startIndex });\n }\n\n index = end;\n }\n\n return matches;\n};\n\nconst maskPhone = (text: string): string => {\n const matches = findPhoneMatches(text);\n if (matches.length === 0) return text;\n\n const ordered = [...matches].sort((a, b) => b.index - a.index);\n let result = text;\n\n for (const match of ordered) {\n const masked = maskValue(match.value);\n result = result.slice(0, match.index) + masked + result.slice(match.index + match.value.length);\n }\n\n return result;\n};\n\n/**\n * PII detection result\n */\nexport interface PIIDetectionResult {\n found: boolean;\n matches: Array<{\n type: PIIType;\n value: string;\n index: number;\n }>;\n}\n\n/**\n * Detect PII in text\n */\nexport function detectPII(\n text: string,\n types: PIIType[] = Object.keys(PII_PATTERNS) as PIIType[],\n): PIIDetectionResult {\n const matches: PIIDetectionResult['matches'] = [];\n\n for (const type of types) {\n if (type === 'email') {\n for (const match of findEmailMatches(text)) {\n matches.push({\n type,\n value: match.value,\n index: match.index,\n });\n }\n continue;\n }\n\n if (type === 'phone') {\n for (const match of findPhoneMatches(text)) {\n matches.push({\n type,\n value: match.value,\n index: match.index,\n });\n }\n continue;\n }\n\n const pattern = PII_PATTERNS[type];\n if (!pattern) continue;\n\n // Reset lastIndex for global patterns\n pattern.lastIndex = 0;\n\n let match;\n while ((match = pattern.exec(text)) !== null) {\n matches.push({\n type,\n value: match[0],\n index: match.index,\n });\n }\n }\n\n return {\n found: matches.length > 0,\n matches,\n };\n}\n\n/**\n * Mask PII in text\n */\nexport function maskPII(text: string, types: PIIType[] = [...SUPPORTED_PII_TYPES]): string {\n let masked = text;\n\n for (const type of types) {\n if (type === 'email') {\n masked = maskEmail(masked);\n continue;\n }\n\n if (type === 'phone') {\n masked = maskPhone(masked);\n continue;\n }\n\n const pattern = PII_PATTERNS[type];\n if (!pattern) continue;\n\n masked = masked.replace(pattern, match => {\n // Preserve some characters for context\n return maskValue(match);\n });\n }\n\n return masked;\n}\n\n/**\n * Create PII filter middleware\n */\nexport function createPIIFilter(config: PIIFilterConfig) {\n return {\n filter: (text: string): string => {\n const result = detectPII(text, config.types);\n\n if (!result.found) return text;\n\n switch (config.action) {\n case 'block':\n throw new GuardrailViolationError(\n `PII detected: ${result.matches.map(m => m.type).join(', ')}`,\n 'pii',\n {\n matches: result.matches.map(({ type, index }) => ({ type, index })),\n },\n );\n\n case 'mask':\n return maskPII(text, config.types);\n\n case 'warn':\n logWarn('[PII Filter] PII detected', {\n types: [...new Set(result.matches.map(m => m.type))],\n count: result.matches.length,\n });\n return text;\n\n default:\n return text;\n }\n },\n };\n}\n","/**\n * Security guardrails middleware\n */\n\nimport { logWarn } from '@repo/shared/logs';\n\nimport { detectPromptInjection, sanitizeInjection } from '../injection/prompt-injection';\nimport { GuardrailViolationError } from '../types';\n\nimport { createPIIFilter } from './pii-filter';\n\nimport type {\n TransformParamsArgs,\n WrapGenerateArgs,\n WrapStreamArgs,\n} from '../../sdk/middleware/model-middleware';\nimport type {\n SDKLanguageModelV3Message as LanguageModelV3Message,\n SDKLanguageModelV3Prompt as LanguageModelV3Prompt,\n SDKLanguageModelV3StreamPart as LanguageModelV3StreamPart,\n SDKLanguageModelV3Middleware } from '../../shared';\nimport type { GuardrailConfig } from '../types';\n\n\n\ntype GuardrailMessage = { content?: unknown; [key: string]: unknown };\ntype TextPart = { type: 'text'; text: string };\ntype StreamDeltaPart = Extract<\n LanguageModelV3StreamPart,\n { type: 'text-delta' | 'reasoning-delta' | 'tool-input-delta' }\n>;\ntype StreamEndPart = Extract<\n LanguageModelV3StreamPart,\n { type: 'text-end' | 'reasoning-end' | 'tool-input-end' }\n>;\ntype StreamStartPart = Extract<\n LanguageModelV3StreamPart,\n { type: 'text-start' | 'reasoning-start' | 'tool-input-start' }\n>;\n\ntype StreamBufferState = {\n pending: string;\n deltaType: StreamDeltaPart['type'];\n};\n\nconst isTextPart = (value: unknown): value is TextPart => {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'type' in value &&\n (value as { type?: unknown }).type === 'text' &&\n 'text' in value &&\n typeof (value as { text?: unknown }).text === 'string'\n );\n};\n\nconst sanitizeInputText = async (\n text: string,\n config: GuardrailConfig,\n piiFilter: ReturnType<typeof createPIIFilter> | null,\n): Promise<string> => {\n let content = text;\n\n if (config.injection?.enabled) {\n const injectionResult = await detectPromptInjection(content);\n\n if (\n injectionResult.detected &&\n injectionResult.confidence >= (config.injection.threshold ?? 0.5)\n ) {\n switch (config.injection.action) {\n case 'block':\n throw new GuardrailViolationError(\n `Prompt injection detected (${(injectionResult.confidence * 100).toFixed(0)}% confidence)`,\n 'injection',\n { patterns: injectionResult.patterns },\n );\n case 'sanitize':\n content = sanitizeInjection(content);\n break;\n case 'warn':\n logWarn('[Guardrail] Possible injection detected', {\n patterns: injectionResult.patterns,\n });\n break;\n }\n }\n }\n\n if (piiFilter) {\n content = piiFilter.filter(content);\n }\n\n return content;\n};\n\nconst sanitizeOutputText = async (\n text: string,\n piiFilter: ReturnType<typeof createPIIFilter> | null,\n): Promise<string> => {\n if (!piiFilter) {\n return text;\n }\n\n return piiFilter.filter(text);\n};\n\nconst isStreamDeltaPart = (part: LanguageModelV3StreamPart): part is StreamDeltaPart => {\n if (\n part.type === 'text-delta' ||\n part.type === 'reasoning-delta' ||\n part.type === 'tool-input-delta'\n ) {\n const candidate = part as { delta?: unknown };\n return typeof candidate.delta === 'string';\n }\n return false;\n};\n\nconst isStreamEndPart = (part: LanguageModelV3StreamPart): part is StreamEndPart => {\n return (\n part.type === 'text-end' || part.type === 'reasoning-end' || part.type === 'tool-input-end'\n );\n};\n\nconst isStreamStartPart = (part: LanguageModelV3StreamPart): part is StreamStartPart => {\n return (\n part.type === 'text-start' ||\n part.type === 'reasoning-start' ||\n part.type === 'tool-input-start'\n );\n};\n\nconst getDeltaTypeForStart = (part: StreamStartPart): StreamDeltaPart['type'] => {\n switch (part.type) {\n case 'text-start':\n return 'text-delta';\n case 'reasoning-start':\n return 'reasoning-delta';\n case 'tool-input-start':\n return 'tool-input-delta';\n }\n};\n\nconst getDeltaTypeForEnd = (part: StreamEndPart): StreamDeltaPart['type'] => {\n switch (part.type) {\n case 'text-end':\n return 'text-delta';\n case 'reasoning-end':\n return 'reasoning-delta';\n case 'tool-input-end':\n return 'tool-input-delta';\n }\n};\n\nconst getBufferKey = (partType: StreamDeltaPart['type'], id: string): string => `${partType}:${id}`;\n\nconst createPIIStreamTransform = (\n piiFilter: ReturnType<typeof createPIIFilter>,\n): TransformStream<LanguageModelV3StreamPart, LanguageModelV3StreamPart> => {\n const buffers = new Map<string, StreamBufferState>();\n const holdBackSize = 64;\n\n const emitBufferedDelta = (\n controller: TransformStreamDefaultController<LanguageModelV3StreamPart>,\n key: string,\n deltaType: StreamDeltaPart['type'],\n providerMetadata: StreamDeltaPart['providerMetadata'],\n ) => {\n const buffer = buffers.get(key);\n if (!buffer || buffer.pending.length === 0) {\n return;\n }\n\n const masked = piiFilter.filter(buffer.pending);\n buffer.pending = '';\n buffers.set(key, buffer);\n\n if (masked.length === 0) {\n return;\n }\n\n controller.enqueue({\n type: deltaType,\n id: key.split(':').slice(1).join(':'),\n delta: masked,\n providerMetadata,\n });\n };\n\n return new TransformStream<LanguageModelV3StreamPart, LanguageModelV3StreamPart>({\n transform(part, controller) {\n if (isStreamStartPart(part)) {\n const deltaType = getDeltaTypeForStart(part);\n const key = getBufferKey(deltaType, part.id);\n if (!buffers.has(key)) {\n buffers.set(key, { pending: '', deltaType });\n }\n controller.enqueue(part);\n return;\n }\n\n if (isStreamDeltaPart(part)) {\n const key = getBufferKey(part.type, part.id);\n const state = buffers.get(key) ?? { pending: '', deltaType: part.type };\n const pending = state.pending + part.delta;\n\n if (pending.length <= holdBackSize) {\n buffers.set(key, { ...state, pending });\n return;\n }\n\n const safePrefix = pending.slice(0, pending.length - holdBackSize);\n const maskedPrefix = piiFilter.filter(safePrefix);\n buffers.set(key, { ...state, pending: pending.slice(pending.length - holdBackSize) });\n\n if (maskedPrefix.length > 0) {\n controller.enqueue({\n ...part,\n delta: maskedPrefix,\n });\n }\n return;\n }\n\n if (isStreamEndPart(part)) {\n const deltaType = getDeltaTypeForEnd(part);\n const key = getBufferKey(deltaType, part.id);\n emitBufferedDelta(controller, key, deltaType, part.providerMetadata);\n buffers.delete(key);\n controller.enqueue(part);\n return;\n }\n\n controller.enqueue(part);\n },\n flush(controller) {\n for (const [key, state] of buffers.entries()) {\n const masked = piiFilter.filter(state.pending);\n if (masked.length > 0) {\n controller.enqueue({\n type: state.deltaType,\n id: key.split(':').slice(1).join(':'),\n delta: masked,\n });\n }\n }\n buffers.clear();\n controller.terminate();\n },\n });\n};\n\nconst sanitizeMessage = async (\n message: GuardrailMessage,\n config: GuardrailConfig,\n piiFilter: ReturnType<typeof createPIIFilter> | null,\n): Promise<GuardrailMessage> => {\n if (typeof message.content === 'string') {\n const content = await sanitizeInputText(message.content, config, piiFilter);\n return { ...message, content };\n }\n\n if (Array.isArray(message.content)) {\n const parts = await Promise.all(\n message.content.map(async part => {\n if (isTextPart(part)) {\n const text = await sanitizeInputText(part.text, config, piiFilter);\n return { ...part, text };\n }\n return part;\n }),\n );\n return { ...message, content: parts };\n }\n\n return message;\n};\n\nconst sanitizePromptMessage = async (\n message: LanguageModelV3Message,\n config: GuardrailConfig,\n piiFilter: ReturnType<typeof createPIIFilter> | null,\n): Promise<LanguageModelV3Message> => {\n if (message.role === 'system') {\n const content = await sanitizeInputText(message.content, config, piiFilter);\n return { ...message, content };\n }\n\n if (message.role === 'user') {\n const parts = await Promise.all(\n message.content.map(async part => {\n if (part.type === 'text') {\n const text = await sanitizeInputText(part.text, config, piiFilter);\n return { ...part, text };\n }\n return part;\n }),\n );\n return { ...message, content: parts };\n }\n\n if (message.role === 'assistant') {\n const parts = await Promise.all(\n message.content.map(async part => {\n if (part.type === 'text' || part.type === 'reasoning') {\n const text = await sanitizeInputText(part.text, config, piiFilter);\n return { ...part, text };\n }\n return part;\n }),\n );\n return { ...message, content: parts };\n }\n\n if (message.role === 'tool') {\n return message;\n }\n\n return message;\n};\n\n/**\n * Create composable guardrail middleware\n *\n * @example\n * ```ts\n * const guardrails = createGuardrailMiddleware({\n * pii: { mask: true, types: [\"email\", \"phone\"], action: \"mask\" },\n * injection: { enabled: true, threshold: 0.5, action: \"block\" },\n * });\n *\n * const model = wrapLanguageModel({\n * model: anthropic(\"claude-sonnet-4-20250514\"),\n * middleware: guardrails,\n * });\n * ```\n */\nexport function createGuardrailMiddleware(config: GuardrailConfig): SDKLanguageModelV3Middleware {\n const piiFilter = config.pii ? createPIIFilter(config.pii) : null;\n\n return {\n specificationVersion: 'v3',\n transformParams: async ({ params }: TransformParamsArgs) => {\n const rawParams = params as GuardrailMessage & {\n messages?: GuardrailMessage[];\n prompt?: unknown;\n system?: unknown;\n };\n const rawMessages = Array.isArray(rawParams.messages) ? rawParams.messages : undefined;\n const rawPromptString = typeof rawParams.prompt === 'string' ? rawParams.prompt : undefined;\n const rawPromptArray = Array.isArray(rawParams.prompt)\n ? (rawParams.prompt as LanguageModelV3Prompt)\n : undefined;\n const rawSystem = typeof rawParams.system === 'string' ? rawParams.system : undefined;\n\n if (rawMessages) {\n const processedMessages = await Promise.all(\n rawMessages.map(msg => sanitizeMessage(msg, config, piiFilter)),\n );\n\n return {\n ...params,\n messages: processedMessages,\n system: rawSystem\n ? await sanitizeInputText(rawSystem, config, piiFilter)\n : rawParams.system,\n } as TransformParamsArgs['params'];\n }\n\n if (rawPromptArray) {\n const processedPrompt = await Promise.all(\n rawPromptArray.map(message => sanitizePromptMessage(message, config, piiFilter)),\n );\n return {\n ...params,\n prompt: processedPrompt,\n system: rawSystem\n ? await sanitizeInputText(rawSystem, config, piiFilter)\n : rawParams.system,\n } as TransformParamsArgs['params'];\n }\n\n if (rawPromptString) {\n const sanitizedPrompt = await sanitizeInputText(rawPromptString, config, piiFilter);\n const prompt = [\n {\n role: 'user' as const,\n content: [{ type: 'text' as const, text: sanitizedPrompt }],\n },\n ];\n return {\n ...params,\n prompt,\n system: rawSystem\n ? await sanitizeInputText(rawSystem, config, piiFilter)\n : rawParams.system,\n } as TransformParamsArgs['params'];\n }\n\n if (rawSystem) {\n return {\n ...params,\n system: await sanitizeInputText(rawSystem, config, piiFilter),\n } as TransformParamsArgs['params'];\n }\n\n return params;\n },\n\n wrapGenerate: async ({ doGenerate }: WrapGenerateArgs) => {\n const result = await doGenerate();\n\n // Post-process: filter PII from output\n if (piiFilter && Array.isArray(result.content)) {\n const content = await Promise.all(\n result.content.map(async part => {\n if (isTextPart(part)) {\n const text = await sanitizeOutputText(part.text, piiFilter);\n return { ...part, text };\n }\n return part;\n }),\n );\n\n const text = content\n .filter(isTextPart)\n .map(part => part.text)\n .join('');\n\n const updatedResult = {\n ...result,\n content,\n };\n\n if ('text' in result) {\n const originalText = (result as { text?: unknown }).text;\n if (typeof originalText === 'string') {\n return {\n ...updatedResult,\n text: text.length > 0 ? text : originalText,\n };\n }\n }\n\n return updatedResult;\n }\n\n return result;\n },\n wrapStream: async ({ doStream }: WrapStreamArgs) => {\n const result = await doStream();\n if (!piiFilter) {\n return result;\n }\n\n const filteredStream = result.stream.pipeThrough(createPIIStreamTransform(piiFilter));\n\n return {\n ...result,\n stream: filteredStream,\n };\n },\n };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Ur as SDKLanguageModelV3Middleware, zr as SDKLanguageModelV3CallOptions } from "./ai-runtime-DIwOEc6g.mjs";
|
|
2
|
+
import { i as CachingMiddlewareOptions, n as CacheStrategy } from "./types-BPnq3GQo.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/caching/middleware.d.ts
|
|
5
|
+
declare function computeCacheKey(params: SDKLanguageModelV3CallOptions, strategy: CacheStrategy, modelId?: string): string;
|
|
6
|
+
declare function createCachingMiddleware(options: CachingMiddlewareOptions): SDKLanguageModelV3Middleware;
|
|
7
|
+
//#endregion
|
|
8
|
+
export { createCachingMiddleware as n, computeCacheKey as t };
|
|
9
|
+
//# sourceMappingURL=middleware-C7k0uItW.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"middleware-C7k0uItW.d.mts","names":[],"sources":["../src/caching/middleware.ts"],"mappings":";;;;iBA6NS,eAAA,CACP,MAAA,EAAQ,6BAAA,EACR,QAAA,EAAU,aAAA,EACV,OAAA;AAAA,iBAmEc,uBAAA,CACd,OAAA,EAAS,wBAAA,GACR,4BAAA"}
|
|
@@ -0,0 +1,366 @@
|
|
|
1
|
+
import { o as resolveModelId } from "./ai-runtime-CDzQztTt.mjs";
|
|
2
|
+
import { logWarn } from "@od-oneapp/shared/logs";
|
|
3
|
+
|
|
4
|
+
//#region src/sdk/middleware/circuit-breaker.ts
|
|
5
|
+
/**
|
|
6
|
+
* Circuit breaker error thrown when circuit is open.
|
|
7
|
+
*/
|
|
8
|
+
var CircuitOpenError = class extends Error {
|
|
9
|
+
circuitName;
|
|
10
|
+
resetTime;
|
|
11
|
+
constructor(circuitName, resetTime) {
|
|
12
|
+
super(`Circuit '${circuitName}' is open. Will attempt reset in ${resetTime}ms`);
|
|
13
|
+
this.name = "CircuitOpenError";
|
|
14
|
+
this.circuitName = circuitName;
|
|
15
|
+
this.resetTime = resetTime;
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Circuit breaker implementation.
|
|
20
|
+
* Manages state transitions and failure tracking for a single circuit.
|
|
21
|
+
*/
|
|
22
|
+
var CircuitBreaker = class {
|
|
23
|
+
state = "closed";
|
|
24
|
+
failureCount = 0;
|
|
25
|
+
successCount = 0;
|
|
26
|
+
lastFailureTime;
|
|
27
|
+
lastSuccessTime;
|
|
28
|
+
totalRequests = 0;
|
|
29
|
+
totalFailures = 0;
|
|
30
|
+
totalSuccesses = 0;
|
|
31
|
+
halfOpenSuccessCount = 0;
|
|
32
|
+
resetTimer;
|
|
33
|
+
config;
|
|
34
|
+
constructor(config) {
|
|
35
|
+
this.config = {
|
|
36
|
+
failureThreshold: config.failureThreshold ?? 5,
|
|
37
|
+
resetTimeout: config.resetTimeout ?? 3e4,
|
|
38
|
+
halfOpenRequests: config.halfOpenRequests ?? 2,
|
|
39
|
+
fallbackBehavior: config.fallbackBehavior ?? "error",
|
|
40
|
+
defaultValue: config.defaultValue,
|
|
41
|
+
onStateChange: config.onStateChange ?? (() => {}),
|
|
42
|
+
onMetrics: config.onMetrics ?? (() => {}),
|
|
43
|
+
name: config.name
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Gets the current circuit state.
|
|
48
|
+
*/
|
|
49
|
+
getState() {
|
|
50
|
+
return this.state;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Gets current metrics for the circuit.
|
|
54
|
+
*/
|
|
55
|
+
getMetrics() {
|
|
56
|
+
return {
|
|
57
|
+
name: this.config.name,
|
|
58
|
+
state: this.state,
|
|
59
|
+
failureCount: this.failureCount,
|
|
60
|
+
successCount: this.successCount,
|
|
61
|
+
lastFailureTime: this.lastFailureTime,
|
|
62
|
+
lastSuccessTime: this.lastSuccessTime,
|
|
63
|
+
totalRequests: this.totalRequests,
|
|
64
|
+
totalFailures: this.totalFailures,
|
|
65
|
+
totalSuccesses: this.totalSuccesses
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Transitions the circuit to a new state.
|
|
70
|
+
*/
|
|
71
|
+
transitionTo(newState) {
|
|
72
|
+
if (this.state === newState) return;
|
|
73
|
+
const oldState = this.state;
|
|
74
|
+
this.state = newState;
|
|
75
|
+
this.config.onStateChange(oldState, newState);
|
|
76
|
+
this.config.onMetrics(this.getMetrics());
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Records a failure and potentially opens the circuit.
|
|
80
|
+
*/
|
|
81
|
+
recordFailure(_error) {
|
|
82
|
+
this.failureCount++;
|
|
83
|
+
this.totalFailures++;
|
|
84
|
+
this.lastFailureTime = Date.now();
|
|
85
|
+
if (this.state === "half-open") this.openCircuit();
|
|
86
|
+
else if (this.failureCount >= this.config.failureThreshold) this.openCircuit();
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Records a success and potentially closes the circuit.
|
|
90
|
+
*/
|
|
91
|
+
recordSuccess() {
|
|
92
|
+
this.successCount++;
|
|
93
|
+
this.totalSuccesses++;
|
|
94
|
+
this.lastSuccessTime = Date.now();
|
|
95
|
+
if (this.state === "half-open") {
|
|
96
|
+
this.halfOpenSuccessCount++;
|
|
97
|
+
if (this.halfOpenSuccessCount >= this.config.halfOpenRequests) this.closeCircuit();
|
|
98
|
+
} else if (this.state === "closed") this.failureCount = 0;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Opens the circuit, preventing requests.
|
|
102
|
+
*/
|
|
103
|
+
openCircuit() {
|
|
104
|
+
this.transitionTo("open");
|
|
105
|
+
this.halfOpenSuccessCount = 0;
|
|
106
|
+
if (this.resetTimer) clearTimeout(this.resetTimer);
|
|
107
|
+
this.resetTimer = setTimeout(() => {
|
|
108
|
+
this.transitionTo("half-open");
|
|
109
|
+
this.halfOpenSuccessCount = 0;
|
|
110
|
+
}, this.config.resetTimeout);
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Closes the circuit, allowing requests.
|
|
114
|
+
*/
|
|
115
|
+
closeCircuit() {
|
|
116
|
+
this.transitionTo("closed");
|
|
117
|
+
this.failureCount = 0;
|
|
118
|
+
this.halfOpenSuccessCount = 0;
|
|
119
|
+
if (this.resetTimer) {
|
|
120
|
+
clearTimeout(this.resetTimer);
|
|
121
|
+
this.resetTimer = void 0;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Checks if the circuit allows a request.
|
|
126
|
+
*/
|
|
127
|
+
canRequest() {
|
|
128
|
+
return this.state !== "open";
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Gets time remaining before circuit resets (in ms).
|
|
132
|
+
* Returns 0 if circuit is not open.
|
|
133
|
+
*/
|
|
134
|
+
getResetTime() {
|
|
135
|
+
if (this.state !== "open" || !this.lastFailureTime) return 0;
|
|
136
|
+
const elapsed = Date.now() - this.lastFailureTime;
|
|
137
|
+
return Math.max(0, this.config.resetTimeout - elapsed);
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Executes a function with circuit breaker protection.
|
|
141
|
+
*
|
|
142
|
+
* @param fn - Function to execute
|
|
143
|
+
* @returns Promise with result or fallback value
|
|
144
|
+
* @throws CircuitOpenError if circuit is open and fallback is 'error'
|
|
145
|
+
*/
|
|
146
|
+
async execute(fn) {
|
|
147
|
+
this.totalRequests++;
|
|
148
|
+
if (!this.canRequest()) {
|
|
149
|
+
const resetTime = this.getResetTime();
|
|
150
|
+
switch (this.config.fallbackBehavior) {
|
|
151
|
+
case "error":
|
|
152
|
+
case "cache": throw new CircuitOpenError(this.config.name, resetTime);
|
|
153
|
+
case "default": return this.config.defaultValue;
|
|
154
|
+
case "partial": break;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
try {
|
|
158
|
+
const result = await fn();
|
|
159
|
+
this.recordSuccess();
|
|
160
|
+
return result;
|
|
161
|
+
} catch (error) {
|
|
162
|
+
this.recordFailure(error instanceof Error ? error : new Error(String(error)));
|
|
163
|
+
throw error;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Reports a failure that occurred outside of execute() (e.g., streaming errors).
|
|
168
|
+
* This allows tracking failures that happen asynchronously after the initial call.
|
|
169
|
+
*
|
|
170
|
+
* @param error - The error that occurred.
|
|
171
|
+
*/
|
|
172
|
+
reportFailure(error) {
|
|
173
|
+
this.recordFailure(error);
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Manually resets the circuit to closed state.
|
|
177
|
+
* Use with caution - typically for testing or manual recovery.
|
|
178
|
+
*/
|
|
179
|
+
reset() {
|
|
180
|
+
const oldState = this.state;
|
|
181
|
+
this.state = "closed";
|
|
182
|
+
this.failureCount = 0;
|
|
183
|
+
this.successCount = 0;
|
|
184
|
+
this.halfOpenSuccessCount = 0;
|
|
185
|
+
if (this.resetTimer) {
|
|
186
|
+
clearTimeout(this.resetTimer);
|
|
187
|
+
this.resetTimer = void 0;
|
|
188
|
+
}
|
|
189
|
+
if (oldState !== "closed") this.config.onStateChange(oldState, "closed");
|
|
190
|
+
this.config.onMetrics(this.getMetrics());
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Cleans up resources (timers).
|
|
194
|
+
*/
|
|
195
|
+
destroy() {
|
|
196
|
+
if (this.resetTimer) {
|
|
197
|
+
clearTimeout(this.resetTimer);
|
|
198
|
+
this.resetTimer = void 0;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
};
|
|
202
|
+
/**
|
|
203
|
+
* Circuit breaker registry for managing multiple circuits.
|
|
204
|
+
*/
|
|
205
|
+
var CircuitBreakerRegistry = class {
|
|
206
|
+
circuits = /* @__PURE__ */ new Map();
|
|
207
|
+
/**
|
|
208
|
+
* Gets or creates a circuit breaker with the given name.
|
|
209
|
+
*/
|
|
210
|
+
getOrCreate(config) {
|
|
211
|
+
let circuit = this.circuits.get(config.name);
|
|
212
|
+
if (!circuit) {
|
|
213
|
+
circuit = new CircuitBreaker(config);
|
|
214
|
+
this.circuits.set(config.name, circuit);
|
|
215
|
+
}
|
|
216
|
+
return circuit;
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Gets a circuit breaker by name.
|
|
220
|
+
*/
|
|
221
|
+
get(name) {
|
|
222
|
+
return this.circuits.get(name);
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Gets all circuit metrics.
|
|
226
|
+
*/
|
|
227
|
+
getAllMetrics() {
|
|
228
|
+
return Array.from(this.circuits.values()).map((c) => c.getMetrics());
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Resets all circuits.
|
|
232
|
+
*/
|
|
233
|
+
resetAll() {
|
|
234
|
+
for (const circuit of this.circuits.values()) circuit.reset();
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Cleans up all circuits.
|
|
238
|
+
*/
|
|
239
|
+
destroy() {
|
|
240
|
+
for (const circuit of this.circuits.values()) circuit.destroy();
|
|
241
|
+
this.circuits.clear();
|
|
242
|
+
}
|
|
243
|
+
};
|
|
244
|
+
/**
|
|
245
|
+
* Default circuit breaker registry instance.
|
|
246
|
+
*/
|
|
247
|
+
const circuitBreakerRegistry = new CircuitBreakerRegistry();
|
|
248
|
+
/**
|
|
249
|
+
* Creates a circuit breaker wrapper for a function.
|
|
250
|
+
*
|
|
251
|
+
* @param name - Circuit name
|
|
252
|
+
* @param config - Circuit configuration (optional)
|
|
253
|
+
* @returns Function wrapper that executes with circuit breaker protection
|
|
254
|
+
*
|
|
255
|
+
* @example
|
|
256
|
+
* ```typescript
|
|
257
|
+
* const protectedFetch = withCircuitBreaker('external-api', {
|
|
258
|
+
* failureThreshold: 3,
|
|
259
|
+
* resetTimeout: 60000,
|
|
260
|
+
* });
|
|
261
|
+
*
|
|
262
|
+
* const result = await protectedFetch(async () => {
|
|
263
|
+
* return fetch('https://api.example.com/data');
|
|
264
|
+
* });
|
|
265
|
+
* ```
|
|
266
|
+
*/
|
|
267
|
+
function withCircuitBreaker(name, config) {
|
|
268
|
+
const circuit = circuitBreakerRegistry.getOrCreate({
|
|
269
|
+
name,
|
|
270
|
+
...config
|
|
271
|
+
});
|
|
272
|
+
return (fn) => circuit.execute(fn);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
//#endregion
|
|
276
|
+
//#region src/sdk/middleware/index.ts
|
|
277
|
+
/**
|
|
278
|
+
* Creates a circuit breaker middleware.
|
|
279
|
+
*
|
|
280
|
+
* Prevents cascading failures by temporarily blocking requests
|
|
281
|
+
* to failing providers.
|
|
282
|
+
*
|
|
283
|
+
* @example
|
|
284
|
+
* ```typescript
|
|
285
|
+
* const breaker = createCircuitBreaker({
|
|
286
|
+
* failureThreshold: 5,
|
|
287
|
+
* successThreshold: 2,
|
|
288
|
+
* timeout: 30_000
|
|
289
|
+
* });
|
|
290
|
+
* ```
|
|
291
|
+
*/
|
|
292
|
+
function createCircuitBreaker(config) {
|
|
293
|
+
const { failureThreshold, successThreshold, timeout, onStateChange } = config;
|
|
294
|
+
const states = /* @__PURE__ */ new Map();
|
|
295
|
+
function getOrCreateState(key) {
|
|
296
|
+
let state = states.get(key);
|
|
297
|
+
if (!state) {
|
|
298
|
+
state = {
|
|
299
|
+
state: "closed",
|
|
300
|
+
failures: 0,
|
|
301
|
+
successes: 0,
|
|
302
|
+
lastFailure: 0,
|
|
303
|
+
lastAttempt: 0
|
|
304
|
+
};
|
|
305
|
+
states.set(key, state);
|
|
306
|
+
}
|
|
307
|
+
return state;
|
|
308
|
+
}
|
|
309
|
+
function transitionTo(key, breaker, newState) {
|
|
310
|
+
if (breaker.state !== newState) {
|
|
311
|
+
breaker.state = newState;
|
|
312
|
+
onStateChange?.(newState, key);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
const middleware = async (ctx, next) => {
|
|
316
|
+
const key = resolveModelId(ctx.model);
|
|
317
|
+
const breaker = getOrCreateState(key);
|
|
318
|
+
const now = Date.now();
|
|
319
|
+
if (breaker.state === "open" && now - breaker.lastFailure >= timeout) transitionTo(key, breaker, "half-open");
|
|
320
|
+
if (breaker.state === "open") return {
|
|
321
|
+
success: false,
|
|
322
|
+
error: /* @__PURE__ */ new Error(`Circuit breaker open for ${key}`),
|
|
323
|
+
duration: 0,
|
|
324
|
+
metadata: {
|
|
325
|
+
circuitState: "open",
|
|
326
|
+
provider: key
|
|
327
|
+
}
|
|
328
|
+
};
|
|
329
|
+
breaker.lastAttempt = now;
|
|
330
|
+
let result;
|
|
331
|
+
try {
|
|
332
|
+
result = await next();
|
|
333
|
+
} catch (error) {
|
|
334
|
+
result = {
|
|
335
|
+
success: false,
|
|
336
|
+
error: error instanceof Error ? error : new Error(String(error)),
|
|
337
|
+
duration: Date.now() - ctx.startTime
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
if (result.success) {
|
|
341
|
+
breaker.failures = 0;
|
|
342
|
+
breaker.successes++;
|
|
343
|
+
if (breaker.state === "half-open" && breaker.successes >= successThreshold) {
|
|
344
|
+
transitionTo(key, breaker, "closed");
|
|
345
|
+
breaker.successes = 0;
|
|
346
|
+
}
|
|
347
|
+
} else {
|
|
348
|
+
breaker.successes = 0;
|
|
349
|
+
breaker.failures++;
|
|
350
|
+
breaker.lastFailure = now;
|
|
351
|
+
if (breaker.failures >= failureThreshold) transitionTo(key, breaker, "open");
|
|
352
|
+
}
|
|
353
|
+
return result;
|
|
354
|
+
};
|
|
355
|
+
const extendedMiddleware = middleware;
|
|
356
|
+
extendedMiddleware.getState = (key = "default") => getOrCreateState(key).state;
|
|
357
|
+
extendedMiddleware.reset = (key) => {
|
|
358
|
+
if (key) states.delete(key);
|
|
359
|
+
else states.clear();
|
|
360
|
+
};
|
|
361
|
+
return extendedMiddleware;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
//#endregion
|
|
365
|
+
export { withCircuitBreaker as a, circuitBreakerRegistry as i, CircuitBreaker as n, CircuitBreakerRegistry as r, createCircuitBreaker as t };
|
|
366
|
+
//# sourceMappingURL=middleware-CZQCTHfl.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"middleware-CZQCTHfl.mjs","names":[],"sources":["../src/sdk/middleware/circuit-breaker.ts","../src/sdk/middleware/index.ts"],"sourcesContent":["/**\n * @fileoverview Circuit breaker middleware for AI operations\n *\n * Implements the circuit breaker pattern to prevent cascading failures\n * in AI operation pipelines. Supports multiple failure states, automatic\n * recovery, and configurable fallback behavior.\n *\n * @module @od-oneapp/ai-platform/sdk/middleware/circuit-breaker\n */\n\n/**\n * Circuit breaker states.\n */\nexport type CircuitState = 'closed' | 'open' | 'half-open';\n\n/**\n * Fallback behavior when circuit is open.\n */\nexport type FallbackBehavior = 'error' | 'default' | 'partial' | 'cache';\n\n/**\n * Circuit breaker configuration.\n */\nexport interface CircuitBreakerConfig<TDefault = unknown> {\n /** Name identifier for the circuit (used in logging) */\n name: string;\n /** Number of failures before opening the circuit (default: 5) */\n failureThreshold?: number;\n /** Time in ms before attempting to close the circuit (default: 30000) */\n resetTimeout?: number;\n /** Number of successful requests in half-open to close circuit (default: 2) */\n halfOpenRequests?: number;\n /** Behavior when circuit is open */\n fallbackBehavior?: FallbackBehavior;\n /** Default value to return when using 'default' fallback */\n defaultValue?: TDefault;\n /** Optional callback when state changes */\n onStateChange?: (from: CircuitState, to: CircuitState) => void;\n /** Optional callback for metrics/telemetry */\n onMetrics?: (metrics: CircuitMetrics) => void;\n}\n\n/**\n * Circuit breaker metrics for monitoring.\n */\nexport interface CircuitMetrics {\n name: string;\n state: CircuitState;\n failureCount: number;\n successCount: number;\n lastFailureTime?: number;\n lastSuccessTime?: number;\n totalRequests: number;\n totalFailures: number;\n totalSuccesses: number;\n}\n\n/**\n * Circuit breaker error thrown when circuit is open.\n */\nexport class CircuitOpenError extends Error {\n readonly circuitName: string;\n readonly resetTime: number;\n\n constructor(circuitName: string, resetTime: number) {\n super(`Circuit '${circuitName}' is open. Will attempt reset in ${resetTime}ms`);\n this.name = 'CircuitOpenError';\n this.circuitName = circuitName;\n this.resetTime = resetTime;\n }\n}\n\n/**\n * Circuit breaker implementation.\n * Manages state transitions and failure tracking for a single circuit.\n */\nexport class CircuitBreaker<TDefault = unknown> {\n private state: CircuitState = 'closed';\n private failureCount = 0;\n private successCount = 0;\n private lastFailureTime?: number;\n private lastSuccessTime?: number;\n private totalRequests = 0;\n private totalFailures = 0;\n private totalSuccesses = 0;\n private halfOpenSuccessCount = 0;\n private resetTimer?: ReturnType<typeof setTimeout>;\n\n private readonly config: Required<CircuitBreakerConfig<TDefault>>;\n\n constructor(config: CircuitBreakerConfig<TDefault>) {\n this.config = {\n failureThreshold: config.failureThreshold ?? 5,\n resetTimeout: config.resetTimeout ?? 30000,\n halfOpenRequests: config.halfOpenRequests ?? 2,\n fallbackBehavior: config.fallbackBehavior ?? 'error',\n defaultValue: config.defaultValue as TDefault,\n onStateChange: config.onStateChange ?? (() => {}),\n onMetrics: config.onMetrics ?? (() => {}),\n name: config.name,\n };\n }\n\n /**\n * Gets the current circuit state.\n */\n getState(): CircuitState {\n return this.state;\n }\n\n /**\n * Gets current metrics for the circuit.\n */\n getMetrics(): CircuitMetrics {\n return {\n name: this.config.name,\n state: this.state,\n failureCount: this.failureCount,\n successCount: this.successCount,\n lastFailureTime: this.lastFailureTime,\n lastSuccessTime: this.lastSuccessTime,\n totalRequests: this.totalRequests,\n totalFailures: this.totalFailures,\n totalSuccesses: this.totalSuccesses,\n };\n }\n\n /**\n * Transitions the circuit to a new state.\n */\n private transitionTo(newState: CircuitState): void {\n if (this.state === newState) return;\n\n const oldState = this.state;\n this.state = newState;\n\n this.config.onStateChange(oldState, newState);\n this.config.onMetrics(this.getMetrics());\n }\n\n /**\n * Records a failure and potentially opens the circuit.\n */\n private recordFailure(_error: Error): void {\n this.failureCount++;\n this.totalFailures++;\n this.lastFailureTime = Date.now();\n\n if (this.state === 'half-open') {\n // Any failure in half-open immediately opens the circuit\n this.openCircuit();\n } else if (this.failureCount >= this.config.failureThreshold) {\n this.openCircuit();\n }\n }\n\n /**\n * Records a success and potentially closes the circuit.\n */\n private recordSuccess(): void {\n this.successCount++;\n this.totalSuccesses++;\n this.lastSuccessTime = Date.now();\n\n if (this.state === 'half-open') {\n this.halfOpenSuccessCount++;\n if (this.halfOpenSuccessCount >= this.config.halfOpenRequests) {\n this.closeCircuit();\n }\n } else if (this.state === 'closed') {\n // Reset failure count on success in closed state\n this.failureCount = 0;\n }\n }\n\n /**\n * Opens the circuit, preventing requests.\n */\n private openCircuit(): void {\n this.transitionTo('open');\n this.halfOpenSuccessCount = 0;\n\n // Schedule transition to half-open\n if (this.resetTimer) {\n clearTimeout(this.resetTimer);\n }\n\n this.resetTimer = setTimeout(() => {\n this.transitionTo('half-open');\n this.halfOpenSuccessCount = 0;\n }, this.config.resetTimeout);\n }\n\n /**\n * Closes the circuit, allowing requests.\n */\n private closeCircuit(): void {\n this.transitionTo('closed');\n this.failureCount = 0;\n this.halfOpenSuccessCount = 0;\n\n if (this.resetTimer) {\n clearTimeout(this.resetTimer);\n this.resetTimer = undefined;\n }\n }\n\n /**\n * Checks if the circuit allows a request.\n */\n canRequest(): boolean {\n return this.state !== 'open';\n }\n\n /**\n * Gets time remaining before circuit resets (in ms).\n * Returns 0 if circuit is not open.\n */\n getResetTime(): number {\n if (this.state !== 'open' || !this.lastFailureTime) {\n return 0;\n }\n const elapsed = Date.now() - this.lastFailureTime;\n return Math.max(0, this.config.resetTimeout - elapsed);\n }\n\n /**\n * Executes a function with circuit breaker protection.\n *\n * @param fn - Function to execute\n * @returns Promise with result or fallback value\n * @throws CircuitOpenError if circuit is open and fallback is 'error'\n */\n async execute<T extends TDefault>(fn: () => Promise<T>): Promise<T> {\n this.totalRequests++;\n\n // Check if circuit allows request\n if (!this.canRequest()) {\n const resetTime = this.getResetTime();\n\n switch (this.config.fallbackBehavior) {\n case 'error':\n case 'cache': // Cache fallback not yet implemented, fall back to error\n throw new CircuitOpenError(this.config.name, resetTime);\n case 'default':\n return this.config.defaultValue as T;\n case 'partial':\n // Allow request but with degraded functionality (handled by caller)\n break;\n }\n }\n\n try {\n const result = await fn();\n this.recordSuccess();\n return result;\n } catch (error) {\n this.recordFailure(error instanceof Error ? error : new Error(String(error)));\n throw error;\n }\n }\n\n /**\n * Reports a failure that occurred outside of execute() (e.g., streaming errors).\n * This allows tracking failures that happen asynchronously after the initial call.\n *\n * @param error - The error that occurred.\n */\n reportFailure(error: Error): void {\n this.recordFailure(error);\n }\n\n /**\n * Manually resets the circuit to closed state.\n * Use with caution - typically for testing or manual recovery.\n */\n reset(): void {\n const oldState = this.state;\n this.state = 'closed';\n this.failureCount = 0;\n this.successCount = 0;\n this.halfOpenSuccessCount = 0;\n\n if (this.resetTimer) {\n clearTimeout(this.resetTimer);\n this.resetTimer = undefined;\n }\n\n if (oldState !== 'closed') {\n this.config.onStateChange(oldState, 'closed');\n }\n this.config.onMetrics(this.getMetrics());\n }\n\n /**\n * Cleans up resources (timers).\n */\n destroy(): void {\n if (this.resetTimer) {\n clearTimeout(this.resetTimer);\n this.resetTimer = undefined;\n }\n }\n}\n\n/**\n * Circuit breaker registry for managing multiple circuits.\n */\nexport class CircuitBreakerRegistry {\n private circuits = new Map<string, CircuitBreaker>();\n\n /**\n * Gets or creates a circuit breaker with the given name.\n */\n getOrCreate<T = unknown>(config: CircuitBreakerConfig<T>): CircuitBreaker<T> {\n let circuit = this.circuits.get(config.name);\n if (!circuit) {\n circuit = new CircuitBreaker(config);\n this.circuits.set(config.name, circuit);\n }\n return circuit as CircuitBreaker<T>;\n }\n\n /**\n * Gets a circuit breaker by name.\n */\n get(name: string): CircuitBreaker | undefined {\n return this.circuits.get(name);\n }\n\n /**\n * Gets all circuit metrics.\n */\n getAllMetrics(): CircuitMetrics[] {\n return Array.from(this.circuits.values()).map(c => c.getMetrics());\n }\n\n /**\n * Resets all circuits.\n */\n resetAll(): void {\n for (const circuit of this.circuits.values()) {\n circuit.reset();\n }\n }\n\n /**\n * Cleans up all circuits.\n */\n destroy(): void {\n for (const circuit of this.circuits.values()) {\n circuit.destroy();\n }\n this.circuits.clear();\n }\n}\n\n/**\n * Default circuit breaker registry instance.\n */\nexport const circuitBreakerRegistry = new CircuitBreakerRegistry();\n\n/**\n * Creates a circuit breaker wrapper for a function.\n *\n * @param name - Circuit name\n * @param config - Circuit configuration (optional)\n * @returns Function wrapper that executes with circuit breaker protection\n *\n * @example\n * ```typescript\n * const protectedFetch = withCircuitBreaker('external-api', {\n * failureThreshold: 3,\n * resetTimeout: 60000,\n * });\n *\n * const result = await protectedFetch(async () => {\n * return fetch('https://api.example.com/data');\n * });\n * ```\n */\nexport function withCircuitBreaker<T>(\n name: string,\n config?: Partial<Omit<CircuitBreakerConfig, 'name'>>,\n): (fn: () => Promise<T>) => Promise<T> {\n const circuit = circuitBreakerRegistry.getOrCreate({ name, ...config });\n return (fn: () => Promise<T>) => circuit.execute(fn);\n}\n","/**\n * Middleware System\n *\n * AI SDK v6 experimental middleware patterns:\n * - Circuit breaker for provider failures\n * - Rate limiting with token bucket\n * - Provider fallback chains\n * - Request/response transformation\n *\n * @module middleware\n */\n\nimport { logWarn } from '@repo/shared/logs';\n\nimport { resolveModelId, type ModelRef } from '../../shared';\n\n/** Middleware function signature */\nexport type MiddlewareFn<TContext = unknown> = (\n ctx: MiddlewareContext<TContext>,\n next: () => Promise<MiddlewareResult>,\n) => Promise<MiddlewareResult>;\n\n/** Model call options */\nexport interface ModelCallOptions {\n readonly prompt?: string;\n readonly messages?: unknown[];\n readonly maxOutputTokens?: number;\n readonly temperature?: number;\n readonly [key: string]: unknown;\n}\n\n/** Context passed through middleware chain */\nexport interface MiddlewareContext<TContext = unknown> {\n readonly model: ModelRef;\n readonly options: ModelCallOptions;\n readonly custom: TContext | undefined;\n readonly attempt: number;\n readonly startTime: number;\n}\n\n/** Result from middleware execution */\nexport interface MiddlewareResult {\n readonly success: boolean;\n readonly response?: unknown;\n readonly error?: Error;\n readonly duration: number;\n readonly metadata?: Record<string, unknown>;\n}\n\n/** Circuit breaker state */\nexport type CircuitState = 'closed' | 'open' | 'half-open';\n\n/** Circuit breaker configuration */\nexport interface CircuitBreakerConfig {\n readonly failureThreshold: number;\n readonly successThreshold: number;\n readonly timeout: number;\n readonly onStateChange?: (state: CircuitState, provider?: string) => void;\n}\n\n/** Rate limiter configuration */\nexport interface RateLimiterConfig {\n readonly tokensPerInterval: number;\n readonly interval: number;\n readonly maxBurst?: number;\n}\n\n/** Provider fallback configuration */\nexport interface FallbackConfig {\n readonly providers: ModelRef[];\n readonly onFallback?: (from: string, to: string, error: Error) => void;\n}\n\n// -----------------------------------------------------------------------------\n// Circuit Breaker\n// -----------------------------------------------------------------------------\n\ninterface CircuitBreakerState {\n state: CircuitState;\n failures: number;\n successes: number;\n lastFailure: number;\n lastAttempt: number;\n}\n\n/**\n * Creates a circuit breaker middleware.\n *\n * Prevents cascading failures by temporarily blocking requests\n * to failing providers.\n *\n * @example\n * ```typescript\n * const breaker = createCircuitBreaker({\n * failureThreshold: 5,\n * successThreshold: 2,\n * timeout: 30_000\n * });\n * ```\n */\nexport function createCircuitBreaker(\n config: CircuitBreakerConfig,\n): MiddlewareFn & { getState: (key?: string) => CircuitState; reset: (key?: string) => void } {\n const { failureThreshold, successThreshold, timeout, onStateChange } = config;\n const states = new Map<string, CircuitBreakerState>();\n\n // Extended middleware with state access\n type ExtendedMiddleware = MiddlewareFn & {\n getState: (key?: string) => CircuitState;\n reset: (key?: string) => void;\n };\n\n function getOrCreateState(key: string): CircuitBreakerState {\n let state = states.get(key);\n if (!state) {\n state = {\n state: 'closed',\n failures: 0,\n successes: 0,\n lastFailure: 0,\n lastAttempt: 0,\n };\n states.set(key, state);\n }\n return state;\n }\n\n function transitionTo(key: string, breaker: CircuitBreakerState, newState: CircuitState): void {\n if (breaker.state !== newState) {\n breaker.state = newState;\n onStateChange?.(newState, key);\n }\n }\n\n const middleware: MiddlewareFn = async (ctx, next) => {\n const key = resolveModelId(ctx.model);\n const breaker = getOrCreateState(key);\n const now = Date.now();\n\n // Check if circuit should transition from open to half-open\n if (breaker.state === 'open' && now - breaker.lastFailure >= timeout) {\n transitionTo(key, breaker, 'half-open');\n }\n\n // Block requests when circuit is open\n if (breaker.state === 'open') {\n return {\n success: false,\n error: new Error(`Circuit breaker open for ${key}`),\n duration: 0,\n metadata: { circuitState: 'open', provider: key },\n };\n }\n\n breaker.lastAttempt = now;\n\n // Wrap next() to catch thrown exceptions and record as failures\n let result: MiddlewareResult;\n try {\n result = await next();\n } catch (error) {\n result = {\n success: false,\n error: error instanceof Error ? error : new Error(String(error)),\n duration: Date.now() - ctx.startTime,\n };\n }\n\n if (result.success) {\n breaker.failures = 0;\n breaker.successes++;\n\n if (breaker.state === 'half-open' && breaker.successes >= successThreshold) {\n transitionTo(key, breaker, 'closed');\n breaker.successes = 0;\n }\n } else {\n breaker.successes = 0;\n breaker.failures++;\n breaker.lastFailure = now;\n\n if (breaker.failures >= failureThreshold) {\n transitionTo(key, breaker, 'open');\n }\n }\n\n return result;\n };\n\n const extendedMiddleware = middleware as ExtendedMiddleware;\n extendedMiddleware.getState = (key = 'default') => getOrCreateState(key).state;\n extendedMiddleware.reset = (key?: string) => {\n if (key) {\n states.delete(key);\n } else {\n states.clear();\n }\n };\n\n return extendedMiddleware;\n}\n\n// -----------------------------------------------------------------------------\n// Rate Limiter (Token Bucket)\n// -----------------------------------------------------------------------------\n\ninterface TokenBucket {\n tokens: number;\n lastRefill: number;\n}\n\n/**\n * Creates a rate limiter middleware using token bucket algorithm.\n *\n * @example\n * ```typescript\n * const limiter = createRateLimiter({\n * tokensPerInterval: 100,\n * interval: 60_000, // 1 minute\n * maxBurst: 150\n * });\n * ```\n */\nexport function createRateLimiter(\n config: RateLimiterConfig,\n): MiddlewareFn & { getAvailableTokens: (key?: string) => number } {\n const { tokensPerInterval, interval, maxBurst = tokensPerInterval } = config;\n const buckets = new Map<string, TokenBucket>();\n\n type ExtendedRateLimiter = MiddlewareFn & {\n getAvailableTokens: (key?: string) => number;\n };\n\n function getOrCreateBucket(key: string): TokenBucket {\n let bucket = buckets.get(key);\n if (!bucket) {\n bucket = { tokens: tokensPerInterval, lastRefill: Date.now() };\n buckets.set(key, bucket);\n }\n return bucket;\n }\n\n function refillBucket(bucket: TokenBucket): void {\n const now = Date.now();\n const elapsed = now - bucket.lastRefill;\n const refillTokens = Math.floor((elapsed / interval) * tokensPerInterval);\n\n if (refillTokens > 0) {\n bucket.tokens = Math.min(maxBurst, bucket.tokens + refillTokens);\n bucket.lastRefill = now;\n }\n }\n\n const middleware: MiddlewareFn = async (ctx, next) => {\n const key = resolveModelId(ctx.model);\n const bucket = getOrCreateBucket(key);\n\n refillBucket(bucket);\n\n if (bucket.tokens < 1) {\n const waitTime = Math.ceil(interval / tokensPerInterval);\n return {\n success: false,\n error: new Error(`Rate limited for ${key}. Retry after ${waitTime}ms`),\n duration: 0,\n metadata: { rateLimited: true, retryAfter: waitTime },\n };\n }\n\n bucket.tokens--;\n return next();\n };\n\n const extendedMiddleware = middleware as ExtendedRateLimiter;\n extendedMiddleware.getAvailableTokens = (key = 'default') => {\n const bucket = getOrCreateBucket(key);\n refillBucket(bucket);\n return bucket.tokens;\n };\n\n return extendedMiddleware;\n}\n\n// -----------------------------------------------------------------------------\n// Provider Fallback\n// -----------------------------------------------------------------------------\n\n/**\n * Creates a provider fallback middleware.\n *\n * Automatically falls back to alternative providers when primary fails.\n *\n * **IMPORTANT**: Due to pipeline architecture, this middleware should be positioned\n * as the LAST middleware in the pipeline (closest to the terminal executor) for\n * fallback to work correctly with each provider. Alternatively, provide an `executor`\n * function that will be called for each provider attempt.\n *\n * @example\n * ```typescript\n * // Option 1: Position as last middleware\n * const pipeline = createPipeline(\n * loggingMiddleware,\n * createFallbackMiddleware({\n * providers: [openai('gpt-4'), anthropic('claude-3')],\n * onFallback: (from, to, error) => console.log(`Falling back from ${from} to ${to}`)\n * }) // LAST - closest to terminal\n * );\n *\n * // Option 2: Provide custom executor\n * const fallback = createFallbackMiddleware({\n * providers: [openai('gpt-4'), anthropic('claude-3')],\n * executor: async (ctx) => executeModelCall(ctx)\n * });\n * ```\n */\nexport function createFallbackMiddleware(\n config: FallbackConfig & {\n /** Optional executor for each provider attempt. If provided, this is called instead of next(). */\n executor?: (ctx: MiddlewareContext) => Promise<MiddlewareResult>;\n },\n): MiddlewareFn {\n const { providers, onFallback, executor } = config;\n\n return async (ctx, next) => {\n let lastError: Error | undefined;\n\n for (let i = 0; i < providers.length; i++) {\n const provider = providers[i];\n if (!provider) continue;\n\n const isOriginal = i === 0;\n const previousProvider = isOriginal ? null : providers[i - 1];\n\n if (!isOriginal && lastError && previousProvider) {\n onFallback?.(resolveModelId(previousProvider), resolveModelId(provider), lastError);\n }\n\n // Create new context with current provider\n const newCtx: MiddlewareContext = {\n ...ctx,\n model: provider,\n attempt: i + 1,\n };\n\n // Execute with current provider\n // Use executor if provided, otherwise use next()\n // Note: Without executor, subsequent iterations reuse the same next()\n // which advances the pipeline rather than re-executing downstream.\n // This only works correctly when fallback is the last middleware.\n if (!executor && process.env.NODE_ENV !== 'production') {\n logWarn(\n '[createFallbackMiddleware] Warning: Fallback middleware should be positioned last or provide an executor option. Without executor, fallback behavior may not work correctly if other middleware follows.',\n );\n }\n const result = executor\n ? await executeWithModel(newCtx, () => executor(newCtx))\n : await executeWithModel(newCtx, next);\n\n if (result.success) {\n return {\n ...result,\n metadata: { ...result.metadata, provider: resolveModelId(provider), attempt: i + 1 },\n };\n }\n\n lastError = result.error;\n }\n\n return {\n success: false,\n error: lastError ?? new Error('All providers failed'),\n duration: Date.now() - ctx.startTime,\n metadata: { attempts: providers.length },\n };\n };\n}\n\nasync function executeWithModel(\n ctx: MiddlewareContext,\n next: () => Promise<MiddlewareResult>,\n): Promise<MiddlewareResult> {\n try {\n return await next();\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error : new Error(String(error)),\n duration: Date.now() - ctx.startTime,\n };\n }\n}\n\n// -----------------------------------------------------------------------------\n// Middleware Pipeline\n// -----------------------------------------------------------------------------\n\n/**\n * Creates a middleware pipeline that executes middlewares in order.\n *\n * @example\n * ```typescript\n * const pipeline = createPipeline(\n * createRateLimiter({ tokensPerInterval: 100, interval: 60_000 }),\n * createCircuitBreaker({ failureThreshold: 5, successThreshold: 2, timeout: 30_000 }),\n * loggingMiddleware\n * );\n *\n * const result = await pipeline.execute(model, options);\n * ```\n */\nexport function createPipeline<TContext = unknown>(\n ...middlewares: MiddlewareFn<TContext>[]\n): {\n execute: (\n model: ModelRef,\n options: ModelCallOptions,\n custom?: TContext,\n ) => Promise<MiddlewareResult>;\n use: (middleware: MiddlewareFn<TContext>) => void;\n} {\n const stack = [...middlewares];\n\n function execute(\n model: ModelRef,\n options: ModelCallOptions,\n custom?: TContext,\n ): Promise<MiddlewareResult> {\n const ctx: MiddlewareContext<TContext> = {\n model,\n options,\n custom,\n attempt: 1,\n startTime: Date.now(),\n };\n\n let index = 0;\n\n const next = async (): Promise<MiddlewareResult> => {\n if (index >= stack.length) {\n // Terminal: execute actual model call\n return executeModelCall(ctx);\n }\n\n const middleware = stack[index++];\n if (!middleware) {\n return next();\n }\n\n return middleware(ctx, next);\n };\n\n return next();\n }\n\n return {\n execute,\n use: (middleware: MiddlewareFn<TContext>) => stack.push(middleware),\n };\n}\n\nasync function executeModelCall(ctx: MiddlewareContext): Promise<MiddlewareResult> {\n const startTime = Date.now();\n\n try {\n // This would be replaced with actual model invocation\n // For now, return success placeholder\n return {\n success: true,\n duration: Date.now() - startTime,\n metadata: { model: resolveModelId(ctx.model) },\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error : new Error(String(error)),\n duration: Date.now() - startTime,\n };\n }\n}\n\n// -----------------------------------------------------------------------------\n// Utility Middlewares\n// -----------------------------------------------------------------------------\n\n/**\n * Creates a logging middleware.\n */\nexport function createLoggingMiddleware(\n logger: { log: (message: string, data?: unknown) => void } = console,\n): MiddlewareFn {\n return async (ctx, next) => {\n const id = Math.random().toString(36).slice(2, 8);\n logger.log(`[${id}] Request to ${resolveModelId(ctx.model)}`, { attempt: ctx.attempt });\n\n const result = await next();\n\n logger.log(`[${id}] Response from ${resolveModelId(ctx.model)}`, {\n success: result.success,\n duration: result.duration,\n });\n\n return result;\n };\n}\n\n/**\n * Creates a timeout middleware.\n */\nexport function createTimeoutMiddleware(timeoutMs: number): MiddlewareFn {\n return async (ctx, next) => {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeoutMs);\n\n try {\n const result = await Promise.race([\n next(),\n new Promise<MiddlewareResult>((resolve, reject) => {\n void resolve;\n controller.signal.addEventListener('abort', () => {\n reject(new Error(`Request timeout after ${timeoutMs}ms`));\n });\n }),\n ]);\n return result;\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error : new Error(String(error)),\n duration: Date.now() - ctx.startTime,\n metadata: { timeout: true },\n };\n } finally {\n clearTimeout(timeoutId);\n }\n };\n}\n\n/**\n * Creates a retry middleware with exponential backoff.\n *\n * **IMPORTANT**: Due to pipeline architecture, this middleware should be positioned\n * as the LAST middleware in the pipeline (closest to the terminal executor) for\n * retries to work correctly. Alternatively, provide an `executor` function that\n * will be called for each retry attempt.\n *\n * @example\n * ```typescript\n * // Option 1: Position as last middleware\n * const pipeline = createPipeline(\n * loggingMiddleware,\n * rateLimiter,\n * createRetryMiddleware({ maxRetries: 3 }) // LAST - closest to terminal\n * );\n *\n * // Option 2: Provide custom executor for true retries\n * const retry = createRetryMiddleware({\n * maxRetries: 3,\n * executor: async (ctx) => executeModelCall(ctx)\n * });\n * ```\n */\nexport function createRetryMiddleware(options: {\n maxRetries: number;\n baseDelay?: number;\n maxDelay?: number;\n shouldRetry?: (error: Error) => boolean;\n /** Optional executor for true retry behavior. If provided, this is called for each retry. */\n executor?: (ctx: MiddlewareContext) => Promise<MiddlewareResult>;\n}): MiddlewareFn {\n const {\n maxRetries,\n baseDelay = 1000,\n maxDelay = 30_000,\n shouldRetry = () => true,\n executor,\n } = options;\n\n return async (ctx, next) => {\n let lastError: Error | undefined;\n // Track if this is the first attempt (use next), or subsequent (use executor if provided)\n let isFirstAttempt = true;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n if (attempt > 0) {\n const delay = Math.min(baseDelay * 2 ** (attempt - 1), maxDelay);\n await new Promise(resolve => setTimeout(resolve, delay));\n }\n\n // For first attempt, always use next() to continue pipeline\n // For subsequent attempts, use executor if provided, otherwise log warning and continue\n let result: MiddlewareResult;\n if (isFirstAttempt) {\n result = await next();\n isFirstAttempt = false;\n } else if (executor) {\n result = await executor({ ...ctx, attempt: attempt + 1 });\n } else {\n // Without executor, subsequent next() calls won't retry - they advance pipeline\n // This is expected when retry is positioned as last middleware\n result = await next();\n }\n\n if (result.success) {\n return { ...result, metadata: { ...result.metadata, attempts: attempt + 1 } };\n }\n\n if (result.error && !shouldRetry(result.error)) {\n return result;\n }\n\n lastError = result.error;\n }\n\n return {\n success: false,\n error: lastError ?? new Error('Max retries exceeded'),\n duration: Date.now() - ctx.startTime,\n metadata: { maxRetriesExceeded: true, attempts: maxRetries + 1 },\n };\n };\n}\n\n// -----------------------------------------------------------------------------\n// Model Middleware (AI SDK v6 experimental)\n// -----------------------------------------------------------------------------\n\nexport {\n // Core wrapper\n wrapLanguageModel,\n getModelMiddleware,\n // Pre-built middleware\n extractReasoningMiddleware,\n addToolInputExamplesMiddleware,\n // Composition\n composeMiddleware,\n // Utility middleware (named differently to avoid conflict with pipeline middleware)\n createModelLoggingMiddleware,\n createModelCachingMiddleware,\n // Types\n type WrapLanguageModelConfig,\n type LanguageModelMiddleware,\n type ExtractReasoningConfig,\n type MiddlewareToolExample,\n type AddToolInputExamplesConfig,\n type MiddlewareTransformResult,\n} from './model-middleware';\n\n// Circuit breaker (standalone class-based implementation from @repo/ai)\nexport {\n CircuitBreaker,\n CircuitBreakerRegistry,\n CircuitOpenError,\n circuitBreakerRegistry,\n withCircuitBreaker,\n type CircuitBreakerConfig as StandaloneCircuitBreakerConfig,\n type CircuitMetrics,\n type FallbackBehavior,\n // Note: CircuitState from circuit-breaker.ts is identical to the one above.\n // Not re-exported here to avoid conflict.\n} from './circuit-breaker';\n"],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import "./ai-runtime-DIwOEc6g.mjs";
|
|
2
|
+
import { a as Gateway, i as getModelMetadata, n as Model, o as ModelMetadata, r as getModelId, s as ModelTier, t as MODEL_METADATA } from "./registry-DVPWzkXR.mjs";
|
|
3
|
+
import { S as getModelsByTier, _ as CreateLanguageModelOptions, a as anthropic_d_exports, b as getCheapestModel, c as TOKENS, d as TokenPreset, f as TopPPreset, g as modelSupportsTools, h as modelSupportsStreaming, i as openai_d_exports, l as TOP_P, m as modelSupportsReasoning, n as xai_d_exports, o as CommonMode, p as commonModes, r as google_d_exports, s as TEMPS, t as perplexity_d_exports, u as TemperaturePreset, v as createLanguageModel, x as getModelTier, y as estimateCost } from "./index-DotINT7o.mjs";
|
|
4
|
+
|
|
5
|
+
//#region src/models/index.d.ts
|
|
6
|
+
declare namespace index_d_exports {
|
|
7
|
+
export { CommonMode, CreateLanguageModelOptions, Gateway, MODEL_METADATA, Model, ModelMetadata, ModelTier, TEMPS, TOKENS, TOP_P, TemperaturePreset, TokenPreset, TopPPreset, anthropic_d_exports as anthropicProvider, commonModes, createLanguageModel, estimateCost, getCheapestModel, getModelId, getModelMetadata, getModelTier, getModelsByTier, google_d_exports as googleProvider, modelSupportsReasoning, modelSupportsStreaming, modelSupportsTools, openai_d_exports as openaiProvider, perplexity_d_exports as perplexityProvider, xai_d_exports as xaiProvider };
|
|
8
|
+
}
|
|
9
|
+
//#endregion
|
|
10
|
+
export { CommonMode, type CreateLanguageModelOptions, type Gateway, MODEL_METADATA, Model, type ModelMetadata, type ModelTier, TEMPS, TOKENS, TOP_P, TemperaturePreset, TokenPreset, TopPPreset, anthropic_d_exports as anthropicProvider, commonModes, createLanguageModel, estimateCost, getCheapestModel, getModelId, getModelMetadata, getModelTier, getModelsByTier, google_d_exports as googleProvider, modelSupportsReasoning, modelSupportsStreaming, modelSupportsTools, openai_d_exports as openaiProvider, perplexity_d_exports as perplexityProvider, index_d_exports as t, xai_d_exports as xaiProvider };
|
|
11
|
+
//# sourceMappingURL=models.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"models.d.mts","names":[],"sources":["../src/models/index.ts"],"mappings":""}
|
package/dist/models.mjs
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { t as __exportAll } from "./chunk-CkzbjWQW.mjs";
|
|
2
|
+
import { i as getModelMetadata, n as Model, r as getModelId, t as MODEL_METADATA } from "./registry-CsD3iTIx.mjs";
|
|
3
|
+
import { _ as getModelsByTier, a as modelSupportsTools, c as anthropic_exports, d as TOP_P, f as commonModes, g as getModelTier, h as getCheapestModel, i as modelSupportsStreaming, l as TEMPS, m as estimateCost, n as google_exports, o as perplexity_exports, p as createLanguageModel, r as modelSupportsReasoning, s as openai_exports, t as xai_exports, u as TOKENS } from "./xai-CbV_dCnP.mjs";
|
|
4
|
+
|
|
5
|
+
//#region src/models/index.ts
|
|
6
|
+
var models_exports = /* @__PURE__ */ __exportAll({
|
|
7
|
+
MODEL_METADATA: () => MODEL_METADATA,
|
|
8
|
+
Model: () => Model,
|
|
9
|
+
TEMPS: () => TEMPS,
|
|
10
|
+
TOKENS: () => TOKENS,
|
|
11
|
+
TOP_P: () => TOP_P,
|
|
12
|
+
anthropicProvider: () => anthropic_exports,
|
|
13
|
+
commonModes: () => commonModes,
|
|
14
|
+
createLanguageModel: () => createLanguageModel,
|
|
15
|
+
estimateCost: () => estimateCost,
|
|
16
|
+
getCheapestModel: () => getCheapestModel,
|
|
17
|
+
getModelId: () => getModelId,
|
|
18
|
+
getModelMetadata: () => getModelMetadata,
|
|
19
|
+
getModelTier: () => getModelTier,
|
|
20
|
+
getModelsByTier: () => getModelsByTier,
|
|
21
|
+
googleProvider: () => google_exports,
|
|
22
|
+
modelSupportsReasoning: () => modelSupportsReasoning,
|
|
23
|
+
modelSupportsStreaming: () => modelSupportsStreaming,
|
|
24
|
+
modelSupportsTools: () => modelSupportsTools,
|
|
25
|
+
openaiProvider: () => openai_exports,
|
|
26
|
+
perplexityProvider: () => perplexity_exports,
|
|
27
|
+
xaiProvider: () => xai_exports
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
//#endregion
|
|
31
|
+
export { MODEL_METADATA, Model, TEMPS, TOKENS, TOP_P, anthropic_exports as anthropicProvider, commonModes, createLanguageModel, estimateCost, getCheapestModel, getModelId, getModelMetadata, getModelTier, getModelsByTier, google_exports as googleProvider, modelSupportsReasoning, modelSupportsStreaming, modelSupportsTools, openai_exports as openaiProvider, perplexity_exports as perplexityProvider, models_exports as t, xai_exports as xaiProvider };
|
|
32
|
+
//# sourceMappingURL=models.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"models.mjs","names":[],"sources":["../src/models/index.ts"],"sourcesContent":["export { Model, MODEL_METADATA, getModelId, getModelMetadata } from './registry';\nexport {\n createLanguageModel,\n getModelsByTier,\n getModelTier,\n getCheapestModel,\n estimateCost,\n type CreateLanguageModelOptions,\n} from './provider-factory';\nexport type { Gateway, ModelTier, ModelMetadata } from './types';\n\n// Cross-provider capability detection\nexport { modelSupportsReasoning, modelSupportsTools, modelSupportsStreaming } from './capabilities';\n\n// Provider configurations (namespaced to avoid conflicts)\nexport * from './providers';\n"],"mappings":""}
|