@warlock.js/ai 4.4.0 → 4.6.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 +63 -52
- package/cjs/index.cjs +240 -14147
- package/cjs/src-Bmajk4Qg.cjs +30 -0
- package/cjs/src-OZyDYHxm.cjs +25089 -0
- package/cjs/src-OZyDYHxm.cjs.map +1 -0
- package/esm/agent/agent-config.type.d.mts +119 -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 +328 -36
- 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/agent/signature.mjs +57 -0
- package/esm/agent/signature.mjs.map +1 -0
- package/esm/agent/snapshot.mjs +101 -0
- package/esm/agent/snapshot.mjs.map +1 -0
- package/esm/ai-openai/src/embedder.mjs +4 -0
- package/esm/ai-openai/src/image.mjs +5 -0
- package/esm/ai-openai/src/index.mjs +7 -0
- package/esm/ai-openai/src/model.mjs +5 -0
- package/esm/ai-openai/src/sdk.mjs +9 -0
- package/esm/ai-openai/src/speech.mjs +5 -0
- package/esm/ai-openai/src/transcription.mjs +6 -0
- package/esm/ai-openai/src/utils/index.mjs +5 -0
- package/esm/ai-openai/src/utils/to-openai-messages.mjs +3 -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 +164 -53
- package/esm/ai.d.mts.map +1 -1
- package/esm/ai.mjs +79 -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 +33 -5
- package/esm/contracts/agent/agent-options.type.d.mts.map +1 -1
- package/esm/contracts/agent/agent-snapshot.type.d.mts +90 -0
- package/esm/contracts/agent/agent-snapshot.type.d.mts.map +1 -0
- package/esm/contracts/agent/agent.contract.d.mts +29 -1
- package/esm/contracts/agent/agent.contract.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/agent/index.d.mts +2 -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/image-model.contract.d.mts +156 -0
- package/esm/contracts/image-model.contract.d.mts.map +1 -0
- package/esm/contracts/index.d.mts +13 -6
- 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 +3 -2
- package/esm/contracts/planner/planner-config.type.d.mts +61 -0
- package/esm/contracts/planner/planner-config.type.d.mts.map +1 -1
- package/esm/contracts/planner/planner-execute-options.type.d.mts +60 -1
- package/esm/contracts/planner/planner-execute-options.type.d.mts.map +1 -1
- package/esm/contracts/planner/planner-result.type.d.mts +8 -0
- package/esm/contracts/planner/planner-result.type.d.mts.map +1 -1
- package/esm/contracts/planner/planner-snapshot.type.d.mts +77 -0
- package/esm/contracts/planner/planner-snapshot.type.d.mts.map +1 -0
- package/esm/contracts/planner/planner.contract.d.mts +21 -1
- package/esm/contracts/planner/planner.contract.d.mts.map +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/supervisor-result.type.d.mts +14 -2
- package/esm/contracts/result/supervisor-result.type.d.mts.map +1 -1
- package/esm/contracts/result/workflow-result.type.d.mts +2 -1
- package/esm/contracts/result/workflow-result.type.d.mts.map +1 -1
- package/esm/contracts/sdk-adapter.contract.d.mts +37 -0
- package/esm/contracts/sdk-adapter.contract.d.mts.map +1 -1
- package/esm/contracts/speech-model.contract.d.mts +97 -0
- package/esm/contracts/speech-model.contract.d.mts.map +1 -0
- 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/transcription-model.contract.d.mts +101 -0
- package/esm/contracts/transcription-model.contract.d.mts.map +1 -0
- 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/agent-drift-error.d.mts +32 -0
- package/esm/errors/agent-drift-error.d.mts.map +1 -0
- package/esm/errors/agent-drift-error.mjs +31 -0
- package/esm/errors/agent-drift-error.mjs.map +1 -0
- package/esm/errors/error-code.type.d.mts +1 -1
- package/esm/errors/index.d.mts +3 -0
- package/esm/errors/index.mjs +3 -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/errors/planner-drift-error.d.mts +34 -0
- package/esm/errors/planner-drift-error.d.mts.map +1 -0
- package/esm/errors/planner-drift-error.mjs +33 -0
- package/esm/errors/planner-drift-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/image/image-cost.d.mts +32 -0
- package/esm/image/image-cost.d.mts.map +1 -0
- package/esm/image/image-cost.mjs +55 -0
- package/esm/image/image-cost.mjs.map +1 -0
- package/esm/image/image.d.mts +92 -0
- package/esm/image/image.d.mts.map +1 -0
- package/esm/image/image.mjs +113 -0
- package/esm/image/image.mjs.map +1 -0
- package/esm/image/index.mjs +4 -0
- package/esm/index.d.mts +137 -24
- package/esm/index.mjs +101 -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/mock/index.d.mts +3 -0
- package/esm/mock/index.mjs +3 -0
- package/esm/mock/mock-config.type.d.mts +22 -0
- package/esm/mock/mock-config.type.d.mts.map +1 -1
- package/esm/mock/mock-image-model.d.mts +41 -0
- package/esm/mock/mock-image-model.d.mts.map +1 -0
- package/esm/mock/mock-image-model.mjs +52 -0
- package/esm/mock/mock-image-model.mjs.map +1 -0
- package/esm/mock/mock-sdk.d.mts +7 -1
- package/esm/mock/mock-sdk.d.mts.map +1 -1
- package/esm/mock/mock-sdk.mjs +27 -0
- package/esm/mock/mock-sdk.mjs.map +1 -1
- package/esm/mock/mock-speech-model.d.mts +31 -0
- package/esm/mock/mock-speech-model.d.mts.map +1 -0
- package/esm/mock/mock-speech-model.mjs +39 -0
- package/esm/mock/mock-speech-model.mjs.map +1 -0
- package/esm/mock/mock-transcription-model.d.mts +32 -0
- package/esm/mock/mock-transcription-model.d.mts.map +1 -0
- package/esm/mock/mock-transcription-model.mjs +36 -0
- package/esm/mock/mock-transcription-model.mjs.map +1 -0
- 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/planner-run.d.mts +8 -0
- package/esm/planner/planner-run.d.mts.map +1 -1
- package/esm/planner/planner-run.mjs +457 -31
- package/esm/planner/planner-run.mjs.map +1 -1
- package/esm/planner/planner.d.mts.map +1 -1
- package/esm/planner/planner.mjs +26 -2
- package/esm/planner/planner.mjs.map +1 -1
- package/esm/planner/snapshot.mjs +95 -0
- package/esm/planner/snapshot.mjs.map +1 -0
- 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 +22 -0
- package/esm/rag/index.mjs +18 -0
- package/esm/rag/loaders/errors.d.mts +19 -0
- package/esm/rag/loaders/errors.d.mts.map +1 -0
- package/esm/rag/loaders/errors.mjs +25 -0
- package/esm/rag/loaders/errors.mjs.map +1 -0
- package/esm/rag/loaders/index.mjs +7 -0
- package/esm/rag/loaders/load-html.d.mts +26 -0
- package/esm/rag/loaders/load-html.d.mts.map +1 -0
- package/esm/rag/loaders/load-html.mjs +138 -0
- package/esm/rag/loaders/load-html.mjs.map +1 -0
- package/esm/rag/loaders/load-pdf.d.mts +38 -0
- package/esm/rag/loaders/load-pdf.d.mts.map +1 -0
- package/esm/rag/loaders/load-pdf.mjs +150 -0
- package/esm/rag/loaders/load-pdf.mjs.map +1 -0
- package/esm/rag/loaders/load-text.d.mts +47 -0
- package/esm/rag/loaders/load-text.d.mts.map +1 -0
- package/esm/rag/loaders/load-text.mjs +60 -0
- package/esm/rag/loaders/load-text.mjs.map +1 -0
- package/esm/rag/loaders/load-web.d.mts +42 -0
- package/esm/rag/loaders/load-web.d.mts.map +1 -0
- package/esm/rag/loaders/load-web.mjs +89 -0
- package/esm/rag/loaders/load-web.mjs.map +1 -0
- package/esm/rag/loaders/loader.type.d.mts +89 -0
- package/esm/rag/loaders/loader.type.d.mts.map +1 -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/pg-vector-store.d.mts +139 -0
- package/esm/rag/store/pg-vector-store.d.mts.map +1 -0
- package/esm/rag/store/pg-vector-store.mjs +328 -0
- package/esm/rag/store/pg-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/speech/index.mjs +3 -0
- package/esm/speech/speech.d.mts +65 -0
- package/esm/speech/speech.d.mts.map +1 -0
- package/esm/speech/speech.mjs +123 -0
- package/esm/speech/speech.mjs.map +1 -0
- package/esm/supervisor/as-tool.mjs +2 -2
- package/esm/supervisor/as-tool.mjs.map +1 -1
- package/esm/supervisor/entries.mjs +2 -2
- package/esm/supervisor/entries.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/transcribe/audio-input.d.mts +47 -0
- package/esm/transcribe/audio-input.d.mts.map +1 -0
- package/esm/transcribe/audio-input.mjs +84 -0
- package/esm/transcribe/audio-input.mjs.map +1 -0
- package/esm/transcribe/index.mjs +4 -0
- package/esm/transcribe/transcribe.d.mts +64 -0
- package/esm/transcribe/transcribe.d.mts.map +1 -0
- package/esm/transcribe/transcribe.mjs +128 -0
- package/esm/transcribe/transcribe.mjs.map +1 -0
- 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 +2572 -204
- package/llms.txt +21 -4
- package/package.json +7 -3
- package/skills/README.md +44 -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-agent-runs/SKILL.md +135 -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/generate-images/SKILL.md +138 -0
- package/skills/generate-speech/SKILL.md +139 -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/rag-loaders-and-stores/SKILL.md +164 -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/transcribe-audio/SKILL.md +157 -0
- 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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"eval-runner.mjs","names":["judgeScorer"],"sources":["../../../../../../../@warlock.js/ai/src/eval/eval-runner.ts"],"sourcesContent":["import type { AgentContract } from \"../contracts/agent/agent.contract\";\nimport type { AgentExecuteOptions } from \"../contracts/agent/agent-options.type\";\nimport type {\n EvalCase,\n EvalCaseResult,\n EvalOptions,\n EvalReport,\n EvalScore,\n EvalScorer,\n EvalScorerContext,\n} from \"../contracts/agent/eval.type\";\nimport { AgentExecutionError } from \"../errors\";\nimport { log } from \"@warlock.js/logger\";\nimport { judge as judgeScorer } from \"./judge-scorer\";\n\nconst LOG_MODULE = \"ai.eval\";\nconst DEFAULT_PASS_THRESHOLD = 0.5;\n\n/**\n * Resolve the scorer list for a single case. Precedence: the case's\n * own `scorers` → the suite `scorers` → a synthesized judge scorer\n * when `judge` is configured. Throws an authoring-time\n * `AgentExecutionError` when a case can resolve none — an eval suite\n * with no way to score a case is a config bug worth surfacing at the\n * call site, not a silent pass.\n */\nfunction resolveScorers<TOutput>(\n evalCase: EvalCase<TOutput>,\n options: EvalOptions<TOutput>,\n passThreshold: number,\n): EvalScorer<TOutput>[] {\n if (evalCase.scorers && evalCase.scorers.length > 0) {\n return evalCase.scorers;\n }\n\n if (options.scorers && options.scorers.length > 0) {\n return options.scorers;\n }\n\n if (options.judge) {\n return [judgeScorer<TOutput>(options.judge, passThreshold)];\n }\n\n throw new AgentExecutionError(\n `eval case \"${evalCase.name}\" has no scorer — supply per-case \"scorers\", suite \"scorers\", or a \"judge\"`,\n { context: { authoring: true, case: evalCase.name } },\n );\n}\n\n/**\n * Decide a single scorer verdict's pass/fail. Honors an explicit\n * `passed` from the scorer; otherwise derives it from\n * `score >= passThreshold`.\n */\nfunction isScorePassing(score: EvalScore, passThreshold: number): boolean {\n if (typeof score.passed === \"boolean\") {\n return score.passed;\n }\n\n return score.score >= passThreshold;\n}\n\n/**\n * Merge suite-level execute options with the case's own override.\n * Per-case wins on conflict (shallow merge).\n */\nfunction mergeOptions<TOutput>(\n suite: AgentExecuteOptions<TOutput> | undefined,\n perCase: AgentExecuteOptions<TOutput> | undefined,\n): AgentExecuteOptions<TOutput> | undefined {\n if (!suite) return perCase;\n if (!perCase) return suite;\n return { ...suite, ...perCase };\n}\n\n/**\n * Run one case end-to-end: execute the agent, run every resolved\n * scorer, aggregate into an {@link EvalCaseResult}. A case passes only\n * when the agent did not error AND every scorer passed.\n */\nasync function runCase<TOutput>(\n agent: AgentContract<TOutput>,\n evalCase: EvalCase<TOutput>,\n options: EvalOptions<TOutput>,\n passThreshold: number,\n): Promise<EvalCaseResult<TOutput>> {\n const scorers = resolveScorers(evalCase, options, passThreshold);\n const executeOptions = mergeOptions(options.executeOptions, evalCase.options);\n\n const start = performance.now();\n const result = await agent.execute(evalCase.input, executeOptions);\n const duration = performance.now() - start;\n\n const context: EvalScorerContext<TOutput> = {\n case: evalCase,\n result,\n output: result.data,\n text: result.text,\n };\n\n const scores: EvalScore[] = [];\n\n for (const scorer of scorers) {\n scores.push(await scorer(context));\n }\n\n const meanScore =\n scores.length > 0 ? scores.reduce((sum, score) => sum + score.score, 0) / scores.length : 0;\n\n const allScorersPassed = scores.every((score) => isScorePassing(score, passThreshold));\n const passed = result.error === undefined && allScorersPassed;\n\n return {\n case: evalCase,\n result,\n scores,\n score: meanScore,\n passed,\n duration,\n };\n}\n\n/**\n * Core implementation of `agent.eval`. Runs every case sequentially\n * (cases share the agent and may carry side effects — ordering must be\n * deterministic), scores each, fires `onFailure` for failed cases, and\n * assembles the aggregate {@link EvalReport}.\n *\n * Never throws on a case-level failure; the only throw is the\n * authoring-time \"no scorer\" guard from {@link resolveScorers}.\n */\nexport async function runEval<TOutput>(\n agent: AgentContract<TOutput>,\n options: EvalOptions<TOutput>,\n): Promise<EvalReport<TOutput>> {\n const passThreshold = options.passThreshold ?? DEFAULT_PASS_THRESHOLD;\n const start = performance.now();\n\n const cases: EvalCaseResult<TOutput>[] = [];\n\n for (const evalCase of
|
|
1
|
+
{"version":3,"file":"eval-runner.mjs","names":["judgeScorer"],"sources":["../../../../../../../@warlock.js/ai/src/eval/eval-runner.ts"],"sourcesContent":["import type { AgentContract } from \"../contracts/agent/agent.contract\";\nimport type { AgentExecuteOptions } from \"../contracts/agent/agent-options.type\";\nimport type {\n EvalCase,\n EvalCaseResult,\n EvalOptions,\n EvalReport,\n EvalScore,\n EvalScorer,\n EvalScorerContext,\n} from \"../contracts/agent/eval.type\";\nimport type { EvalCase as EvalCaseType } from \"../contracts/agent/eval.type\";\nimport { AgentExecutionError } from \"../errors\";\nimport { log } from \"@warlock.js/logger\";\nimport { judge as judgeScorer } from \"./judge-scorer\";\nimport { diff } from \"./regression\";\n\n/**\n * Narrow `EvalOptions.cases` to the underlying `EvalCase[]`. A\n * `DatasetContract` is identified structurally by its `cases` property\n * (an array carried alongside `name` / `filter` / `shard`); a raw\n * `EvalCase[]` is used as-is.\n */\nfunction resolveCases<TOutput>(\n cases: EvalOptions<TOutput>[\"cases\"],\n): EvalCaseType<TOutput>[] {\n if (Array.isArray(cases)) {\n return cases;\n }\n\n return cases.cases;\n}\n\nconst LOG_MODULE = \"ai.eval\";\nconst DEFAULT_PASS_THRESHOLD = 0.5;\n\n/**\n * Resolve the scorer list for a single case. Precedence: the case's\n * own `scorers` → the suite `scorers` → a synthesized judge scorer\n * when `judge` is configured. Throws an authoring-time\n * `AgentExecutionError` when a case can resolve none — an eval suite\n * with no way to score a case is a config bug worth surfacing at the\n * call site, not a silent pass.\n */\nfunction resolveScorers<TOutput>(\n evalCase: EvalCase<TOutput>,\n options: EvalOptions<TOutput>,\n passThreshold: number,\n): EvalScorer<TOutput>[] {\n if (evalCase.scorers && evalCase.scorers.length > 0) {\n return evalCase.scorers;\n }\n\n if (options.scorers && options.scorers.length > 0) {\n return options.scorers;\n }\n\n if (options.judge) {\n return [judgeScorer<TOutput>(options.judge, passThreshold)];\n }\n\n throw new AgentExecutionError(\n `eval case \"${evalCase.name}\" has no scorer — supply per-case \"scorers\", suite \"scorers\", or a \"judge\"`,\n { context: { authoring: true, case: evalCase.name } },\n );\n}\n\n/**\n * Decide a single scorer verdict's pass/fail. Honors an explicit\n * `passed` from the scorer; otherwise derives it from\n * `score >= passThreshold`.\n */\nfunction isScorePassing(score: EvalScore, passThreshold: number): boolean {\n if (typeof score.passed === \"boolean\") {\n return score.passed;\n }\n\n return score.score >= passThreshold;\n}\n\n/**\n * Merge suite-level execute options with the case's own override.\n * Per-case wins on conflict (shallow merge).\n */\nfunction mergeOptions<TOutput>(\n suite: AgentExecuteOptions<TOutput> | undefined,\n perCase: AgentExecuteOptions<TOutput> | undefined,\n): AgentExecuteOptions<TOutput> | undefined {\n if (!suite) return perCase;\n if (!perCase) return suite;\n return { ...suite, ...perCase };\n}\n\n/**\n * Run one case end-to-end: execute the agent, run every resolved\n * scorer, aggregate into an {@link EvalCaseResult}. A case passes only\n * when the agent did not error AND every scorer passed.\n */\nasync function runCase<TOutput>(\n agent: AgentContract<TOutput>,\n evalCase: EvalCase<TOutput>,\n options: EvalOptions<TOutput>,\n passThreshold: number,\n): Promise<EvalCaseResult<TOutput>> {\n const scorers = resolveScorers(evalCase, options, passThreshold);\n const executeOptions = mergeOptions(options.executeOptions, evalCase.options);\n\n const start = performance.now();\n const result = await agent.execute(evalCase.input, executeOptions);\n const duration = performance.now() - start;\n\n const context: EvalScorerContext<TOutput> = {\n case: evalCase,\n result,\n output: result.data,\n text: result.text,\n };\n\n const scores: EvalScore[] = [];\n\n for (const scorer of scorers) {\n scores.push(await scorer(context));\n }\n\n const meanScore =\n scores.length > 0 ? scores.reduce((sum, score) => sum + score.score, 0) / scores.length : 0;\n\n const allScorersPassed = scores.every((score) => isScorePassing(score, passThreshold));\n const passed = result.error === undefined && allScorersPassed;\n\n return {\n case: evalCase,\n result,\n scores,\n score: meanScore,\n passed,\n duration,\n };\n}\n\n/**\n * Core implementation of `agent.eval`. Runs every case sequentially\n * (cases share the agent and may carry side effects — ordering must be\n * deterministic), scores each, fires `onFailure` for failed cases, and\n * assembles the aggregate {@link EvalReport}.\n *\n * Never throws on a case-level failure; the only throw is the\n * authoring-time \"no scorer\" guard from {@link resolveScorers}.\n */\nexport async function runEval<TOutput>(\n agent: AgentContract<TOutput>,\n options: EvalOptions<TOutput>,\n): Promise<EvalReport<TOutput>> {\n const passThreshold = options.passThreshold ?? DEFAULT_PASS_THRESHOLD;\n const start = performance.now();\n\n const suiteCases = resolveCases(options.cases);\n const cases: EvalCaseResult<TOutput>[] = [];\n\n for (const evalCase of suiteCases) {\n const caseResult = await runCase(agent, evalCase, options, passThreshold);\n\n cases.push(caseResult);\n\n if (!caseResult.passed && options.onFailure) {\n try {\n await options.onFailure(caseResult);\n } catch (error) {\n log.warn(LOG_MODULE, \"onFailure.hook.error\", \"eval onFailure handler threw\", {\n agent: agent.name,\n case: evalCase.name,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n }\n\n const passedCount = cases.filter((entry) => entry.passed).length;\n const total = cases.length;\n const meanScore =\n total > 0 ? cases.reduce((sum, entry) => sum + entry.score, 0) / total : 0;\n\n const report: EvalReport<TOutput> = {\n agentName: agent.name,\n total,\n passedCount,\n failedCount: total - passedCount,\n passRate: total > 0 ? passedCount / total : 0,\n meanScore,\n passed: total > 0 && passedCount === total,\n cases,\n duration: performance.now() - start,\n };\n\n if (options.baseline) {\n report.regression = diff(report, options.baseline, options.tolerance);\n }\n\n return report;\n}\n"],"mappings":";;;;;;;;;;;;;AAuBA,SAAS,aACP,OACyB;CACzB,IAAI,MAAM,QAAQ,KAAK,GACrB,OAAO;CAGT,OAAO,MAAM;AACf;AAEA,MAAM,aAAa;AACnB,MAAM,yBAAyB;;;;;;;;;AAU/B,SAAS,eACP,UACA,SACA,eACuB;CACvB,IAAI,SAAS,WAAW,SAAS,QAAQ,SAAS,GAChD,OAAO,SAAS;CAGlB,IAAI,QAAQ,WAAW,QAAQ,QAAQ,SAAS,GAC9C,OAAO,QAAQ;CAGjB,IAAI,QAAQ,OACV,OAAO,CAACA,MAAqB,QAAQ,OAAO,aAAa,CAAC;CAG5D,MAAM,IAAI,oBACR,cAAc,SAAS,KAAK,6EAC5B,EAAE,SAAS;EAAE,WAAW;EAAM,MAAM,SAAS;CAAK,EAAE,CACtD;AACF;;;;;;AAOA,SAAS,eAAe,OAAkB,eAAgC;CACxE,IAAI,OAAO,MAAM,WAAW,WAC1B,OAAO,MAAM;CAGf,OAAO,MAAM,SAAS;AACxB;;;;;AAMA,SAAS,aACP,OACA,SAC0C;CAC1C,IAAI,CAAC,OAAO,OAAO;CACnB,IAAI,CAAC,SAAS,OAAO;CACrB,OAAO;EAAE,GAAG;EAAO,GAAG;CAAQ;AAChC;;;;;;AAOA,eAAe,QACb,OACA,UACA,SACA,eACkC;CAClC,MAAM,UAAU,eAAe,UAAU,SAAS,aAAa;CAC/D,MAAM,iBAAiB,aAAa,QAAQ,gBAAgB,SAAS,OAAO;CAE5E,MAAM,QAAQ,YAAY,IAAI;CAC9B,MAAM,SAAS,MAAM,MAAM,QAAQ,SAAS,OAAO,cAAc;CACjE,MAAM,WAAW,YAAY,IAAI,IAAI;CAErC,MAAM,UAAsC;EAC1C,MAAM;EACN;EACA,QAAQ,OAAO;EACf,MAAM,OAAO;CACf;CAEA,MAAM,SAAsB,CAAC;CAE7B,KAAK,MAAM,UAAU,SACnB,OAAO,KAAK,MAAM,OAAO,OAAO,CAAC;CAGnC,MAAM,YACJ,OAAO,SAAS,IAAI,OAAO,QAAQ,KAAK,UAAU,MAAM,MAAM,OAAO,CAAC,IAAI,OAAO,SAAS;CAE5F,MAAM,mBAAmB,OAAO,OAAO,UAAU,eAAe,OAAO,aAAa,CAAC;CAGrF,OAAO;EACL,MAAM;EACN;EACA;EACA,OAAO;EACP,QAPa,OAAO,UAAU,UAAa;EAQ3C;CACF;AACF;;;;;;;;;;AAWA,eAAsB,QACpB,OACA,SAC8B;CAC9B,MAAM,gBAAgB,QAAQ,iBAAiB;CAC/C,MAAM,QAAQ,YAAY,IAAI;CAE9B,MAAM,aAAa,aAAa,QAAQ,KAAK;CAC7C,MAAM,QAAmC,CAAC;CAE1C,KAAK,MAAM,YAAY,YAAY;EACjC,MAAM,aAAa,MAAM,QAAQ,OAAO,UAAU,SAAS,aAAa;EAExE,MAAM,KAAK,UAAU;EAErB,IAAI,CAAC,WAAW,UAAU,QAAQ,WAChC,IAAI;GACF,MAAM,QAAQ,UAAU,UAAU;EACpC,SAAS,OAAO;GACd,IAAI,KAAK,YAAY,wBAAwB,gCAAgC;IAC3E,OAAO,MAAM;IACb,MAAM,SAAS;IACf,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;GAC9D,CAAC;EACH;CAEJ;CAEA,MAAM,cAAc,MAAM,QAAQ,UAAU,MAAM,MAAM,CAAC,CAAC;CAC1D,MAAM,QAAQ,MAAM;CACpB,MAAM,YACJ,QAAQ,IAAI,MAAM,QAAQ,KAAK,UAAU,MAAM,MAAM,OAAO,CAAC,IAAI,QAAQ;CAE3E,MAAM,SAA8B;EAClC,WAAW,MAAM;EACjB;EACA;EACA,aAAa,QAAQ;EACrB,UAAU,QAAQ,IAAI,cAAc,QAAQ;EAC5C;EACA,QAAQ,QAAQ,KAAK,gBAAgB;EACrC;EACA,UAAU,YAAY,IAAI,IAAI;CAChC;CAEA,IAAI,QAAQ,UACV,OAAO,aAAa,KAAK,QAAQ,QAAQ,UAAU,QAAQ,SAAS;CAGtE,OAAO;AACT"}
|
package/esm/eval/index.d.mts
CHANGED
|
@@ -1,28 +1,47 @@
|
|
|
1
|
+
import { DatasetContract, DatasetEntry, DatasetOptions } from "./dataset.type.mjs";
|
|
1
2
|
import { judge } from "./judge-scorer.mjs";
|
|
3
|
+
import { fromJSON, toJSON } from "./report-json.mjs";
|
|
4
|
+
import { toJUnit } from "./report-junit.mjs";
|
|
2
5
|
import { EvalPredicate, contains, exact, predicate } from "./scorers.mjs";
|
|
3
6
|
import { runEval } from "./eval-runner.mjs";
|
|
7
|
+
import { dataset } from "./dataset.mjs";
|
|
8
|
+
import { diff } from "./regression.mjs";
|
|
4
9
|
|
|
5
10
|
//#region ../@warlock.js/ai/src/eval/index.d.ts
|
|
6
11
|
/**
|
|
7
|
-
* Built-in eval scorer factories, surfaced on
|
|
12
|
+
* Built-in eval scorer factories plus the CI reporters, surfaced on
|
|
13
|
+
* `ai.eval.*`.
|
|
8
14
|
*
|
|
15
|
+
* Scorers:
|
|
9
16
|
* - `exact()` — pass when output equals the case `expected` (trimmed,
|
|
10
17
|
* case-insensitive; structured values compared by canonical JSON).
|
|
11
18
|
* - `contains()` — pass when `expected` appears as a substring.
|
|
12
19
|
* - `predicate(fn)` — wrap an arbitrary boolean assertion.
|
|
13
20
|
* - `judge(config)` — LLM-as-judge scoring against a rubric.
|
|
14
21
|
*
|
|
22
|
+
* Reporters / serialization (pure functions over a finished `EvalReport`):
|
|
23
|
+
* - `toJUnit(report)` — JUnit-XML artifact for CI ingestion.
|
|
24
|
+
* - `toJSON(report)` / `fromJSON(serialized)` — round-trippable snapshot;
|
|
25
|
+
* today's report becomes tomorrow's `baseline`.
|
|
26
|
+
*
|
|
15
27
|
* @example
|
|
16
28
|
* await myAgent.eval({
|
|
17
29
|
* cases: [{ name: "q", input: "Capital of Egypt?", expected: "Cairo" }],
|
|
18
30
|
* scorers: [ai.eval.contains()],
|
|
19
31
|
* });
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* const report = await myAgent.eval({ cases: ds, scorers: [ai.eval.exact()] });
|
|
35
|
+
* await writeFile("./report.junit.xml", ai.eval.toJUnit(report));
|
|
20
36
|
*/
|
|
21
37
|
declare const evalScorers: {
|
|
22
38
|
exact: typeof exact;
|
|
23
39
|
contains: typeof contains;
|
|
24
40
|
predicate: typeof predicate;
|
|
25
41
|
judge: typeof judge;
|
|
42
|
+
toJUnit: typeof toJUnit;
|
|
43
|
+
toJSON: typeof toJSON;
|
|
44
|
+
fromJSON: typeof fromJSON;
|
|
26
45
|
};
|
|
27
46
|
//#endregion
|
|
28
47
|
export { evalScorers };
|
package/esm/eval/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../../../../../../../@warlock.js/ai/src/eval/index.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../../../../../../../@warlock.js/ai/src/eval/index.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAqDa,WAAA"}
|
package/esm/eval/index.mjs
CHANGED
|
@@ -1,28 +1,46 @@
|
|
|
1
1
|
import { judge } from "./judge-scorer.mjs";
|
|
2
|
+
import { diff } from "./regression.mjs";
|
|
2
3
|
import { runEval } from "./eval-runner.mjs";
|
|
4
|
+
import { fromJSON, toJSON } from "./report-json.mjs";
|
|
5
|
+
import { toJUnit } from "./report-junit.mjs";
|
|
3
6
|
import { contains, exact, predicate } from "./scorers.mjs";
|
|
7
|
+
import { dataset } from "./dataset.mjs";
|
|
4
8
|
|
|
5
9
|
//#region ../@warlock.js/ai/src/eval/index.ts
|
|
6
10
|
/**
|
|
7
|
-
* Built-in eval scorer factories, surfaced on
|
|
11
|
+
* Built-in eval scorer factories plus the CI reporters, surfaced on
|
|
12
|
+
* `ai.eval.*`.
|
|
8
13
|
*
|
|
14
|
+
* Scorers:
|
|
9
15
|
* - `exact()` — pass when output equals the case `expected` (trimmed,
|
|
10
16
|
* case-insensitive; structured values compared by canonical JSON).
|
|
11
17
|
* - `contains()` — pass when `expected` appears as a substring.
|
|
12
18
|
* - `predicate(fn)` — wrap an arbitrary boolean assertion.
|
|
13
19
|
* - `judge(config)` — LLM-as-judge scoring against a rubric.
|
|
14
20
|
*
|
|
21
|
+
* Reporters / serialization (pure functions over a finished `EvalReport`):
|
|
22
|
+
* - `toJUnit(report)` — JUnit-XML artifact for CI ingestion.
|
|
23
|
+
* - `toJSON(report)` / `fromJSON(serialized)` — round-trippable snapshot;
|
|
24
|
+
* today's report becomes tomorrow's `baseline`.
|
|
25
|
+
*
|
|
15
26
|
* @example
|
|
16
27
|
* await myAgent.eval({
|
|
17
28
|
* cases: [{ name: "q", input: "Capital of Egypt?", expected: "Cairo" }],
|
|
18
29
|
* scorers: [ai.eval.contains()],
|
|
19
30
|
* });
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* const report = await myAgent.eval({ cases: ds, scorers: [ai.eval.exact()] });
|
|
34
|
+
* await writeFile("./report.junit.xml", ai.eval.toJUnit(report));
|
|
20
35
|
*/
|
|
21
36
|
const evalScorers = {
|
|
22
37
|
exact,
|
|
23
38
|
contains,
|
|
24
39
|
predicate,
|
|
25
|
-
judge
|
|
40
|
+
judge,
|
|
41
|
+
toJUnit,
|
|
42
|
+
toJSON,
|
|
43
|
+
fromJSON
|
|
26
44
|
};
|
|
27
45
|
|
|
28
46
|
//#endregion
|
package/esm/eval/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../../../../../../@warlock.js/ai/src/eval/index.ts"],"sourcesContent":["import { judge } from \"./judge-scorer\";\nimport { contains, exact, predicate } from \"./scorers\";\n\n// Runner — wired into AgentContract.eval() by the agent factory.\nexport { runEval } from \"./eval-runner\";\n\n// Scorer factories — re-exported individually for direct import.\nexport { contains, exact, predicate } from \"./scorers\";\nexport type { EvalPredicate } from \"./scorers\";\nexport { judge } from \"./judge-scorer\";\n\n/**\n * Built-in eval scorer factories, surfaced on `ai.eval.*`.\n *\n * - `exact()` — pass when output equals the case `expected` (trimmed,\n * case-insensitive; structured values compared by canonical JSON).\n * - `contains()` — pass when `expected` appears as a substring.\n * - `predicate(fn)` — wrap an arbitrary boolean assertion.\n * - `judge(config)` — LLM-as-judge scoring against a rubric.\n *\n * @example\n * await myAgent.eval({\n * cases: [{ name: \"q\", input: \"Capital of Egypt?\", expected: \"Cairo\" }],\n * scorers: [ai.eval.contains()],\n * });\n */\nexport const evalScorers = {\n exact,\n contains,\n predicate,\n judge,\n};\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../../../../../../@warlock.js/ai/src/eval/index.ts"],"sourcesContent":["import { dataset } from \"./dataset\";\nimport { judge } from \"./judge-scorer\";\nimport { fromJSON, toJSON } from \"./report-json\";\nimport { toJUnit } from \"./report-junit\";\nimport { contains, exact, predicate } from \"./scorers\";\n\n// Runner — wired into AgentContract.eval() by the agent factory.\nexport { runEval } from \"./eval-runner\";\n\n// Scorer factories — re-exported individually for direct import.\nexport { contains, exact, predicate } from \"./scorers\";\nexport type { EvalPredicate } from \"./scorers\";\nexport { judge } from \"./judge-scorer\";\n\n// Dataset primitive — feeds `agent.eval({ cases })`.\nexport { dataset } from \"./dataset\";\nexport type {\n DatasetContract,\n DatasetEntry,\n DatasetOptions,\n} from \"./dataset.type\";\n\n// Regression diff + CI reporters (pure, runner-decoupled).\nexport { diff } from \"./regression\";\nexport { toJSON, fromJSON } from \"./report-json\";\nexport { toJUnit } from \"./report-junit\";\n\n/**\n * Built-in eval scorer factories plus the CI reporters, surfaced on\n * `ai.eval.*`.\n *\n * Scorers:\n * - `exact()` — pass when output equals the case `expected` (trimmed,\n * case-insensitive; structured values compared by canonical JSON).\n * - `contains()` — pass when `expected` appears as a substring.\n * - `predicate(fn)` — wrap an arbitrary boolean assertion.\n * - `judge(config)` — LLM-as-judge scoring against a rubric.\n *\n * Reporters / serialization (pure functions over a finished `EvalReport`):\n * - `toJUnit(report)` — JUnit-XML artifact for CI ingestion.\n * - `toJSON(report)` / `fromJSON(serialized)` — round-trippable snapshot;\n * today's report becomes tomorrow's `baseline`.\n *\n * @example\n * await myAgent.eval({\n * cases: [{ name: \"q\", input: \"Capital of Egypt?\", expected: \"Cairo\" }],\n * scorers: [ai.eval.contains()],\n * });\n *\n * @example\n * const report = await myAgent.eval({ cases: ds, scorers: [ai.eval.exact()] });\n * await writeFile(\"./report.junit.xml\", ai.eval.toJUnit(report));\n */\nexport const evalScorers = {\n exact,\n contains,\n predicate,\n judge,\n toJUnit,\n toJSON,\n fromJSON,\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqDA,MAAa,cAAc;CACzB;CACA;CACA;CACA;CACA;CACA;CACA;AACF"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { EvalRegression, EvalReport } from "../contracts/agent/eval.type.mjs";
|
|
2
|
+
|
|
3
|
+
//#region ../@warlock.js/ai/src/eval/regression.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Diff a fresh {@link EvalReport} against a `baseline`, joining cases by
|
|
6
|
+
* name, to produce an {@link EvalRegression} verdict.
|
|
7
|
+
*
|
|
8
|
+
* A case **regresses** when its new aggregate `score` is more than
|
|
9
|
+
* `tolerance` below its baseline score (`before - after > tolerance`).
|
|
10
|
+
* Cases that improved, held steady, or moved within `tolerance` are not
|
|
11
|
+
* flagged. Cases present in only one of the two reports are surfaced
|
|
12
|
+
* under `added` / `removed` rather than treated as regressions, so adding
|
|
13
|
+
* or dropping a case never fails the gate by itself.
|
|
14
|
+
*
|
|
15
|
+
* Pure — depends only on the two reports and the tolerance; attaches no
|
|
16
|
+
* state and mutates neither input.
|
|
17
|
+
*
|
|
18
|
+
* @param report - The newly produced report.
|
|
19
|
+
* @param baseline - A prior report to compare against.
|
|
20
|
+
* @param tolerance - Max allowed score drop before a case counts as a
|
|
21
|
+
* regression. Defaults to `0` (any drop regresses).
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* const regression = diff(report, baseline, 0.05);
|
|
25
|
+
* expect(regression.passed).toBe(true);
|
|
26
|
+
*/
|
|
27
|
+
declare function diff<TOutput = unknown>(report: EvalReport<TOutput>, baseline: EvalReport<TOutput>, tolerance?: number): EvalRegression;
|
|
28
|
+
//#endregion
|
|
29
|
+
export { diff };
|
|
30
|
+
//# sourceMappingURL=regression.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"regression.d.mts","names":[],"sources":["../../../../../../../@warlock.js/ai/src/eval/regression.ts"],"mappings":";;;;;AAyBA;;;;;;;;;;;;;;;;;;;;AAIiB;iBAJD,IAAA,oBACd,MAAA,EAAQ,UAAA,CAAW,OAAA,GACnB,QAAA,EAAU,UAAA,CAAW,OAAA,GACrB,SAAA,YACC,cAAA"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
//#region ../@warlock.js/ai/src/eval/regression.ts
|
|
2
|
+
/**
|
|
3
|
+
* Diff a fresh {@link EvalReport} against a `baseline`, joining cases by
|
|
4
|
+
* name, to produce an {@link EvalRegression} verdict.
|
|
5
|
+
*
|
|
6
|
+
* A case **regresses** when its new aggregate `score` is more than
|
|
7
|
+
* `tolerance` below its baseline score (`before - after > tolerance`).
|
|
8
|
+
* Cases that improved, held steady, or moved within `tolerance` are not
|
|
9
|
+
* flagged. Cases present in only one of the two reports are surfaced
|
|
10
|
+
* under `added` / `removed` rather than treated as regressions, so adding
|
|
11
|
+
* or dropping a case never fails the gate by itself.
|
|
12
|
+
*
|
|
13
|
+
* Pure — depends only on the two reports and the tolerance; attaches no
|
|
14
|
+
* state and mutates neither input.
|
|
15
|
+
*
|
|
16
|
+
* @param report - The newly produced report.
|
|
17
|
+
* @param baseline - A prior report to compare against.
|
|
18
|
+
* @param tolerance - Max allowed score drop before a case counts as a
|
|
19
|
+
* regression. Defaults to `0` (any drop regresses).
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* const regression = diff(report, baseline, 0.05);
|
|
23
|
+
* expect(regression.passed).toBe(true);
|
|
24
|
+
*/
|
|
25
|
+
function diff(report, baseline, tolerance = 0) {
|
|
26
|
+
const baselineScores = /* @__PURE__ */ new Map();
|
|
27
|
+
for (const entry of baseline.cases) baselineScores.set(entry.case.name, entry.score);
|
|
28
|
+
const currentNames = /* @__PURE__ */ new Set();
|
|
29
|
+
const regressed = [];
|
|
30
|
+
for (const entry of report.cases) {
|
|
31
|
+
const name = entry.case.name;
|
|
32
|
+
currentNames.add(name);
|
|
33
|
+
const before = baselineScores.get(name);
|
|
34
|
+
if (before === void 0) continue;
|
|
35
|
+
if (before - entry.score > tolerance) regressed.push({
|
|
36
|
+
name,
|
|
37
|
+
before,
|
|
38
|
+
after: entry.score
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
return {
|
|
42
|
+
regressed,
|
|
43
|
+
removed: baseline.cases.map((entry) => entry.case.name).filter((name) => !currentNames.has(name)),
|
|
44
|
+
added: report.cases.map((entry) => entry.case.name).filter((name) => !baselineScores.has(name)),
|
|
45
|
+
passed: regressed.length === 0
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
//#endregion
|
|
50
|
+
export { diff };
|
|
51
|
+
//# sourceMappingURL=regression.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"regression.mjs","names":[],"sources":["../../../../../../../@warlock.js/ai/src/eval/regression.ts"],"sourcesContent":["import type { EvalRegression, EvalReport } from \"../contracts/agent/eval.type\";\n\n/**\n * Diff a fresh {@link EvalReport} against a `baseline`, joining cases by\n * name, to produce an {@link EvalRegression} verdict.\n *\n * A case **regresses** when its new aggregate `score` is more than\n * `tolerance` below its baseline score (`before - after > tolerance`).\n * Cases that improved, held steady, or moved within `tolerance` are not\n * flagged. Cases present in only one of the two reports are surfaced\n * under `added` / `removed` rather than treated as regressions, so adding\n * or dropping a case never fails the gate by itself.\n *\n * Pure — depends only on the two reports and the tolerance; attaches no\n * state and mutates neither input.\n *\n * @param report - The newly produced report.\n * @param baseline - A prior report to compare against.\n * @param tolerance - Max allowed score drop before a case counts as a\n * regression. Defaults to `0` (any drop regresses).\n *\n * @example\n * const regression = diff(report, baseline, 0.05);\n * expect(regression.passed).toBe(true);\n */\nexport function diff<TOutput = unknown>(\n report: EvalReport<TOutput>,\n baseline: EvalReport<TOutput>,\n tolerance = 0,\n): EvalRegression {\n const baselineScores = new Map<string, number>();\n\n for (const entry of baseline.cases) {\n baselineScores.set(entry.case.name, entry.score);\n }\n\n const currentNames = new Set<string>();\n const regressed: EvalRegression[\"regressed\"] = [];\n\n for (const entry of report.cases) {\n const name = entry.case.name;\n currentNames.add(name);\n\n const before = baselineScores.get(name);\n\n if (before === undefined) {\n continue;\n }\n\n if (before - entry.score > tolerance) {\n regressed.push({ name, before, after: entry.score });\n }\n }\n\n const removed = baseline.cases\n .map((entry) => entry.case.name)\n .filter((name) => !currentNames.has(name));\n\n const added = report.cases\n .map((entry) => entry.case.name)\n .filter((name) => !baselineScores.has(name));\n\n return {\n regressed,\n removed,\n added,\n passed: regressed.length === 0,\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAyBA,SAAgB,KACd,QACA,UACA,YAAY,GACI;CAChB,MAAM,iCAAiB,IAAI,IAAoB;CAE/C,KAAK,MAAM,SAAS,SAAS,OAC3B,eAAe,IAAI,MAAM,KAAK,MAAM,MAAM,KAAK;CAGjD,MAAM,+BAAe,IAAI,IAAY;CACrC,MAAM,YAAyC,CAAC;CAEhD,KAAK,MAAM,SAAS,OAAO,OAAO;EAChC,MAAM,OAAO,MAAM,KAAK;EACxB,aAAa,IAAI,IAAI;EAErB,MAAM,SAAS,eAAe,IAAI,IAAI;EAEtC,IAAI,WAAW,QACb;EAGF,IAAI,SAAS,MAAM,QAAQ,WACzB,UAAU,KAAK;GAAE;GAAM;GAAQ,OAAO,MAAM;EAAM,CAAC;CAEvD;CAUA,OAAO;EACL;EACA,SAVc,SAAS,MACtB,KAAK,UAAU,MAAM,KAAK,IAAI,CAAC,CAC/B,QAAQ,SAAS,CAAC,aAAa,IAAI,IAAI,CAQlC;EACN,OAPY,OAAO,MAClB,KAAK,UAAU,MAAM,KAAK,IAAI,CAAC,CAC/B,QAAQ,SAAS,CAAC,eAAe,IAAI,IAAI,CAKtC;EACJ,QAAQ,UAAU,WAAW;CAC/B;AACF"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { EvalReport } from "../contracts/agent/eval.type.mjs";
|
|
2
|
+
|
|
3
|
+
//#region ../@warlock.js/ai/src/eval/report-json.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Serialize an {@link EvalReport} to a pretty-printed JSON string — a
|
|
6
|
+
* round-trippable snapshot suitable for committing as the next run's
|
|
7
|
+
* baseline (`agent.eval({ baseline: fromJSON(...) })`).
|
|
8
|
+
*
|
|
9
|
+
* Pure. The whole report is emitted verbatim; `result` payloads,
|
|
10
|
+
* per-case `scores`, timings, and any attached `regression` block are all
|
|
11
|
+
* preserved, so a parsed report drives regression diffing exactly as the
|
|
12
|
+
* in-memory one would.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* await writeFile("./eval/baseline.json", toJSON(report));
|
|
16
|
+
*/
|
|
17
|
+
declare function toJSON(report: EvalReport): string;
|
|
18
|
+
/**
|
|
19
|
+
* Parse a string produced by {@link toJSON} back into an
|
|
20
|
+
* {@link EvalReport}. The inverse of `toJSON` — `fromJSON(toJSON(r))`
|
|
21
|
+
* reproduces `r`'s data (functions such as scorers were never part of the
|
|
22
|
+
* serialized report, so the round-trip is over plain data only).
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* const baseline = fromJSON(await readFile("./eval/baseline.json", "utf8"));
|
|
26
|
+
*/
|
|
27
|
+
declare function fromJSON<TOutput = unknown>(serialized: string): EvalReport<TOutput>;
|
|
28
|
+
//#endregion
|
|
29
|
+
export { fromJSON, toJSON };
|
|
30
|
+
//# sourceMappingURL=report-json.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report-json.d.mts","names":[],"sources":["../../../../../../../@warlock.js/ai/src/eval/report-json.ts"],"mappings":";;;;;AAeA;;;;AAAyC;AAazC;;;;;;iBAbgB,MAAA,CAAO,MAAkB,EAAV,UAAU;;;AAa0C;;;;;;;iBAAnE,QAAA,oBAA4B,UAAA,WAAqB,UAAU,CAAC,OAAA"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
//#region ../@warlock.js/ai/src/eval/report-json.ts
|
|
2
|
+
/**
|
|
3
|
+
* Serialize an {@link EvalReport} to a pretty-printed JSON string — a
|
|
4
|
+
* round-trippable snapshot suitable for committing as the next run's
|
|
5
|
+
* baseline (`agent.eval({ baseline: fromJSON(...) })`).
|
|
6
|
+
*
|
|
7
|
+
* Pure. The whole report is emitted verbatim; `result` payloads,
|
|
8
|
+
* per-case `scores`, timings, and any attached `regression` block are all
|
|
9
|
+
* preserved, so a parsed report drives regression diffing exactly as the
|
|
10
|
+
* in-memory one would.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* await writeFile("./eval/baseline.json", toJSON(report));
|
|
14
|
+
*/
|
|
15
|
+
function toJSON(report) {
|
|
16
|
+
return JSON.stringify(report, void 0, 2);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Parse a string produced by {@link toJSON} back into an
|
|
20
|
+
* {@link EvalReport}. The inverse of `toJSON` — `fromJSON(toJSON(r))`
|
|
21
|
+
* reproduces `r`'s data (functions such as scorers were never part of the
|
|
22
|
+
* serialized report, so the round-trip is over plain data only).
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* const baseline = fromJSON(await readFile("./eval/baseline.json", "utf8"));
|
|
26
|
+
*/
|
|
27
|
+
function fromJSON(serialized) {
|
|
28
|
+
return JSON.parse(serialized);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
//#endregion
|
|
32
|
+
export { fromJSON, toJSON };
|
|
33
|
+
//# sourceMappingURL=report-json.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report-json.mjs","names":[],"sources":["../../../../../../../@warlock.js/ai/src/eval/report-json.ts"],"sourcesContent":["import type { EvalReport } from \"../contracts/agent/eval.type\";\n\n/**\n * Serialize an {@link EvalReport} to a pretty-printed JSON string — a\n * round-trippable snapshot suitable for committing as the next run's\n * baseline (`agent.eval({ baseline: fromJSON(...) })`).\n *\n * Pure. The whole report is emitted verbatim; `result` payloads,\n * per-case `scores`, timings, and any attached `regression` block are all\n * preserved, so a parsed report drives regression diffing exactly as the\n * in-memory one would.\n *\n * @example\n * await writeFile(\"./eval/baseline.json\", toJSON(report));\n */\nexport function toJSON(report: EvalReport): string {\n return JSON.stringify(report, undefined, 2);\n}\n\n/**\n * Parse a string produced by {@link toJSON} back into an\n * {@link EvalReport}. The inverse of `toJSON` — `fromJSON(toJSON(r))`\n * reproduces `r`'s data (functions such as scorers were never part of the\n * serialized report, so the round-trip is over plain data only).\n *\n * @example\n * const baseline = fromJSON(await readFile(\"./eval/baseline.json\", \"utf8\"));\n */\nexport function fromJSON<TOutput = unknown>(serialized: string): EvalReport<TOutput> {\n return JSON.parse(serialized) as EvalReport<TOutput>;\n}\n"],"mappings":";;;;;;;;;;;;;;AAeA,SAAgB,OAAO,QAA4B;CACjD,OAAO,KAAK,UAAU,QAAQ,QAAW,CAAC;AAC5C;;;;;;;;;;AAWA,SAAgB,SAA4B,YAAyC;CACnF,OAAO,KAAK,MAAM,UAAU;AAC9B"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { EvalReport } from "../contracts/agent/eval.type.mjs";
|
|
2
|
+
|
|
3
|
+
//#region ../@warlock.js/ai/src/eval/report-junit.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Serialize an {@link EvalReport} to a JUnit-XML string for CI ingestion.
|
|
6
|
+
*
|
|
7
|
+
* **Role.** A pure, runner-decoupled reporter: one `<testsuite>` whose
|
|
8
|
+
* name is the agent, one `<testcase>` per eval case, a `<failure>` child
|
|
9
|
+
* on each case that did not pass (with the joined scorer reasons), and a
|
|
10
|
+
* `time` attribute carrying the case / suite duration in **seconds**
|
|
11
|
+
* (JUnit's unit; the report stores milliseconds).
|
|
12
|
+
*
|
|
13
|
+
* XML is hand-emitted (no `xml` dependency) and every dynamic value is
|
|
14
|
+
* entity-escaped via {@link escapeXml}.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* await writeFile("./report.junit.xml", toJUnit(report));
|
|
18
|
+
*/
|
|
19
|
+
declare function toJUnit(report: EvalReport): string;
|
|
20
|
+
//#endregion
|
|
21
|
+
export { toJUnit };
|
|
22
|
+
//# sourceMappingURL=report-junit.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report-junit.d.mts","names":[],"sources":["../../../../../../../@warlock.js/ai/src/eval/report-junit.ts"],"mappings":";;;;;AAqDA;;;;AAA0C;;;;;;;;;iBAA1B,OAAA,CAAQ,MAAkB,EAAV,UAAU"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
//#region ../@warlock.js/ai/src/eval/report-junit.ts
|
|
2
|
+
/**
|
|
3
|
+
* Escape the five XML predefined entities so arbitrary text (case names,
|
|
4
|
+
* failure reasons, agent names) is safe inside an attribute value or
|
|
5
|
+
* element body. Covers `&`, `<`, `>`, `"`, and `'`.
|
|
6
|
+
*/
|
|
7
|
+
function escapeXml(value) {
|
|
8
|
+
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Build the `<failure>` body for a failed case: the joined reasons of
|
|
12
|
+
* every non-passing scorer, falling back to a generic message when a
|
|
13
|
+
* scorer offered no reason (or the failure was an agent error).
|
|
14
|
+
*/
|
|
15
|
+
function failureMessage(entry) {
|
|
16
|
+
if (entry.result.error) return `agent error: ${entry.result.error.message}`;
|
|
17
|
+
const reasons = entry.scores.filter((score) => score.passed === false).map((score) => score.reason).filter((reason) => typeof reason === "string" && reason !== "");
|
|
18
|
+
if (reasons.length > 0) return reasons.join("; ");
|
|
19
|
+
return "case did not pass";
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Serialize an {@link EvalReport} to a JUnit-XML string for CI ingestion.
|
|
23
|
+
*
|
|
24
|
+
* **Role.** A pure, runner-decoupled reporter: one `<testsuite>` whose
|
|
25
|
+
* name is the agent, one `<testcase>` per eval case, a `<failure>` child
|
|
26
|
+
* on each case that did not pass (with the joined scorer reasons), and a
|
|
27
|
+
* `time` attribute carrying the case / suite duration in **seconds**
|
|
28
|
+
* (JUnit's unit; the report stores milliseconds).
|
|
29
|
+
*
|
|
30
|
+
* XML is hand-emitted (no `xml` dependency) and every dynamic value is
|
|
31
|
+
* entity-escaped via {@link escapeXml}.
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* await writeFile("./report.junit.xml", toJUnit(report));
|
|
35
|
+
*/
|
|
36
|
+
function toJUnit(report) {
|
|
37
|
+
const suiteName = escapeXml(report.agentName);
|
|
38
|
+
const suiteTime = (report.duration / 1e3).toFixed(3);
|
|
39
|
+
const lines = [];
|
|
40
|
+
lines.push("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
|
|
41
|
+
lines.push(`<testsuite name="${suiteName}" tests="${report.total}" failures="${report.failedCount}" time="${suiteTime}">`);
|
|
42
|
+
for (const entry of report.cases) {
|
|
43
|
+
const caseName = escapeXml(entry.case.name);
|
|
44
|
+
const caseTime = (entry.duration / 1e3).toFixed(3);
|
|
45
|
+
if (entry.passed) {
|
|
46
|
+
lines.push(` <testcase name="${caseName}" classname="${suiteName}" time="${caseTime}"/>`);
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
const message = failureMessage(entry);
|
|
50
|
+
lines.push(` <testcase name="${caseName}" classname="${suiteName}" time="${caseTime}">`);
|
|
51
|
+
lines.push(` <failure message="${escapeXml(message)}">${escapeXml(message)}</failure>`);
|
|
52
|
+
lines.push(" </testcase>");
|
|
53
|
+
}
|
|
54
|
+
lines.push("</testsuite>");
|
|
55
|
+
return lines.join("\n");
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
//#endregion
|
|
59
|
+
export { toJUnit };
|
|
60
|
+
//# sourceMappingURL=report-junit.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report-junit.mjs","names":[],"sources":["../../../../../../../@warlock.js/ai/src/eval/report-junit.ts"],"sourcesContent":["import type { EvalCaseResult, EvalReport } from \"../contracts/agent/eval.type\";\n\n/**\n * Escape the five XML predefined entities so arbitrary text (case names,\n * failure reasons, agent names) is safe inside an attribute value or\n * element body. Covers `&`, `<`, `>`, `\"`, and `'`.\n */\nfunction escapeXml(value: string): string {\n return value\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\")\n .replace(/'/g, \"'\");\n}\n\n/**\n * Build the `<failure>` body for a failed case: the joined reasons of\n * every non-passing scorer, falling back to a generic message when a\n * scorer offered no reason (or the failure was an agent error).\n */\nfunction failureMessage(entry: EvalCaseResult): string {\n if (entry.result.error) {\n return `agent error: ${entry.result.error.message}`;\n }\n\n const reasons = entry.scores\n .filter((score) => score.passed === false)\n .map((score) => score.reason)\n .filter((reason): reason is string => typeof reason === \"string\" && reason !== \"\");\n\n if (reasons.length > 0) {\n return reasons.join(\"; \");\n }\n\n return \"case did not pass\";\n}\n\n/**\n * Serialize an {@link EvalReport} to a JUnit-XML string for CI ingestion.\n *\n * **Role.** A pure, runner-decoupled reporter: one `<testsuite>` whose\n * name is the agent, one `<testcase>` per eval case, a `<failure>` child\n * on each case that did not pass (with the joined scorer reasons), and a\n * `time` attribute carrying the case / suite duration in **seconds**\n * (JUnit's unit; the report stores milliseconds).\n *\n * XML is hand-emitted (no `xml` dependency) and every dynamic value is\n * entity-escaped via {@link escapeXml}.\n *\n * @example\n * await writeFile(\"./report.junit.xml\", toJUnit(report));\n */\nexport function toJUnit(report: EvalReport): string {\n const suiteName = escapeXml(report.agentName);\n const suiteTime = (report.duration / 1000).toFixed(3);\n\n const lines: string[] = [];\n\n lines.push('<?xml version=\"1.0\" encoding=\"UTF-8\"?>');\n lines.push(\n `<testsuite name=\"${suiteName}\" tests=\"${report.total}\" failures=\"${report.failedCount}\" time=\"${suiteTime}\">`,\n );\n\n for (const entry of report.cases) {\n const caseName = escapeXml(entry.case.name);\n const caseTime = (entry.duration / 1000).toFixed(3);\n\n if (entry.passed) {\n lines.push(\n ` <testcase name=\"${caseName}\" classname=\"${suiteName}\" time=\"${caseTime}\"/>`,\n );\n\n continue;\n }\n\n const message = failureMessage(entry);\n lines.push(\n ` <testcase name=\"${caseName}\" classname=\"${suiteName}\" time=\"${caseTime}\">`,\n );\n lines.push(\n ` <failure message=\"${escapeXml(message)}\">${escapeXml(message)}</failure>`,\n );\n lines.push(\" </testcase>\");\n }\n\n lines.push(\"</testsuite>\");\n\n return lines.join(\"\\n\");\n}\n"],"mappings":";;;;;;AAOA,SAAS,UAAU,OAAuB;CACxC,OAAO,MACJ,QAAQ,MAAM,OAAO,CAAC,CACtB,QAAQ,MAAM,MAAM,CAAC,CACrB,QAAQ,MAAM,MAAM,CAAC,CACrB,QAAQ,MAAM,QAAQ,CAAC,CACvB,QAAQ,MAAM,QAAQ;AAC3B;;;;;;AAOA,SAAS,eAAe,OAA+B;CACrD,IAAI,MAAM,OAAO,OACf,OAAO,gBAAgB,MAAM,OAAO,MAAM;CAG5C,MAAM,UAAU,MAAM,OACnB,QAAQ,UAAU,MAAM,WAAW,KAAK,CAAC,CACzC,KAAK,UAAU,MAAM,MAAM,CAAC,CAC5B,QAAQ,WAA6B,OAAO,WAAW,YAAY,WAAW,EAAE;CAEnF,IAAI,QAAQ,SAAS,GACnB,OAAO,QAAQ,KAAK,IAAI;CAG1B,OAAO;AACT;;;;;;;;;;;;;;;;AAiBA,SAAgB,QAAQ,QAA4B;CAClD,MAAM,YAAY,UAAU,OAAO,SAAS;CAC5C,MAAM,aAAa,OAAO,WAAW,IAAI,CAAE,QAAQ,CAAC;CAEpD,MAAM,QAAkB,CAAC;CAEzB,MAAM,KAAK,4CAAwC;CACnD,MAAM,KACJ,oBAAoB,UAAU,WAAW,OAAO,MAAM,cAAc,OAAO,YAAY,UAAU,UAAU,GAC7G;CAEA,KAAK,MAAM,SAAS,OAAO,OAAO;EAChC,MAAM,WAAW,UAAU,MAAM,KAAK,IAAI;EAC1C,MAAM,YAAY,MAAM,WAAW,IAAI,CAAE,QAAQ,CAAC;EAElD,IAAI,MAAM,QAAQ;GAChB,MAAM,KACJ,qBAAqB,SAAS,eAAe,UAAU,UAAU,SAAS,IAC5E;GAEA;EACF;EAEA,MAAM,UAAU,eAAe,KAAK;EACpC,MAAM,KACJ,qBAAqB,SAAS,eAAe,UAAU,UAAU,SAAS,GAC5E;EACA,MAAM,KACJ,yBAAyB,UAAU,OAAO,EAAE,IAAI,UAAU,OAAO,EAAE,WACrE;EACA,MAAM,KAAK,eAAe;CAC5B;CAEA,MAAM,KAAK,cAAc;CAEzB,OAAO,MAAM,KAAK,IAAI;AACxB"}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { MiddlewareTripContext } from "../../contracts/middleware/middleware-context.type.mjs";
|
|
2
|
+
import { GuardrailAction, GuardrailMatch, GuardrailPhase } from "./verdict.type.mjs";
|
|
3
|
+
import { GuardrailDetector } from "./guardrail.contract.mjs";
|
|
4
|
+
import { OpenAiClientLike } from "./openai-client.contract.mjs";
|
|
5
|
+
|
|
6
|
+
//#region ../@warlock.js/ai/src/guard/contracts/guard-options.type.d.ts
|
|
7
|
+
/**
|
|
8
|
+
* The payload handed to {@link GuardrailEscalation.onBlock} when a detector
|
|
9
|
+
* returns `{ type: "block", escalate: true }`. The factory builds it just
|
|
10
|
+
* before throwing the `GuardrailViolationError`, so a host can route the
|
|
11
|
+
* hard block to a human-review surface.
|
|
12
|
+
*/
|
|
13
|
+
interface GuardrailBlockEvent {
|
|
14
|
+
/** Where the block fired: input prompt, output, or tool args. */
|
|
15
|
+
readonly phase: GuardrailPhase;
|
|
16
|
+
/** The detector's human-readable reason. */
|
|
17
|
+
readonly reason: string;
|
|
18
|
+
/** The matches that triggered the block, when the detector reported them. */
|
|
19
|
+
readonly matches?: readonly GuardrailMatch[];
|
|
20
|
+
/** The live middleware trip context (state, messages, agent, model, signal). */
|
|
21
|
+
readonly ctx: MiddlewareTripContext;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Escalation seam for composing a hard block with a human-review surface.
|
|
25
|
+
*
|
|
26
|
+
* The callback fires **only** for a verdict of `{ type: "block", escalate:
|
|
27
|
+
* true }`, awaited *before* the `GuardrailViolationError` is thrown. It is a
|
|
28
|
+
* plain callback by design — `ai-guard` takes no dependency on the deferred
|
|
29
|
+
* human-step machinery; the host wires its own review queue / resume loop
|
|
30
|
+
* inside `onBlock`.
|
|
31
|
+
*/
|
|
32
|
+
interface GuardrailEscalation {
|
|
33
|
+
/** Route a `{ type: "block", escalate: true }` verdict to a human. */
|
|
34
|
+
onBlock?(event: GuardrailBlockEvent): void | Promise<void>;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Configuration for the {@link guard} factory (surfaced as
|
|
38
|
+
* `ai.guardrail(options)`). Each phase array runs in registration order;
|
|
39
|
+
* the first non-`allow` verdict decides the action for that phase.
|
|
40
|
+
*
|
|
41
|
+
* At least one of `input` / `output` / `tool` should be supplied — a guard
|
|
42
|
+
* with no detectors is a no-op middleware.
|
|
43
|
+
*/
|
|
44
|
+
interface GuardOptions {
|
|
45
|
+
/**
|
|
46
|
+
* Override the middleware name — surfaces on
|
|
47
|
+
* `GuardrailViolationError.guardrail` and as the `ctx.state` namespace so
|
|
48
|
+
* operators can tell two guards apart. Default `"guardrail"`.
|
|
49
|
+
*/
|
|
50
|
+
name?: string;
|
|
51
|
+
/**
|
|
52
|
+
* Detectors run on the outbound prompt at `trip.before`.
|
|
53
|
+
*
|
|
54
|
+
* **Input redaction is not supported in v1:** the core `trip.before` hook
|
|
55
|
+
* can only short-circuit, not rewrite-and-continue, so a `redact` verdict
|
|
56
|
+
* here is treated as a `block`. Input detectors are effectively
|
|
57
|
+
* `block` / `flag` only.
|
|
58
|
+
*/
|
|
59
|
+
input?: readonly GuardrailDetector[];
|
|
60
|
+
/** Detectors run on `response.content` at `trip.after`. Support `redact`. */
|
|
61
|
+
output?: readonly GuardrailDetector[];
|
|
62
|
+
/**
|
|
63
|
+
* Detectors run on `JSON.stringify(toolArgs)` at `tool.before`. A
|
|
64
|
+
* `redact` verdict here is treated as a `block` (silently rewriting tool
|
|
65
|
+
* arguments changes side-effects unpredictably).
|
|
66
|
+
*/
|
|
67
|
+
tool?: readonly GuardrailDetector[];
|
|
68
|
+
/**
|
|
69
|
+
* The tool names the `tool` detectors apply to. Omit to apply to every
|
|
70
|
+
* tool. When set, the middleware's `tool` hooks are scoped via the core
|
|
71
|
+
* `forTool(toolNames, mw)` helper; `trip` hooks are unaffected.
|
|
72
|
+
*/
|
|
73
|
+
toolNames?: string | readonly string[];
|
|
74
|
+
/** Compose a `{ type: "block", escalate: true }` verdict with a human. */
|
|
75
|
+
escalation?: GuardrailEscalation;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* The PII categories the built-in `pii` detector can scan for. Each is a
|
|
79
|
+
* linear (anchored, no nested quantifiers) regex — safe against catastrophic
|
|
80
|
+
* backtracking.
|
|
81
|
+
*/
|
|
82
|
+
type PiiCategory = "ssn" | "email" | "phone" | "credit-card" | "ipv4";
|
|
83
|
+
/**
|
|
84
|
+
* Options for the built-in `pii` detector (`ai.guardrail.pii`). All built-in
|
|
85
|
+
* PII matching is regex / exact-string only — zero runtime dependency.
|
|
86
|
+
*/
|
|
87
|
+
interface PiiDetectorOptions {
|
|
88
|
+
/** Which categories to scan for. Default: every {@link PiiCategory}. */
|
|
89
|
+
detect?: readonly PiiCategory[];
|
|
90
|
+
/** What to do on a match. Default `"redact"`. */
|
|
91
|
+
onMatch?: Extract<GuardrailAction, "redact" | "block" | "flag">;
|
|
92
|
+
/**
|
|
93
|
+
* Replacement template used on `redact`. Supports the `{label}` token,
|
|
94
|
+
* substituted with the matched category — e.g. `"[REDACTED:{label}]"`.
|
|
95
|
+
* Default masks the matched span with a fixed placeholder.
|
|
96
|
+
*/
|
|
97
|
+
mask?: string;
|
|
98
|
+
/** Extra exact-string terms to treat as PII alongside the built-in regexes. */
|
|
99
|
+
dictionary?: readonly string[];
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Options for the built-in `topic` filter (`ai.guardrail.topic`). Matches a
|
|
103
|
+
* case-insensitive substring or a `RegExp` against the inspected text.
|
|
104
|
+
*/
|
|
105
|
+
interface TopicFilterOptions {
|
|
106
|
+
/**
|
|
107
|
+
* Deny-list terms / phrases. A `string` matches case-insensitively as a
|
|
108
|
+
* substring; a `RegExp` is tested as-is. Any hit triggers `onMatch`.
|
|
109
|
+
*/
|
|
110
|
+
deny?: readonly (string | RegExp)[];
|
|
111
|
+
/**
|
|
112
|
+
* Allow-list terms / phrases. When set, text matching **none** of these
|
|
113
|
+
* triggers `onMatch` (an allow-list miss).
|
|
114
|
+
*/
|
|
115
|
+
allow?: readonly (string | RegExp)[];
|
|
116
|
+
/** Action on a deny hit (or an allow-list miss). Default `"block"`. */
|
|
117
|
+
onMatch?: Extract<GuardrailAction, "block" | "flag">;
|
|
118
|
+
/** Override the verdict's human-readable reason. */
|
|
119
|
+
reason?: string;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Options for the built-in `injection` detector (`ai.guardrail.injection`).
|
|
123
|
+
* Matches a built-in set of jailbreak / prompt-injection marker phrases,
|
|
124
|
+
* extensible with caller-supplied markers.
|
|
125
|
+
*/
|
|
126
|
+
interface InjectionDetectorOptions {
|
|
127
|
+
/**
|
|
128
|
+
* Extra marker phrases beyond the built-in jailbreak / prompt-injection
|
|
129
|
+
* set. A `string` matches case-insensitively as a substring; a `RegExp`
|
|
130
|
+
* is tested as-is.
|
|
131
|
+
*/
|
|
132
|
+
markers?: readonly (string | RegExp)[];
|
|
133
|
+
/**
|
|
134
|
+
* Action on a match. Default `"flag"` — callers commonly escalate to
|
|
135
|
+
* `"block"` on the input phase.
|
|
136
|
+
*/
|
|
137
|
+
onMatch?: Extract<GuardrailAction, "block" | "flag">;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Options for the optional `moderation` detector (`ai.guardrail.moderation`),
|
|
141
|
+
* backed by a lazily-imported `openai` peer. Importing `@warlock.js/ai`
|
|
142
|
+
* never forces `openai` to resolve; the detector throws a curated install
|
|
143
|
+
* string on first `check()` when the SDK is absent.
|
|
144
|
+
*/
|
|
145
|
+
interface OpenAiModerationOptions {
|
|
146
|
+
/**
|
|
147
|
+
* A pre-built OpenAI-compatible client (any object matching
|
|
148
|
+
* {@link OpenAiClientLike}, including a real `OpenAI` instance). When
|
|
149
|
+
* supplied, the detector calls it directly and never imports the SDK —
|
|
150
|
+
* the bring-your-own-client / test escape hatch.
|
|
151
|
+
*/
|
|
152
|
+
client?: OpenAiClientLike;
|
|
153
|
+
/** OpenAI API key. Reads `OPENAI_API_KEY` from the environment when omitted. */
|
|
154
|
+
apiKey?: string;
|
|
155
|
+
/** Moderation model to call. Default `"omni-moderation-latest"`. */
|
|
156
|
+
model?: string;
|
|
157
|
+
/**
|
|
158
|
+
* Categories that escalate to `block`; every other flagged category
|
|
159
|
+
* produces a `flag` verdict instead. Omit to `flag` on any category.
|
|
160
|
+
*/
|
|
161
|
+
blockOn?: readonly string[];
|
|
162
|
+
}
|
|
163
|
+
//#endregion
|
|
164
|
+
export { GuardOptions, GuardrailBlockEvent, GuardrailEscalation, InjectionDetectorOptions, OpenAiModerationOptions, PiiCategory, PiiDetectorOptions, TopicFilterOptions };
|
|
165
|
+
//# sourceMappingURL=guard-options.type.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guard-options.type.d.mts","names":[],"sources":["../../../../../../../../@warlock.js/ai/src/guard/contracts/guard-options.type.ts"],"mappings":";;;;;;;;AAeA;;;;UAAiB,mBAAA;EAQD;EAAA,SANL,KAAA,EAAO,cAAA;EAMmB;EAAA,SAJ1B,MAAA;EAFO;EAAA,SAIP,OAAA,YAAmB,cAAA;EAAnB;EAAA,SAEA,GAAA,EAAK,qBAAA;AAAA;;;AAAqB;AAYrC;;;;;;UAAiB,mBAAA;EAE8B;EAA7C,OAAA,EAAS,KAAA,EAAO,mBAAA,UAA6B,OAAO;AAAA;AAWtD;;;;;;;;AAAA,UAAiB,YAAA;EAMf;;;;;EAAA,IAAA;EAiBgB;;;;;AAQgB;AAQlC;;EAxBE,KAAA,YAAiB,iBAAA;EAwBI;EAtBrB,MAAA,YAAkB,iBAAA;EA4BH;;;;;EAtBf,IAAA,YAAgB,iBAAA;EA0BC;;;;;EApBjB,SAAA;EAoBkB;EAlBlB,UAAA,GAAa,mBAAA;AAAA;;AA0BH;AAOZ;;;KAzBY,WAAA;;;;;UAMK,kBAAA;EAwBf;EAtBA,MAAA,YAAkB,WAAA;EA2BlB;EAzBA,OAAA,GAAU,OAAA,CAAQ,eAAA;EA2BlB;;;;;EArBA,IAAA;EA+Be;EA7Bf,UAAA;AAAA;;;;;UAOe,kBAAA;EA4Bf;;;;EAvBA,IAAA,sBAA0B,MAAA;EA4BO;AAAA;AASnC;;EAhCE,KAAA,sBAA2B,MAAA;EAuCF;EArCzB,OAAA,GAAU,OAAA,CAAQ,eAAA;EAqCT;EAnCT,MAAA;AAAA;;;AA4CO;;;UApCQ,wBAAA;;;;;;EAMf,OAAA,sBAA6B,MAAA;;;;;EAK7B,OAAA,GAAU,OAAA,CAAQ,eAAA;AAAA;;;;;;;UASH,uBAAA;;;;;;;EAOf,MAAA,GAAS,gBAAgB;;EAEzB,MAAA;;EAEA,KAAA;;;;;EAKA,OAAA;AAAA"}
|