@warlock.js/ai 4.4.0 → 4.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +63 -52
- package/cjs/index.cjs +240 -14147
- package/cjs/src-Bmajk4Qg.cjs +30 -0
- package/cjs/src-OZyDYHxm.cjs +25089 -0
- package/cjs/src-OZyDYHxm.cjs.map +1 -0
- package/esm/agent/agent-config.type.d.mts +119 -1
- package/esm/agent/agent-config.type.d.mts.map +1 -1
- package/esm/agent/agent-input-builder.mjs +27 -6
- package/esm/agent/agent-input-builder.mjs.map +1 -1
- package/esm/agent/agent.d.mts +40 -1
- package/esm/agent/agent.d.mts.map +1 -1
- package/esm/agent/agent.mjs +328 -36
- package/esm/agent/agent.mjs.map +1 -1
- package/esm/agent/index.d.mts +2 -1
- package/esm/agent/index.mjs +1 -0
- package/esm/agent/judge-config.type.d.mts +33 -0
- package/esm/agent/judge-config.type.d.mts.map +1 -0
- package/esm/agent/judge-config.type.mjs +13 -0
- package/esm/agent/judge-config.type.mjs.map +1 -0
- package/esm/agent/signature.mjs +57 -0
- package/esm/agent/signature.mjs.map +1 -0
- package/esm/agent/snapshot.mjs +101 -0
- package/esm/agent/snapshot.mjs.map +1 -0
- package/esm/ai-openai/src/embedder.mjs +4 -0
- package/esm/ai-openai/src/image.mjs +5 -0
- package/esm/ai-openai/src/index.mjs +7 -0
- package/esm/ai-openai/src/model.mjs +5 -0
- package/esm/ai-openai/src/sdk.mjs +9 -0
- package/esm/ai-openai/src/speech.mjs +5 -0
- package/esm/ai-openai/src/transcription.mjs +6 -0
- package/esm/ai-openai/src/utils/index.mjs +5 -0
- package/esm/ai-openai/src/utils/to-openai-messages.mjs +3 -0
- package/esm/ai-openai/src/utils/to-openai-tools.mjs +3 -0
- package/esm/ai-openai/src/utils/wrap-openai-error.mjs +4 -0
- package/esm/ai.d.mts +164 -53
- package/esm/ai.d.mts.map +1 -1
- package/esm/ai.mjs +79 -8
- package/esm/ai.mjs.map +1 -1
- package/esm/batch/batch.d.mts.map +1 -1
- package/esm/batch/batch.mjs +21 -1
- package/esm/batch/batch.mjs.map +1 -1
- package/esm/batch/batch.type.d.mts +11 -4
- package/esm/batch/batch.type.d.mts.map +1 -1
- package/esm/config.d.mts +39 -3
- package/esm/config.d.mts.map +1 -1
- package/esm/config.mjs +26 -2
- package/esm/config.mjs.map +1 -1
- package/esm/contracts/agent/agent-options.type.d.mts +33 -5
- package/esm/contracts/agent/agent-options.type.d.mts.map +1 -1
- package/esm/contracts/agent/agent-snapshot.type.d.mts +90 -0
- package/esm/contracts/agent/agent-snapshot.type.d.mts.map +1 -0
- package/esm/contracts/agent/agent.contract.d.mts +29 -1
- package/esm/contracts/agent/agent.contract.d.mts.map +1 -1
- package/esm/contracts/agent/eval.type.d.mts +43 -2
- package/esm/contracts/agent/eval.type.d.mts.map +1 -1
- package/esm/contracts/agent/index.d.mts +2 -1
- package/esm/contracts/attachment-policy.type.d.mts +51 -0
- package/esm/contracts/attachment-policy.type.d.mts.map +1 -0
- package/esm/contracts/attachment.type.d.mts +16 -7
- package/esm/contracts/attachment.type.d.mts.map +1 -1
- package/esm/contracts/content-part.type.d.mts +14 -5
- package/esm/contracts/content-part.type.d.mts.map +1 -1
- package/esm/contracts/events/supervisor-events.type.d.mts.map +1 -1
- package/esm/contracts/image-model.contract.d.mts +156 -0
- package/esm/contracts/image-model.contract.d.mts.map +1 -0
- package/esm/contracts/index.d.mts +13 -6
- package/esm/contracts/model.contract.d.mts +11 -8
- package/esm/contracts/model.contract.d.mts.map +1 -1
- package/esm/contracts/orchestrator/index.d.mts +1 -0
- package/esm/contracts/orchestrator/orchestrator-config.type.d.mts +31 -2
- package/esm/contracts/orchestrator/orchestrator-config.type.d.mts.map +1 -1
- package/esm/contracts/orchestrator/session-lock.contract.d.mts +47 -0
- package/esm/contracts/orchestrator/session-lock.contract.d.mts.map +1 -0
- package/esm/contracts/planner/index.d.mts +3 -2
- package/esm/contracts/planner/planner-config.type.d.mts +61 -0
- package/esm/contracts/planner/planner-config.type.d.mts.map +1 -1
- package/esm/contracts/planner/planner-execute-options.type.d.mts +60 -1
- package/esm/contracts/planner/planner-execute-options.type.d.mts.map +1 -1
- package/esm/contracts/planner/planner-result.type.d.mts +8 -0
- package/esm/contracts/planner/planner-result.type.d.mts.map +1 -1
- package/esm/contracts/planner/planner-snapshot.type.d.mts +77 -0
- package/esm/contracts/planner/planner-snapshot.type.d.mts.map +1 -0
- package/esm/contracts/planner/planner.contract.d.mts +21 -1
- package/esm/contracts/planner/planner.contract.d.mts.map +1 -1
- package/esm/contracts/result/agent-result.type.d.mts +6 -4
- package/esm/contracts/result/agent-result.type.d.mts.map +1 -1
- package/esm/contracts/result/base-report.type.d.mts +21 -3
- package/esm/contracts/result/base-report.type.d.mts.map +1 -1
- package/esm/contracts/result/base-report.type.mjs.map +1 -1
- package/esm/contracts/result/execution-report.type.d.mts +53 -1
- package/esm/contracts/result/execution-report.type.d.mts.map +1 -1
- package/esm/contracts/result/supervisor-result.type.d.mts +14 -2
- package/esm/contracts/result/supervisor-result.type.d.mts.map +1 -1
- package/esm/contracts/result/workflow-result.type.d.mts +2 -1
- package/esm/contracts/result/workflow-result.type.d.mts.map +1 -1
- package/esm/contracts/sdk-adapter.contract.d.mts +37 -0
- package/esm/contracts/sdk-adapter.contract.d.mts.map +1 -1
- package/esm/contracts/speech-model.contract.d.mts +97 -0
- package/esm/contracts/speech-model.contract.d.mts.map +1 -0
- package/esm/contracts/supervisor/supervisor-config.type.d.mts +29 -0
- package/esm/contracts/supervisor/supervisor-config.type.d.mts.map +1 -1
- package/esm/contracts/system-prompt.contract.d.mts +103 -1
- package/esm/contracts/system-prompt.contract.d.mts.map +1 -1
- package/esm/contracts/team/index.d.mts +1 -0
- package/esm/contracts/team/team-config.type.d.mts +127 -0
- package/esm/contracts/team/team-config.type.d.mts.map +1 -0
- package/esm/contracts/tool.contract.d.mts +4 -2
- package/esm/contracts/tool.contract.d.mts.map +1 -1
- package/esm/contracts/transcription-model.contract.d.mts +101 -0
- package/esm/contracts/transcription-model.contract.d.mts.map +1 -0
- package/esm/contracts/workflow/step.contract.d.mts +30 -5
- package/esm/contracts/workflow/step.contract.d.mts.map +1 -1
- package/esm/contracts/workflow/workflow.contract.d.mts +16 -0
- package/esm/contracts/workflow/workflow.contract.d.mts.map +1 -1
- package/esm/errors/agent-drift-error.d.mts +32 -0
- package/esm/errors/agent-drift-error.d.mts.map +1 -0
- package/esm/errors/agent-drift-error.mjs +31 -0
- package/esm/errors/agent-drift-error.mjs.map +1 -0
- package/esm/errors/error-code.type.d.mts +1 -1
- package/esm/errors/index.d.mts +3 -0
- package/esm/errors/index.mjs +3 -0
- package/esm/errors/outbound-policy-error.d.mts +27 -0
- package/esm/errors/outbound-policy-error.d.mts.map +1 -0
- package/esm/errors/outbound-policy-error.mjs +32 -0
- package/esm/errors/outbound-policy-error.mjs.map +1 -0
- package/esm/errors/planner-drift-error.d.mts +34 -0
- package/esm/errors/planner-drift-error.d.mts.map +1 -0
- package/esm/errors/planner-drift-error.mjs +33 -0
- package/esm/errors/planner-drift-error.mjs.map +1 -0
- package/esm/eval/dataset.d.mts +28 -0
- package/esm/eval/dataset.d.mts.map +1 -0
- package/esm/eval/dataset.mjs +112 -0
- package/esm/eval/dataset.mjs.map +1 -0
- package/esm/eval/dataset.type.d.mts +53 -0
- package/esm/eval/dataset.type.d.mts.map +1 -0
- package/esm/eval/eval-runner.d.mts.map +1 -1
- package/esm/eval/eval-runner.mjs +16 -2
- package/esm/eval/eval-runner.mjs.map +1 -1
- package/esm/eval/index.d.mts +20 -1
- package/esm/eval/index.d.mts.map +1 -1
- package/esm/eval/index.mjs +20 -2
- package/esm/eval/index.mjs.map +1 -1
- package/esm/eval/regression.d.mts +30 -0
- package/esm/eval/regression.d.mts.map +1 -0
- package/esm/eval/regression.mjs +51 -0
- package/esm/eval/regression.mjs.map +1 -0
- package/esm/eval/report-json.d.mts +30 -0
- package/esm/eval/report-json.d.mts.map +1 -0
- package/esm/eval/report-json.mjs +33 -0
- package/esm/eval/report-json.mjs.map +1 -0
- package/esm/eval/report-junit.d.mts +22 -0
- package/esm/eval/report-junit.d.mts.map +1 -0
- package/esm/eval/report-junit.mjs +60 -0
- package/esm/eval/report-junit.mjs.map +1 -0
- package/esm/guard/contracts/guard-options.type.d.mts +165 -0
- package/esm/guard/contracts/guard-options.type.d.mts.map +1 -0
- package/esm/guard/contracts/guardrail.contract.d.mts +78 -0
- package/esm/guard/contracts/guardrail.contract.d.mts.map +1 -0
- package/esm/guard/contracts/index.d.mts +4 -0
- package/esm/guard/contracts/openai-client.contract.d.mts +51 -0
- package/esm/guard/contracts/openai-client.contract.d.mts.map +1 -0
- package/esm/guard/contracts/verdict.type.d.mts +76 -0
- package/esm/guard/contracts/verdict.type.d.mts.map +1 -0
- package/esm/guard/detectors/index.d.mts +4 -0
- package/esm/guard/detectors/index.mjs +6 -0
- package/esm/guard/detectors/injection.d.mts +34 -0
- package/esm/guard/detectors/injection.d.mts.map +1 -0
- package/esm/guard/detectors/injection.mjs +254 -0
- package/esm/guard/detectors/injection.mjs.map +1 -0
- package/esm/guard/detectors/moderation.d.mts +32 -0
- package/esm/guard/detectors/moderation.d.mts.map +1 -0
- package/esm/guard/detectors/moderation.mjs +134 -0
- package/esm/guard/detectors/moderation.mjs.map +1 -0
- package/esm/guard/detectors/pii.d.mts +41 -0
- package/esm/guard/detectors/pii.d.mts.map +1 -0
- package/esm/guard/detectors/pii.mjs +199 -0
- package/esm/guard/detectors/pii.mjs.map +1 -0
- package/esm/guard/detectors/topic.d.mts +29 -0
- package/esm/guard/detectors/topic.d.mts.map +1 -0
- package/esm/guard/detectors/topic.mjs +99 -0
- package/esm/guard/detectors/topic.mjs.map +1 -0
- package/esm/guard/errors.d.mts +12 -0
- package/esm/guard/errors.d.mts.map +1 -0
- package/esm/guard/errors.mjs +18 -0
- package/esm/guard/errors.mjs.map +1 -0
- package/esm/guard/guard.d.mts +67 -0
- package/esm/guard/guard.d.mts.map +1 -0
- package/esm/guard/guard.mjs +209 -0
- package/esm/guard/guard.mjs.map +1 -0
- package/esm/guard/guardrail.d.mts +39 -0
- package/esm/guard/guardrail.d.mts.map +1 -0
- package/esm/guard/guardrail.mjs +22 -0
- package/esm/guard/guardrail.mjs.map +1 -0
- package/esm/human/contracts/approval.type.d.mts +154 -0
- package/esm/human/contracts/approval.type.d.mts.map +1 -0
- package/esm/human/contracts/human-approval.type.d.mts +38 -0
- package/esm/human/contracts/human-approval.type.d.mts.map +1 -0
- package/esm/human/contracts/index.d.mts +4 -0
- package/esm/human/contracts/interrupt-store.contract.d.mts +112 -0
- package/esm/human/contracts/interrupt-store.contract.d.mts.map +1 -0
- package/esm/human/contracts/resume.type.d.mts +77 -0
- package/esm/human/contracts/resume.type.d.mts.map +1 -0
- package/esm/human/errors.d.mts +84 -0
- package/esm/human/errors.d.mts.map +1 -0
- package/esm/human/errors.mjs +60 -0
- package/esm/human/errors.mjs.map +1 -0
- package/esm/human/human-approval.d.mts +57 -0
- package/esm/human/human-approval.d.mts.map +1 -0
- package/esm/human/human-approval.mjs +170 -0
- package/esm/human/human-approval.mjs.map +1 -0
- package/esm/human/policy.d.mts +55 -0
- package/esm/human/policy.d.mts.map +1 -0
- package/esm/human/policy.mjs +67 -0
- package/esm/human/policy.mjs.map +1 -0
- package/esm/human/register.mjs +37 -0
- package/esm/human/register.mjs.map +1 -0
- package/esm/human/resume-seed.mjs +53 -0
- package/esm/human/resume-seed.mjs.map +1 -0
- package/esm/human/resume.d.mts +54 -0
- package/esm/human/resume.d.mts.map +1 -0
- package/esm/human/resume.mjs +121 -0
- package/esm/human/resume.mjs.map +1 -0
- package/esm/human/stores/index.mjs +5 -0
- package/esm/human/stores/memory.d.mts +30 -0
- package/esm/human/stores/memory.d.mts.map +1 -0
- package/esm/human/stores/memory.mjs +91 -0
- package/esm/human/stores/memory.mjs.map +1 -0
- package/esm/human/stores/pg.d.mts +59 -0
- package/esm/human/stores/pg.d.mts.map +1 -0
- package/esm/human/stores/pg.mjs +220 -0
- package/esm/human/stores/pg.mjs.map +1 -0
- package/esm/human/stores/redis.d.mts +56 -0
- package/esm/human/stores/redis.d.mts.map +1 -0
- package/esm/human/stores/redis.mjs +201 -0
- package/esm/human/stores/redis.mjs.map +1 -0
- package/esm/image/image-cost.d.mts +32 -0
- package/esm/image/image-cost.d.mts.map +1 -0
- package/esm/image/image-cost.mjs +55 -0
- package/esm/image/image-cost.mjs.map +1 -0
- package/esm/image/image.d.mts +92 -0
- package/esm/image/image.d.mts.map +1 -0
- package/esm/image/image.mjs +113 -0
- package/esm/image/image.mjs.map +1 -0
- package/esm/image/index.mjs +4 -0
- package/esm/index.d.mts +137 -24
- package/esm/index.mjs +101 -11
- package/esm/middleware/builtins/budget.mjs +6 -2
- package/esm/middleware/builtins/budget.mjs.map +1 -1
- package/esm/middleware/utils/extract-user-text.d.mts +8 -1
- package/esm/middleware/utils/extract-user-text.d.mts.map +1 -1
- package/esm/middleware/utils/extract-user-text.mjs +8 -1
- package/esm/middleware/utils/extract-user-text.mjs.map +1 -1
- package/esm/mock/index.d.mts +3 -0
- package/esm/mock/index.mjs +3 -0
- package/esm/mock/mock-config.type.d.mts +22 -0
- package/esm/mock/mock-config.type.d.mts.map +1 -1
- package/esm/mock/mock-image-model.d.mts +41 -0
- package/esm/mock/mock-image-model.d.mts.map +1 -0
- package/esm/mock/mock-image-model.mjs +52 -0
- package/esm/mock/mock-image-model.mjs.map +1 -0
- package/esm/mock/mock-sdk.d.mts +7 -1
- package/esm/mock/mock-sdk.d.mts.map +1 -1
- package/esm/mock/mock-sdk.mjs +27 -0
- package/esm/mock/mock-sdk.mjs.map +1 -1
- package/esm/mock/mock-speech-model.d.mts +31 -0
- package/esm/mock/mock-speech-model.d.mts.map +1 -0
- package/esm/mock/mock-speech-model.mjs +39 -0
- package/esm/mock/mock-speech-model.mjs.map +1 -0
- package/esm/mock/mock-transcription-model.d.mts +32 -0
- package/esm/mock/mock-transcription-model.d.mts.map +1 -0
- package/esm/mock/mock-transcription-model.mjs +36 -0
- package/esm/mock/mock-transcription-model.mjs.map +1 -0
- package/esm/object-stream/index.d.mts +2 -0
- package/esm/object-stream/index.mjs +4 -0
- package/esm/object-stream/parse-partial-json.d.mts +22 -0
- package/esm/object-stream/parse-partial-json.d.mts.map +1 -0
- package/esm/object-stream/parse-partial-json.mjs +78 -0
- package/esm/object-stream/parse-partial-json.mjs.map +1 -0
- package/esm/object-stream/stream-object.d.mts +68 -0
- package/esm/object-stream/stream-object.d.mts.map +1 -0
- package/esm/object-stream/stream-object.mjs +104 -0
- package/esm/object-stream/stream-object.mjs.map +1 -0
- package/esm/observe/index.mjs +4 -0
- package/esm/observe/observer-registry.d.mts +30 -0
- package/esm/observe/observer-registry.d.mts.map +1 -0
- package/esm/observe/observer-registry.mjs +51 -0
- package/esm/observe/observer-registry.mjs.map +1 -0
- package/esm/observe/observer.contract.d.mts +40 -0
- package/esm/observe/observer.contract.d.mts.map +1 -0
- package/esm/observe/resolve-observers.d.mts +40 -0
- package/esm/observe/resolve-observers.d.mts.map +1 -0
- package/esm/observe/resolve-observers.mjs +73 -0
- package/esm/observe/resolve-observers.mjs.map +1 -0
- package/esm/orchestrator/execution.d.mts.map +1 -1
- package/esm/orchestrator/execution.mjs +5 -2
- package/esm/orchestrator/execution.mjs.map +1 -1
- package/esm/orchestrator/index.d.mts +1 -0
- package/esm/orchestrator/index.mjs +1 -0
- package/esm/orchestrator/orchestrator.d.mts.map +1 -1
- package/esm/orchestrator/orchestrator.mjs +39 -6
- package/esm/orchestrator/orchestrator.mjs.map +1 -1
- package/esm/orchestrator/session-lock.d.mts +25 -0
- package/esm/orchestrator/session-lock.d.mts.map +1 -0
- package/esm/orchestrator/session-lock.mjs +83 -0
- package/esm/orchestrator/session-lock.mjs.map +1 -0
- package/esm/planner/dag-scheduler.mjs +97 -0
- package/esm/planner/dag-scheduler.mjs.map +1 -0
- package/esm/planner/plan-prompt.d.mts +1 -1
- package/esm/planner/plan-prompt.d.mts.map +1 -1
- package/esm/planner/plan-prompt.mjs +2 -1
- package/esm/planner/plan-prompt.mjs.map +1 -1
- package/esm/planner/planner-run.d.mts +8 -0
- package/esm/planner/planner-run.d.mts.map +1 -1
- package/esm/planner/planner-run.mjs +457 -31
- package/esm/planner/planner-run.mjs.map +1 -1
- package/esm/planner/planner.d.mts.map +1 -1
- package/esm/planner/planner.mjs +26 -2
- package/esm/planner/planner.mjs.map +1 -1
- package/esm/planner/snapshot.mjs +95 -0
- package/esm/planner/snapshot.mjs.map +1 -0
- package/esm/prompt/errors.d.mts +57 -0
- package/esm/prompt/errors.d.mts.map +1 -0
- package/esm/prompt/errors.mjs +73 -0
- package/esm/prompt/errors.mjs.map +1 -0
- package/esm/prompt/index.d.mts +3 -0
- package/esm/prompt/index.mjs +4 -0
- package/esm/prompt/prompt-langfuse-sync.mjs +104 -0
- package/esm/prompt/prompt-langfuse-sync.mjs.map +1 -0
- package/esm/prompt/prompt-langfuse-sync.type.d.mts +32 -0
- package/esm/prompt/prompt-langfuse-sync.type.d.mts.map +1 -0
- package/esm/prompt/prompt-validate.mjs +170 -0
- package/esm/prompt/prompt-validate.mjs.map +1 -0
- package/esm/prompt/prompt.d.mts +54 -0
- package/esm/prompt/prompt.d.mts.map +1 -0
- package/esm/prompt/prompt.mjs +218 -0
- package/esm/prompt/prompt.mjs.map +1 -0
- package/esm/prompt/prompt.type.d.mts +174 -0
- package/esm/prompt/prompt.type.d.mts.map +1 -0
- package/esm/prompts/index.d.mts +3 -0
- package/esm/prompts/index.mjs +3 -0
- package/esm/prompts/prompts-manager.contract.d.mts +154 -0
- package/esm/prompts/prompts-manager.contract.d.mts.map +1 -0
- package/esm/prompts/prompts-manager.d.mts +38 -0
- package/esm/prompts/prompts-manager.d.mts.map +1 -0
- package/esm/prompts/prompts-manager.mjs +410 -0
- package/esm/prompts/prompts-manager.mjs.map +1 -0
- package/esm/prompts/prompts-manager.type.d.mts +172 -0
- package/esm/prompts/prompts-manager.type.d.mts.map +1 -0
- package/esm/prompts/prompts-validate.mjs +200 -0
- package/esm/prompts/prompts-validate.mjs.map +1 -0
- package/esm/rag/as-tool.mjs +48 -0
- package/esm/rag/as-tool.mjs.map +1 -0
- package/esm/rag/chunk/chunk.d.mts +24 -0
- package/esm/rag/chunk/chunk.d.mts.map +1 -0
- package/esm/rag/chunk/chunk.mjs +44 -0
- package/esm/rag/chunk/chunk.mjs.map +1 -0
- package/esm/rag/chunk/fixed.mjs +32 -0
- package/esm/rag/chunk/fixed.mjs.map +1 -0
- package/esm/rag/chunk/markdown.mjs +75 -0
- package/esm/rag/chunk/markdown.mjs.map +1 -0
- package/esm/rag/chunk/recursive.mjs +132 -0
- package/esm/rag/chunk/recursive.mjs.map +1 -0
- package/esm/rag/chunk/sentence.mjs +73 -0
- package/esm/rag/chunk/sentence.mjs.map +1 -0
- package/esm/rag/contracts/chunk-options.type.d.mts +35 -0
- package/esm/rag/contracts/chunk-options.type.d.mts.map +1 -0
- package/esm/rag/contracts/citation.type.d.mts +35 -0
- package/esm/rag/contracts/citation.type.d.mts.map +1 -0
- package/esm/rag/contracts/index.d.mts +4 -0
- package/esm/rag/contracts/rag-config.type.d.mts +68 -0
- package/esm/rag/contracts/rag-config.type.d.mts.map +1 -0
- package/esm/rag/contracts/rag-document.type.d.mts +21 -0
- package/esm/rag/contracts/rag-document.type.d.mts.map +1 -0
- package/esm/rag/hybrid/bm25.d.mts +23 -0
- package/esm/rag/hybrid/bm25.d.mts.map +1 -0
- package/esm/rag/hybrid/bm25.mjs +51 -0
- package/esm/rag/hybrid/bm25.mjs.map +1 -0
- package/esm/rag/hybrid/hybrid-rank.d.mts +33 -0
- package/esm/rag/hybrid/hybrid-rank.d.mts.map +1 -0
- package/esm/rag/hybrid/hybrid-rank.mjs +29 -0
- package/esm/rag/hybrid/hybrid-rank.mjs.map +1 -0
- package/esm/rag/hybrid/rrf.d.mts +25 -0
- package/esm/rag/hybrid/rrf.d.mts.map +1 -0
- package/esm/rag/hybrid/rrf.mjs +30 -0
- package/esm/rag/hybrid/rrf.mjs.map +1 -0
- package/esm/rag/index.d.mts +22 -0
- package/esm/rag/index.mjs +18 -0
- package/esm/rag/loaders/errors.d.mts +19 -0
- package/esm/rag/loaders/errors.d.mts.map +1 -0
- package/esm/rag/loaders/errors.mjs +25 -0
- package/esm/rag/loaders/errors.mjs.map +1 -0
- package/esm/rag/loaders/index.mjs +7 -0
- package/esm/rag/loaders/load-html.d.mts +26 -0
- package/esm/rag/loaders/load-html.d.mts.map +1 -0
- package/esm/rag/loaders/load-html.mjs +138 -0
- package/esm/rag/loaders/load-html.mjs.map +1 -0
- package/esm/rag/loaders/load-pdf.d.mts +38 -0
- package/esm/rag/loaders/load-pdf.d.mts.map +1 -0
- package/esm/rag/loaders/load-pdf.mjs +150 -0
- package/esm/rag/loaders/load-pdf.mjs.map +1 -0
- package/esm/rag/loaders/load-text.d.mts +47 -0
- package/esm/rag/loaders/load-text.d.mts.map +1 -0
- package/esm/rag/loaders/load-text.mjs +60 -0
- package/esm/rag/loaders/load-text.mjs.map +1 -0
- package/esm/rag/loaders/load-web.d.mts +42 -0
- package/esm/rag/loaders/load-web.d.mts.map +1 -0
- package/esm/rag/loaders/load-web.mjs +89 -0
- package/esm/rag/loaders/load-web.mjs.map +1 -0
- package/esm/rag/loaders/loader.type.d.mts +89 -0
- package/esm/rag/loaders/loader.type.d.mts.map +1 -0
- package/esm/rag/rag.d.mts +38 -0
- package/esm/rag/rag.d.mts.map +1 -0
- package/esm/rag/rag.mjs +126 -0
- package/esm/rag/rag.mjs.map +1 -0
- package/esm/rag/rerank/keyword-reranker.d.mts +32 -0
- package/esm/rag/rerank/keyword-reranker.d.mts.map +1 -0
- package/esm/rag/rerank/keyword-reranker.mjs +58 -0
- package/esm/rag/rerank/keyword-reranker.mjs.map +1 -0
- package/esm/rag/rerank/llm-reranker.d.mts +36 -0
- package/esm/rag/rerank/llm-reranker.d.mts.map +1 -0
- package/esm/rag/rerank/llm-reranker.mjs +85 -0
- package/esm/rag/rerank/llm-reranker.mjs.map +1 -0
- package/esm/rag/rerank/reranker.contract.d.mts +28 -0
- package/esm/rag/rerank/reranker.contract.d.mts.map +1 -0
- package/esm/rag/retrieve.mjs +68 -0
- package/esm/rag/retrieve.mjs.map +1 -0
- package/esm/rag/store/cache-vector-store.d.mts +27 -0
- package/esm/rag/store/cache-vector-store.d.mts.map +1 -0
- package/esm/rag/store/cache-vector-store.mjs +48 -0
- package/esm/rag/store/cache-vector-store.mjs.map +1 -0
- package/esm/rag/store/pg-vector-store.d.mts +139 -0
- package/esm/rag/store/pg-vector-store.d.mts.map +1 -0
- package/esm/rag/store/pg-vector-store.mjs +328 -0
- package/esm/rag/store/pg-vector-store.mjs.map +1 -0
- package/esm/rag/store/vector-store.contract.d.mts +38 -0
- package/esm/rag/store/vector-store.contract.d.mts.map +1 -0
- package/esm/rag/transforms/multi-query.d.mts +27 -0
- package/esm/rag/transforms/multi-query.d.mts.map +1 -0
- package/esm/rag/transforms/multi-query.mjs +41 -0
- package/esm/rag/transforms/multi-query.mjs.map +1 -0
- package/esm/security/index.mjs +5 -0
- package/esm/security/outbound-policy.d.mts +46 -0
- package/esm/security/outbound-policy.d.mts.map +1 -0
- package/esm/security/outbound-policy.mjs +187 -0
- package/esm/security/outbound-policy.mjs.map +1 -0
- package/esm/security/outbound-policy.type.d.mts +74 -0
- package/esm/security/outbound-policy.type.d.mts.map +1 -0
- package/esm/security/private-ip.d.mts +15 -0
- package/esm/security/private-ip.d.mts.map +1 -0
- package/esm/security/private-ip.mjs +48 -0
- package/esm/security/private-ip.mjs.map +1 -0
- package/esm/security/redact.d.mts +59 -0
- package/esm/security/redact.d.mts.map +1 -0
- package/esm/security/redact.mjs +122 -0
- package/esm/security/redact.mjs.map +1 -0
- package/esm/serve/serve.d.mts +50 -0
- package/esm/serve/serve.d.mts.map +1 -0
- package/esm/serve/serve.mjs +90 -0
- package/esm/serve/serve.mjs.map +1 -0
- package/esm/serve/sse.d.mts +20 -0
- package/esm/serve/sse.d.mts.map +1 -0
- package/esm/serve/sse.mjs +25 -0
- package/esm/serve/sse.mjs.map +1 -0
- package/esm/serve/stream-to-sse.d.mts +29 -0
- package/esm/serve/stream-to-sse.d.mts.map +1 -0
- package/esm/serve/stream-to-sse.mjs +37 -0
- package/esm/serve/stream-to-sse.mjs.map +1 -0
- package/esm/skills/catalog.d.mts +49 -0
- package/esm/skills/catalog.d.mts.map +1 -0
- package/esm/skills/catalog.mjs +140 -0
- package/esm/skills/catalog.mjs.map +1 -0
- package/esm/skills/contracts/skill-record.type.d.mts +37 -0
- package/esm/skills/contracts/skill-record.type.d.mts.map +1 -0
- package/esm/skills/contracts/skills-config.type.d.mts +108 -0
- package/esm/skills/contracts/skills-config.type.d.mts.map +1 -0
- package/esm/skills/contracts/skills-store.contract.d.mts +28 -0
- package/esm/skills/contracts/skills-store.contract.d.mts.map +1 -0
- package/esm/skills/contracts/skills.contract.d.mts +43 -0
- package/esm/skills/contracts/skills.contract.d.mts.map +1 -0
- package/esm/skills/index.d.mts +16 -0
- package/esm/skills/index.mjs +14 -0
- package/esm/skills/load-skill-tool.d.mts +38 -0
- package/esm/skills/load-skill-tool.d.mts.map +1 -0
- package/esm/skills/load-skill-tool.mjs +65 -0
- package/esm/skills/load-skill-tool.mjs.map +1 -0
- package/esm/skills/review-gate.d.mts +33 -0
- package/esm/skills/review-gate.d.mts.map +1 -0
- package/esm/skills/review-gate.mjs +60 -0
- package/esm/skills/review-gate.mjs.map +1 -0
- package/esm/skills/save-skill-tool.d.mts +39 -0
- package/esm/skills/save-skill-tool.d.mts.map +1 -0
- package/esm/skills/save-skill-tool.mjs +65 -0
- package/esm/skills/save-skill-tool.mjs.map +1 -0
- package/esm/skills/skills.d.mts +33 -0
- package/esm/skills/skills.d.mts.map +1 -0
- package/esm/skills/skills.mjs +109 -0
- package/esm/skills/skills.mjs.map +1 -0
- package/esm/skills/sources/directory-source.d.mts +19 -0
- package/esm/skills/sources/directory-source.d.mts.map +1 -0
- package/esm/skills/sources/directory-source.mjs +108 -0
- package/esm/skills/sources/directory-source.mjs.map +1 -0
- package/esm/skills/sources/index.d.mts +18 -0
- package/esm/skills/sources/index.d.mts.map +1 -0
- package/esm/skills/sources/index.mjs +27 -0
- package/esm/skills/sources/index.mjs.map +1 -0
- package/esm/skills/sources/parse-frontmatter.d.mts +27 -0
- package/esm/skills/sources/parse-frontmatter.d.mts.map +1 -0
- package/esm/skills/sources/parse-frontmatter.mjs +46 -0
- package/esm/skills/sources/parse-frontmatter.mjs.map +1 -0
- package/esm/skills/sources/store-source.d.mts +14 -0
- package/esm/skills/sources/store-source.d.mts.map +1 -0
- package/esm/skills/sources/store-source.mjs +15 -0
- package/esm/skills/sources/store-source.mjs.map +1 -0
- package/esm/skills/sources/url-source.d.mts +29 -0
- package/esm/skills/sources/url-source.d.mts.map +1 -0
- package/esm/skills/sources/url-source.mjs +117 -0
- package/esm/skills/sources/url-source.mjs.map +1 -0
- package/esm/skills/store/mock-skills-store.d.mts +57 -0
- package/esm/skills/store/mock-skills-store.d.mts.map +1 -0
- package/esm/skills/store/mock-skills-store.mjs +100 -0
- package/esm/skills/store/mock-skills-store.mjs.map +1 -0
- package/esm/skills/store/procedural-skill-store.d.mts +30 -0
- package/esm/skills/store/procedural-skill-store.d.mts.map +1 -0
- package/esm/skills/store/procedural-skill-store.mjs +125 -0
- package/esm/skills/store/procedural-skill-store.mjs.map +1 -0
- package/esm/speech/index.mjs +3 -0
- package/esm/speech/speech.d.mts +65 -0
- package/esm/speech/speech.d.mts.map +1 -0
- package/esm/speech/speech.mjs +123 -0
- package/esm/speech/speech.mjs.map +1 -0
- package/esm/supervisor/as-tool.mjs +2 -2
- package/esm/supervisor/as-tool.mjs.map +1 -1
- package/esm/supervisor/entries.mjs +2 -2
- package/esm/supervisor/entries.mjs.map +1 -1
- package/esm/supervisor/execution.d.mts.map +1 -1
- package/esm/supervisor/execution.mjs +31 -28
- package/esm/supervisor/execution.mjs.map +1 -1
- package/esm/supervisor/supervisor.d.mts.map +1 -1
- package/esm/supervisor/supervisor.mjs +8 -3
- package/esm/supervisor/supervisor.mjs.map +1 -1
- package/esm/system-prompt/index.d.mts +4 -0
- package/esm/system-prompt/system-prompt.d.mts +68 -4
- package/esm/system-prompt/system-prompt.d.mts.map +1 -1
- package/esm/system-prompt/system-prompt.mjs +89 -5
- package/esm/system-prompt/system-prompt.mjs.map +1 -1
- package/esm/team/gates.mjs +48 -0
- package/esm/team/gates.mjs.map +1 -0
- package/esm/team/index.d.mts +1 -0
- package/esm/team/index.mjs +3 -0
- package/esm/team/team.d.mts +42 -0
- package/esm/team/team.d.mts.map +1 -0
- package/esm/team/team.mjs +94 -0
- package/esm/team/team.mjs.map +1 -0
- package/esm/tool/executable-as-tool.d.mts.map +1 -1
- package/esm/tool/executable-as-tool.mjs +2 -2
- package/esm/tool/executable-as-tool.mjs.map +1 -1
- package/esm/tool/tool.d.mts.map +1 -1
- package/esm/tool/tool.mjs +2 -2
- package/esm/tool/tool.mjs.map +1 -1
- package/esm/transcribe/audio-input.d.mts +47 -0
- package/esm/transcribe/audio-input.d.mts.map +1 -0
- package/esm/transcribe/audio-input.mjs +84 -0
- package/esm/transcribe/audio-input.mjs.map +1 -0
- package/esm/transcribe/index.mjs +4 -0
- package/esm/transcribe/transcribe.d.mts +64 -0
- package/esm/transcribe/transcribe.d.mts.map +1 -0
- package/esm/transcribe/transcribe.mjs +128 -0
- package/esm/transcribe/transcribe.mjs.map +1 -0
- package/esm/utils/compute-cost.d.mts +17 -1
- package/esm/utils/compute-cost.d.mts.map +1 -1
- package/esm/utils/compute-cost.mjs +26 -1
- package/esm/utils/compute-cost.mjs.map +1 -1
- package/esm/utils/extract-json-lenient.d.mts +42 -0
- package/esm/utils/extract-json-lenient.d.mts.map +1 -0
- package/esm/utils/extract-json-lenient.mjs +97 -0
- package/esm/utils/extract-json-lenient.mjs.map +1 -0
- package/esm/utils/index.d.mts +4 -2
- package/esm/utils/index.mjs +3 -1
- package/esm/utils/json-schema.d.mts +1 -1
- package/esm/utils/prepare-attachment-part.d.mts +10 -1
- package/esm/utils/prepare-attachment-part.d.mts.map +1 -1
- package/esm/utils/prepare-attachment-part.mjs +103 -11
- package/esm/utils/prepare-attachment-part.mjs.map +1 -1
- package/esm/utils/resolve-attachment.d.mts +4 -3
- package/esm/utils/resolve-attachment.d.mts.map +1 -1
- package/esm/utils/resolve-attachment.mjs +4 -3
- package/esm/utils/resolve-attachment.mjs.map +1 -1
- package/esm/utils/run-context.d.mts +94 -0
- package/esm/utils/run-context.d.mts.map +1 -0
- package/esm/utils/run-context.mjs +98 -0
- package/esm/utils/run-context.mjs.map +1 -0
- package/esm/vcr/cassette-io.mjs +57 -0
- package/esm/vcr/cassette-io.mjs.map +1 -0
- package/esm/vcr/errors.d.mts +42 -0
- package/esm/vcr/errors.d.mts.map +1 -0
- package/esm/vcr/errors.mjs +37 -0
- package/esm/vcr/errors.mjs.map +1 -0
- package/esm/vcr/hash-request.d.mts +28 -0
- package/esm/vcr/hash-request.d.mts.map +1 -0
- package/esm/vcr/hash-request.mjs +118 -0
- package/esm/vcr/hash-request.mjs.map +1 -0
- package/esm/vcr/index.d.mts +4 -0
- package/esm/vcr/index.mjs +5 -0
- package/esm/vcr/vcr.d.mts +32 -0
- package/esm/vcr/vcr.d.mts.map +1 -0
- package/esm/vcr/vcr.mjs +248 -0
- package/esm/vcr/vcr.mjs.map +1 -0
- package/esm/vcr/vcr.type.d.mts +118 -0
- package/esm/vcr/vcr.type.d.mts.map +1 -0
- package/esm/workflow/as-tool.mjs +2 -2
- package/esm/workflow/as-tool.mjs.map +1 -1
- package/esm/workflow/engine.mjs +1 -0
- package/esm/workflow/engine.mjs.map +1 -1
- package/esm/workflow/step-runner.mjs +19 -20
- package/esm/workflow/step-runner.mjs.map +1 -1
- package/esm/workflow/workflow.d.mts.map +1 -1
- package/esm/workflow/workflow.mjs +8 -3
- package/esm/workflow/workflow.mjs.map +1 -1
- package/llms-full.txt +2572 -204
- package/llms.txt +21 -4
- package/package.json +7 -3
- package/skills/README.md +44 -4
- package/skills/ai-dx-helpers/SKILL.md +2 -2
- package/skills/approve-tool-calls/SKILL.md +134 -0
- package/skills/attach-ai-middleware/SKILL.md +1 -1
- package/skills/detect-and-redact-pii/SKILL.md +104 -0
- package/skills/durable-agent-runs/SKILL.md +135 -0
- package/skills/durable-resume/SKILL.md +128 -0
- package/skills/escalate-block-to-human/SKILL.md +85 -0
- package/skills/eval-datasets-and-ci/SKILL.md +117 -0
- package/skills/generate-images/SKILL.md +138 -0
- package/skills/generate-speech/SKILL.md +139 -0
- package/skills/guard-input-output/SKILL.md +117 -0
- package/skills/manage-prompts/SKILL.md +186 -0
- package/skills/observe-ai-flows/SKILL.md +94 -0
- package/skills/rag-loaders-and-stores/SKILL.md +164 -0
- package/skills/record-replay-llm/SKILL.md +92 -0
- package/skills/run-ai-agent/SKILL.md +26 -1
- package/skills/run-ai-rag/SKILL.md +139 -0
- package/skills/run-ai-team/SKILL.md +107 -0
- package/skills/run-orchestrator/SKILL.md +2 -0
- package/skills/run-planner/SKILL.md +73 -8
- package/skills/run-supervisor/SKILL.md +20 -1
- package/skills/transcribe-audio/SKILL.md +157 -0
- package/skills/use-runtime-skills/SKILL.md +106 -0
- package/skills/write-system-prompt/SKILL.md +30 -1
- package/cjs/index.cjs.map +0 -1
- package/esm/contracts/result/index.d.mts +0 -15
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
//#region ../@warlock.js/ai/src/prompt/prompt-langfuse-sync.ts
|
|
2
|
+
let LangfuseSdk;
|
|
3
|
+
let isModuleExists = null;
|
|
4
|
+
let loadingPromise;
|
|
5
|
+
const PROMPT_LANGFUSE_INSTALL_INSTRUCTIONS = `
|
|
6
|
+
The prompt registry's Langfuse sync requires the langfuse package.
|
|
7
|
+
Install it with:
|
|
8
|
+
|
|
9
|
+
npm install langfuse
|
|
10
|
+
|
|
11
|
+
Or with your preferred package manager:
|
|
12
|
+
|
|
13
|
+
pnpm add langfuse
|
|
14
|
+
yarn add langfuse
|
|
15
|
+
`.trim();
|
|
16
|
+
/**
|
|
17
|
+
* Settle the lazy import of `langfuse` once, concurrency-safe. Only needed
|
|
18
|
+
* when the caller did not pass a ready `client`. A bare `catch` flips the
|
|
19
|
+
* flag to `false`; the curated install string surfaces at use time, never a
|
|
20
|
+
* raw module-resolution stack trace.
|
|
21
|
+
*/
|
|
22
|
+
function loadLangfuse() {
|
|
23
|
+
if (isModuleExists !== null) return Promise.resolve();
|
|
24
|
+
if (loadingPromise) return loadingPromise;
|
|
25
|
+
loadingPromise = (async () => {
|
|
26
|
+
try {
|
|
27
|
+
LangfuseSdk = await import("langfuse");
|
|
28
|
+
isModuleExists = true;
|
|
29
|
+
} catch {
|
|
30
|
+
isModuleExists = false;
|
|
31
|
+
}
|
|
32
|
+
})();
|
|
33
|
+
return loadingPromise;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Resolve the Langfuse client — the caller-supplied one when present,
|
|
37
|
+
* otherwise a lazily-constructed client from credentials. Throws the curated
|
|
38
|
+
* install error when the SDK is missing and no client was supplied.
|
|
39
|
+
*/
|
|
40
|
+
async function resolveClient(options) {
|
|
41
|
+
if (options.client) return options.client;
|
|
42
|
+
await loadLangfuse();
|
|
43
|
+
if (!isModuleExists) throw new Error(PROMPT_LANGFUSE_INSTALL_INSTRUCTIONS);
|
|
44
|
+
return new LangfuseSdk.Langfuse({
|
|
45
|
+
publicKey: options.publicKey,
|
|
46
|
+
secretKey: options.secretKey,
|
|
47
|
+
baseUrl: options.baseUrl
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Map one Langfuse prompt handle onto a {@link PromptEntry} version snapshot.
|
|
52
|
+
* Langfuse versions are numeric; they become the string `version` label.
|
|
53
|
+
*/
|
|
54
|
+
function toEntry(remote) {
|
|
55
|
+
return {
|
|
56
|
+
name: remote.name,
|
|
57
|
+
versions: [{
|
|
58
|
+
version: String(remote.version),
|
|
59
|
+
template: remote.prompt
|
|
60
|
+
}]
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Warm the lazy `langfuse` import without blocking — call when a registry is
|
|
65
|
+
* constructed with a `langfuse` option but no pre-built client, so the first
|
|
66
|
+
* `.sync()` does not pay the resolution cost. A bare miss is tolerated.
|
|
67
|
+
*/
|
|
68
|
+
function warmLangfuse(options) {
|
|
69
|
+
if (!options.client) loadLangfuse();
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Run one Langfuse-prompts sync pass.
|
|
73
|
+
*
|
|
74
|
+
* **Pull** (`direction: "pull"` | `"both"`) fetches each named prompt from
|
|
75
|
+
* Langfuse and hands the mapped {@link PromptEntry} to `upsert`. **Push**
|
|
76
|
+
* (`direction: "push"` | `"both"`) writes the latest version of each local
|
|
77
|
+
* entry back as a new Langfuse text prompt. Default direction is `"pull"`.
|
|
78
|
+
*
|
|
79
|
+
* Lazily imports `langfuse` (unless a `client` was supplied) and throws a
|
|
80
|
+
* curated install error when the peer is missing.
|
|
81
|
+
*
|
|
82
|
+
* @param options - The configured sync options (client / credentials / direction).
|
|
83
|
+
* @param names - The prompt names to pull (ignored for push-only).
|
|
84
|
+
* @param localEntries - Snapshot of the local catalog, for push.
|
|
85
|
+
* @param upsert - Callback receiving each pulled entry to merge into the catalog.
|
|
86
|
+
*/
|
|
87
|
+
async function syncLangfusePrompts(options, names, localEntries, upsert) {
|
|
88
|
+
const direction = options.direction ?? "pull";
|
|
89
|
+
const client = await resolveClient(options);
|
|
90
|
+
if (direction === "pull" || direction === "both") for (const name of names) upsert(toEntry(await client.getPrompt(name)));
|
|
91
|
+
if (direction === "push" || direction === "both") for (const entry of localEntries) {
|
|
92
|
+
const latest = entry.versions[entry.versions.length - 1];
|
|
93
|
+
if (!latest) continue;
|
|
94
|
+
await client.createPrompt({
|
|
95
|
+
name: entry.name,
|
|
96
|
+
prompt: latest.template,
|
|
97
|
+
type: "text"
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
//#endregion
|
|
103
|
+
export { syncLangfusePrompts, warmLangfuse };
|
|
104
|
+
//# sourceMappingURL=prompt-langfuse-sync.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-langfuse-sync.mjs","names":[],"sources":["../../../../../../../@warlock.js/ai/src/prompt/prompt-langfuse-sync.ts"],"sourcesContent":["import type { PromptEntry, PromptLangfuseSyncOptions } from \"./prompt.type\";\nimport type {\n LangfuseClientLike,\n LangfusePromptLike,\n} from \"./prompt-langfuse-sync.type\";\n\n// ============================================================\n// Lazily-loaded langfuse SDK (OPTIONAL peer)\n// ============================================================\n\nlet LangfuseSdk: typeof import(\"langfuse\");\nlet isModuleExists: boolean | null = null;\nlet loadingPromise: Promise<void> | undefined;\n\nconst PROMPT_LANGFUSE_INSTALL_INSTRUCTIONS = `\nThe prompt registry's Langfuse sync requires the langfuse package.\nInstall it with:\n\n npm install langfuse\n\nOr with your preferred package manager:\n\n pnpm add langfuse\n yarn add langfuse\n`.trim();\n\n/**\n * Settle the lazy import of `langfuse` once, concurrency-safe. Only needed\n * when the caller did not pass a ready `client`. A bare `catch` flips the\n * flag to `false`; the curated install string surfaces at use time, never a\n * raw module-resolution stack trace.\n */\nfunction loadLangfuse(): Promise<void> {\n if (isModuleExists !== null) {\n return Promise.resolve();\n }\n\n if (loadingPromise) {\n return loadingPromise;\n }\n\n loadingPromise = (async () => {\n try {\n LangfuseSdk = await import(\"langfuse\");\n isModuleExists = true;\n } catch {\n isModuleExists = false;\n }\n })();\n\n return loadingPromise;\n}\n\n/**\n * Resolve the Langfuse client — the caller-supplied one when present,\n * otherwise a lazily-constructed client from credentials. Throws the curated\n * install error when the SDK is missing and no client was supplied.\n */\nasync function resolveClient(\n options: PromptLangfuseSyncOptions,\n): Promise<LangfuseClientLike> {\n if (options.client) {\n return options.client;\n }\n\n await loadLangfuse();\n\n if (!isModuleExists) {\n throw new Error(PROMPT_LANGFUSE_INSTALL_INSTRUCTIONS);\n }\n\n return new LangfuseSdk.Langfuse({\n publicKey: options.publicKey,\n secretKey: options.secretKey,\n baseUrl: options.baseUrl,\n }) as unknown as LangfuseClientLike;\n}\n\n/**\n * Map one Langfuse prompt handle onto a {@link PromptEntry} version snapshot.\n * Langfuse versions are numeric; they become the string `version` label.\n */\nfunction toEntry(remote: LangfusePromptLike): PromptEntry {\n return {\n name: remote.name,\n versions: [{ version: String(remote.version), template: remote.prompt }],\n };\n}\n\n/**\n * Warm the lazy `langfuse` import without blocking — call when a registry is\n * constructed with a `langfuse` option but no pre-built client, so the first\n * `.sync()` does not pay the resolution cost. A bare miss is tolerated.\n */\nexport function warmLangfuse(options: PromptLangfuseSyncOptions): void {\n if (!options.client) {\n void loadLangfuse();\n }\n}\n\n/**\n * Run one Langfuse-prompts sync pass.\n *\n * **Pull** (`direction: \"pull\"` | `\"both\"`) fetches each named prompt from\n * Langfuse and hands the mapped {@link PromptEntry} to `upsert`. **Push**\n * (`direction: \"push\"` | `\"both\"`) writes the latest version of each local\n * entry back as a new Langfuse text prompt. Default direction is `\"pull\"`.\n *\n * Lazily imports `langfuse` (unless a `client` was supplied) and throws a\n * curated install error when the peer is missing.\n *\n * @param options - The configured sync options (client / credentials / direction).\n * @param names - The prompt names to pull (ignored for push-only).\n * @param localEntries - Snapshot of the local catalog, for push.\n * @param upsert - Callback receiving each pulled entry to merge into the catalog.\n */\nexport async function syncLangfusePrompts(\n options: PromptLangfuseSyncOptions,\n names: string[],\n localEntries: PromptEntry[],\n upsert: (entry: PromptEntry) => void,\n): Promise<void> {\n const direction = options.direction ?? \"pull\";\n const client = await resolveClient(options);\n\n if (direction === \"pull\" || direction === \"both\") {\n for (const name of names) {\n const remote = await client.getPrompt(name);\n upsert(toEntry(remote));\n }\n }\n\n if (direction === \"push\" || direction === \"both\") {\n for (const entry of localEntries) {\n const latest = entry.versions[entry.versions.length - 1];\n\n if (!latest) {\n continue;\n }\n\n await client.createPrompt({\n name: entry.name,\n prompt: latest.template,\n type: \"text\",\n });\n }\n }\n}\n"],"mappings":";AAUA,IAAI;AACJ,IAAI,iBAAiC;AACrC,IAAI;AAEJ,MAAM,uCAAuC;;;;;;;;;;EAU3C,KAAK;;;;;;;AAQP,SAAS,eAA8B;CACrC,IAAI,mBAAmB,MACrB,OAAO,QAAQ,QAAQ;CAGzB,IAAI,gBACF,OAAO;CAGT,kBAAkB,YAAY;EAC5B,IAAI;GACF,cAAc,MAAM,OAAO;GAC3B,iBAAiB;EACnB,QAAQ;GACN,iBAAiB;EACnB;CACF,EAAC,CAAE;CAEH,OAAO;AACT;;;;;;AAOA,eAAe,cACb,SAC6B;CAC7B,IAAI,QAAQ,QACV,OAAO,QAAQ;CAGjB,MAAM,aAAa;CAEnB,IAAI,CAAC,gBACH,MAAM,IAAI,MAAM,oCAAoC;CAGtD,OAAO,IAAI,YAAY,SAAS;EAC9B,WAAW,QAAQ;EACnB,WAAW,QAAQ;EACnB,SAAS,QAAQ;CACnB,CAAC;AACH;;;;;AAMA,SAAS,QAAQ,QAAyC;CACxD,OAAO;EACL,MAAM,OAAO;EACb,UAAU,CAAC;GAAE,SAAS,OAAO,OAAO,OAAO;GAAG,UAAU,OAAO;EAAO,CAAC;CACzE;AACF;;;;;;AAOA,SAAgB,aAAa,SAA0C;CACrE,IAAI,CAAC,QAAQ,QACX,AAAK,aAAa;AAEtB;;;;;;;;;;;;;;;;;AAkBA,eAAsB,oBACpB,SACA,OACA,cACA,QACe;CACf,MAAM,YAAY,QAAQ,aAAa;CACvC,MAAM,SAAS,MAAM,cAAc,OAAO;CAE1C,IAAI,cAAc,UAAU,cAAc,QACxC,KAAK,MAAM,QAAQ,OAEjB,OAAO,QAAQ,MADM,OAAO,UAAU,IAAI,CACrB,CAAC;CAI1B,IAAI,cAAc,UAAU,cAAc,QACxC,KAAK,MAAM,SAAS,cAAc;EAChC,MAAM,SAAS,MAAM,SAAS,MAAM,SAAS,SAAS;EAEtD,IAAI,CAAC,QACH;EAGF,MAAM,OAAO,aAAa;GACxB,MAAM,MAAM;GACZ,QAAQ,OAAO;GACf,MAAM;EACR,CAAC;CACH;AAEJ"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
//#region ../@warlock.js/ai/src/prompt/prompt-langfuse-sync.type.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Minimal structural view of the parts of the `langfuse` SDK the prompt sync
|
|
4
|
+
* actually calls. Declared locally (rather than importing the SDK's own types)
|
|
5
|
+
* so this module type-checks even when `langfuse` is not installed — it is an
|
|
6
|
+
* OPTIONAL peer, lazily imported at runtime. The shape tracks Langfuse SDK v3's
|
|
7
|
+
* prompt API: `getPrompt(name, version?)` reads a prompt and `createPrompt(...)`
|
|
8
|
+
* writes a new prompt version.
|
|
9
|
+
*/
|
|
10
|
+
type LangfuseClientLike = {
|
|
11
|
+
/** Fetch a single prompt by name (optionally a specific version). */getPrompt(name: string, version?: number): Promise<LangfusePromptLike>; /** Create (push) a new text prompt version. */
|
|
12
|
+
createPrompt(body: LangfuseCreatePromptBody): Promise<LangfusePromptLike>;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* A Langfuse prompt handle as returned by `getPrompt` / `createPrompt`. Only
|
|
16
|
+
* the `name` / `version` / `prompt` (body) fields the sync maps are modeled.
|
|
17
|
+
*/
|
|
18
|
+
type LangfusePromptLike = {
|
|
19
|
+
/** Prompt name. */name: string; /** Numeric version assigned by Langfuse. */
|
|
20
|
+
version: number; /** The prompt body text (Langfuse `type: "text"` prompts). */
|
|
21
|
+
prompt: string;
|
|
22
|
+
};
|
|
23
|
+
/** Body accepted by `client.createPrompt(...)` for a text prompt. */
|
|
24
|
+
type LangfuseCreatePromptBody = {
|
|
25
|
+
/** Prompt name. */name: string; /** Prompt body text. */
|
|
26
|
+
prompt: string; /** Discriminator — always `"text"` for the bodies this sync pushes. */
|
|
27
|
+
type?: "text"; /** Deploy labels (e.g. `["production"]`). Optional. */
|
|
28
|
+
labels?: string[];
|
|
29
|
+
};
|
|
30
|
+
//#endregion
|
|
31
|
+
export { LangfuseClientLike };
|
|
32
|
+
//# sourceMappingURL=prompt-langfuse-sync.type.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-langfuse-sync.type.d.mts","names":[],"sources":["../../../../../../../@warlock.js/ai/src/prompt/prompt-langfuse-sync.type.ts"],"mappings":";;AAQA;;;;;;;KAAY,kBAAA;EAI2C,qEAFrD,SAAA,CAAU,IAAA,UAAc,OAAA,YAAmB,OAAA,CAAQ,kBAAA,GAAnD;EAEA,YAAA,CAAa,IAAA,EAAM,wBAAA,GAA2B,OAAA,CAAQ,kBAAA;AAAA;;;;;KAO5C,kBAAA;EAPoC,mBAS9C,IAAA,UATwE;EAWxE,OAAA,UAJU;EAMV,MAAA;AAAA;;KAIU,wBAAA;EANV,mBAQA,IAAA,UANM;EAQN,MAAA,UAJU;EAMV,IAAA;EAEA,MAAA;AAAA"}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { judge } from "../eval/judge-scorer.mjs";
|
|
2
|
+
|
|
3
|
+
//#region ../@warlock.js/ai/src/prompt/prompt-validate.ts
|
|
4
|
+
/**
|
|
5
|
+
* Placeholder matcher — kept in lock-step with the matcher
|
|
6
|
+
* `renderPlaceholders` uses (`src/system-prompt/render-placeholders.ts`) so the
|
|
7
|
+
* lint sees the same `{{key}}` / `{{a.b}}` / `{{key|default}}` set the renderer
|
|
8
|
+
* substitutes. Global so every occurrence is collected.
|
|
9
|
+
*/
|
|
10
|
+
const PLACEHOLDER_PATTERN = /\{\{\s*([^{}]+?)\s*\}\}/g;
|
|
11
|
+
/** Lower bound below which a prompt is suspiciously terse. */
|
|
12
|
+
const MIN_REASONABLE_LENGTH = 12;
|
|
13
|
+
/** Upper bound above which a prompt is likely bloated / unfocused. */
|
|
14
|
+
const MAX_REASONABLE_LENGTH = 8e3;
|
|
15
|
+
/**
|
|
16
|
+
* Severity rank for most-severe-first ordering. Higher sorts earlier.
|
|
17
|
+
*/
|
|
18
|
+
const SEVERITY_RANK = {
|
|
19
|
+
error: 2,
|
|
20
|
+
warn: 1,
|
|
21
|
+
info: 0
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* The fixed rubric the LLM-as-judge grades a prompt body against. Surfaced
|
|
25
|
+
* here (not inline) so the static-lint pass and the judge pass document the
|
|
26
|
+
* same quality dimensions.
|
|
27
|
+
*/
|
|
28
|
+
const PROMPT_JUDGE_RUBRIC = [
|
|
29
|
+
"Grade this SYSTEM PROMPT on a 0..1 scale for overall quality:",
|
|
30
|
+
"- Clarity: is the intent unambiguous and easy to follow?",
|
|
31
|
+
"- Role definition: does it clearly state who/what the assistant is?",
|
|
32
|
+
"- Output-format specificity: does it say how the answer should be shaped?",
|
|
33
|
+
"- No conflicting instructions: are any directives contradictory?",
|
|
34
|
+
"Score 1.0 only when all four hold; deduct for each weakness and explain why."
|
|
35
|
+
].join("\n");
|
|
36
|
+
/**
|
|
37
|
+
* Heuristic role-line detector — a prompt that never says "you are …" /
|
|
38
|
+
* "act as …" / "your role is …" typically lacks a persona. Case-insensitive.
|
|
39
|
+
*/
|
|
40
|
+
const ROLE_HINT_PATTERN = /\b(you are|act as|your role is|you're a|you will act)\b/i;
|
|
41
|
+
/**
|
|
42
|
+
* Run the cheap, model-free static lint over a prompt body. Flags:
|
|
43
|
+
* - length out of the reasonable band (too terse / too bloated),
|
|
44
|
+
* - any `{{placeholder}}` that survives (undeclared / unresolved at lint time),
|
|
45
|
+
* - a missing role line.
|
|
46
|
+
*
|
|
47
|
+
* Pure and synchronous — used standalone (no judge model) and merged with the
|
|
48
|
+
* judge findings when a model is available.
|
|
49
|
+
*
|
|
50
|
+
* @param text - The prompt body to lint.
|
|
51
|
+
*/
|
|
52
|
+
function staticLint(text) {
|
|
53
|
+
const notes = [];
|
|
54
|
+
const trimmed = text.trim();
|
|
55
|
+
if (trimmed.length < MIN_REASONABLE_LENGTH) notes.push({
|
|
56
|
+
severity: "warn",
|
|
57
|
+
message: `Prompt is very short (${trimmed.length} chars) — it may be too vague to steer the model.`,
|
|
58
|
+
suggestion: "Add an explicit role and at least one concrete instruction."
|
|
59
|
+
});
|
|
60
|
+
if (trimmed.length > MAX_REASONABLE_LENGTH) notes.push({
|
|
61
|
+
severity: "warn",
|
|
62
|
+
message: `Prompt is very long (${trimmed.length} chars) — long prompts dilute focus and inflate cost.`,
|
|
63
|
+
suggestion: "Split into a tighter persona plus a few focused instructions."
|
|
64
|
+
});
|
|
65
|
+
const placeholders = collectPlaceholders(text);
|
|
66
|
+
for (const placeholder of placeholders) notes.push({
|
|
67
|
+
severity: "info",
|
|
68
|
+
message: `Unresolved placeholder "{{${placeholder}}}" — confirm it is supplied at resolve time or give it a default ("{{${placeholder}|...}}").`
|
|
69
|
+
});
|
|
70
|
+
if (!ROLE_HINT_PATTERN.test(trimmed)) notes.push({
|
|
71
|
+
severity: "warn",
|
|
72
|
+
message: "No role line found — the prompt never states who the assistant is.",
|
|
73
|
+
suggestion: "Open with a role, e.g. \"You are a senior support engineer for …\"."
|
|
74
|
+
});
|
|
75
|
+
return notes;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Collect every distinct placeholder PATH (the part before any `|default`)
|
|
79
|
+
* from a template, in first-seen order. Matches `renderPlaceholders`' own
|
|
80
|
+
* parsing so the lint never disagrees with the renderer.
|
|
81
|
+
*/
|
|
82
|
+
function collectPlaceholders(template) {
|
|
83
|
+
const found = [];
|
|
84
|
+
const seen = /* @__PURE__ */ new Set();
|
|
85
|
+
for (const match of template.matchAll(PLACEHOLDER_PATTERN)) {
|
|
86
|
+
const path = match[1].split("|")[0].trim();
|
|
87
|
+
if (path.length > 0 && !seen.has(path)) {
|
|
88
|
+
seen.add(path);
|
|
89
|
+
found.push(path);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return found;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Stable, most-severe-first ordering: `error` before `warn` before `info`,
|
|
96
|
+
* preserving original order within a severity. Returns a fresh array.
|
|
97
|
+
*/
|
|
98
|
+
function sortNotesBySeverity(notes) {
|
|
99
|
+
return notes.map((note, index) => ({
|
|
100
|
+
note,
|
|
101
|
+
index
|
|
102
|
+
})).sort((a, b) => {
|
|
103
|
+
const rankDiff = SEVERITY_RANK[b.note.severity] - SEVERITY_RANK[a.note.severity];
|
|
104
|
+
return rankDiff !== 0 ? rankDiff : a.index - b.index;
|
|
105
|
+
}).map((entry) => entry.note);
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Score the static-lint findings alone, on a `0..1` scale. Starts at `1.0`
|
|
109
|
+
* and deducts per finding by severity, clamped at `0`. Used as the report
|
|
110
|
+
* score when no judge model is available.
|
|
111
|
+
*/
|
|
112
|
+
function staticScore(notes) {
|
|
113
|
+
let score = 1;
|
|
114
|
+
for (const note of notes) if (note.severity === "error") score -= .4;
|
|
115
|
+
else if (note.severity === "warn") score -= .2;
|
|
116
|
+
else score -= .05;
|
|
117
|
+
return Math.max(0, Number(score.toFixed(4)));
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Run the LLM-as-judge pass over `text` using a judge agent built from
|
|
121
|
+
* `model`, REUSING the eval `judge` scorer so there is no second judging
|
|
122
|
+
* path. Returns the judge `score` (`0..1`) and a single derived note carrying
|
|
123
|
+
* its reason (when present). The judge prompt is the prompt-quality rubric;
|
|
124
|
+
* the "answer to grade" is the prompt body itself.
|
|
125
|
+
*
|
|
126
|
+
* @param text - The prompt body under evaluation.
|
|
127
|
+
* @param model - The model that powers the judge agent.
|
|
128
|
+
* @param buildJudgeAgent - Factory that wraps a model into a name-bearing judge agent.
|
|
129
|
+
*/
|
|
130
|
+
async function judgePrompt(text, model, buildJudgeAgent) {
|
|
131
|
+
const score = await judge({
|
|
132
|
+
agent: buildJudgeAgent(model),
|
|
133
|
+
rubric: PROMPT_JUDGE_RUBRIC
|
|
134
|
+
})({
|
|
135
|
+
case: {
|
|
136
|
+
name: "prompt-quality",
|
|
137
|
+
input: "Grade the system prompt below."
|
|
138
|
+
},
|
|
139
|
+
text,
|
|
140
|
+
result: { text },
|
|
141
|
+
output: void 0
|
|
142
|
+
});
|
|
143
|
+
const notes = [];
|
|
144
|
+
if (score.reason) notes.push({
|
|
145
|
+
severity: score.passed ? "info" : "warn",
|
|
146
|
+
message: `LLM-as-judge: ${score.reason}`
|
|
147
|
+
});
|
|
148
|
+
return {
|
|
149
|
+
score: score.score,
|
|
150
|
+
notes
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Assemble the final {@link PromptValidationReport} from the static-lint
|
|
155
|
+
* findings and (optionally) the judge findings. Notes are merged and sorted
|
|
156
|
+
* most-severe-first. The score is the static score alone when no judge ran,
|
|
157
|
+
* else the mean of the static score and the judge score.
|
|
158
|
+
*/
|
|
159
|
+
function buildValidationReport(staticNotes, judgeResult) {
|
|
160
|
+
const allNotes = judgeResult ? [...staticNotes, ...judgeResult.notes] : staticNotes;
|
|
161
|
+
const lintScore = staticScore(staticNotes);
|
|
162
|
+
return {
|
|
163
|
+
score: judgeResult ? Number(((lintScore + judgeResult.score) / 2).toFixed(4)) : lintScore,
|
|
164
|
+
notes: sortNotesBySeverity(allNotes)
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
//#endregion
|
|
169
|
+
export { PROMPT_JUDGE_RUBRIC, buildValidationReport, judgePrompt, staticLint };
|
|
170
|
+
//# sourceMappingURL=prompt-validate.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-validate.mjs","names":[],"sources":["../../../../../../../@warlock.js/ai/src/prompt/prompt-validate.ts"],"sourcesContent":["import type { AgentContract } from \"../contracts/agent/agent.contract\";\nimport type { ModelContract } from \"../contracts/model.contract\";\nimport { judge } from \"../eval/judge-scorer\";\nimport type { PromptValidationNote, PromptValidationReport } from \"./prompt.type\";\n\n/**\n * Placeholder matcher — kept in lock-step with the matcher\n * `renderPlaceholders` uses (`src/system-prompt/render-placeholders.ts`) so the\n * lint sees the same `{{key}}` / `{{a.b}}` / `{{key|default}}` set the renderer\n * substitutes. Global so every occurrence is collected.\n */\nconst PLACEHOLDER_PATTERN = /\\{\\{\\s*([^{}]+?)\\s*\\}\\}/g;\n\n/** Lower bound below which a prompt is suspiciously terse. */\nconst MIN_REASONABLE_LENGTH = 12;\n\n/** Upper bound above which a prompt is likely bloated / unfocused. */\nconst MAX_REASONABLE_LENGTH = 8000;\n\n/**\n * Severity rank for most-severe-first ordering. Higher sorts earlier.\n */\nconst SEVERITY_RANK: Record<PromptValidationNote[\"severity\"], number> = {\n error: 2,\n warn: 1,\n info: 0,\n};\n\n/**\n * The fixed rubric the LLM-as-judge grades a prompt body against. Surfaced\n * here (not inline) so the static-lint pass and the judge pass document the\n * same quality dimensions.\n */\nexport const PROMPT_JUDGE_RUBRIC = [\n \"Grade this SYSTEM PROMPT on a 0..1 scale for overall quality:\",\n \"- Clarity: is the intent unambiguous and easy to follow?\",\n \"- Role definition: does it clearly state who/what the assistant is?\",\n \"- Output-format specificity: does it say how the answer should be shaped?\",\n \"- No conflicting instructions: are any directives contradictory?\",\n \"Score 1.0 only when all four hold; deduct for each weakness and explain why.\",\n].join(\"\\n\");\n\n/**\n * Heuristic role-line detector — a prompt that never says \"you are …\" /\n * \"act as …\" / \"your role is …\" typically lacks a persona. Case-insensitive.\n */\nconst ROLE_HINT_PATTERN = /\\b(you are|act as|your role is|you're a|you will act)\\b/i;\n\n/**\n * Run the cheap, model-free static lint over a prompt body. Flags:\n * - length out of the reasonable band (too terse / too bloated),\n * - any `{{placeholder}}` that survives (undeclared / unresolved at lint time),\n * - a missing role line.\n *\n * Pure and synchronous — used standalone (no judge model) and merged with the\n * judge findings when a model is available.\n *\n * @param text - The prompt body to lint.\n */\nexport function staticLint(text: string): PromptValidationNote[] {\n const notes: PromptValidationNote[] = [];\n const trimmed = text.trim();\n\n if (trimmed.length < MIN_REASONABLE_LENGTH) {\n notes.push({\n severity: \"warn\",\n message: `Prompt is very short (${trimmed.length} chars) — it may be too vague to steer the model.`,\n suggestion: \"Add an explicit role and at least one concrete instruction.\",\n });\n }\n\n if (trimmed.length > MAX_REASONABLE_LENGTH) {\n notes.push({\n severity: \"warn\",\n message: `Prompt is very long (${trimmed.length} chars) — long prompts dilute focus and inflate cost.`,\n suggestion: \"Split into a tighter persona plus a few focused instructions.\",\n });\n }\n\n const placeholders = collectPlaceholders(text);\n\n for (const placeholder of placeholders) {\n notes.push({\n severity: \"info\",\n message: `Unresolved placeholder \"{{${placeholder}}}\" — confirm it is supplied at resolve time or give it a default (\"{{${placeholder}|...}}\").`,\n });\n }\n\n if (!ROLE_HINT_PATTERN.test(trimmed)) {\n notes.push({\n severity: \"warn\",\n message: \"No role line found — the prompt never states who the assistant is.\",\n suggestion: 'Open with a role, e.g. \"You are a senior support engineer for …\".',\n });\n }\n\n return notes;\n}\n\n/**\n * Collect every distinct placeholder PATH (the part before any `|default`)\n * from a template, in first-seen order. Matches `renderPlaceholders`' own\n * parsing so the lint never disagrees with the renderer.\n */\nfunction collectPlaceholders(template: string): string[] {\n const found: string[] = [];\n const seen = new Set<string>();\n\n for (const match of template.matchAll(PLACEHOLDER_PATTERN)) {\n const path = match[1].split(\"|\")[0].trim();\n\n if (path.length > 0 && !seen.has(path)) {\n seen.add(path);\n found.push(path);\n }\n }\n\n return found;\n}\n\n/**\n * Stable, most-severe-first ordering: `error` before `warn` before `info`,\n * preserving original order within a severity. Returns a fresh array.\n */\nexport function sortNotesBySeverity(\n notes: PromptValidationNote[],\n): PromptValidationNote[] {\n return notes\n .map((note, index) => ({ note, index }))\n .sort((a, b) => {\n const rankDiff = SEVERITY_RANK[b.note.severity] - SEVERITY_RANK[a.note.severity];\n\n return rankDiff !== 0 ? rankDiff : a.index - b.index;\n })\n .map(entry => entry.note);\n}\n\n/**\n * Score the static-lint findings alone, on a `0..1` scale. Starts at `1.0`\n * and deducts per finding by severity, clamped at `0`. Used as the report\n * score when no judge model is available.\n */\nexport function staticScore(notes: PromptValidationNote[]): number {\n let score = 1;\n\n for (const note of notes) {\n if (note.severity === \"error\") {\n score -= 0.4;\n } else if (note.severity === \"warn\") {\n score -= 0.2;\n } else {\n score -= 0.05;\n }\n }\n\n return Math.max(0, Number(score.toFixed(4)));\n}\n\n/**\n * Run the LLM-as-judge pass over `text` using a judge agent built from\n * `model`, REUSING the eval `judge` scorer so there is no second judging\n * path. Returns the judge `score` (`0..1`) and a single derived note carrying\n * its reason (when present). The judge prompt is the prompt-quality rubric;\n * the \"answer to grade\" is the prompt body itself.\n *\n * @param text - The prompt body under evaluation.\n * @param model - The model that powers the judge agent.\n * @param buildJudgeAgent - Factory that wraps a model into a name-bearing judge agent.\n */\nexport async function judgePrompt(\n text: string,\n model: ModelContract,\n buildJudgeAgent: (model: ModelContract) => AgentContract<unknown>,\n): Promise<{ score: number; notes: PromptValidationNote[] }> {\n const judgeAgent = buildJudgeAgent(model);\n const scorer = judge({ agent: judgeAgent, rubric: PROMPT_JUDGE_RUBRIC });\n\n const score = await scorer({\n // The judge scorer only reads `case.input` / `case.expected` / `text` /\n // `output` from the context. We feed the rubric question via `input` and\n // the prompt body as the answer to grade via `text`.\n case: { name: \"prompt-quality\", input: \"Grade the system prompt below.\" },\n text,\n // `result` is unused by the judge scorer's prompt builder; a minimal\n // stand-in keeps the structural contract satisfied without a real run.\n result: { text } as never,\n output: undefined,\n });\n\n const notes: PromptValidationNote[] = [];\n\n if (score.reason) {\n notes.push({\n severity: score.passed ? \"info\" : \"warn\",\n message: `LLM-as-judge: ${score.reason}`,\n });\n }\n\n return { score: score.score, notes };\n}\n\n/**\n * Assemble the final {@link PromptValidationReport} from the static-lint\n * findings and (optionally) the judge findings. Notes are merged and sorted\n * most-severe-first. The score is the static score alone when no judge ran,\n * else the mean of the static score and the judge score.\n */\nexport function buildValidationReport(\n staticNotes: PromptValidationNote[],\n judgeResult?: { score: number; notes: PromptValidationNote[] },\n): PromptValidationReport {\n const allNotes = judgeResult\n ? [...staticNotes, ...judgeResult.notes]\n : staticNotes;\n\n const lintScore = staticScore(staticNotes);\n\n const score = judgeResult\n ? Number(((lintScore + judgeResult.score) / 2).toFixed(4))\n : lintScore;\n\n return {\n score,\n notes: sortNotesBySeverity(allNotes),\n };\n}\n"],"mappings":";;;;;;;;;AAWA,MAAM,sBAAsB;;AAG5B,MAAM,wBAAwB;;AAG9B,MAAM,wBAAwB;;;;AAK9B,MAAM,gBAAkE;CACtE,OAAO;CACP,MAAM;CACN,MAAM;AACR;;;;;;AAOA,MAAa,sBAAsB;CACjC;CACA;CACA;CACA;CACA;CACA;AACF,CAAC,CAAC,KAAK,IAAI;;;;;AAMX,MAAM,oBAAoB;;;;;;;;;;;;AAa1B,SAAgB,WAAW,MAAsC;CAC/D,MAAM,QAAgC,CAAC;CACvC,MAAM,UAAU,KAAK,KAAK;CAE1B,IAAI,QAAQ,SAAS,uBACnB,MAAM,KAAK;EACT,UAAU;EACV,SAAS,yBAAyB,QAAQ,OAAO;EACjD,YAAY;CACd,CAAC;CAGH,IAAI,QAAQ,SAAS,uBACnB,MAAM,KAAK;EACT,UAAU;EACV,SAAS,wBAAwB,QAAQ,OAAO;EAChD,YAAY;CACd,CAAC;CAGH,MAAM,eAAe,oBAAoB,IAAI;CAE7C,KAAK,MAAM,eAAe,cACxB,MAAM,KAAK;EACT,UAAU;EACV,SAAS,6BAA6B,YAAY,wEAAwE,YAAY;CACxI,CAAC;CAGH,IAAI,CAAC,kBAAkB,KAAK,OAAO,GACjC,MAAM,KAAK;EACT,UAAU;EACV,SAAS;EACT,YAAY;CACd,CAAC;CAGH,OAAO;AACT;;;;;;AAOA,SAAS,oBAAoB,UAA4B;CACvD,MAAM,QAAkB,CAAC;CACzB,MAAM,uBAAO,IAAI,IAAY;CAE7B,KAAK,MAAM,SAAS,SAAS,SAAS,mBAAmB,GAAG;EAC1D,MAAM,OAAO,MAAM,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC,KAAK;EAEzC,IAAI,KAAK,SAAS,KAAK,CAAC,KAAK,IAAI,IAAI,GAAG;GACtC,KAAK,IAAI,IAAI;GACb,MAAM,KAAK,IAAI;EACjB;CACF;CAEA,OAAO;AACT;;;;;AAMA,SAAgB,oBACd,OACwB;CACxB,OAAO,MACJ,KAAK,MAAM,WAAW;EAAE;EAAM;CAAM,EAAE,CAAC,CACvC,MAAM,GAAG,MAAM;EACd,MAAM,WAAW,cAAc,EAAE,KAAK,YAAY,cAAc,EAAE,KAAK;EAEvE,OAAO,aAAa,IAAI,WAAW,EAAE,QAAQ,EAAE;CACjD,CAAC,CAAC,CACD,KAAI,UAAS,MAAM,IAAI;AAC5B;;;;;;AAOA,SAAgB,YAAY,OAAuC;CACjE,IAAI,QAAQ;CAEZ,KAAK,MAAM,QAAQ,OACjB,IAAI,KAAK,aAAa,SACpB,SAAS;MACJ,IAAI,KAAK,aAAa,QAC3B,SAAS;MAET,SAAS;CAIb,OAAO,KAAK,IAAI,GAAG,OAAO,MAAM,QAAQ,CAAC,CAAC,CAAC;AAC7C;;;;;;;;;;;;AAaA,eAAsB,YACpB,MACA,OACA,iBAC2D;CAI3D,MAAM,QAAQ,MAFC,MAAM;EAAE,OADJ,gBAAgB,KACI;EAAG,QAAQ;CAAoB,CAE7C,CAAC,CAAC;EAIzB,MAAM;GAAE,MAAM;GAAkB,OAAO;EAAiC;EACxE;EAGA,QAAQ,EAAE,KAAK;EACf,QAAQ;CACV,CAAC;CAED,MAAM,QAAgC,CAAC;CAEvC,IAAI,MAAM,QACR,MAAM,KAAK;EACT,UAAU,MAAM,SAAS,SAAS;EAClC,SAAS,iBAAiB,MAAM;CAClC,CAAC;CAGH,OAAO;EAAE,OAAO,MAAM;EAAO;CAAM;AACrC;;;;;;;AAQA,SAAgB,sBACd,aACA,aACwB;CACxB,MAAM,WAAW,cACb,CAAC,GAAG,aAAa,GAAG,YAAY,KAAK,IACrC;CAEJ,MAAM,YAAY,YAAY,WAAW;CAMzC,OAAO;EACL,OALY,cACV,SAAS,YAAY,YAAY,SAAS,EAAC,CAAE,QAAQ,CAAC,CAAC,IACvD;EAIF,OAAO,oBAAoB,QAAQ;CACrC;AACF"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { SystemPromptContract } from "../contracts/system-prompt.contract.mjs";
|
|
2
|
+
import { PromptRegistryContract, PromptRegistryOptions } from "./prompt.type.mjs";
|
|
3
|
+
|
|
4
|
+
//#region ../@warlock.js/ai/src/prompt/prompt.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* Create a versioned, typed prompt registry — a thin facade over the unified
|
|
7
|
+
* `ai.prompts` manager.
|
|
8
|
+
*
|
|
9
|
+
* **Role.** Public factory for {@link PromptRegistryContract}. Keeps
|
|
10
|
+
* user-facing code free of `new` and consistent with `ai.memory`,
|
|
11
|
+
* `ai.orchestrator`, `ai.batch` (all return instances). Each call returns a
|
|
12
|
+
* fresh, isolated registry backed by its own unified manager, so parallel test
|
|
13
|
+
* suites and multi-tenant apps never share mutable global prompt state.
|
|
14
|
+
*
|
|
15
|
+
* @param options - Seed entries, an optional default judge model, and an
|
|
16
|
+
* optional Langfuse sync.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* const prompts = prompt({
|
|
20
|
+
* prompts: [
|
|
21
|
+
* {
|
|
22
|
+
* name: "support-agent",
|
|
23
|
+
* versions: [
|
|
24
|
+
* { version: "1", template: "You are support for {{product}}. Reply in {{language|English}}." },
|
|
25
|
+
* { version: "2", template: "You are senior support for {{product}}.", required: ["product"] },
|
|
26
|
+
* ],
|
|
27
|
+
* },
|
|
28
|
+
* ],
|
|
29
|
+
* });
|
|
30
|
+
*
|
|
31
|
+
* const resolved = prompts.resolve("support-agent", { placeholders: { product: "Warlock" } });
|
|
32
|
+
* const agent = ai.agent({ model, systemPrompt: resolved.toSystemPrompt() });
|
|
33
|
+
* // resolved.version === "2"; a missing `product` would throw PromptValidationError.
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* // Resolve a globally-registered prompt by name from `ai.prompts`.
|
|
37
|
+
* ai.systemPrompt("You are support.", { name: "support" });
|
|
38
|
+
* const sp = ai.prompt("support"); // → the registered SystemPromptContract
|
|
39
|
+
*/
|
|
40
|
+
declare function promptFactory(name: string, versionOrTag?: string): SystemPromptContract;
|
|
41
|
+
declare function promptFactory(options?: PromptRegistryOptions): PromptRegistryContract;
|
|
42
|
+
/**
|
|
43
|
+
* Create a versioned prompt registry, OR resolve a globally-registered prompt
|
|
44
|
+
* by name from `ai.prompts`.
|
|
45
|
+
*
|
|
46
|
+
* - `prompt(options?)` → a fresh, isolated {@link PromptRegistryContract}.
|
|
47
|
+
* - `prompt(name, versionOrTag?)` → the `SystemPromptContract` registered under
|
|
48
|
+
* `name` in the process-wide `ai.prompts` manager (latest version by default,
|
|
49
|
+
* or a specific version / pinned tag).
|
|
50
|
+
*/
|
|
51
|
+
declare const prompt: typeof promptFactory;
|
|
52
|
+
//#endregion
|
|
53
|
+
export { prompt };
|
|
54
|
+
//# sourceMappingURL=prompt.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt.d.mts","names":[],"sources":["../../../../../../../@warlock.js/ai/src/prompt/prompt.ts"],"mappings":";;;;;;AA+BuB;;;;;;;;AA+UA;AAAA;;;;;;;;AACwD;AAyB/E;;;;AAAyD;;;;;;;;;;;iBA7BhD,aAAA,CACP,IAAA,UACA,YAAA,YACC,oBAAoB;AAAA,iBACd,aAAA,CAAc,OAAA,GAAU,qBAAA,GAAwB,sBAAsB;;;;;;;;;;cAyBlE,MAAA,SAAe,aAA6B"}
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import { agent } from "../agent/agent.mjs";
|
|
2
|
+
import { renderPlaceholders } from "../system-prompt/render-placeholders.mjs";
|
|
3
|
+
import { Instruction } from "../system-prompt/instruction.mjs";
|
|
4
|
+
import { SystemPrompt } from "../system-prompt/system-prompt.mjs";
|
|
5
|
+
import { buildValidationReport, judgePrompt, staticLint } from "./prompt-validate.mjs";
|
|
6
|
+
import { defaultPromptsManager, prompts } from "../prompts/prompts-manager.mjs";
|
|
7
|
+
import { PromptNotFoundError, PromptValidationError } from "./errors.mjs";
|
|
8
|
+
import { syncLangfusePrompts, warmLangfuse } from "./prompt-langfuse-sync.mjs";
|
|
9
|
+
|
|
10
|
+
//#region ../@warlock.js/ai/src/prompt/prompt.ts
|
|
11
|
+
/**
|
|
12
|
+
* Build the one-shot judge agent the `validate()` LLM-as-judge pass runs.
|
|
13
|
+
* Name-bearing (the eval `judge` scorer requires a usable agent) and seeded
|
|
14
|
+
* with a strict-JSON instruction so its verdict parses even without an output
|
|
15
|
+
* schema. Kept module-private so the registry's only model dependency is the
|
|
16
|
+
* `agent()` factory.
|
|
17
|
+
*/
|
|
18
|
+
function buildJudgeAgent(model) {
|
|
19
|
+
return agent({
|
|
20
|
+
name: "prompt-quality-judge",
|
|
21
|
+
model,
|
|
22
|
+
systemPrompt: "You are a strict prompt-quality grader. Respond with JSON only: { \"score\": <0..1>, \"passed\": <true|false>, \"reason\": \"<short explanation>\" }."
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Build the `SystemPromptContract` a single {@link PromptVersion} maps to: its
|
|
27
|
+
* `template` becomes one instruction block, and its `required` keys ride along
|
|
28
|
+
* as `meta.required` so the unified manager (and `validate`) can see them.
|
|
29
|
+
*
|
|
30
|
+
* Deliberately ANONYMOUS (no `meta.name`) so the `SystemPrompt` constructor
|
|
31
|
+
* never auto-registers this version into the process-wide `ai.prompts` default
|
|
32
|
+
* manager — each `prompt()` registry owns its OWN isolated
|
|
33
|
+
* {@link PromptsManagerContract}, the single storage shape behind this facade.
|
|
34
|
+
*/
|
|
35
|
+
function versionToContract(version) {
|
|
36
|
+
return new SystemPrompt([new Instruction(version.template)], { ...version.required ? { required: version.required } : {} });
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Legacy `PromptRegistryContract` — now a THIN FACADE over the unified
|
|
40
|
+
* {@link PromptsManagerContract} (`ai.prompts`).
|
|
41
|
+
*
|
|
42
|
+
* **Role.** The store behind `ai.prompt(...)`. Historically it held a private
|
|
43
|
+
* `Map<string, PromptVersion[]>`; it now delegates ALL storage to a private,
|
|
44
|
+
* per-instance {@link PromptsManagerContract}, so there is exactly ONE storage
|
|
45
|
+
* shape across the whole prompt surface: a `SystemPromptContract` keyed by
|
|
46
|
+
* `name@version`. A version's raw `template` string maps to a single
|
|
47
|
+
* instruction block and its `required` keys to `meta.required`.
|
|
48
|
+
*
|
|
49
|
+
* **Responsibility.**
|
|
50
|
+
* - Owns: the legacy method surface (`register` / `add` / `versions` /
|
|
51
|
+
* `resolve` / `validate` / `sync`) and the back-compat behaviors — duplicate
|
|
52
|
+
* version rejection, required-key assertion on `resolve()`, the
|
|
53
|
+
* `{ score, notes }` validation report shape, and the optional Langfuse sync.
|
|
54
|
+
* - Does NOT own: the actual storage (delegated to the internal manager),
|
|
55
|
+
* placeholder rendering (delegated to `renderPlaceholders`), or the unified
|
|
56
|
+
* validation primitives (delegated to `prompt-validate`).
|
|
57
|
+
*
|
|
58
|
+
* Each `prompt(options)` call builds its own isolated manager — so parallel
|
|
59
|
+
* test suites and multi-tenant apps never share mutable global prompt state,
|
|
60
|
+
* exactly as before the unification.
|
|
61
|
+
*
|
|
62
|
+
* Users construct via the `prompt()` factory — `new PromptRegistry()` is not
|
|
63
|
+
* the public API.
|
|
64
|
+
*/
|
|
65
|
+
var PromptRegistry = class {
|
|
66
|
+
constructor(options = {}) {
|
|
67
|
+
this.options = options;
|
|
68
|
+
this.versionMeta = /* @__PURE__ */ new Map();
|
|
69
|
+
this.manager = prompts();
|
|
70
|
+
for (const entry of options.prompts ?? []) this.register(entry);
|
|
71
|
+
if (options.langfuse) warmLangfuse(options.langfuse);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Register a whole entry. Merges onto an existing name's history; a
|
|
75
|
+
* duplicate version label throws {@link PromptValidationError}.
|
|
76
|
+
*/
|
|
77
|
+
register(entry) {
|
|
78
|
+
for (const version of entry.versions) this.add(entry.name, version);
|
|
79
|
+
if (!this.versionMeta.has(entry.name)) this.versionMeta.set(entry.name, []);
|
|
80
|
+
return this;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Add a new version to a name (creating it when absent). A duplicate
|
|
84
|
+
* version label throws {@link PromptValidationError} — never a silent
|
|
85
|
+
* overwrite.
|
|
86
|
+
*/
|
|
87
|
+
add(name, version) {
|
|
88
|
+
const mirror = this.versionMeta.get(name) ?? [];
|
|
89
|
+
if (mirror.some((existing) => existing.version === version.version)) throw new PromptValidationError(`Prompt "${name}" already has a version labeled "${version.version}".`, { context: {
|
|
90
|
+
name,
|
|
91
|
+
version: version.version
|
|
92
|
+
} });
|
|
93
|
+
this.manager.register(versionToContract(version), {
|
|
94
|
+
name,
|
|
95
|
+
version: version.version
|
|
96
|
+
});
|
|
97
|
+
this.versionMeta.set(name, [...mirror, version]);
|
|
98
|
+
return this;
|
|
99
|
+
}
|
|
100
|
+
/** Whether a name is registered. */
|
|
101
|
+
has(name) {
|
|
102
|
+
return this.versionMeta.has(name);
|
|
103
|
+
}
|
|
104
|
+
/** Every registered prompt name, in registration order. */
|
|
105
|
+
list() {
|
|
106
|
+
return [...this.versionMeta.keys()];
|
|
107
|
+
}
|
|
108
|
+
/** Versions registered for a name, latest last. Throws on an unknown name. */
|
|
109
|
+
versions(name) {
|
|
110
|
+
const mirror = this.versionMeta.get(name);
|
|
111
|
+
if (!mirror) throw new PromptNotFoundError(name);
|
|
112
|
+
return [...mirror];
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Resolve + render. Picks the requested or latest version, validates the
|
|
116
|
+
* version's `required` keys against the merged placeholders, then renders by
|
|
117
|
+
* delegating to the shared `renderPlaceholders` over the contract's text.
|
|
118
|
+
*/
|
|
119
|
+
resolve(name, options = {}) {
|
|
120
|
+
const picked = this.pickVersion(name, options.version);
|
|
121
|
+
const placeholders = options.placeholders ?? {};
|
|
122
|
+
this.assertRequired(name, picked, placeholders);
|
|
123
|
+
const text = renderPlaceholders(this.manager.get(name, picked.version).blocks[0]?.text ?? picked.template, placeholders);
|
|
124
|
+
return {
|
|
125
|
+
name,
|
|
126
|
+
version: picked.version,
|
|
127
|
+
text,
|
|
128
|
+
toSystemPrompt: () => new SystemPrompt([new Instruction(text)])
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Quality-check a raw prompt body or a registered prompt (by name). Backed by
|
|
133
|
+
* the unified deterministic validate primitives plus the LLM-as-judge pass,
|
|
134
|
+
* but returns the legacy `{ score, notes }` report shape so existing callers
|
|
135
|
+
* keep working.
|
|
136
|
+
*
|
|
137
|
+
* Always runs the static lint; runs the LLM-as-judge pass too when a model is
|
|
138
|
+
* resolvable. Never throws when no judge model is available.
|
|
139
|
+
*/
|
|
140
|
+
async validate(textOrName, options = {}) {
|
|
141
|
+
const text = this.resolveValidationText(textOrName, options.version);
|
|
142
|
+
const staticNotes = staticLint(text);
|
|
143
|
+
const model = options.model ?? this.options.judgeModel;
|
|
144
|
+
if (!model) return buildValidationReport(staticNotes);
|
|
145
|
+
return buildValidationReport(staticNotes, await judgePrompt(text, model, buildJudgeAgent));
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Synchronize named prompts with Langfuse-prompts. No-op (resolves) when no
|
|
149
|
+
* `langfuse` option was configured. The resolved (rendered) body + the
|
|
150
|
+
* `name@version` label are what is pushed/pulled.
|
|
151
|
+
*/
|
|
152
|
+
async sync() {
|
|
153
|
+
if (!this.options.langfuse) return;
|
|
154
|
+
await syncLangfusePrompts(this.options.langfuse, this.list(), this.snapshotEntries(), (entry) => this.register(entry));
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Pick the requested (or latest) {@link PromptVersion} for a name from the
|
|
158
|
+
* mirror, throwing {@link PromptNotFoundError} on an unknown name or version.
|
|
159
|
+
*/
|
|
160
|
+
pickVersion(name, version) {
|
|
161
|
+
const mirror = this.versionMeta.get(name);
|
|
162
|
+
if (!mirror || mirror.length === 0) throw new PromptNotFoundError(name);
|
|
163
|
+
const picked = version ? mirror.find((candidate) => candidate.version === version) : mirror[mirror.length - 1];
|
|
164
|
+
if (!picked) throw new PromptNotFoundError(name, { context: {
|
|
165
|
+
name,
|
|
166
|
+
version
|
|
167
|
+
} });
|
|
168
|
+
return picked;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Resolve the text `validate()` should grade: a registered name yields its
|
|
172
|
+
* picked version's raw `template`; anything else is treated as the raw body.
|
|
173
|
+
*/
|
|
174
|
+
resolveValidationText(textOrName, version) {
|
|
175
|
+
const mirror = this.versionMeta.get(textOrName);
|
|
176
|
+
if (!mirror || mirror.length === 0) return textOrName;
|
|
177
|
+
const picked = version ? mirror.find((candidate) => candidate.version === version) : mirror[mirror.length - 1];
|
|
178
|
+
return picked ? picked.template : textOrName;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Throw {@link PromptValidationError} listing every `required` key absent
|
|
182
|
+
* from the merged placeholders. A no-op when the version declares none.
|
|
183
|
+
*/
|
|
184
|
+
assertRequired(name, version, placeholders) {
|
|
185
|
+
if (!version.required || version.required.length === 0) return;
|
|
186
|
+
const missing = version.required.filter((key) => placeholders[key] === void 0 || placeholders[key] === null || placeholders[key] === "");
|
|
187
|
+
if (missing.length > 0) throw new PromptValidationError(`Prompt "${name}" version "${version.version}" is missing required placeholder${missing.length > 1 ? "s" : ""}: ${missing.join(", ")}.`, { context: {
|
|
188
|
+
name,
|
|
189
|
+
version: version.version,
|
|
190
|
+
missing
|
|
191
|
+
} });
|
|
192
|
+
}
|
|
193
|
+
/** Snapshot the catalog as `PromptEntry[]` (for the Langfuse push path). */
|
|
194
|
+
snapshotEntries() {
|
|
195
|
+
return [...this.versionMeta.entries()].map(([name, versions]) => ({
|
|
196
|
+
name,
|
|
197
|
+
versions: [...versions]
|
|
198
|
+
}));
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
function promptFactory(first, versionOrTag) {
|
|
202
|
+
if (typeof first === "string") return defaultPromptsManager().get(first, versionOrTag);
|
|
203
|
+
return new PromptRegistry(first);
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Create a versioned prompt registry, OR resolve a globally-registered prompt
|
|
207
|
+
* by name from `ai.prompts`.
|
|
208
|
+
*
|
|
209
|
+
* - `prompt(options?)` → a fresh, isolated {@link PromptRegistryContract}.
|
|
210
|
+
* - `prompt(name, versionOrTag?)` → the `SystemPromptContract` registered under
|
|
211
|
+
* `name` in the process-wide `ai.prompts` manager (latest version by default,
|
|
212
|
+
* or a specific version / pinned tag).
|
|
213
|
+
*/
|
|
214
|
+
const prompt = promptFactory;
|
|
215
|
+
|
|
216
|
+
//#endregion
|
|
217
|
+
export { prompt };
|
|
218
|
+
//# sourceMappingURL=prompt.mjs.map
|