@warlock.js/ai 4.3.0 → 4.5.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/CHANGELOG.md +52 -48
- package/cjs/index.cjs +221 -14144
- package/cjs/src-C02yzsLs.cjs +22991 -0
- package/cjs/src-C02yzsLs.cjs.map +1 -0
- package/cjs/src-DFibP2FQ.cjs +30 -0
- package/esm/agent/agent-config.type.d.mts +90 -1
- package/esm/agent/agent-config.type.d.mts.map +1 -1
- package/esm/agent/agent-input-builder.mjs +27 -6
- package/esm/agent/agent-input-builder.mjs.map +1 -1
- package/esm/agent/agent.d.mts +40 -1
- package/esm/agent/agent.d.mts.map +1 -1
- package/esm/agent/agent.mjs +203 -30
- package/esm/agent/agent.mjs.map +1 -1
- package/esm/agent/index.d.mts +2 -1
- package/esm/agent/index.mjs +1 -0
- package/esm/agent/judge-config.type.d.mts +33 -0
- package/esm/agent/judge-config.type.d.mts.map +1 -0
- package/esm/agent/judge-config.type.mjs +13 -0
- package/esm/agent/judge-config.type.mjs.map +1 -0
- package/esm/ai-openai/src/embedder.mjs +4 -0
- package/esm/ai-openai/src/index.mjs +4 -0
- package/esm/ai-openai/src/model.mjs +5 -0
- package/esm/ai-openai/src/sdk.mjs +6 -0
- package/esm/ai-openai/src/utils/index.mjs +4 -0
- package/esm/ai-openai/src/utils/to-openai-tools.mjs +3 -0
- package/esm/ai-openai/src/utils/wrap-openai-error.mjs +4 -0
- package/esm/ai.d.mts +119 -53
- package/esm/ai.d.mts.map +1 -1
- package/esm/ai.mjs +43 -8
- package/esm/ai.mjs.map +1 -1
- package/esm/batch/batch.d.mts.map +1 -1
- package/esm/batch/batch.mjs +21 -1
- package/esm/batch/batch.mjs.map +1 -1
- package/esm/batch/batch.type.d.mts +11 -4
- package/esm/batch/batch.type.d.mts.map +1 -1
- package/esm/config.d.mts +39 -3
- package/esm/config.d.mts.map +1 -1
- package/esm/config.mjs +26 -2
- package/esm/config.mjs.map +1 -1
- package/esm/contracts/agent/agent-options.type.d.mts +11 -3
- package/esm/contracts/agent/agent-options.type.d.mts.map +1 -1
- package/esm/contracts/agent/eval.type.d.mts +43 -2
- package/esm/contracts/agent/eval.type.d.mts.map +1 -1
- package/esm/contracts/attachment-policy.type.d.mts +51 -0
- package/esm/contracts/attachment-policy.type.d.mts.map +1 -0
- package/esm/contracts/attachment.type.d.mts +16 -7
- package/esm/contracts/attachment.type.d.mts.map +1 -1
- package/esm/contracts/content-part.type.d.mts +14 -5
- package/esm/contracts/content-part.type.d.mts.map +1 -1
- package/esm/contracts/events/supervisor-events.type.d.mts.map +1 -1
- package/esm/contracts/index.d.mts +6 -4
- package/esm/contracts/model.contract.d.mts +11 -8
- package/esm/contracts/model.contract.d.mts.map +1 -1
- package/esm/contracts/orchestrator/index.d.mts +1 -0
- package/esm/contracts/orchestrator/orchestrator-config.type.d.mts +31 -2
- package/esm/contracts/orchestrator/orchestrator-config.type.d.mts.map +1 -1
- package/esm/contracts/orchestrator/session-lock.contract.d.mts +47 -0
- package/esm/contracts/orchestrator/session-lock.contract.d.mts.map +1 -0
- package/esm/contracts/planner/index.d.mts +1 -1
- package/esm/contracts/planner/planner-config.type.d.mts +31 -0
- package/esm/contracts/planner/planner-config.type.d.mts.map +1 -1
- package/esm/contracts/planner/planner-execute-options.type.d.mts +48 -1
- package/esm/contracts/planner/planner-execute-options.type.d.mts.map +1 -1
- package/esm/contracts/planner/planner-result.type.d.mts +19 -5
- package/esm/contracts/planner/planner-result.type.d.mts.map +1 -1
- package/esm/contracts/planner/planner.contract.d.mts +1 -1
- package/esm/contracts/result/agent-result.type.d.mts +6 -4
- package/esm/contracts/result/agent-result.type.d.mts.map +1 -1
- package/esm/contracts/result/base-report.type.d.mts +21 -3
- package/esm/contracts/result/base-report.type.d.mts.map +1 -1
- package/esm/contracts/result/base-report.type.mjs.map +1 -1
- package/esm/contracts/result/execution-report.type.d.mts +53 -1
- package/esm/contracts/result/execution-report.type.d.mts.map +1 -1
- package/esm/contracts/result/orchestrator-result.type.d.mts +15 -11
- package/esm/contracts/result/orchestrator-result.type.d.mts.map +1 -1
- package/esm/contracts/result/supervisor-result.type.d.mts +13 -1
- package/esm/contracts/result/supervisor-result.type.d.mts.map +1 -1
- package/esm/contracts/result/tool-call.type.d.mts +2 -2
- package/esm/contracts/result/tool-call.type.d.mts.map +1 -1
- package/esm/contracts/result/workflow-result.type.d.mts +1 -0
- package/esm/contracts/result/workflow-result.type.d.mts.map +1 -1
- package/esm/contracts/supervisor/supervisor-config.type.d.mts +29 -0
- package/esm/contracts/supervisor/supervisor-config.type.d.mts.map +1 -1
- package/esm/contracts/system-prompt.contract.d.mts +103 -1
- package/esm/contracts/system-prompt.contract.d.mts.map +1 -1
- package/esm/contracts/team/index.d.mts +1 -0
- package/esm/contracts/team/team-config.type.d.mts +127 -0
- package/esm/contracts/team/team-config.type.d.mts.map +1 -0
- package/esm/contracts/tool.contract.d.mts +4 -2
- package/esm/contracts/tool.contract.d.mts.map +1 -1
- package/esm/contracts/workflow/step.contract.d.mts +30 -5
- package/esm/contracts/workflow/step.contract.d.mts.map +1 -1
- package/esm/contracts/workflow/workflow.contract.d.mts +16 -0
- package/esm/contracts/workflow/workflow.contract.d.mts.map +1 -1
- package/esm/errors/error-code.type.d.mts +1 -1
- package/esm/errors/index.d.mts +1 -0
- package/esm/errors/index.mjs +1 -0
- package/esm/errors/outbound-policy-error.d.mts +27 -0
- package/esm/errors/outbound-policy-error.d.mts.map +1 -0
- package/esm/errors/outbound-policy-error.mjs +32 -0
- package/esm/errors/outbound-policy-error.mjs.map +1 -0
- package/esm/eval/dataset.d.mts +28 -0
- package/esm/eval/dataset.d.mts.map +1 -0
- package/esm/eval/dataset.mjs +112 -0
- package/esm/eval/dataset.mjs.map +1 -0
- package/esm/eval/dataset.type.d.mts +53 -0
- package/esm/eval/dataset.type.d.mts.map +1 -0
- package/esm/eval/eval-runner.d.mts.map +1 -1
- package/esm/eval/eval-runner.mjs +16 -2
- package/esm/eval/eval-runner.mjs.map +1 -1
- package/esm/eval/index.d.mts +20 -1
- package/esm/eval/index.d.mts.map +1 -1
- package/esm/eval/index.mjs +20 -2
- package/esm/eval/index.mjs.map +1 -1
- package/esm/eval/regression.d.mts +30 -0
- package/esm/eval/regression.d.mts.map +1 -0
- package/esm/eval/regression.mjs +51 -0
- package/esm/eval/regression.mjs.map +1 -0
- package/esm/eval/report-json.d.mts +30 -0
- package/esm/eval/report-json.d.mts.map +1 -0
- package/esm/eval/report-json.mjs +33 -0
- package/esm/eval/report-json.mjs.map +1 -0
- package/esm/eval/report-junit.d.mts +22 -0
- package/esm/eval/report-junit.d.mts.map +1 -0
- package/esm/eval/report-junit.mjs +60 -0
- package/esm/eval/report-junit.mjs.map +1 -0
- package/esm/guard/contracts/guard-options.type.d.mts +165 -0
- package/esm/guard/contracts/guard-options.type.d.mts.map +1 -0
- package/esm/guard/contracts/guardrail.contract.d.mts +78 -0
- package/esm/guard/contracts/guardrail.contract.d.mts.map +1 -0
- package/esm/guard/contracts/index.d.mts +4 -0
- package/esm/guard/contracts/openai-client.contract.d.mts +51 -0
- package/esm/guard/contracts/openai-client.contract.d.mts.map +1 -0
- package/esm/guard/contracts/verdict.type.d.mts +76 -0
- package/esm/guard/contracts/verdict.type.d.mts.map +1 -0
- package/esm/guard/detectors/index.d.mts +4 -0
- package/esm/guard/detectors/index.mjs +6 -0
- package/esm/guard/detectors/injection.d.mts +34 -0
- package/esm/guard/detectors/injection.d.mts.map +1 -0
- package/esm/guard/detectors/injection.mjs +254 -0
- package/esm/guard/detectors/injection.mjs.map +1 -0
- package/esm/guard/detectors/moderation.d.mts +32 -0
- package/esm/guard/detectors/moderation.d.mts.map +1 -0
- package/esm/guard/detectors/moderation.mjs +134 -0
- package/esm/guard/detectors/moderation.mjs.map +1 -0
- package/esm/guard/detectors/pii.d.mts +41 -0
- package/esm/guard/detectors/pii.d.mts.map +1 -0
- package/esm/guard/detectors/pii.mjs +199 -0
- package/esm/guard/detectors/pii.mjs.map +1 -0
- package/esm/guard/detectors/topic.d.mts +29 -0
- package/esm/guard/detectors/topic.d.mts.map +1 -0
- package/esm/guard/detectors/topic.mjs +99 -0
- package/esm/guard/detectors/topic.mjs.map +1 -0
- package/esm/guard/errors.d.mts +12 -0
- package/esm/guard/errors.d.mts.map +1 -0
- package/esm/guard/errors.mjs +18 -0
- package/esm/guard/errors.mjs.map +1 -0
- package/esm/guard/guard.d.mts +67 -0
- package/esm/guard/guard.d.mts.map +1 -0
- package/esm/guard/guard.mjs +209 -0
- package/esm/guard/guard.mjs.map +1 -0
- package/esm/guard/guardrail.d.mts +39 -0
- package/esm/guard/guardrail.d.mts.map +1 -0
- package/esm/guard/guardrail.mjs +22 -0
- package/esm/guard/guardrail.mjs.map +1 -0
- package/esm/human/contracts/approval.type.d.mts +154 -0
- package/esm/human/contracts/approval.type.d.mts.map +1 -0
- package/esm/human/contracts/human-approval.type.d.mts +38 -0
- package/esm/human/contracts/human-approval.type.d.mts.map +1 -0
- package/esm/human/contracts/index.d.mts +4 -0
- package/esm/human/contracts/interrupt-store.contract.d.mts +112 -0
- package/esm/human/contracts/interrupt-store.contract.d.mts.map +1 -0
- package/esm/human/contracts/resume.type.d.mts +77 -0
- package/esm/human/contracts/resume.type.d.mts.map +1 -0
- package/esm/human/errors.d.mts +84 -0
- package/esm/human/errors.d.mts.map +1 -0
- package/esm/human/errors.mjs +60 -0
- package/esm/human/errors.mjs.map +1 -0
- package/esm/human/human-approval.d.mts +57 -0
- package/esm/human/human-approval.d.mts.map +1 -0
- package/esm/human/human-approval.mjs +170 -0
- package/esm/human/human-approval.mjs.map +1 -0
- package/esm/human/policy.d.mts +55 -0
- package/esm/human/policy.d.mts.map +1 -0
- package/esm/human/policy.mjs +67 -0
- package/esm/human/policy.mjs.map +1 -0
- package/esm/human/register.mjs +37 -0
- package/esm/human/register.mjs.map +1 -0
- package/esm/human/resume-seed.mjs +53 -0
- package/esm/human/resume-seed.mjs.map +1 -0
- package/esm/human/resume.d.mts +54 -0
- package/esm/human/resume.d.mts.map +1 -0
- package/esm/human/resume.mjs +121 -0
- package/esm/human/resume.mjs.map +1 -0
- package/esm/human/stores/index.mjs +5 -0
- package/esm/human/stores/memory.d.mts +30 -0
- package/esm/human/stores/memory.d.mts.map +1 -0
- package/esm/human/stores/memory.mjs +91 -0
- package/esm/human/stores/memory.mjs.map +1 -0
- package/esm/human/stores/pg.d.mts +59 -0
- package/esm/human/stores/pg.d.mts.map +1 -0
- package/esm/human/stores/pg.mjs +220 -0
- package/esm/human/stores/pg.mjs.map +1 -0
- package/esm/human/stores/redis.d.mts +56 -0
- package/esm/human/stores/redis.d.mts.map +1 -0
- package/esm/human/stores/redis.mjs +201 -0
- package/esm/human/stores/redis.mjs.map +1 -0
- package/esm/index.d.mts +113 -22
- package/esm/index.mjs +82 -11
- package/esm/middleware/builtins/budget.mjs +6 -2
- package/esm/middleware/builtins/budget.mjs.map +1 -1
- package/esm/middleware/utils/extract-user-text.d.mts +8 -1
- package/esm/middleware/utils/extract-user-text.d.mts.map +1 -1
- package/esm/middleware/utils/extract-user-text.mjs +8 -1
- package/esm/middleware/utils/extract-user-text.mjs.map +1 -1
- package/esm/object-stream/index.d.mts +2 -0
- package/esm/object-stream/index.mjs +4 -0
- package/esm/object-stream/parse-partial-json.d.mts +22 -0
- package/esm/object-stream/parse-partial-json.d.mts.map +1 -0
- package/esm/object-stream/parse-partial-json.mjs +78 -0
- package/esm/object-stream/parse-partial-json.mjs.map +1 -0
- package/esm/object-stream/stream-object.d.mts +68 -0
- package/esm/object-stream/stream-object.d.mts.map +1 -0
- package/esm/object-stream/stream-object.mjs +104 -0
- package/esm/object-stream/stream-object.mjs.map +1 -0
- package/esm/observe/index.mjs +4 -0
- package/esm/observe/observer-registry.d.mts +30 -0
- package/esm/observe/observer-registry.d.mts.map +1 -0
- package/esm/observe/observer-registry.mjs +51 -0
- package/esm/observe/observer-registry.mjs.map +1 -0
- package/esm/observe/observer.contract.d.mts +40 -0
- package/esm/observe/observer.contract.d.mts.map +1 -0
- package/esm/observe/resolve-observers.d.mts +40 -0
- package/esm/observe/resolve-observers.d.mts.map +1 -0
- package/esm/observe/resolve-observers.mjs +73 -0
- package/esm/observe/resolve-observers.mjs.map +1 -0
- package/esm/orchestrator/execution.d.mts.map +1 -1
- package/esm/orchestrator/execution.mjs +5 -2
- package/esm/orchestrator/execution.mjs.map +1 -1
- package/esm/orchestrator/index.d.mts +1 -0
- package/esm/orchestrator/index.mjs +1 -0
- package/esm/orchestrator/orchestrator.d.mts.map +1 -1
- package/esm/orchestrator/orchestrator.mjs +39 -6
- package/esm/orchestrator/orchestrator.mjs.map +1 -1
- package/esm/orchestrator/session-lock.d.mts +25 -0
- package/esm/orchestrator/session-lock.d.mts.map +1 -0
- package/esm/orchestrator/session-lock.mjs +83 -0
- package/esm/orchestrator/session-lock.mjs.map +1 -0
- package/esm/planner/dag-scheduler.mjs +97 -0
- package/esm/planner/dag-scheduler.mjs.map +1 -0
- package/esm/planner/plan-prompt.d.mts +1 -1
- package/esm/planner/plan-prompt.d.mts.map +1 -1
- package/esm/planner/plan-prompt.mjs +2 -1
- package/esm/planner/plan-prompt.mjs.map +1 -1
- package/esm/planner/plan-schema.mjs +17 -14
- package/esm/planner/plan-schema.mjs.map +1 -1
- package/esm/planner/planner-run.d.mts.map +1 -1
- package/esm/planner/planner-run.mjs +300 -29
- package/esm/planner/planner-run.mjs.map +1 -1
- package/esm/planner/planner.mjs +1 -1
- package/esm/planner/planner.mjs.map +1 -1
- package/esm/prompt/errors.d.mts +57 -0
- package/esm/prompt/errors.d.mts.map +1 -0
- package/esm/prompt/errors.mjs +73 -0
- package/esm/prompt/errors.mjs.map +1 -0
- package/esm/prompt/index.d.mts +3 -0
- package/esm/prompt/index.mjs +4 -0
- package/esm/prompt/prompt-langfuse-sync.mjs +104 -0
- package/esm/prompt/prompt-langfuse-sync.mjs.map +1 -0
- package/esm/prompt/prompt-langfuse-sync.type.d.mts +32 -0
- package/esm/prompt/prompt-langfuse-sync.type.d.mts.map +1 -0
- package/esm/prompt/prompt-validate.mjs +170 -0
- package/esm/prompt/prompt-validate.mjs.map +1 -0
- package/esm/prompt/prompt.d.mts +54 -0
- package/esm/prompt/prompt.d.mts.map +1 -0
- package/esm/prompt/prompt.mjs +218 -0
- package/esm/prompt/prompt.mjs.map +1 -0
- package/esm/prompt/prompt.type.d.mts +174 -0
- package/esm/prompt/prompt.type.d.mts.map +1 -0
- package/esm/prompts/index.d.mts +3 -0
- package/esm/prompts/index.mjs +3 -0
- package/esm/prompts/prompts-manager.contract.d.mts +154 -0
- package/esm/prompts/prompts-manager.contract.d.mts.map +1 -0
- package/esm/prompts/prompts-manager.d.mts +38 -0
- package/esm/prompts/prompts-manager.d.mts.map +1 -0
- package/esm/prompts/prompts-manager.mjs +410 -0
- package/esm/prompts/prompts-manager.mjs.map +1 -0
- package/esm/prompts/prompts-manager.type.d.mts +172 -0
- package/esm/prompts/prompts-manager.type.d.mts.map +1 -0
- package/esm/prompts/prompts-validate.mjs +200 -0
- package/esm/prompts/prompts-validate.mjs.map +1 -0
- package/esm/rag/as-tool.mjs +48 -0
- package/esm/rag/as-tool.mjs.map +1 -0
- package/esm/rag/chunk/chunk.d.mts +24 -0
- package/esm/rag/chunk/chunk.d.mts.map +1 -0
- package/esm/rag/chunk/chunk.mjs +44 -0
- package/esm/rag/chunk/chunk.mjs.map +1 -0
- package/esm/rag/chunk/fixed.mjs +32 -0
- package/esm/rag/chunk/fixed.mjs.map +1 -0
- package/esm/rag/chunk/markdown.mjs +75 -0
- package/esm/rag/chunk/markdown.mjs.map +1 -0
- package/esm/rag/chunk/recursive.mjs +132 -0
- package/esm/rag/chunk/recursive.mjs.map +1 -0
- package/esm/rag/chunk/sentence.mjs +73 -0
- package/esm/rag/chunk/sentence.mjs.map +1 -0
- package/esm/rag/contracts/chunk-options.type.d.mts +35 -0
- package/esm/rag/contracts/chunk-options.type.d.mts.map +1 -0
- package/esm/rag/contracts/citation.type.d.mts +35 -0
- package/esm/rag/contracts/citation.type.d.mts.map +1 -0
- package/esm/rag/contracts/index.d.mts +4 -0
- package/esm/rag/contracts/rag-config.type.d.mts +68 -0
- package/esm/rag/contracts/rag-config.type.d.mts.map +1 -0
- package/esm/rag/contracts/rag-document.type.d.mts +21 -0
- package/esm/rag/contracts/rag-document.type.d.mts.map +1 -0
- package/esm/rag/hybrid/bm25.d.mts +23 -0
- package/esm/rag/hybrid/bm25.d.mts.map +1 -0
- package/esm/rag/hybrid/bm25.mjs +51 -0
- package/esm/rag/hybrid/bm25.mjs.map +1 -0
- package/esm/rag/hybrid/hybrid-rank.d.mts +33 -0
- package/esm/rag/hybrid/hybrid-rank.d.mts.map +1 -0
- package/esm/rag/hybrid/hybrid-rank.mjs +29 -0
- package/esm/rag/hybrid/hybrid-rank.mjs.map +1 -0
- package/esm/rag/hybrid/rrf.d.mts +25 -0
- package/esm/rag/hybrid/rrf.d.mts.map +1 -0
- package/esm/rag/hybrid/rrf.mjs +30 -0
- package/esm/rag/hybrid/rrf.mjs.map +1 -0
- package/esm/rag/index.d.mts +15 -0
- package/esm/rag/index.mjs +11 -0
- package/esm/rag/rag.d.mts +38 -0
- package/esm/rag/rag.d.mts.map +1 -0
- package/esm/rag/rag.mjs +126 -0
- package/esm/rag/rag.mjs.map +1 -0
- package/esm/rag/rerank/keyword-reranker.d.mts +32 -0
- package/esm/rag/rerank/keyword-reranker.d.mts.map +1 -0
- package/esm/rag/rerank/keyword-reranker.mjs +58 -0
- package/esm/rag/rerank/keyword-reranker.mjs.map +1 -0
- package/esm/rag/rerank/llm-reranker.d.mts +36 -0
- package/esm/rag/rerank/llm-reranker.d.mts.map +1 -0
- package/esm/rag/rerank/llm-reranker.mjs +85 -0
- package/esm/rag/rerank/llm-reranker.mjs.map +1 -0
- package/esm/rag/rerank/reranker.contract.d.mts +28 -0
- package/esm/rag/rerank/reranker.contract.d.mts.map +1 -0
- package/esm/rag/retrieve.mjs +68 -0
- package/esm/rag/retrieve.mjs.map +1 -0
- package/esm/rag/store/cache-vector-store.d.mts +27 -0
- package/esm/rag/store/cache-vector-store.d.mts.map +1 -0
- package/esm/rag/store/cache-vector-store.mjs +48 -0
- package/esm/rag/store/cache-vector-store.mjs.map +1 -0
- package/esm/rag/store/vector-store.contract.d.mts +38 -0
- package/esm/rag/store/vector-store.contract.d.mts.map +1 -0
- package/esm/rag/transforms/multi-query.d.mts +27 -0
- package/esm/rag/transforms/multi-query.d.mts.map +1 -0
- package/esm/rag/transforms/multi-query.mjs +41 -0
- package/esm/rag/transforms/multi-query.mjs.map +1 -0
- package/esm/security/index.mjs +5 -0
- package/esm/security/outbound-policy.d.mts +46 -0
- package/esm/security/outbound-policy.d.mts.map +1 -0
- package/esm/security/outbound-policy.mjs +187 -0
- package/esm/security/outbound-policy.mjs.map +1 -0
- package/esm/security/outbound-policy.type.d.mts +74 -0
- package/esm/security/outbound-policy.type.d.mts.map +1 -0
- package/esm/security/private-ip.d.mts +15 -0
- package/esm/security/private-ip.d.mts.map +1 -0
- package/esm/security/private-ip.mjs +48 -0
- package/esm/security/private-ip.mjs.map +1 -0
- package/esm/security/redact.d.mts +59 -0
- package/esm/security/redact.d.mts.map +1 -0
- package/esm/security/redact.mjs +122 -0
- package/esm/security/redact.mjs.map +1 -0
- package/esm/serve/serve.d.mts +50 -0
- package/esm/serve/serve.d.mts.map +1 -0
- package/esm/serve/serve.mjs +90 -0
- package/esm/serve/serve.mjs.map +1 -0
- package/esm/serve/sse.d.mts +20 -0
- package/esm/serve/sse.d.mts.map +1 -0
- package/esm/serve/sse.mjs +25 -0
- package/esm/serve/sse.mjs.map +1 -0
- package/esm/serve/stream-to-sse.d.mts +29 -0
- package/esm/serve/stream-to-sse.d.mts.map +1 -0
- package/esm/serve/stream-to-sse.mjs +37 -0
- package/esm/serve/stream-to-sse.mjs.map +1 -0
- package/esm/skills/catalog.d.mts +49 -0
- package/esm/skills/catalog.d.mts.map +1 -0
- package/esm/skills/catalog.mjs +140 -0
- package/esm/skills/catalog.mjs.map +1 -0
- package/esm/skills/contracts/skill-record.type.d.mts +37 -0
- package/esm/skills/contracts/skill-record.type.d.mts.map +1 -0
- package/esm/skills/contracts/skills-config.type.d.mts +108 -0
- package/esm/skills/contracts/skills-config.type.d.mts.map +1 -0
- package/esm/skills/contracts/skills-store.contract.d.mts +28 -0
- package/esm/skills/contracts/skills-store.contract.d.mts.map +1 -0
- package/esm/skills/contracts/skills.contract.d.mts +43 -0
- package/esm/skills/contracts/skills.contract.d.mts.map +1 -0
- package/esm/skills/index.d.mts +16 -0
- package/esm/skills/index.mjs +14 -0
- package/esm/skills/load-skill-tool.d.mts +38 -0
- package/esm/skills/load-skill-tool.d.mts.map +1 -0
- package/esm/skills/load-skill-tool.mjs +65 -0
- package/esm/skills/load-skill-tool.mjs.map +1 -0
- package/esm/skills/review-gate.d.mts +33 -0
- package/esm/skills/review-gate.d.mts.map +1 -0
- package/esm/skills/review-gate.mjs +60 -0
- package/esm/skills/review-gate.mjs.map +1 -0
- package/esm/skills/save-skill-tool.d.mts +39 -0
- package/esm/skills/save-skill-tool.d.mts.map +1 -0
- package/esm/skills/save-skill-tool.mjs +65 -0
- package/esm/skills/save-skill-tool.mjs.map +1 -0
- package/esm/skills/skills.d.mts +33 -0
- package/esm/skills/skills.d.mts.map +1 -0
- package/esm/skills/skills.mjs +109 -0
- package/esm/skills/skills.mjs.map +1 -0
- package/esm/skills/sources/directory-source.d.mts +19 -0
- package/esm/skills/sources/directory-source.d.mts.map +1 -0
- package/esm/skills/sources/directory-source.mjs +108 -0
- package/esm/skills/sources/directory-source.mjs.map +1 -0
- package/esm/skills/sources/index.d.mts +18 -0
- package/esm/skills/sources/index.d.mts.map +1 -0
- package/esm/skills/sources/index.mjs +27 -0
- package/esm/skills/sources/index.mjs.map +1 -0
- package/esm/skills/sources/parse-frontmatter.d.mts +27 -0
- package/esm/skills/sources/parse-frontmatter.d.mts.map +1 -0
- package/esm/skills/sources/parse-frontmatter.mjs +46 -0
- package/esm/skills/sources/parse-frontmatter.mjs.map +1 -0
- package/esm/skills/sources/store-source.d.mts +14 -0
- package/esm/skills/sources/store-source.d.mts.map +1 -0
- package/esm/skills/sources/store-source.mjs +15 -0
- package/esm/skills/sources/store-source.mjs.map +1 -0
- package/esm/skills/sources/url-source.d.mts +29 -0
- package/esm/skills/sources/url-source.d.mts.map +1 -0
- package/esm/skills/sources/url-source.mjs +117 -0
- package/esm/skills/sources/url-source.mjs.map +1 -0
- package/esm/skills/store/mock-skills-store.d.mts +57 -0
- package/esm/skills/store/mock-skills-store.d.mts.map +1 -0
- package/esm/skills/store/mock-skills-store.mjs +100 -0
- package/esm/skills/store/mock-skills-store.mjs.map +1 -0
- package/esm/skills/store/procedural-skill-store.d.mts +30 -0
- package/esm/skills/store/procedural-skill-store.d.mts.map +1 -0
- package/esm/skills/store/procedural-skill-store.mjs +125 -0
- package/esm/skills/store/procedural-skill-store.mjs.map +1 -0
- package/esm/supervisor/as-tool.mjs +2 -2
- package/esm/supervisor/as-tool.mjs.map +1 -1
- package/esm/supervisor/execution.d.mts.map +1 -1
- package/esm/supervisor/execution.mjs +31 -28
- package/esm/supervisor/execution.mjs.map +1 -1
- package/esm/supervisor/supervisor.d.mts.map +1 -1
- package/esm/supervisor/supervisor.mjs +8 -3
- package/esm/supervisor/supervisor.mjs.map +1 -1
- package/esm/system-prompt/index.d.mts +4 -0
- package/esm/system-prompt/system-prompt.d.mts +68 -4
- package/esm/system-prompt/system-prompt.d.mts.map +1 -1
- package/esm/system-prompt/system-prompt.mjs +89 -5
- package/esm/system-prompt/system-prompt.mjs.map +1 -1
- package/esm/team/gates.mjs +48 -0
- package/esm/team/gates.mjs.map +1 -0
- package/esm/team/index.d.mts +1 -0
- package/esm/team/index.mjs +3 -0
- package/esm/team/team.d.mts +42 -0
- package/esm/team/team.d.mts.map +1 -0
- package/esm/team/team.mjs +94 -0
- package/esm/team/team.mjs.map +1 -0
- package/esm/tool/executable-as-tool.d.mts.map +1 -1
- package/esm/tool/executable-as-tool.mjs +2 -2
- package/esm/tool/executable-as-tool.mjs.map +1 -1
- package/esm/tool/tool.d.mts.map +1 -1
- package/esm/tool/tool.mjs +2 -2
- package/esm/tool/tool.mjs.map +1 -1
- package/esm/utils/compute-cost.d.mts +17 -1
- package/esm/utils/compute-cost.d.mts.map +1 -1
- package/esm/utils/compute-cost.mjs +26 -1
- package/esm/utils/compute-cost.mjs.map +1 -1
- package/esm/utils/extract-json-lenient.d.mts +42 -0
- package/esm/utils/extract-json-lenient.d.mts.map +1 -0
- package/esm/utils/extract-json-lenient.mjs +97 -0
- package/esm/utils/extract-json-lenient.mjs.map +1 -0
- package/esm/utils/index.d.mts +4 -2
- package/esm/utils/index.mjs +3 -1
- package/esm/utils/json-schema.d.mts +1 -1
- package/esm/utils/prepare-attachment-part.d.mts +10 -1
- package/esm/utils/prepare-attachment-part.d.mts.map +1 -1
- package/esm/utils/prepare-attachment-part.mjs +103 -11
- package/esm/utils/prepare-attachment-part.mjs.map +1 -1
- package/esm/utils/resolve-attachment.d.mts +4 -3
- package/esm/utils/resolve-attachment.d.mts.map +1 -1
- package/esm/utils/resolve-attachment.mjs +4 -3
- package/esm/utils/resolve-attachment.mjs.map +1 -1
- package/esm/utils/run-context.d.mts +94 -0
- package/esm/utils/run-context.d.mts.map +1 -0
- package/esm/utils/run-context.mjs +98 -0
- package/esm/utils/run-context.mjs.map +1 -0
- package/esm/vcr/cassette-io.mjs +57 -0
- package/esm/vcr/cassette-io.mjs.map +1 -0
- package/esm/vcr/errors.d.mts +42 -0
- package/esm/vcr/errors.d.mts.map +1 -0
- package/esm/vcr/errors.mjs +37 -0
- package/esm/vcr/errors.mjs.map +1 -0
- package/esm/vcr/hash-request.d.mts +28 -0
- package/esm/vcr/hash-request.d.mts.map +1 -0
- package/esm/vcr/hash-request.mjs +118 -0
- package/esm/vcr/hash-request.mjs.map +1 -0
- package/esm/vcr/index.d.mts +4 -0
- package/esm/vcr/index.mjs +5 -0
- package/esm/vcr/vcr.d.mts +32 -0
- package/esm/vcr/vcr.d.mts.map +1 -0
- package/esm/vcr/vcr.mjs +248 -0
- package/esm/vcr/vcr.mjs.map +1 -0
- package/esm/vcr/vcr.type.d.mts +118 -0
- package/esm/vcr/vcr.type.d.mts.map +1 -0
- package/esm/workflow/as-tool.mjs +2 -2
- package/esm/workflow/as-tool.mjs.map +1 -1
- package/esm/workflow/engine.mjs +1 -0
- package/esm/workflow/engine.mjs.map +1 -1
- package/esm/workflow/step-runner.mjs +19 -20
- package/esm/workflow/step-runner.mjs.map +1 -1
- package/esm/workflow/workflow.d.mts.map +1 -1
- package/esm/workflow/workflow.mjs +8 -3
- package/esm/workflow/workflow.mjs.map +1 -1
- package/llms-full.txt +1683 -68
- package/llms.txt +16 -4
- package/package.json +7 -3
- package/skills/README.md +40 -4
- package/skills/ai-dx-helpers/SKILL.md +2 -2
- package/skills/approve-tool-calls/SKILL.md +134 -0
- package/skills/attach-ai-middleware/SKILL.md +1 -1
- package/skills/detect-and-redact-pii/SKILL.md +104 -0
- package/skills/durable-resume/SKILL.md +128 -0
- package/skills/escalate-block-to-human/SKILL.md +85 -0
- package/skills/eval-datasets-and-ci/SKILL.md +117 -0
- package/skills/guard-input-output/SKILL.md +117 -0
- package/skills/manage-prompts/SKILL.md +186 -0
- package/skills/observe-ai-flows/SKILL.md +94 -0
- package/skills/record-replay-llm/SKILL.md +92 -0
- package/skills/run-ai-agent/SKILL.md +26 -1
- package/skills/run-ai-rag/SKILL.md +139 -0
- package/skills/run-ai-team/SKILL.md +107 -0
- package/skills/run-orchestrator/SKILL.md +2 -0
- package/skills/run-planner/SKILL.md +73 -8
- package/skills/run-supervisor/SKILL.md +20 -1
- package/skills/use-runtime-skills/SKILL.md +106 -0
- package/skills/write-system-prompt/SKILL.md +30 -1
- package/cjs/index.cjs.map +0 -1
- package/esm/contracts/result/index.d.mts +0 -15
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
//#region ../@warlock.js/ai/src/security/redact.ts
|
|
2
|
+
/**
|
|
3
|
+
* Default set of sensitive key fragments (matched case-insensitively as
|
|
4
|
+
* substrings of an object key). Covers the secrets that leak through
|
|
5
|
+
* recorded requests, error causes, and trace payloads: auth headers, API
|
|
6
|
+
* keys, cookies, tokens, passwords, and private keys.
|
|
7
|
+
*/
|
|
8
|
+
const DEFAULT_SENSITIVE_KEYS = [
|
|
9
|
+
"authorization",
|
|
10
|
+
"x-api-key",
|
|
11
|
+
"api-key",
|
|
12
|
+
"apikey",
|
|
13
|
+
"cookie",
|
|
14
|
+
"set-cookie",
|
|
15
|
+
"password",
|
|
16
|
+
"passwd",
|
|
17
|
+
"secret",
|
|
18
|
+
"token",
|
|
19
|
+
"access_token",
|
|
20
|
+
"refresh_token",
|
|
21
|
+
"client_secret",
|
|
22
|
+
"private_key",
|
|
23
|
+
"session"
|
|
24
|
+
];
|
|
25
|
+
/** HTTP header names always stripped from a serialized error/cause. */
|
|
26
|
+
const SENSITIVE_HEADERS = [
|
|
27
|
+
"authorization",
|
|
28
|
+
"x-api-key",
|
|
29
|
+
"api-key",
|
|
30
|
+
"cookie",
|
|
31
|
+
"set-cookie",
|
|
32
|
+
"proxy-authorization"
|
|
33
|
+
];
|
|
34
|
+
const DEFAULT_PLACEHOLDER = "[redacted]";
|
|
35
|
+
const DEFAULT_MAX_DEPTH = 8;
|
|
36
|
+
function keyIsSensitive(key, fragments) {
|
|
37
|
+
const lower = key.toLowerCase();
|
|
38
|
+
return fragments.some((fragment) => lower.includes(fragment));
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Deep-copy `value` with any property whose KEY matches a sensitive
|
|
42
|
+
* fragment replaced by the placeholder. Arrays are walked element-wise;
|
|
43
|
+
* circular references and over-deep trees collapse to the placeholder.
|
|
44
|
+
* Primitives pass through untouched (redaction is key-driven, not
|
|
45
|
+
* value-driven — it never guesses at a bare string being a secret).
|
|
46
|
+
*
|
|
47
|
+
* Shared by VCR cassettes (S2), Panoptic content capture, and the error /
|
|
48
|
+
* cause serializer (S4) so there is ONE redaction policy, not three.
|
|
49
|
+
*/
|
|
50
|
+
function redact(value, options = {}) {
|
|
51
|
+
const fragments = [...DEFAULT_SENSITIVE_KEYS, ...options.keys ?? []].map((k) => k.toLowerCase());
|
|
52
|
+
const placeholder = options.placeholder ?? DEFAULT_PLACEHOLDER;
|
|
53
|
+
const maxDepth = options.maxDepth ?? DEFAULT_MAX_DEPTH;
|
|
54
|
+
const seen = /* @__PURE__ */ new WeakSet();
|
|
55
|
+
const walk = (input, depth) => {
|
|
56
|
+
if (input === null || typeof input !== "object") return input;
|
|
57
|
+
if (depth >= maxDepth || seen.has(input)) return placeholder;
|
|
58
|
+
seen.add(input);
|
|
59
|
+
if (Array.isArray(input)) return input.map((item) => walk(item, depth + 1));
|
|
60
|
+
const out = {};
|
|
61
|
+
for (const [key, val] of Object.entries(input)) out[key] = keyIsSensitive(key, fragments) ? placeholder : walk(val, depth + 1);
|
|
62
|
+
return out;
|
|
63
|
+
};
|
|
64
|
+
return walk(value, 0);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Strip sensitive HTTP headers from a `Headers` instance or a plain
|
|
68
|
+
* header record, returning a redacted plain object. Header names are
|
|
69
|
+
* matched case-insensitively against {@link SENSITIVE_HEADERS}.
|
|
70
|
+
*/
|
|
71
|
+
function redactHeaders(headers, placeholder = DEFAULT_PLACEHOLDER) {
|
|
72
|
+
if (!headers) return {};
|
|
73
|
+
const entries = headers instanceof Headers ? [...headers.entries()] : Object.entries(headers);
|
|
74
|
+
const out = {};
|
|
75
|
+
for (const [key, val] of entries) out[key] = SENSITIVE_HEADERS.includes(key.toLowerCase()) ? placeholder : val;
|
|
76
|
+
return out;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Patterns for secrets that hide in FREE TEXT (error messages, stack
|
|
80
|
+
* traces, log lines) where the key-based {@link redact} can't reach them.
|
|
81
|
+
* Each entry replaces the secret with `[redacted]` while keeping
|
|
82
|
+
* surrounding context.
|
|
83
|
+
*/
|
|
84
|
+
const SECRET_PATTERNS = [
|
|
85
|
+
[/\bBearer\s+[A-Za-z0-9._~+/-]+=*/gi, "Bearer [redacted]"],
|
|
86
|
+
[/\b(authorization|x-api-key|api[_-]?key|cookie)("?\s*[:=]\s*"?)[^\s",}]+/gi, "$1$2[redacted]"],
|
|
87
|
+
[/\bsk-[A-Za-z0-9]{16,}\b/g, "[redacted]"],
|
|
88
|
+
[/\bxox[baprs]-[A-Za-z0-9-]{8,}\b/g, "[redacted]"],
|
|
89
|
+
[/\bgh[pousr]_[A-Za-z0-9]{20,}\b/g, "[redacted]"],
|
|
90
|
+
[/\bAKIA[0-9A-Z]{16}\b/g, "[redacted]"]
|
|
91
|
+
];
|
|
92
|
+
/**
|
|
93
|
+
* Scrub secrets that appear in free-form text — error messages, stack
|
|
94
|
+
* traces, exported log lines. Complements {@link redact} (which is key-
|
|
95
|
+
* driven and can't see a token embedded in a string). Used by the trace /
|
|
96
|
+
* error serializer (S4) before a message or stack is stored or exported.
|
|
97
|
+
*/
|
|
98
|
+
function scrubSecrets(text) {
|
|
99
|
+
let out = text;
|
|
100
|
+
for (const [pattern, replacement] of SECRET_PATTERNS) out = out.replace(pattern, replacement);
|
|
101
|
+
return out;
|
|
102
|
+
}
|
|
103
|
+
function redactError(error, options = {}) {
|
|
104
|
+
const { includeStack, ...redactOptions } = options;
|
|
105
|
+
if (error === null || typeof error !== "object") return {
|
|
106
|
+
name: "Error",
|
|
107
|
+
message: String(error)
|
|
108
|
+
};
|
|
109
|
+
const err = error;
|
|
110
|
+
const result = {
|
|
111
|
+
name: typeof err.name === "string" ? err.name : "Error",
|
|
112
|
+
message: typeof err.message === "string" ? err.message : String(error)
|
|
113
|
+
};
|
|
114
|
+
if (typeof err.code === "string") result.code = err.code;
|
|
115
|
+
if (err.cause !== void 0) result.cause = err.cause !== null && typeof err.cause === "object" ? redact(err.cause, redactOptions) : err.cause;
|
|
116
|
+
if (includeStack && typeof err.stack === "string") result.stack = err.stack;
|
|
117
|
+
return result;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
//#endregion
|
|
121
|
+
export { DEFAULT_SENSITIVE_KEYS, SENSITIVE_HEADERS, redact, redactError, redactHeaders, scrubSecrets };
|
|
122
|
+
//# sourceMappingURL=redact.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redact.mjs","names":[],"sources":["../../../../../../../@warlock.js/ai/src/security/redact.ts"],"sourcesContent":["/**\n * Default set of sensitive key fragments (matched case-insensitively as\n * substrings of an object key). Covers the secrets that leak through\n * recorded requests, error causes, and trace payloads: auth headers, API\n * keys, cookies, tokens, passwords, and private keys.\n */\nexport const DEFAULT_SENSITIVE_KEYS: readonly string[] = [\n \"authorization\",\n \"x-api-key\",\n \"api-key\",\n \"apikey\",\n \"cookie\",\n \"set-cookie\",\n \"password\",\n \"passwd\",\n \"secret\",\n \"token\",\n \"access_token\",\n \"refresh_token\",\n \"client_secret\",\n \"private_key\",\n \"session\",\n];\n\n/** HTTP header names always stripped from a serialized error/cause. */\nexport const SENSITIVE_HEADERS: readonly string[] = [\n \"authorization\",\n \"x-api-key\",\n \"api-key\",\n \"cookie\",\n \"set-cookie\",\n \"proxy-authorization\",\n];\n\nexport type RedactOptions = {\n /** Extra key fragments to redact, merged with {@link DEFAULT_SENSITIVE_KEYS}. */\n keys?: string[];\n /** Replacement for a redacted value. Default `\"[redacted]\"`. */\n placeholder?: string;\n /** Maximum recursion depth before bailing out. Default `8`. */\n maxDepth?: number;\n};\n\nconst DEFAULT_PLACEHOLDER = \"[redacted]\";\nconst DEFAULT_MAX_DEPTH = 8;\n\nfunction keyIsSensitive(key: string, fragments: string[]): boolean {\n const lower = key.toLowerCase();\n return fragments.some(fragment => lower.includes(fragment));\n}\n\n/**\n * Deep-copy `value` with any property whose KEY matches a sensitive\n * fragment replaced by the placeholder. Arrays are walked element-wise;\n * circular references and over-deep trees collapse to the placeholder.\n * Primitives pass through untouched (redaction is key-driven, not\n * value-driven — it never guesses at a bare string being a secret).\n *\n * Shared by VCR cassettes (S2), Panoptic content capture, and the error /\n * cause serializer (S4) so there is ONE redaction policy, not three.\n */\nexport function redact<T>(value: T, options: RedactOptions = {}): T {\n const fragments = [...DEFAULT_SENSITIVE_KEYS, ...(options.keys ?? [])].map(k =>\n k.toLowerCase(),\n );\n const placeholder = options.placeholder ?? DEFAULT_PLACEHOLDER;\n const maxDepth = options.maxDepth ?? DEFAULT_MAX_DEPTH;\n const seen = new WeakSet<object>();\n\n const walk = (input: unknown, depth: number): unknown => {\n if (input === null || typeof input !== \"object\") {\n return input;\n }\n if (depth >= maxDepth || seen.has(input)) {\n return placeholder;\n }\n seen.add(input as object);\n\n if (Array.isArray(input)) {\n return input.map(item => walk(item, depth + 1));\n }\n\n const out: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(input as Record<string, unknown>)) {\n out[key] = keyIsSensitive(key, fragments)\n ? placeholder\n : walk(val, depth + 1);\n }\n return out;\n };\n\n return walk(value, 0) as T;\n}\n\n/**\n * Strip sensitive HTTP headers from a `Headers` instance or a plain\n * header record, returning a redacted plain object. Header names are\n * matched case-insensitively against {@link SENSITIVE_HEADERS}.\n */\nexport function redactHeaders(\n headers: Headers | Record<string, unknown> | undefined,\n placeholder: string = DEFAULT_PLACEHOLDER,\n): Record<string, unknown> {\n if (!headers) return {};\n\n const entries: Array<[string, unknown]> =\n headers instanceof Headers\n ? [...headers.entries()]\n : Object.entries(headers);\n\n const out: Record<string, unknown> = {};\n for (const [key, val] of entries) {\n out[key] = SENSITIVE_HEADERS.includes(key.toLowerCase()) ? placeholder : val;\n }\n return out;\n}\n\n/**\n * Patterns for secrets that hide in FREE TEXT (error messages, stack\n * traces, log lines) where the key-based {@link redact} can't reach them.\n * Each entry replaces the secret with `[redacted]` while keeping\n * surrounding context.\n */\nconst SECRET_PATTERNS: ReadonlyArray<readonly [RegExp, string]> = [\n [/\\bBearer\\s+[A-Za-z0-9._~+/-]+=*/gi, \"Bearer [redacted]\"],\n [/\\b(authorization|x-api-key|api[_-]?key|cookie)(\"?\\s*[:=]\\s*\"?)[^\\s\",}]+/gi, \"$1$2[redacted]\"],\n [/\\bsk-[A-Za-z0-9]{16,}\\b/g, \"[redacted]\"], // OpenAI-style keys\n [/\\bxox[baprs]-[A-Za-z0-9-]{8,}\\b/g, \"[redacted]\"], // Slack tokens\n [/\\bgh[pousr]_[A-Za-z0-9]{20,}\\b/g, \"[redacted]\"], // GitHub tokens\n [/\\bAKIA[0-9A-Z]{16}\\b/g, \"[redacted]\"], // AWS access key ids\n];\n\n/**\n * Scrub secrets that appear in free-form text — error messages, stack\n * traces, exported log lines. Complements {@link redact} (which is key-\n * driven and can't see a token embedded in a string). Used by the trace /\n * error serializer (S4) before a message or stack is stored or exported.\n */\nexport function scrubSecrets(text: string): string {\n let out = text;\n for (const [pattern, replacement] of SECRET_PATTERNS) {\n out = out.replace(pattern, replacement);\n }\n return out;\n}\n\n/**\n * Serialized, secret-free view of an error. `stack` is omitted by default\n * (it can embed local paths, endpoints, and tokens); pass\n * `includeStack: true` only for a trusted local sink. The retained\n * `cause` is deep-redacted via {@link redact}, so a raw provider SDK error\n * carrying `Authorization` / `x-api-key` on `cause.headers` is sanitized.\n */\nexport type RedactedError = {\n name: string;\n message: string;\n code?: string;\n cause?: unknown;\n stack?: string;\n};\n\nexport function redactError(\n error: unknown,\n options: { includeStack?: boolean } & RedactOptions = {},\n): RedactedError {\n const { includeStack, ...redactOptions } = options;\n\n if (error === null || typeof error !== \"object\") {\n return { name: \"Error\", message: String(error) };\n }\n\n const err = error as {\n name?: unknown;\n message?: unknown;\n code?: unknown;\n cause?: unknown;\n stack?: unknown;\n };\n\n const result: RedactedError = {\n name: typeof err.name === \"string\" ? err.name : \"Error\",\n message: typeof err.message === \"string\" ? err.message : String(error),\n };\n\n if (typeof err.code === \"string\") {\n result.code = err.code;\n }\n if (err.cause !== undefined) {\n result.cause =\n err.cause !== null && typeof err.cause === \"object\"\n ? redact(err.cause, redactOptions)\n : err.cause;\n }\n if (includeStack && typeof err.stack === \"string\") {\n result.stack = err.stack;\n }\n\n return result;\n}\n"],"mappings":";;;;;;;AAMA,MAAa,yBAA4C;CACvD;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;;AAGA,MAAa,oBAAuC;CAClD;CACA;CACA;CACA;CACA;CACA;AACF;AAWA,MAAM,sBAAsB;AAC5B,MAAM,oBAAoB;AAE1B,SAAS,eAAe,KAAa,WAA8B;CACjE,MAAM,QAAQ,IAAI,YAAY;CAC9B,OAAO,UAAU,MAAK,aAAY,MAAM,SAAS,QAAQ,CAAC;AAC5D;;;;;;;;;;;AAYA,SAAgB,OAAU,OAAU,UAAyB,CAAC,GAAM;CAClE,MAAM,YAAY,CAAC,GAAG,wBAAwB,GAAI,QAAQ,QAAQ,CAAC,CAAE,CAAC,CAAC,KAAI,MACzE,EAAE,YAAY,CAChB;CACA,MAAM,cAAc,QAAQ,eAAe;CAC3C,MAAM,WAAW,QAAQ,YAAY;CACrC,MAAM,uBAAO,IAAI,QAAgB;CAEjC,MAAM,QAAQ,OAAgB,UAA2B;EACvD,IAAI,UAAU,QAAQ,OAAO,UAAU,UACrC,OAAO;EAET,IAAI,SAAS,YAAY,KAAK,IAAI,KAAK,GACrC,OAAO;EAET,KAAK,IAAI,KAAe;EAExB,IAAI,MAAM,QAAQ,KAAK,GACrB,OAAO,MAAM,KAAI,SAAQ,KAAK,MAAM,QAAQ,CAAC,CAAC;EAGhD,MAAM,MAA+B,CAAC;EACtC,KAAK,MAAM,CAAC,KAAK,QAAQ,OAAO,QAAQ,KAAgC,GACtE,IAAI,OAAO,eAAe,KAAK,SAAS,IACpC,cACA,KAAK,KAAK,QAAQ,CAAC;EAEzB,OAAO;CACT;CAEA,OAAO,KAAK,OAAO,CAAC;AACtB;;;;;;AAOA,SAAgB,cACd,SACA,cAAsB,qBACG;CACzB,IAAI,CAAC,SAAS,OAAO,CAAC;CAEtB,MAAM,UACJ,mBAAmB,UACf,CAAC,GAAG,QAAQ,QAAQ,CAAC,IACrB,OAAO,QAAQ,OAAO;CAE5B,MAAM,MAA+B,CAAC;CACtC,KAAK,MAAM,CAAC,KAAK,QAAQ,SACvB,IAAI,OAAO,kBAAkB,SAAS,IAAI,YAAY,CAAC,IAAI,cAAc;CAE3E,OAAO;AACT;;;;;;;AAQA,MAAM,kBAA4D;CAChE,CAAC,qCAAqC,mBAAmB;CACzD,CAAC,6EAA6E,gBAAgB;CAC9F,CAAC,4BAA4B,YAAY;CACzC,CAAC,oCAAoC,YAAY;CACjD,CAAC,mCAAmC,YAAY;CAChD,CAAC,yBAAyB,YAAY;AACxC;;;;;;;AAQA,SAAgB,aAAa,MAAsB;CACjD,IAAI,MAAM;CACV,KAAK,MAAM,CAAC,SAAS,gBAAgB,iBACnC,MAAM,IAAI,QAAQ,SAAS,WAAW;CAExC,OAAO;AACT;AAiBA,SAAgB,YACd,OACA,UAAsD,CAAC,GACxC;CACf,MAAM,EAAE,cAAc,GAAG,kBAAkB;CAE3C,IAAI,UAAU,QAAQ,OAAO,UAAU,UACrC,OAAO;EAAE,MAAM;EAAS,SAAS,OAAO,KAAK;CAAE;CAGjD,MAAM,MAAM;CAQZ,MAAM,SAAwB;EAC5B,MAAM,OAAO,IAAI,SAAS,WAAW,IAAI,OAAO;EAChD,SAAS,OAAO,IAAI,YAAY,WAAW,IAAI,UAAU,OAAO,KAAK;CACvE;CAEA,IAAI,OAAO,IAAI,SAAS,UACtB,OAAO,OAAO,IAAI;CAEpB,IAAI,IAAI,UAAU,QAChB,OAAO,QACL,IAAI,UAAU,QAAQ,OAAO,IAAI,UAAU,WACvC,OAAO,IAAI,OAAO,aAAa,IAC/B,IAAI;CAEZ,IAAI,gBAAgB,OAAO,IAAI,UAAU,UACvC,OAAO,QAAQ,IAAI;CAGrB,OAAO;AACT"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { StreamLike } from "./stream-to-sse.mjs";
|
|
2
|
+
import { IncomingMessage, ServerResponse } from "node:http";
|
|
3
|
+
|
|
4
|
+
//#region ../@warlock.js/ai/src/serve/serve.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* Anything `serve` can expose: a primitive whose `stream(input, options)`
|
|
7
|
+
* returns a {@link StreamLike}. Agents, supervisors, and orchestrators all
|
|
8
|
+
* satisfy it.
|
|
9
|
+
*/
|
|
10
|
+
type ServableExecutable<TInput = unknown> = {
|
|
11
|
+
stream(input: TInput, options?: Record<string, unknown>): StreamLike<{
|
|
12
|
+
type: string;
|
|
13
|
+
}, unknown>;
|
|
14
|
+
};
|
|
15
|
+
/** Options for {@link serve}. */
|
|
16
|
+
type ServeOptions<TInput = unknown> = {
|
|
17
|
+
/**
|
|
18
|
+
* Bearer token required on every request. When set, a request must send
|
|
19
|
+
* `Authorization: Bearer <token>`, else `401` (S4-style auth, the same
|
|
20
|
+
* control the dashboard uses — fold this in for a production deploy).
|
|
21
|
+
*/
|
|
22
|
+
authToken?: string;
|
|
23
|
+
/**
|
|
24
|
+
* Map the parsed JSON request body to the executable's input. Default:
|
|
25
|
+
* `body.input`. Override to accept a different request shape.
|
|
26
|
+
*/
|
|
27
|
+
toInput?: (body: Record<string, unknown>) => TInput;
|
|
28
|
+
/**
|
|
29
|
+
* Map the parsed body to per-call stream options (e.g. an orchestrator
|
|
30
|
+
* `{ sessionId, history }` so a turn resumes the right session — A3
|
|
31
|
+
* wiring). Default: pass `sessionId` / `history` straight through.
|
|
32
|
+
*/
|
|
33
|
+
toOptions?: (body: Record<string, unknown>) => Record<string, unknown>;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Turn an executable into a `node:http` request handler that streams its
|
|
37
|
+
* run to the client as Server-Sent Events (A3) — the production-serving
|
|
38
|
+
* primitive. POST a JSON body (`{ input, sessionId?, history? }`); the
|
|
39
|
+
* response is an `text/event-stream` of the primitive's events, the final
|
|
40
|
+
* `result`, then `[DONE]`. Absorbs the auth-token control; pair with a
|
|
41
|
+
* `sessionLock` + an orchestrator for durable multi-turn serving.
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* import { createServer } from "node:http";
|
|
45
|
+
* createServer(ai.serve(myAgent, { authToken: process.env.TOKEN })).listen(8787);
|
|
46
|
+
*/
|
|
47
|
+
declare function serve<TInput = unknown>(executable: ServableExecutable<TInput>, options?: ServeOptions<TInput>): (req: IncomingMessage, res: ServerResponse) => void;
|
|
48
|
+
//#endregion
|
|
49
|
+
export { ServableExecutable, ServeOptions, serve };
|
|
50
|
+
//# sourceMappingURL=serve.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serve.d.mts","names":[],"sources":["../../../../../../../@warlock.js/ai/src/serve/serve.ts"],"mappings":";;;;;;AAQA;;;KAAY,kBAAA;EACV,MAAA,CAAO,KAAA,EAAO,MAAA,EAAQ,OAAA,GAAU,MAAA,oBAA0B,UAAA;IAAa,IAAA;EAAA;AAAA;;KAI7D,YAAA;EAJI;;;;;EAUd,SAAA;EAV2E;AAAA;AAI7E;;EAWE,OAAA,IAAW,IAAA,EAAM,MAAA,sBAA4B,MAAA;EAA5B;;;;;EAMjB,SAAA,IAAa,IAAA,EAAM,MAAA,sBAA4B,MAAA;AAAA;;;;;;;;;;;AAAM;AAqBvD;iBAAgB,KAAA,mBACd,UAAA,EAAY,kBAAA,CAAmB,MAAA,GAC/B,OAAA,GAAS,YAAA,CAAa,MAAA,KACpB,GAAA,EAAK,eAAA,EAAiB,GAAA,EAAK,cAAA"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { streamToSSE } from "./stream-to-sse.mjs";
|
|
2
|
+
|
|
3
|
+
//#region ../@warlock.js/ai/src/serve/serve.ts
|
|
4
|
+
const SECURITY_HEADERS = {
|
|
5
|
+
"x-content-type-options": "nosniff",
|
|
6
|
+
"x-frame-options": "DENY",
|
|
7
|
+
"referrer-policy": "no-referrer"
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Turn an executable into a `node:http` request handler that streams its
|
|
11
|
+
* run to the client as Server-Sent Events (A3) — the production-serving
|
|
12
|
+
* primitive. POST a JSON body (`{ input, sessionId?, history? }`); the
|
|
13
|
+
* response is an `text/event-stream` of the primitive's events, the final
|
|
14
|
+
* `result`, then `[DONE]`. Absorbs the auth-token control; pair with a
|
|
15
|
+
* `sessionLock` + an orchestrator for durable multi-turn serving.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* import { createServer } from "node:http";
|
|
19
|
+
* createServer(ai.serve(myAgent, { authToken: process.env.TOKEN })).listen(8787);
|
|
20
|
+
*/
|
|
21
|
+
function serve(executable, options = {}) {
|
|
22
|
+
const toInput = options.toInput ?? ((body) => body.input);
|
|
23
|
+
const toOptions = options.toOptions ?? ((body) => {
|
|
24
|
+
const opts = {};
|
|
25
|
+
if (body.sessionId !== void 0) opts.sessionId = body.sessionId;
|
|
26
|
+
if (body.history !== void 0) opts.history = body.history;
|
|
27
|
+
return opts;
|
|
28
|
+
});
|
|
29
|
+
return function handle(req, res) {
|
|
30
|
+
(async () => {
|
|
31
|
+
if (req.method !== "POST") {
|
|
32
|
+
sendJson(res, 405, { error: "method_not_allowed" });
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
if (options.authToken && req.headers.authorization !== `Bearer ${options.authToken}`) {
|
|
36
|
+
sendJson(res, 401, { error: "unauthorized" });
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
let body;
|
|
40
|
+
try {
|
|
41
|
+
body = await readJsonBody(req);
|
|
42
|
+
} catch {
|
|
43
|
+
sendJson(res, 400, { error: "invalid_json" });
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
res.writeHead(200, {
|
|
47
|
+
"content-type": "text/event-stream; charset=utf-8",
|
|
48
|
+
"cache-control": "no-cache",
|
|
49
|
+
connection: "keep-alive",
|
|
50
|
+
...SECURITY_HEADERS
|
|
51
|
+
});
|
|
52
|
+
try {
|
|
53
|
+
const stream = executable.stream(toInput(body), toOptions(body));
|
|
54
|
+
for await (const frame of streamToSSE(stream)) res.write(frame);
|
|
55
|
+
} catch (error) {
|
|
56
|
+
res.write(`event: error\ndata: ${JSON.stringify({ message: error instanceof Error ? error.message : String(error) })}\n\n`);
|
|
57
|
+
} finally {
|
|
58
|
+
res.end();
|
|
59
|
+
}
|
|
60
|
+
})();
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
/** Read and JSON-parse a request body. */
|
|
64
|
+
function readJsonBody(req) {
|
|
65
|
+
return new Promise((resolve, reject) => {
|
|
66
|
+
let raw = "";
|
|
67
|
+
req.on("data", (chunk) => {
|
|
68
|
+
raw += chunk.toString();
|
|
69
|
+
});
|
|
70
|
+
req.on("end", () => {
|
|
71
|
+
try {
|
|
72
|
+
resolve(raw ? JSON.parse(raw) : {});
|
|
73
|
+
} catch (error) {
|
|
74
|
+
reject(error);
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
req.on("error", reject);
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
function sendJson(res, status, body) {
|
|
81
|
+
res.writeHead(status, {
|
|
82
|
+
"content-type": "application/json; charset=utf-8",
|
|
83
|
+
...SECURITY_HEADERS
|
|
84
|
+
});
|
|
85
|
+
res.end(JSON.stringify(body));
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
//#endregion
|
|
89
|
+
export { serve };
|
|
90
|
+
//# sourceMappingURL=serve.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serve.mjs","names":[],"sources":["../../../../../../../@warlock.js/ai/src/serve/serve.ts"],"sourcesContent":["import type { IncomingMessage, ServerResponse } from \"node:http\";\nimport { streamToSSE, type StreamLike } from \"./stream-to-sse\";\n\n/**\n * Anything `serve` can expose: a primitive whose `stream(input, options)`\n * returns a {@link StreamLike}. Agents, supervisors, and orchestrators all\n * satisfy it.\n */\nexport type ServableExecutable<TInput = unknown> = {\n stream(input: TInput, options?: Record<string, unknown>): StreamLike<{ type: string }, unknown>;\n};\n\n/** Options for {@link serve}. */\nexport type ServeOptions<TInput = unknown> = {\n /**\n * Bearer token required on every request. When set, a request must send\n * `Authorization: Bearer <token>`, else `401` (S4-style auth, the same\n * control the dashboard uses — fold this in for a production deploy).\n */\n authToken?: string;\n /**\n * Map the parsed JSON request body to the executable's input. Default:\n * `body.input`. Override to accept a different request shape.\n */\n toInput?: (body: Record<string, unknown>) => TInput;\n /**\n * Map the parsed body to per-call stream options (e.g. an orchestrator\n * `{ sessionId, history }` so a turn resumes the right session — A3\n * wiring). Default: pass `sessionId` / `history` straight through.\n */\n toOptions?: (body: Record<string, unknown>) => Record<string, unknown>;\n};\n\nconst SECURITY_HEADERS: Record<string, string> = {\n \"x-content-type-options\": \"nosniff\",\n \"x-frame-options\": \"DENY\",\n \"referrer-policy\": \"no-referrer\",\n};\n\n/**\n * Turn an executable into a `node:http` request handler that streams its\n * run to the client as Server-Sent Events (A3) — the production-serving\n * primitive. POST a JSON body (`{ input, sessionId?, history? }`); the\n * response is an `text/event-stream` of the primitive's events, the final\n * `result`, then `[DONE]`. Absorbs the auth-token control; pair with a\n * `sessionLock` + an orchestrator for durable multi-turn serving.\n *\n * @example\n * import { createServer } from \"node:http\";\n * createServer(ai.serve(myAgent, { authToken: process.env.TOKEN })).listen(8787);\n */\nexport function serve<TInput = unknown>(\n executable: ServableExecutable<TInput>,\n options: ServeOptions<TInput> = {},\n): (req: IncomingMessage, res: ServerResponse) => void {\n const toInput = options.toInput ?? ((body) => body.input as TInput);\n const toOptions =\n options.toOptions ??\n ((body) => {\n const opts: Record<string, unknown> = {};\n if (body.sessionId !== undefined) opts.sessionId = body.sessionId;\n if (body.history !== undefined) opts.history = body.history;\n return opts;\n });\n\n return function handle(req: IncomingMessage, res: ServerResponse): void {\n void (async () => {\n if (req.method !== \"POST\") {\n sendJson(res, 405, { error: \"method_not_allowed\" });\n return;\n }\n\n if (options.authToken && req.headers.authorization !== `Bearer ${options.authToken}`) {\n sendJson(res, 401, { error: \"unauthorized\" });\n return;\n }\n\n let body: Record<string, unknown>;\n try {\n body = await readJsonBody(req);\n } catch {\n sendJson(res, 400, { error: \"invalid_json\" });\n return;\n }\n\n res.writeHead(200, {\n \"content-type\": \"text/event-stream; charset=utf-8\",\n \"cache-control\": \"no-cache\",\n connection: \"keep-alive\",\n ...SECURITY_HEADERS,\n });\n\n try {\n const stream = executable.stream(toInput(body), toOptions(body));\n for await (const frame of streamToSSE(stream)) {\n res.write(frame);\n }\n } catch (error) {\n res.write(\n `event: error\\ndata: ${JSON.stringify({\n message: error instanceof Error ? error.message : String(error),\n })}\\n\\n`,\n );\n } finally {\n res.end();\n }\n })();\n };\n}\n\n/** Read and JSON-parse a request body. */\nfunction readJsonBody(req: IncomingMessage): Promise<Record<string, unknown>> {\n return new Promise((resolve, reject) => {\n let raw = \"\";\n req.on(\"data\", (chunk: Buffer | string) => {\n raw += chunk.toString();\n });\n req.on(\"end\", () => {\n try {\n resolve(raw ? (JSON.parse(raw) as Record<string, unknown>) : {});\n } catch (error) {\n reject(error);\n }\n });\n req.on(\"error\", reject);\n });\n}\n\nfunction sendJson(res: ServerResponse, status: number, body: unknown): void {\n res.writeHead(status, { \"content-type\": \"application/json; charset=utf-8\", ...SECURITY_HEADERS });\n res.end(JSON.stringify(body));\n}\n"],"mappings":";;;AAiCA,MAAM,mBAA2C;CAC/C,0BAA0B;CAC1B,mBAAmB;CACnB,mBAAmB;AACrB;;;;;;;;;;;;;AAcA,SAAgB,MACd,YACA,UAAgC,CAAC,GACoB;CACrD,MAAM,UAAU,QAAQ,aAAa,SAAS,KAAK;CACnD,MAAM,YACJ,QAAQ,eACN,SAAS;EACT,MAAM,OAAgC,CAAC;EACvC,IAAI,KAAK,cAAc,QAAW,KAAK,YAAY,KAAK;EACxD,IAAI,KAAK,YAAY,QAAW,KAAK,UAAU,KAAK;EACpD,OAAO;CACT;CAEF,OAAO,SAAS,OAAO,KAAsB,KAA2B;EACtE,CAAM,YAAY;GAChB,IAAI,IAAI,WAAW,QAAQ;IACzB,SAAS,KAAK,KAAK,EAAE,OAAO,qBAAqB,CAAC;IAClD;GACF;GAEA,IAAI,QAAQ,aAAa,IAAI,QAAQ,kBAAkB,UAAU,QAAQ,aAAa;IACpF,SAAS,KAAK,KAAK,EAAE,OAAO,eAAe,CAAC;IAC5C;GACF;GAEA,IAAI;GACJ,IAAI;IACF,OAAO,MAAM,aAAa,GAAG;GAC/B,QAAQ;IACN,SAAS,KAAK,KAAK,EAAE,OAAO,eAAe,CAAC;IAC5C;GACF;GAEA,IAAI,UAAU,KAAK;IACjB,gBAAgB;IAChB,iBAAiB;IACjB,YAAY;IACZ,GAAG;GACL,CAAC;GAED,IAAI;IACF,MAAM,SAAS,WAAW,OAAO,QAAQ,IAAI,GAAG,UAAU,IAAI,CAAC;IAC/D,WAAW,MAAM,SAAS,YAAY,MAAM,GAC1C,IAAI,MAAM,KAAK;GAEnB,SAAS,OAAO;IACd,IAAI,MACF,uBAAuB,KAAK,UAAU,EACpC,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,EAChE,CAAC,EAAE,KACL;GACF,UAAU;IACR,IAAI,IAAI;GACV;EACF,EAAC,CAAE;CACL;AACF;;AAGA,SAAS,aAAa,KAAwD;CAC5E,OAAO,IAAI,SAAS,SAAS,WAAW;EACtC,IAAI,MAAM;EACV,IAAI,GAAG,SAAS,UAA2B;GACzC,OAAO,MAAM,SAAS;EACxB,CAAC;EACD,IAAI,GAAG,aAAa;GAClB,IAAI;IACF,QAAQ,MAAO,KAAK,MAAM,GAAG,IAAgC,CAAC,CAAC;GACjE,SAAS,OAAO;IACd,OAAO,KAAK;GACd;EACF,CAAC;EACD,IAAI,GAAG,SAAS,MAAM;CACxB,CAAC;AACH;AAEA,SAAS,SAAS,KAAqB,QAAgB,MAAqB;CAC1E,IAAI,UAAU,QAAQ;EAAE,gBAAgB;EAAmC,GAAG;CAAiB,CAAC;CAChG,IAAI,IAAI,KAAK,UAAU,IAAI,CAAC;AAC9B"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
//#region ../@warlock.js/ai/src/serve/sse.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Encode one Server-Sent-Events frame. Multi-line `data` is split into
|
|
4
|
+
* multiple `data:` lines per the SSE spec, so JSON with embedded newlines
|
|
5
|
+
* still parses on the client.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* encodeSSE({ event: "agent.trip.streaming", data: { delta: "Hi" } });
|
|
9
|
+
* // "event: agent.trip.streaming\ndata: {\"delta\":\"Hi\"}\n\n"
|
|
10
|
+
*/
|
|
11
|
+
declare function encodeSSE(frame: {
|
|
12
|
+
event?: string;
|
|
13
|
+
data: unknown;
|
|
14
|
+
id?: string;
|
|
15
|
+
}): string;
|
|
16
|
+
/** The terminal SSE frame a client watches for to stop reading. */
|
|
17
|
+
declare const SSE_DONE = "data: [DONE]\n\n";
|
|
18
|
+
//#endregion
|
|
19
|
+
export { SSE_DONE, encodeSSE };
|
|
20
|
+
//# sourceMappingURL=sse.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sse.d.mts","names":[],"sources":["../../../../../../../@warlock.js/ai/src/serve/sse.ts"],"mappings":";;AASA;;;;;;;;iBAAgB,SAAA,CAAU,KAAA;EAAS,KAAA;EAAgB,IAAA;EAAe,EAAA;AAAA;;cAgBrD,QAAA"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
//#region ../@warlock.js/ai/src/serve/sse.ts
|
|
2
|
+
/**
|
|
3
|
+
* Encode one Server-Sent-Events frame. Multi-line `data` is split into
|
|
4
|
+
* multiple `data:` lines per the SSE spec, so JSON with embedded newlines
|
|
5
|
+
* still parses on the client.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* encodeSSE({ event: "agent.trip.streaming", data: { delta: "Hi" } });
|
|
9
|
+
* // "event: agent.trip.streaming\ndata: {\"delta\":\"Hi\"}\n\n"
|
|
10
|
+
*/
|
|
11
|
+
function encodeSSE(frame) {
|
|
12
|
+
let out = "";
|
|
13
|
+
if (frame.id) out += `id: ${frame.id}\n`;
|
|
14
|
+
if (frame.event) out += `event: ${frame.event}\n`;
|
|
15
|
+
const data = typeof frame.data === "string" ? frame.data : JSON.stringify(frame.data);
|
|
16
|
+
for (const line of data.split("\n")) out += `data: ${line}\n`;
|
|
17
|
+
out += "\n";
|
|
18
|
+
return out;
|
|
19
|
+
}
|
|
20
|
+
/** The terminal SSE frame a client watches for to stop reading. */
|
|
21
|
+
const SSE_DONE = "data: [DONE]\n\n";
|
|
22
|
+
|
|
23
|
+
//#endregion
|
|
24
|
+
export { SSE_DONE, encodeSSE };
|
|
25
|
+
//# sourceMappingURL=sse.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sse.mjs","names":[],"sources":["../../../../../../../@warlock.js/ai/src/serve/sse.ts"],"sourcesContent":["/**\n * Encode one Server-Sent-Events frame. Multi-line `data` is split into\n * multiple `data:` lines per the SSE spec, so JSON with embedded newlines\n * still parses on the client.\n *\n * @example\n * encodeSSE({ event: \"agent.trip.streaming\", data: { delta: \"Hi\" } });\n * // \"event: agent.trip.streaming\\ndata: {\\\"delta\\\":\\\"Hi\\\"}\\n\\n\"\n */\nexport function encodeSSE(frame: { event?: string; data: unknown; id?: string }): string {\n let out = \"\";\n if (frame.id) out += `id: ${frame.id}\\n`;\n if (frame.event) out += `event: ${frame.event}\\n`;\n\n const data =\n typeof frame.data === \"string\" ? frame.data : JSON.stringify(frame.data);\n for (const line of data.split(\"\\n\")) {\n out += `data: ${line}\\n`;\n }\n\n out += \"\\n\";\n return out;\n}\n\n/** The terminal SSE frame a client watches for to stop reading. */\nexport const SSE_DONE = \"data: [DONE]\\n\\n\";\n"],"mappings":";;;;;;;;;;AASA,SAAgB,UAAU,OAA+D;CACvF,IAAI,MAAM;CACV,IAAI,MAAM,IAAI,OAAO,OAAO,MAAM,GAAG;CACrC,IAAI,MAAM,OAAO,OAAO,UAAU,MAAM,MAAM;CAE9C,MAAM,OACJ,OAAO,MAAM,SAAS,WAAW,MAAM,OAAO,KAAK,UAAU,MAAM,IAAI;CACzE,KAAK,MAAM,QAAQ,KAAK,MAAM,IAAI,GAChC,OAAO,SAAS,KAAK;CAGvB,OAAO;CACP,OAAO;AACT;;AAGA,MAAa,WAAW"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
//#region ../@warlock.js/ai/src/serve/stream-to-sse.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* A streamable execution: an async iterable of typed events that also
|
|
4
|
+
* exposes the final `result` promise — exactly the shape every primitive's
|
|
5
|
+
* `stream()` returns ({@link StreamContract}).
|
|
6
|
+
*/
|
|
7
|
+
type StreamLike<TEvent extends {
|
|
8
|
+
type: string;
|
|
9
|
+
}, TResult> = AsyncIterable<TEvent> & {
|
|
10
|
+
result?: Promise<TResult>;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Convert a primitive's event stream into an SSE byte stream (A3): each
|
|
14
|
+
* event becomes an SSE frame named by its `type`, then the final `result`
|
|
15
|
+
* (or an `error` frame if it rejects) is emitted, and finally the
|
|
16
|
+
* `[DONE]` sentinel. Pure and transport-agnostic — {@link serve} pipes it
|
|
17
|
+
* to an HTTP response, but it works against any sink.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* for await (const frame of streamToSSE(agent.stream("hi"))) {
|
|
21
|
+
* res.write(frame);
|
|
22
|
+
* }
|
|
23
|
+
*/
|
|
24
|
+
declare function streamToSSE<TEvent extends {
|
|
25
|
+
type: string;
|
|
26
|
+
}, TResult>(stream: StreamLike<TEvent, TResult>): AsyncIterable<string>;
|
|
27
|
+
//#endregion
|
|
28
|
+
export { StreamLike, streamToSSE };
|
|
29
|
+
//# sourceMappingURL=stream-to-sse.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream-to-sse.d.mts","names":[],"sources":["../../../../../../../@warlock.js/ai/src/serve/stream-to-sse.ts"],"mappings":";;AAOA;;;;KAAY,UAAA;EAA4B,IAAA;AAAA,cACtC,aAAA,CAAc,MAAA;EAAY,MAAA,GAAS,OAAA,CAAQ,OAAA;AAAA;;;;;;;;;;AAAO;AAcpD;;iBAAuB,WAAA;EAA6B,IAAA;AAAA,YAClD,MAAA,EAAQ,UAAA,CAAW,MAAA,EAAQ,OAAA,IAC1B,aAAA"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { SSE_DONE, encodeSSE } from "./sse.mjs";
|
|
2
|
+
|
|
3
|
+
//#region ../@warlock.js/ai/src/serve/stream-to-sse.ts
|
|
4
|
+
/**
|
|
5
|
+
* Convert a primitive's event stream into an SSE byte stream (A3): each
|
|
6
|
+
* event becomes an SSE frame named by its `type`, then the final `result`
|
|
7
|
+
* (or an `error` frame if it rejects) is emitted, and finally the
|
|
8
|
+
* `[DONE]` sentinel. Pure and transport-agnostic — {@link serve} pipes it
|
|
9
|
+
* to an HTTP response, but it works against any sink.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* for await (const frame of streamToSSE(agent.stream("hi"))) {
|
|
13
|
+
* res.write(frame);
|
|
14
|
+
* }
|
|
15
|
+
*/
|
|
16
|
+
async function* streamToSSE(stream) {
|
|
17
|
+
for await (const event of stream) yield encodeSSE({
|
|
18
|
+
event: event.type,
|
|
19
|
+
data: event
|
|
20
|
+
});
|
|
21
|
+
if (stream.result) try {
|
|
22
|
+
yield encodeSSE({
|
|
23
|
+
event: "result",
|
|
24
|
+
data: await stream.result
|
|
25
|
+
});
|
|
26
|
+
} catch (error) {
|
|
27
|
+
yield encodeSSE({
|
|
28
|
+
event: "error",
|
|
29
|
+
data: { message: error instanceof Error ? error.message : String(error) }
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
yield SSE_DONE;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
//#endregion
|
|
36
|
+
export { streamToSSE };
|
|
37
|
+
//# sourceMappingURL=stream-to-sse.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream-to-sse.mjs","names":[],"sources":["../../../../../../../@warlock.js/ai/src/serve/stream-to-sse.ts"],"sourcesContent":["import { encodeSSE, SSE_DONE } from \"./sse\";\n\n/**\n * A streamable execution: an async iterable of typed events that also\n * exposes the final `result` promise — exactly the shape every primitive's\n * `stream()` returns ({@link StreamContract}).\n */\nexport type StreamLike<TEvent extends { type: string }, TResult> =\n AsyncIterable<TEvent> & { result?: Promise<TResult> };\n\n/**\n * Convert a primitive's event stream into an SSE byte stream (A3): each\n * event becomes an SSE frame named by its `type`, then the final `result`\n * (or an `error` frame if it rejects) is emitted, and finally the\n * `[DONE]` sentinel. Pure and transport-agnostic — {@link serve} pipes it\n * to an HTTP response, but it works against any sink.\n *\n * @example\n * for await (const frame of streamToSSE(agent.stream(\"hi\"))) {\n * res.write(frame);\n * }\n */\nexport async function* streamToSSE<TEvent extends { type: string }, TResult>(\n stream: StreamLike<TEvent, TResult>,\n): AsyncIterable<string> {\n for await (const event of stream) {\n yield encodeSSE({ event: event.type, data: event });\n }\n\n if (stream.result) {\n try {\n const result = await stream.result;\n yield encodeSSE({ event: \"result\", data: result });\n } catch (error) {\n yield encodeSSE({\n event: \"error\",\n data: { message: error instanceof Error ? error.message : String(error) },\n });\n }\n }\n\n yield SSE_DONE;\n}\n"],"mappings":";;;;;;;;;;;;;;;AAsBA,gBAAuB,YACrB,QACuB;CACvB,WAAW,MAAM,SAAS,QACxB,MAAM,UAAU;EAAE,OAAO,MAAM;EAAM,MAAM;CAAM,CAAC;CAGpD,IAAI,OAAO,QACT,IAAI;EAEF,MAAM,UAAU;GAAE,OAAO;GAAU,MAAM,MADpB,OAAO;EACoB,CAAC;CACnD,SAAS,OAAO;EACd,MAAM,UAAU;GACd,OAAO;GACP,MAAM,EAAE,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,EAAE;EAC1E,CAAC;CACH;CAGF,MAAM;AACR"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { EmbedderContract } from "../contracts/embedder.contract.mjs";
|
|
2
|
+
import { SkillCatalogEntry, SkillRecord } from "./contracts/skill-record.type.mjs";
|
|
3
|
+
import { SkillsStoreContract } from "./contracts/skills-store.contract.mjs";
|
|
4
|
+
|
|
5
|
+
//#region ../@warlock.js/ai/src/skills/catalog.d.ts
|
|
6
|
+
/**
|
|
7
|
+
* Merge every source's `list()` into one de-duplicated catalog. Sources
|
|
8
|
+
* are merged in order; a LATER source wins on a name collision (explicit,
|
|
9
|
+
* documented precedence). Candidates are already filtered by each store's
|
|
10
|
+
* `list()`, so the merged catalog never carries an inert candidate.
|
|
11
|
+
*/
|
|
12
|
+
declare function buildCatalog(stores: SkillsStoreContract[], scope?: {
|
|
13
|
+
tags?: string[];
|
|
14
|
+
}): Promise<SkillCatalogEntry[]>;
|
|
15
|
+
/**
|
|
16
|
+
* Render the catalog as one line per skill — `name`, `version`,
|
|
17
|
+
* `description` — matching the projection `scripts/generate-llms.mjs`
|
|
18
|
+
* emits for `llms.txt` so the runtime catalog and the docs index read
|
|
19
|
+
* identically. Returns an empty string when no skills are in scope so the
|
|
20
|
+
* agent prepends nothing.
|
|
21
|
+
*/
|
|
22
|
+
declare function renderCatalogPrompt(name: string, entries: SkillCatalogEntry[]): string;
|
|
23
|
+
/**
|
|
24
|
+
* Load the full record for `name` across the merged sources, honoring the
|
|
25
|
+
* later-source-wins precedence: the FIRST store (iterating in reverse) to
|
|
26
|
+
* return a hit owns the name. A pinned `version` narrows the lookup.
|
|
27
|
+
* Returns `undefined` when no source has the skill.
|
|
28
|
+
*/
|
|
29
|
+
declare function loadRecord(stores: SkillsStoreContract[], name: string, version?: number): Promise<SkillRecord | undefined>;
|
|
30
|
+
/**
|
|
31
|
+
* Rank the in-scope catalog by cosine similarity to `input` and return the
|
|
32
|
+
* full `SkillRecord`s for the top `topK` clearing `threshold`.
|
|
33
|
+
*
|
|
34
|
+
* Embeds `input` and every catalog `description` via the resolved
|
|
35
|
+
* embedder (explicit `inject.embedder`, else the lazy provider), scores by
|
|
36
|
+
* cosine similarity, sorts descending, applies the optional floor, slices
|
|
37
|
+
* to `topK`, then loads those bodies. The embedder is the only optional
|
|
38
|
+
* dependency this whole feature carries.
|
|
39
|
+
*/
|
|
40
|
+
declare function semanticPreselect(stores: SkillsStoreContract[], input: string, topK: number, options?: {
|
|
41
|
+
embedder?: EmbedderContract;
|
|
42
|
+
threshold?: number;
|
|
43
|
+
scope?: {
|
|
44
|
+
tags?: string[];
|
|
45
|
+
};
|
|
46
|
+
}): Promise<SkillRecord[]>;
|
|
47
|
+
//#endregion
|
|
48
|
+
export { buildCatalog, loadRecord, renderCatalogPrompt, semanticPreselect };
|
|
49
|
+
//# sourceMappingURL=catalog.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"catalog.d.mts","names":[],"sources":["../../../../../../../@warlock.js/ai/src/skills/catalog.ts"],"mappings":";;;;;;;AA+FA;;;;iBAAsB,YAAA,CACpB,MAAA,EAAQ,mBAAA,IACR,KAAA;EAAU,IAAA;AAAA,IACT,OAAA,CAAQ,iBAAA;;;;;;;;iBAqBK,mBAAA,CAAoB,IAAA,UAAc,OAAA,EAAS,iBAAiB;AArBhD;AAqB5B;;;;;AArB4B,iBA6CN,UAAA,CACpB,MAAA,EAAQ,mBAAA,IACR,IAAA,UACA,OAAA,YACC,OAAA,CAAQ,WAAA;;;AA5BmE;AAwB9E;;;;;;;iBA0BsB,iBAAA,CACpB,MAAA,EAAQ,mBAAA,IACR,KAAA,UACA,IAAA,UACA,OAAA;EAAW,QAAA,GAAW,gBAAA;EAAkB,SAAA;EAAoB,KAAA;IAAU,IAAA;EAAA;AAAA,IACrE,OAAA,CAAQ,WAAA"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
//#region ../@warlock.js/ai/src/skills/catalog.ts
|
|
2
|
+
let isEmbedderPeerInstalled = null;
|
|
3
|
+
let loadingPromise;
|
|
4
|
+
const EMBEDDER_INSTALL_INSTRUCTIONS = `
|
|
5
|
+
Semantic skill pre-injection ({ inject: { select: "semantic" } }) needs an
|
|
6
|
+
embedder. Pass one explicitly (reuse the one you built for ai.memory()):
|
|
7
|
+
|
|
8
|
+
skills({ inject: { select: "semantic", topK: 2, embedder } })
|
|
9
|
+
|
|
10
|
+
or install an embedder provider:
|
|
11
|
+
|
|
12
|
+
npm install @warlock.js/ai-openai
|
|
13
|
+
|
|
14
|
+
Or with your preferred package manager:
|
|
15
|
+
|
|
16
|
+
pnpm add @warlock.js/ai-openai
|
|
17
|
+
yarn add @warlock.js/ai-openai
|
|
18
|
+
|
|
19
|
+
Then build one with \`new OpenAIEmbedder(client, { name: "text-embedding-3-small" })\`
|
|
20
|
+
and pass it via \`inject.embedder\`.
|
|
21
|
+
`.trim();
|
|
22
|
+
/**
|
|
23
|
+
* Probe for an installed embedder provider once, concurrency-safe. A bare
|
|
24
|
+
* `catch` flips the flag to `false`; the curated install string surfaces
|
|
25
|
+
* at use time. The provider's embedder needs a constructed SDK client, so
|
|
26
|
+
* we cannot auto-build one — the probe only decides whether the curated
|
|
27
|
+
* message should mention installing the package vs. just passing one in.
|
|
28
|
+
*/
|
|
29
|
+
function probeEmbedderPeer() {
|
|
30
|
+
if (isEmbedderPeerInstalled !== null) return Promise.resolve();
|
|
31
|
+
if (loadingPromise) return loadingPromise;
|
|
32
|
+
loadingPromise = (async () => {
|
|
33
|
+
try {
|
|
34
|
+
await import("../ai-openai/src/index.mjs");
|
|
35
|
+
isEmbedderPeerInstalled = true;
|
|
36
|
+
} catch {
|
|
37
|
+
isEmbedderPeerInstalled = false;
|
|
38
|
+
}
|
|
39
|
+
})();
|
|
40
|
+
return loadingPromise;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Resolve the embedder for semantic selection. The explicit
|
|
44
|
+
* `inject.embedder` always wins. With none supplied, the lazy probe runs
|
|
45
|
+
* and the curated install string is thrown at use time — a provider's
|
|
46
|
+
* embedder requires a constructed client, so there is no safe auto-build.
|
|
47
|
+
*/
|
|
48
|
+
async function resolveEmbedder(explicit) {
|
|
49
|
+
if (explicit) return explicit;
|
|
50
|
+
probeEmbedderPeer();
|
|
51
|
+
throw new Error(EMBEDDER_INSTALL_INSTRUCTIONS);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Merge every source's `list()` into one de-duplicated catalog. Sources
|
|
55
|
+
* are merged in order; a LATER source wins on a name collision (explicit,
|
|
56
|
+
* documented precedence). Candidates are already filtered by each store's
|
|
57
|
+
* `list()`, so the merged catalog never carries an inert candidate.
|
|
58
|
+
*/
|
|
59
|
+
async function buildCatalog(stores, scope) {
|
|
60
|
+
const merged = /* @__PURE__ */ new Map();
|
|
61
|
+
for (const store of stores) {
|
|
62
|
+
const entries = await store.list(scope);
|
|
63
|
+
for (const entry of entries) merged.set(entry.name, entry);
|
|
64
|
+
}
|
|
65
|
+
return [...merged.values()];
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Render the catalog as one line per skill — `name`, `version`,
|
|
69
|
+
* `description` — matching the projection `scripts/generate-llms.mjs`
|
|
70
|
+
* emits for `llms.txt` so the runtime catalog and the docs index read
|
|
71
|
+
* identically. Returns an empty string when no skills are in scope so the
|
|
72
|
+
* agent prepends nothing.
|
|
73
|
+
*/
|
|
74
|
+
function renderCatalogPrompt(name, entries) {
|
|
75
|
+
if (entries.length === 0) return "";
|
|
76
|
+
const lines = entries.map((entry) => `- ${entry.name} (v${entry.version}): ${entry.description}`);
|
|
77
|
+
return [
|
|
78
|
+
`# Available skills — "${name}"`,
|
|
79
|
+
"",
|
|
80
|
+
"You can load any of the following skills on demand with the `loadSkill` tool to pull its full instructions into context:",
|
|
81
|
+
"",
|
|
82
|
+
...lines
|
|
83
|
+
].join("\n");
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Load the full record for `name` across the merged sources, honoring the
|
|
87
|
+
* later-source-wins precedence: the FIRST store (iterating in reverse) to
|
|
88
|
+
* return a hit owns the name. A pinned `version` narrows the lookup.
|
|
89
|
+
* Returns `undefined` when no source has the skill.
|
|
90
|
+
*/
|
|
91
|
+
async function loadRecord(stores, name, version) {
|
|
92
|
+
for (let index = stores.length - 1; index >= 0; index--) {
|
|
93
|
+
const record = await stores[index].load(name, version);
|
|
94
|
+
if (record) return record;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Rank the in-scope catalog by cosine similarity to `input` and return the
|
|
99
|
+
* full `SkillRecord`s for the top `topK` clearing `threshold`.
|
|
100
|
+
*
|
|
101
|
+
* Embeds `input` and every catalog `description` via the resolved
|
|
102
|
+
* embedder (explicit `inject.embedder`, else the lazy provider), scores by
|
|
103
|
+
* cosine similarity, sorts descending, applies the optional floor, slices
|
|
104
|
+
* to `topK`, then loads those bodies. The embedder is the only optional
|
|
105
|
+
* dependency this whole feature carries.
|
|
106
|
+
*/
|
|
107
|
+
async function semanticPreselect(stores, input, topK, options = {}) {
|
|
108
|
+
const catalog = await buildCatalog(stores, options.scope);
|
|
109
|
+
if (catalog.length === 0 || topK <= 0) return [];
|
|
110
|
+
const { vectors } = await (await resolveEmbedder(options.embedder)).embedMany([input, ...catalog.map((entry) => entry.description)]);
|
|
111
|
+
const inputVector = vectors[0];
|
|
112
|
+
const threshold = options.threshold ?? 0;
|
|
113
|
+
const scored = catalog.map((entry, index) => ({
|
|
114
|
+
entry,
|
|
115
|
+
score: cosineSimilarity(inputVector, vectors[index + 1])
|
|
116
|
+
})).filter((candidate) => candidate.score >= threshold).sort((first, second) => second.score - first.score).slice(0, topK);
|
|
117
|
+
const records = [];
|
|
118
|
+
for (const candidate of scored) {
|
|
119
|
+
const record = await loadRecord(stores, candidate.entry.name, candidate.entry.version);
|
|
120
|
+
if (record) records.push(record);
|
|
121
|
+
}
|
|
122
|
+
return records;
|
|
123
|
+
}
|
|
124
|
+
/** Cosine similarity of two equal-length vectors; `0` when either is degenerate. */
|
|
125
|
+
function cosineSimilarity(a, b) {
|
|
126
|
+
let dot = 0;
|
|
127
|
+
let normA = 0;
|
|
128
|
+
let normB = 0;
|
|
129
|
+
for (let index = 0; index < a.length; index++) {
|
|
130
|
+
dot += a[index] * b[index];
|
|
131
|
+
normA += a[index] * a[index];
|
|
132
|
+
normB += b[index] * b[index];
|
|
133
|
+
}
|
|
134
|
+
if (normA === 0 || normB === 0) return 0;
|
|
135
|
+
return dot / (Math.sqrt(normA) * Math.sqrt(normB));
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
//#endregion
|
|
139
|
+
export { buildCatalog, loadRecord, renderCatalogPrompt, semanticPreselect };
|
|
140
|
+
//# sourceMappingURL=catalog.mjs.map
|