stable-harness 0.0.37 → 0.0.39
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/docs/compatibility-matrix.md +11 -0
- package/node_modules/@stable-harness/adapter-deepagents/dist/src/adapter.d.ts +9 -0
- package/node_modules/@stable-harness/adapter-deepagents/dist/src/adapter.js +1 -0
- package/node_modules/@stable-harness/adapter-deepagents/dist/src/index.d.ts +4 -0
- package/node_modules/@stable-harness/adapter-deepagents/dist/src/index.js +1 -0
- package/node_modules/@stable-harness/adapter-deepagents/dist/src/internal/builtin/permissions.d.ts +17 -0
- package/node_modules/@stable-harness/adapter-deepagents/dist/src/internal/builtin/permissions.js +1 -0
- package/node_modules/@stable-harness/adapter-deepagents/dist/src/internal/builtin/task-inventory.d.ts +13 -0
- package/node_modules/@stable-harness/adapter-deepagents/dist/src/internal/builtin/task-inventory.js +1 -0
- package/node_modules/@stable-harness/adapter-deepagents/dist/src/internal/builtin-args.d.ts +5 -0
- package/node_modules/@stable-harness/adapter-deepagents/dist/src/internal/builtin-args.js +1 -0
- package/node_modules/@stable-harness/adapter-deepagents/dist/src/internal/builtin-call-repair.d.ts +9 -0
- package/node_modules/@stable-harness/adapter-deepagents/dist/src/internal/builtin-call-repair.js +1 -0
- package/node_modules/@stable-harness/adapter-deepagents/dist/src/internal/builtin-tool-policy.d.ts +28 -0
- package/node_modules/@stable-harness/adapter-deepagents/dist/src/internal/builtin-tool-policy.js +1 -0
- package/node_modules/@stable-harness/adapter-deepagents/dist/src/internal/gateway/tool-evidence.d.ts +10 -0
- package/node_modules/@stable-harness/adapter-deepagents/dist/src/internal/gateway/tool-evidence.js +1 -0
- package/node_modules/@stable-harness/adapter-deepagents/dist/src/internal/gateway/tool-failure-events.d.ts +2 -0
- package/node_modules/@stable-harness/adapter-deepagents/dist/src/internal/gateway/tool-failure-events.js +1 -0
- package/node_modules/@stable-harness/adapter-deepagents/dist/src/internal/gateway-tools.d.ts +11 -0
- package/node_modules/@stable-harness/adapter-deepagents/dist/src/internal/gateway-tools.js +1 -0
- package/node_modules/@stable-harness/adapter-deepagents/dist/src/internal/messages.d.ts +9 -0
- package/node_modules/@stable-harness/adapter-deepagents/dist/src/internal/messages.js +1 -0
- package/node_modules/@stable-harness/adapter-deepagents/dist/src/internal/raw-tool-call-parser.d.ts +12 -0
- package/node_modules/@stable-harness/adapter-deepagents/dist/src/internal/raw-tool-call-parser.js +1 -0
- package/node_modules/@stable-harness/adapter-deepagents/dist/src/internal/skill-file-policy.d.ts +10 -0
- package/node_modules/@stable-harness/adapter-deepagents/dist/src/internal/skill-file-policy.js +1 -0
- package/node_modules/@stable-harness/adapter-deepagents/dist/src/internal/stream-events.d.ts +2 -0
- package/node_modules/@stable-harness/adapter-deepagents/dist/src/internal/stream-events.js +1 -0
- package/node_modules/@stable-harness/adapter-deepagents/dist/src/internal/tool-repeat-visibility.d.ts +4 -0
- package/node_modules/@stable-harness/adapter-deepagents/dist/src/internal/tool-repeat-visibility.js +1 -0
- package/node_modules/@stable-harness/adapter-deepagents/dist/src/internal/trace-projection.d.ts +1 -0
- package/node_modules/@stable-harness/adapter-deepagents/dist/src/internal/trace-projection.js +1 -0
- package/node_modules/@stable-harness/adapter-deepagents/dist/src/memory.d.ts +5 -0
- package/node_modules/@stable-harness/adapter-deepagents/dist/src/memory.js +1 -0
- package/node_modules/@stable-harness/adapter-deepagents/dist/src/model-providers.d.ts +4 -0
- package/node_modules/@stable-harness/adapter-deepagents/dist/src/model-providers.js +1 -0
- package/node_modules/@stable-harness/adapter-deepagents/dist/src/retry-policy.d.ts +2 -0
- package/node_modules/@stable-harness/adapter-deepagents/dist/src/retry-policy.js +1 -0
- package/node_modules/@stable-harness/adapter-deepagents/dist/src/types.d.ts +12 -0
- package/node_modules/@stable-harness/adapter-deepagents/dist/src/types.js +1 -0
- package/node_modules/@stable-harness/adapter-deepagents/package.json +26 -0
- package/node_modules/@stable-harness/adapter-langgraph/dist/src/graph.d.ts +3 -0
- package/node_modules/@stable-harness/adapter-langgraph/dist/src/graph.js +1 -0
- package/node_modules/@stable-harness/adapter-langgraph/dist/src/index.d.ts +8 -0
- package/node_modules/@stable-harness/adapter-langgraph/dist/src/index.js +1 -0
- package/node_modules/@stable-harness/adapter-langgraph/dist/src/runtime.d.ts +3 -0
- package/node_modules/@stable-harness/adapter-langgraph/dist/src/runtime.js +1 -0
- package/node_modules/@stable-harness/adapter-langgraph/dist/src/skill-providers.d.ts +29 -0
- package/node_modules/@stable-harness/adapter-langgraph/dist/src/skill-providers.js +1 -0
- package/node_modules/@stable-harness/adapter-langgraph/dist/src/types.d.ts +60 -0
- package/node_modules/@stable-harness/adapter-langgraph/dist/src/types.js +1 -0
- package/node_modules/@stable-harness/adapter-langgraph/package.json +16 -0
- package/node_modules/@stable-harness/core/dist/boundary-scan.d.ts +38 -0
- package/node_modules/@stable-harness/core/dist/boundary-scan.js +1 -0
- package/node_modules/@stable-harness/core/dist/evaluations/index.d.ts +18 -0
- package/node_modules/@stable-harness/core/dist/evaluations/index.js +1 -0
- package/node_modules/@stable-harness/core/dist/execution-contract.d.ts +9 -0
- package/node_modules/@stable-harness/core/dist/execution-contract.js +1 -0
- package/node_modules/@stable-harness/core/dist/index.d.ts +22 -0
- package/node_modules/@stable-harness/core/dist/index.js +1 -0
- package/node_modules/@stable-harness/core/dist/memory-plugins/maintenance.d.ts +42 -0
- package/node_modules/@stable-harness/core/dist/memory-plugins/maintenance.js +1 -0
- package/node_modules/@stable-harness/core/dist/memory-plugins/shared.d.ts +8 -0
- package/node_modules/@stable-harness/core/dist/memory-plugins/shared.js +1 -0
- package/node_modules/@stable-harness/core/dist/memory-plugins.d.ts +25 -0
- package/node_modules/@stable-harness/core/dist/memory-plugins.js +1 -0
- package/node_modules/@stable-harness/core/dist/quality/event-evidence.d.ts +11 -0
- package/node_modules/@stable-harness/core/dist/quality/event-evidence.js +1 -0
- package/node_modules/@stable-harness/core/dist/quality/execution-review.d.ts +2 -0
- package/node_modules/@stable-harness/core/dist/quality/execution-review.js +1 -0
- package/node_modules/@stable-harness/core/dist/quality/index.d.ts +9 -0
- package/node_modules/@stable-harness/core/dist/quality/index.js +1 -0
- package/node_modules/@stable-harness/core/dist/quality/llm-review.d.ts +7 -0
- package/node_modules/@stable-harness/core/dist/quality/llm-review.js +1 -0
- package/node_modules/@stable-harness/core/dist/quality/planning-review.d.ts +2 -0
- package/node_modules/@stable-harness/core/dist/quality/planning-review.js +1 -0
- package/node_modules/@stable-harness/core/dist/quality/profile.d.ts +3 -0
- package/node_modules/@stable-harness/core/dist/quality/profile.js +1 -0
- package/node_modules/@stable-harness/core/dist/quality/recovery-policy.d.ts +11 -0
- package/node_modules/@stable-harness/core/dist/quality/recovery-policy.js +1 -0
- package/node_modules/@stable-harness/core/dist/quality/runtime.d.ts +13 -0
- package/node_modules/@stable-harness/core/dist/quality/runtime.js +1 -0
- package/node_modules/@stable-harness/core/dist/quality/synthesis/fields.d.ts +20 -0
- package/node_modules/@stable-harness/core/dist/quality/synthesis/fields.js +1 -0
- package/node_modules/@stable-harness/core/dist/quality/synthesis/language.d.ts +3 -0
- package/node_modules/@stable-harness/core/dist/quality/synthesis/language.js +1 -0
- package/node_modules/@stable-harness/core/dist/quality/synthesis/observed.d.ts +3 -0
- package/node_modules/@stable-harness/core/dist/quality/synthesis/observed.js +1 -0
- package/node_modules/@stable-harness/core/dist/quality/synthesis.d.ts +2 -0
- package/node_modules/@stable-harness/core/dist/quality/synthesis.js +1 -0
- package/node_modules/@stable-harness/core/dist/quality/types.d.ts +54 -0
- package/node_modules/@stable-harness/core/dist/quality/types.js +1 -0
- package/node_modules/@stable-harness/core/dist/recovery/tool-call.d.ts +28 -0
- package/node_modules/@stable-harness/core/dist/recovery/tool-call.js +1 -0
- package/node_modules/@stable-harness/core/dist/runtime/capabilities.d.ts +48 -0
- package/node_modules/@stable-harness/core/dist/runtime/capabilities.js +1 -0
- package/node_modules/@stable-harness/core/dist/runtime/completion.d.ts +18 -0
- package/node_modules/@stable-harness/core/dist/runtime/completion.js +1 -0
- package/node_modules/@stable-harness/core/dist/runtime/direct-tool-call.d.ts +11 -0
- package/node_modules/@stable-harness/core/dist/runtime/direct-tool-call.js +1 -0
- package/node_modules/@stable-harness/core/dist/runtime/events.d.ts +295 -0
- package/node_modules/@stable-harness/core/dist/runtime/events.js +1 -0
- package/node_modules/@stable-harness/core/dist/runtime/governance/approval-gate.d.ts +8 -0
- package/node_modules/@stable-harness/core/dist/runtime/governance/approval-gate.js +1 -0
- package/node_modules/@stable-harness/core/dist/runtime/governance/sandbox.d.ts +9 -0
- package/node_modules/@stable-harness/core/dist/runtime/governance/sandbox.js +1 -0
- package/node_modules/@stable-harness/core/dist/runtime/inspection/artifacts.d.ts +15 -0
- package/node_modules/@stable-harness/core/dist/runtime/inspection/artifacts.js +1 -0
- package/node_modules/@stable-harness/core/dist/runtime/inspection/methods.d.ts +11 -0
- package/node_modules/@stable-harness/core/dist/runtime/inspection/methods.js +1 -0
- package/node_modules/@stable-harness/core/dist/runtime/inspection/replay.d.ts +6 -0
- package/node_modules/@stable-harness/core/dist/runtime/inspection/replay.js +1 -0
- package/node_modules/@stable-harness/core/dist/runtime/memory.d.ts +29 -0
- package/node_modules/@stable-harness/core/dist/runtime/memory.js +1 -0
- package/node_modules/@stable-harness/core/dist/runtime/persistence/artifacts.d.ts +8 -0
- package/node_modules/@stable-harness/core/dist/runtime/persistence/artifacts.js +1 -0
- package/node_modules/@stable-harness/core/dist/runtime/persistence/inspection.d.ts +4 -0
- package/node_modules/@stable-harness/core/dist/runtime/persistence/inspection.js +1 -0
- package/node_modules/@stable-harness/core/dist/runtime/persistence/queue.d.ts +2 -0
- package/node_modules/@stable-harness/core/dist/runtime/persistence/queue.js +1 -0
- package/node_modules/@stable-harness/core/dist/runtime/persistence/stores.d.ts +3 -0
- package/node_modules/@stable-harness/core/dist/runtime/persistence/stores.js +1 -0
- package/node_modules/@stable-harness/core/dist/runtime/policy/projection.d.ts +11 -0
- package/node_modules/@stable-harness/core/dist/runtime/policy/projection.js +1 -0
- package/node_modules/@stable-harness/core/dist/runtime/policy/tool-invocation.d.ts +45 -0
- package/node_modules/@stable-harness/core/dist/runtime/policy/tool-invocation.js +1 -0
- package/node_modules/@stable-harness/core/dist/runtime/progress-narration.d.ts +38 -0
- package/node_modules/@stable-harness/core/dist/runtime/progress-narration.js +1 -0
- package/node_modules/@stable-harness/core/dist/runtime/selection-repair.d.ts +24 -0
- package/node_modules/@stable-harness/core/dist/runtime/selection-repair.js +1 -0
- package/node_modules/@stable-harness/core/dist/runtime/tool-failure.d.ts +41 -0
- package/node_modules/@stable-harness/core/dist/runtime/tool-failure.js +1 -0
- package/node_modules/@stable-harness/core/dist/runtime/tool-gateway.d.ts +59 -0
- package/node_modules/@stable-harness/core/dist/runtime/tool-gateway.js +1 -0
- package/node_modules/@stable-harness/core/dist/runtime/types.d.ts +191 -0
- package/node_modules/@stable-harness/core/dist/runtime/types.js +1 -0
- package/node_modules/@stable-harness/core/dist/runtime.d.ts +21 -0
- package/node_modules/@stable-harness/core/dist/runtime.js +1 -0
- package/node_modules/@stable-harness/core/dist/spec-driven/config.d.ts +4 -0
- package/node_modules/@stable-harness/core/dist/spec-driven/config.js +1 -0
- package/node_modules/@stable-harness/core/dist/spec-driven/events.d.ts +11 -0
- package/node_modules/@stable-harness/core/dist/spec-driven/events.js +1 -0
- package/node_modules/@stable-harness/core/dist/spec-driven/index.d.ts +4 -0
- package/node_modules/@stable-harness/core/dist/spec-driven/index.js +1 -0
- package/node_modules/@stable-harness/core/dist/spec-driven/lifecycle.d.ts +11 -0
- package/node_modules/@stable-harness/core/dist/spec-driven/lifecycle.js +1 -0
- package/node_modules/@stable-harness/core/dist/spec-driven/types.d.ts +38 -0
- package/node_modules/@stable-harness/core/dist/spec-driven/types.js +1 -0
- package/node_modules/@stable-harness/core/dist/trace.d.ts +21 -0
- package/node_modules/@stable-harness/core/dist/trace.js +1 -0
- package/node_modules/@stable-harness/core/dist/types.d.ts +145 -0
- package/node_modules/@stable-harness/core/dist/types.js +1 -0
- package/node_modules/@stable-harness/core/dist/workflows/index.d.ts +70 -0
- package/node_modules/@stable-harness/core/dist/workflows/index.js +1 -0
- package/node_modules/@stable-harness/core/dist/workflows/runtime.d.ts +12 -0
- package/node_modules/@stable-harness/core/dist/workflows/runtime.js +1 -0
- package/node_modules/@stable-harness/core/dist/workspace/tool-quality.d.ts +22 -0
- package/node_modules/@stable-harness/core/dist/workspace/tool-quality.js +1 -0
- package/node_modules/@stable-harness/core/dist/workspace/types.d.ts +134 -0
- package/node_modules/@stable-harness/core/dist/workspace/types.js +1 -0
- package/node_modules/@stable-harness/core/package.json +18 -0
- package/node_modules/@stable-harness/governance/dist/src/approval-queue.d.ts +2 -0
- package/node_modules/@stable-harness/governance/dist/src/approval-queue.js +1 -0
- package/node_modules/@stable-harness/governance/dist/src/index.d.ts +4 -0
- package/node_modules/@stable-harness/governance/dist/src/index.js +1 -0
- package/node_modules/@stable-harness/governance/dist/src/policy-engine.d.ts +2 -0
- package/node_modules/@stable-harness/governance/dist/src/policy-engine.js +1 -0
- package/node_modules/@stable-harness/governance/dist/src/skill-candidates.d.ts +2 -0
- package/node_modules/@stable-harness/governance/dist/src/skill-candidates.js +1 -0
- package/node_modules/@stable-harness/governance/dist/src/types.d.ts +101 -0
- package/node_modules/@stable-harness/governance/dist/src/types.js +1 -0
- package/node_modules/@stable-harness/governance/package.json +12 -0
- package/node_modules/@stable-harness/memory/dist/src/index.d.ts +9 -0
- package/node_modules/@stable-harness/memory/dist/src/index.js +1 -0
- package/node_modules/@stable-harness/memory/dist/src/langmem-service.d.ts +8 -0
- package/node_modules/@stable-harness/memory/dist/src/langmem-service.js +1 -0
- package/node_modules/@stable-harness/memory/dist/src/maintenance.d.ts +2 -0
- package/node_modules/@stable-harness/memory/dist/src/maintenance.js +1 -0
- package/node_modules/@stable-harness/memory/dist/src/persistence.d.ts +4 -0
- package/node_modules/@stable-harness/memory/dist/src/persistence.js +1 -0
- package/node_modules/@stable-harness/memory/dist/src/policy.d.ts +2 -0
- package/node_modules/@stable-harness/memory/dist/src/policy.js +1 -0
- package/node_modules/@stable-harness/memory/dist/src/provider.d.ts +50 -0
- package/node_modules/@stable-harness/memory/dist/src/provider.js +1 -0
- package/node_modules/@stable-harness/memory/dist/src/store.d.ts +5 -0
- package/node_modules/@stable-harness/memory/dist/src/store.js +1 -0
- package/node_modules/@stable-harness/memory/dist/src/types.d.ts +138 -0
- package/node_modules/@stable-harness/memory/dist/src/types.js +1 -0
- package/node_modules/@stable-harness/memory/package.json +12 -0
- package/node_modules/@stable-harness/protocols/dist/src/http-server.d.ts +3 -0
- package/node_modules/@stable-harness/protocols/dist/src/http-server.js +1 -0
- package/node_modules/@stable-harness/protocols/dist/src/in-process-client.d.ts +2 -0
- package/node_modules/@stable-harness/protocols/dist/src/in-process-client.js +1 -0
- package/node_modules/@stable-harness/protocols/dist/src/index.d.ts +4 -0
- package/node_modules/@stable-harness/protocols/dist/src/index.js +1 -0
- package/node_modules/@stable-harness/protocols/dist/src/openai-compatible.d.ts +9 -0
- package/node_modules/@stable-harness/protocols/dist/src/openai-compatible.js +1 -0
- package/node_modules/@stable-harness/protocols/dist/src/openai-payload.d.ts +74 -0
- package/node_modules/@stable-harness/protocols/dist/src/openai-payload.js +1 -0
- package/node_modules/@stable-harness/protocols/dist/src/openai-stream.d.ts +39 -0
- package/node_modules/@stable-harness/protocols/dist/src/openai-stream.js +1 -0
- package/node_modules/@stable-harness/protocols/package.json +15 -0
- package/node_modules/@stable-harness/tool-gateway/dist/src/argument-guard.d.ts +33 -0
- package/node_modules/@stable-harness/tool-gateway/dist/src/argument-guard.js +1 -0
- package/node_modules/@stable-harness/tool-gateway/dist/src/in-memory.d.ts +4 -0
- package/node_modules/@stable-harness/tool-gateway/dist/src/in-memory.js +1 -0
- package/node_modules/@stable-harness/tool-gateway/dist/src/index.d.ts +7 -0
- package/node_modules/@stable-harness/tool-gateway/dist/src/index.js +1 -0
- package/node_modules/@stable-harness/tool-gateway/dist/src/module-loader.d.ts +13 -0
- package/node_modules/@stable-harness/tool-gateway/dist/src/module-loader.js +1 -0
- package/node_modules/@stable-harness/tool-gateway/dist/src/schema-validation.d.ts +3 -0
- package/node_modules/@stable-harness/tool-gateway/dist/src/schema-validation.js +1 -0
- package/node_modules/@stable-harness/tool-gateway/dist/src/types.d.ts +79 -0
- package/node_modules/@stable-harness/tool-gateway/dist/src/types.js +1 -0
- package/node_modules/@stable-harness/tool-gateway/package.json +15 -0
- package/node_modules/@stable-harness/workspace-yaml/dist/boundary-scan.d.ts +3 -0
- package/node_modules/@stable-harness/workspace-yaml/dist/boundary-scan.js +1 -0
- package/node_modules/@stable-harness/workspace-yaml/dist/discovery.d.ts +4 -0
- package/node_modules/@stable-harness/workspace-yaml/dist/discovery.js +1 -0
- package/node_modules/@stable-harness/workspace-yaml/dist/documents.d.ts +16 -0
- package/node_modules/@stable-harness/workspace-yaml/dist/documents.js +1 -0
- package/node_modules/@stable-harness/workspace-yaml/dist/evaluations.d.ts +9 -0
- package/node_modules/@stable-harness/workspace-yaml/dist/evaluations.js +1 -0
- package/node_modules/@stable-harness/workspace-yaml/dist/index.d.ts +1 -0
- package/node_modules/@stable-harness/workspace-yaml/dist/index.js +1 -0
- package/node_modules/@stable-harness/workspace-yaml/dist/loader.d.ts +2 -0
- package/node_modules/@stable-harness/workspace-yaml/dist/loader.js +1 -0
- package/node_modules/@stable-harness/workspace-yaml/dist/workflows.d.ts +16 -0
- package/node_modules/@stable-harness/workspace-yaml/dist/workflows.js +1 -0
- package/node_modules/@stable-harness/workspace-yaml/package.json +16 -0
- package/package.json +33 -11
- package/packages/adapter-deepagents/dist/src/adapter.js +1 -1
- package/packages/adapter-deepagents/dist/src/internal/builtin/permissions.d.ts +17 -0
- package/packages/adapter-deepagents/dist/src/internal/builtin/permissions.js +1 -0
- package/packages/adapter-deepagents/dist/src/internal/builtin/task-inventory.d.ts +13 -0
- package/packages/adapter-deepagents/dist/src/internal/builtin/task-inventory.js +1 -0
- package/packages/adapter-deepagents/dist/src/internal/builtin-tool-policy.d.ts +2 -13
- package/packages/adapter-deepagents/dist/src/internal/builtin-tool-policy.js +1 -1
- package/packages/adapter-deepagents/dist/src/internal/gateway-tools.d.ts +1 -23
- package/packages/adapter-deepagents/dist/src/internal/gateway-tools.js +1 -1
- package/packages/adapter-deepagents/dist/src/internal/tool-repeat-visibility.d.ts +1 -1
- package/packages/adapter-deepagents/dist/src/internal/tool-repeat-visibility.js +1 -1
- package/packages/adapter-deepagents/dist/src/internal/trace-projection.d.ts +1 -16
- package/packages/adapter-deepagents/dist/src/internal/trace-projection.js +1 -1
- package/packages/adapter-deepagents/package.json +4 -6
- package/packages/adapter-langgraph/package.json +1 -1
- package/packages/cli/package.json +1 -1
- package/packages/core/dist/index.d.ts +2 -0
- package/packages/core/dist/index.js +1 -1
- package/packages/core/dist/quality/profile.js +1 -1
- package/packages/core/dist/quality/synthesis/fields.d.ts +3 -2
- package/packages/core/dist/quality/synthesis/fields.js +1 -1
- package/packages/core/dist/quality/synthesis/observed.js +1 -1
- package/packages/core/dist/quality/synthesis.js +1 -1
- package/packages/core/dist/quality/types.d.ts +2 -0
- package/packages/core/dist/runtime/capabilities.d.ts +1 -0
- package/packages/core/dist/runtime/capabilities.js +1 -1
- package/packages/core/dist/runtime/policy/projection.d.ts +11 -0
- package/packages/core/dist/runtime/policy/projection.js +1 -0
- package/packages/core/dist/runtime/policy/tool-invocation.d.ts +45 -0
- package/packages/core/dist/runtime/policy/tool-invocation.js +1 -0
- package/packages/core/dist/runtime.js +1 -1
- package/packages/core/dist/trace.d.ts +6 -0
- package/packages/core/dist/trace.js +1 -1
- package/packages/core/dist/types.d.ts +1 -0
- package/packages/core/package.json +1 -1
- package/packages/evaluation/package.json +1 -1
- package/packages/protocols/package.json +1 -1
- package/packages/tool-gateway/package.json +1 -1
- package/packages/workspace-yaml/package.json +1 -1
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@stable-harness/tool-gateway",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"files": [
|
|
6
|
+
"dist/**/*.js",
|
|
7
|
+
"dist/**/*.d.ts",
|
|
8
|
+
"package.json"
|
|
9
|
+
],
|
|
10
|
+
"main": "dist/src/index.js",
|
|
11
|
+
"types": "dist/src/index.d.ts",
|
|
12
|
+
"peerDependencies": {
|
|
13
|
+
"@botbotgo/better-call": "^0.1.58"
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { CompiledWorkspace, WorkspaceBoundaryDiagnostic } from "@stable-harness/core";
|
|
2
|
+
export declare function scanWorkspaceBoundaries(workspace: CompiledWorkspace): WorkspaceBoundaryDiagnostic[];
|
|
3
|
+
export declare function assertWorkspaceBoundaryDiagnostics(diagnostics: WorkspaceBoundaryDiagnostic[]): void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{assertBoundaryPolicyDiagnostics as s,checkBoundaryScanPolicy as o,scanAgentBoundary as t}from"@stable-harness/core";export function scanWorkspaceBoundaries(s){const e=s.runtime.workspaceValidation?.boundaryScan;if(!0!==e?.enabled)return[];const a=t({subagents:readSubagents(s),skills:readSkills(s),tools:readTools(s)});return o(a,e)}export function assertWorkspaceBoundaryDiagnostics(o){s(o)}function readSubagents(s){const o=s.agents.get(s.runtime.defaultAgentId);return(o?.subagents??[]).map(o=>s.agents.get(o)).filter(s=>Boolean(s)).map(s=>({id:s.id,description:s.description,text:s.systemPrompt,tools:s.tools,skills:s.skills,subagents:s.subagents,locations:s.sourcePath?[s.sourcePath]:[]}))}function readSkills(s){return[...s.skills.values()].map(s=>({id:s.id,description:s.description,tools:s.allowedTools,locations:[s.path]}))}function readTools(s){return[...s.tools.values()].map(s=>({id:s.id,description:s.description,text:s.id,locations:s.sourcePath?[s.sourcePath]:[]}))}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { WorkspaceSkill, WorkspaceTool } from "@stable-harness/core";
|
|
2
|
+
export declare function listYamlFiles(root: string): Promise<string[]>;
|
|
3
|
+
export declare function discoverModuleTools(workspaceRoot: string): Promise<WorkspaceTool[]>;
|
|
4
|
+
export declare function discoverSkills(workspaceRoot: string): Promise<WorkspaceSkill[]>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{readdir as t,readFile as e}from"node:fs/promises";import r from"node:path";import{parseAllDocuments as i}from"yaml";export async function listYamlFiles(e){const i=await t(e,{withFileTypes:!0});return(await Promise.all(i.map(async t=>{const i=r.join(e,t.name);return t.isDirectory()?listYamlFiles(i):t.isFile()&&/\.ya?ml$/iu.test(t.name)?[i]:[]}))).flat().sort()}export async function discoverModuleTools(i){const o=r.join(i,"resources","tools");let n;try{n=await t(o,{withFileTypes:!0})}catch{return[]}return(await Promise.all(n.filter(t=>t.isFile()&&t.name.endsWith(".mjs")&&!t.name.startsWith("_")).map(t=>async function discoverModuleToolFile(t){const i=await e(t,"utf8"),o=[...i.matchAll(/export\s+const\s+([A-Za-z_][A-Za-z0-9_]*)\s*=\s*tool\s*\(/gu)].map(t=>t[1]).filter(t=>"default"!==t);return(o.length>0?o:[r.basename(t,".mjs")]).map(e=>({id:e,sourcePath:t,...readModuleToolDescription(i,e)}))}(r.join(o,t.name))))).flat()}export async function discoverSkills(o){const n=r.join(o,"resources","skills");let s;try{s=await t(n,{withFileTypes:!0})}catch{return[]}return(await Promise.all(s.filter(t=>t.isDirectory()).map(t=>async function readSkill(t,o){const n=r.join(t,"SKILL.md");let s;try{s=await e(n,"utf8")}catch{return}const a=function readFrontMatter(t){const e=t.match(/^---\n([\s\S]*?)\n---/u);if(!e)return{};const r=i(e[1]).at(0)?.toJSON();return"object"!=typeof r||null===r||Array.isArray(r)?{}:r}(s);return{id:readOptionalString(a.name)??o,path:n,...readOptionalString(a.description)?{description:readOptionalString(a.description)}:{},allowedTools:(l=a["allowed-tools"],Array.isArray(l)?l.filter(t=>"string"==typeof t&&t.trim().length>0):[])};var l}(r.join(n,t.name),t.name)))).filter(t=>Boolean(t))}function readModuleToolDescription(t,e){const r=t.match(new RegExp(`export\\s+const\\s+${function escapeRegExp(t){return t.replace(/[.*+?^${}()|[\]\\]/gu,"\\$&")}(e)}\\s*=\\s*tool\\s*\\(\\s*\\{[\\s\\S]{0,4000}?description\\s*:\\s*(["'\`])([\\s\\S]*?)\\1`,"u")),i=t.match(/description\s*:\s*(["'`])([\s\S]*?)\1/u),o=function normalizeDescription(t){const e=t?.replace(/\\n/gu," ").replace(/\s+/gu," ").trim();return e||void 0}(r?.[2]??i?.[2]);return o?{description:o}:{}}function readOptionalString(t){return"string"==typeof t&&t.trim()?t.trim():void 0}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { WorkspaceAgent, WorkspaceMemory, WorkspaceModel, WorkspaceRuntimePolicy, WorkspaceTool } from "@stable-harness/core";
|
|
2
|
+
export type RawDocument = {
|
|
3
|
+
apiVersion?: unknown;
|
|
4
|
+
kind?: unknown;
|
|
5
|
+
metadata?: {
|
|
6
|
+
name?: unknown;
|
|
7
|
+
description?: unknown;
|
|
8
|
+
};
|
|
9
|
+
spec?: unknown;
|
|
10
|
+
};
|
|
11
|
+
export declare function compileRuntime(document: RawDocument): WorkspaceRuntimePolicy;
|
|
12
|
+
export declare function compileAgent(document: RawDocument, sourcePath: string): WorkspaceAgent;
|
|
13
|
+
export declare function compileModel(document: RawDocument): WorkspaceModel;
|
|
14
|
+
export declare function compileModelSpec(spec: Record<string, unknown>, fallback?: string): WorkspaceModel;
|
|
15
|
+
export declare function compileTool(document: RawDocument, sourcePath?: string): WorkspaceTool;
|
|
16
|
+
export declare function compileMemory(document: RawDocument): WorkspaceMemory;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{assertSpecDrivenWorkflowPolicy as e,createSpecDrivenWorkflowPolicy as r}from"@stable-harness/core";function assertRecord(e,r){if("object"!=typeof e||null===e||Array.isArray(e))throw new Error(`${r} must be an object`);return e}function readName(e,r){const t=e.metadata?.name;if("string"==typeof t&&t.trim())return t.trim();if(r)return r;throw new Error(`Document kind ${String(e.kind)} requires metadata.name`)}function readDescription(e){const r=e.metadata?.description;return"string"==typeof r&&r.trim()?r.trim():void 0}function readOptionalString(e){return"string"==typeof e&&e.trim()?e.trim():void 0}function toStringArray(e){return Array.isArray(e)?e.filter(e=>"string"==typeof e&&e.trim().length>0):[]}function resolveValue(e){if("string"!=typeof e)return e;const r=e.match(/^\$\{env:([A-Za-z_][A-Za-z0-9_]*)(?::-(.*))?\}$/u);return r?process.env[r[1]]??r[2]??"":e}export function compileRuntime(e){const r=assertRecord(e.spec,"Runtime.spec"),t=assertRecord(r.routing??{},"Runtime.spec.routing");return{defaultAgentId:"string"==typeof t.defaultAgentId&&t.defaultAgentId.trim()?t.defaultAgentId.trim():"orchestra",...void 0!==t.routes?{routes:readAgentRoutes(t.routes)}:{},...readOptionalString(r.workspaceId)?{workspaceId:readOptionalString(r.workspaceId)}:{},...readOptionalString(r.profile)?{profile:readOptionalString(r.profile)}:{},...void 0!==r.adapters?{adapters:readAdapters(r.adapters)}:{},..."object"==typeof r.workflowRouting&&r.workflowRouting?{workflowRouting:readWorkflowRouting(r.workflowRouting)}:{},..."object"==typeof r.specDrivenWorkflow&&r.specDrivenWorkflow?{specDrivenWorkflow:readSpecDrivenWorkflow(r.specDrivenWorkflow)}:{},..."object"==typeof r.approvals&&r.approvals?{approvals:r.approvals}:{},..."object"==typeof r.recovery&&r.recovery?{recovery:r.recovery}:{},..."object"==typeof r.retry&&r.retry?{retry:r.retry}:{},..."object"==typeof r.toolGateway&&r.toolGateway?{toolGateway:r.toolGateway}:{},..."object"==typeof r.memory&&r.memory?{memory:r.memory}:{},..."object"==typeof r.protocols&&r.protocols?{protocols:r.protocols}:{},..."object"==typeof r.progress&&r.progress?{progress:r.progress}:{},..."object"==typeof r.cli&&r.cli?{cli:r.cli}:{},..."string"==typeof r.quality||"object"==typeof r.quality&&r.quality?{quality:r.quality}:{},..."object"==typeof r.workspaceValidation&&r.workspaceValidation?{workspaceValidation:r.workspaceValidation}:{},..."object"==typeof r.responseLanguage&&r.responseLanguage?{responseLanguage:r.responseLanguage}:{},..."object"==typeof r.responsePresentation&&r.responsePresentation?{responsePresentation:r.responsePresentation}:{}}}function readAgentRoutes(e){if(!Array.isArray(e))throw new Error("Runtime.spec.routing.routes must be an array");return e.map(e=>{const r=assertRecord(e,"Runtime.spec.routing.routes[]"),t=readOptionalString(r.id),o=readOptionalString(r.agentId);if(!t||!o)throw new Error("Runtime.spec.routing.routes[] requires id and agentId");const n=void 0===r.keywords?void 0:function assertStringArray(e,r){if(!Array.isArray(e))throw new Error(`${r} must be an array`);return e.map(e=>{if("string"!=typeof e||!e.trim())throw new Error(`${r} must contain non-empty strings`);return e.trim()})}(r.keywords,"Runtime.spec.routing.routes[].keywords"),i=readOptionalString(r.pattern);if(!(n&&0!==n.length||i))throw new Error("Runtime.spec.routing.routes[] requires keywords or pattern");return{id:t,agentId:o,...n&&n.length>0?{keywords:n}:{},...i?{pattern:i}:{},...readOptionalString(r.description)?{description:readOptionalString(r.description)}:{}}})}function readSpecDrivenWorkflow(t){const o=assertRecord(t,"Runtime.spec.specDrivenWorkflow"),n=r({enabled:!0===o.enabled,constitution:readOptionalString(o.constitution),artifactsDir:readOptionalString(o.artifactsDir),phases:void 0===o.phases?void 0:readSpecDrivenPhases(o.phases),..."object"==typeof o.gates&&o.gates?{gates:o.gates}:{},..."object"==typeof o.config&&o.config?{config:o.config}:{}});return e(n),n}function readSpecDrivenPhases(e){if(!Array.isArray(e))throw new Error("Runtime.spec.specDrivenWorkflow.phases must be an array");return e.map(e=>{if("string"==typeof e&&e.trim())return{id:e.trim()};const r=assertRecord(e,"Runtime.spec.specDrivenWorkflow.phases[]"),t=readOptionalString(r.id);if(!t)throw new Error("Runtime.spec.specDrivenWorkflow.phases[] requires id");return{id:t,...readOptionalString(r.artifactKind)?{artifactKind:readOptionalString(r.artifactKind)}:{},..."boolean"==typeof r.required?{required:r.required}:{},...readOptionalString(r.gate)?{gate:readOptionalString(r.gate)}:{},..."object"==typeof r.config&&r.config?{config:r.config}:{}}})}export function compileAgent(e,r){const t=assertRecord(e.spec,"Agent.spec"),o=readName(e),n=readOptionalString(t.backend);if(!n)throw new Error(`Agent ${o} requires spec.backend`);const i="object"==typeof t.config&&t.config?t.config:{},a="string"==typeof t.systemPrompt?t.systemPrompt:"string"==typeof i.systemPrompt?i.systemPrompt:void 0;return{id:o,...readDescription(e)?{description:readDescription(e)}:{},sourcePath:r,backend:n,..."string"==typeof t.modelRef&&t.modelRef.trim()?{modelRef:(s=t.modelRef,s.replace(/^[^/]+\//u,""))}:{},...void 0!==a?{systemPrompt:a}:{},tools:toStringArray(t.tools),skills:toStringArray(t.skills),memory:Array.isArray(t.memory)?t.memory:[],subagents:toStringArray(t.subagents),...void 0!==t.edges?{edges:readAgentEdges(t.edges,o)}:{},config:i};var s}export function compileModel(e){return compileModelSpec(assertRecord(e.spec,"Model.spec"),readName(e))}export function compileModelSpec(e,r){const t="string"==typeof e.name&&e.name.trim()?e.name.trim():r??"default",o=resolveValue(e.provider),n=resolveValue(e.model),i="string"==typeof o&&o.trim()?o.trim():"unknown",a="string"==typeof n&&n.trim()?n.trim():t,s={...e};return delete s.name,delete s.provider,delete s.model,{id:t,provider:i,model:a,config:Object.fromEntries(Object.entries(s).map(([e,r])=>[e,resolveValue(r)]))}}export function compileTool(e,r){const t=assertRecord(e.spec,"Tool.spec");return{id:readName(e),...r?{sourcePath:r}:{},..."string"==typeof t.description?{description:t.description}:{},...void 0!==t.schema?{schema:t.schema}:{},...void 0!==t.outputSchema?{outputSchema:t.outputSchema}:{},..."object"==typeof t.metadata&&t.metadata?{metadata:t.metadata}:{},..."string"==typeof t.implementation?{implementation:t.implementation}:{}}}export function compileMemory(e){const r=assertRecord(e.spec,"Memory.spec"),t=readName(e),o={...r};return delete o.provider,delete o.profile,delete o.mode,delete o.enabled,delete o.prompts,{id:t,provider:readOptionalString(r.provider)??"langmem",...readOptionalString(r.profile)?{profile:readOptionalString(r.profile)}:{},...readOptionalString(r.mode)?{mode:readOptionalString(r.mode)}:{},enabled:!1!==r.enabled,..."object"==typeof r.prompts&&r.prompts?{prompts:readMemoryPrompts(r.prompts)}:{},...Object.keys(o).length>0?{config:o}:{}}}function readWorkflowRouting(e){const r=assertRecord(e,"Runtime.spec.workflowRouting"),t=void 0===r.routes?void 0:function readWorkflowRoutes(e){if(!Array.isArray(e))throw new Error("Runtime.spec.workflowRouting.routes must be an array");return e.map(e=>{const r=assertRecord(e,"Runtime.spec.workflowRouting.routes[]"),t=readOptionalString(r.id),o=readOptionalString(r.workflowId);if(!t||!o)throw new Error("Runtime.spec.workflowRouting.routes[] requires id and workflowId");return{id:t,workflowId:o,...readOptionalString(r.description)?{description:readOptionalString(r.description)}:{},..."object"==typeof r.metadata&&r.metadata?{metadata:r.metadata}:{}}})}(r.routes);return{...readOptionalString(r.defaultWorkflowId)?{defaultWorkflowId:readOptionalString(r.defaultWorkflowId)}:{},...t?{routes:t}:{}}}function readAdapters(e){if(!Array.isArray(e))throw new Error("Runtime.spec.adapters must be an array");return e.map(readAdapter)}function readAgentEdges(e,r){if(!Array.isArray(e))throw new Error(`Agent ${r} spec.edges must be an array`);return e.map(e=>{const t=assertRecord(e,`Agent ${r} spec.edges[]`),o=readOptionalString(t.from),n=readOptionalString(t.to);if(!o||!n)throw new Error(`Agent ${r} spec.edges[] requires from and to`);return{from:o,to:n,...readOptionalString(t.condition)?{condition:readOptionalString(t.condition)}:{}}})}function readAdapter(e){if("string"==typeof e&&e.trim())return{name:e.trim()};const r=assertRecord(e,"Runtime.spec.adapters[]"),t=readOptionalString(r.name)??readOptionalString(r.id)??readOptionalString(r.backend);if(!t)throw new Error("Runtime.spec.adapters[] requires name");return{name:t,..."boolean"==typeof r.enabled?{enabled:r.enabled}:{},..."object"==typeof r.config&&r.config?{config:r.config}:{}}}function readMemoryPrompts(e){const r=assertRecord(e,"Memory.spec.prompts");return{...readOptionalString(r.semantic)?{semantic:readOptionalString(r.semantic)}:{},...readOptionalString(r.episodic)?{episodic:readOptionalString(r.episodic)}:{},...readOptionalString(r.procedural)?{procedural:readOptionalString(r.procedural)}:{}}}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { WorkspaceAgent, WorkspaceEvaluation, WorkspaceTool, WorkspaceWorkflow } from "@stable-harness/core";
|
|
2
|
+
import type { RawDocument } from "./documents.js";
|
|
3
|
+
export declare function compileEvaluation(document: RawDocument, sourcePath: string): WorkspaceEvaluation;
|
|
4
|
+
export declare function validateEvaluations(input: {
|
|
5
|
+
evaluations: Map<string, WorkspaceEvaluation>;
|
|
6
|
+
agents: Map<string, WorkspaceAgent>;
|
|
7
|
+
tools: Map<string, WorkspaceTool>;
|
|
8
|
+
workflows: Map<string, WorkspaceWorkflow>;
|
|
9
|
+
}): void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export function compileEvaluation(r,t){const e=assertRecord(r.spec,"Evaluation.spec"),o=function readName(r){const t=r.metadata?.name;if("string"==typeof t&&t.trim())return t.trim();throw new Error("Evaluation document requires metadata.name")}(r);return{id:o,...readDescription(r)?{description:readDescription(r)}:{},sourcePath:t,...readString(e.suite)?{suite:readString(e.suite)}:{},cases:readCases(e.cases,o),..."object"==typeof e.config&&e.config?{config:e.config}:{}}}export function validateEvaluations(r){for(const t of r.evaluations.values())for(const e of t.cases){if(e.agentId&&!r.agents.has(e.agentId))throw new Error(`Evaluation ${t.id} case ${e.id} references unknown agent ${e.agentId}`);if(e.workflowId&&!r.workflows.has(e.workflowId))throw new Error(`Evaluation ${t.id} case ${e.id} references unknown workflow ${e.workflowId}`);for(const o of e.tools??[])if(!r.tools.has(o))throw new Error(`Evaluation ${t.id} case ${e.id} references unknown tool ${o}`)}}function readCases(r,t){if(!Array.isArray(r)||0===r.length)throw new Error(`Evaluation ${t} spec.cases must be a non-empty array`);return r.map(r=>{const e=assertRecord(r,`Evaluation ${t} spec.cases[]`),o=readString(e.id);if(!o)throw new Error(`Evaluation ${t} spec.cases[] requires id`);return{id:o,...readString(e.description)?{description:readString(e.description)}:{},...readString(e.agentId)?{agentId:readString(e.agentId)}:{},...readString(e.workflowId)?{workflowId:readString(e.workflowId)}:{},...void 0!==e.input?{input:e.input}:{},...Array.isArray(e.tools)?{tools:e.tools.filter(r=>"string"==typeof r&&r.trim().length>0)}:{},..."object"==typeof e.assertions&&e.assertions?{assertions:e.assertions}:{},..."object"==typeof e.metadata&&e.metadata?{metadata:e.metadata}:{}}})}function assertRecord(r,t){if("object"!=typeof r||null===r||Array.isArray(r))throw new Error(`${t} must be an object`);return r}function readDescription(r){return readString(r.metadata?.description)}function readString(r){return"string"==typeof r&&r.trim()?r.trim():void 0}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./loader.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export*from"./loader.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{readFile as o}from"node:fs/promises";import e from"node:path";import{parseAllDocuments as s}from"yaml";import{discoverModuleTools as t,discoverSkills as r,listYamlFiles as a}from"./discovery.js";import{compileAgent as n,compileMemory as l,compileModel as i,compileModelSpec as c,compileRuntime as f,compileTool as u}from"./documents.js";import{compileWorkflow as m,validateWorkflows as w}from"./workflows.js";import{compileEvaluation as d,validateEvaluations as p}from"./evaluations.js";import{assertWorkspaceBoundaryDiagnostics as k,scanWorkspaceBoundaries as g}from"./boundary-scan.js";import{assertWorkspaceToolQualityDiagnostics as v,scanWorkspaceToolQuality as y}from"@stable-harness/core";export async function loadWorkspaceFromYaml(n){const l=e.join(n,"config"),i=await a(l),c=[],f=new Map,u=new Map,m=new Map,d=new Map,M=new Map,W=new Map,h=new Map;for(const e of i){const t=await o(e,"utf8"),r=s(t).map(o=>o.toJSON()).filter(o=>null!==o);for(const o of r)collectWorkspaceDocument(o,e,{runtimeDocs:c,agents:f,models:u,tools:m,memories:M,workflows:W,evaluations:h})}for(const o of await t(n))m.has(o.id)||m.set(o.id,o);for(const o of await r(n))d.set(o.id,o);const R=c.at(-1)??{defaultAgentId:"orchestra"};w({workflows:W,agents:f,tools:m,skills:d}),p({evaluations:h,agents:f,tools:m,workflows:W}),function validateAgentRouting(o,e){for(const s of o.routes??[])if(!e.has(s.agentId))throw new Error(`Runtime routing route ${s.id} references unknown agent ${s.agentId}`)}(R,f),function validateWorkflowRouting(o,e){const s=o.workflowRouting;if(s){if(s.defaultWorkflowId&&!e.has(s.defaultWorkflowId))throw new Error(`Runtime workflowRouting.defaultWorkflowId references unknown workflow ${s.defaultWorkflowId}`);for(const o of s.routes??[])if(!e.has(o.workflowId))throw new Error(`Runtime workflowRouting route ${o.id} references unknown workflow ${o.workflowId}`)}}(R,W);const A={root:n,runtime:R,agents:f,models:u,tools:m,skills:d,memories:M,workflows:W,evaluations:h},I=g(A);k(I);const O=y(A,R.workspaceValidation?.toolQuality);return v(O),{...A,...[...I??[],...O].length>0?{diagnostics:[...I,...O]}:{}}}function collectWorkspaceDocument(o,e,s){if("string"==typeof o.kind)switch(o.kind){case"Runtime":return void s.runtimeDocs.push(f(o));case"Agent":return collectOne(s.agents,n(o,e));case"Model":return collectOne(s.models,i(o));case"Models":return function collectModelSpecs(o,e){if(Array.isArray(o.spec))for(const s of o.spec)if("object"==typeof s&&null!==s&&!Array.isArray(s)){const o=c(s);e.set(o.id,o)}}(o,s.models);case"Tool":return collectOne(s.tools,u(o,e));case"Memory":return collectOne(s.memories,l(o));case"Workflow":return collectOne(s.workflows,m(o,e));case"Evaluation":return collectOne(s.evaluations,d(o,e));default:return}}function collectOne(o,e){o.set(e.id,e)}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { WorkspaceAgent, WorkspaceSkill, WorkspaceTool, WorkspaceWorkflow } from "@stable-harness/core";
|
|
2
|
+
type RawDocument = {
|
|
3
|
+
metadata?: {
|
|
4
|
+
name?: unknown;
|
|
5
|
+
description?: unknown;
|
|
6
|
+
};
|
|
7
|
+
spec?: unknown;
|
|
8
|
+
};
|
|
9
|
+
export declare function compileWorkflow(document: RawDocument, sourcePath: string): WorkspaceWorkflow;
|
|
10
|
+
export declare function validateWorkflows(input: {
|
|
11
|
+
workflows: Map<string, WorkspaceWorkflow>;
|
|
12
|
+
agents: Map<string, WorkspaceAgent>;
|
|
13
|
+
tools: Map<string, WorkspaceTool>;
|
|
14
|
+
skills: Map<string, WorkspaceSkill>;
|
|
15
|
+
}): void;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export function compileWorkflow(o,r){const e=assertRecord(o.spec,"Workflow.spec"),t="object"==typeof e.config&&e.config?e.config:{};return{id:readName(o),...readDescription(o)?{description:readDescription(o)}:{},sourcePath:r,...readOptionalString(e.adapter)?{adapter:readOptionalString(e.adapter)}:{},...readOptionalString(e.entry)?{entry:readOptionalString(e.entry)}:{},..."object"==typeof e.state&&e.state?{state:readWorkflowState(e.state)}:{},nodes:readWorkflowNodes(e.nodes),edges:readWorkflowEdges(e.edges),..."object"==typeof e.policies&&e.policies?{policies:e.policies}:{},...Object.keys(t).length>0?{config:t}:{}}}export function validateWorkflows(o){for(const r of o.workflows.values()){const e=new Set(r.nodes.map(o=>o.id));validateWorkflowEntry(r,e),validateWorkflowEdges(r,e);for(const e of r.nodes)validateWorkflowUse(e.use,o)}}function readWorkflowState(o){const r=assertRecord(o,"Workflow.spec.state");return{...readOptionalString(r.schema)?{schema:readOptionalString(r.schema)}:{},..."object"==typeof r.config&&r.config?{config:r.config}:{}}}function readWorkflowNodes(o){if(!Array.isArray(o)||0===o.length)throw new Error("Workflow.spec.nodes must be a non-empty array");return o.map(o=>{const r=assertRecord(o,"Workflow.spec.nodes[]"),e=readOptionalString(r.id),t=readOptionalString(r.use);if(!e||!t)throw new Error("Workflow.spec.nodes[] requires id and use");return{id:e,use:t,...readOptionalString(r.type)?{type:readOptionalString(r.type)}:{},..."object"==typeof r.config&&r.config?{config:r.config}:{}}})}function readWorkflowEdges(o){if(!Array.isArray(o))throw new Error("Workflow.spec.edges must be an array");return o.map(o=>{const r=assertRecord(o,"Workflow.spec.edges[]"),e=readOptionalString(r.from),t=readOptionalString(r.to);if(!e||!t)throw new Error("Workflow.spec.edges[] requires from and to");return{from:e,to:t,...readOptionalString(r.condition)?{condition:readOptionalString(r.condition)}:{}}})}function validateWorkflowEntry(o,r){if(o.entry&&!r.has(o.entry))throw new Error(`Workflow ${o.id} entry references unknown node ${o.entry}`)}function validateWorkflowEdges(o,r){for(const e of o.edges)if(!r.has(e.from)||!r.has(e.to))throw new Error(`Workflow ${o.id} edge references unknown node ${e.from}->${e.to}`)}function validateWorkflowUse(o,r){const e=o.indexOf("."),t=e>0?o.slice(0,e):"",n=e>0?o.slice(e+1):"";if(!t||!n)throw new Error(`Workflow node use must reference inventory as agents.<id>, tools.<id>, skills.<id>, or workflows.<id>: ${o}`);const i="agents"===t?r.agents:"tools"===t?r.tools:"skills"===t?r.skills:"workflows"===t?r.workflows:void 0;if(!i?.has(n))throw new Error(`Workflow node references unknown ${t}.${n}`)}function assertRecord(o,r){if("object"!=typeof o||null===o||Array.isArray(o))throw new Error(`${r} must be an object`);return o}function readName(o){const r=o.metadata?.name;if("string"==typeof r&&r.trim())return r.trim();throw new Error("Workflow document requires metadata.name")}function readDescription(o){const r=o.metadata?.description;return"string"==typeof r&&r.trim()?r.trim():void 0}function readOptionalString(o){return"string"==typeof o&&o.trim()?o.trim():void 0}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@stable-harness/workspace-yaml",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"files": [
|
|
6
|
+
"dist/**/*.js",
|
|
7
|
+
"dist/**/*.d.ts",
|
|
8
|
+
"package.json"
|
|
9
|
+
],
|
|
10
|
+
"exports": {
|
|
11
|
+
".": "./dist/index.js"
|
|
12
|
+
},
|
|
13
|
+
"peerDependencies": {
|
|
14
|
+
"@stable-harness/core": "0.0.1"
|
|
15
|
+
}
|
|
16
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "stable-harness",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.39",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Stable application runtime and operator control plane for agent workspaces.",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
"benchmark:tool-guard:matrix": "node scripts/benchmarks/tool-argument-guard-matrix.mjs",
|
|
63
63
|
"test:langmem:sqlite:e2e": "node scripts/run-langmem-sqlite-e2e.mjs",
|
|
64
64
|
"validate:workspace": "node scripts/validate-workspace.mjs",
|
|
65
|
-
"test": "rm -rf dist/test && tsc -b test/tsconfig.json && node --test dist/test/*.test.js dist/test/adapter/*.test.js dist/test/adapter/*/*.test.js dist/test/compat/*.test.js dist/test/evaluation/*.test.js dist/test/memory/*.test.js dist/test/protocol/*.test.js dist/test/retry/*.test.js dist/test/runtime/*.test.js dist/test/runtime/*/*.test.js dist/test/sdk/*.test.js dist/test/workspace/*.test.js",
|
|
65
|
+
"test": "rm -rf dist/test && tsc -b test/tsconfig.json && npm run build:chmod && node --test dist/test/*.test.js dist/test/adapter/*.test.js dist/test/adapter/*/*.test.js dist/test/compat/*.test.js dist/test/evaluation/*.test.js dist/test/memory/*.test.js dist/test/protocol/*.test.js dist/test/retry/*.test.js dist/test/runtime/*.test.js dist/test/runtime/*/*.test.js dist/test/sdk/*.test.js dist/test/workspace/*.test.js",
|
|
66
66
|
"test:langmem:maintenance:e2e": "node scripts/run-langmem-maintenance-e2e.mjs",
|
|
67
67
|
"test:skill-mining:e2e": "node scripts/run-skill-candidate-mining-e2e.mjs",
|
|
68
68
|
"prepublishOnly": "npm run build && npm run release:check-package",
|
|
@@ -84,14 +84,14 @@
|
|
|
84
84
|
"@langchain/langgraph-api": "^1.2.1",
|
|
85
85
|
"@langchain/ollama": "^1.2.7",
|
|
86
86
|
"@langchain/openai": "^1.4.5",
|
|
87
|
-
"@stable-harness/adapter-deepagents": "
|
|
88
|
-
"@stable-harness/adapter-langgraph": "
|
|
89
|
-
"@stable-harness/core": "
|
|
90
|
-
"@stable-harness/governance": "
|
|
91
|
-
"@stable-harness/memory": "
|
|
92
|
-
"@stable-harness/protocols": "
|
|
93
|
-
"@stable-harness/tool-gateway": "
|
|
94
|
-
"@stable-harness/workspace-yaml": "
|
|
87
|
+
"@stable-harness/adapter-deepagents": "0.0.1",
|
|
88
|
+
"@stable-harness/adapter-langgraph": "0.0.1",
|
|
89
|
+
"@stable-harness/core": "0.0.1",
|
|
90
|
+
"@stable-harness/governance": "0.0.1",
|
|
91
|
+
"@stable-harness/memory": "0.0.1",
|
|
92
|
+
"@stable-harness/protocols": "0.0.1",
|
|
93
|
+
"@stable-harness/tool-gateway": "0.0.1",
|
|
94
|
+
"@stable-harness/workspace-yaml": "0.0.1",
|
|
95
95
|
"deepagents": "^1.9.1",
|
|
96
96
|
"langchain": "^1.3.1",
|
|
97
97
|
"yaml": "^2.8.2",
|
|
@@ -101,5 +101,27 @@
|
|
|
101
101
|
"@types/node": "^25.6.2",
|
|
102
102
|
"terser": "^5.47.1",
|
|
103
103
|
"typescript": "^5.9.3"
|
|
104
|
-
}
|
|
104
|
+
},
|
|
105
|
+
"main": "index.js",
|
|
106
|
+
"directories": {
|
|
107
|
+
"doc": "docs",
|
|
108
|
+
"example": "examples",
|
|
109
|
+
"test": "test"
|
|
110
|
+
},
|
|
111
|
+
"keywords": [],
|
|
112
|
+
"author": "",
|
|
113
|
+
"bugs": {
|
|
114
|
+
"url": "https://github.com/botbotgo/stable-harness/issues"
|
|
115
|
+
},
|
|
116
|
+
"homepage": "https://github.com/botbotgo/stable-harness#readme",
|
|
117
|
+
"bundleDependencies": [
|
|
118
|
+
"@stable-harness/adapter-deepagents",
|
|
119
|
+
"@stable-harness/adapter-langgraph",
|
|
120
|
+
"@stable-harness/core",
|
|
121
|
+
"@stable-harness/governance",
|
|
122
|
+
"@stable-harness/memory",
|
|
123
|
+
"@stable-harness/protocols",
|
|
124
|
+
"@stable-harness/tool-gateway",
|
|
125
|
+
"@stable-harness/workspace-yaml"
|
|
126
|
+
]
|
|
105
127
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{realpathSync as e}from"node:fs";import t from"node:path";import{
|
|
1
|
+
import{realpathSync as e}from"node:fs";import t from"node:path";import{buildRuntimeSystemPrompt as r}from"@stable-harness/core";import{createBuiltinToolPolicyMiddleware as n,createObserverMiddleware as o}from"./internal/builtin-tool-policy.js";import{resolveFilesystemPermissions as s}from"./internal/builtin/permissions.js";import{createToolRepeatState as a}from"@stable-harness/core";import{buildGatewayTools as i,stringifyDeepAgentResult as p}from"./internal/gateway-tools.js";import{resolveDeepAgentsNativeMemories as d}from"./memory.js";import{buildDeepAgentRequest as l}from"./internal/messages.js";import{createRawToolCallParserMiddleware as c}from"./internal/raw-tool-call-parser.js";import{createBackendModel as u}from"./model-providers.js";import{createDeepAgentsRetryMiddleware as m}from"./retry-policy.js";import{streamDeepAgentResult as g}from"./internal/stream-events.js";export function createDeepAgentsAdapter(e={}){return{name:"deepagents",canRun:e=>"deepagents"===e.backend,async run(t){if(t.emit({type:"runtime.adapter.event",requestId:t.requestId,sessionId:t.sessionId,agentId:t.agent.id,event:{adapter:"deepagents",phase:"agent.handoff",modelRef:t.agent.modelRef,tools:t.agent.tools,subagents:t.agent.subagents}}),e.runner)return e.runner(t);const r=e.createDeepAgent?void 0:await async function loadDeepAgentsModule(){try{return await async function importOptionalPackage(e){return import(e)}("deepagents")}catch(e){throw new Error(`DeepAgents package is required for the default adapter path: ${function formatError(e){return e instanceof Error?e.message:String(e)}(e)}`)}}(),n=e.createDeepAgent??function readCreateDeepAgent(e){const t=e?.createDeepAgent;if("function"==typeof t)return t;throw new Error("DeepAgents package does not export createDeepAgent.")}(r),o=n(function buildDeepAgentParams(e,t,r){const n={...readDeepAgentsConfig(t),...readDeepAgentsConfig(e.agent.config.deepagents)},o=resolveDeepAgentsSkills(e,e.agent),a=n.permissions??s(e,e.agent),p=requestScopedRepeatState(e,e.agent.id);return pruneUndefined({name:e.agent.id,model:n.model??resolveAgentModel(e,e.agent),systemPrompt:buildSystemPrompt(e,e.agent),backend:n.backend??resolveDeepAgentsBackend(e,r,o),checkpointer:n.checkpointer,store:n.store,middleware:mergeMiddleware(e,e.agent,n.middleware,p),responseFormat:n.responseFormat,contextSchema:n.contextSchema,interruptOn:n.interruptOn,generalPurposeAgent:readBoolean(n.generalPurposeAgent),taskDescription:readString(n.taskDescription),permissions:a,tools:i(e,e.agent.id,e.agent.tools,resolveAgentRepairModel(e,e.agent,n),p),subagents:e.agent.subagents.map(t=>{const r=e.workspace.agents.get(t),n=readDeepAgentsConfig(r?.config.deepagents),o=n.permissions??s(e,r),a=scopedInput(e,r),p=requestScopedRepeatState(e,t);return pruneUndefined({name:t,description:r?.description??readString(r?.config.description)??r?.id,systemPrompt:buildSystemPrompt(e,r),model:n.model??(r?resolveAgentModel(e,r):void 0),middleware:mergeMiddleware(a,r,n.middleware,p),interruptOn:n.interruptOn,generalPurposeAgent:readBoolean(n.generalPurposeAgent),taskDescription:readString(n.taskDescription),permissions:o,responseFormat:n.responseFormat,tools:i(e,t,r?.tools??[],resolveAgentRepairModel(a,r,n),p),memory:resolveDeepAgentsMemory(e,r),skills:resolveDeepAgentsSkills(e,r)})}),memory:resolveDeepAgentsMemory(e,e.agent),skills:o})}(t,e.config,r)),a=l(t),d=function buildDeepAgentInvokeConfig(e){return pruneUndefined({recursionLimit:readNumber(readDeepAgentsConfig(e.config.deepagents).recursionLimit)??readNumber(e.config.recursionLimit)})}(t.agent);if(!0===t.request.metadata?.openaiStream&&o.streamEvents)return g(t,o.streamEvents(a,{version:"v2",...d}),p);const c=await o.invoke(a,d);return p(c)}}}function buildSystemPrompt(e,t){const n=t?.systemPrompt??readString(t?.config.systemPrompt);return r({workspace:e.workspace,request:e.request,agent:t},n)}function resolveDeepAgentsMemory(e,t){const r=readDeepAgentsStringArray(t?.config,"memory");if(r)return r;const n=d(e.workspace).map(e=>`/memories/${e.id}.md`);return n.length>0?n:void 0}function resolveDeepAgentsSkills(r,n){const o=readDeepAgentsStringArray(n?.config,"skills");if(o)return o;const s=[...new Set((n?.skills??[]).map(e=>r.workspace.skills.get(e)?.path).filter(e=>"string"==typeof e&&e.trim().length>0).map(n=>function backendSkillSourcePath(r,n){const o=t.dirname(t.dirname(n)),s=t.relative(r,o);return!s||s.startsWith("..")||t.isAbsolute(s)?""===s?"/":function canonicalPath(t){try{return e.native(t)}catch{return t}}(o):`/${s.split(t.sep).join("/")}`}(r.workspace.root,n)))];return s.length>0?s:void 0}function resolveDeepAgentsBackend(e,t,r){if(t?.FilesystemBackend&&r&&0!==r.length)return()=>new t.FilesystemBackend({rootDir:e.workspace.root})}function mergeMiddleware(e,t,r,s=a(e.workspace.runtime.toolGateway)){const i=Array.isArray(r)?r:[],p=scopedInput(e,t),d=new Set;return[o(p,{observedToolIds:d,repeatState:s}),n(p,{repeatState:s}),...m(e.workspace.runtime.retry),...i,c(p)]}function requestScopedRepeatState(e,t){const r=`deepagents.repeat.${t}`,n=e.requestState?.get(r);if(n)return n;const o=a(e.workspace.runtime.toolGateway);return e.requestState&&o&&e.requestState.set(r,o),o}function scopedInput(e,t){return t?{...e,agent:t}:e}function resolveAgentModel(e,t){const r=t.modelRef?e.workspace.models.get(t.modelRef):void 0;return r?u(r):void 0}function resolveAgentRepairModel(e,t,r){const n=r.model;if(isRepairModel(n))return n;if(!t)return;const o=resolveAgentModel(e,t);return isRepairModel(o)?o:void 0}function readDeepAgentsConfig(e){return isRecord(e)?e:{}}function readDeepAgentsStringArray(e,t){const r=isRecord(e)?e:{},n=readDeepAgentsConfig(r.deepagents),o="memory"===t?["memory","memorySources"]:["skills","skillSources"];for(const e of o){const t=readStringArray(n[e]);if(t)return t}return readStringArray(r[t])}function pruneUndefined(e){return Object.fromEntries(Object.entries(e).filter(([,e])=>void 0!==e))}function readString(e){return"string"==typeof e&&e.trim()?e:void 0}function readNumber(e){return"number"==typeof e&&Number.isFinite(e)?e:void 0}function readBoolean(e){return"boolean"==typeof e?e:void 0}function readStringArray(e){return Array.isArray(e)?e.filter(e=>"string"==typeof e):void 0}function isRecord(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}function isRepairModel(e){return"object"==typeof e&&null!==e&&"invoke"in e&&"function"==typeof e.invoke}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ToolMessage } from "@langchain/core/messages";
|
|
2
|
+
import type { RuntimeAdapter, WorkspaceAgent } from "@stable-harness/core";
|
|
3
|
+
type AdapterRunInput = Parameters<RuntimeAdapter["run"]>[0];
|
|
4
|
+
export declare const filesystemBuiltinToolIds: Set<string>;
|
|
5
|
+
export declare function validateFilesystemBuiltinCall(input: AdapterRunInput, toolId: string, request: {
|
|
6
|
+
toolCall?: {
|
|
7
|
+
id?: string;
|
|
8
|
+
};
|
|
9
|
+
}): ToolMessage<import("@langchain/core/messages").MessageStructure<import("@langchain/core/messages").MessageToolSet>> | undefined;
|
|
10
|
+
export declare function resolveFilesystemPermissions(input: AdapterRunInput, agent: WorkspaceAgent | undefined): {
|
|
11
|
+
operations: string[];
|
|
12
|
+
paths: string[];
|
|
13
|
+
mode: string;
|
|
14
|
+
}[] | undefined;
|
|
15
|
+
export declare function isFilesystemDisabled(input: AdapterRunInput): boolean;
|
|
16
|
+
export declare function isFilesystemTool(name: unknown): boolean;
|
|
17
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{realpathSync as e}from"node:fs";import{ToolMessage as t}from"@langchain/core/messages";export const filesystemBuiltinToolIds=new Set(["ls","read_file","write_file","edit_file","glob","grep"]);export function validateFilesystemBuiltinCall(e,i,o){if(isFilesystemDisabled(e)&&filesystemBuiltinToolIds.has(i))return new t({tool_call_id:o.toolCall?.id??`stable-harness-${i}-policy`,name:i,content:`Filesystem builtin tool '${i}' is disabled for this agent. Do not retry filesystem tools; use the agent's registered workspace tools and already collected evidence instead.`})}export function resolveFilesystemPermissions(e,t){const i=readConfigRecord(t?.config,"builtinTools"),o=[];if(o.push(...function skillReadPermissions(e,t){const i=[...new Set((t?.skills??[]).flatMap(t=>function skillReadPaths(e,t){return t?[...new Set([t,canonicalPath(t),backendSkillPath(e,t)])].flatMap(e=>function skillReadPathCandidates(e){const t=e.replace(/\/+$/u,""),i=t.endsWith("/SKILL.md")?t.slice(0,-9):t,o=function parentPath(e){const t=e.lastIndexOf("/");return t>0?e.slice(0,t):void 0}(i);return[t,i,`${i}/**`,...o?[o,`${o}/**`]:[]]}(e)):[]}(e.workspace.root,e.workspace.skills.get(t)?.path)).filter(e=>e.startsWith("/")))];return i.length>0?[{operations:["read"],paths:i,mode:"allow"}]:[]}(e,t)),!1!==i?.filesystem){if(deepagentsMemoryWritable(e))return o.length>0?o:void 0}else o.push({operations:["read"],paths:["/memories/**"],mode:"allow"}),o.push({operations:["read","write"],paths:["/**"],mode:"deny"});return deepagentsMemoryWritable(e)||o.push({operations:["write"],paths:["/memories/**"],mode:"deny"}),o.length>0?o:void 0}export function isFilesystemDisabled(e){const t=readConfigRecord(e.agent.config,"builtinTools");return!1===t?.filesystem}export function isFilesystemTool(e){return"string"==typeof e&&filesystemBuiltinToolIds.has(e)}function backendSkillPath(e,t){const i=function pathRelative(e,t){const i=e.split("/").filter(Boolean),o=t.split("/").filter(Boolean);if(!(o.length<i.length)){for(let e=0;e<i.length;e+=1)if(i[e]!==o[e])return;return o.slice(i.length).join("/")}}(e,t);return void 0===i?t:`/${i.split("/").filter(Boolean).join("/")}`}function canonicalPath(t){try{return e.native(t)}catch{return t}}function deepagentsMemoryWritable(e){const t=readConfigRecord(e.workspace.runtime.memory,"deepagentsMem");return!1!==t?.write}function readConfigRecord(e,t){const i=isRecord(e)?e:{};return isRecord(i[t])?i[t]:void 0}function isRecord(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ToolMessage } from "@langchain/core/messages";
|
|
2
|
+
import type { RuntimeAdapter } from "@stable-harness/core";
|
|
3
|
+
type AdapterRunInput = Parameters<RuntimeAdapter["run"]>[0];
|
|
4
|
+
export declare function repairTaskCall<T extends {
|
|
5
|
+
toolCall?: {
|
|
6
|
+
id?: string;
|
|
7
|
+
args?: unknown;
|
|
8
|
+
};
|
|
9
|
+
}>(input: AdapterRunInput, request: T): Promise<{
|
|
10
|
+
request: T;
|
|
11
|
+
blocked?: ToolMessage;
|
|
12
|
+
}>;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{repairCallSelection as e}from"@botbotgo/better-call";import{ToolMessage as t}from"@langchain/core/messages";import{normalizeArgsRecord as n}from"../builtin-args.js";export async function repairTaskCall(r,a){const o=function allowedTaskTypes(e){const t=readConfigRecord(e.agent.config,"deepagents");if(!0===t?.generalPurposeAgent)return;const n=readConfigRecord(e.agent.config,"builtinTools")?.modelExposed;return!1===n?[]:Array.isArray(n)?n.includes("task")?e.agent.subagents:[]:0===e.agent.subagents.length?[]:void 0}(r);if(void 0===o)return{request:a};const s=n(a.toolCall?.args),i=function readTaskSubagentType(e){const t=isRecord(e)?e:{};return readString(t.subagent_type)??readString(t.subagentType)}(s);if(i&&o.includes(i))return{request:a};const d=await e({call:{id:i,args:s},candidates:taskCallCandidates(r,o),mode:"repair"});if(d.ok){emitInventoryRepair(r,"repaired",i,d.candidateId,o);const e={...s,...d.args,subagent_type:d.candidateId};return{request:{...a,toolCall:{...a.toolCall,args:e}}}}emitInventoryRepair(r,"blocked",i,void 0,o,d.reason);const l=i?`: ${i}`:"",c=o.length>0?o.join(", "):"none";return{request:a,blocked:new t({tool_call_id:a.toolCall?.id??"stable-harness-task-policy",name:"task",status:"error",content:[`Task delegation target is not in the workspace inventory${l}. Allowed task targets: ${c}.`,"Retry with an allowed target only when that target semantically owns the original user request.","Do not substitute another specialist just to continue the same evidence need; synthesize from already collected evidence when no allowed target is a semantic match."].join(" ")})}}function emitInventoryRepair(e,t,n,r,a,o){e.emit({type:"runtime.adapter.event",requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,event:{adapter:"deepagents",phase:"inventory.repair",status:t,diagnostic:{layer:"task",owner:"stable_runtime_policy",originalId:n,repairedId:r,candidateIds:a,reason:o}}})}function taskCallCandidates(e,t){return t.map(t=>({id:t,description:e.workspace.agents.get(t)?.description,schema:{type:"object",properties:{subagent_type:{type:"string"},subagentType:{type:"string"},description:{type:"string"}},required:["description"],additionalProperties:!0}}))}function readConfigRecord(e,t){const n=isRecord(e)?e:{};return isRecord(n[t])?n[t]:void 0}function readString(e){return"string"==typeof e&&e.trim()?e:void 0}function isRecord(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
import { type ToolRepeatState } from "./gateway-tools.js";
|
|
1
|
+
import type { RuntimeAdapter } from "@stable-harness/core";
|
|
2
|
+
import { type ToolRepeatState } from "@stable-harness/core";
|
|
4
3
|
type AdapterRunInput = Parameters<RuntimeAdapter["run"]>[0];
|
|
5
4
|
export declare function createBuiltinToolPolicyMiddleware(input: AdapterRunInput, options?: {
|
|
6
5
|
repeatState?: ToolRepeatState;
|
|
@@ -13,11 +12,6 @@ export declare function createBuiltinToolPolicyMiddleware(input: AdapterRunInput
|
|
|
13
12
|
toolChoice?: unknown;
|
|
14
13
|
}, handler: (request: unknown) => Promise<unknown>): Promise<unknown>;
|
|
15
14
|
};
|
|
16
|
-
export declare function validateFilesystemBuiltinCall(input: AdapterRunInput, toolId: string, request: {
|
|
17
|
-
toolCall?: {
|
|
18
|
-
id?: string;
|
|
19
|
-
};
|
|
20
|
-
}): ToolMessage<import("@langchain/core/messages").MessageStructure<import("@langchain/core/messages").MessageToolSet>> | undefined;
|
|
21
15
|
export declare function createObserverMiddleware(input: AdapterRunInput, options?: {
|
|
22
16
|
observedToolIds?: Set<string>;
|
|
23
17
|
repeatState?: ToolRepeatState;
|
|
@@ -31,9 +25,4 @@ export declare function createObserverMiddleware(input: AdapterRunInput, options
|
|
|
31
25
|
};
|
|
32
26
|
}, handler: (request: unknown) => Promise<unknown>): Promise<unknown>;
|
|
33
27
|
};
|
|
34
|
-
export declare function resolveFilesystemPermissions(input: AdapterRunInput, agent: WorkspaceAgent | undefined): {
|
|
35
|
-
operations: string[];
|
|
36
|
-
paths: string[];
|
|
37
|
-
mode: string;
|
|
38
|
-
}[] | undefined;
|
|
39
28
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{ToolMessage as t}from"@langchain/core/messages";import{afterToolInvoke as e,beforeToolInvoke as o,createToolRepeatState as r}from"@stable-harness/core";import{filesystemBuiltinToolIds as i,isFilesystemDisabled as n,isFilesystemTool as s,validateFilesystemBuiltinCall as a}from"./builtin/permissions.js";import{repairTaskCall as l}from"./builtin/task-inventory.js";import{repairBuiltinToolRequest as u}from"./builtin-call-repair.js";import{stringifyDeepAgentResult as c,toolControlProjection as d}from"./gateway-tools.js";import{isSuccessfulEvidenceOutput as p,observedToolEvidence as m,recordObservedToolEvidence as g}from"./gateway/tool-evidence.js";import{validateSkillFileBuiltinCall as f}from"./skill-file-policy.js";import{filterRepeatLimitedTools as v}from"./tool-repeat-visibility.js";import{traceProjectionForBuiltinTool as b}from"./trace-projection.js";const T=new Set(["write_todos","read_todos","task","execute",...i]);export function createBuiltinToolPolicyMiddleware(t,e={}){return{name:"StableHarnessBuiltinToolPolicy",async wrapModelCall(o,r){const i=Array.isArray(o.tools)?v(o.tools.filter(e=>!function hasHiddenBuiltins(t){return n(t)||!isTaskVisible(t)}(t)||isModelVisibleBuiltin(t,e.name)),e.repeatState):o.tools,s=function normalizeToolChoice(t,e,o){return"required"===e?o&&o.length>0?e:"auto":function isForcedHiddenTool(t,e){return"string"==typeof e?.function?.name&&!isModelVisibleBuiltin(t,e.function.name)}(t,e)?"auto":e}(t,o.toolChoice,i);return r({...o,tools:i,toolChoice:s})}}}export function createObserverMiddleware(i,n={}){const s=n.repeatState??r(i.workspace.runtime.toolGateway);return{name:"StableHarnessObserver",async wrapToolCall(r,d){const g=r.toolCall?.name;if(!g||!T.has(g))return d(r);const v=await u({toolId:g,request:r,workspaceRoot:i.workspace.root});emitToolEvent(i,g,"agent.tool.start",v.toolCall?.args);const b="task"===g?await l(i,v):{request:v},h=b.request,y=b.blocked;if(y)return emitToolEvent(i,g,"agent.tool.result",h.toolCall?.args,{output:y.content}),y;const k=a(i,g,h);if(k)return emitToolEvent(i,g,"agent.tool.result",h.toolCall?.args,{output:k.content}),k;const C=f(i,g,h);if(C)return emitToolEvent(i,g,"agent.tool.result",h.toolCall?.args,{output:C.content}),C;try{const a=s?o(g,h.toolCall?.args,s):void 0;if(a)return emitToolEvent(i,g,"agent.tool.result",h.toolCall?.args,{output:a.eventOutput}),builtinToolMessage(r,g,function modelOutputForRepeatedBuiltin(t,e){return"task"!==t?e:function readPreviousOutput(t){try{const e=JSON.parse(t);if(!isRecord(e)||"repeated_tool_call_limit"!==e.status||"string"!=typeof e.previousOutput)return;const o=e.previousOutput.trim();return o.length>0?o:void 0}catch{return}}(e)??e}(g,a.modelOutput));const l=await d(h),u=function observedToolOutput(t,e,o){return"write_todos"===t?JSON.stringify({status:"recorded",args:e.toolCall?.args}):c(o)}(g,h,l),m=s?e({toolId:g,args:h.toolCall?.args,output:u,successful:!(l instanceof t&&"error"===l.status)&&p(u),state:s}):{};return emitToolEvent(i,g,"agent.tool.result",h.toolCall?.args,{output:m.eventOutput??u}),n.observedToolIds?.add(g),void 0===m.modelOutput?l:builtinToolMessage(r,g,m.modelOutput)}catch(e){const o=function recoverableBuiltinToolError(e,o,r,i){const n=formatError(i);if("task"===o&&/repeat limit reached for tool/iu.test(n)){const o=function formatObservedEvidence(t){const e=m(t);if(0===e.length)return"";const o=e.map(t=>[`Agent: ${t.agentId}`,`Tool: ${t.toolId}`,t.output].join("\n")).join("\n\n---\n\n");return o.length>12e3?`${o.slice(0,12e3)}\n[truncated]`:o}(e);return new t({tool_call_id:r.toolCall?.id??"stable-harness-task-repeat-limit",name:"task",content:JSON.stringify({status:"delegated_task_repeat_limit",finalizationRequired:!0,instruction:"The delegated agent reached a configured tool repeat limit. Stop delegating this evidence need and do not send a synthesis task to another subagent for the same need. Finalize only from observedEvidence and other evidence that is already visible in this run. If the visible evidence is insufficient for a requested claim, report an explicit blocker or evidence gap instead of estimating, inventing, or using generic knowledge.",...o?{observedEvidence:o}:{},error:previewError(n)})})}if(/Received tool input did not match expected schema|Invalid input:/iu.test(n))return new t({tool_call_id:r.toolCall?.id??`stable-harness-${o}-argument-error`,name:o,status:"error",content:JSON.stringify({status:"tool_argument_error",toolId:o,instruction:"The upstream builtin tool rejected these arguments. Fix the tool arguments according to the tool schema, or choose a more appropriate available tool.",error:previewError(n)})})}(i,g,r,e);if(o)return emitToolEvent(i,g,"agent.tool.result",v.toolCall?.args,{output:o.content}),o;throw emitToolEvent(i,g,"agent.tool.result",v.toolCall?.args,{error:formatError(e)}),e}}}}function builtinToolMessage(e,o,r){return new t({tool_call_id:e.toolCall?.id??`stable-harness-${o}-repeat-guard`,name:o,content:r})}function emitToolEvent(t,e,o,r,i={}){"string"==typeof i.output&&g(t,t.agent.id,e,i.output),t.emit({type:"runtime.adapter.event",requestId:t.requestId,sessionId:t.sessionId,agentId:t.agent.id,event:{adapter:"deepagents",phase:o,toolId:e,..."agent.tool.start"===o?{args:r}:{},...i,..."string"==typeof i.output?d(i.output):{},...b(e,o,r)}})}function isTaskVisible(t){const e=function readConfigRecord(t,e){const o=isRecord(t)?t:{};return isRecord(o[e])?o[e]:void 0}(t.agent.config,"builtinTools")?.modelExposed;return!1!==e&&(!Array.isArray(e)||e.includes("task"))}function isModelVisibleBuiltin(t,e){return(!n(t)||!s(e))&&("task"!==e||isTaskVisible(t))}function isRecord(t){return"object"==typeof t&&null!==t&&!Array.isArray(t)}function formatError(t){return t instanceof Error?t.message:String(t)}function previewError(t){const e=t.replace(/\s+/gu," ").trim();return e.length>800?`${e.slice(0,797)}...`:e}
|
|
@@ -1,30 +1,8 @@
|
|
|
1
1
|
import { ToolMessage } from "@langchain/core/messages";
|
|
2
2
|
import type { RuntimeAdapter } from "@stable-harness/core";
|
|
3
3
|
import type { RuntimeToolRepairModel } from "@stable-harness/core";
|
|
4
|
-
|
|
5
|
-
successfulCalls: Map<string, string>;
|
|
6
|
-
duplicateCallCounts: Map<string, number>;
|
|
7
|
-
latestSuccessfulOutputByTool: Map<string, string>;
|
|
8
|
-
successfulToolCounts: Map<string, number>;
|
|
9
|
-
toolCallCounts: Map<string, number>;
|
|
10
|
-
maxDuplicateCallsPerTool?: number;
|
|
11
|
-
maxCallsPerTool?: number;
|
|
12
|
-
maxSuccessfulCallsPerTool?: number;
|
|
13
|
-
maxCallsByTool: Map<string, number>;
|
|
14
|
-
maxSuccessfulCallsByTool: Map<string, number>;
|
|
15
|
-
returnPreviousOutputOnRepeatLimit: boolean;
|
|
16
|
-
};
|
|
4
|
+
import { type ToolRepeatState } from "@stable-harness/core";
|
|
17
5
|
export declare function buildGatewayTools(input: Parameters<RuntimeAdapter["run"]>[0], agentId: string, toolIds: string[], repairModel?: RuntimeToolRepairModel, repeatState?: ToolRepeatState | undefined): import("@langchain/core/tools").DynamicTool<string | ToolMessage<import("@langchain/core/messages").MessageStructure<import("@langchain/core/messages").MessageToolSet>>, unknown>[];
|
|
18
|
-
export declare function createToolRepeatState(config: unknown): ToolRepeatState | undefined;
|
|
19
|
-
export declare function beforeToolInvoke(toolId: string, args: unknown, state: ToolRepeatState): {
|
|
20
|
-
eventOutput: string;
|
|
21
|
-
modelOutput: string;
|
|
22
|
-
} | undefined;
|
|
23
|
-
export declare function isToolRepeatLimitReached(toolId: string, state: ToolRepeatState | undefined): boolean;
|
|
24
|
-
export declare function afterToolInvoke(toolId: string, args: unknown, output: string, result: unknown, state: ToolRepeatState): {
|
|
25
|
-
eventOutput?: string;
|
|
26
|
-
modelOutput?: string;
|
|
27
|
-
};
|
|
28
6
|
export declare function stringifyDeepAgentResult(result: unknown): string;
|
|
29
7
|
export declare function toolControlProjection(output: string): {
|
|
30
8
|
controlStatus: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{ToolMessage as e}from"@langchain/core/messages";import{tool as t}from"@langchain/core/tools";import{isSuccessfulEvidenceOutput as o,observedToolEvidence as r,recordObservedToolEvidence as n}from"./gateway/tool-evidence.js";import{emitStructuredToolFailure as s}from"./gateway/tool-failure-events.js";export function buildGatewayTools(o,n,a,i,l=createToolRepeatState(o.workspace.runtime.toolGateway)){return o.toolGateway?a.flatMap(a=>{const u=o.toolGateway?.get(a);if(!u)return[];const c=o.workspace.tools.get(a),d=c?.schema??u.schema;return[t(async t=>async function invokeGuardedGatewayTool(t){emitToolResult(t.input,t.agentId,t.toolId,void 0);const o=function missingRequiredPlanContent(e,t){const o=readRecord(e.agent.config.executionContract);if(!0!==o?.requiresPlan)return"";const n=readStringArray(o.planEvidenceTools);if(0===n.length||n.includes(t))return"";const s=new Set(r(e).map(e=>e.toolId));return n.some(e=>s.has(e))?"":["Status: plan_required",`Evidence tool: ${t}`,`Blocker: execution contract requires a planning checkpoint from one of: ${n.join(", ")} before evidence tools run.`,"Instruction: call the planning tool first, then retry this atomic evidence tool with repaired arguments."].join("\n")}(t.input,t.toolId);if(o)return emitToolResult(t.input,t.agentId,t.toolId,o),o;const n=function missingToolDependencyContent(e,t){const o=readRecord(e.agent.config.executionContract),n=readStringArray(readRecord(o.toolDependencies)[t]);if(0===n.length)return"";const s=new Set(r(e).map(e=>e.toolId)),a=n.filter(e=>!s.has(e));return 0===a.length?"":["Status: dependency_required",`Evidence tool: ${t}`,`Blocker: this atomic evidence tool requires completed dependency evidence from: ${a.join(", ")}.`,"Instruction: complete the dependency tool first, evaluate it, then retry this atomic evidence tool."].join("\n")}(t.input,t.toolId);if(n)return emitToolResult(t.input,t.agentId,t.toolId,n),n;const a=t.repeatState?beforeToolInvoke(t.toolId,t.args,t.repeatState):void 0;if(a)return emitToolResult(t.input,t.agentId,t.toolId,a.eventOutput),a.modelOutput;const i=await async function invokeGatewayTool(t,o,r,n,a){try{if(t.toolFailureTracker?.isCircuitOpen(r))throw new Error(`Tool circuit is open: ${r}`);const e=await t.toolGateway.invoke({toolId:r,args:n,repairModel:a,context:{workspaceRoot:t.workspace.root,requestId:t.requestId,sessionId:t.sessionId,agentId:o,requestInput:t.request.input,observedEvidence:formatObservedEvidenceForToolContext(t),approvalIds:readApprovalIds(t.request.metadata)}});return t.toolFailureTracker?.recordSuccess(r),e}catch(n){if(s(t,o,r,n),function isToolArgumentValidationError(e){return e instanceof Error&&"ToolArgumentValidationError"===e.name&&"string"==typeof e.toolId&&Array.isArray(e.issues)}(n))return new e({tool_call_id:`stable-harness-${r}-argument-guard`,name:r,status:"error",content:formatToolArgumentError(n)});if(t.workspace.runtime.retry?.tools?.enabled)throw n;return new e({tool_call_id:`stable-harness-${r}-execution-error`,name:r,status:"error",content:JSON.stringify({error:"tool_execution_failed",toolId:r,message:formatError(n),retry:"Use the error as evidence, adjust the tool arguments if possible, or return a final answer with the blocker."})})}}(t.input,t.agentId,t.toolId,t.args,t.repairModel),l=i instanceof e?String(i.content):stringifyDeepAgentResult(i.output),u=t.repeatState?afterToolInvoke(t.toolId,t.args,l,i,t.repeatState):{};return emitToolResult(t.input,t.agentId,t.toolId,u.eventOutput??l),void 0!==u.modelOutput?u.modelOutput:i instanceof e?i:l}({input:o,agentId:n,toolId:a,args:t,repairModel:i,repeatState:l}),{name:a,description:buildToolDescription(c?.description??u.description??a,d,o.workspace.runtime.toolGateway,a),schema:{type:"object",additionalProperties:!0}})]}):[]}export function createToolRepeatState(e){if(function repeatGuardEnabled(e){return!0===repeatGuardConfig(e).enabled}(e))return{successfulCalls:new Map,duplicateCallCounts:new Map,latestSuccessfulOutputByTool:new Map,successfulToolCounts:new Map,toolCallCounts:new Map,maxDuplicateCallsPerTool:readPositiveInteger(repeatGuardConfig(e).maxDuplicateCallsPerTool)??3,maxCallsPerTool:readPositiveInteger(repeatGuardConfig(e).maxCallsPerTool),maxSuccessfulCallsPerTool:readPositiveInteger(repeatGuardConfig(e).maxSuccessfulCallsPerTool),maxCallsByTool:readPositiveIntegerMap(repeatGuardConfig(e).maxCallsByTool),maxSuccessfulCallsByTool:readPositiveIntegerMap(repeatGuardConfig(e).maxSuccessfulCallsByTool),returnPreviousOutputOnRepeatLimit:!0===repeatGuardConfig(e).returnPreviousOutputOnRepeatLimit}}function repeatGuardConfig(e){return isRecord(e)&&isRecord(e.repeatGuard)?e.repeatGuard:{}}function readPositiveInteger(e){return"number"==typeof e&&Number.isInteger(e)&&e>0?e:void 0}function readPositiveIntegerMap(e){return isRecord(e)?new Map(Object.entries(e).map(([e,t])=>[e,readPositiveInteger(t)]).filter(e=>void 0!==e[1])):new Map}export function beforeToolInvoke(e,t,o){const r=o.toolCallCounts.get(e)??0;o.toolCallCounts.set(e,r+1);const n=o.maxCallsByTool.get(e)??o.maxCallsPerTool;if(void 0!==n&&r>=n){const t=o.latestSuccessfulOutputByTool.get(e),r=repeatedToolCallLimitContent(e,t);return{eventOutput:r,modelOutput:repeatLimitModelOutput(r,t,o)}}const s=o.maxSuccessfulCallsByTool.get(e)??o.maxSuccessfulCallsPerTool;if(void 0!==s&&(o.successfulToolCounts.get(e)??0)>=s){const t=o.latestSuccessfulOutputByTool.get(e),r=repeatedToolCallLimitContent(e,t);return{eventOutput:r,modelOutput:repeatLimitModelOutput(r,t,o)}}const a=stableToolCallKey(e,t),i=o.successfulCalls.get(a);if(void 0!==i){const t=o.duplicateCallCounts.get(a)??0;if(o.duplicateCallCounts.set(a,t+1),void 0!==o.maxDuplicateCallsPerTool&&t>=o.maxDuplicateCallsPerTool){const t=repeatedToolCallLimitContent(e);return{eventOutput:t,modelOutput:t}}const r=function duplicateToolCallContent(e,t){return JSON.stringify({status:"duplicate_tool_call",toolId:e,instruction:"This agent already completed an equivalent tool call. Use the prior evidence instead of calling the tool again.",previousOutput:t})}(e,i);return{eventOutput:r,modelOutput:i}}}function repeatLimitModelOutput(e,t,o){return o.returnPreviousOutputOnRepeatLimit&&void 0!==t&&0!==t.trim().length?t:e}export function isToolRepeatLimitReached(e,t){if(!t)return!1;const o=t.maxCallsByTool.get(e)??t.maxCallsPerTool;if(void 0!==o&&(t.toolCallCounts.get(e)??0)>=o)return!0;const r=t.maxSuccessfulCallsByTool.get(e)??t.maxSuccessfulCallsPerTool;return void 0!==r&&(t.successfulToolCounts.get(e)??0)>=r}export function afterToolInvoke(t,r,n,s,a){return s instanceof e&&"error"===s.status?{}:o(n)?(a.successfulCalls.set(stableToolCallKey(t,r),n),a.latestSuccessfulOutputByTool.set(t,n),a.successfulToolCounts.set(t,(a.successfulToolCounts.get(t)??0)+1),{}):{}}function emitToolResult(e,t,o,r){void 0!==r&&n(e,t,o,r),e.emit({type:"runtime.adapter.event",requestId:e.requestId,sessionId:e.sessionId,agentId:t,event:void 0===r?{adapter:"deepagents",phase:"agent.tool.start",toolId:o}:{adapter:"deepagents",phase:"agent.tool.result",toolId:o,output:previewToolOutput(r),evidenceOutput:r,...toolControlProjection(r)}})}function repeatedToolCallLimitContent(e,t){return JSON.stringify({status:"repeated_tool_call_limit",toolId:e,instruction:"This tool reached the configured repeat limit for this request. Do not call this tool or a substitute tool for the same evidence need again. Use previousOutput and the collected evidence to produce the final answer now, or report the remaining gap explicitly.",...void 0!==t?{previousOutput:t}:{}})}export function stringifyDeepAgentResult(t){if(t instanceof e)return function stringifyToolMessageContent(e){return"string"==typeof e?e:JSON.stringify(e)}(t.content);if("string"==typeof t)return t;if(isRecord(t)){const e=t.structuredResponse??t.structured_response;if(void 0!==e)return"string"==typeof e?e:JSON.stringify(e);const o=(Array.isArray(t.messages)?t.messages:[]).at(-1);if(isRecord(o)&&"string"==typeof o.content)return o.content;const r=(isRecord(t.update)&&Array.isArray(t.update.messages)?t.update.messages:[]).at(-1);if(isRecord(r)&&isRecord(r.kwargs)&&"string"==typeof r.kwargs.content)return r.kwargs.content;if(isRecord(r)&&"string"==typeof r.content)return r.content}return JSON.stringify(t)}function buildToolDescription(e,t,o,r){const n=function toolRepeatPolicyDescription(e,t){const o=repeatGuardConfig(e),r=readPositiveIntegerMap(o.maxSuccessfulCallsByTool).get(t)??readPositiveInteger(o.maxSuccessfulCallsPerTool);return void 0===r?"":`Stable runtime repeat policy: call this tool at most ${r} successful time(s) for this request. If more detail is needed, include the dimensions in the first call and synthesize after the result returns.`}(o,r),s=n?`${e}\n\n${n}`:e;return t?`${s}\n\nStable tool input schema:\n${previewToolOutput(JSON.stringify(t))}`:s}function previewToolOutput(e){const t=e.replace(/\s+/gu," ").trim();return t.length>500?`${t.slice(0,497)}...`:t}export function toolControlProjection(e){const t=function parseJsonRecord(e){try{const t=JSON.parse(e);return isRecord(t)?t:void 0}catch{return}}(e);if("string"==typeof t?.status)return{controlStatus:t.status};const o=function readTextStatus(e){return String(e).match(/^Status:\s*([A-Za-z0-9_-]+)/imu)?.[1]}(e);return o?{controlStatus:o}:"string"==typeof t?.error?{controlStatus:t.error}:e.startsWith("Task delegation target is not in the workspace inventory")?{controlStatus:"task_inventory_blocked"}:{}}function stableToolCallKey(e,t){return`${e}:${stableJson(t)}`}function stableJson(e){return Array.isArray(e)?`[${e.map(stableJson).join(",")}]`:isRecord(e)?`{${Object.keys(e).sort().map(t=>`${JSON.stringify(t)}:${stableJson(e[t])}`).join(",")}}`:JSON.stringify(e)}function readApprovalIds(e){const t=e?.approvalIds??e?.approvalId;return"string"==typeof t&&t.trim()?[t.trim()]:Array.isArray(t)?t.filter(e=>"string"==typeof e&&e.trim().length>0):void 0}function formatObservedEvidenceForToolContext(e){const t=r(e).map(e=>`Tool: ${e.toolId}\n${e.output}`).join("\n\n---\n\n");return t.length>12e3?`${t.slice(0,12e3)}\n[truncated]`:t}function formatToolArgumentError(e){return JSON.stringify({error:"tool_argument_validation_failed",toolId:e.toolId,issues:e.issues,retry:"Call the same tool again with arguments that satisfy the reported schema and semantic issues."})}function isRecord(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}function readRecord(e){return isRecord(e)?e:{}}function readStringArray(e){return Array.isArray(e)?e.filter(e=>"string"==typeof e&&e.length>0):[]}function formatError(e){return e instanceof Error?e.message:String(e)}
|
|
1
|
+
import{ToolMessage as t}from"@langchain/core/messages";import{tool as e}from"@langchain/core/tools";import{afterToolInvoke as o,beforeToolInvoke as r,createToolRepeatState as n,missingRequiredPlanContent as s,missingToolDependencyContent as a,toolInvocationEvents as i}from"@stable-harness/core";import{isSuccessfulEvidenceOutput as u,observedToolEvidence as l,recordObservedToolEvidence as c}from"./gateway/tool-evidence.js";import{emitStructuredToolFailure as d}from"./gateway/tool-failure-events.js";export function buildGatewayTools(l,c,p,f,g=n(l.workspace.runtime.toolGateway)){return l.toolGateway?p.flatMap(n=>{const p=l.toolGateway?.get(n);if(!p)return[];const m=l.workspace.tools.get(n),y=m?.schema??p.schema;return[e(async e=>async function invokeGuardedGatewayTool(e){emitToolResult(e.input,e.agentId,e.toolId,void 0);const n=i({request:e.input.request,getEvents:e.input.getEvents}),l=s({agent:e.input.agent,events:n,toolId:e.toolId});if(l)return emitToolResult(e.input,e.agentId,e.toolId,l),l;const c=a({agent:e.input.agent,events:n,toolId:e.toolId});if(c)return emitToolResult(e.input,e.agentId,e.toolId,c),c;const p=e.repeatState?r(e.toolId,e.args,e.repeatState):void 0;if(p)return emitToolResult(e.input,e.agentId,e.toolId,p.eventOutput),p.modelOutput;const f=await async function invokeGatewayTool(e,o,r,n,s){try{if(e.toolFailureTracker?.isCircuitOpen(r))throw new Error(`Tool circuit is open: ${r}`);const t=await e.toolGateway.invoke({toolId:r,args:n,repairModel:s,context:{workspaceRoot:e.workspace.root,requestId:e.requestId,sessionId:e.sessionId,agentId:o,requestInput:e.request.input,observedEvidence:formatObservedEvidenceForToolContext(e),approvalIds:readApprovalIds(e.request.metadata)}});return e.toolFailureTracker?.recordSuccess(r),t}catch(n){if(d(e,o,r,n),function isToolArgumentValidationError(t){return t instanceof Error&&"ToolArgumentValidationError"===t.name&&"string"==typeof t.toolId&&Array.isArray(t.issues)}(n))return new t({tool_call_id:`stable-harness-${r}-argument-guard`,name:r,status:"error",content:formatToolArgumentError(n)});if(e.workspace.runtime.retry?.tools?.enabled)throw n;return new t({tool_call_id:`stable-harness-${r}-execution-error`,name:r,status:"error",content:JSON.stringify({error:"tool_execution_failed",toolId:r,message:formatError(n),retry:"Use the error as evidence, adjust the tool arguments if possible, or return a final answer with the blocker."})})}}(e.input,e.agentId,e.toolId,e.args,e.repairModel),g=f instanceof t?String(f.content):stringifyDeepAgentResult(f.output),m=e.repeatState?o({toolId:e.toolId,args:e.args,output:g,successful:!(f instanceof t&&"error"===f.status)&&u(g),state:e.repeatState}):{};return emitToolResult(e.input,e.agentId,e.toolId,m.eventOutput??g),void 0!==m.modelOutput?m.modelOutput:f instanceof t?f:g}({input:l,agentId:c,toolId:n,args:e,repairModel:f,repeatState:g}),{name:n,description:buildToolDescription(m?.description??p.description??n,y,l.workspace.runtime.toolGateway,n),schema:{type:"object",additionalProperties:!0}})]}):[]}function emitToolResult(t,e,o,r){void 0!==r&&c(t,e,o,r),t.emit({type:"runtime.adapter.event",requestId:t.requestId,sessionId:t.sessionId,agentId:e,event:void 0===r?{adapter:"deepagents",phase:"agent.tool.start",toolId:o}:{adapter:"deepagents",phase:"agent.tool.result",toolId:o,output:previewToolOutput(r),evidenceOutput:r,...toolControlProjection(r)}})}export function stringifyDeepAgentResult(e){if(e instanceof t)return function stringifyToolMessageContent(t){return"string"==typeof t?t:JSON.stringify(t)}(e.content);if("string"==typeof e)return e;if(isRecord(e)){const t=e.structuredResponse??e.structured_response;if(void 0!==t)return"string"==typeof t?t:JSON.stringify(t);const o=(Array.isArray(e.messages)?e.messages:[]).at(-1);if(isRecord(o)&&"string"==typeof o.content)return o.content;const r=(isRecord(e.update)&&Array.isArray(e.update.messages)?e.update.messages:[]).at(-1);if(isRecord(r)&&isRecord(r.kwargs)&&"string"==typeof r.kwargs.content)return r.kwargs.content;if(isRecord(r)&&"string"==typeof r.content)return r.content}return JSON.stringify(e)}function buildToolDescription(t,e,o,r){const n=function toolRepeatPolicyDescription(t,e){const o=function repeatGuardConfig(t){return isRecord(t)&&isRecord(t.repeatGuard)?t.repeatGuard:{}}(t),r=function readPositiveIntegerMap(t){return isRecord(t)?new Map(Object.entries(t).map(([t,e])=>[t,readPositiveInteger(e)]).filter(t=>void 0!==t[1])):new Map}(o.maxSuccessfulCallsByTool).get(e)??readPositiveInteger(o.maxSuccessfulCallsPerTool);return void 0===r?"":`Stable runtime repeat policy: call this tool at most ${r} successful time(s) for this request. If more detail is needed, include the dimensions in the first call and synthesize after the result returns.`}(o,r),s=n?`${t}\n\n${n}`:t;return e?`${s}\n\nStable tool input schema:\n${previewToolOutput(JSON.stringify(e))}`:s}function readPositiveInteger(t){return"number"==typeof t&&Number.isInteger(t)&&t>0?t:void 0}function previewToolOutput(t){const e=t.replace(/\s+/gu," ").trim();return e.length>500?`${e.slice(0,497)}...`:e}export function toolControlProjection(t){const e=function parseJsonRecord(t){try{const e=JSON.parse(t);return isRecord(e)?e:void 0}catch{return}}(t);if("string"==typeof e?.status)return{controlStatus:e.status};const o=function readTextStatus(t){return String(t).match(/^Status:\s*([A-Za-z0-9_-]+)/imu)?.[1]}(t);return o?{controlStatus:o}:"string"==typeof e?.error?{controlStatus:e.error}:t.startsWith("Task delegation target is not in the workspace inventory")?{controlStatus:"task_inventory_blocked"}:{}}function readApprovalIds(t){const e=t?.approvalIds??t?.approvalId;return"string"==typeof e&&e.trim()?[e.trim()]:Array.isArray(e)?e.filter(t=>"string"==typeof t&&t.trim().length>0):void 0}function formatObservedEvidenceForToolContext(t){const e=l(t).map(t=>`Tool: ${t.toolId}\n${t.output}`).join("\n\n---\n\n");return e.length>12e3?`${e.slice(0,12e3)}\n[truncated]`:e}function formatToolArgumentError(t){return JSON.stringify({error:"tool_argument_validation_failed",toolId:t.toolId,issues:t.issues,retry:"Call the same tool again with arguments that satisfy the reported schema and semantic issues."})}function isRecord(t){return"object"==typeof t&&null!==t&&!Array.isArray(t)}function formatError(t){return t instanceof Error?t.message:String(t)}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type ToolRepeatState } from "@stable-harness/core";
|
|
2
2
|
export declare function filterRepeatLimitedTools<T extends {
|
|
3
3
|
name?: unknown;
|
|
4
4
|
}>(tools: T[] | undefined, repeatState: ToolRepeatState | undefined): T[] | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{isToolRepeatLimitReached as e}from"
|
|
1
|
+
import{isToolRepeatLimitReached as e}from"@stable-harness/core";export function filterRepeatLimitedTools(t,i){return t&&i?t.filter(t=>"string"!=typeof t.name||!e(t.name,i)):t}
|
|
@@ -1,16 +1 @@
|
|
|
1
|
-
export declare function traceProjectionForBuiltinTool(toolId: string, phase: "agent.tool.start" | "agent.tool.result", args: unknown): {
|
|
2
|
-
traceType: string;
|
|
3
|
-
traceLabel: string;
|
|
4
|
-
subagentType: string | undefined;
|
|
5
|
-
todos?: undefined;
|
|
6
|
-
} | {
|
|
7
|
-
traceType: string;
|
|
8
|
-
traceLabel: string;
|
|
9
|
-
todos: any[];
|
|
10
|
-
subagentType?: undefined;
|
|
11
|
-
} | {
|
|
12
|
-
traceType?: undefined;
|
|
13
|
-
traceLabel?: undefined;
|
|
14
|
-
subagentType?: undefined;
|
|
15
|
-
todos?: undefined;
|
|
16
|
-
};
|
|
1
|
+
export declare function traceProjectionForBuiltinTool(toolId: string, phase: "agent.tool.start" | "agent.tool.result", args: unknown): {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export function traceProjectionForBuiltinTool(
|
|
1
|
+
import{createDelegationTraceProjection as t,createPlanTraceProjection as e}from"@stable-harness/core";export function traceProjectionForBuiltinTool(r,o,n){return"task"===r?t("agent.tool.start"===o?"delegation.start":"delegation.completed",{subagentType:readTaskSubagentType(n)}):"write_todos"===r&&"agent.tool.result"===o?e("plan.updated",{todos:readTodoArgs(n)}):{}}function readTaskSubagentType(t){const e=isRecord(t)?t:{};return readString(e.subagent_type)??readString(e.subagentType)}function readTodoArgs(t){const e=isRecord(t)?t:{};return Array.isArray(e.todos)?e.todos:[]}function isRecord(t){return"object"==typeof t&&null!==t&&!Array.isArray(t)}function readString(t){return"string"==typeof t&&t.trim()?t:void 0}
|
|
@@ -9,16 +9,14 @@
|
|
|
9
9
|
],
|
|
10
10
|
"main": "dist/src/index.js",
|
|
11
11
|
"types": "dist/src/index.d.ts",
|
|
12
|
-
"
|
|
12
|
+
"peerDependencies": {
|
|
13
13
|
"@botbotgo/better-call": "^0.1.58",
|
|
14
14
|
"@langchain/core": "^1.1.43",
|
|
15
15
|
"@langchain/ollama": "^1.2.7",
|
|
16
16
|
"@langchain/openai": "^1.4.5",
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
|
|
20
|
-
"peerDependencies": {
|
|
21
|
-
"deepagents": "^1.9.1"
|
|
17
|
+
"@stable-harness/core": "0.0.1",
|
|
18
|
+
"deepagents": "^1.9.1",
|
|
19
|
+
"langchain": "^1.3.1"
|
|
22
20
|
},
|
|
23
21
|
"peerDependenciesMeta": {
|
|
24
22
|
"deepagents": {
|
|
@@ -7,9 +7,11 @@ export * from "./runtime/persistence/inspection.js";
|
|
|
7
7
|
export { createWorkspaceSandboxPolicy } from "./runtime/governance/sandbox.js";
|
|
8
8
|
export * from "./memory-plugins.js";
|
|
9
9
|
export * from "./runtime/persistence/queue.js";
|
|
10
|
+
export * from "./runtime/policy/projection.js";
|
|
10
11
|
export * from "./runtime.js";
|
|
11
12
|
export * from "./runtime/selection-repair.js";
|
|
12
13
|
export * from "./runtime/tool-failure.js";
|
|
14
|
+
export * from "./runtime/policy/tool-invocation.js";
|
|
13
15
|
export * from "./runtime/persistence/stores.js";
|
|
14
16
|
export * from "./trace.js";
|
|
15
17
|
export * from "./types.js";
|