@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,73 @@
|
|
|
1
|
+
//#region ../@warlock.js/ai/src/rag/chunk/sentence.ts
|
|
2
|
+
/** Matches a sentence terminator (`.`, `!`, `?`) followed by whitespace. */
|
|
3
|
+
const SENTENCE_BOUNDARY = /([.!?])\s+/g;
|
|
4
|
+
/**
|
|
5
|
+
* Sentence-aware character splitter.
|
|
6
|
+
*
|
|
7
|
+
* Splits the text on sentence terminators (`. `, `! `, `? `), keeping the
|
|
8
|
+
* terminator attached, then greedily packs whole sentences into chunks up
|
|
9
|
+
* to `size` characters, carrying `overlap` characters forward between
|
|
10
|
+
* adjacent chunks. A single sentence longer than `size` becomes its own
|
|
11
|
+
* (oversize) chunk rather than being cut mid-sentence. Spans are exact.
|
|
12
|
+
*/
|
|
13
|
+
function sentenceChunk(text, size, overlap) {
|
|
14
|
+
if (text.trim().length === 0) return [];
|
|
15
|
+
const sentences = splitSentences(text);
|
|
16
|
+
const chunks = [];
|
|
17
|
+
let bufferStart = -1;
|
|
18
|
+
let bufferEnd = -1;
|
|
19
|
+
let index = 0;
|
|
20
|
+
const flush = () => {
|
|
21
|
+
if (bufferStart === -1) return;
|
|
22
|
+
chunks.push({
|
|
23
|
+
text: text.slice(bufferStart, bufferEnd),
|
|
24
|
+
index,
|
|
25
|
+
span: [bufferStart, bufferEnd]
|
|
26
|
+
});
|
|
27
|
+
index += 1;
|
|
28
|
+
};
|
|
29
|
+
for (const sentence of sentences) {
|
|
30
|
+
if (bufferStart === -1) {
|
|
31
|
+
bufferStart = sentence.start;
|
|
32
|
+
bufferEnd = sentence.end;
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
if (sentence.end - bufferStart <= size) {
|
|
36
|
+
bufferEnd = sentence.end;
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
flush();
|
|
40
|
+
bufferStart = overlap > 0 ? Math.max(bufferStart, sentence.start - overlap) : sentence.start;
|
|
41
|
+
bufferEnd = sentence.end;
|
|
42
|
+
}
|
|
43
|
+
flush();
|
|
44
|
+
return chunks;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Split `text` into sentence spans on terminator + whitespace, keeping the
|
|
48
|
+
* terminator with its sentence and absorbing the trailing whitespace into
|
|
49
|
+
* the boundary so reconstructing the spans loses no characters.
|
|
50
|
+
*/
|
|
51
|
+
function splitSentences(text) {
|
|
52
|
+
const spans = [];
|
|
53
|
+
let start = 0;
|
|
54
|
+
let match;
|
|
55
|
+
SENTENCE_BOUNDARY.lastIndex = 0;
|
|
56
|
+
while ((match = SENTENCE_BOUNDARY.exec(text)) !== null) {
|
|
57
|
+
const end = match.index + match[0].length;
|
|
58
|
+
spans.push({
|
|
59
|
+
start,
|
|
60
|
+
end
|
|
61
|
+
});
|
|
62
|
+
start = end;
|
|
63
|
+
}
|
|
64
|
+
if (start < text.length) spans.push({
|
|
65
|
+
start,
|
|
66
|
+
end: text.length
|
|
67
|
+
});
|
|
68
|
+
return spans;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
//#endregion
|
|
72
|
+
export { sentenceChunk };
|
|
73
|
+
//# sourceMappingURL=sentence.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sentence.mjs","names":[],"sources":["../../../../../../../../@warlock.js/ai/src/rag/chunk/sentence.ts"],"sourcesContent":["import type { Chunk } from \"../contracts/chunk-options.type\";\n\n/** Matches a sentence terminator (`.`, `!`, `?`) followed by whitespace. */\nconst SENTENCE_BOUNDARY = /([.!?])\\s+/g;\n\n/**\n * Sentence-aware character splitter.\n *\n * Splits the text on sentence terminators (`. `, `! `, `? `), keeping the\n * terminator attached, then greedily packs whole sentences into chunks up\n * to `size` characters, carrying `overlap` characters forward between\n * adjacent chunks. A single sentence longer than `size` becomes its own\n * (oversize) chunk rather than being cut mid-sentence. Spans are exact.\n */\nexport function sentenceChunk(text: string, size: number, overlap: number): Chunk[] {\n if (text.trim().length === 0) {\n return [];\n }\n\n const sentences = splitSentences(text);\n const chunks: Chunk[] = [];\n\n let bufferStart = -1;\n let bufferEnd = -1;\n let index = 0;\n\n const flush = (): void => {\n if (bufferStart === -1) {\n return;\n }\n\n chunks.push({\n text: text.slice(bufferStart, bufferEnd),\n index,\n span: [bufferStart, bufferEnd],\n });\n index += 1;\n };\n\n for (const sentence of sentences) {\n if (bufferStart === -1) {\n bufferStart = sentence.start;\n bufferEnd = sentence.end;\n\n continue;\n }\n\n if (sentence.end - bufferStart <= size) {\n bufferEnd = sentence.end;\n\n continue;\n }\n\n flush();\n\n const overlapStart =\n overlap > 0 ? Math.max(bufferStart, sentence.start - overlap) : sentence.start;\n\n bufferStart = overlapStart;\n bufferEnd = sentence.end;\n }\n\n flush();\n\n return chunks;\n}\n\n/** A sentence with its absolute `[start, end)` span in the original text. */\ntype SentenceSpan = {\n start: number;\n end: number;\n};\n\n/**\n * Split `text` into sentence spans on terminator + whitespace, keeping the\n * terminator with its sentence and absorbing the trailing whitespace into\n * the boundary so reconstructing the spans loses no characters.\n */\nfunction splitSentences(text: string): SentenceSpan[] {\n const spans: SentenceSpan[] = [];\n let start = 0;\n let match: RegExpExecArray | null;\n\n SENTENCE_BOUNDARY.lastIndex = 0;\n\n while ((match = SENTENCE_BOUNDARY.exec(text)) !== null) {\n const end = match.index + match[0].length;\n\n spans.push({ start, end });\n start = end;\n }\n\n if (start < text.length) {\n spans.push({ start, end: text.length });\n }\n\n return spans;\n}\n"],"mappings":";;AAGA,MAAM,oBAAoB;;;;;;;;;;AAW1B,SAAgB,cAAc,MAAc,MAAc,SAA0B;CAClF,IAAI,KAAK,KAAK,CAAC,CAAC,WAAW,GACzB,OAAO,CAAC;CAGV,MAAM,YAAY,eAAe,IAAI;CACrC,MAAM,SAAkB,CAAC;CAEzB,IAAI,cAAc;CAClB,IAAI,YAAY;CAChB,IAAI,QAAQ;CAEZ,MAAM,cAAoB;EACxB,IAAI,gBAAgB,IAClB;EAGF,OAAO,KAAK;GACV,MAAM,KAAK,MAAM,aAAa,SAAS;GACvC;GACA,MAAM,CAAC,aAAa,SAAS;EAC/B,CAAC;EACD,SAAS;CACX;CAEA,KAAK,MAAM,YAAY,WAAW;EAChC,IAAI,gBAAgB,IAAI;GACtB,cAAc,SAAS;GACvB,YAAY,SAAS;GAErB;EACF;EAEA,IAAI,SAAS,MAAM,eAAe,MAAM;GACtC,YAAY,SAAS;GAErB;EACF;EAEA,MAAM;EAKN,cAFE,UAAU,IAAI,KAAK,IAAI,aAAa,SAAS,QAAQ,OAAO,IAAI,SAAS;EAG3E,YAAY,SAAS;CACvB;CAEA,MAAM;CAEN,OAAO;AACT;;;;;;AAaA,SAAS,eAAe,MAA8B;CACpD,MAAM,QAAwB,CAAC;CAC/B,IAAI,QAAQ;CACZ,IAAI;CAEJ,kBAAkB,YAAY;CAE9B,QAAQ,QAAQ,kBAAkB,KAAK,IAAI,OAAO,MAAM;EACtD,MAAM,MAAM,MAAM,QAAQ,MAAM,EAAE,CAAC;EAEnC,MAAM,KAAK;GAAE;GAAO;EAAI,CAAC;EACzB,QAAQ;CACV;CAEA,IAAI,QAAQ,KAAK,QACf,MAAM,KAAK;EAAE;EAAO,KAAK,KAAK;CAAO,CAAC;CAGxC,OAAO;AACT"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
//#region ../@warlock.js/ai/src/rag/contracts/chunk-options.type.d.ts
|
|
2
|
+
/** Splitter strategy used to break a document's text before embedding. */
|
|
3
|
+
type ChunkType = "recursive" | "sentence" | "fixed" | "markdown";
|
|
4
|
+
/**
|
|
5
|
+
* How a document's text is split before embedding.
|
|
6
|
+
*
|
|
7
|
+
* All sizing is in **characters**, not tokens, so the pipeline stays
|
|
8
|
+
* tokenizer-free (the embedder owns token counting). A character budget
|
|
9
|
+
* is deterministic and dep-free; it may occasionally over/under-shoot a
|
|
10
|
+
* provider's per-request token cap, which the sub-batching guard in
|
|
11
|
+
* `index()` absorbs.
|
|
12
|
+
*/
|
|
13
|
+
type ChunkOptions = {
|
|
14
|
+
/** Splitter strategy. Default `"recursive"`. */type?: ChunkType; /** Target chunk size in characters (not tokens, to stay tokenizer-free). Default 1000. */
|
|
15
|
+
size?: number; /** Character overlap carried between adjacent chunks. Default 200. */
|
|
16
|
+
overlap?: number;
|
|
17
|
+
/**
|
|
18
|
+
* Ordered separators for the `"recursive"` splitter, tried largest-unit
|
|
19
|
+
* first. Default `["\n\n", "\n", ". ", " ", ""]`.
|
|
20
|
+
*/
|
|
21
|
+
separators?: string[];
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* A single chunk emitted by a splitter — its text plus the exact
|
|
25
|
+
* `[start, end)` character span inside the original source text, so the
|
|
26
|
+
* citation's `span` is precise.
|
|
27
|
+
*/
|
|
28
|
+
type Chunk = {
|
|
29
|
+
/** The chunk text. */text: string; /** 0-based index of the chunk within its source document. */
|
|
30
|
+
index: number; /** Character span `[start, end)` of the chunk inside the original source text. */
|
|
31
|
+
span: [start: number, end: number];
|
|
32
|
+
};
|
|
33
|
+
//#endregion
|
|
34
|
+
export { Chunk, ChunkOptions, ChunkType };
|
|
35
|
+
//# sourceMappingURL=chunk-options.type.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chunk-options.type.d.mts","names":[],"sources":["../../../../../../../../@warlock.js/ai/src/rag/contracts/chunk-options.type.ts"],"mappings":";;KACY,SAAA;;;;AAAS;AAWrB;;;;;KAAY,YAAA;EAIV,gDAFA,IAAA,GAAO,SAAS,EAShB;EAPA,IAAA,WAOU;EALV,OAAA;EAae;;;;EARf,UAAA;AAAA;;;;AAcyB;;KANf,KAAA;wBAEV,IAAA;EAEA,KAAA;EAEA,IAAA,GAAO,KAAA,UAAe,GAAA;AAAA"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
//#region ../@warlock.js/ai/src/rag/contracts/citation.type.d.ts
|
|
2
|
+
/** Where a retrieved chunk came from — the unit an answer cites. */
|
|
3
|
+
type Citation = {
|
|
4
|
+
/** `id` of the source `RagDocument` this chunk was split from. */sourceId: string; /** 0-based index of the chunk within its source document. */
|
|
5
|
+
chunkIndex: number; /** Character span `[start, end)` of the chunk inside the original source text. */
|
|
6
|
+
span: [start: number, end: number]; /** Relevance score the retrieval assigned, in `[0, 1]`. */
|
|
7
|
+
score: number; /** Metadata copied verbatim from the source document. */
|
|
8
|
+
metadata?: Record<string, unknown>;
|
|
9
|
+
};
|
|
10
|
+
/** A single retrieval hit, carrying its citation. */
|
|
11
|
+
type RetrievedChunk = {
|
|
12
|
+
/** Chunk text injected into the model prompt. */text: string; /** Relevance in `[0, 1]` — cosine similarity, or the reranker's score when one ran. */
|
|
13
|
+
score: number; /** Provenance for grounding the answer. */
|
|
14
|
+
citation: Citation;
|
|
15
|
+
};
|
|
16
|
+
/** Knobs controlling a single `retrieve()` call. */
|
|
17
|
+
type RetrieveOptions = {
|
|
18
|
+
/** Number of chunks to return AFTER reranking. Default 5. */topK?: number; /** Cosine floor `[0, 1]` applied at the vector-store stage. Default 0.5. */
|
|
19
|
+
threshold?: number;
|
|
20
|
+
/**
|
|
21
|
+
* Candidate pool size fetched from the store before reranking. Defaults
|
|
22
|
+
* to `topK * 4` (clamped to >= topK) — an overscan that mirrors the
|
|
23
|
+
* episodic/procedural memory tiers' `k * 5` pattern.
|
|
24
|
+
*/
|
|
25
|
+
candidates?: number; /** Restrict retrieval to chunks whose source had one of these tags. */
|
|
26
|
+
tags?: string[];
|
|
27
|
+
};
|
|
28
|
+
/** Result of a single retrieval. */
|
|
29
|
+
type RetrieveResult = {
|
|
30
|
+
/** The query that was embedded. */query: string; /** Ranked, cited chunks. */
|
|
31
|
+
chunks: RetrievedChunk[];
|
|
32
|
+
};
|
|
33
|
+
//#endregion
|
|
34
|
+
export { Citation, RetrieveOptions, RetrieveResult, RetrievedChunk };
|
|
35
|
+
//# sourceMappingURL=citation.type.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"citation.type.d.mts","names":[],"sources":["../../../../../../../../@warlock.js/ai/src/rag/contracts/citation.type.ts"],"mappings":";;KACY,QAAA;EAAQ,kEAElB,QAAA,UAQiB;EANjB,UAAA;EAEA,IAAA,GAAO,KAAA,UAAe,GAAA,WAAf;EAEP,KAAA;EAEA,QAAA,GAAW,MAAM;AAAA;;KAIP,cAAA;EAAA,iDAEV,IAAA;EAEA,KAAA,UAFA;EAIA,QAAA,EAAU,QAAQ;AAAA;;KAIR,eAAA;EAJQ,6DAMlB,IAAA,WAFyB;EAIzB,SAAA;EAJyB;;;;;EAUzB,UAAA,WAEI;EAAJ,IAAA;AAAA;;KAIU,cAAA;EAEV,mCAAA,KAAA,UAEQ;EAAR,MAAA,EAAQ,cAAc;AAAA"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { Citation, RetrieveOptions, RetrieveResult, RetrievedChunk } from "./citation.type.mjs";
|
|
2
|
+
import { Chunk, ChunkOptions, ChunkType } from "./chunk-options.type.mjs";
|
|
3
|
+
import { RagDocument } from "./rag-document.type.mjs";
|
|
4
|
+
import { Rag, RagAsToolOptions, RagConfig } from "./rag-config.type.mjs";
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { ToolContract } from "../../tool/tool.mjs";
|
|
2
|
+
import { EmbedderContract } from "../../contracts/embedder.contract.mjs";
|
|
3
|
+
import { RetrieveOptions, RetrieveResult } from "./citation.type.mjs";
|
|
4
|
+
import { RagReranker } from "../rerank/reranker.contract.mjs";
|
|
5
|
+
import { ChunkOptions } from "./chunk-options.type.mjs";
|
|
6
|
+
import { RagDocument } from "./rag-document.type.mjs";
|
|
7
|
+
import { CacheDriver } from "@warlock.js/cache";
|
|
8
|
+
|
|
9
|
+
//#region ../@warlock.js/ai/src/rag/contracts/rag-config.type.d.ts
|
|
10
|
+
/** Options for `rag.asTool()` — how retrieval is exposed to an agent. */
|
|
11
|
+
type RagAsToolOptions = {
|
|
12
|
+
/** LLM tool name. Default `"retrieve_<rag.name>"`. */name?: string; /** Tool description the model reads. Sensible default derived from the rag name. */
|
|
13
|
+
description?: string; /** Override `topK` / `threshold` / `tags` for the tool path. */
|
|
14
|
+
retrieve?: RetrieveOptions;
|
|
15
|
+
};
|
|
16
|
+
/** Configuration for the `rag()` factory. */
|
|
17
|
+
type RagConfig = {
|
|
18
|
+
/** Stable name — used in tool names, cache namespace, logs. Default `"rag"`. */name?: string; /** Embedder for both indexing and query embedding. Required. */
|
|
19
|
+
embedder: EmbedderContract;
|
|
20
|
+
/**
|
|
21
|
+
* Vector-capable cache driver = the vector store. Falls back to
|
|
22
|
+
* `ai.config({ defaultStore })` when omitted; throws at construction if
|
|
23
|
+
* neither resolves (same rule as `SemanticMemoryConfig.store`).
|
|
24
|
+
*/
|
|
25
|
+
store?: CacheDriver<any, any>; /** Namespace prefix for every key written. Default `"ai.rag." + name`. */
|
|
26
|
+
namespace?: string; /** Chunking defaults for `index()`. Overridable per `index()` call. */
|
|
27
|
+
chunk?: ChunkOptions; /** Optional reranker run between the store fetch and the topK slice. */
|
|
28
|
+
reranker?: RagReranker; /** Default retrieval knobs. */
|
|
29
|
+
retrieve?: RetrieveOptions;
|
|
30
|
+
/**
|
|
31
|
+
* Ingestion guardrails for `index()` (D5). Each is a hard cap that
|
|
32
|
+
* throws before any embedding spend when exceeded — unbounded ingestion
|
|
33
|
+
* is a real cost / memory / quota foot-gun. All optional; omit for no
|
|
34
|
+
* limit (the prior behavior).
|
|
35
|
+
*/
|
|
36
|
+
limits?: {
|
|
37
|
+
/** Max documents accepted in a single `index()` call. */maxDocuments?: number; /** Max chunks produced across the call (after chunking). */
|
|
38
|
+
maxChunks?: number; /** Max total bytes of document text accepted in a single call. */
|
|
39
|
+
maxBytes?: number;
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* A configured RAG pipeline: chunk → embed → vector store → retrieve →
|
|
44
|
+
* rerank → cite. Built by the `rag()` factory.
|
|
45
|
+
*/
|
|
46
|
+
interface Rag {
|
|
47
|
+
/** Stable name used in tool names, namespace, and logs. */
|
|
48
|
+
readonly name: string;
|
|
49
|
+
/** Chunk → embed (batched) → store. Returns the chunk count written. */
|
|
50
|
+
index(docs: RagDocument[], chunk?: ChunkOptions): Promise<{
|
|
51
|
+
chunks: number;
|
|
52
|
+
}>;
|
|
53
|
+
/** Embed the query, fetch candidates, rerank, slice topK, attach citations. */
|
|
54
|
+
retrieve(query: string, options?: RetrieveOptions): Promise<RetrieveResult>;
|
|
55
|
+
/** Drop every entry written under this rag's namespace. */
|
|
56
|
+
clear(): Promise<void>;
|
|
57
|
+
/**
|
|
58
|
+
* Expose `retrieve()` as a tool for an agent's `tools: []` loop. Input is
|
|
59
|
+
* `{ query: string }`; output is `RetrieveResult`. Built via the same
|
|
60
|
+
* composite-as-tool engine the other primitives use.
|
|
61
|
+
*/
|
|
62
|
+
asTool(options?: RagAsToolOptions): ToolContract<{
|
|
63
|
+
query: string;
|
|
64
|
+
}, RetrieveResult>;
|
|
65
|
+
}
|
|
66
|
+
//#endregion
|
|
67
|
+
export { Rag, RagAsToolOptions, RagConfig };
|
|
68
|
+
//# sourceMappingURL=rag-config.type.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rag-config.type.d.mts","names":[],"sources":["../../../../../../../../@warlock.js/ai/src/rag/contracts/rag-config.type.ts"],"mappings":";;;;;;;;;;KASY,gBAAA;EAAA,sDAEV,IAAA;EAEA,WAAA,WAFA;EAIA,QAAA,GAAW,eAAe;AAAA;;KAIhB,SAAA;EAJgB,gFAM1B,IAAA,WAFmB;EAInB,QAAA,EAAU,gBAAA;EAAA;;;;;EAMV,KAAA,GAAQ,WAAA,YAQkB;EAN1B,SAAA,WARA;EAUA,KAAA,GAAQ,YAAA,EAJR;EAMA,QAAA,GAAW,WAAA,EAJX;EAMA,QAAA,GAAW,eAAA;EAJH;;;;;;EAWR,MAAA;IAIE,yDAFA,YAAA,WAIQ;IAFR,SAAA,WAUa;IARb,QAAA;EAAA;AAAA;;;;;UAQa,GAAA;EAQN;EAAA,SANA,IAAA;EAY2D;EAVpE,KAAA,CAAM,IAAA,EAAM,WAAA,IAAe,KAAA,GAAQ,YAAA,GAAe,OAAA;IAAU,MAAA;EAAA;EAFnD;EAIT,QAAA,CAAS,KAAA,UAAe,OAAA,GAAU,eAAA,GAAkB,OAAA,CAAQ,cAAA;EAFhD;EAIZ,KAAA,IAAS,OAAA;EAJ0B;;;;;EAUnC,MAAA,CAAO,OAAA,GAAU,gBAAA,GAAmB,YAAA;IAAe,KAAA;EAAA,GAAiB,cAAA;AAAA"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
//#region ../@warlock.js/ai/src/rag/contracts/rag-document.type.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* A raw document handed to the pipeline before chunking.
|
|
4
|
+
*
|
|
5
|
+
* The caller is responsible for loading documents (from files, a DB, an
|
|
6
|
+
* API, …) and parsing them down to text — document loaders are out of
|
|
7
|
+
* scope for v1. `index()` takes already-loaded `{ id, text }` documents.
|
|
8
|
+
*/
|
|
9
|
+
type RagDocument = {
|
|
10
|
+
/** Stable source id — propagated to every chunk + citation from this doc. */id: string; /** Full text to be chunked + embedded. */
|
|
11
|
+
text: string; /** Opaque metadata round-tripped onto chunks + citations (url, title, page…). */
|
|
12
|
+
metadata?: Record<string, unknown>;
|
|
13
|
+
/**
|
|
14
|
+
* Optional tags applied to every chunk written from this document, so
|
|
15
|
+
* `retrieve({ tags })` can restrict retrieval to a subset of sources.
|
|
16
|
+
*/
|
|
17
|
+
tags?: string[];
|
|
18
|
+
};
|
|
19
|
+
//#endregion
|
|
20
|
+
export { RagDocument };
|
|
21
|
+
//# sourceMappingURL=rag-document.type.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rag-document.type.d.mts","names":[],"sources":["../../../../../../../../@warlock.js/ai/src/rag/contracts/rag-document.type.ts"],"mappings":";;AAOA;;;;;;KAAY,WAAA;EAMC,6EAJX,EAAA,UASI;EAPJ,IAAA;EAEA,QAAA,GAAW,MAAM;;;;;EAKjB,IAAA;AAAA"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { RankedItem } from "./rrf.mjs";
|
|
2
|
+
|
|
3
|
+
//#region ../@warlock.js/ai/src/rag/hybrid/bm25.d.ts
|
|
4
|
+
/** A document to score lexically. */
|
|
5
|
+
type LexicalDoc = {
|
|
6
|
+
id: string;
|
|
7
|
+
text: string;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Rank `docs` against `query` with BM25 (A4) — the lexical half of hybrid
|
|
11
|
+
* retrieval. Scores keyword overlap with TF saturation (`k1`) and length
|
|
12
|
+
* normalization (`b`) over the candidate set, so an exact-term match
|
|
13
|
+
* surfaces even when dense embeddings miss it. Returns docs sorted by
|
|
14
|
+
* score (highest first); zero-score docs are dropped.
|
|
15
|
+
*
|
|
16
|
+
* Operates over the supplied candidate set (typically the dense retriever's
|
|
17
|
+
* over-fetch), so it needs no global corpus index — ideal for fusing with
|
|
18
|
+
* a vector ranking via {@link reciprocalRankFusion}.
|
|
19
|
+
*/
|
|
20
|
+
declare function bm25Rank(query: string, docs: ReadonlyArray<LexicalDoc>): RankedItem[];
|
|
21
|
+
//#endregion
|
|
22
|
+
export { LexicalDoc, bm25Rank };
|
|
23
|
+
//# sourceMappingURL=bm25.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bm25.d.mts","names":[],"sources":["../../../../../../../../@warlock.js/ai/src/rag/hybrid/bm25.ts"],"mappings":";;;;KAGY,UAAA;EAAe,EAAA;EAAY,IAAI;AAAA;;AAAA;AAwB3C;;;;;;;;;iBAAgB,QAAA,CAAS,KAAA,UAAe,IAAA,EAAM,aAAA,CAAc,UAAA,IAAc,UAAA"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
//#region ../@warlock.js/ai/src/rag/hybrid/bm25.ts
|
|
2
|
+
const BM25_K1 = 1.5;
|
|
3
|
+
const BM25_B = .75;
|
|
4
|
+
/** Lowercase + split on non-word characters; drop empties. */
|
|
5
|
+
function tokenize(text) {
|
|
6
|
+
return text.toLowerCase().split(/[^a-z0-9]+/i).filter(Boolean);
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Rank `docs` against `query` with BM25 (A4) — the lexical half of hybrid
|
|
10
|
+
* retrieval. Scores keyword overlap with TF saturation (`k1`) and length
|
|
11
|
+
* normalization (`b`) over the candidate set, so an exact-term match
|
|
12
|
+
* surfaces even when dense embeddings miss it. Returns docs sorted by
|
|
13
|
+
* score (highest first); zero-score docs are dropped.
|
|
14
|
+
*
|
|
15
|
+
* Operates over the supplied candidate set (typically the dense retriever's
|
|
16
|
+
* over-fetch), so it needs no global corpus index — ideal for fusing with
|
|
17
|
+
* a vector ranking via {@link reciprocalRankFusion}.
|
|
18
|
+
*/
|
|
19
|
+
function bm25Rank(query, docs) {
|
|
20
|
+
const queryTerms = [...new Set(tokenize(query))];
|
|
21
|
+
if (queryTerms.length === 0 || docs.length === 0) return [];
|
|
22
|
+
const tokenized = docs.map((doc) => ({
|
|
23
|
+
id: doc.id,
|
|
24
|
+
terms: tokenize(doc.text)
|
|
25
|
+
}));
|
|
26
|
+
const avgLen = tokenized.reduce((sum, d) => sum + d.terms.length, 0) / tokenized.length || 1;
|
|
27
|
+
const df = /* @__PURE__ */ new Map();
|
|
28
|
+
for (const term of queryTerms) df.set(term, tokenized.filter((d) => d.terms.includes(term)).length);
|
|
29
|
+
const n = tokenized.length;
|
|
30
|
+
return tokenized.map((doc) => {
|
|
31
|
+
const len = doc.terms.length || 1;
|
|
32
|
+
let score = 0;
|
|
33
|
+
for (const term of queryTerms) {
|
|
34
|
+
const tf = doc.terms.filter((t) => t === term).length;
|
|
35
|
+
if (tf === 0) continue;
|
|
36
|
+
const docFreq = df.get(term) ?? 0;
|
|
37
|
+
const idf = Math.log(1 + (n - docFreq + .5) / (docFreq + .5));
|
|
38
|
+
const numerator = tf * 2.5;
|
|
39
|
+
const denominator = tf + BM25_K1 * (1 - BM25_B + BM25_B * (len / avgLen));
|
|
40
|
+
score += idf * (numerator / denominator);
|
|
41
|
+
}
|
|
42
|
+
return {
|
|
43
|
+
id: doc.id,
|
|
44
|
+
score
|
|
45
|
+
};
|
|
46
|
+
}).filter((item) => item.score > 0).sort((a, b) => b.score - a.score);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
//#endregion
|
|
50
|
+
export { bm25Rank };
|
|
51
|
+
//# sourceMappingURL=bm25.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bm25.mjs","names":[],"sources":["../../../../../../../../@warlock.js/ai/src/rag/hybrid/bm25.ts"],"sourcesContent":["import type { RankedItem } from \"./rrf\";\n\n/** A document to score lexically. */\nexport type LexicalDoc = { id: string; text: string };\n\nconst BM25_K1 = 1.5;\nconst BM25_B = 0.75;\n\n/** Lowercase + split on non-word characters; drop empties. */\nfunction tokenize(text: string): string[] {\n return text\n .toLowerCase()\n .split(/[^a-z0-9]+/i)\n .filter(Boolean);\n}\n\n/**\n * Rank `docs` against `query` with BM25 (A4) — the lexical half of hybrid\n * retrieval. Scores keyword overlap with TF saturation (`k1`) and length\n * normalization (`b`) over the candidate set, so an exact-term match\n * surfaces even when dense embeddings miss it. Returns docs sorted by\n * score (highest first); zero-score docs are dropped.\n *\n * Operates over the supplied candidate set (typically the dense retriever's\n * over-fetch), so it needs no global corpus index — ideal for fusing with\n * a vector ranking via {@link reciprocalRankFusion}.\n */\nexport function bm25Rank(query: string, docs: ReadonlyArray<LexicalDoc>): RankedItem[] {\n const queryTerms = [...new Set(tokenize(query))];\n if (queryTerms.length === 0 || docs.length === 0) return [];\n\n const tokenized = docs.map(doc => ({ id: doc.id, terms: tokenize(doc.text) }));\n const avgLen =\n tokenized.reduce((sum, d) => sum + d.terms.length, 0) / tokenized.length || 1;\n\n // Document frequency per query term, across the candidate set.\n const df = new Map<string, number>();\n for (const term of queryTerms) {\n df.set(\n term,\n tokenized.filter(d => d.terms.includes(term)).length,\n );\n }\n\n const n = tokenized.length;\n\n const scored = tokenized.map(doc => {\n const len = doc.terms.length || 1;\n let score = 0;\n\n for (const term of queryTerms) {\n const tf = doc.terms.filter(t => t === term).length;\n if (tf === 0) continue;\n\n const docFreq = df.get(term) ?? 0;\n // BM25 idf (with the +1 to keep it non-negative).\n const idf = Math.log(1 + (n - docFreq + 0.5) / (docFreq + 0.5));\n const numerator = tf * (BM25_K1 + 1);\n const denominator = tf + BM25_K1 * (1 - BM25_B + BM25_B * (len / avgLen));\n score += idf * (numerator / denominator);\n }\n\n return { id: doc.id, score };\n });\n\n return scored.filter(item => item.score > 0).sort((a, b) => b.score - a.score);\n}\n"],"mappings":";AAKA,MAAM,UAAU;AAChB,MAAM,SAAS;;AAGf,SAAS,SAAS,MAAwB;CACxC,OAAO,KACJ,YAAY,CAAC,CACb,MAAM,aAAa,CAAC,CACpB,OAAO,OAAO;AACnB;;;;;;;;;;;;AAaA,SAAgB,SAAS,OAAe,MAA+C;CACrF,MAAM,aAAa,CAAC,GAAG,IAAI,IAAI,SAAS,KAAK,CAAC,CAAC;CAC/C,IAAI,WAAW,WAAW,KAAK,KAAK,WAAW,GAAG,OAAO,CAAC;CAE1D,MAAM,YAAY,KAAK,KAAI,SAAQ;EAAE,IAAI,IAAI;EAAI,OAAO,SAAS,IAAI,IAAI;CAAE,EAAE;CAC7E,MAAM,SACJ,UAAU,QAAQ,KAAK,MAAM,MAAM,EAAE,MAAM,QAAQ,CAAC,IAAI,UAAU,UAAU;CAG9E,MAAM,qBAAK,IAAI,IAAoB;CACnC,KAAK,MAAM,QAAQ,YACjB,GAAG,IACD,MACA,UAAU,QAAO,MAAK,EAAE,MAAM,SAAS,IAAI,CAAC,CAAC,CAAC,MAChD;CAGF,MAAM,IAAI,UAAU;CAqBpB,OAnBe,UAAU,KAAI,QAAO;EAClC,MAAM,MAAM,IAAI,MAAM,UAAU;EAChC,IAAI,QAAQ;EAEZ,KAAK,MAAM,QAAQ,YAAY;GAC7B,MAAM,KAAK,IAAI,MAAM,QAAO,MAAK,MAAM,IAAI,CAAC,CAAC;GAC7C,IAAI,OAAO,GAAG;GAEd,MAAM,UAAU,GAAG,IAAI,IAAI,KAAK;GAEhC,MAAM,MAAM,KAAK,IAAI,KAAK,IAAI,UAAU,OAAQ,UAAU,GAAI;GAC9D,MAAM,YAAY,KAAM;GACxB,MAAM,cAAc,KAAK,WAAW,IAAI,SAAS,UAAU,MAAM;GACjE,SAAS,OAAO,YAAY;EAC9B;EAEA,OAAO;GAAE,IAAI,IAAI;GAAI;EAAM;CAC7B,CAEY,CAAC,CAAC,QAAO,SAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK;AAC/E"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { RankedItem } from "./rrf.mjs";
|
|
2
|
+
import { LexicalDoc } from "./bm25.mjs";
|
|
3
|
+
|
|
4
|
+
//#region ../@warlock.js/ai/src/rag/hybrid/hybrid-rank.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* Hybrid rank (A4) — fuse a dense (vector) ranking with a BM25 lexical
|
|
7
|
+
* ranking over the same candidate set via Reciprocal Rank Fusion. Dense
|
|
8
|
+
* retrieval captures semantic similarity; BM25 captures exact-term
|
|
9
|
+
* matches dense embeddings miss (names, ids, rare tokens). Fusing both
|
|
10
|
+
* beats either alone for keyword-heavy queries.
|
|
11
|
+
*
|
|
12
|
+
* `dense` is the vector retriever's result in rank order; `candidates`
|
|
13
|
+
* supplies the text for the lexical pass (typically the same over-fetched
|
|
14
|
+
* set). Returns the fused ranking, highest score first.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* const fused = hybridRank({
|
|
18
|
+
* query: "invoice 8842 refund",
|
|
19
|
+
* dense: vectorHits, // [{ id }, ...] in similarity order
|
|
20
|
+
* candidates: vectorHits.map(h => ({ id: h.id, text: h.text })),
|
|
21
|
+
* });
|
|
22
|
+
*/
|
|
23
|
+
declare function hybridRank(params: {
|
|
24
|
+
query: string;
|
|
25
|
+
dense: ReadonlyArray<{
|
|
26
|
+
id: string;
|
|
27
|
+
}>;
|
|
28
|
+
candidates: ReadonlyArray<LexicalDoc>;
|
|
29
|
+
k?: number;
|
|
30
|
+
}): RankedItem[];
|
|
31
|
+
//#endregion
|
|
32
|
+
export { hybridRank };
|
|
33
|
+
//# sourceMappingURL=hybrid-rank.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hybrid-rank.d.mts","names":[],"sources":["../../../../../../../../@warlock.js/ai/src/rag/hybrid/hybrid-rank.ts"],"mappings":";;;;;;AAqBA;;;;;;;;;;;;;;;;iBAAgB,UAAA,CAAW,MAAA;EACzB,KAAA;EACA,KAAA,EAAO,aAAA;IAAgB,EAAA;EAAA;EACvB,UAAA,EAAY,aAAA,CAAc,UAAA;EAC1B,CAAA;AAAA,IACE,UAAA"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { reciprocalRankFusion } from "./rrf.mjs";
|
|
2
|
+
import { bm25Rank } from "./bm25.mjs";
|
|
3
|
+
|
|
4
|
+
//#region ../@warlock.js/ai/src/rag/hybrid/hybrid-rank.ts
|
|
5
|
+
/**
|
|
6
|
+
* Hybrid rank (A4) — fuse a dense (vector) ranking with a BM25 lexical
|
|
7
|
+
* ranking over the same candidate set via Reciprocal Rank Fusion. Dense
|
|
8
|
+
* retrieval captures semantic similarity; BM25 captures exact-term
|
|
9
|
+
* matches dense embeddings miss (names, ids, rare tokens). Fusing both
|
|
10
|
+
* beats either alone for keyword-heavy queries.
|
|
11
|
+
*
|
|
12
|
+
* `dense` is the vector retriever's result in rank order; `candidates`
|
|
13
|
+
* supplies the text for the lexical pass (typically the same over-fetched
|
|
14
|
+
* set). Returns the fused ranking, highest score first.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* const fused = hybridRank({
|
|
18
|
+
* query: "invoice 8842 refund",
|
|
19
|
+
* dense: vectorHits, // [{ id }, ...] in similarity order
|
|
20
|
+
* candidates: vectorHits.map(h => ({ id: h.id, text: h.text })),
|
|
21
|
+
* });
|
|
22
|
+
*/
|
|
23
|
+
function hybridRank(params) {
|
|
24
|
+
return reciprocalRankFusion([params.dense.map((d) => d.id), bm25Rank(params.query, params.candidates).map((r) => r.id)], params.k);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
//#endregion
|
|
28
|
+
export { hybridRank };
|
|
29
|
+
//# sourceMappingURL=hybrid-rank.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hybrid-rank.mjs","names":[],"sources":["../../../../../../../../@warlock.js/ai/src/rag/hybrid/hybrid-rank.ts"],"sourcesContent":["import { bm25Rank, type LexicalDoc } from \"./bm25\";\nimport { reciprocalRankFusion, type RankedItem } from \"./rrf\";\n\n/**\n * Hybrid rank (A4) — fuse a dense (vector) ranking with a BM25 lexical\n * ranking over the same candidate set via Reciprocal Rank Fusion. Dense\n * retrieval captures semantic similarity; BM25 captures exact-term\n * matches dense embeddings miss (names, ids, rare tokens). Fusing both\n * beats either alone for keyword-heavy queries.\n *\n * `dense` is the vector retriever's result in rank order; `candidates`\n * supplies the text for the lexical pass (typically the same over-fetched\n * set). Returns the fused ranking, highest score first.\n *\n * @example\n * const fused = hybridRank({\n * query: \"invoice 8842 refund\",\n * dense: vectorHits, // [{ id }, ...] in similarity order\n * candidates: vectorHits.map(h => ({ id: h.id, text: h.text })),\n * });\n */\nexport function hybridRank(params: {\n query: string;\n dense: ReadonlyArray<{ id: string }>;\n candidates: ReadonlyArray<LexicalDoc>;\n k?: number;\n}): RankedItem[] {\n const denseIds = params.dense.map(d => d.id);\n const lexicalIds = bm25Rank(params.query, params.candidates).map(r => r.id);\n\n return reciprocalRankFusion([denseIds, lexicalIds], params.k);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAqBA,SAAgB,WAAW,QAKV;CAIf,OAAO,qBAAqB,CAHX,OAAO,MAAM,KAAI,MAAK,EAAE,EAGL,GAFjB,SAAS,OAAO,OAAO,OAAO,UAAU,CAAC,CAAC,KAAI,MAAK,EAAE,EAExB,CAAC,GAAG,OAAO,CAAC;AAC9D"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
//#region ../@warlock.js/ai/src/rag/hybrid/rrf.d.ts
|
|
2
|
+
/** One item's id paired with a fused relevance score. */
|
|
3
|
+
type RankedItem = {
|
|
4
|
+
id: string;
|
|
5
|
+
score: number;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Reciprocal Rank Fusion (A4) — combine several independently-ranked
|
|
9
|
+
* lists of ids into one consensus ranking. Each list contributes
|
|
10
|
+
* `1 / (k + rank)` to an id's score (rank is 0-based within that list), so
|
|
11
|
+
* an id near the top of multiple lists rises even if no single list ranks
|
|
12
|
+
* it first. The classic fusion for hybrid (dense + lexical) retrieval
|
|
13
|
+
* because it needs no score calibration between the lists.
|
|
14
|
+
*
|
|
15
|
+
* `k` (default 60, the standard) dampens the contribution of lower ranks.
|
|
16
|
+
* Returns ids sorted by fused score, highest first.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* reciprocalRankFusion([["a", "b", "c"], ["b", "a"]]);
|
|
20
|
+
* // → [{ id: "b", ... }, { id: "a", ... }, { id: "c", ... }]
|
|
21
|
+
*/
|
|
22
|
+
declare function reciprocalRankFusion(rankedLists: ReadonlyArray<ReadonlyArray<string>>, k?: number): RankedItem[];
|
|
23
|
+
//#endregion
|
|
24
|
+
export { RankedItem, reciprocalRankFusion };
|
|
25
|
+
//# sourceMappingURL=rrf.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rrf.d.mts","names":[],"sources":["../../../../../../../../@warlock.js/ai/src/rag/hybrid/rrf.ts"],"mappings":";;KACY,UAAA;EAAe,EAAA;EAAY,KAAK;AAAA;AAAA;AAiB5C;;;;;;;;;;;;;;AAjB4C,iBAiB5B,oBAAA,CACd,WAAA,EAAa,aAAA,CAAc,aAAA,WAC3B,CAAA,YACC,UAAA"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
//#region ../@warlock.js/ai/src/rag/hybrid/rrf.ts
|
|
2
|
+
/**
|
|
3
|
+
* Reciprocal Rank Fusion (A4) — combine several independently-ranked
|
|
4
|
+
* lists of ids into one consensus ranking. Each list contributes
|
|
5
|
+
* `1 / (k + rank)` to an id's score (rank is 0-based within that list), so
|
|
6
|
+
* an id near the top of multiple lists rises even if no single list ranks
|
|
7
|
+
* it first. The classic fusion for hybrid (dense + lexical) retrieval
|
|
8
|
+
* because it needs no score calibration between the lists.
|
|
9
|
+
*
|
|
10
|
+
* `k` (default 60, the standard) dampens the contribution of lower ranks.
|
|
11
|
+
* Returns ids sorted by fused score, highest first.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* reciprocalRankFusion([["a", "b", "c"], ["b", "a"]]);
|
|
15
|
+
* // → [{ id: "b", ... }, { id: "a", ... }, { id: "c", ... }]
|
|
16
|
+
*/
|
|
17
|
+
function reciprocalRankFusion(rankedLists, k = 60) {
|
|
18
|
+
const scores = /* @__PURE__ */ new Map();
|
|
19
|
+
for (const list of rankedLists) list.forEach((id, rank) => {
|
|
20
|
+
scores.set(id, (scores.get(id) ?? 0) + 1 / (k + rank));
|
|
21
|
+
});
|
|
22
|
+
return [...scores.entries()].map(([id, score]) => ({
|
|
23
|
+
id,
|
|
24
|
+
score
|
|
25
|
+
})).sort((a, b) => b.score - a.score);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
//#endregion
|
|
29
|
+
export { reciprocalRankFusion };
|
|
30
|
+
//# sourceMappingURL=rrf.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rrf.mjs","names":[],"sources":["../../../../../../../../@warlock.js/ai/src/rag/hybrid/rrf.ts"],"sourcesContent":["/** One item's id paired with a fused relevance score. */\nexport type RankedItem = { id: string; score: number };\n\n/**\n * Reciprocal Rank Fusion (A4) — combine several independently-ranked\n * lists of ids into one consensus ranking. Each list contributes\n * `1 / (k + rank)` to an id's score (rank is 0-based within that list), so\n * an id near the top of multiple lists rises even if no single list ranks\n * it first. The classic fusion for hybrid (dense + lexical) retrieval\n * because it needs no score calibration between the lists.\n *\n * `k` (default 60, the standard) dampens the contribution of lower ranks.\n * Returns ids sorted by fused score, highest first.\n *\n * @example\n * reciprocalRankFusion([[\"a\", \"b\", \"c\"], [\"b\", \"a\"]]);\n * // → [{ id: \"b\", ... }, { id: \"a\", ... }, { id: \"c\", ... }]\n */\nexport function reciprocalRankFusion(\n rankedLists: ReadonlyArray<ReadonlyArray<string>>,\n k = 60,\n): RankedItem[] {\n const scores = new Map<string, number>();\n\n for (const list of rankedLists) {\n list.forEach((id, rank) => {\n scores.set(id, (scores.get(id) ?? 0) + 1 / (k + rank));\n });\n }\n\n return [...scores.entries()]\n .map(([id, score]) => ({ id, score }))\n .sort((a, b) => b.score - a.score);\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAkBA,SAAgB,qBACd,aACA,IAAI,IACU;CACd,MAAM,yBAAS,IAAI,IAAoB;CAEvC,KAAK,MAAM,QAAQ,aACjB,KAAK,SAAS,IAAI,SAAS;EACzB,OAAO,IAAI,KAAK,OAAO,IAAI,EAAE,KAAK,KAAK,KAAK,IAAI,KAAK;CACvD,CAAC;CAGH,OAAO,CAAC,GAAG,OAAO,QAAQ,CAAC,CAAC,CACzB,KAAK,CAAC,IAAI,YAAY;EAAE;EAAI;CAAM,EAAE,CAAC,CACrC,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK;AACrC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Citation, RetrieveOptions, RetrieveResult, RetrievedChunk } from "./contracts/citation.type.mjs";
|
|
2
|
+
import { RagReranker } from "./rerank/reranker.contract.mjs";
|
|
3
|
+
import { Chunk, ChunkOptions, ChunkType } from "./contracts/chunk-options.type.mjs";
|
|
4
|
+
import { RagDocument } from "./contracts/rag-document.type.mjs";
|
|
5
|
+
import { Rag, RagAsToolOptions, RagConfig } from "./contracts/rag-config.type.mjs";
|
|
6
|
+
import { rag } from "./rag.mjs";
|
|
7
|
+
import { chunk } from "./chunk/chunk.mjs";
|
|
8
|
+
import { VectorStore } from "./store/vector-store.contract.mjs";
|
|
9
|
+
import { cacheVectorStore } from "./store/cache-vector-store.mjs";
|
|
10
|
+
import { KeywordRerankerOptions, keywordReranker } from "./rerank/keyword-reranker.mjs";
|
|
11
|
+
import { LlmRerankerOptions, llmReranker } from "./rerank/llm-reranker.mjs";
|
|
12
|
+
import { RankedItem, reciprocalRankFusion } from "./hybrid/rrf.mjs";
|
|
13
|
+
import { LexicalDoc, bm25Rank } from "./hybrid/bm25.mjs";
|
|
14
|
+
import { hybridRank } from "./hybrid/hybrid-rank.mjs";
|
|
15
|
+
import { MultiQueryOptions, multiQuery } from "./transforms/multi-query.mjs";
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { chunk } from "./chunk/chunk.mjs";
|
|
2
|
+
import { cacheVectorStore } from "./store/cache-vector-store.mjs";
|
|
3
|
+
import { rag } from "./rag.mjs";
|
|
4
|
+
import { keywordReranker } from "./rerank/keyword-reranker.mjs";
|
|
5
|
+
import { llmReranker } from "./rerank/llm-reranker.mjs";
|
|
6
|
+
import { reciprocalRankFusion } from "./hybrid/rrf.mjs";
|
|
7
|
+
import { bm25Rank } from "./hybrid/bm25.mjs";
|
|
8
|
+
import { hybridRank } from "./hybrid/hybrid-rank.mjs";
|
|
9
|
+
import { multiQuery } from "./transforms/multi-query.mjs";
|
|
10
|
+
|
|
11
|
+
export { };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Rag, RagConfig } from "./contracts/rag-config.type.mjs";
|
|
2
|
+
|
|
3
|
+
//#region ../@warlock.js/ai/src/rag/rag.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Create a RAG pipeline: **chunk → embed → vector store → retrieve →
|
|
6
|
+
* rerank → cite**, reusing the app's `ai.embedder` for embedding, a
|
|
7
|
+
* `@warlock.js/cache` `CacheDriver` as the vector store, and the
|
|
8
|
+
* composite-as-tool engine to expose retrieval as a tool.
|
|
9
|
+
*
|
|
10
|
+
* Resolution is loud at construction (mirroring `memory()`):
|
|
11
|
+
* - `embedder` is required — a provider with no embedder must be caught
|
|
12
|
+
* here, not at first index.
|
|
13
|
+
* - `store` falls back to `ai.config({ defaultStore })`; if neither
|
|
14
|
+
* resolves, construction throws.
|
|
15
|
+
*
|
|
16
|
+
* `retrieve()` is return-only — it never auto-injects into a prompt; the
|
|
17
|
+
* caller formats the cited chunks (or uses `asTool()` for the agent loop).
|
|
18
|
+
* The reranker is OFF by default (cosine-only) unless `config.reranker`
|
|
19
|
+
* is set.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* import { ai } from "@warlock.js/ai";
|
|
23
|
+
* import { MemoryCacheDriver } from "@warlock.js/cache";
|
|
24
|
+
*
|
|
25
|
+
* const kb = ai.rag({
|
|
26
|
+
* name: "docs",
|
|
27
|
+
* embedder: openai.embedder({ name: "text-embedding-3-small" }),
|
|
28
|
+
* store: new MemoryCacheDriver(),
|
|
29
|
+
* chunk: { type: "markdown", size: 800, overlap: 120 },
|
|
30
|
+
* });
|
|
31
|
+
*
|
|
32
|
+
* await kb.index([{ id: "guide", text: longMarkdown, metadata: { url: "/guide" } }]);
|
|
33
|
+
* const { chunks } = await kb.retrieve("how do I configure caching?", { topK: 4 });
|
|
34
|
+
*/
|
|
35
|
+
declare function rag(config: RagConfig): Rag;
|
|
36
|
+
//#endregion
|
|
37
|
+
export { rag };
|
|
38
|
+
//# sourceMappingURL=rag.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rag.d.mts","names":[],"sources":["../../../../../../../@warlock.js/ai/src/rag/rag.ts"],"mappings":";;;;;AAyDA;;;;;;;;AAA2C;;;;;;;;;;;;;;;;;;;;;iBAA3B,GAAA,CAAI,MAAA,EAAQ,SAAA,GAAY,GAAG"}
|