@warlock.js/core 4.8.0 → 4.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/esm/connectors/ai-connector.mjs +1 -1
- package/package.json +12 -9
- package/esm/ai/src/agent/agent-input-builder.mjs +0 -133
- package/esm/ai/src/agent/agent-input-builder.mjs.map +0 -1
- package/esm/ai/src/agent/agent-log-event.mjs +0 -101
- package/esm/ai/src/agent/agent-log-event.mjs.map +0 -1
- package/esm/ai/src/agent/agent-stream.mjs +0 -82
- package/esm/ai/src/agent/agent-stream.mjs.map +0 -1
- package/esm/ai/src/agent/agent-to-stream-event.mjs +0 -86
- package/esm/ai/src/agent/agent-to-stream-event.mjs.map +0 -1
- package/esm/ai/src/agent/agent.mjs +0 -1276
- package/esm/ai/src/agent/agent.mjs.map +0 -1
- package/esm/ai/src/agent/index.mjs +0 -5
- package/esm/ai/src/agent/json-stream-guard.mjs +0 -400
- package/esm/ai/src/agent/json-stream-guard.mjs.map +0 -1
- package/esm/ai/src/agent/signature.mjs +0 -57
- package/esm/ai/src/agent/signature.mjs.map +0 -1
- package/esm/ai/src/agent/snapshot.mjs +0 -101
- package/esm/ai/src/agent/snapshot.mjs.map +0 -1
- package/esm/ai/src/agent/spawn-sub-agent.mjs +0 -68
- package/esm/ai/src/agent/spawn-sub-agent.mjs.map +0 -1
- package/esm/ai/src/ai.mjs +0 -191
- package/esm/ai/src/ai.mjs.map +0 -1
- package/esm/ai/src/batch/batch.mjs +0 -198
- package/esm/ai/src/batch/batch.mjs.map +0 -1
- package/esm/ai/src/batch/index.mjs +0 -3
- package/esm/ai/src/batch/run-batch-item.mjs +0 -100
- package/esm/ai/src/batch/run-batch-item.mjs.map +0 -1
- package/esm/ai/src/batch/run-with-concurrency.mjs +0 -39
- package/esm/ai/src/batch/run-with-concurrency.mjs.map +0 -1
- package/esm/ai/src/checkpoint/memory.mjs +0 -0
- package/esm/ai/src/checkpoint/memory.mjs.map +0 -1
- package/esm/ai/src/checkpoint/pg.mjs +0 -265
- package/esm/ai/src/checkpoint/pg.mjs.map +0 -1
- package/esm/ai/src/checkpoint/redis.mjs +0 -200
- package/esm/ai/src/checkpoint/redis.mjs.map +0 -1
- package/esm/ai/src/config.mjs +0 -59
- package/esm/ai/src/config.mjs.map +0 -1
- package/esm/ai/src/contracts/end.type.mjs +0 -47
- package/esm/ai/src/contracts/end.type.mjs.map +0 -1
- package/esm/ai/src/errors/agent-cancelled-error.mjs +0 -43
- package/esm/ai/src/errors/agent-cancelled-error.mjs.map +0 -1
- package/esm/ai/src/errors/agent-drift-error.mjs +0 -31
- package/esm/ai/src/errors/agent-drift-error.mjs.map +0 -1
- package/esm/ai/src/errors/agent-execution-error.mjs +0 -35
- package/esm/ai/src/errors/agent-execution-error.mjs.map +0 -1
- package/esm/ai/src/errors/agent-max-trips-error.mjs +0 -41
- package/esm/ai/src/errors/agent-max-trips-error.mjs.map +0 -1
- package/esm/ai/src/errors/ai-error.mjs +0 -68
- package/esm/ai/src/errors/ai-error.mjs.map +0 -1
- package/esm/ai/src/errors/budget-exceeded-error.mjs +0 -31
- package/esm/ai/src/errors/budget-exceeded-error.mjs.map +0 -1
- package/esm/ai/src/errors/content-filter-error.mjs +0 -28
- package/esm/ai/src/errors/content-filter-error.mjs.map +0 -1
- package/esm/ai/src/errors/context-length-exceeded-error.mjs +0 -31
- package/esm/ai/src/errors/context-length-exceeded-error.mjs.map +0 -1
- package/esm/ai/src/errors/guardrail-violation-error.mjs +0 -41
- package/esm/ai/src/errors/guardrail-violation-error.mjs.map +0 -1
- package/esm/ai/src/errors/index.mjs +0 -40
- package/esm/ai/src/errors/invalid-request-error.mjs +0 -31
- package/esm/ai/src/errors/invalid-request-error.mjs.map +0 -1
- package/esm/ai/src/errors/max-iterations-error.mjs +0 -32
- package/esm/ai/src/errors/max-iterations-error.mjs.map +0 -1
- package/esm/ai/src/errors/max-steps-exceeded-error.mjs +0 -21
- package/esm/ai/src/errors/max-steps-exceeded-error.mjs.map +0 -1
- package/esm/ai/src/errors/orchestrator-cancelled-error.mjs +0 -31
- package/esm/ai/src/errors/orchestrator-cancelled-error.mjs.map +0 -1
- package/esm/ai/src/errors/orchestrator-config-error.mjs +0 -30
- package/esm/ai/src/errors/orchestrator-config-error.mjs.map +0 -1
- package/esm/ai/src/errors/orchestrator-drift-error.mjs +0 -37
- package/esm/ai/src/errors/orchestrator-drift-error.mjs.map +0 -1
- package/esm/ai/src/errors/orchestrator-failed-error.mjs +0 -36
- package/esm/ai/src/errors/orchestrator-failed-error.mjs.map +0 -1
- package/esm/ai/src/errors/outbound-policy-error.mjs +0 -32
- package/esm/ai/src/errors/outbound-policy-error.mjs.map +0 -1
- package/esm/ai/src/errors/planner-cancelled-error.mjs +0 -29
- package/esm/ai/src/errors/planner-cancelled-error.mjs.map +0 -1
- package/esm/ai/src/errors/planner-drift-error.mjs +0 -33
- package/esm/ai/src/errors/planner-drift-error.mjs.map +0 -1
- package/esm/ai/src/errors/planner-failed-error.mjs +0 -37
- package/esm/ai/src/errors/planner-failed-error.mjs.map +0 -1
- package/esm/ai/src/errors/planner-plan-invalid-error.mjs +0 -25
- package/esm/ai/src/errors/planner-plan-invalid-error.mjs.map +0 -1
- package/esm/ai/src/errors/prompt-refinement-error.mjs +0 -27
- package/esm/ai/src/errors/prompt-refinement-error.mjs.map +0 -1
- package/esm/ai/src/errors/provider-auth-error.mjs +0 -26
- package/esm/ai/src/errors/provider-auth-error.mjs.map +0 -1
- package/esm/ai/src/errors/provider-error.mjs +0 -42
- package/esm/ai/src/errors/provider-error.mjs.map +0 -1
- package/esm/ai/src/errors/provider-rate-limit-error.mjs +0 -31
- package/esm/ai/src/errors/provider-rate-limit-error.mjs.map +0 -1
- package/esm/ai/src/errors/provider-timeout-error.mjs +0 -26
- package/esm/ai/src/errors/provider-timeout-error.mjs.map +0 -1
- package/esm/ai/src/errors/quota-exceeded-error.mjs +0 -40
- package/esm/ai/src/errors/quota-exceeded-error.mjs.map +0 -1
- package/esm/ai/src/errors/routing-error.mjs +0 -23
- package/esm/ai/src/errors/routing-error.mjs.map +0 -1
- package/esm/ai/src/errors/schema-validation-error.mjs +0 -37
- package/esm/ai/src/errors/schema-validation-error.mjs.map +0 -1
- package/esm/ai/src/errors/step-failed-error.mjs +0 -19
- package/esm/ai/src/errors/step-failed-error.mjs.map +0 -1
- package/esm/ai/src/errors/supervisor-cancelled-error.mjs +0 -29
- package/esm/ai/src/errors/supervisor-cancelled-error.mjs.map +0 -1
- package/esm/ai/src/errors/supervisor-drift-error.mjs +0 -30
- package/esm/ai/src/errors/supervisor-drift-error.mjs.map +0 -1
- package/esm/ai/src/errors/supervisor-failed-error.mjs +0 -43
- package/esm/ai/src/errors/supervisor-failed-error.mjs.map +0 -1
- package/esm/ai/src/errors/supervisor-routing-error.mjs +0 -39
- package/esm/ai/src/errors/supervisor-routing-error.mjs.map +0 -1
- package/esm/ai/src/errors/tool-execution-error.mjs +0 -32
- package/esm/ai/src/errors/tool-execution-error.mjs.map +0 -1
- package/esm/ai/src/errors/workflow-cancelled-error.mjs +0 -23
- package/esm/ai/src/errors/workflow-cancelled-error.mjs.map +0 -1
- package/esm/ai/src/errors/workflow-drift-error.mjs +0 -24
- package/esm/ai/src/errors/workflow-drift-error.mjs.map +0 -1
- package/esm/ai/src/errors/workflow-error.mjs +0 -18
- package/esm/ai/src/errors/workflow-error.mjs.map +0 -1
- package/esm/ai/src/eval/dataset.mjs +0 -112
- package/esm/ai/src/eval/dataset.mjs.map +0 -1
- package/esm/ai/src/eval/eval-runner.mjs +0 -135
- package/esm/ai/src/eval/eval-runner.mjs.map +0 -1
- package/esm/ai/src/eval/index.mjs +0 -48
- package/esm/ai/src/eval/index.mjs.map +0 -1
- package/esm/ai/src/eval/judge-scorer.mjs +0 -87
- package/esm/ai/src/eval/judge-scorer.mjs.map +0 -1
- package/esm/ai/src/eval/regression.mjs +0 -51
- package/esm/ai/src/eval/regression.mjs.map +0 -1
- package/esm/ai/src/eval/report-json.mjs +0 -33
- package/esm/ai/src/eval/report-json.mjs.map +0 -1
- package/esm/ai/src/eval/report-junit.mjs +0 -60
- package/esm/ai/src/eval/report-junit.mjs.map +0 -1
- package/esm/ai/src/eval/scorers.mjs +0 -101
- package/esm/ai/src/eval/scorers.mjs.map +0 -1
- package/esm/ai/src/guard/detectors/index.mjs +0 -6
- package/esm/ai/src/guard/detectors/injection.mjs +0 -254
- package/esm/ai/src/guard/detectors/injection.mjs.map +0 -1
- package/esm/ai/src/guard/detectors/moderation.mjs +0 -134
- package/esm/ai/src/guard/detectors/moderation.mjs.map +0 -1
- package/esm/ai/src/guard/detectors/pii.mjs +0 -199
- package/esm/ai/src/guard/detectors/pii.mjs.map +0 -1
- package/esm/ai/src/guard/detectors/topic.mjs +0 -99
- package/esm/ai/src/guard/detectors/topic.mjs.map +0 -1
- package/esm/ai/src/guard/errors.mjs +0 -18
- package/esm/ai/src/guard/errors.mjs.map +0 -1
- package/esm/ai/src/guard/guard.mjs +0 -209
- package/esm/ai/src/guard/guard.mjs.map +0 -1
- package/esm/ai/src/guard/guardrail.mjs +0 -22
- package/esm/ai/src/guard/guardrail.mjs.map +0 -1
- package/esm/ai/src/human/errors.mjs +0 -60
- package/esm/ai/src/human/errors.mjs.map +0 -1
- package/esm/ai/src/human/human-approval.mjs +0 -170
- package/esm/ai/src/human/human-approval.mjs.map +0 -1
- package/esm/ai/src/human/policy.mjs +0 -67
- package/esm/ai/src/human/policy.mjs.map +0 -1
- package/esm/ai/src/human/register.mjs +0 -37
- package/esm/ai/src/human/register.mjs.map +0 -1
- package/esm/ai/src/human/resume-seed.mjs +0 -53
- package/esm/ai/src/human/resume-seed.mjs.map +0 -1
- package/esm/ai/src/human/resume.mjs +0 -121
- package/esm/ai/src/human/resume.mjs.map +0 -1
- package/esm/ai/src/human/stores/index.mjs +0 -5
- package/esm/ai/src/human/stores/memory.mjs +0 -91
- package/esm/ai/src/human/stores/memory.mjs.map +0 -1
- package/esm/ai/src/human/stores/pg.mjs +0 -220
- package/esm/ai/src/human/stores/pg.mjs.map +0 -1
- package/esm/ai/src/human/stores/redis.mjs +0 -201
- package/esm/ai/src/human/stores/redis.mjs.map +0 -1
- package/esm/ai/src/image/image-cost.mjs +0 -55
- package/esm/ai/src/image/image-cost.mjs.map +0 -1
- package/esm/ai/src/image/image.mjs +0 -112
- package/esm/ai/src/image/image.mjs.map +0 -1
- package/esm/ai/src/image/index.mjs +0 -4
- package/esm/ai/src/index.mjs +0 -196
- package/esm/ai/src/memory/derive-id.mjs +0 -24
- package/esm/ai/src/memory/derive-id.mjs.map +0 -1
- package/esm/ai/src/memory/episodic-memory.mjs +0 -106
- package/esm/ai/src/memory/episodic-memory.mjs.map +0 -1
- package/esm/ai/src/memory/memory.mjs +0 -166
- package/esm/ai/src/memory/memory.mjs.map +0 -1
- package/esm/ai/src/memory/procedural-memory.mjs +0 -103
- package/esm/ai/src/memory/procedural-memory.mjs.map +0 -1
- package/esm/ai/src/memory/semantic-memory.mjs +0 -80
- package/esm/ai/src/memory/semantic-memory.mjs.map +0 -1
- package/esm/ai/src/memory/working-memory.mjs +0 -62
- package/esm/ai/src/memory/working-memory.mjs.map +0 -1
- package/esm/ai/src/middleware/builtins/budget.mjs +0 -219
- package/esm/ai/src/middleware/builtins/budget.mjs.map +0 -1
- package/esm/ai/src/middleware/builtins/guardrail.mjs +0 -76
- package/esm/ai/src/middleware/builtins/guardrail.mjs.map +0 -1
- package/esm/ai/src/middleware/builtins/semantic-cache.mjs +0 -149
- package/esm/ai/src/middleware/builtins/semantic-cache.mjs.map +0 -1
- package/esm/ai/src/middleware/helpers/compose.mjs +0 -52
- package/esm/ai/src/middleware/helpers/compose.mjs.map +0 -1
- package/esm/ai/src/middleware/helpers/for-tool.mjs +0 -80
- package/esm/ai/src/middleware/helpers/for-tool.mjs.map +0 -1
- package/esm/ai/src/middleware/index.mjs +0 -10
- package/esm/ai/src/middleware/pipeline.mjs +0 -100
- package/esm/ai/src/middleware/pipeline.mjs.map +0 -1
- package/esm/ai/src/middleware/utils/extract-user-text.mjs +0 -47
- package/esm/ai/src/middleware/utils/extract-user-text.mjs.map +0 -1
- package/esm/ai/src/middleware/utils/namespaced-state.mjs +0 -60
- package/esm/ai/src/middleware/utils/namespaced-state.mjs.map +0 -1
- package/esm/ai/src/mock/index.mjs +0 -4
- package/esm/ai/src/mock/mock-agent.mjs +0 -3
- package/esm/ai/src/mock/mock-router.mjs +0 -58
- package/esm/ai/src/mock/mock-router.mjs.map +0 -1
- package/esm/ai/src/model/fallback-model.mjs +0 -218
- package/esm/ai/src/model/fallback-model.mjs.map +0 -1
- package/esm/ai/src/model/index.mjs +0 -3
- package/esm/ai/src/object-stream/index.mjs +0 -4
- package/esm/ai/src/object-stream/parse-partial-json.mjs +0 -78
- package/esm/ai/src/object-stream/parse-partial-json.mjs.map +0 -1
- package/esm/ai/src/object-stream/stream-object.mjs +0 -97
- package/esm/ai/src/object-stream/stream-object.mjs.map +0 -1
- package/esm/ai/src/observe/index.mjs +0 -4
- package/esm/ai/src/observe/observer-registry.mjs +0 -35
- package/esm/ai/src/observe/observer-registry.mjs.map +0 -1
- package/esm/ai/src/observe/resolve-observers.mjs +0 -73
- package/esm/ai/src/observe/resolve-observers.mjs.map +0 -1
- package/esm/ai/src/orchestrator/as-tool.mjs +0 -98
- package/esm/ai/src/orchestrator/as-tool.mjs.map +0 -1
- package/esm/ai/src/orchestrator/checkpoint.mjs +0 -75
- package/esm/ai/src/orchestrator/checkpoint.mjs.map +0 -1
- package/esm/ai/src/orchestrator/commands.mjs +0 -34
- package/esm/ai/src/orchestrator/commands.mjs.map +0 -1
- package/esm/ai/src/orchestrator/compaction.mjs +0 -206
- package/esm/ai/src/orchestrator/compaction.mjs.map +0 -1
- package/esm/ai/src/orchestrator/dispatch.mjs +0 -171
- package/esm/ai/src/orchestrator/dispatch.mjs.map +0 -1
- package/esm/ai/src/orchestrator/emitter.mjs +0 -85
- package/esm/ai/src/orchestrator/emitter.mjs.map +0 -1
- package/esm/ai/src/orchestrator/execution.mjs +0 -395
- package/esm/ai/src/orchestrator/execution.mjs.map +0 -1
- package/esm/ai/src/orchestrator/index.mjs +0 -11
- package/esm/ai/src/orchestrator/load.mjs +0 -49
- package/esm/ai/src/orchestrator/load.mjs.map +0 -1
- package/esm/ai/src/orchestrator/lock.mjs +0 -75
- package/esm/ai/src/orchestrator/lock.mjs.map +0 -1
- package/esm/ai/src/orchestrator/memory.mjs +0 -141
- package/esm/ai/src/orchestrator/memory.mjs.map +0 -1
- package/esm/ai/src/orchestrator/orchestrator-stream.mjs +0 -98
- package/esm/ai/src/orchestrator/orchestrator-stream.mjs.map +0 -1
- package/esm/ai/src/orchestrator/orchestrator.mjs +0 -206
- package/esm/ai/src/orchestrator/orchestrator.mjs.map +0 -1
- package/esm/ai/src/orchestrator/resume.mjs +0 -74
- package/esm/ai/src/orchestrator/resume.mjs.map +0 -1
- package/esm/ai/src/orchestrator/session-lock.mjs +0 -83
- package/esm/ai/src/orchestrator/session-lock.mjs.map +0 -1
- package/esm/ai/src/orchestrator/signature.mjs +0 -120
- package/esm/ai/src/orchestrator/signature.mjs.map +0 -1
- package/esm/ai/src/orchestrator/window.mjs +0 -56
- package/esm/ai/src/orchestrator/window.mjs.map +0 -1
- package/esm/ai/src/planner/dag-scheduler.mjs +0 -97
- package/esm/ai/src/planner/dag-scheduler.mjs.map +0 -1
- package/esm/ai/src/planner/index.mjs +0 -6
- package/esm/ai/src/planner/plan-prompt.mjs +0 -31
- package/esm/ai/src/planner/plan-prompt.mjs.map +0 -1
- package/esm/ai/src/planner/plan-schema.mjs +0 -120
- package/esm/ai/src/planner/plan-schema.mjs.map +0 -1
- package/esm/ai/src/planner/planner-run.mjs +0 -769
- package/esm/ai/src/planner/planner-run.mjs.map +0 -1
- package/esm/ai/src/planner/planner.mjs +0 -144
- package/esm/ai/src/planner/planner.mjs.map +0 -1
- package/esm/ai/src/planner/signature.mjs +0 -27
- package/esm/ai/src/planner/signature.mjs.map +0 -1
- package/esm/ai/src/planner/snapshot.mjs +0 -95
- package/esm/ai/src/planner/snapshot.mjs.map +0 -1
- package/esm/ai/src/prompt/errors.mjs +0 -73
- package/esm/ai/src/prompt/errors.mjs.map +0 -1
- package/esm/ai/src/prompt/index.mjs +0 -4
- package/esm/ai/src/prompt/prompt-langfuse-sync.mjs +0 -104
- package/esm/ai/src/prompt/prompt-langfuse-sync.mjs.map +0 -1
- package/esm/ai/src/prompt/prompt-validate.mjs +0 -170
- package/esm/ai/src/prompt/prompt-validate.mjs.map +0 -1
- package/esm/ai/src/prompt/prompt.mjs +0 -218
- package/esm/ai/src/prompt/prompt.mjs.map +0 -1
- package/esm/ai/src/prompts/index.mjs +0 -3
- package/esm/ai/src/prompts/prompts-manager.mjs +0 -410
- package/esm/ai/src/prompts/prompts-manager.mjs.map +0 -1
- package/esm/ai/src/prompts/prompts-validate.mjs +0 -0
- package/esm/ai/src/prompts/prompts-validate.mjs.map +0 -1
- package/esm/ai/src/rag/as-tool.mjs +0 -48
- package/esm/ai/src/rag/as-tool.mjs.map +0 -1
- package/esm/ai/src/rag/chunk/chunk.mjs +0 -44
- package/esm/ai/src/rag/chunk/chunk.mjs.map +0 -1
- package/esm/ai/src/rag/chunk/fixed.mjs +0 -32
- package/esm/ai/src/rag/chunk/fixed.mjs.map +0 -1
- package/esm/ai/src/rag/chunk/markdown.mjs +0 -75
- package/esm/ai/src/rag/chunk/markdown.mjs.map +0 -1
- package/esm/ai/src/rag/chunk/recursive.mjs +0 -132
- package/esm/ai/src/rag/chunk/recursive.mjs.map +0 -1
- package/esm/ai/src/rag/chunk/sentence.mjs +0 -73
- package/esm/ai/src/rag/chunk/sentence.mjs.map +0 -1
- package/esm/ai/src/rag/hybrid/bm25.mjs +0 -51
- package/esm/ai/src/rag/hybrid/bm25.mjs.map +0 -1
- package/esm/ai/src/rag/hybrid/hybrid-rank.mjs +0 -29
- package/esm/ai/src/rag/hybrid/hybrid-rank.mjs.map +0 -1
- package/esm/ai/src/rag/hybrid/rrf.mjs +0 -30
- package/esm/ai/src/rag/hybrid/rrf.mjs.map +0 -1
- package/esm/ai/src/rag/index.mjs +0 -18
- package/esm/ai/src/rag/loaders/errors.mjs +0 -25
- package/esm/ai/src/rag/loaders/errors.mjs.map +0 -1
- package/esm/ai/src/rag/loaders/index.mjs +0 -7
- package/esm/ai/src/rag/loaders/load-html.mjs +0 -138
- package/esm/ai/src/rag/loaders/load-html.mjs.map +0 -1
- package/esm/ai/src/rag/loaders/load-pdf.mjs +0 -150
- package/esm/ai/src/rag/loaders/load-pdf.mjs.map +0 -1
- package/esm/ai/src/rag/loaders/load-text.mjs +0 -60
- package/esm/ai/src/rag/loaders/load-text.mjs.map +0 -1
- package/esm/ai/src/rag/loaders/load-web.mjs +0 -89
- package/esm/ai/src/rag/loaders/load-web.mjs.map +0 -1
- package/esm/ai/src/rag/rag.mjs +0 -126
- package/esm/ai/src/rag/rag.mjs.map +0 -1
- package/esm/ai/src/rag/rerank/keyword-reranker.mjs +0 -58
- package/esm/ai/src/rag/rerank/keyword-reranker.mjs.map +0 -1
- package/esm/ai/src/rag/rerank/llm-reranker.mjs +0 -85
- package/esm/ai/src/rag/rerank/llm-reranker.mjs.map +0 -1
- package/esm/ai/src/rag/retrieve.mjs +0 -68
- package/esm/ai/src/rag/retrieve.mjs.map +0 -1
- package/esm/ai/src/rag/store/cache-vector-store.mjs +0 -48
- package/esm/ai/src/rag/store/cache-vector-store.mjs.map +0 -1
- package/esm/ai/src/rag/store/pg-vector-store.mjs +0 -328
- package/esm/ai/src/rag/store/pg-vector-store.mjs.map +0 -1
- package/esm/ai/src/rag/transforms/multi-query.mjs +0 -41
- package/esm/ai/src/rag/transforms/multi-query.mjs.map +0 -1
- package/esm/ai/src/security/index.mjs +0 -5
- package/esm/ai/src/security/outbound-policy.mjs +0 -187
- package/esm/ai/src/security/outbound-policy.mjs.map +0 -1
- package/esm/ai/src/security/private-ip.mjs +0 -48
- package/esm/ai/src/security/private-ip.mjs.map +0 -1
- package/esm/ai/src/security/redact.mjs +0 -60
- package/esm/ai/src/security/redact.mjs.map +0 -1
- package/esm/ai/src/serve/serve.mjs +0 -90
- package/esm/ai/src/serve/serve.mjs.map +0 -1
- package/esm/ai/src/serve/sse.mjs +0 -25
- package/esm/ai/src/serve/sse.mjs.map +0 -1
- package/esm/ai/src/serve/stream-to-sse.mjs +0 -37
- package/esm/ai/src/serve/stream-to-sse.mjs.map +0 -1
- package/esm/ai/src/skills/catalog.mjs +0 -140
- package/esm/ai/src/skills/catalog.mjs.map +0 -1
- package/esm/ai/src/skills/index.mjs +0 -11
- package/esm/ai/src/skills/load-skill-tool.mjs +0 -65
- package/esm/ai/src/skills/load-skill-tool.mjs.map +0 -1
- package/esm/ai/src/skills/save-skill-tool.mjs +0 -65
- package/esm/ai/src/skills/save-skill-tool.mjs.map +0 -1
- package/esm/ai/src/skills/skills.mjs +0 -109
- package/esm/ai/src/skills/skills.mjs.map +0 -1
- package/esm/ai/src/skills/sources/directory-source.mjs +0 -108
- package/esm/ai/src/skills/sources/directory-source.mjs.map +0 -1
- package/esm/ai/src/skills/sources/index.mjs +0 -27
- package/esm/ai/src/skills/sources/index.mjs.map +0 -1
- package/esm/ai/src/skills/sources/parse-frontmatter.mjs +0 -46
- package/esm/ai/src/skills/sources/parse-frontmatter.mjs.map +0 -1
- package/esm/ai/src/skills/sources/store-source.mjs +0 -15
- package/esm/ai/src/skills/sources/store-source.mjs.map +0 -1
- package/esm/ai/src/skills/sources/url-source.mjs +0 -117
- package/esm/ai/src/skills/sources/url-source.mjs.map +0 -1
- package/esm/ai/src/snapshot/memory.mjs +0 -81
- package/esm/ai/src/snapshot/memory.mjs.map +0 -1
- package/esm/ai/src/snapshot/pg.mjs +0 -146
- package/esm/ai/src/snapshot/pg.mjs.map +0 -1
- package/esm/ai/src/snapshot/redis.mjs +0 -101
- package/esm/ai/src/snapshot/redis.mjs.map +0 -1
- package/esm/ai/src/speech/index.mjs +0 -3
- package/esm/ai/src/speech/speech.mjs +0 -122
- package/esm/ai/src/speech/speech.mjs.map +0 -1
- package/esm/ai/src/supervisor/as-tool.mjs +0 -74
- package/esm/ai/src/supervisor/as-tool.mjs.map +0 -1
- package/esm/ai/src/supervisor/cancellation.mjs +0 -22
- package/esm/ai/src/supervisor/cancellation.mjs.map +0 -1
- package/esm/ai/src/supervisor/decide.mjs +0 -272
- package/esm/ai/src/supervisor/decide.mjs.map +0 -1
- package/esm/ai/src/supervisor/emitter.mjs +0 -47
- package/esm/ai/src/supervisor/emitter.mjs.map +0 -1
- package/esm/ai/src/supervisor/entries.mjs +0 -206
- package/esm/ai/src/supervisor/entries.mjs.map +0 -1
- package/esm/ai/src/supervisor/execution.mjs +0 -1921
- package/esm/ai/src/supervisor/execution.mjs.map +0 -1
- package/esm/ai/src/supervisor/fan-out.mjs +0 -65
- package/esm/ai/src/supervisor/fan-out.mjs.map +0 -1
- package/esm/ai/src/supervisor/index.mjs +0 -14
- package/esm/ai/src/supervisor/router-factory.mjs +0 -141
- package/esm/ai/src/supervisor/router-factory.mjs.map +0 -1
- package/esm/ai/src/supervisor/router-prompt.mjs +0 -52
- package/esm/ai/src/supervisor/router-prompt.mjs.map +0 -1
- package/esm/ai/src/supervisor/signature.mjs +0 -89
- package/esm/ai/src/supervisor/signature.mjs.map +0 -1
- package/esm/ai/src/supervisor/snapshot.mjs +0 -69
- package/esm/ai/src/supervisor/snapshot.mjs.map +0 -1
- package/esm/ai/src/supervisor/supervisor-stream.mjs +0 -89
- package/esm/ai/src/supervisor/supervisor-stream.mjs.map +0 -1
- package/esm/ai/src/supervisor/supervisor.mjs +0 -144
- package/esm/ai/src/supervisor/supervisor.mjs.map +0 -1
- package/esm/ai/src/system-prompt/index.mjs +0 -7
- package/esm/ai/src/system-prompt/instruction.mjs +0 -57
- package/esm/ai/src/system-prompt/instruction.mjs.map +0 -1
- package/esm/ai/src/system-prompt/persona.mjs +0 -57
- package/esm/ai/src/system-prompt/persona.mjs.map +0 -1
- package/esm/ai/src/system-prompt/refined-system-prompt.mjs +0 -461
- package/esm/ai/src/system-prompt/refined-system-prompt.mjs.map +0 -1
- package/esm/ai/src/system-prompt/render-placeholders.mjs +0 -58
- package/esm/ai/src/system-prompt/render-placeholders.mjs.map +0 -1
- package/esm/ai/src/system-prompt/system-prompt.mjs +0 -286
- package/esm/ai/src/system-prompt/system-prompt.mjs.map +0 -1
- package/esm/ai/src/team/gates.mjs +0 -48
- package/esm/ai/src/team/gates.mjs.map +0 -1
- package/esm/ai/src/team/index.mjs +0 -3
- package/esm/ai/src/team/team.mjs +0 -94
- package/esm/ai/src/team/team.mjs.map +0 -1
- package/esm/ai/src/tool/executable-as-tool.mjs +0 -81
- package/esm/ai/src/tool/executable-as-tool.mjs.map +0 -1
- package/esm/ai/src/tool/index.mjs +0 -4
- package/esm/ai/src/tool/tool.mjs +0 -185
- package/esm/ai/src/tool/tool.mjs.map +0 -1
- package/esm/ai/src/transcribe/audio-input.mjs +0 -84
- package/esm/ai/src/transcribe/audio-input.mjs.map +0 -1
- package/esm/ai/src/transcribe/index.mjs +0 -4
- package/esm/ai/src/transcribe/transcribe.mjs +0 -127
- package/esm/ai/src/transcribe/transcribe.mjs.map +0 -1
- package/esm/ai/src/utils/compute-cost.mjs +0 -112
- package/esm/ai/src/utils/compute-cost.mjs.map +0 -1
- package/esm/ai/src/utils/extract-json-lenient.mjs +0 -97
- package/esm/ai/src/utils/extract-json-lenient.mjs.map +0 -1
- package/esm/ai/src/utils/extract-json-payload.mjs +0 -39
- package/esm/ai/src/utils/extract-json-payload.mjs.map +0 -1
- package/esm/ai/src/utils/generate-run-id.mjs +0 -23
- package/esm/ai/src/utils/generate-run-id.mjs.map +0 -1
- package/esm/ai/src/utils/index.mjs +0 -12
- package/esm/ai/src/utils/json-schema.mjs +0 -89
- package/esm/ai/src/utils/json-schema.mjs.map +0 -1
- package/esm/ai/src/utils/prepare-attachment-part.mjs +0 -232
- package/esm/ai/src/utils/prepare-attachment-part.mjs.map +0 -1
- package/esm/ai/src/utils/resolve-attachment.mjs +0 -74
- package/esm/ai/src/utils/resolve-attachment.mjs.map +0 -1
- package/esm/ai/src/utils/run-context.mjs +0 -89
- package/esm/ai/src/utils/run-context.mjs.map +0 -1
- package/esm/ai/src/utils/safe-json-parse.mjs +0 -22
- package/esm/ai/src/utils/safe-json-parse.mjs.map +0 -1
- package/esm/ai/src/utils/stamp-report-lineage.mjs +0 -45
- package/esm/ai/src/utils/stamp-report-lineage.mjs.map +0 -1
- package/esm/ai/src/vcr/cassette-io.mjs +0 -57
- package/esm/ai/src/vcr/cassette-io.mjs.map +0 -1
- package/esm/ai/src/vcr/errors.mjs +0 -37
- package/esm/ai/src/vcr/errors.mjs.map +0 -1
- package/esm/ai/src/vcr/hash-request.mjs +0 -118
- package/esm/ai/src/vcr/hash-request.mjs.map +0 -1
- package/esm/ai/src/vcr/index.mjs +0 -5
- package/esm/ai/src/vcr/vcr.mjs +0 -248
- package/esm/ai/src/vcr/vcr.mjs.map +0 -1
- package/esm/ai/src/workflow/as-tool.mjs +0 -49
- package/esm/ai/src/workflow/as-tool.mjs.map +0 -1
- package/esm/ai/src/workflow/cancellation.mjs +0 -44
- package/esm/ai/src/workflow/cancellation.mjs.map +0 -1
- package/esm/ai/src/workflow/emitter.mjs +0 -40
- package/esm/ai/src/workflow/emitter.mjs.map +0 -1
- package/esm/ai/src/workflow/engine.mjs +0 -363
- package/esm/ai/src/workflow/engine.mjs.map +0 -1
- package/esm/ai/src/workflow/index.mjs +0 -5
- package/esm/ai/src/workflow/retry.mjs +0 -32
- package/esm/ai/src/workflow/retry.mjs.map +0 -1
- package/esm/ai/src/workflow/router.mjs +0 -56
- package/esm/ai/src/workflow/router.mjs.map +0 -1
- package/esm/ai/src/workflow/run-scoped-emitter.mjs +0 -32
- package/esm/ai/src/workflow/run-scoped-emitter.mjs.map +0 -1
- package/esm/ai/src/workflow/signature.mjs +0 -34
- package/esm/ai/src/workflow/signature.mjs.map +0 -1
- package/esm/ai/src/workflow/snapshot.mjs +0 -77
- package/esm/ai/src/workflow/snapshot.mjs.map +0 -1
- package/esm/ai/src/workflow/state.mjs +0 -37
- package/esm/ai/src/workflow/state.mjs.map +0 -1
- package/esm/ai/src/workflow/step-runner.mjs +0 -370
- package/esm/ai/src/workflow/step-runner.mjs.map +0 -1
- package/esm/ai/src/workflow/step.mjs +0 -37
- package/esm/ai/src/workflow/step.mjs.map +0 -1
- package/esm/ai/src/workflow/workflow.mjs +0 -122
- package/esm/ai/src/workflow/workflow.mjs.map +0 -1
- package/esm/ai-openai/src/embedder.mjs +0 -4
- package/esm/ai-openai/src/image.mjs +0 -5
- package/esm/ai-openai/src/index.mjs +0 -7
- package/esm/ai-openai/src/model.mjs +0 -5
- package/esm/ai-openai/src/sdk.mjs +0 -9
- package/esm/ai-openai/src/speech.mjs +0 -5
- package/esm/ai-openai/src/transcription.mjs +0 -6
- package/esm/ai-openai/src/utils/index.mjs +0 -5
- package/esm/ai-openai/src/utils/to-openai-messages.mjs +0 -3
- package/esm/ai-openai/src/utils/to-openai-tools.mjs +0 -3
- package/esm/ai-openai/src/utils/wrap-openai-error.mjs +0 -4
- package/esm/node_modules/langfuse/lib/index.mjs +0 -1827
- package/esm/node_modules/langfuse/lib/index.mjs.map +0 -1
- package/esm/node_modules/langfuse-core/lib/index.mjs +0 -1770
- package/esm/node_modules/langfuse-core/lib/index.mjs.map +0 -1
- package/esm/node_modules/mustache/mustache.mjs +0 -587
- package/esm/node_modules/mustache/mustache.mjs.map +0 -1
- package/esm/node_modules/openai/_vendor/partial-json-parser/parser.mjs +0 -180
- package/esm/node_modules/openai/_vendor/partial-json-parser/parser.mjs.map +0 -1
- package/esm/node_modules/openai/auth/workload-identity-auth.mjs +0 -80
- package/esm/node_modules/openai/auth/workload-identity-auth.mjs.map +0 -1
- package/esm/node_modules/openai/azure.mjs +0 -82
- package/esm/node_modules/openai/azure.mjs.map +0 -1
- package/esm/node_modules/openai/client.mjs +0 -638
- package/esm/node_modules/openai/client.mjs.map +0 -1
- package/esm/node_modules/openai/core/api-promise.mjs +0 -75
- package/esm/node_modules/openai/core/api-promise.mjs.map +0 -1
- package/esm/node_modules/openai/core/error.mjs +0 -110
- package/esm/node_modules/openai/core/error.mjs.map +0 -1
- package/esm/node_modules/openai/core/pagination.mjs +0 -160
- package/esm/node_modules/openai/core/pagination.mjs.map +0 -1
- package/esm/node_modules/openai/core/resource.mjs +0 -10
- package/esm/node_modules/openai/core/resource.mjs.map +0 -1
- package/esm/node_modules/openai/core/streaming.mjs +0 -238
- package/esm/node_modules/openai/core/streaming.mjs.map +0 -1
- package/esm/node_modules/openai/index.mjs +0 -8
- package/esm/node_modules/openai/internal/decoders/line.mjs +0 -91
- package/esm/node_modules/openai/internal/decoders/line.mjs.map +0 -1
- package/esm/node_modules/openai/internal/detect-platform.mjs +0 -123
- package/esm/node_modules/openai/internal/detect-platform.mjs.map +0 -1
- package/esm/node_modules/openai/internal/errors.mjs +0 -26
- package/esm/node_modules/openai/internal/errors.mjs.map +0 -1
- package/esm/node_modules/openai/internal/headers.mjs +0 -65
- package/esm/node_modules/openai/internal/headers.mjs.map +0 -1
- package/esm/node_modules/openai/internal/parse.mjs +0 -41
- package/esm/node_modules/openai/internal/parse.mjs.map +0 -1
- package/esm/node_modules/openai/internal/qs/formats.mjs +0 -12
- package/esm/node_modules/openai/internal/qs/formats.mjs.map +0 -1
- package/esm/node_modules/openai/internal/qs/stringify.mjs +0 -179
- package/esm/node_modules/openai/internal/qs/stringify.mjs.map +0 -1
- package/esm/node_modules/openai/internal/qs/utils.mjs +0 -65
- package/esm/node_modules/openai/internal/qs/utils.mjs.map +0 -1
- package/esm/node_modules/openai/internal/request-options.mjs +0 -11
- package/esm/node_modules/openai/internal/request-options.mjs.map +0 -1
- package/esm/node_modules/openai/internal/shims.mjs +0 -77
- package/esm/node_modules/openai/internal/shims.mjs.map +0 -1
- package/esm/node_modules/openai/internal/to-file.mjs +0 -63
- package/esm/node_modules/openai/internal/to-file.mjs.map +0 -1
- package/esm/node_modules/openai/internal/tslib.mjs +0 -16
- package/esm/node_modules/openai/internal/tslib.mjs.map +0 -1
- package/esm/node_modules/openai/internal/uploads.mjs +0 -94
- package/esm/node_modules/openai/internal/uploads.mjs.map +0 -1
- package/esm/node_modules/openai/internal/utils/base64.mjs +0 -22
- package/esm/node_modules/openai/internal/utils/base64.mjs.map +0 -1
- package/esm/node_modules/openai/internal/utils/bytes.mjs +0 -26
- package/esm/node_modules/openai/internal/utils/bytes.mjs.map +0 -1
- package/esm/node_modules/openai/internal/utils/env.mjs +0 -16
- package/esm/node_modules/openai/internal/utils/env.mjs.map +0 -1
- package/esm/node_modules/openai/internal/utils/log.mjs +0 -58
- package/esm/node_modules/openai/internal/utils/log.mjs.map +0 -1
- package/esm/node_modules/openai/internal/utils/path.mjs +0 -62
- package/esm/node_modules/openai/internal/utils/path.mjs.map +0 -1
- package/esm/node_modules/openai/internal/utils/query.mjs +0 -10
- package/esm/node_modules/openai/internal/utils/query.mjs.map +0 -1
- package/esm/node_modules/openai/internal/utils/sleep.mjs +0 -6
- package/esm/node_modules/openai/internal/utils/sleep.mjs.map +0 -1
- package/esm/node_modules/openai/internal/utils/uuid.mjs +0 -18
- package/esm/node_modules/openai/internal/utils/uuid.mjs.map +0 -1
- package/esm/node_modules/openai/internal/utils/values.mjs +0 -41
- package/esm/node_modules/openai/internal/utils/values.mjs.map +0 -1
- package/esm/node_modules/openai/lib/AbstractChatCompletionRunner.mjs +0 -247
- package/esm/node_modules/openai/lib/AbstractChatCompletionRunner.mjs.map +0 -1
- package/esm/node_modules/openai/lib/AssistantStream.mjs +0 -472
- package/esm/node_modules/openai/lib/AssistantStream.mjs.map +0 -1
- package/esm/node_modules/openai/lib/ChatCompletionRunner.mjs +0 -26
- package/esm/node_modules/openai/lib/ChatCompletionRunner.mjs.map +0 -1
- package/esm/node_modules/openai/lib/ChatCompletionStream.mjs +0 -423
- package/esm/node_modules/openai/lib/ChatCompletionStream.mjs.map +0 -1
- package/esm/node_modules/openai/lib/ChatCompletionStreamingRunner.mjs +0 -26
- package/esm/node_modules/openai/lib/ChatCompletionStreamingRunner.mjs.map +0 -1
- package/esm/node_modules/openai/lib/EventStream.mjs +0 -163
- package/esm/node_modules/openai/lib/EventStream.mjs.map +0 -1
- package/esm/node_modules/openai/lib/ResponsesParser.mjs +0 -94
- package/esm/node_modules/openai/lib/ResponsesParser.mjs.map +0 -1
- package/esm/node_modules/openai/lib/RunnableFunction.mjs +0 -8
- package/esm/node_modules/openai/lib/RunnableFunction.mjs.map +0 -1
- package/esm/node_modules/openai/lib/Util.mjs +0 -19
- package/esm/node_modules/openai/lib/Util.mjs.map +0 -1
- package/esm/node_modules/openai/lib/chatCompletionUtils.mjs +0 -11
- package/esm/node_modules/openai/lib/chatCompletionUtils.mjs.map +0 -1
- package/esm/node_modules/openai/lib/parser.mjs +0 -88
- package/esm/node_modules/openai/lib/parser.mjs.map +0 -1
- package/esm/node_modules/openai/lib/responses/ResponseStream.mjs +0 -231
- package/esm/node_modules/openai/lib/responses/ResponseStream.mjs.map +0 -1
- package/esm/node_modules/openai/resources/admin/admin.mjs +0 -15
- package/esm/node_modules/openai/resources/admin/admin.mjs.map +0 -1
- package/esm/node_modules/openai/resources/admin/organization/admin-api-keys.mjs +0 -81
- package/esm/node_modules/openai/resources/admin/organization/admin-api-keys.mjs.map +0 -1
- package/esm/node_modules/openai/resources/admin/organization/audit-logs.mjs +0 -31
- package/esm/node_modules/openai/resources/admin/organization/audit-logs.mjs.map +0 -1
- package/esm/node_modules/openai/resources/admin/organization/certificates.mjs +0 -153
- package/esm/node_modules/openai/resources/admin/organization/certificates.mjs.map +0 -1
- package/esm/node_modules/openai/resources/admin/organization/data-retention.mjs +0 -42
- package/esm/node_modules/openai/resources/admin/organization/data-retention.mjs.map +0 -1
- package/esm/node_modules/openai/resources/admin/organization/groups/groups.mjs +0 -106
- package/esm/node_modules/openai/resources/admin/organization/groups/groups.mjs.map +0 -1
- package/esm/node_modules/openai/resources/admin/organization/groups/roles.mjs +0 -88
- package/esm/node_modules/openai/resources/admin/organization/groups/roles.mjs.map +0 -1
- package/esm/node_modules/openai/resources/admin/organization/groups/users.mjs +0 -88
- package/esm/node_modules/openai/resources/admin/organization/groups/users.mjs.map +0 -1
- package/esm/node_modules/openai/resources/admin/organization/invites.mjs +0 -83
- package/esm/node_modules/openai/resources/admin/organization/invites.mjs.map +0 -1
- package/esm/node_modules/openai/resources/admin/organization/organization.mjs +0 -45
- package/esm/node_modules/openai/resources/admin/organization/organization.mjs.map +0 -1
- package/esm/node_modules/openai/resources/admin/organization/projects/api-keys.mjs +0 -72
- package/esm/node_modules/openai/resources/admin/organization/projects/api-keys.mjs.map +0 -1
- package/esm/node_modules/openai/resources/admin/organization/projects/certificates.mjs +0 -78
- package/esm/node_modules/openai/resources/admin/organization/projects/certificates.mjs.map +0 -1
- package/esm/node_modules/openai/resources/admin/organization/projects/data-retention.mjs +0 -46
- package/esm/node_modules/openai/resources/admin/organization/projects/data-retention.mjs.map +0 -1
- package/esm/node_modules/openai/resources/admin/organization/projects/groups/groups.mjs +0 -95
- package/esm/node_modules/openai/resources/admin/organization/projects/groups/groups.mjs.map +0 -1
- package/esm/node_modules/openai/resources/admin/organization/projects/groups/roles.mjs +0 -91
- package/esm/node_modules/openai/resources/admin/organization/projects/groups/roles.mjs.map +0 -1
- package/esm/node_modules/openai/resources/admin/organization/projects/hosted-tool-permissions.mjs +0 -45
- package/esm/node_modules/openai/resources/admin/organization/projects/hosted-tool-permissions.mjs.map +0 -1
- package/esm/node_modules/openai/resources/admin/organization/projects/model-permissions.mjs +0 -63
- package/esm/node_modules/openai/resources/admin/organization/projects/model-permissions.mjs.map +0 -1
- package/esm/node_modules/openai/resources/admin/organization/projects/projects.mjs +0 -137
- package/esm/node_modules/openai/resources/admin/organization/projects/projects.mjs.map +0 -1
- package/esm/node_modules/openai/resources/admin/organization/projects/rate-limits.mjs +0 -51
- package/esm/node_modules/openai/resources/admin/organization/projects/rate-limits.mjs.map +0 -1
- package/esm/node_modules/openai/resources/admin/organization/projects/roles.mjs +0 -108
- package/esm/node_modules/openai/resources/admin/organization/projects/roles.mjs.map +0 -1
- package/esm/node_modules/openai/resources/admin/organization/projects/service-accounts.mjs +0 -112
- package/esm/node_modules/openai/resources/admin/organization/projects/service-accounts.mjs.map +0 -1
- package/esm/node_modules/openai/resources/admin/organization/projects/spend-alerts.mjs +0 -106
- package/esm/node_modules/openai/resources/admin/organization/projects/spend-alerts.mjs.map +0 -1
- package/esm/node_modules/openai/resources/admin/organization/projects/users/roles.mjs +0 -91
- package/esm/node_modules/openai/resources/admin/organization/projects/users/roles.mjs.map +0 -1
- package/esm/node_modules/openai/resources/admin/organization/projects/users/users.mjs +0 -118
- package/esm/node_modules/openai/resources/admin/organization/projects/users/users.mjs.map +0 -1
- package/esm/node_modules/openai/resources/admin/organization/roles.mjs +0 -96
- package/esm/node_modules/openai/resources/admin/organization/roles.mjs.map +0 -1
- package/esm/node_modules/openai/resources/admin/organization/spend-alerts.mjs +0 -97
- package/esm/node_modules/openai/resources/admin/organization/spend-alerts.mjs.map +0 -1
- package/esm/node_modules/openai/resources/admin/organization/usage.mjs +0 -207
- package/esm/node_modules/openai/resources/admin/organization/usage.mjs.map +0 -1
- package/esm/node_modules/openai/resources/admin/organization/users/roles.mjs +0 -88
- package/esm/node_modules/openai/resources/admin/organization/users/roles.mjs.map +0 -1
- package/esm/node_modules/openai/resources/admin/organization/users/users.mjs +0 -82
- package/esm/node_modules/openai/resources/admin/organization/users/users.mjs.map +0 -1
- package/esm/node_modules/openai/resources/audio/audio.mjs +0 -21
- package/esm/node_modules/openai/resources/audio/audio.mjs.map +0 -1
- package/esm/node_modules/openai/resources/audio/speech.mjs +0 -39
- package/esm/node_modules/openai/resources/audio/speech.mjs.map +0 -1
- package/esm/node_modules/openai/resources/audio/transcriptions.mjs +0 -22
- package/esm/node_modules/openai/resources/audio/transcriptions.mjs.map +0 -1
- package/esm/node_modules/openai/resources/audio/translations.mjs +0 -21
- package/esm/node_modules/openai/resources/audio/translations.mjs.map +0 -1
- package/esm/node_modules/openai/resources/batches.mjs +0 -54
- package/esm/node_modules/openai/resources/batches.mjs.map +0 -1
- package/esm/node_modules/openai/resources/beta/assistants.mjs +0 -78
- package/esm/node_modules/openai/resources/beta/assistants.mjs.map +0 -1
- package/esm/node_modules/openai/resources/beta/beta.mjs +0 -24
- package/esm/node_modules/openai/resources/beta/beta.mjs.map +0 -1
- package/esm/node_modules/openai/resources/beta/chatkit/chatkit.mjs +0 -18
- package/esm/node_modules/openai/resources/beta/chatkit/chatkit.mjs.map +0 -1
- package/esm/node_modules/openai/resources/beta/chatkit/sessions.mjs +0 -49
- package/esm/node_modules/openai/resources/beta/chatkit/sessions.mjs.map +0 -1
- package/esm/node_modules/openai/resources/beta/chatkit/threads.mjs +0 -85
- package/esm/node_modules/openai/resources/beta/chatkit/threads.mjs.map +0 -1
- package/esm/node_modules/openai/resources/beta/realtime/realtime.mjs +0 -21
- package/esm/node_modules/openai/resources/beta/realtime/realtime.mjs.map +0 -1
- package/esm/node_modules/openai/resources/beta/realtime/sessions.mjs +0 -33
- package/esm/node_modules/openai/resources/beta/realtime/sessions.mjs.map +0 -1
- package/esm/node_modules/openai/resources/beta/realtime/transcription-sessions.mjs +0 -33
- package/esm/node_modules/openai/resources/beta/realtime/transcription-sessions.mjs.map +0 -1
- package/esm/node_modules/openai/resources/beta/threads/messages.mjs +0 -83
- package/esm/node_modules/openai/resources/beta/threads/messages.mjs.map +0 -1
- package/esm/node_modules/openai/resources/beta/threads/runs/runs.mjs +0 -183
- package/esm/node_modules/openai/resources/beta/threads/runs/runs.mjs.map +0 -1
- package/esm/node_modules/openai/resources/beta/threads/runs/steps.mjs +0 -45
- package/esm/node_modules/openai/resources/beta/threads/runs/steps.mjs.map +0 -1
- package/esm/node_modules/openai/resources/beta/threads/threads.mjs +0 -101
- package/esm/node_modules/openai/resources/beta/threads/threads.mjs.map +0 -1
- package/esm/node_modules/openai/resources/chat/chat.mjs +0 -15
- package/esm/node_modules/openai/resources/chat/chat.mjs.map +0 -1
- package/esm/node_modules/openai/resources/chat/completions/completions.mjs +0 -123
- package/esm/node_modules/openai/resources/chat/completions/completions.mjs.map +0 -1
- package/esm/node_modules/openai/resources/chat/completions/index.mjs +0 -7
- package/esm/node_modules/openai/resources/chat/completions/messages.mjs +0 -35
- package/esm/node_modules/openai/resources/chat/completions/messages.mjs.map +0 -1
- package/esm/node_modules/openai/resources/chat/index.mjs +0 -5
- package/esm/node_modules/openai/resources/completions.mjs +0 -20
- package/esm/node_modules/openai/resources/completions.mjs.map +0 -1
- package/esm/node_modules/openai/resources/containers/containers.mjs +0 -57
- package/esm/node_modules/openai/resources/containers/containers.mjs.map +0 -1
- package/esm/node_modules/openai/resources/containers/files/content.mjs +0 -23
- package/esm/node_modules/openai/resources/containers/files/content.mjs.map +0 -1
- package/esm/node_modules/openai/resources/containers/files/files.mjs +0 -63
- package/esm/node_modules/openai/resources/containers/files/files.mjs.map +0 -1
- package/esm/node_modules/openai/resources/conversations/conversations.mjs +0 -57
- package/esm/node_modules/openai/resources/conversations/conversations.mjs.map +0 -1
- package/esm/node_modules/openai/resources/conversations/items.mjs +0 -57
- package/esm/node_modules/openai/resources/conversations/items.mjs.map +0 -1
- package/esm/node_modules/openai/resources/embeddings.mjs +0 -48
- package/esm/node_modules/openai/resources/embeddings.mjs.map +0 -1
- package/esm/node_modules/openai/resources/evals/evals.mjs +0 -73
- package/esm/node_modules/openai/resources/evals/evals.mjs.map +0 -1
- package/esm/node_modules/openai/resources/evals/runs/output-items.mjs +0 -35
- package/esm/node_modules/openai/resources/evals/runs/output-items.mjs.map +0 -1
- package/esm/node_modules/openai/resources/evals/runs/runs.mjs +0 -72
- package/esm/node_modules/openai/resources/evals/runs/runs.mjs.map +0 -1
- package/esm/node_modules/openai/resources/files.mjs +0 -111
- package/esm/node_modules/openai/resources/files.mjs.map +0 -1
- package/esm/node_modules/openai/resources/fine-tuning/alpha/alpha.mjs +0 -15
- package/esm/node_modules/openai/resources/fine-tuning/alpha/alpha.mjs.map +0 -1
- package/esm/node_modules/openai/resources/fine-tuning/alpha/graders.mjs +0 -60
- package/esm/node_modules/openai/resources/fine-tuning/alpha/graders.mjs.map +0 -1
- package/esm/node_modules/openai/resources/fine-tuning/checkpoints/checkpoints.mjs +0 -15
- package/esm/node_modules/openai/resources/fine-tuning/checkpoints/checkpoints.mjs.map +0 -1
- package/esm/node_modules/openai/resources/fine-tuning/checkpoints/permissions.mjs +0 -102
- package/esm/node_modules/openai/resources/fine-tuning/checkpoints/permissions.mjs.map +0 -1
- package/esm/node_modules/openai/resources/fine-tuning/fine-tuning.mjs +0 -24
- package/esm/node_modules/openai/resources/fine-tuning/fine-tuning.mjs.map +0 -1
- package/esm/node_modules/openai/resources/fine-tuning/jobs/checkpoints.mjs +0 -34
- package/esm/node_modules/openai/resources/fine-tuning/jobs/checkpoints.mjs.map +0 -1
- package/esm/node_modules/openai/resources/fine-tuning/jobs/jobs.mjs +0 -148
- package/esm/node_modules/openai/resources/fine-tuning/jobs/jobs.mjs.map +0 -1
- package/esm/node_modules/openai/resources/fine-tuning/methods.mjs +0 -8
- package/esm/node_modules/openai/resources/fine-tuning/methods.mjs.map +0 -1
- package/esm/node_modules/openai/resources/graders/grader-models.mjs +0 -8
- package/esm/node_modules/openai/resources/graders/grader-models.mjs.map +0 -1
- package/esm/node_modules/openai/resources/graders/graders.mjs +0 -15
- package/esm/node_modules/openai/resources/graders/graders.mjs.map +0 -1
- package/esm/node_modules/openai/resources/images.mjs +0 -46
- package/esm/node_modules/openai/resources/images.mjs.map +0 -1
- package/esm/node_modules/openai/resources/index.mjs +0 -27
- package/esm/node_modules/openai/resources/models.mjs +0 -44
- package/esm/node_modules/openai/resources/models.mjs.map +0 -1
- package/esm/node_modules/openai/resources/moderations.mjs +0 -23
- package/esm/node_modules/openai/resources/moderations.mjs.map +0 -1
- package/esm/node_modules/openai/resources/realtime/calls.mjs +0 -79
- package/esm/node_modules/openai/resources/realtime/calls.mjs.map +0 -1
- package/esm/node_modules/openai/resources/realtime/client-secrets.mjs +0 -39
- package/esm/node_modules/openai/resources/realtime/client-secrets.mjs.map +0 -1
- package/esm/node_modules/openai/resources/realtime/realtime.mjs +0 -18
- package/esm/node_modules/openai/resources/realtime/realtime.mjs.map +0 -1
- package/esm/node_modules/openai/resources/responses/input-items.mjs +0 -31
- package/esm/node_modules/openai/resources/responses/input-items.mjs.map +0 -1
- package/esm/node_modules/openai/resources/responses/input-tokens.mjs +0 -27
- package/esm/node_modules/openai/resources/responses/input-tokens.mjs.map +0 -1
- package/esm/node_modules/openai/resources/responses/responses.mjs +0 -110
- package/esm/node_modules/openai/resources/responses/responses.mjs.map +0 -1
- package/esm/node_modules/openai/resources/skills/content.mjs +0 -22
- package/esm/node_modules/openai/resources/skills/content.mjs.map +0 -1
- package/esm/node_modules/openai/resources/skills/skills.mjs +0 -69
- package/esm/node_modules/openai/resources/skills/skills.mjs.map +0 -1
- package/esm/node_modules/openai/resources/skills/versions/content.mjs +0 -23
- package/esm/node_modules/openai/resources/skills/versions/content.mjs.map +0 -1
- package/esm/node_modules/openai/resources/skills/versions/versions.mjs +0 -58
- package/esm/node_modules/openai/resources/skills/versions/versions.mjs.map +0 -1
- package/esm/node_modules/openai/resources/uploads/parts.mjs +0 -34
- package/esm/node_modules/openai/resources/uploads/parts.mjs.map +0 -1
- package/esm/node_modules/openai/resources/uploads/uploads.mjs +0 -84
- package/esm/node_modules/openai/resources/uploads/uploads.mjs.map +0 -1
- package/esm/node_modules/openai/resources/vector-stores/file-batches.mjs +0 -126
- package/esm/node_modules/openai/resources/vector-stores/file-batches.mjs.map +0 -1
- package/esm/node_modules/openai/resources/vector-stores/files.mjs +0 -147
- package/esm/node_modules/openai/resources/vector-stores/files.mjs.map +0 -1
- package/esm/node_modules/openai/resources/vector-stores/vector-stores.mjs +0 -87
- package/esm/node_modules/openai/resources/vector-stores/vector-stores.mjs.map +0 -1
- package/esm/node_modules/openai/resources/videos.mjs +0 -115
- package/esm/node_modules/openai/resources/videos.mjs.map +0 -1
- package/esm/node_modules/openai/resources/webhooks/index.mjs +0 -3
- package/esm/node_modules/openai/resources/webhooks/webhooks.mjs +0 -69
- package/esm/node_modules/openai/resources/webhooks/webhooks.mjs.map +0 -1
- package/esm/node_modules/openai/resources/webhooks.mjs +0 -4
- package/esm/node_modules/openai/streaming.mjs +0 -3
- package/esm/node_modules/openai/version.mjs +0 -6
- package/esm/node_modules/openai/version.mjs.map +0 -1
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
import { extractUserText } from "../utils/extract-user-text.mjs";
|
|
2
|
-
import { resolveDefaultStore } from "../../config.mjs";
|
|
3
|
-
|
|
4
|
-
//#region ../@warlock.js/ai/src/middleware/builtins/semantic-cache.ts
|
|
5
|
-
const DEFAULT_NAMESPACE = "ai.cache";
|
|
6
|
-
/**
|
|
7
|
-
* Build a stable fingerprint for a prompt covering the full message
|
|
8
|
-
* list (system + history + user turn). Ensures two prompts sharing
|
|
9
|
-
* the user text but differing in prior context do not collide on
|
|
10
|
-
* the exact-match fast path.
|
|
11
|
-
*
|
|
12
|
-
* FNV-1a variant — cheap, collision-resistant enough for a cache,
|
|
13
|
-
* dependency-free. NOT a cryptographic hash: collisions would
|
|
14
|
-
* surface as wrong cache hits, not a security issue in the current
|
|
15
|
-
* trust model.
|
|
16
|
-
*/
|
|
17
|
-
function hashPrompt(messages) {
|
|
18
|
-
const serialized = messages.map((message) => {
|
|
19
|
-
return `${message.role}:${Array.isArray(message.content) ? message.content.filter((part) => part.type === "text").map((part) => part.text).join("|") : message.content}`;
|
|
20
|
-
}).join("||");
|
|
21
|
-
let hash = 2166136261;
|
|
22
|
-
for (let index = 0; index < serialized.length; index++) {
|
|
23
|
-
hash ^= serialized.charCodeAt(index);
|
|
24
|
-
hash = Math.imul(hash, 16777619);
|
|
25
|
-
}
|
|
26
|
-
return (hash >>> 0).toString(16);
|
|
27
|
-
}
|
|
28
|
-
function isFresh(entry, ttlMs) {
|
|
29
|
-
if (ttlMs === void 0) return true;
|
|
30
|
-
return Date.now() - entry.storedAt <= ttlMs;
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* Semantic-similarity response cache for an agent run.
|
|
34
|
-
*
|
|
35
|
-
* **Role.** Skips LLM round-trips when the current prompt is
|
|
36
|
-
* semantically close to one the agent has already answered. For
|
|
37
|
-
* FAQ / support-style traffic this often eliminates 60–80% of
|
|
38
|
-
* model calls — the production win is massive for cost and
|
|
39
|
-
* latency.
|
|
40
|
-
*
|
|
41
|
-
* **Delegation to `@warlock.js/cache`.** This middleware does NOT
|
|
42
|
-
* implement similarity search itself. It delegates to the supplied
|
|
43
|
-
* `CacheDriver`. Production deployments pick a driver with an ANN
|
|
44
|
-
* index (`pg` + pgvector, `redis` + RediSearch). Dev / test
|
|
45
|
-
* environments pass `new MemoryCacheDriver()` — zero config, correct,
|
|
46
|
-
* but O(N) per query. Drivers without similarity support throw
|
|
47
|
-
* `CacheUnsupportedError` from `set({ vector })` / `similar()`.
|
|
48
|
-
*
|
|
49
|
-
* **Two-tier lookup.**
|
|
50
|
-
* 1. *Exact-match key* — a cheap FNV hash over the entire message
|
|
51
|
-
* list. `store.get(hash)` returns the entry without an embedding
|
|
52
|
-
* round trip when the prompt hasn't changed at all.
|
|
53
|
-
* 2. *Vector-match* — on exact-match miss, embed the prompt and
|
|
54
|
-
* call `store.similar(vector, { topK: 1, threshold })`. The
|
|
55
|
-
* driver uses its native similarity index; anything clearing
|
|
56
|
-
* `threshold` is returned as a hit.
|
|
57
|
-
*
|
|
58
|
-
* **Write-on-miss.** When both tiers miss, `trip.before` stashes
|
|
59
|
-
* the prompt hash + vector in `ctx.state`; `trip.after` reads back
|
|
60
|
-
* the pending entry and calls
|
|
61
|
-
* `store.set(hash, entry, { vector })`. If an outer middleware
|
|
62
|
-
* (guardrail) throws in `trip.after` before the cache's `trip.after`
|
|
63
|
-
* runs, the pending entry is never written — bad responses stay out
|
|
64
|
-
* of the cache **as long as the canonical install order is followed**
|
|
65
|
-
* (cache outermost).
|
|
66
|
-
*
|
|
67
|
-
* **Synthetic-response on hit.** Returns a `ModelResponse` with
|
|
68
|
-
* `usage: { input: 0, output: 0, total: 0 }` so budget /
|
|
69
|
-
* observability correctly exclude the saved trip.
|
|
70
|
-
*
|
|
71
|
-
* @example
|
|
72
|
-
* import { semanticCache } from "@warlock.js/ai";
|
|
73
|
-
* import { MemoryCacheDriver } from "@warlock.js/cache";
|
|
74
|
-
*
|
|
75
|
-
* const store = new MemoryCacheDriver();
|
|
76
|
-
* store.setOptions({});
|
|
77
|
-
*
|
|
78
|
-
* const cache = semanticCache({
|
|
79
|
-
* embedder: openai.embedder({ name: "text-embedding-3-small" }),
|
|
80
|
-
* store,
|
|
81
|
-
* threshold: 0.95,
|
|
82
|
-
* ttlMs: 60 * 60 * 1000,
|
|
83
|
-
* });
|
|
84
|
-
*
|
|
85
|
-
* const myAgent = agent({ model, middleware: [cache] });
|
|
86
|
-
*/
|
|
87
|
-
function semanticCache(options) {
|
|
88
|
-
const name = options.name ?? "semantic-cache";
|
|
89
|
-
const namespace = options.namespace ?? DEFAULT_NAMESPACE;
|
|
90
|
-
const pendingKey = `${name}.pending`;
|
|
91
|
-
const store = options.store ?? resolveDefaultStore();
|
|
92
|
-
if (!store) throw new Error(`semanticCache: no store supplied — pass \`store\` in options or call \`ai.config({ defaultStore })\` at app boot before constructing the middleware`);
|
|
93
|
-
const keyFor = (hash) => `${namespace}.${hash}`;
|
|
94
|
-
return {
|
|
95
|
-
name,
|
|
96
|
-
log: true,
|
|
97
|
-
trip: {
|
|
98
|
-
async before(context) {
|
|
99
|
-
if (context.tripIndex !== 0) return;
|
|
100
|
-
const promptText = extractUserText(context.messages);
|
|
101
|
-
if (!promptText) return;
|
|
102
|
-
const promptKey = hashPrompt(context.messages);
|
|
103
|
-
const scopedKey = keyFor(promptKey);
|
|
104
|
-
const exact = await store.get(scopedKey);
|
|
105
|
-
if (exact && isFresh(exact, options.ttlMs)) return toSyntheticResponse(exact.response);
|
|
106
|
-
const query = await options.embedder.embed(promptText);
|
|
107
|
-
const [hit] = await store.similar(query.vector, {
|
|
108
|
-
topK: 1,
|
|
109
|
-
threshold: options.threshold
|
|
110
|
-
});
|
|
111
|
-
if (hit && isFresh(hit.value, options.ttlMs)) {
|
|
112
|
-
if (hit.key.startsWith(`${namespace}.`)) return toSyntheticResponse(hit.value.response);
|
|
113
|
-
}
|
|
114
|
-
const pending = {
|
|
115
|
-
promptKey,
|
|
116
|
-
vector: query.vector
|
|
117
|
-
};
|
|
118
|
-
context.state.set(pendingKey, pending);
|
|
119
|
-
},
|
|
120
|
-
async after(context, response) {
|
|
121
|
-
const pending = context.state.get(pendingKey);
|
|
122
|
-
if (!pending) return;
|
|
123
|
-
if (response.finishReason === "tool_calls") return;
|
|
124
|
-
context.state.delete(pendingKey);
|
|
125
|
-
const entry = {
|
|
126
|
-
response,
|
|
127
|
-
storedAt: Date.now()
|
|
128
|
-
};
|
|
129
|
-
await store.set(keyFor(pending.promptKey), entry, { vector: pending.vector });
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
};
|
|
133
|
-
}
|
|
134
|
-
function toSyntheticResponse(response) {
|
|
135
|
-
return {
|
|
136
|
-
content: response.content,
|
|
137
|
-
finishReason: response.finishReason,
|
|
138
|
-
usage: {
|
|
139
|
-
input: 0,
|
|
140
|
-
output: 0,
|
|
141
|
-
total: 0
|
|
142
|
-
},
|
|
143
|
-
toolCalls: response.toolCalls
|
|
144
|
-
};
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
//#endregion
|
|
148
|
-
export { semanticCache };
|
|
149
|
-
//# sourceMappingURL=semantic-cache.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"semantic-cache.mjs","names":[],"sources":["../../../../../../../../../../@warlock.js/ai/src/middleware/builtins/semantic-cache.ts"],"sourcesContent":["import type { CacheDriver } from \"@warlock.js/cache\";\nimport { resolveDefaultStore } from \"../../config\";\nimport type { Message } from \"../../contracts/conversation-message.type\";\nimport type { EmbedderContract } from \"../../contracts/embedder.contract\";\nimport type { AgentMiddleware } from \"../../contracts/middleware\";\nimport type { ModelResponse } from \"../../contracts/model.contract\";\nimport { extractUserText } from \"../utils\";\n\n/**\n * Configuration for `semanticCache()`.\n */\nexport type SemanticCacheOptions = {\n /** Embedder used to produce the query vector from the prompt text. */\n embedder: EmbedderContract;\n /**\n * Vector-capable cache driver from `@warlock.js/cache`. Production\n * deployments pick a driver with a real ANN index (`pg` with\n * pgvector, `redis` with RediSearch). Dev / test environments use\n * `new MemoryCacheDriver()` — zero config, correct, but O(N) per\n * query. Drivers without similarity support throw\n * `CacheUnsupportedError` from `set({ vector })` / `similar()`.\n *\n * Falls back to `ai.config({ defaultStore })` when omitted. When\n * neither is set, the factory throws at construction time —\n * semantic cache cannot operate without a store.\n */\n store?: CacheDriver<any, any>;\n /**\n * Minimum cosine similarity for a vector hit. Between 0 and 1 —\n * 0.95 is a solid default for question-answering caches.\n */\n threshold: number;\n /**\n * Optional TTL in milliseconds. Entries whose `storedAt` is older\n * than this are treated as misses on read and overwritten on the\n * next write. Default: no expiry — entries live until the store\n * evicts them (per its own TTL/eviction policy).\n */\n ttlMs?: number;\n /**\n * Namespace prefix applied to every key the cache writes. Lets\n * multiple agents share one driver without collision. Default\n * `\"ai.cache\"`.\n */\n namespace?: string;\n /**\n * Middleware name — also the state-bag key prefix inside a single\n * execution. Default `\"semantic-cache\"`.\n */\n name?: string;\n};\n\ntype CachedEntry = {\n response: ModelResponse;\n storedAt: number;\n};\n\ntype PendingWrite = {\n promptKey: string;\n vector: number[];\n};\n\nconst DEFAULT_NAMESPACE = \"ai.cache\";\n\n/**\n * Build a stable fingerprint for a prompt covering the full message\n * list (system + history + user turn). Ensures two prompts sharing\n * the user text but differing in prior context do not collide on\n * the exact-match fast path.\n *\n * FNV-1a variant — cheap, collision-resistant enough for a cache,\n * dependency-free. NOT a cryptographic hash: collisions would\n * surface as wrong cache hits, not a security issue in the current\n * trust model.\n */\nfunction hashPrompt(messages: ReadonlyArray<Message>): string {\n const serialized = messages\n .map((message) => {\n const role = message.role;\n const content = Array.isArray(message.content)\n ? message.content\n .filter((part) => part.type === \"text\")\n .map((part) => (part as { text: string }).text)\n .join(\"|\")\n : message.content;\n\n return `${role}:${content}`;\n })\n .join(\"||\");\n\n let hash = 0x811c9dc5;\n\n for (let index = 0; index < serialized.length; index++) {\n hash ^= serialized.charCodeAt(index);\n hash = Math.imul(hash, 0x01000193);\n }\n\n return (hash >>> 0).toString(16);\n}\n\nfunction isFresh(entry: CachedEntry, ttlMs: number | undefined): boolean {\n if (ttlMs === undefined) {\n return true;\n }\n\n return Date.now() - entry.storedAt <= ttlMs;\n}\n\n/**\n * Semantic-similarity response cache for an agent run.\n *\n * **Role.** Skips LLM round-trips when the current prompt is\n * semantically close to one the agent has already answered. For\n * FAQ / support-style traffic this often eliminates 60–80% of\n * model calls — the production win is massive for cost and\n * latency.\n *\n * **Delegation to `@warlock.js/cache`.** This middleware does NOT\n * implement similarity search itself. It delegates to the supplied\n * `CacheDriver`. Production deployments pick a driver with an ANN\n * index (`pg` + pgvector, `redis` + RediSearch). Dev / test\n * environments pass `new MemoryCacheDriver()` — zero config, correct,\n * but O(N) per query. Drivers without similarity support throw\n * `CacheUnsupportedError` from `set({ vector })` / `similar()`.\n *\n * **Two-tier lookup.**\n * 1. *Exact-match key* — a cheap FNV hash over the entire message\n * list. `store.get(hash)` returns the entry without an embedding\n * round trip when the prompt hasn't changed at all.\n * 2. *Vector-match* — on exact-match miss, embed the prompt and\n * call `store.similar(vector, { topK: 1, threshold })`. The\n * driver uses its native similarity index; anything clearing\n * `threshold` is returned as a hit.\n *\n * **Write-on-miss.** When both tiers miss, `trip.before` stashes\n * the prompt hash + vector in `ctx.state`; `trip.after` reads back\n * the pending entry and calls\n * `store.set(hash, entry, { vector })`. If an outer middleware\n * (guardrail) throws in `trip.after` before the cache's `trip.after`\n * runs, the pending entry is never written — bad responses stay out\n * of the cache **as long as the canonical install order is followed**\n * (cache outermost).\n *\n * **Synthetic-response on hit.** Returns a `ModelResponse` with\n * `usage: { input: 0, output: 0, total: 0 }` so budget /\n * observability correctly exclude the saved trip.\n *\n * @example\n * import { semanticCache } from \"@warlock.js/ai\";\n * import { MemoryCacheDriver } from \"@warlock.js/cache\";\n *\n * const store = new MemoryCacheDriver();\n * store.setOptions({});\n *\n * const cache = semanticCache({\n * embedder: openai.embedder({ name: \"text-embedding-3-small\" }),\n * store,\n * threshold: 0.95,\n * ttlMs: 60 * 60 * 1000,\n * });\n *\n * const myAgent = agent({ model, middleware: [cache] });\n */\nexport function semanticCache(options: SemanticCacheOptions): AgentMiddleware {\n const name = options.name ?? \"semantic-cache\";\n const namespace = options.namespace ?? DEFAULT_NAMESPACE;\n const pendingKey = `${name}.pending`;\n\n // Resolve the effective store at factory time, not per-call. Every\n // subsequent hook closes over `store` so the resolution happens once.\n // Throws now (loud, at construction) instead of later during the\n // first trip (silent until the agent actually runs).\n const store = options.store ?? resolveDefaultStore();\n\n if (!store) {\n throw new Error(\n `semanticCache: no store supplied — pass \\`store\\` in options or call \\`ai.config({ defaultStore })\\` at app boot before constructing the middleware`,\n );\n }\n\n // Cache's parseKey replaces \":\" with \".\" so the namespace boundary\n // matches what `similar()` actually returns in `hit.key`. Using a\n // dot here keeps prefix checks aligned with stored keys.\n const keyFor = (hash: string): string => `${namespace}.${hash}`;\n\n return {\n name,\n log: true,\n trip: {\n async before(context) {\n // Only cache the first trip's response. Subsequent trips\n // happen because the previous trip requested tool calls — the\n // message list now carries tool results the original prompt\n // never saw, so a semantic match on the unchanged user text\n // would serve back the prior `tool_calls` response and loop\n // the agent forever. The first turn is also the only one\n // where a \"same question → same final answer\" caching story\n // is sound.\n if (context.tripIndex !== 0) {\n return;\n }\n\n const promptText = extractUserText(context.messages);\n\n if (!promptText) {\n return;\n }\n\n const promptKey = hashPrompt(context.messages);\n const scopedKey = keyFor(promptKey);\n\n const exact = await store.get<CachedEntry>(scopedKey);\n\n if (exact && isFresh(exact, options.ttlMs)) {\n return toSyntheticResponse(exact.response);\n }\n\n const query = await options.embedder.embed(promptText);\n\n const [hit] = await store.similar<CachedEntry>(query.vector, {\n topK: 1,\n threshold: options.threshold,\n });\n\n if (hit && isFresh(hit.value, options.ttlMs)) {\n // Only return hits whose stored key is within this cache's\n // namespace. Drivers shared across namespaces would otherwise\n // leak foreign entries into queries.\n if (hit.key.startsWith(`${namespace}.`)) {\n return toSyntheticResponse(hit.value.response);\n }\n }\n\n const pending: PendingWrite = { promptKey, vector: query.vector };\n context.state.set(pendingKey, pending);\n\n return;\n },\n async after(context, response) {\n const pending = context.state.get(pendingKey) as PendingWrite | undefined;\n\n if (!pending) {\n return;\n }\n\n // Mid-stream tool-call responses must not be cached — the\n // useful answer comes from the trip *after* the tool returns.\n // Crucially, leave the pending entry in place so a later trip\n // (the one that actually finishes with `stop`) can read it\n // and write the final response under the *original* trip-0\n // prompt key. Deleting here would orphan the pending and the\n // post-tool answer would never make it into the store.\n if (response.finishReason === \"tool_calls\") {\n return;\n }\n\n context.state.delete(pendingKey);\n\n const entry: CachedEntry = { response, storedAt: Date.now() };\n\n await store.set(keyFor(pending.promptKey), entry, {\n vector: pending.vector,\n });\n\n return;\n },\n },\n };\n}\n\nfunction toSyntheticResponse(response: ModelResponse): ModelResponse {\n return {\n content: response.content,\n finishReason: response.finishReason,\n usage: { input: 0, output: 0, total: 0 },\n toolCalls: response.toolCalls,\n };\n}\n"],"mappings":";;;;AA8DA,MAAM,oBAAoB;;;;;;;;;;;;AAa1B,SAAS,WAAW,UAA0C;CAC5D,MAAM,aAAa,SAChB,KAAK,YAAY;EAShB,OAAO,GARM,QAAQ,KAQN,GAPC,MAAM,QAAQ,QAAQ,OAAO,IACzC,QAAQ,QACL,QAAQ,SAAS,KAAK,SAAS,MAAM,CAAC,CACtC,KAAK,SAAU,KAA0B,IAAI,CAAC,CAC9C,KAAK,GAAG,IACX,QAAQ;CAGd,CAAC,CAAC,CACD,KAAK,IAAI;CAEZ,IAAI,OAAO;CAEX,KAAK,IAAI,QAAQ,GAAG,QAAQ,WAAW,QAAQ,SAAS;EACtD,QAAQ,WAAW,WAAW,KAAK;EACnC,OAAO,KAAK,KAAK,MAAM,QAAU;CACnC;CAEA,QAAQ,SAAS,EAAC,CAAE,SAAS,EAAE;AACjC;AAEA,SAAS,QAAQ,OAAoB,OAAoC;CACvE,IAAI,UAAU,QACZ,OAAO;CAGT,OAAO,KAAK,IAAI,IAAI,MAAM,YAAY;AACxC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyDA,SAAgB,cAAc,SAAgD;CAC5E,MAAM,OAAO,QAAQ,QAAQ;CAC7B,MAAM,YAAY,QAAQ,aAAa;CACvC,MAAM,aAAa,GAAG,KAAK;CAM3B,MAAM,QAAQ,QAAQ,SAAS,oBAAoB;CAEnD,IAAI,CAAC,OACH,MAAM,IAAI,MACR,qJACF;CAMF,MAAM,UAAU,SAAyB,GAAG,UAAU,GAAG;CAEzD,OAAO;EACL;EACA,KAAK;EACL,MAAM;GACJ,MAAM,OAAO,SAAS;IASpB,IAAI,QAAQ,cAAc,GACxB;IAGF,MAAM,aAAa,gBAAgB,QAAQ,QAAQ;IAEnD,IAAI,CAAC,YACH;IAGF,MAAM,YAAY,WAAW,QAAQ,QAAQ;IAC7C,MAAM,YAAY,OAAO,SAAS;IAElC,MAAM,QAAQ,MAAM,MAAM,IAAiB,SAAS;IAEpD,IAAI,SAAS,QAAQ,OAAO,QAAQ,KAAK,GACvC,OAAO,oBAAoB,MAAM,QAAQ;IAG3C,MAAM,QAAQ,MAAM,QAAQ,SAAS,MAAM,UAAU;IAErD,MAAM,CAAC,OAAO,MAAM,MAAM,QAAqB,MAAM,QAAQ;KAC3D,MAAM;KACN,WAAW,QAAQ;IACrB,CAAC;IAED,IAAI,OAAO,QAAQ,IAAI,OAAO,QAAQ,KAAK,GAIzC;SAAI,IAAI,IAAI,WAAW,GAAG,UAAU,EAAE,GACpC,OAAO,oBAAoB,IAAI,MAAM,QAAQ;IAC/C;IAGF,MAAM,UAAwB;KAAE;KAAW,QAAQ,MAAM;IAAO;IAChE,QAAQ,MAAM,IAAI,YAAY,OAAO;GAGvC;GACA,MAAM,MAAM,SAAS,UAAU;IAC7B,MAAM,UAAU,QAAQ,MAAM,IAAI,UAAU;IAE5C,IAAI,CAAC,SACH;IAUF,IAAI,SAAS,iBAAiB,cAC5B;IAGF,QAAQ,MAAM,OAAO,UAAU;IAE/B,MAAM,QAAqB;KAAE;KAAU,UAAU,KAAK,IAAI;IAAE;IAE5D,MAAM,MAAM,IAAI,OAAO,QAAQ,SAAS,GAAG,OAAO,EAChD,QAAQ,QAAQ,OAClB,CAAC;GAGH;EACF;CACF;AACF;AAEA,SAAS,oBAAoB,UAAwC;CACnE,OAAO;EACL,SAAS,SAAS;EAClB,cAAc,SAAS;EACvB,OAAO;GAAE,OAAO;GAAG,QAAQ;GAAG,OAAO;EAAE;EACvC,WAAW,SAAS;CACtB;AACF"}
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
//#region ../@warlock.js/ai/src/middleware/helpers/compose.ts
|
|
2
|
-
/**
|
|
3
|
-
* Flatten one or more middleware sources into a single ordered
|
|
4
|
-
* array suitable for `agent({ middleware: [...] })`.
|
|
5
|
-
*
|
|
6
|
-
* **Role.** As middleware catalogs grow, agent configs accumulate
|
|
7
|
-
* long arrays that mix "always-on" stacks (cache + budget + guardrail)
|
|
8
|
-
* with per-concern extras (per-tool rate-limits, audit hooks). A
|
|
9
|
-
* single `compose` call lets callers keep those sources as named
|
|
10
|
-
* variables and flatten at the registration site.
|
|
11
|
-
*
|
|
12
|
-
* **Semantics.** Registration order is preserved across sources —
|
|
13
|
-
* `compose(a, b, c)` produces `[...a, ...b, ...c]`. Because the
|
|
14
|
-
* pipeline's onion is strictly registration-ordered, the flattened
|
|
15
|
-
* order is the execution order. No de-duplication, no sorting, no
|
|
16
|
-
* priority logic — that would hide bugs, not fix them.
|
|
17
|
-
*
|
|
18
|
-
* **Accepts arrays OR individual middlewares.** Both forms are
|
|
19
|
-
* common in callsite code; the helper flattens either.
|
|
20
|
-
*
|
|
21
|
-
* @example
|
|
22
|
-
* const standardStack = [
|
|
23
|
-
* ai.middleware.semanticCache({ ... }),
|
|
24
|
-
* ai.middleware.budget({ maxTokens: 20_000 }),
|
|
25
|
-
* ai.middleware.guardrail({ ... }),
|
|
26
|
-
* ];
|
|
27
|
-
*
|
|
28
|
-
* const toolRateLimits = [
|
|
29
|
-
* toolRateLimit({ tool: "search_web", maxCalls: 3 }),
|
|
30
|
-
* toolRateLimit({ tool: "expensive_api", maxCalls: 1 }),
|
|
31
|
-
* ];
|
|
32
|
-
*
|
|
33
|
-
* const myAgent = ai.agent({
|
|
34
|
-
* model,
|
|
35
|
-
* middleware: ai.middleware.compose(standardStack, toolRateLimits, auditMiddleware),
|
|
36
|
-
* });
|
|
37
|
-
*/
|
|
38
|
-
function composeMiddleware(...sources) {
|
|
39
|
-
const out = [];
|
|
40
|
-
for (const source of sources) {
|
|
41
|
-
if (Array.isArray(source)) {
|
|
42
|
-
out.push(...source);
|
|
43
|
-
continue;
|
|
44
|
-
}
|
|
45
|
-
out.push(source);
|
|
46
|
-
}
|
|
47
|
-
return out;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
//#endregion
|
|
51
|
-
export { composeMiddleware };
|
|
52
|
-
//# sourceMappingURL=compose.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"compose.mjs","names":[],"sources":["../../../../../../../../../../@warlock.js/ai/src/middleware/helpers/compose.ts"],"sourcesContent":["import type { AgentMiddleware } from \"../../contracts/middleware\";\n\n/**\n * Flatten one or more middleware sources into a single ordered\n * array suitable for `agent({ middleware: [...] })`.\n *\n * **Role.** As middleware catalogs grow, agent configs accumulate\n * long arrays that mix \"always-on\" stacks (cache + budget + guardrail)\n * with per-concern extras (per-tool rate-limits, audit hooks). A\n * single `compose` call lets callers keep those sources as named\n * variables and flatten at the registration site.\n *\n * **Semantics.** Registration order is preserved across sources —\n * `compose(a, b, c)` produces `[...a, ...b, ...c]`. Because the\n * pipeline's onion is strictly registration-ordered, the flattened\n * order is the execution order. No de-duplication, no sorting, no\n * priority logic — that would hide bugs, not fix them.\n *\n * **Accepts arrays OR individual middlewares.** Both forms are\n * common in callsite code; the helper flattens either.\n *\n * @example\n * const standardStack = [\n * ai.middleware.semanticCache({ ... }),\n * ai.middleware.budget({ maxTokens: 20_000 }),\n * ai.middleware.guardrail({ ... }),\n * ];\n *\n * const toolRateLimits = [\n * toolRateLimit({ tool: \"search_web\", maxCalls: 3 }),\n * toolRateLimit({ tool: \"expensive_api\", maxCalls: 1 }),\n * ];\n *\n * const myAgent = ai.agent({\n * model,\n * middleware: ai.middleware.compose(standardStack, toolRateLimits, auditMiddleware),\n * });\n */\nexport function composeMiddleware(\n ...sources: ReadonlyArray<AgentMiddleware | ReadonlyArray<AgentMiddleware>>\n): AgentMiddleware[] {\n const out: AgentMiddleware[] = [];\n\n for (const source of sources) {\n if (Array.isArray(source)) {\n out.push(...source);\n continue;\n }\n\n out.push(source as AgentMiddleware);\n }\n\n return out;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsCA,SAAgB,kBACd,GAAG,SACgB;CACnB,MAAM,MAAyB,CAAC;CAEhC,KAAK,MAAM,UAAU,SAAS;EAC5B,IAAI,MAAM,QAAQ,MAAM,GAAG;GACzB,IAAI,KAAK,GAAG,MAAM;GAClB;EACF;EAEA,IAAI,KAAK,MAAyB;CACpC;CAEA,OAAO;AACT"}
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
//#region ../@warlock.js/ai/src/middleware/helpers/for-tool.ts
|
|
2
|
-
/**
|
|
3
|
-
* Scope a middleware's `tool`-level hooks to only fire for a
|
|
4
|
-
* specific tool name (or a set of names). `execute` and `trip`
|
|
5
|
-
* hooks pass through unchanged.
|
|
6
|
-
*
|
|
7
|
-
* **Role.** Tool-specific concerns — "rate-limit `search_web`",
|
|
8
|
-
* "cache results for `fetch_faq`" — are common. Rather than adding
|
|
9
|
-
* a `middleware` field to `ai.tool()` (see decisions §27), the
|
|
10
|
-
* framework keeps one contract (`AgentMiddleware`) and offers this
|
|
11
|
-
* helper for the locality problem. The middleware body stays agnostic
|
|
12
|
-
* of the tool name; `forTool` handles the filtering.
|
|
13
|
-
*
|
|
14
|
-
* **What gets filtered.** Only `tool.before` / `tool.after` /
|
|
15
|
-
* `tool.onError`. Each hook is wrapped so that `ctx.tool.name`
|
|
16
|
-
* must be in the allowed set or the wrapped hook is a no-op.
|
|
17
|
-
* `execute` and `trip` hooks are NOT touched — they run normally.
|
|
18
|
-
*
|
|
19
|
-
* **Why not filter execute/trip too?** Because a middleware that
|
|
20
|
-
* reaches across levels (a tool-specific budget that initializes a
|
|
21
|
-
* counter in `execute.before` and checks it in `tool.before`) still
|
|
22
|
-
* needs `execute.before` to fire unconditionally. Scoping all hooks
|
|
23
|
-
* would break cross-level middleware; scoping only `tool` hooks
|
|
24
|
-
* matches the mental model of "this middleware cares about these
|
|
25
|
-
* tools."
|
|
26
|
-
*
|
|
27
|
-
* **Single-name vs multi-name.** A string matches one tool; a string
|
|
28
|
-
* array matches any of the listed tools. No wildcards, no regex —
|
|
29
|
-
* keep it boring.
|
|
30
|
-
*
|
|
31
|
-
* @example
|
|
32
|
-
* // Single tool
|
|
33
|
-
* const scoped = ai.middleware.forTool(
|
|
34
|
-
* "search_web",
|
|
35
|
-
* toolRateLimit({ maxCalls: 3 }),
|
|
36
|
-
* );
|
|
37
|
-
*
|
|
38
|
-
* @example
|
|
39
|
-
* // Multiple tools sharing a rule
|
|
40
|
-
* const scoped = ai.middleware.forTool(
|
|
41
|
-
* ["paid_api", "expensive_db"],
|
|
42
|
-
* toolRateLimit({ maxCalls: 5 }),
|
|
43
|
-
* );
|
|
44
|
-
*
|
|
45
|
-
* ai.agent({
|
|
46
|
-
* model,
|
|
47
|
-
* tools: [webTool, paidApiTool, expensiveDbTool],
|
|
48
|
-
* middleware: [scoped],
|
|
49
|
-
* });
|
|
50
|
-
*/
|
|
51
|
-
function forTool(toolNames, middleware) {
|
|
52
|
-
const allowed = new Set(typeof toolNames === "string" ? [toolNames] : toolNames);
|
|
53
|
-
const scope = allowed.size === 1 ? Array.from(allowed)[0] : Array.from(allowed).join("+");
|
|
54
|
-
if (!middleware.tool) return middleware;
|
|
55
|
-
const innerBefore = middleware.tool.before;
|
|
56
|
-
const innerAfter = middleware.tool.after;
|
|
57
|
-
const innerOnError = middleware.tool.onError;
|
|
58
|
-
return {
|
|
59
|
-
...middleware,
|
|
60
|
-
name: `${middleware.name}[for:${scope}]`,
|
|
61
|
-
tool: {
|
|
62
|
-
before: innerBefore ? async (ctx) => {
|
|
63
|
-
if (!allowed.has(ctx.tool.name)) return;
|
|
64
|
-
return innerBefore(ctx);
|
|
65
|
-
} : void 0,
|
|
66
|
-
after: innerAfter ? async (ctx, result) => {
|
|
67
|
-
if (!allowed.has(ctx.tool.name)) return;
|
|
68
|
-
return innerAfter(ctx, result);
|
|
69
|
-
} : void 0,
|
|
70
|
-
onError: innerOnError ? async (ctx, error) => {
|
|
71
|
-
if (!allowed.has(ctx.tool.name)) return;
|
|
72
|
-
return innerOnError(ctx, error);
|
|
73
|
-
} : void 0
|
|
74
|
-
}
|
|
75
|
-
};
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
//#endregion
|
|
79
|
-
export { forTool };
|
|
80
|
-
//# sourceMappingURL=for-tool.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"for-tool.mjs","names":[],"sources":["../../../../../../../../../../@warlock.js/ai/src/middleware/helpers/for-tool.ts"],"sourcesContent":["import type { AgentMiddleware } from \"../../contracts/middleware\";\n\n/**\n * Scope a middleware's `tool`-level hooks to only fire for a\n * specific tool name (or a set of names). `execute` and `trip`\n * hooks pass through unchanged.\n *\n * **Role.** Tool-specific concerns — \"rate-limit `search_web`\",\n * \"cache results for `fetch_faq`\" — are common. Rather than adding\n * a `middleware` field to `ai.tool()` (see decisions §27), the\n * framework keeps one contract (`AgentMiddleware`) and offers this\n * helper for the locality problem. The middleware body stays agnostic\n * of the tool name; `forTool` handles the filtering.\n *\n * **What gets filtered.** Only `tool.before` / `tool.after` /\n * `tool.onError`. Each hook is wrapped so that `ctx.tool.name`\n * must be in the allowed set or the wrapped hook is a no-op.\n * `execute` and `trip` hooks are NOT touched — they run normally.\n *\n * **Why not filter execute/trip too?** Because a middleware that\n * reaches across levels (a tool-specific budget that initializes a\n * counter in `execute.before` and checks it in `tool.before`) still\n * needs `execute.before` to fire unconditionally. Scoping all hooks\n * would break cross-level middleware; scoping only `tool` hooks\n * matches the mental model of \"this middleware cares about these\n * tools.\"\n *\n * **Single-name vs multi-name.** A string matches one tool; a string\n * array matches any of the listed tools. No wildcards, no regex —\n * keep it boring.\n *\n * @example\n * // Single tool\n * const scoped = ai.middleware.forTool(\n * \"search_web\",\n * toolRateLimit({ maxCalls: 3 }),\n * );\n *\n * @example\n * // Multiple tools sharing a rule\n * const scoped = ai.middleware.forTool(\n * [\"paid_api\", \"expensive_db\"],\n * toolRateLimit({ maxCalls: 5 }),\n * );\n *\n * ai.agent({\n * model,\n * tools: [webTool, paidApiTool, expensiveDbTool],\n * middleware: [scoped],\n * });\n */\nexport function forTool(\n toolNames: string | ReadonlyArray<string>,\n middleware: AgentMiddleware,\n): AgentMiddleware {\n const allowed = new Set(\n typeof toolNames === \"string\" ? [toolNames] : toolNames,\n );\n const scope =\n allowed.size === 1 ? Array.from(allowed)[0] : Array.from(allowed).join(\"+\");\n\n if (!middleware.tool) {\n return middleware;\n }\n\n const innerBefore = middleware.tool.before;\n const innerAfter = middleware.tool.after;\n const innerOnError = middleware.tool.onError;\n\n return {\n ...middleware,\n name: `${middleware.name}[for:${scope}]`,\n tool: {\n before: innerBefore\n ? async ctx => {\n if (!allowed.has(ctx.tool.name)) {\n return;\n }\n\n return innerBefore(ctx);\n }\n : undefined,\n after: innerAfter\n ? async (ctx, result) => {\n if (!allowed.has(ctx.tool.name)) {\n return;\n }\n\n return innerAfter(ctx, result);\n }\n : undefined,\n onError: innerOnError\n ? async (ctx, error) => {\n if (!allowed.has(ctx.tool.name)) {\n return;\n }\n\n return innerOnError(ctx, error);\n }\n : undefined,\n },\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmDA,SAAgB,QACd,WACA,YACiB;CACjB,MAAM,UAAU,IAAI,IAClB,OAAO,cAAc,WAAW,CAAC,SAAS,IAAI,SAChD;CACA,MAAM,QACJ,QAAQ,SAAS,IAAI,MAAM,KAAK,OAAO,CAAC,CAAC,KAAK,MAAM,KAAK,OAAO,CAAC,CAAC,KAAK,GAAG;CAE5E,IAAI,CAAC,WAAW,MACd,OAAO;CAGT,MAAM,cAAc,WAAW,KAAK;CACpC,MAAM,aAAa,WAAW,KAAK;CACnC,MAAM,eAAe,WAAW,KAAK;CAErC,OAAO;EACL,GAAG;EACH,MAAM,GAAG,WAAW,KAAK,OAAO,MAAM;EACtC,MAAM;GACJ,QAAQ,cACJ,OAAM,QAAO;IACX,IAAI,CAAC,QAAQ,IAAI,IAAI,KAAK,IAAI,GAC5B;IAGF,OAAO,YAAY,GAAG;GACxB,IACA;GACJ,OAAO,aACH,OAAO,KAAK,WAAW;IACrB,IAAI,CAAC,QAAQ,IAAI,IAAI,KAAK,IAAI,GAC5B;IAGF,OAAO,WAAW,KAAK,MAAM;GAC/B,IACA;GACJ,SAAS,eACL,OAAO,KAAK,UAAU;IACpB,IAAI,CAAC,QAAQ,IAAI,IAAI,KAAK,IAAI,GAC5B;IAGF,OAAO,aAAa,KAAK,KAAK;GAChC,IACA;EACN;CACF;AACF"}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { extractUserText } from "./utils/extract-user-text.mjs";
|
|
2
|
-
import { namespacedState } from "./utils/namespaced-state.mjs";
|
|
3
|
-
import { budget, readBudgetFallbackSignal } from "./builtins/budget.mjs";
|
|
4
|
-
import { guardrail } from "./builtins/guardrail.mjs";
|
|
5
|
-
import { semanticCache } from "./builtins/semantic-cache.mjs";
|
|
6
|
-
import { composeMiddleware } from "./helpers/compose.mjs";
|
|
7
|
-
import { forTool } from "./helpers/for-tool.mjs";
|
|
8
|
-
import { runPipeline } from "./pipeline.mjs";
|
|
9
|
-
|
|
10
|
-
export { };
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
//#region ../@warlock.js/ai/src/middleware/pipeline.ts
|
|
2
|
-
const LOG_MODULE = "ai.middleware";
|
|
3
|
-
/**
|
|
4
|
-
* Run an inner async operation through a stack of agent middlewares
|
|
5
|
-
* at a single level, applying the onion-model before/after/onError
|
|
6
|
-
* semantics documented on `AgentMiddleware`.
|
|
7
|
-
*
|
|
8
|
-
* **Semantics.**
|
|
9
|
-
* - `before` hooks run in registration order (top-down).
|
|
10
|
-
* Returning a defined value from a `before` hook short-circuits the
|
|
11
|
-
* pipeline with that value as the result, skipping `inner()` and
|
|
12
|
-
* all deeper `before` / `after` hooks — but outer middleware
|
|
13
|
-
* `after` hooks (registered earlier) still run on the synthetic
|
|
14
|
-
* value.
|
|
15
|
-
* - `after` hooks run in reverse registration order (bottom-up).
|
|
16
|
-
* Returning a defined value replaces the result before it
|
|
17
|
-
* propagates further out. Returning `void` / `undefined` keeps the
|
|
18
|
-
* existing result.
|
|
19
|
-
* - `onError` hooks also run in reverse (bottom-up) — any error
|
|
20
|
-
* thrown by `inner()`, by a `before` hook, or by an `after` hook
|
|
21
|
-
* unwinds through each frame's `onError` in turn. Returning a
|
|
22
|
-
* defined value from `onError` recovers: the error is cleared and
|
|
23
|
-
* the returned value becomes the new result (which then flows
|
|
24
|
-
* through outer `after` hooks). Returning `void` propagates the
|
|
25
|
-
* error to the next outer frame.
|
|
26
|
-
*
|
|
27
|
-
* **Implementation.** Built by folding the middleware array from the
|
|
28
|
-
* end inward: each middleware produces a closure that wraps the
|
|
29
|
-
* previous closure (the deeper pipeline). The outermost wrap is
|
|
30
|
-
* middleware index 0 — so registration order matches onion order
|
|
31
|
-
* without any reverse iteration at call time.
|
|
32
|
-
*
|
|
33
|
-
* **No magic.** The pipeline does not swallow, retry, or translate
|
|
34
|
-
* errors. Hooks that throw propagate unchanged (subject to `onError`
|
|
35
|
-
* recovery). Pipeline-level logging is debug-only and respects each
|
|
36
|
-
* middleware's `log: false` kill-switch.
|
|
37
|
-
*
|
|
38
|
-
* @example
|
|
39
|
-
* const response = await runPipeline(
|
|
40
|
-
* middlewares,
|
|
41
|
-
* "trip",
|
|
42
|
-
* tripContext,
|
|
43
|
-
* () => model.complete(messages, callOptions),
|
|
44
|
-
* logger,
|
|
45
|
-
* );
|
|
46
|
-
*/
|
|
47
|
-
async function runPipeline(middlewares, level, context, inner, logger) {
|
|
48
|
-
if (middlewares.length === 0) return inner();
|
|
49
|
-
let next = inner;
|
|
50
|
-
for (let index = middlewares.length - 1; index >= 0; index--) {
|
|
51
|
-
const middleware = middlewares[index];
|
|
52
|
-
const hooks = middleware[level];
|
|
53
|
-
if (!hooks) continue;
|
|
54
|
-
const previous = next;
|
|
55
|
-
next = async () => {
|
|
56
|
-
const logEnabled = middleware.log !== false && logger !== void 0;
|
|
57
|
-
if (hooks.before) {
|
|
58
|
-
if (logEnabled) logger.debug(LOG_MODULE, `${level}.before`, middleware.name, {
|
|
59
|
-
middleware: middleware.name,
|
|
60
|
-
level
|
|
61
|
-
});
|
|
62
|
-
const shortCircuit = await hooks.before(context);
|
|
63
|
-
if (shortCircuit !== void 0) {
|
|
64
|
-
if (logEnabled) logger.debug(LOG_MODULE, `${level}.short-circuit`, middleware.name, {
|
|
65
|
-
middleware: middleware.name,
|
|
66
|
-
level
|
|
67
|
-
});
|
|
68
|
-
return shortCircuit;
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
let result;
|
|
72
|
-
try {
|
|
73
|
-
result = await previous();
|
|
74
|
-
} catch (thrown) {
|
|
75
|
-
if (!hooks.onError) throw thrown;
|
|
76
|
-
const recovered = await hooks.onError(context, thrown);
|
|
77
|
-
if (recovered === void 0) throw thrown;
|
|
78
|
-
if (logEnabled) logger.debug(LOG_MODULE, `${level}.recovered`, middleware.name, {
|
|
79
|
-
middleware: middleware.name,
|
|
80
|
-
level
|
|
81
|
-
});
|
|
82
|
-
result = recovered;
|
|
83
|
-
}
|
|
84
|
-
if (hooks.after) {
|
|
85
|
-
const replacement = await hooks.after(context, result);
|
|
86
|
-
if (replacement !== void 0) result = replacement;
|
|
87
|
-
if (logEnabled) logger.debug(LOG_MODULE, `${level}.after`, middleware.name, {
|
|
88
|
-
middleware: middleware.name,
|
|
89
|
-
level
|
|
90
|
-
});
|
|
91
|
-
}
|
|
92
|
-
return result;
|
|
93
|
-
};
|
|
94
|
-
}
|
|
95
|
-
return next();
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
//#endregion
|
|
99
|
-
export { runPipeline };
|
|
100
|
-
//# sourceMappingURL=pipeline.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"pipeline.mjs","names":[],"sources":["../../../../../../../../../@warlock.js/ai/src/middleware/pipeline.ts"],"sourcesContent":["import type { Logger } from \"@warlock.js/logger\";\nimport type {\n AgentMiddleware,\n MiddlewareExecuteContext,\n MiddlewareSupervisorContext,\n MiddlewareToolContext,\n MiddlewareTripContext,\n} from \"../contracts/middleware\";\n\nconst LOG_MODULE = \"ai.middleware\";\n\n/**\n * The four levels at which middleware can hook — mirrors\n * `AgentMiddleware`'s optional `execute` / `trip` / `tool` /\n * `supervisor` keys. Kept as a single named union so callers can pass\n * it around without inline-duplicating the literals. The first three\n * fire on the agent pipeline; `supervisor` fires once around a whole\n * `supervisor.execute()` run.\n */\nexport type MiddlewareLevel = \"execute\" | \"trip\" | \"tool\" | \"supervisor\";\n\n/**\n * Shape of the context object for each level. The pipeline is\n * level-parameterized on the ctx type via this mapping so callers\n * get compile-time narrowing when they instantiate `runPipeline`.\n */\nexport type MiddlewareContextByLevel = {\n execute: MiddlewareExecuteContext;\n trip: MiddlewareTripContext;\n tool: MiddlewareToolContext;\n supervisor: MiddlewareSupervisorContext;\n};\n\n/**\n * Run an inner async operation through a stack of agent middlewares\n * at a single level, applying the onion-model before/after/onError\n * semantics documented on `AgentMiddleware`.\n *\n * **Semantics.**\n * - `before` hooks run in registration order (top-down).\n * Returning a defined value from a `before` hook short-circuits the\n * pipeline with that value as the result, skipping `inner()` and\n * all deeper `before` / `after` hooks — but outer middleware\n * `after` hooks (registered earlier) still run on the synthetic\n * value.\n * - `after` hooks run in reverse registration order (bottom-up).\n * Returning a defined value replaces the result before it\n * propagates further out. Returning `void` / `undefined` keeps the\n * existing result.\n * - `onError` hooks also run in reverse (bottom-up) — any error\n * thrown by `inner()`, by a `before` hook, or by an `after` hook\n * unwinds through each frame's `onError` in turn. Returning a\n * defined value from `onError` recovers: the error is cleared and\n * the returned value becomes the new result (which then flows\n * through outer `after` hooks). Returning `void` propagates the\n * error to the next outer frame.\n *\n * **Implementation.** Built by folding the middleware array from the\n * end inward: each middleware produces a closure that wraps the\n * previous closure (the deeper pipeline). The outermost wrap is\n * middleware index 0 — so registration order matches onion order\n * without any reverse iteration at call time.\n *\n * **No magic.** The pipeline does not swallow, retry, or translate\n * errors. Hooks that throw propagate unchanged (subject to `onError`\n * recovery). Pipeline-level logging is debug-only and respects each\n * middleware's `log: false` kill-switch.\n *\n * @example\n * const response = await runPipeline(\n * middlewares,\n * \"trip\",\n * tripContext,\n * () => model.complete(messages, callOptions),\n * logger,\n * );\n */\nexport async function runPipeline<Level extends MiddlewareLevel, TResult>(\n middlewares: ReadonlyArray<AgentMiddleware>,\n level: Level,\n context: MiddlewareContextByLevel[Level],\n inner: () => Promise<TResult>,\n logger?: Logger,\n): Promise<TResult> {\n if (middlewares.length === 0) {\n return inner();\n }\n\n let next: () => Promise<TResult> = inner;\n\n for (let index = middlewares.length - 1; index >= 0; index--) {\n const middleware = middlewares[index];\n const hooks = middleware[level];\n\n if (!hooks) {\n continue;\n }\n\n const previous = next;\n\n next = async () => {\n const logEnabled = middleware.log !== false && logger !== undefined;\n\n if (hooks.before) {\n if (logEnabled) {\n logger!.debug(LOG_MODULE, `${level}.before`, middleware.name, {\n middleware: middleware.name,\n level,\n });\n }\n\n const shortCircuit = await (\n hooks.before as (ctx: unknown) => Promise<unknown> | unknown\n )(context);\n\n if (shortCircuit !== undefined) {\n if (logEnabled) {\n logger!.debug(\n LOG_MODULE,\n `${level}.short-circuit`,\n middleware.name,\n {\n middleware: middleware.name,\n level,\n },\n );\n }\n\n return shortCircuit as TResult;\n }\n }\n\n let result: TResult;\n\n try {\n result = await previous();\n } catch (thrown) {\n if (!hooks.onError) {\n throw thrown;\n }\n\n const recovered = await (\n hooks.onError as (\n ctx: unknown,\n error: unknown,\n ) => Promise<unknown> | unknown\n )(context, thrown);\n\n if (recovered === undefined) {\n throw thrown;\n }\n\n if (logEnabled) {\n logger!.debug(LOG_MODULE, `${level}.recovered`, middleware.name, {\n middleware: middleware.name,\n level,\n });\n }\n\n result = recovered as TResult;\n }\n\n if (hooks.after) {\n const replacement = await (\n hooks.after as (\n ctx: unknown,\n value: unknown,\n ) => Promise<unknown> | unknown\n )(context, result);\n\n if (replacement !== undefined) {\n result = replacement as TResult;\n }\n\n if (logEnabled) {\n logger!.debug(LOG_MODULE, `${level}.after`, middleware.name, {\n middleware: middleware.name,\n level,\n });\n }\n }\n\n return result;\n };\n }\n\n return next();\n}\n"],"mappings":";AASA,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoEnB,eAAsB,YACpB,aACA,OACA,SACA,OACA,QACkB;CAClB,IAAI,YAAY,WAAW,GACzB,OAAO,MAAM;CAGf,IAAI,OAA+B;CAEnC,KAAK,IAAI,QAAQ,YAAY,SAAS,GAAG,SAAS,GAAG,SAAS;EAC5D,MAAM,aAAa,YAAY;EAC/B,MAAM,QAAQ,WAAW;EAEzB,IAAI,CAAC,OACH;EAGF,MAAM,WAAW;EAEjB,OAAO,YAAY;GACjB,MAAM,aAAa,WAAW,QAAQ,SAAS,WAAW;GAE1D,IAAI,MAAM,QAAQ;IAChB,IAAI,YACF,OAAQ,MAAM,YAAY,GAAG,MAAM,UAAU,WAAW,MAAM;KAC5D,YAAY,WAAW;KACvB;IACF,CAAC;IAGH,MAAM,eAAe,MACnB,MAAM,OACN,OAAO;IAET,IAAI,iBAAiB,QAAW;KAC9B,IAAI,YACF,OAAQ,MACN,YACA,GAAG,MAAM,iBACT,WAAW,MACX;MACE,YAAY,WAAW;MACvB;KACF,CACF;KAGF,OAAO;IACT;GACF;GAEA,IAAI;GAEJ,IAAI;IACF,SAAS,MAAM,SAAS;GAC1B,SAAS,QAAQ;IACf,IAAI,CAAC,MAAM,SACT,MAAM;IAGR,MAAM,YAAY,MAChB,MAAM,QAIN,SAAS,MAAM;IAEjB,IAAI,cAAc,QAChB,MAAM;IAGR,IAAI,YACF,OAAQ,MAAM,YAAY,GAAG,MAAM,aAAa,WAAW,MAAM;KAC/D,YAAY,WAAW;KACvB;IACF,CAAC;IAGH,SAAS;GACX;GAEA,IAAI,MAAM,OAAO;IACf,MAAM,cAAc,MAClB,MAAM,MAIN,SAAS,MAAM;IAEjB,IAAI,gBAAgB,QAClB,SAAS;IAGX,IAAI,YACF,OAAQ,MAAM,YAAY,GAAG,MAAM,SAAS,WAAW,MAAM;KAC3D,YAAY,WAAW;KACvB;IACF,CAAC;GAEL;GAEA,OAAO;EACT;CACF;CAEA,OAAO,KAAK;AACd"}
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
//#region ../@warlock.js/ai/src/middleware/utils/extract-user-text.ts
|
|
2
|
-
/**
|
|
3
|
-
* Pull the text a content-inspection middleware should care about
|
|
4
|
-
* from the outbound message list.
|
|
5
|
-
*
|
|
6
|
-
* **Role.** Built-ins that inspect "what the user just said" — the
|
|
7
|
-
* guardrail on `trip.before`, the semantic cache on `trip.before`,
|
|
8
|
-
* future consumers like PII redactors — all need the same string:
|
|
9
|
-
* the most recent `user`-role message's text content. This helper
|
|
10
|
-
* is the single authority on how that string is resolved.
|
|
11
|
-
*
|
|
12
|
-
* **Behavior.**
|
|
13
|
-
* - Walks `messages` from the end backwards so the LAST user turn
|
|
14
|
-
* wins (correct when the agent has history + a fresh prompt).
|
|
15
|
-
* - Returns a plain string directly when `content` is a string.
|
|
16
|
-
* - Joins `text` parts with `"\n"` when `content` is a multipart
|
|
17
|
-
* `ContentPart[]`. Non-text parts (images, audio, pdf) are skipped —
|
|
18
|
-
* callers concerned with multimodal content inspect `request`
|
|
19
|
-
* / attachments separately.
|
|
20
|
-
* - Returns `""` when there is no user message at all (e.g. a trip
|
|
21
|
-
* composed entirely of tool results).
|
|
22
|
-
*
|
|
23
|
-
* **Coverage limit (D3).** Because only `text` parts are extracted, any
|
|
24
|
-
* guardrail / PII detector built on this helper inspects **text only** —
|
|
25
|
-
* image / PDF / audio attachment content is NOT scanned. A guardrail is
|
|
26
|
-
* therefore not a multimodal safety control: for non-text inputs add an
|
|
27
|
-
* attachment-level policy (e.g. an OCR / moderation pass before the call)
|
|
28
|
-
* rather than relying on input detectors.
|
|
29
|
-
*
|
|
30
|
-
* @example
|
|
31
|
-
* const prompt = extractUserText(context.messages);
|
|
32
|
-
* if (!prompt) return;
|
|
33
|
-
* const verdict = await inputCheck(prompt);
|
|
34
|
-
*/
|
|
35
|
-
function extractUserText(messages) {
|
|
36
|
-
for (let index = messages.length - 1; index >= 0; index--) {
|
|
37
|
-
const message = messages[index];
|
|
38
|
-
if (message.role !== "user") continue;
|
|
39
|
-
if (typeof message.content === "string") return message.content;
|
|
40
|
-
if (Array.isArray(message.content)) return message.content.filter((part) => part.type === "text").map((part) => part.text).join("\n");
|
|
41
|
-
}
|
|
42
|
-
return "";
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
//#endregion
|
|
46
|
-
export { extractUserText };
|
|
47
|
-
//# sourceMappingURL=extract-user-text.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"extract-user-text.mjs","names":[],"sources":["../../../../../../../../../../@warlock.js/ai/src/middleware/utils/extract-user-text.ts"],"sourcesContent":["import type { Message } from \"../../contracts/conversation-message.type\";\n\n/**\n * Pull the text a content-inspection middleware should care about\n * from the outbound message list.\n *\n * **Role.** Built-ins that inspect \"what the user just said\" — the\n * guardrail on `trip.before`, the semantic cache on `trip.before`,\n * future consumers like PII redactors — all need the same string:\n * the most recent `user`-role message's text content. This helper\n * is the single authority on how that string is resolved.\n *\n * **Behavior.**\n * - Walks `messages` from the end backwards so the LAST user turn\n * wins (correct when the agent has history + a fresh prompt).\n * - Returns a plain string directly when `content` is a string.\n * - Joins `text` parts with `\"\\n\"` when `content` is a multipart\n * `ContentPart[]`. Non-text parts (images, audio, pdf) are skipped —\n * callers concerned with multimodal content inspect `request`\n * / attachments separately.\n * - Returns `\"\"` when there is no user message at all (e.g. a trip\n * composed entirely of tool results).\n *\n * **Coverage limit (D3).** Because only `text` parts are extracted, any\n * guardrail / PII detector built on this helper inspects **text only** —\n * image / PDF / audio attachment content is NOT scanned. A guardrail is\n * therefore not a multimodal safety control: for non-text inputs add an\n * attachment-level policy (e.g. an OCR / moderation pass before the call)\n * rather than relying on input detectors.\n *\n * @example\n * const prompt = extractUserText(context.messages);\n * if (!prompt) return;\n * const verdict = await inputCheck(prompt);\n */\nexport function extractUserText(messages: ReadonlyArray<Message>): string {\n for (let index = messages.length - 1; index >= 0; index--) {\n const message = messages[index];\n\n if (message.role !== \"user\") {\n continue;\n }\n\n if (typeof message.content === \"string\") {\n return message.content;\n }\n\n if (Array.isArray(message.content)) {\n return message.content\n .filter((part) => part.type === \"text\")\n .map((part) => (part as { text: string }).text)\n .join(\"\\n\");\n }\n }\n\n return \"\";\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmCA,SAAgB,gBAAgB,UAA0C;CACxE,KAAK,IAAI,QAAQ,SAAS,SAAS,GAAG,SAAS,GAAG,SAAS;EACzD,MAAM,UAAU,SAAS;EAEzB,IAAI,QAAQ,SAAS,QACnB;EAGF,IAAI,OAAO,QAAQ,YAAY,UAC7B,OAAO,QAAQ;EAGjB,IAAI,MAAM,QAAQ,QAAQ,OAAO,GAC/B,OAAO,QAAQ,QACZ,QAAQ,SAAS,KAAK,SAAS,MAAM,CAAC,CACtC,KAAK,SAAU,KAA0B,IAAI,CAAC,CAC9C,KAAK,IAAI;CAEhB;CAEA,OAAO;AACT"}
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
//#region ../@warlock.js/ai/src/middleware/utils/namespaced-state.ts
|
|
2
|
-
/**
|
|
3
|
-
* Typed accessor over `ctx.state` for a single namespace key. Wraps
|
|
4
|
-
* the raw `Map<string, unknown>` so middleware authors stop typing
|
|
5
|
-
* `as Counters | undefined` on every read.
|
|
6
|
-
*
|
|
7
|
-
* **Role.** Every built-in middleware reads and writes one or two
|
|
8
|
-
* entries in `ctx.state` under its own name. Without a helper,
|
|
9
|
-
* every call-site looks like:
|
|
10
|
-
*
|
|
11
|
-
* ```ts
|
|
12
|
-
* const counters = context.state.get("budget.counters") as Counters | undefined;
|
|
13
|
-
* if (!counters) { ... }
|
|
14
|
-
* counters.tokens += n;
|
|
15
|
-
* ```
|
|
16
|
-
*
|
|
17
|
-
* — cast noise, no type narrowing on `set`, no protection against
|
|
18
|
-
* key typos. `namespacedState<T>` eliminates all three.
|
|
19
|
-
*
|
|
20
|
-
* **Scope.** Deliberately narrow: one key, typed value, four methods
|
|
21
|
-
* (`get` / `set` / `delete` / `has`). Does NOT try to model compound
|
|
22
|
-
* or nested keys — if you need those, use the raw `ctx.state` Map
|
|
23
|
-
* directly, or create a second namespaced accessor for the second key.
|
|
24
|
-
*
|
|
25
|
-
* **Namespace convention.** Use the middleware's `name` as the key
|
|
26
|
-
* (or a `name.<field>` prefix when a middleware needs multiple
|
|
27
|
-
* entries). The pipeline does not enforce this — it is a convention
|
|
28
|
-
* the built-ins follow to avoid collisions between middlewares.
|
|
29
|
-
*
|
|
30
|
-
* @example
|
|
31
|
-
* // Inside a budget middleware:
|
|
32
|
-
* const counters = namespacedState<Counters>(ctx, "budget");
|
|
33
|
-
*
|
|
34
|
-
* if (!counters.has()) {
|
|
35
|
-
* counters.set({ tokens: 0, costUSD: 0 });
|
|
36
|
-
* }
|
|
37
|
-
*
|
|
38
|
-
* const current = counters.get()!;
|
|
39
|
-
* current.tokens += response.usage.total;
|
|
40
|
-
*/
|
|
41
|
-
function namespacedState(ctx, namespace) {
|
|
42
|
-
return {
|
|
43
|
-
get() {
|
|
44
|
-
return ctx.state.get(namespace);
|
|
45
|
-
},
|
|
46
|
-
set(value) {
|
|
47
|
-
ctx.state.set(namespace, value);
|
|
48
|
-
},
|
|
49
|
-
delete() {
|
|
50
|
-
ctx.state.delete(namespace);
|
|
51
|
-
},
|
|
52
|
-
has() {
|
|
53
|
-
return ctx.state.has(namespace);
|
|
54
|
-
}
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
//#endregion
|
|
59
|
-
export { namespacedState };
|
|
60
|
-
//# sourceMappingURL=namespaced-state.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"namespaced-state.mjs","names":[],"sources":["../../../../../../../../../../@warlock.js/ai/src/middleware/utils/namespaced-state.ts"],"sourcesContent":["import type { MiddlewareState } from \"../../contracts/middleware\";\n\n/**\n * Typed accessor over `ctx.state` for a single namespace key. Wraps\n * the raw `Map<string, unknown>` so middleware authors stop typing\n * `as Counters | undefined` on every read.\n *\n * **Role.** Every built-in middleware reads and writes one or two\n * entries in `ctx.state` under its own name. Without a helper,\n * every call-site looks like:\n *\n * ```ts\n * const counters = context.state.get(\"budget.counters\") as Counters | undefined;\n * if (!counters) { ... }\n * counters.tokens += n;\n * ```\n *\n * — cast noise, no type narrowing on `set`, no protection against\n * key typos. `namespacedState<T>` eliminates all three.\n *\n * **Scope.** Deliberately narrow: one key, typed value, four methods\n * (`get` / `set` / `delete` / `has`). Does NOT try to model compound\n * or nested keys — if you need those, use the raw `ctx.state` Map\n * directly, or create a second namespaced accessor for the second key.\n *\n * **Namespace convention.** Use the middleware's `name` as the key\n * (or a `name.<field>` prefix when a middleware needs multiple\n * entries). The pipeline does not enforce this — it is a convention\n * the built-ins follow to avoid collisions between middlewares.\n *\n * @example\n * // Inside a budget middleware:\n * const counters = namespacedState<Counters>(ctx, \"budget\");\n *\n * if (!counters.has()) {\n * counters.set({ tokens: 0, costUSD: 0 });\n * }\n *\n * const current = counters.get()!;\n * current.tokens += response.usage.total;\n */\nexport function namespacedState<T>(\n ctx: { readonly state: MiddlewareState },\n namespace: string,\n): NamespacedStateAccessor<T> {\n return {\n get(): T | undefined {\n return ctx.state.get(namespace) as T | undefined;\n },\n set(value: T): void {\n ctx.state.set(namespace, value);\n },\n delete(): void {\n ctx.state.delete(namespace);\n },\n has(): boolean {\n return ctx.state.has(namespace);\n },\n };\n}\n\n/**\n * Four-method accessor returned by `namespacedState`. Callers hold\n * it for the lifetime of a hook body — it is a thin typed view over\n * `ctx.state`, not a detached snapshot. Reads are live; writes hit\n * the underlying Map immediately and are visible to every other\n * hook that uses the same namespace.\n */\nexport type NamespacedStateAccessor<T> = {\n get(): T | undefined;\n set(value: T): void;\n delete(): void;\n has(): boolean;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyCA,SAAgB,gBACd,KACA,WAC4B;CAC5B,OAAO;EACL,MAAqB;GACnB,OAAO,IAAI,MAAM,IAAI,SAAS;EAChC;EACA,IAAI,OAAgB;GAClB,IAAI,MAAM,IAAI,WAAW,KAAK;EAChC;EACA,SAAe;GACb,IAAI,MAAM,OAAO,SAAS;EAC5B;EACA,MAAe;GACb,OAAO,IAAI,MAAM,IAAI,SAAS;EAChC;CACF;AACF"}
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import { END } from "../contracts/end.type.mjs";
|
|
2
|
-
|
|
3
|
-
//#region ../@warlock.js/ai/src/mock/mock-router.ts
|
|
4
|
-
/**
|
|
5
|
-
* Build a deterministic `route` callback that replays a canned
|
|
6
|
-
* sequence of routing decisions — one per supervisor iteration — for
|
|
7
|
-
* testing supervisors without an LLM router.
|
|
8
|
-
*
|
|
9
|
-
* Drop the returned callback into `ai.supervisor({ route: mockRouter([...]) })`
|
|
10
|
-
* in place of an LLM `router`. The Nth iteration consumes the Nth
|
|
11
|
-
* decision; a function decision is evaluated against the live
|
|
12
|
-
* `RouteContext`. When the queue runs out, behavior follows
|
|
13
|
-
* `options.onExhausted` (default: terminate with `END`).
|
|
14
|
-
*
|
|
15
|
-
* Pairs with the `toRouteTo` / `toConverge` matchers to assert the
|
|
16
|
-
* resulting report tree.
|
|
17
|
-
*
|
|
18
|
-
* @example
|
|
19
|
-
* const supervisor = ai.supervisor({
|
|
20
|
-
* name: "draft-then-review",
|
|
21
|
-
* intents: { writer, critic },
|
|
22
|
-
* route: mockRouter(["writer", "critic", END]),
|
|
23
|
-
* });
|
|
24
|
-
*
|
|
25
|
-
* @example
|
|
26
|
-
* // Branch on accumulated state, repeat the last decision until done.
|
|
27
|
-
* route: mockRouter(
|
|
28
|
-
* ["research", (ctx) => (ctx.state.summary ? END : "research")],
|
|
29
|
-
* { onExhausted: "repeat" },
|
|
30
|
-
* );
|
|
31
|
-
*/
|
|
32
|
-
function mockRouter(decisions, options = {}) {
|
|
33
|
-
const onExhausted = options.onExhausted ?? "end";
|
|
34
|
-
let cursor = 0;
|
|
35
|
-
return (context) => {
|
|
36
|
-
if (cursor < decisions.length) {
|
|
37
|
-
const decision = decisions[cursor];
|
|
38
|
-
cursor++;
|
|
39
|
-
return resolveDecision(decision, context);
|
|
40
|
-
}
|
|
41
|
-
if (onExhausted === "throw") throw new Error(`mockRouter exhausted after ${decisions.length} decision(s) at iteration ${context.iteration}`);
|
|
42
|
-
if (onExhausted === "repeat" && decisions.length > 0) return resolveDecision(decisions[decisions.length - 1], context);
|
|
43
|
-
return END;
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* Resolve a single decision entry into a concrete {@link Next} —
|
|
48
|
-
* invoking the predicate form against the live context, or returning
|
|
49
|
-
* the literal form verbatim.
|
|
50
|
-
*/
|
|
51
|
-
function resolveDecision(decision, context) {
|
|
52
|
-
if (typeof decision === "function") return decision(context);
|
|
53
|
-
return decision;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
//#endregion
|
|
57
|
-
export { mockRouter };
|
|
58
|
-
//# sourceMappingURL=mock-router.mjs.map
|