@warlock.js/ai 4.1.1
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 +72 -0
- package/cjs/index.cjs +8625 -0
- package/cjs/index.cjs.map +1 -0
- package/esm/agent/agent-config.type.d.mts +160 -0
- package/esm/agent/agent-config.type.d.mts.map +1 -0
- package/esm/agent/agent-input-builder.mjs +111 -0
- package/esm/agent/agent-input-builder.mjs.map +1 -0
- package/esm/agent/agent-log-event.mjs +101 -0
- package/esm/agent/agent-log-event.mjs.map +1 -0
- package/esm/agent/agent-stream.d.mts +47 -0
- package/esm/agent/agent-stream.d.mts.map +1 -0
- package/esm/agent/agent-stream.mjs +82 -0
- package/esm/agent/agent-stream.mjs.map +1 -0
- package/esm/agent/agent-to-stream-event.mjs +86 -0
- package/esm/agent/agent-to-stream-event.mjs.map +1 -0
- package/esm/agent/agent.d.mts +38 -0
- package/esm/agent/agent.d.mts.map +1 -0
- package/esm/agent/agent.mjs +974 -0
- package/esm/agent/agent.mjs.map +1 -0
- package/esm/agent/index.d.mts +3 -0
- package/esm/agent/index.mjs +4 -0
- package/esm/agent/json-stream-guard.mjs +400 -0
- package/esm/agent/json-stream-guard.mjs.map +1 -0
- package/esm/ai.d.mts +64 -0
- package/esm/ai.d.mts.map +1 -0
- package/esm/ai.mjs +65 -0
- package/esm/ai.mjs.map +1 -0
- package/esm/config.d.mts +79 -0
- package/esm/config.d.mts.map +1 -0
- package/esm/config.mjs +43 -0
- package/esm/config.mjs.map +1 -0
- package/esm/contracts/agent/agent-options.type.d.mts +132 -0
- package/esm/contracts/agent/agent-options.type.d.mts.map +1 -0
- package/esm/contracts/agent/agent.contract.d.mts +92 -0
- package/esm/contracts/agent/agent.contract.d.mts.map +1 -0
- package/esm/contracts/agent/index.d.mts +2 -0
- package/esm/contracts/attachment.type.d.mts +100 -0
- package/esm/contracts/attachment.type.d.mts.map +1 -0
- package/esm/contracts/content-part.type.d.mts +55 -0
- package/esm/contracts/content-part.type.d.mts.map +1 -0
- package/esm/contracts/conversation-message.type.d.mts +51 -0
- package/esm/contracts/conversation-message.type.d.mts.map +1 -0
- package/esm/contracts/embedder.contract.d.mts +69 -0
- package/esm/contracts/embedder.contract.d.mts.map +1 -0
- package/esm/contracts/end.type.d.mts +53 -0
- package/esm/contracts/end.type.d.mts.map +1 -0
- package/esm/contracts/end.type.mjs +47 -0
- package/esm/contracts/end.type.mjs.map +1 -0
- package/esm/contracts/events/agent-events.type.d.mts +71 -0
- package/esm/contracts/events/agent-events.type.d.mts.map +1 -0
- package/esm/contracts/events/complete-event.type.d.mts +33 -0
- package/esm/contracts/events/complete-event.type.d.mts.map +1 -0
- package/esm/contracts/events/event-identity.type.d.mts +30 -0
- package/esm/contracts/events/event-identity.type.d.mts.map +1 -0
- package/esm/contracts/events/event-map.type.d.mts +80 -0
- package/esm/contracts/events/event-map.type.d.mts.map +1 -0
- package/esm/contracts/events/index.d.mts +7 -0
- package/esm/contracts/events/supervisor-events.type.d.mts +162 -0
- package/esm/contracts/events/supervisor-events.type.d.mts.map +1 -0
- package/esm/contracts/events/usage-event.type.d.mts +39 -0
- package/esm/contracts/events/usage-event.type.d.mts.map +1 -0
- package/esm/contracts/events/workflow-events.type.d.mts +51 -0
- package/esm/contracts/events/workflow-events.type.d.mts.map +1 -0
- package/esm/contracts/executable.contract.d.mts +25 -0
- package/esm/contracts/executable.contract.d.mts.map +1 -0
- package/esm/contracts/finish-reason.type.d.mts +17 -0
- package/esm/contracts/finish-reason.type.d.mts.map +1 -0
- package/esm/contracts/index.d.mts +63 -0
- package/esm/contracts/middleware/index.d.mts +3 -0
- package/esm/contracts/middleware/middleware-context.type.d.mts +99 -0
- package/esm/contracts/middleware/middleware-context.type.d.mts.map +1 -0
- package/esm/contracts/middleware/middleware-state.type.d.mts +34 -0
- package/esm/contracts/middleware/middleware-state.type.d.mts.map +1 -0
- package/esm/contracts/middleware/middleware.contract.d.mts +140 -0
- package/esm/contracts/middleware/middleware.contract.d.mts.map +1 -0
- package/esm/contracts/model-tool-call-request.type.d.mts +58 -0
- package/esm/contracts/model-tool-call-request.type.d.mts.map +1 -0
- package/esm/contracts/model.contract.d.mts +164 -0
- package/esm/contracts/model.contract.d.mts.map +1 -0
- package/esm/contracts/placeholders.type.d.mts +23 -0
- package/esm/contracts/placeholders.type.d.mts.map +1 -0
- package/esm/contracts/result/agent-result.type.d.mts +33 -0
- package/esm/contracts/result/agent-result.type.d.mts.map +1 -0
- package/esm/contracts/result/attempt-entry.type.d.mts +40 -0
- package/esm/contracts/result/attempt-entry.type.d.mts.map +1 -0
- package/esm/contracts/result/base-report.type.d.mts +137 -0
- package/esm/contracts/result/base-report.type.d.mts.map +1 -0
- package/esm/contracts/result/base-report.type.mjs +17 -0
- package/esm/contracts/result/base-report.type.mjs.map +1 -0
- package/esm/contracts/result/base-result.type.d.mts +26 -0
- package/esm/contracts/result/base-result.type.d.mts.map +1 -0
- package/esm/contracts/result/execute-result.type.d.mts +40 -0
- package/esm/contracts/result/execute-result.type.d.mts.map +1 -0
- package/esm/contracts/result/execution-report.type.d.mts +50 -0
- package/esm/contracts/result/execution-report.type.d.mts.map +1 -0
- package/esm/contracts/result/index.d.mts +14 -0
- package/esm/contracts/result/llm-trip.type.d.mts +36 -0
- package/esm/contracts/result/llm-trip.type.d.mts.map +1 -0
- package/esm/contracts/result/model-pricing.type.d.mts +51 -0
- package/esm/contracts/result/model-pricing.type.d.mts.map +1 -0
- package/esm/contracts/result/session-send-result.type.d.mts +29 -0
- package/esm/contracts/result/session-send-result.type.d.mts.map +1 -0
- package/esm/contracts/result/step-result.type.d.mts +43 -0
- package/esm/contracts/result/step-result.type.d.mts.map +1 -0
- package/esm/contracts/result/supervisor-result.type.d.mts +86 -0
- package/esm/contracts/result/supervisor-result.type.d.mts.map +1 -0
- package/esm/contracts/result/tool-call.type.d.mts +44 -0
- package/esm/contracts/result/tool-call.type.d.mts.map +1 -0
- package/esm/contracts/result/usage.type.d.mts +57 -0
- package/esm/contracts/result/usage.type.d.mts.map +1 -0
- package/esm/contracts/result/workflow-result.type.d.mts +45 -0
- package/esm/contracts/result/workflow-result.type.d.mts.map +1 -0
- package/esm/contracts/sdk-adapter.contract.d.mts +77 -0
- package/esm/contracts/sdk-adapter.contract.d.mts.map +1 -0
- package/esm/contracts/stream/stream-event.type.d.mts +68 -0
- package/esm/contracts/stream/stream-event.type.d.mts.map +1 -0
- package/esm/contracts/stream/stream.contract.d.mts +61 -0
- package/esm/contracts/stream/stream.contract.d.mts.map +1 -0
- package/esm/contracts/streaming-tool-guard-config.type.d.mts +78 -0
- package/esm/contracts/streaming-tool-guard-config.type.d.mts.map +1 -0
- package/esm/contracts/supervisor/ack-entry.type.d.mts +97 -0
- package/esm/contracts/supervisor/ack-entry.type.d.mts.map +1 -0
- package/esm/contracts/supervisor/classifier-context.type.d.mts +189 -0
- package/esm/contracts/supervisor/classifier-context.type.d.mts.map +1 -0
- package/esm/contracts/supervisor/dispatch-context.type.d.mts +235 -0
- package/esm/contracts/supervisor/dispatch-context.type.d.mts.map +1 -0
- package/esm/contracts/supervisor/evaluate-context.type.d.mts +124 -0
- package/esm/contracts/supervisor/evaluate-context.type.d.mts.map +1 -0
- package/esm/contracts/supervisor/index.d.mts +16 -0
- package/esm/contracts/supervisor/intent-entry.type.d.mts +254 -0
- package/esm/contracts/supervisor/intent-entry.type.d.mts.map +1 -0
- package/esm/contracts/supervisor/iteration-snapshot.type.d.mts +117 -0
- package/esm/contracts/supervisor/iteration-snapshot.type.d.mts.map +1 -0
- package/esm/contracts/supervisor/next.type.d.mts +25 -0
- package/esm/contracts/supervisor/next.type.d.mts.map +1 -0
- package/esm/contracts/supervisor/route-context.type.d.mts +91 -0
- package/esm/contracts/supervisor/route-context.type.d.mts.map +1 -0
- package/esm/contracts/supervisor/router-entry.type.d.mts +67 -0
- package/esm/contracts/supervisor/router-entry.type.d.mts.map +1 -0
- package/esm/contracts/supervisor/supervisor-config.type.d.mts +356 -0
- package/esm/contracts/supervisor/supervisor-config.type.d.mts.map +1 -0
- package/esm/contracts/supervisor/supervisor-execute-options.type.d.mts +90 -0
- package/esm/contracts/supervisor/supervisor-execute-options.type.d.mts.map +1 -0
- package/esm/contracts/supervisor/supervisor-input.type.d.mts +24 -0
- package/esm/contracts/supervisor/supervisor-input.type.d.mts.map +1 -0
- package/esm/contracts/supervisor/supervisor-snapshot.type.d.mts +49 -0
- package/esm/contracts/supervisor/supervisor-snapshot.type.d.mts.map +1 -0
- package/esm/contracts/supervisor/supervisor-stream-event.type.d.mts +16 -0
- package/esm/contracts/supervisor/supervisor-stream-event.type.d.mts.map +1 -0
- package/esm/contracts/supervisor/supervisor.contract.d.mts +126 -0
- package/esm/contracts/supervisor/supervisor.contract.d.mts.map +1 -0
- package/esm/contracts/system-prompt.contract.d.mts +118 -0
- package/esm/contracts/system-prompt.contract.d.mts.map +1 -0
- package/esm/contracts/tool.contract.d.mts +161 -0
- package/esm/contracts/tool.contract.d.mts.map +1 -0
- package/esm/contracts/workflow/index.d.mts +6 -0
- package/esm/contracts/workflow/next-step-result.type.d.mts +17 -0
- package/esm/contracts/workflow/next-step-result.type.d.mts.map +1 -0
- package/esm/contracts/workflow/retry-config.type.d.mts +19 -0
- package/esm/contracts/workflow/retry-config.type.d.mts.map +1 -0
- package/esm/contracts/workflow/step.contract.d.mts +189 -0
- package/esm/contracts/workflow/step.contract.d.mts.map +1 -0
- package/esm/contracts/workflow/workflow-context.type.d.mts +45 -0
- package/esm/contracts/workflow/workflow-context.type.d.mts.map +1 -0
- package/esm/contracts/workflow/workflow-snapshot.type.d.mts +24 -0
- package/esm/contracts/workflow/workflow-snapshot.type.d.mts.map +1 -0
- package/esm/contracts/workflow/workflow.contract.d.mts +142 -0
- package/esm/contracts/workflow/workflow.contract.d.mts.map +1 -0
- package/esm/errors/agent-cancelled-error.d.mts +49 -0
- package/esm/errors/agent-cancelled-error.d.mts.map +1 -0
- package/esm/errors/agent-cancelled-error.mjs +43 -0
- package/esm/errors/agent-cancelled-error.mjs.map +1 -0
- package/esm/errors/agent-execution-error.d.mts +32 -0
- package/esm/errors/agent-execution-error.d.mts.map +1 -0
- package/esm/errors/agent-execution-error.mjs +35 -0
- package/esm/errors/agent-execution-error.mjs.map +1 -0
- package/esm/errors/agent-max-trips-error.d.mts +45 -0
- package/esm/errors/agent-max-trips-error.d.mts.map +1 -0
- package/esm/errors/agent-max-trips-error.mjs +41 -0
- package/esm/errors/agent-max-trips-error.mjs.map +1 -0
- package/esm/errors/ai-error.d.mts +94 -0
- package/esm/errors/ai-error.d.mts.map +1 -0
- package/esm/errors/ai-error.mjs +68 -0
- package/esm/errors/ai-error.mjs.map +1 -0
- package/esm/errors/budget-exceeded-error.d.mts +41 -0
- package/esm/errors/budget-exceeded-error.d.mts.map +1 -0
- package/esm/errors/budget-exceeded-error.mjs +31 -0
- package/esm/errors/budget-exceeded-error.mjs.map +1 -0
- package/esm/errors/content-filter-error.d.mts +33 -0
- package/esm/errors/content-filter-error.d.mts.map +1 -0
- package/esm/errors/content-filter-error.mjs +28 -0
- package/esm/errors/content-filter-error.mjs.map +1 -0
- package/esm/errors/context-length-exceeded-error.d.mts +38 -0
- package/esm/errors/context-length-exceeded-error.d.mts.map +1 -0
- package/esm/errors/context-length-exceeded-error.mjs +31 -0
- package/esm/errors/context-length-exceeded-error.mjs.map +1 -0
- package/esm/errors/error-category.type.d.mts +30 -0
- package/esm/errors/error-category.type.d.mts.map +1 -0
- package/esm/errors/error-code.type.d.mts +19 -0
- package/esm/errors/error-code.type.d.mts.map +1 -0
- package/esm/errors/guardrail-violation-error.d.mts +55 -0
- package/esm/errors/guardrail-violation-error.d.mts.map +1 -0
- package/esm/errors/guardrail-violation-error.mjs +41 -0
- package/esm/errors/guardrail-violation-error.mjs.map +1 -0
- package/esm/errors/index.d.mts +29 -0
- package/esm/errors/index.mjs +29 -0
- package/esm/errors/invalid-request-error.d.mts +27 -0
- package/esm/errors/invalid-request-error.d.mts.map +1 -0
- package/esm/errors/invalid-request-error.mjs +31 -0
- package/esm/errors/invalid-request-error.mjs.map +1 -0
- package/esm/errors/max-iterations-error.d.mts +31 -0
- package/esm/errors/max-iterations-error.d.mts.map +1 -0
- package/esm/errors/max-iterations-error.mjs +32 -0
- package/esm/errors/max-iterations-error.mjs.map +1 -0
- package/esm/errors/max-steps-exceeded-error.d.mts +20 -0
- package/esm/errors/max-steps-exceeded-error.d.mts.map +1 -0
- package/esm/errors/max-steps-exceeded-error.mjs +21 -0
- package/esm/errors/max-steps-exceeded-error.mjs.map +1 -0
- package/esm/errors/provider-auth-error.d.mts +22 -0
- package/esm/errors/provider-auth-error.d.mts.map +1 -0
- package/esm/errors/provider-auth-error.mjs +26 -0
- package/esm/errors/provider-auth-error.mjs.map +1 -0
- package/esm/errors/provider-error.d.mts +38 -0
- package/esm/errors/provider-error.d.mts.map +1 -0
- package/esm/errors/provider-error.mjs +42 -0
- package/esm/errors/provider-error.mjs.map +1 -0
- package/esm/errors/provider-rate-limit-error.d.mts +34 -0
- package/esm/errors/provider-rate-limit-error.d.mts.map +1 -0
- package/esm/errors/provider-rate-limit-error.mjs +31 -0
- package/esm/errors/provider-rate-limit-error.mjs.map +1 -0
- package/esm/errors/provider-timeout-error.d.mts +22 -0
- package/esm/errors/provider-timeout-error.d.mts.map +1 -0
- package/esm/errors/provider-timeout-error.mjs +26 -0
- package/esm/errors/provider-timeout-error.mjs.map +1 -0
- package/esm/errors/quota-exceeded-error.d.mts +36 -0
- package/esm/errors/quota-exceeded-error.d.mts.map +1 -0
- package/esm/errors/quota-exceeded-error.mjs +40 -0
- package/esm/errors/quota-exceeded-error.mjs.map +1 -0
- package/esm/errors/routing-error.d.mts +23 -0
- package/esm/errors/routing-error.d.mts.map +1 -0
- package/esm/errors/routing-error.mjs +23 -0
- package/esm/errors/routing-error.mjs.map +1 -0
- package/esm/errors/schema-validation-error.d.mts +40 -0
- package/esm/errors/schema-validation-error.d.mts.map +1 -0
- package/esm/errors/schema-validation-error.mjs +37 -0
- package/esm/errors/schema-validation-error.mjs.map +1 -0
- package/esm/errors/step-failed-error.d.mts +20 -0
- package/esm/errors/step-failed-error.d.mts.map +1 -0
- package/esm/errors/step-failed-error.mjs +19 -0
- package/esm/errors/step-failed-error.mjs.map +1 -0
- package/esm/errors/supervisor-cancelled-error.d.mts +29 -0
- package/esm/errors/supervisor-cancelled-error.d.mts.map +1 -0
- package/esm/errors/supervisor-cancelled-error.mjs +29 -0
- package/esm/errors/supervisor-cancelled-error.mjs.map +1 -0
- package/esm/errors/supervisor-drift-error.d.mts +31 -0
- package/esm/errors/supervisor-drift-error.d.mts.map +1 -0
- package/esm/errors/supervisor-drift-error.mjs +30 -0
- package/esm/errors/supervisor-drift-error.mjs.map +1 -0
- package/esm/errors/supervisor-failed-error.d.mts +40 -0
- package/esm/errors/supervisor-failed-error.d.mts.map +1 -0
- package/esm/errors/supervisor-failed-error.mjs +43 -0
- package/esm/errors/supervisor-failed-error.mjs.map +1 -0
- package/esm/errors/supervisor-routing-error.d.mts +44 -0
- package/esm/errors/supervisor-routing-error.d.mts.map +1 -0
- package/esm/errors/supervisor-routing-error.mjs +39 -0
- package/esm/errors/supervisor-routing-error.mjs.map +1 -0
- package/esm/errors/tool-execution-error.d.mts +35 -0
- package/esm/errors/tool-execution-error.d.mts.map +1 -0
- package/esm/errors/tool-execution-error.mjs +32 -0
- package/esm/errors/tool-execution-error.mjs.map +1 -0
- package/esm/errors/workflow-cancelled-error.d.mts +23 -0
- package/esm/errors/workflow-cancelled-error.d.mts.map +1 -0
- package/esm/errors/workflow-cancelled-error.mjs +23 -0
- package/esm/errors/workflow-cancelled-error.mjs.map +1 -0
- package/esm/errors/workflow-drift-error.d.mts +25 -0
- package/esm/errors/workflow-drift-error.d.mts.map +1 -0
- package/esm/errors/workflow-drift-error.mjs +24 -0
- package/esm/errors/workflow-drift-error.mjs.map +1 -0
- package/esm/errors/workflow-error.d.mts +15 -0
- package/esm/errors/workflow-error.d.mts.map +1 -0
- package/esm/errors/workflow-error.mjs +18 -0
- package/esm/errors/workflow-error.mjs.map +1 -0
- package/esm/index.d.mts +137 -0
- package/esm/index.mjs +81 -0
- package/esm/middleware/builtins/budget.d.mts +103 -0
- package/esm/middleware/builtins/budget.d.mts.map +1 -0
- package/esm/middleware/builtins/budget.mjs +100 -0
- package/esm/middleware/builtins/budget.mjs.map +1 -0
- package/esm/middleware/builtins/guardrail.d.mts +92 -0
- package/esm/middleware/builtins/guardrail.d.mts.map +1 -0
- package/esm/middleware/builtins/guardrail.mjs +76 -0
- package/esm/middleware/builtins/guardrail.mjs.map +1 -0
- package/esm/middleware/builtins/semantic-cache.d.mts +106 -0
- package/esm/middleware/builtins/semantic-cache.d.mts.map +1 -0
- package/esm/middleware/builtins/semantic-cache.mjs +149 -0
- package/esm/middleware/builtins/semantic-cache.mjs.map +1 -0
- package/esm/middleware/helpers/compose.d.mts +42 -0
- package/esm/middleware/helpers/compose.d.mts.map +1 -0
- package/esm/middleware/helpers/compose.mjs +52 -0
- package/esm/middleware/helpers/compose.mjs.map +1 -0
- package/esm/middleware/helpers/for-tool.d.mts +55 -0
- package/esm/middleware/helpers/for-tool.d.mts.map +1 -0
- package/esm/middleware/helpers/for-tool.mjs +80 -0
- package/esm/middleware/helpers/for-tool.mjs.map +1 -0
- package/esm/middleware/helpers/index.d.mts +2 -0
- package/esm/middleware/index.d.mts +8 -0
- package/esm/middleware/index.mjs +10 -0
- package/esm/middleware/pipeline.d.mts +70 -0
- package/esm/middleware/pipeline.d.mts.map +1 -0
- package/esm/middleware/pipeline.mjs +100 -0
- package/esm/middleware/pipeline.mjs.map +1 -0
- package/esm/middleware/utils/extract-user-text.d.mts +33 -0
- package/esm/middleware/utils/extract-user-text.d.mts.map +1 -0
- package/esm/middleware/utils/extract-user-text.mjs +40 -0
- package/esm/middleware/utils/extract-user-text.mjs.map +1 -0
- package/esm/middleware/utils/index.d.mts +2 -0
- package/esm/middleware/utils/namespaced-state.d.mts +60 -0
- package/esm/middleware/utils/namespaced-state.d.mts.map +1 -0
- package/esm/middleware/utils/namespaced-state.mjs +60 -0
- package/esm/middleware/utils/namespaced-state.mjs.map +1 -0
- package/esm/mock/index.d.mts +4 -0
- package/esm/mock/index.mjs +5 -0
- package/esm/mock/mock-agent.d.mts +41 -0
- package/esm/mock/mock-agent.d.mts.map +1 -0
- package/esm/mock/mock-agent.mjs +39 -0
- package/esm/mock/mock-agent.mjs.map +1 -0
- package/esm/mock/mock-config.type.d.mts +31 -0
- package/esm/mock/mock-config.type.d.mts.map +1 -0
- package/esm/mock/mock-model.d.mts +94 -0
- package/esm/mock/mock-model.d.mts.map +1 -0
- package/esm/mock/mock-model.mjs +150 -0
- package/esm/mock/mock-model.mjs.map +1 -0
- package/esm/mock/mock-sdk.d.mts +25 -0
- package/esm/mock/mock-sdk.d.mts.map +1 -0
- package/esm/mock/mock-sdk.mjs +37 -0
- package/esm/mock/mock-sdk.mjs.map +1 -0
- package/esm/supervisor/as-tool.d.mts +45 -0
- package/esm/supervisor/as-tool.d.mts.map +1 -0
- package/esm/supervisor/as-tool.mjs +80 -0
- package/esm/supervisor/as-tool.mjs.map +1 -0
- package/esm/supervisor/cancellation.d.mts +12 -0
- package/esm/supervisor/cancellation.d.mts.map +1 -0
- package/esm/supervisor/cancellation.mjs +22 -0
- package/esm/supervisor/cancellation.mjs.map +1 -0
- package/esm/supervisor/decide.mjs +272 -0
- package/esm/supervisor/decide.mjs.map +1 -0
- package/esm/supervisor/emitter.d.mts +27 -0
- package/esm/supervisor/emitter.d.mts.map +1 -0
- package/esm/supervisor/emitter.mjs +47 -0
- package/esm/supervisor/emitter.mjs.map +1 -0
- package/esm/supervisor/entries.d.mts +141 -0
- package/esm/supervisor/entries.d.mts.map +1 -0
- package/esm/supervisor/entries.mjs +206 -0
- package/esm/supervisor/entries.mjs.map +1 -0
- package/esm/supervisor/execution.d.mts +637 -0
- package/esm/supervisor/execution.d.mts.map +1 -0
- package/esm/supervisor/execution.mjs +1868 -0
- package/esm/supervisor/execution.mjs.map +1 -0
- package/esm/supervisor/index.d.mts +11 -0
- package/esm/supervisor/index.mjs +12 -0
- package/esm/supervisor/router-prompt.d.mts +56 -0
- package/esm/supervisor/router-prompt.d.mts.map +1 -0
- package/esm/supervisor/router-prompt.mjs +52 -0
- package/esm/supervisor/router-prompt.mjs.map +1 -0
- package/esm/supervisor/signature.d.mts +28 -0
- package/esm/supervisor/signature.d.mts.map +1 -0
- package/esm/supervisor/signature.mjs +89 -0
- package/esm/supervisor/signature.mjs.map +1 -0
- package/esm/supervisor/snapshot.d.mts +54 -0
- package/esm/supervisor/snapshot.d.mts.map +1 -0
- package/esm/supervisor/snapshot.mjs +77 -0
- package/esm/supervisor/snapshot.mjs.map +1 -0
- package/esm/supervisor/supervisor-stream.d.mts +29 -0
- package/esm/supervisor/supervisor-stream.d.mts.map +1 -0
- package/esm/supervisor/supervisor-stream.mjs +89 -0
- package/esm/supervisor/supervisor-stream.mjs.map +1 -0
- package/esm/supervisor/supervisor.d.mts +27 -0
- package/esm/supervisor/supervisor.d.mts.map +1 -0
- package/esm/supervisor/supervisor.mjs +138 -0
- package/esm/supervisor/supervisor.mjs.map +1 -0
- package/esm/system-prompt/instruction.d.mts +52 -0
- package/esm/system-prompt/instruction.d.mts.map +1 -0
- package/esm/system-prompt/instruction.mjs +57 -0
- package/esm/system-prompt/instruction.mjs.map +1 -0
- package/esm/system-prompt/persona.d.mts +52 -0
- package/esm/system-prompt/persona.d.mts.map +1 -0
- package/esm/system-prompt/persona.mjs +57 -0
- package/esm/system-prompt/persona.mjs.map +1 -0
- package/esm/system-prompt/render-placeholders.d.mts +31 -0
- package/esm/system-prompt/render-placeholders.d.mts.map +1 -0
- package/esm/system-prompt/render-placeholders.mjs +58 -0
- package/esm/system-prompt/render-placeholders.mjs.map +1 -0
- package/esm/system-prompt/system-prompt.d.mts +117 -0
- package/esm/system-prompt/system-prompt.d.mts.map +1 -0
- package/esm/system-prompt/system-prompt.mjs +137 -0
- package/esm/system-prompt/system-prompt.mjs.map +1 -0
- package/esm/tool/index.d.mts +1 -0
- package/esm/tool/index.mjs +3 -0
- package/esm/tool/tool.d.mts +64 -0
- package/esm/tool/tool.d.mts.map +1 -0
- package/esm/tool/tool.mjs +184 -0
- package/esm/tool/tool.mjs.map +1 -0
- package/esm/utils/compute-cost.d.mts +58 -0
- package/esm/utils/compute-cost.d.mts.map +1 -0
- package/esm/utils/compute-cost.mjs +87 -0
- package/esm/utils/compute-cost.mjs.map +1 -0
- package/esm/utils/extract-json-payload.d.mts +33 -0
- package/esm/utils/extract-json-payload.d.mts.map +1 -0
- package/esm/utils/extract-json-payload.mjs +39 -0
- package/esm/utils/extract-json-payload.mjs.map +1 -0
- package/esm/utils/generate-run-id.d.mts +20 -0
- package/esm/utils/generate-run-id.d.mts.map +1 -0
- package/esm/utils/generate-run-id.mjs +23 -0
- package/esm/utils/generate-run-id.mjs.map +1 -0
- package/esm/utils/index.d.mts +9 -0
- package/esm/utils/index.mjs +11 -0
- package/esm/utils/json-schema.d.mts +57 -0
- package/esm/utils/json-schema.d.mts.map +1 -0
- package/esm/utils/json-schema.mjs +89 -0
- package/esm/utils/json-schema.mjs.map +1 -0
- package/esm/utils/prepare-attachment-part.d.mts +36 -0
- package/esm/utils/prepare-attachment-part.d.mts.map +1 -0
- package/esm/utils/prepare-attachment-part.mjs +140 -0
- package/esm/utils/prepare-attachment-part.mjs.map +1 -0
- package/esm/utils/resolve-attachment.d.mts +33 -0
- package/esm/utils/resolve-attachment.d.mts.map +1 -0
- package/esm/utils/resolve-attachment.mjs +73 -0
- package/esm/utils/resolve-attachment.mjs.map +1 -0
- package/esm/utils/safe-json-parse.d.mts +14 -0
- package/esm/utils/safe-json-parse.d.mts.map +1 -0
- package/esm/utils/safe-json-parse.mjs +22 -0
- package/esm/utils/safe-json-parse.mjs.map +1 -0
- package/esm/utils/stamp-report-lineage.d.mts +61 -0
- package/esm/utils/stamp-report-lineage.d.mts.map +1 -0
- package/esm/utils/stamp-report-lineage.mjs +47 -0
- package/esm/utils/stamp-report-lineage.mjs.map +1 -0
- package/esm/utils/token-count.d.mts +15 -0
- package/esm/utils/token-count.d.mts.map +1 -0
- package/esm/utils/token-count.mjs +18 -0
- package/esm/utils/token-count.mjs.map +1 -0
- package/esm/workflow/as-tool.mjs +55 -0
- package/esm/workflow/as-tool.mjs.map +1 -0
- package/esm/workflow/cancellation.mjs +44 -0
- package/esm/workflow/cancellation.mjs.map +1 -0
- package/esm/workflow/emitter.mjs +40 -0
- package/esm/workflow/emitter.mjs.map +1 -0
- package/esm/workflow/engine.mjs +362 -0
- package/esm/workflow/engine.mjs.map +1 -0
- package/esm/workflow/index.d.mts +3 -0
- package/esm/workflow/index.mjs +5 -0
- package/esm/workflow/retry.mjs +32 -0
- package/esm/workflow/retry.mjs.map +1 -0
- package/esm/workflow/router.mjs +56 -0
- package/esm/workflow/router.mjs.map +1 -0
- package/esm/workflow/run-scoped-emitter.mjs +32 -0
- package/esm/workflow/run-scoped-emitter.mjs.map +1 -0
- package/esm/workflow/signature.d.mts +7 -0
- package/esm/workflow/signature.d.mts.map +1 -0
- package/esm/workflow/signature.mjs +34 -0
- package/esm/workflow/signature.mjs.map +1 -0
- package/esm/workflow/snapshot.mjs +71 -0
- package/esm/workflow/snapshot.mjs.map +1 -0
- package/esm/workflow/state.mjs +37 -0
- package/esm/workflow/state.mjs.map +1 -0
- package/esm/workflow/step-runner.mjs +371 -0
- package/esm/workflow/step-runner.mjs.map +1 -0
- package/esm/workflow/step.d.mts +19 -0
- package/esm/workflow/step.d.mts.map +1 -0
- package/esm/workflow/step.mjs +37 -0
- package/esm/workflow/step.mjs.map +1 -0
- package/esm/workflow/workflow.d.mts +12 -0
- package/esm/workflow/workflow.d.mts.map +1 -0
- package/esm/workflow/workflow.mjs +116 -0
- package/esm/workflow/workflow.mjs.map +1 -0
- package/llms-full.txt +2293 -0
- package/llms.txt +20 -0
- package/package.json +37 -0
- package/skills/README.md +53 -0
- package/skills/ai-basics/SKILL.md +95 -0
- package/skills/attach-ai-middleware/SKILL.md +184 -0
- package/skills/define-ai-tool/SKILL.md +186 -0
- package/skills/embed-text/SKILL.md +105 -0
- package/skills/handle-ai-errors/SKILL.md +194 -0
- package/skills/log-ai-calls/SKILL.md +141 -0
- package/skills/persist-ai-data/SKILL.md +207 -0
- package/skills/pick-ai-provider/SKILL.md +164 -0
- package/skills/run-ai-agent/SKILL.md +267 -0
- package/skills/run-ai-workflow/SKILL.md +258 -0
- package/skills/run-supervisor/SKILL.md +309 -0
- package/skills/write-system-prompt/SKILL.md +129 -0
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pick-ai-provider
|
|
3
|
+
description: 'Choose an AI provider adapter — @warlock.js/ai-openai (shipped, also handles OpenRouter / Azure via baseURL), @warlock.js/ai-anthropic, @warlock.js/ai-bedrock, @warlock.js/ai-google, @warlock.js/ai-ollama. Triggers: `OpenAISDK`, `SDKAdapterContract`, `ModelContract`, `sdk.model`, `sdk.embedder`, `capabilities.vision`, `capabilities.structuredOutput`, `pricing`, `baseURL`, `provider: "openrouter"`; ''pick a provider'', ''openai vs openrouter'', ''does this model support vision'', ''configure pricing''; typical import `import { OpenAISDK } from "@warlock.js/ai-openai"`. Skip: agent factory — `@warlock.js/ai/run-ai-agent/SKILL.md`; competing libs raw `openai`, `@anthropic-ai/sdk`, `@aws-sdk/client-bedrock-runtime`.'
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Pick an AI provider adapter
|
|
7
|
+
|
|
8
|
+
`@warlock.js/ai` is provider-agnostic. Concrete adapters live in sibling packages and follow the same `SDKAdapterContract`. Pick by which provider(s) your app talks to and which capabilities the model needs.
|
|
9
|
+
|
|
10
|
+
## Available adapters
|
|
11
|
+
|
|
12
|
+
| Package | Status | Notes |
|
|
13
|
+
| --- | --- | --- |
|
|
14
|
+
| `@warlock.js/ai-openai` | ✅ Shipped | OpenAI + any OpenAI-compatible gateway (OpenRouter, Together.ai, etc.) |
|
|
15
|
+
| `@warlock.js/ai-anthropic` | ✅ Shipped | Native Claude API (Opus / Sonnet / Haiku) |
|
|
16
|
+
| `@warlock.js/ai-bedrock` | ✅ Shipped | AWS Bedrock — Converse API + Titan embeddings |
|
|
17
|
+
| `@warlock.js/ai-google` | ✅ Shipped | Gemini direct via `@google/genai`, native batch embeddings |
|
|
18
|
+
| `@warlock.js/ai-ollama` | ✅ Shipped | Local models via the official `ollama` client |
|
|
19
|
+
|
|
20
|
+
All five first-party adapters share the same `SDKAdapterContract`, so switching providers is a one-line change at the model construction site. `ai-openrouter` is intentionally deferred — use `ai-openai` with a `baseURL` pointed at OpenRouter.
|
|
21
|
+
|
|
22
|
+
## Decision tree
|
|
23
|
+
|
|
24
|
+
- **Default first choice:** `@warlock.js/ai-openai` direct to OpenAI. Best support, predictable behavior, native structured-output, native vision on `gpt-4o*`, embeddings, streaming.
|
|
25
|
+
- **Need many models / cost arbitrage:** `@warlock.js/ai-openai` against OpenRouter. Same code, different `baseURL` + `provider: "openrouter"` on the SDK.
|
|
26
|
+
- **Need native Claude features:** `@warlock.js/ai-anthropic` — Opus / Sonnet / Haiku via the native Messages API.
|
|
27
|
+
- **Need local / self-hosted models:** `@warlock.js/ai-ollama`, or a local OpenAI-compatible gateway via `ai-openai`.
|
|
28
|
+
- **Need AWS Bedrock pricing / compliance:** `@warlock.js/ai-bedrock` — Converse API + Titan embeddings.
|
|
29
|
+
- **Need Gemini:** `@warlock.js/ai-google` — Gemini direct via `@google/genai`.
|
|
30
|
+
|
|
31
|
+
## The adapter contract
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
interface SDKAdapterContract {
|
|
35
|
+
model(config): ModelContract; // chat completions / tool calls / structured output
|
|
36
|
+
count(text, model?): Promise<number>; // token counting
|
|
37
|
+
embedder?(config): EmbedderContract; // optional — not every provider supports embeddings
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Adapters are classes — `new OpenAISDK({ apiKey })`, `new AnthropicSDK({ apiKey })`. They expose:
|
|
42
|
+
|
|
43
|
+
- `model({ name, ...options })` — returns a `ModelContract`. The provider label lives on the returned `ModelContract.provider` (`"openai"`, `"openrouter"`, …), not on the SDK.
|
|
44
|
+
- `count(text, model?)` — provider-appropriate token count.
|
|
45
|
+
- `embedder({ name })` — text-to-vector. Optional; check `typeof sdk.embedder === "function"` before calling.
|
|
46
|
+
|
|
47
|
+
The `ModelContract.capabilities` field declares what the model supports — two flags today, both optional (absent = treat as `false`):
|
|
48
|
+
|
|
49
|
+
```ts
|
|
50
|
+
type ModelCapabilities = {
|
|
51
|
+
structuredOutput?: boolean; // native response_format: json_schema support?
|
|
52
|
+
vision?: boolean; // can accept image attachments?
|
|
53
|
+
};
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
The framework reads `capabilities` to fail loud upfront — e.g. passing `attachments: [...]` to a non-vision model throws at the boundary instead of failing mid-trip.
|
|
57
|
+
|
|
58
|
+
## OpenAI adapter — usage
|
|
59
|
+
|
|
60
|
+
```ts
|
|
61
|
+
import { OpenAISDK } from "@warlock.js/ai-openai";
|
|
62
|
+
|
|
63
|
+
// Direct OpenAI
|
|
64
|
+
const openai = new OpenAISDK({
|
|
65
|
+
apiKey: process.env.OPENAI_API_KEY!,
|
|
66
|
+
pricing: {
|
|
67
|
+
"gpt-4o-mini": { input: 0.15, output: 0.6, cachedInput: 0.075 },
|
|
68
|
+
"gpt-4o": { input: 5.0, output: 15.0 },
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
const agent = ai.agent({ model: openai.model({ name: "gpt-4o-mini" }) });
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Via OpenRouter (cost arbitrage, many providers)
|
|
76
|
+
|
|
77
|
+
```ts
|
|
78
|
+
const openrouter = new OpenAISDK({
|
|
79
|
+
apiKey: process.env.OPENROUTER_API_KEY!,
|
|
80
|
+
baseURL: "https://openrouter.ai/api/v1",
|
|
81
|
+
provider: "openrouter", // labels reports correctly
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
const agent = ai.agent({ model: openrouter.model({ name: "anthropic/claude-3.5-sonnet" }) });
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Same `OpenAISDK` class, different `baseURL`. Reports label the provider via the `provider` field for downstream metrics.
|
|
88
|
+
|
|
89
|
+
### Per-model overrides
|
|
90
|
+
|
|
91
|
+
```ts
|
|
92
|
+
const openai = new OpenAISDK({ apiKey });
|
|
93
|
+
|
|
94
|
+
// Override capabilities for a custom or fine-tuned model
|
|
95
|
+
const customModel = openai.model({
|
|
96
|
+
name: "my-org/custom-gpt-4-finetuned",
|
|
97
|
+
vision: true, // override capabilities.vision
|
|
98
|
+
structuredOutput: true,
|
|
99
|
+
pricing: { input: 1.0, output: 3.0 }, // per-model pricing (wins over SDK registry)
|
|
100
|
+
});
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Pricing — per-channel cost breakdown
|
|
104
|
+
|
|
105
|
+
Configure `pricing` on the model (or via the SDK registry) and every report carries `Usage.cost`:
|
|
106
|
+
|
|
107
|
+
```ts
|
|
108
|
+
const openai = new OpenAISDK({
|
|
109
|
+
apiKey,
|
|
110
|
+
pricing: { "gpt-4o-mini": { input: 0.15, output: 0.6, cachedInput: 0.075 } },
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
const { usage } = await ai.agent({ model: openai.model({ name: "gpt-4o-mini" }) }).execute("hi");
|
|
114
|
+
|
|
115
|
+
usage.cost;
|
|
116
|
+
// { input: 0.0000045, output: 0.000192, cachedInput: 0.000009 } — USD breakdown
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Shape mirrors `ModelPricing` — `{ input, output, cachedInput?, cachedOutput? }`. Per-model `pricing` wins over the SDK-level registry. `undefined` when no pricing configured — honest absence over false zero.
|
|
120
|
+
|
|
121
|
+
## Embeddings
|
|
122
|
+
|
|
123
|
+
OpenAI ships the first embedder:
|
|
124
|
+
|
|
125
|
+
```ts
|
|
126
|
+
const embedder = openai.embedder({ name: "text-embedding-3-small" });
|
|
127
|
+
const { vector } = await embedder.embed("Hello, world.");
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
See [`@warlock.js/ai/embed-text/SKILL.md`](@warlock.js/ai/embed-text/SKILL.md).
|
|
131
|
+
|
|
132
|
+
## Multi-provider apps
|
|
133
|
+
|
|
134
|
+
Pattern: one SDK instance per provider, mix at the call site:
|
|
135
|
+
|
|
136
|
+
```ts
|
|
137
|
+
const openai = new OpenAISDK({ apiKey: process.env.OPENAI_API_KEY! });
|
|
138
|
+
const openrouter = new OpenAISDK({
|
|
139
|
+
apiKey: process.env.OPENROUTER_API_KEY!,
|
|
140
|
+
baseURL: "https://openrouter.ai/api/v1",
|
|
141
|
+
provider: "openrouter",
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
const fastAgent = ai.agent({ model: openai.model({ name: "gpt-4o-mini" }) });
|
|
145
|
+
const claudeAgent = ai.agent({ model: openrouter.model({ name: "anthropic/claude-3.5-sonnet" }) });
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Reports label per-agent provider correctly. Pricing applies per SDK instance.
|
|
149
|
+
|
|
150
|
+
## When the adapter changes
|
|
151
|
+
|
|
152
|
+
If you switch providers mid-project (e.g. OpenAI → Anthropic):
|
|
153
|
+
|
|
154
|
+
1. The agent factory call signature stays the same — `ai.agent({ model: <newSdk>.model({...}) })`.
|
|
155
|
+
2. Capabilities matter — if the new model doesn't support `structuredOutput` natively, fall back to the soft "respond in JSON only" instruction (framework handles it).
|
|
156
|
+
3. Errors stay typed — `ProviderAuthError`, `ContextLengthExceededError`, etc. are adapter-agnostic.
|
|
157
|
+
4. Pricing matrix needs updating per the new provider's rates.
|
|
158
|
+
|
|
159
|
+
## See also
|
|
160
|
+
|
|
161
|
+
- [`@warlock.js/ai-openai/setup-openai/SKILL.md`](@warlock.js/ai-openai/setup-openai/SKILL.md) — full OpenAI adapter docs
|
|
162
|
+
- [`@warlock.js/ai/run-ai-agent/SKILL.md`](@warlock.js/ai/run-ai-agent/SKILL.md) — model passed into `ai.agent({...})`
|
|
163
|
+
- [`@warlock.js/ai/embed-text/SKILL.md`](@warlock.js/ai/embed-text/SKILL.md) — embedder primitive on the SDK
|
|
164
|
+
- [`@warlock.js/ai/handle-ai-errors/SKILL.md`](@warlock.js/ai/handle-ai-errors/SKILL.md) — adapter error categorization
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: run-ai-agent
|
|
3
|
+
description: 'Build agents with ai.agent({...}) — the single-LLM-turn primitive. Covers execute / stream, attachments, structured output, placeholders, events. Triggers: `ai.agent`, `agent.execute`, `agent.stream`, `AgentResult`, `AgentReport`, `streamingToolGuard`, `attachments`, `repair`, `maxTrips`, `sessionId`; ''run an agent'', ''stream an agent response'', ''structured output schema'', ''pass image to agent'', ''cancel an agent run''; typical import `import { ai } from "@warlock.js/ai"`. Skip: tool definition — `@warlock.js/ai/define-ai-tool/SKILL.md`; workflows — `@warlock.js/ai/run-ai-workflow/SKILL.md`; competing libs `langchain`, `ai` (Vercel), raw `openai`.'
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# `ai.agent()` — single-turn primitive
|
|
7
|
+
|
|
8
|
+
The lowest rung of the 4-primitive ladder. One LLM call, optional tool loop, optional structured output. Stateless across calls.
|
|
9
|
+
|
|
10
|
+
## Factory shape
|
|
11
|
+
|
|
12
|
+
```ts
|
|
13
|
+
import { ai } from "@warlock.js/ai";
|
|
14
|
+
import { OpenAISDK } from "@warlock.js/ai-openai";
|
|
15
|
+
|
|
16
|
+
const openai = new OpenAISDK({ apiKey: process.env.OPENAI_API_KEY! });
|
|
17
|
+
|
|
18
|
+
ai.agent({
|
|
19
|
+
name?: string, // optional — anonymous gets a fingerprint
|
|
20
|
+
model: openai.model({ name: "gpt-4o-mini" }),
|
|
21
|
+
systemPrompt?: string | SystemPromptContract,
|
|
22
|
+
tools?: ToolContract<any, any>[],
|
|
23
|
+
placeholders?: Record<string, unknown>,
|
|
24
|
+
maxTrips?: number, // default 10
|
|
25
|
+
modelOptions?: ModelCallOptions,
|
|
26
|
+
output?: StandardSchemaV1<T>, // default structured-output schema
|
|
27
|
+
middleware?: AgentMiddleware[],
|
|
28
|
+
streamingToolGuard?: StreamingToolGuardConfig, // opt-in tool-call recovery from text leaks
|
|
29
|
+
on?: AgentEventHandlers,
|
|
30
|
+
version?: string, // mirrored onto reports for trip archives
|
|
31
|
+
});
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
The factory returns an `AgentContract<TOutput>`. Every execution spawns a fresh internal `Execution` — the factory holds no per-call state.
|
|
35
|
+
|
|
36
|
+
## Anonymous agents
|
|
37
|
+
|
|
38
|
+
`name` is optional. Anonymous agents receive a deterministic fingerprint:
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
anon_<provider>_<model>[_<tool1>+<tool2>+...]
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Same config across process restarts → same synthetic name. Keeps workflow signature drift detection honest when you compose anonymous agents into a workflow.
|
|
45
|
+
|
|
46
|
+
## Execute surface
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
agent.execute(input: string, options?: AgentExecuteOptions): Promise<AgentResult<T>>;
|
|
50
|
+
agent.stream(input: string, options?: AgentExecuteOptions): StreamContract<AgentResult<T>>;
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
`AgentExecuteOptions` — every field optional:
|
|
54
|
+
|
|
55
|
+
```ts
|
|
56
|
+
{
|
|
57
|
+
history?: Message[];
|
|
58
|
+
attachments?: Attachment[]; // images today; PDFs later
|
|
59
|
+
placeholders?: Record<string, unknown>;
|
|
60
|
+
output?: StandardSchemaV1<T>; // typed structured output → result.data
|
|
61
|
+
responseSchema?: Record<string, unknown>; // hand-crafted JSON Schema escape hatch
|
|
62
|
+
systemPrompt?: SystemPromptContract; // per-call override
|
|
63
|
+
repair?: { maxAttempts?: number }; // opt-in re-ask on validation failure
|
|
64
|
+
signal?: AbortSignal; // cancellation
|
|
65
|
+
sessionId?: string; // stitch many runs into one session
|
|
66
|
+
streamingToolGuard?: StreamingToolGuardConfig;
|
|
67
|
+
on?: AgentEventHandlers;
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## `streamingToolGuard` — recover tool calls leaked as text
|
|
72
|
+
|
|
73
|
+
Cheap and fast models occasionally emit a registered tool's structured input as **literal text in the content stream** instead of as a real `tool_call`. Without intervention, customers watch raw JSON build character-by-character.
|
|
74
|
+
|
|
75
|
+
```ts
|
|
76
|
+
ai.agent({
|
|
77
|
+
model: someFastModel,
|
|
78
|
+
tools: [suggestFollowupsTool, searchCatalogTool],
|
|
79
|
+
streamingToolGuard: {}, // empty object = on with defaults
|
|
80
|
+
});
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Recovery conditions: the buffered JSON must (a) parse cleanly, (b) carry a `name` or `tool` key resolving to a registered tool, AND (c) carry an `arguments` or `input` key whose value validates against that tool's input schema. Anything else flushes back as text — the guard never invents calls.
|
|
84
|
+
|
|
85
|
+
**Off by default.** Set this explicitly on agents whose registered tools have been observed to leak.
|
|
86
|
+
|
|
87
|
+
## `sessionId` — stitch many runs into one user session
|
|
88
|
+
|
|
89
|
+
```ts
|
|
90
|
+
const sessionId = "sess_user_42_2026-05-12";
|
|
91
|
+
await agent.execute("what's my order?", { sessionId });
|
|
92
|
+
await agent.execute("cancel it", { sessionId }); // 30 seconds later, same session
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
The framework stamps it onto every report node this run produces. Cost dashboards can group by `sessionId` without joining the report tree.
|
|
96
|
+
|
|
97
|
+
## Result shape — `AgentResult<T>`
|
|
98
|
+
|
|
99
|
+
```ts
|
|
100
|
+
type AgentResult<T> = {
|
|
101
|
+
type: "agent";
|
|
102
|
+
data?: T; // structured output when `output` schema was supplied
|
|
103
|
+
text?: string; // raw final LLM text
|
|
104
|
+
report: AgentReport; // trips, toolCalls, status, timing
|
|
105
|
+
usage: Usage; // aggregated token usage + cost breakdown
|
|
106
|
+
error?: AIError;
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
type AgentReport = {
|
|
110
|
+
runId: string;
|
|
111
|
+
rootRunId: string;
|
|
112
|
+
name: string;
|
|
113
|
+
status: "completed" | "failed" | "cancelled";
|
|
114
|
+
startedAt: string;
|
|
115
|
+
endedAt: string;
|
|
116
|
+
duration: number;
|
|
117
|
+
model: { name: string; provider: string };
|
|
118
|
+
trips: LLMTrip[];
|
|
119
|
+
children: ToolCall[]; // tool dispatches — filter by `c.type === "tool"`
|
|
120
|
+
};
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Tool calls are NOT a separate `report.toolCalls` field — every tool dispatch is a child `BaseReport` node (`type: "tool"`) on `report.children`. Filter the tree to isolate them:
|
|
124
|
+
|
|
125
|
+
```ts
|
|
126
|
+
const toolCalls = report.children.filter((c) => c.type === "tool");
|
|
127
|
+
const nestedAgents = report.children.filter((c) => c.type === "agent");
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Canonical destructuring:
|
|
131
|
+
|
|
132
|
+
```ts
|
|
133
|
+
const { data, text, report, usage, error } = await agent.execute(input);
|
|
134
|
+
|
|
135
|
+
if (error) {
|
|
136
|
+
logger.warn(error.code, { duration: report.duration, trips: report.trips.length });
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## Pattern — structured output
|
|
142
|
+
|
|
143
|
+
```ts
|
|
144
|
+
import { v, type Infer } from "@warlock.js/seal";
|
|
145
|
+
|
|
146
|
+
const summarySchema = v.object({
|
|
147
|
+
summary: v.string(),
|
|
148
|
+
keyPoints: v.array(v.string()).min(1),
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
const result = await myAgent.execute(input, { output: summarySchema });
|
|
152
|
+
|
|
153
|
+
if (result.data) {
|
|
154
|
+
// typed as Infer<typeof summarySchema>
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Adapters with `capabilities.structuredOutput: true` forward the schema natively. Adapters without it get a soft "respond in JSON only" instruction. Client-side validation always runs.
|
|
159
|
+
|
|
160
|
+
## Pattern — output baked into the agent
|
|
161
|
+
|
|
162
|
+
```ts
|
|
163
|
+
const titleAgent = ai.agent({
|
|
164
|
+
model: openai.model({ name: "gpt-4o-mini" }),
|
|
165
|
+
output: titleSchema, // typed end-to-end via AgentContract<Infer<typeof titleSchema>>
|
|
166
|
+
systemPrompt: "...",
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
const result = await titleAgent.execute(currentMessage, { history });
|
|
170
|
+
// ^? AgentResult<{ title?: string }>
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Call-site `options.output` fully **replaces** `config.output` for that run — no merging.
|
|
174
|
+
|
|
175
|
+
## Pattern — repair on validation failure
|
|
176
|
+
|
|
177
|
+
```ts
|
|
178
|
+
await myAgent.execute(input, {
|
|
179
|
+
output: schema,
|
|
180
|
+
repair: { maxAttempts: 1 }, // re-ask once on parse/validation failure
|
|
181
|
+
});
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
Disabled by default. Each repair attempt counts against `maxTrips`.
|
|
185
|
+
|
|
186
|
+
## Pattern — image attachments
|
|
187
|
+
|
|
188
|
+
```ts
|
|
189
|
+
await myAgent.execute("What's in this?", {
|
|
190
|
+
attachments: ["./photo.png", "https://cdn.example.com/cat.jpg"],
|
|
191
|
+
});
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
Shorthand strings infer the image kind from extension. Tagged form for explicit control:
|
|
195
|
+
|
|
196
|
+
```ts
|
|
197
|
+
attachments: [
|
|
198
|
+
{ type: "image", source: "./photo" },
|
|
199
|
+
{ type: "image", source: { base64: "...", mediaType: "image/png" } },
|
|
200
|
+
];
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
Model must declare `capabilities.vision`. OpenAI adapter auto-infers from name; override with `openai.model({ name, vision: true })`.
|
|
204
|
+
|
|
205
|
+
## Pattern — streaming
|
|
206
|
+
|
|
207
|
+
```ts
|
|
208
|
+
const stream = myAgent.stream(input);
|
|
209
|
+
|
|
210
|
+
for await (const event of stream) {
|
|
211
|
+
if (event.type === "agent.trip.streaming") {
|
|
212
|
+
process.stdout.write(event.delta);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
const result = await stream.result;
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
Or use `.on({ "agent.trip.streaming": ..., "agent.completed": ..., "agent.error": ... })` alongside iteration.
|
|
220
|
+
|
|
221
|
+
## Pattern — cancellation
|
|
222
|
+
|
|
223
|
+
```ts
|
|
224
|
+
const ctrl = new AbortController();
|
|
225
|
+
const resultPromise = myAgent.execute(input, { signal: ctrl.signal });
|
|
226
|
+
|
|
227
|
+
setTimeout(() => ctrl.abort("too slow"), 30_000);
|
|
228
|
+
|
|
229
|
+
const { error, report } = await resultPromise;
|
|
230
|
+
if (report.status === "cancelled") {
|
|
231
|
+
// error is an AgentCancelledError (code "AGENT_CANCELLED",
|
|
232
|
+
// category "cancelled") carrying `cancelledAt` + `reason`
|
|
233
|
+
}
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
Between-trip abort is guaranteed. Mid-trip best-effort.
|
|
237
|
+
|
|
238
|
+
## Events — dot-notation + 3-tier subscription
|
|
239
|
+
|
|
240
|
+
- `agent.starting`, `agent.trip.started`, `agent.trip.streaming`, `agent.trip.completed`
|
|
241
|
+
- `agent.tool.calling`, `agent.tool.called`, `agent.tool.failed`
|
|
242
|
+
- `agent.completed`, `agent.error`
|
|
243
|
+
|
|
244
|
+
Three subscription tiers — fire in order **factory → instance → per-call**:
|
|
245
|
+
|
|
246
|
+
```ts
|
|
247
|
+
ai.agent({ model, on: { "agent.starting": () => metrics.inc("agent.runs") } });
|
|
248
|
+
|
|
249
|
+
const unsubscribe = myAgent.on("agent.error", ({ error }) => logger.error(error));
|
|
250
|
+
|
|
251
|
+
await myAgent.execute("go", {
|
|
252
|
+
on: { "agent.trip.completed": ({ trip }) => console.log(trip.duration) },
|
|
253
|
+
});
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
Every event payload carries `runId` and `rootRunId`. Same identity fields ride on stream events.
|
|
257
|
+
|
|
258
|
+
## When NOT to use this primitive
|
|
259
|
+
|
|
260
|
+
- Multi-step pipeline with a fixed shape → [`@warlock.js/ai/run-ai-workflow/SKILL.md`](@warlock.js/ai/run-ai-workflow/SKILL.md)
|
|
261
|
+
- Multi-agent routing with iteration → [`@warlock.js/ai/run-supervisor/SKILL.md`](@warlock.js/ai/run-supervisor/SKILL.md)
|
|
262
|
+
|
|
263
|
+
## See also
|
|
264
|
+
|
|
265
|
+
- [`@warlock.js/ai/define-ai-tool/SKILL.md`](@warlock.js/ai/define-ai-tool/SKILL.md) — tool wiring + schema validation
|
|
266
|
+
- [`@warlock.js/ai/write-system-prompt/SKILL.md`](@warlock.js/ai/write-system-prompt/SKILL.md) — persona / instruction builders
|
|
267
|
+
- [`@warlock.js/ai/handle-ai-errors/SKILL.md`](@warlock.js/ai/handle-ai-errors/SKILL.md) — `AIError` hierarchy
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: run-ai-workflow
|
|
3
|
+
description: 'Build durable resumable pipelines with ai.workflow({...}) + ai.step({...}) — lifecycle (skip / before / run|agent|parallel / output / after / nextStep), retry, parallel groups, snapshot resume. Triggers: `ai.workflow`, `ai.step`, `wf.execute`, `wf.resume`, `WorkflowContext`, `WorkflowResult`, `StepSnapshot`, `nextStep`, `onFailure`, `WorkflowDriftError`; ''build a workflow'', ''define a step'', ''resume after crash'', ''parallel steps'', ''retry with backoff''; typical import `import { ai } from "@warlock.js/ai"`. Skip: agent — `@warlock.js/ai/run-ai-agent/SKILL.md`; supervisor — `@warlock.js/ai/run-supervisor/SKILL.md`; competing libs `temporal`, `inngest`, `bullmq`.'
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# `ai.workflow()` — static, deterministic pipelines
|
|
7
|
+
|
|
8
|
+
Second rung of the 4-primitive ladder. A named, ordered set of steps with a stable signature. Each step is exactly one of: an agent call (`agent`), a `run` function, or a parallel group (`parallel`). Compose another workflow in by wrapping it with `workflow.asTool()` and calling it from a `run` step. Durable (resumable via any `CacheDriver` from `@warlock.js/cache`), observable, cancellable.
|
|
9
|
+
|
|
10
|
+
## When NOT to use a workflow
|
|
11
|
+
|
|
12
|
+
- Unknown shape at author time → wait for `ai.planner()` (v3)
|
|
13
|
+
- Quality-loop until goal met → [`@warlock.js/ai/run-supervisor/SKILL.md`](@warlock.js/ai/run-supervisor/SKILL.md)
|
|
14
|
+
- Multi-turn conversation with persistent session → orchestrator (v2)
|
|
15
|
+
- Iterate a runtime list of items → `ai.batch()` utility wrapping a workflow
|
|
16
|
+
|
|
17
|
+
## Minimal shape
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
import { ai } from "@warlock.js/ai";
|
|
21
|
+
import { MemoryCacheDriver } from "@warlock.js/cache";
|
|
22
|
+
import { v } from "@warlock.js/seal";
|
|
23
|
+
|
|
24
|
+
ai.config({ defaultStore: new MemoryCacheDriver() });
|
|
25
|
+
|
|
26
|
+
type CatalogInput = { url: string };
|
|
27
|
+
type CatalogOutput = { id: string };
|
|
28
|
+
type CatalogState = { html?: string; catalogId?: string };
|
|
29
|
+
|
|
30
|
+
const wf = ai.workflow<CatalogInput, CatalogOutput, CatalogState>({
|
|
31
|
+
name: "catalog-item",
|
|
32
|
+
output: {
|
|
33
|
+
extract: (ctx) => ({ id: ctx.state.catalogId ?? "" }),
|
|
34
|
+
schema: v.object({ id: v.string() }),
|
|
35
|
+
},
|
|
36
|
+
steps: [
|
|
37
|
+
ai.step<CatalogInput, CatalogState>({
|
|
38
|
+
name: "fetch",
|
|
39
|
+
run: async (ctx) => {
|
|
40
|
+
ctx.state.html = await fetch(ctx.input.url).then(r => r.text());
|
|
41
|
+
},
|
|
42
|
+
}),
|
|
43
|
+
ai.step<CatalogInput, CatalogState>({
|
|
44
|
+
name: "extract",
|
|
45
|
+
agent: extractorAgent,
|
|
46
|
+
input: (ctx) => ({ prompt: `Extract from: ${ctx.state.html}` }),
|
|
47
|
+
output: {
|
|
48
|
+
extract: (ctx) => ctx.agentResult?.data,
|
|
49
|
+
schema: itemSchema,
|
|
50
|
+
},
|
|
51
|
+
retry: { attempts: 3, backoff: "exponential" },
|
|
52
|
+
}),
|
|
53
|
+
],
|
|
54
|
+
});
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Generics
|
|
58
|
+
|
|
59
|
+
```ts
|
|
60
|
+
ai.workflow<TInput, TOutput, TState, TContext>(...)
|
|
61
|
+
ai.step<TInput, TState, TContext>(...)
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Order: Input/Output describe the public contract, State before Context because step bodies touch state more often. Defaults (`unknown`, `Record<string, unknown>`) let partial typing work.
|
|
65
|
+
|
|
66
|
+
## Execute — two interchangeable shapes
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
// canonical — mirrors agent.execute
|
|
70
|
+
const result = await wf.execute(
|
|
71
|
+
{ url: "https://..." },
|
|
72
|
+
{ runId: "catalog-123", signal: AbortSignal.timeout(60_000) },
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
// single-object — ergonomic alt
|
|
76
|
+
const result = await wf.execute({
|
|
77
|
+
input: { url: "https://..." },
|
|
78
|
+
runId: "catalog-123",
|
|
79
|
+
});
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
`WorkflowRunOptions` carries `runId`, `signal`, `on`, `context`, `sessionId`. `WorkflowDefinition.version` mirrors onto every produced report.
|
|
83
|
+
|
|
84
|
+
## `execute()` never throws
|
|
85
|
+
|
|
86
|
+
All failures funnel into `result.error`:
|
|
87
|
+
|
|
88
|
+
- `StepFailedError` / `STEP_FAILED`
|
|
89
|
+
- `RoutingError` / `WORKFLOW_INVALID_GOTO`
|
|
90
|
+
- `WorkflowDriftError` / `WORKFLOW_DRIFT`
|
|
91
|
+
- `WorkflowCancelledError` / `WORKFLOW_CANCELLED`
|
|
92
|
+
- `MaxStepsExceededError` / `WORKFLOW_MAX_STEPS`
|
|
93
|
+
|
|
94
|
+
See [`@warlock.js/ai/handle-ai-errors/SKILL.md`](@warlock.js/ai/handle-ai-errors/SKILL.md).
|
|
95
|
+
|
|
96
|
+
## Result shape
|
|
97
|
+
|
|
98
|
+
```ts
|
|
99
|
+
const { data, report, usage, error } = await wf.execute(input);
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
```ts
|
|
103
|
+
type WorkflowResult<TOutput> = {
|
|
104
|
+
type: "workflow";
|
|
105
|
+
data?: TOutput; // from workflow.output.extract
|
|
106
|
+
report: WorkflowReport; // runId, signature, status, timings, per-step snapshots
|
|
107
|
+
usage: Usage; // aggregated across all agent calls
|
|
108
|
+
error?: AIError;
|
|
109
|
+
};
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
`report.steps[name]` holds a frozen `StepSnapshot` with `output`, `status`, `attempts`, `attemptHistory`, timings, nested children for parallel groups.
|
|
113
|
+
|
|
114
|
+
## Step lifecycle
|
|
115
|
+
|
|
116
|
+
```
|
|
117
|
+
skip? → before? → (run | agent | parallel) → output.extract (+ schema) → after? → nextStep?
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Exactly one of `run` / `agent` / `parallel` per step (enforced at `ai.step()` author time).
|
|
121
|
+
|
|
122
|
+
| Phase | Purpose |
|
|
123
|
+
| --- | --- |
|
|
124
|
+
| `skip` | Return `true` to skip the step. Output becomes `undefined`. `nextStep` still fires. |
|
|
125
|
+
| `before` | Pre-work — fetch, set state, validate. |
|
|
126
|
+
| `run` | Core non-agent work. |
|
|
127
|
+
| `agent` | Agent to execute. Takes `input(ctx)` as prompt builder. |
|
|
128
|
+
| `input` | Required when `agent` is set. |
|
|
129
|
+
| `output` | `{ extract, schema? }` — extracts the step's output. |
|
|
130
|
+
| `after` | Post-work — save, notify. |
|
|
131
|
+
| `nextStep` | Step-level routing on `completed` / `skipped`. |
|
|
132
|
+
| `onFailure` | Step-level recovery routing after retries exhaust. |
|
|
133
|
+
| `onCancel` | Cleanup if cancelled in-flight. |
|
|
134
|
+
|
|
135
|
+
Errors in `before`/`run`/`agent`/`after`/`output` are retryable. Errors in `nextStep` and `onFailure` terminate the workflow with `RoutingError`.
|
|
136
|
+
|
|
137
|
+
## Context (`ctx`)
|
|
138
|
+
|
|
139
|
+
```ts
|
|
140
|
+
type WorkflowContext<TInput, TState, TContext> = {
|
|
141
|
+
readonly input: TInput; // frozen — durable cause
|
|
142
|
+
readonly context: TContext; // frozen — per-execution
|
|
143
|
+
readonly steps: Record<string, StepSnapshot>; // frozen snapshots of COMPLETED steps
|
|
144
|
+
state: TState; // mutable current shared state
|
|
145
|
+
readonly agentResult?: AgentResult<unknown>; // set when current step has an agent
|
|
146
|
+
readonly runId: string;
|
|
147
|
+
readonly signal?: AbortSignal;
|
|
148
|
+
readonly startedAt: Date;
|
|
149
|
+
};
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
`input`, `context`, `steps` are deep-frozen. `state` is mutable during a step and frozen into `steps[name].state` on completion.
|
|
153
|
+
|
|
154
|
+
### `input` vs `context`
|
|
155
|
+
|
|
156
|
+
- `input` answers *what* to process — persisted in the snapshot, replayed verbatim on `resume()`.
|
|
157
|
+
- `context` answers *who's running it* — tenancy, user, locale, traceId. **Never persisted.** Callers pass fresh on every `execute()` and `resume()`.
|
|
158
|
+
|
|
159
|
+
**Resume rule.** No fingerprinting on context. Persistence-scoping fields (e.g. `organizationId`) MUST match across resume — silent data corruption otherwise.
|
|
160
|
+
|
|
161
|
+
## State vs `steps[x].output` — performance
|
|
162
|
+
|
|
163
|
+
- **Small control data** (flags, counters) → `ctx.state`. Cheap.
|
|
164
|
+
- **Large artifacts** (HTML blobs, embedding vectors) → producer's `output.extract`, read via `ctx.steps[prev].output`. `ctx.state` clones on every retry attempt; `ctx.steps` clones once on step commit.
|
|
165
|
+
|
|
166
|
+
## Parallel children
|
|
167
|
+
|
|
168
|
+
```ts
|
|
169
|
+
ai.step({
|
|
170
|
+
name: "generate",
|
|
171
|
+
parallel: [
|
|
172
|
+
ai.step({ name: "draft", agent: writerAgent, input, output }),
|
|
173
|
+
ai.step({ name: "suggest-articles", agent: kbAgent, input, output }),
|
|
174
|
+
],
|
|
175
|
+
});
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
- Children share `ctx.state` — last-write-wins.
|
|
179
|
+
- Addressable by flat (`ctx.steps.draft`) AND nested (`ctx.steps.generate.steps.draft`) path.
|
|
180
|
+
- Any child fails → all siblings still complete (atomic settlement); parent's `error` becomes the first child's error.
|
|
181
|
+
- Checkpoint atomically after all children settle.
|
|
182
|
+
|
|
183
|
+
## Routing — `nextStep` (success) + `onFailure` (failure)
|
|
184
|
+
|
|
185
|
+
```ts
|
|
186
|
+
ai.step({
|
|
187
|
+
name: "qa",
|
|
188
|
+
agent: qaReviewerAgent,
|
|
189
|
+
input,
|
|
190
|
+
output,
|
|
191
|
+
nextStep: (ctx) => {
|
|
192
|
+
if (!ctx.agentResult?.data.approved) {
|
|
193
|
+
ctx.state.qaFeedback = ctx.agentResult?.data.feedback;
|
|
194
|
+
return { goto: "draft" }; // success-path route
|
|
195
|
+
}
|
|
196
|
+
},
|
|
197
|
+
onFailure: (ctx, error) => {
|
|
198
|
+
if (error.code === "PROVIDER_RATE_LIMIT") {
|
|
199
|
+
return { goto: "fallbackQa" };
|
|
200
|
+
}
|
|
201
|
+
// void → halt with the original StepFailedError
|
|
202
|
+
},
|
|
203
|
+
});
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
Returns: `{ goto: "stepName" }`, `{ end: true }`, or `void` (fall through / halt).
|
|
207
|
+
|
|
208
|
+
**Guards:** `maxSteps` (default 100) hard-fails with `MaxStepsExceededError`. `loopWarnAfter` (default 5) emits `workflow.loop.warning`.
|
|
209
|
+
|
|
210
|
+
## Retry
|
|
211
|
+
|
|
212
|
+
```ts
|
|
213
|
+
retry: {
|
|
214
|
+
attempts: 3, // default 1 = no retry
|
|
215
|
+
backoff: "exponential", // "none" | "linear" | "exponential" | (attempt) => ms
|
|
216
|
+
retryOn: (error, attempt) => true,
|
|
217
|
+
onRetry: (attempt, error) => {},
|
|
218
|
+
}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
Exponential defaults: 500 ms → 1 s → 2 s → 4 s → 8 s, capped at 30 s. `AbortError` short-circuits retry.
|
|
222
|
+
|
|
223
|
+
## Cancellation
|
|
224
|
+
|
|
225
|
+
```ts
|
|
226
|
+
const ctrl = new AbortController();
|
|
227
|
+
const result = wf.execute({ input, signal: ctrl.signal });
|
|
228
|
+
ctrl.abort("user cancelled");
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
Between-step cancellation is guaranteed. Mid-step is best-effort. `status: "cancelled"` on return with partial `report.steps`; checkpoint written before returning (resume works).
|
|
232
|
+
|
|
233
|
+
## Persistence & resume
|
|
234
|
+
|
|
235
|
+
See [`@warlock.js/ai/persist-ai-data/SKILL.md`](@warlock.js/ai/persist-ai-data/SKILL.md).
|
|
236
|
+
|
|
237
|
+
```ts
|
|
238
|
+
await wf.execute({ input, runId: "ticket-123" }); // fresh run
|
|
239
|
+
await wf.resume("ticket-123"); // after crash
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
## Events — three-tier subscription
|
|
243
|
+
|
|
244
|
+
`workflow.starting`, `workflow.step.{starting|streaming|completed|skipped|retrying|failed}`, `workflow.loop.warning`, `workflow.cancelled`, `workflow.completed`, `workflow.error`.
|
|
245
|
+
|
|
246
|
+
Subscription order: **definition → instance → per-call** (all matching handlers fire).
|
|
247
|
+
|
|
248
|
+
Every payload carries `runId` and `rootRunId`.
|
|
249
|
+
|
|
250
|
+
## Design reference
|
|
251
|
+
|
|
252
|
+
`domains/ai/design/workflow.md` — locked spec, §1–§16 covers every rule with five PoC examples.
|
|
253
|
+
|
|
254
|
+
## See also
|
|
255
|
+
|
|
256
|
+
- [`@warlock.js/ai/run-ai-agent/SKILL.md`](@warlock.js/ai/run-ai-agent/SKILL.md) — agents inside steps
|
|
257
|
+
- [`@warlock.js/ai/persist-ai-data/SKILL.md`](@warlock.js/ai/persist-ai-data/SKILL.md) — snapshot resume + drift
|
|
258
|
+
- [`@warlock.js/ai/handle-ai-errors/SKILL.md`](@warlock.js/ai/handle-ai-errors/SKILL.md) — `WorkflowError` subclasses
|