stable-harness 0.0.37 → 0.0.38
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/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-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 +39 -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 +33 -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 +16 -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 +20 -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 +19 -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 +52 -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 +47 -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/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 +15 -0
- package/node_modules/@stable-harness/core/dist/trace.js +1 -0
- package/node_modules/@stable-harness/core/dist/types.d.ts +144 -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 +32 -10
- 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/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,138 @@
|
|
|
1
|
+
export type MemoryKind = "semantic" | "episodic" | "procedural";
|
|
2
|
+
export type MemoryScope = "session" | "agent" | "workspace" | "user" | "project";
|
|
3
|
+
export type MemoryRecordStatus = "active" | "stale" | "conflicted" | "archived" | "pending_review";
|
|
4
|
+
export type MemorySensitivity = "public" | "internal" | "sensitive" | "restricted";
|
|
5
|
+
export type MemoryDecisionAction = "reject" | "store" | "merge" | "refresh" | "supersede" | "archive" | "review";
|
|
6
|
+
export type MemoryCandidate = {
|
|
7
|
+
namespace: string;
|
|
8
|
+
content: string;
|
|
9
|
+
sourceType?: string;
|
|
10
|
+
sourceRef?: string;
|
|
11
|
+
kindHint?: MemoryKind;
|
|
12
|
+
summary?: string;
|
|
13
|
+
scopeHint?: MemoryScope;
|
|
14
|
+
confidenceHint?: number;
|
|
15
|
+
tags?: string[];
|
|
16
|
+
sensitivity?: MemorySensitivity;
|
|
17
|
+
noStore?: boolean;
|
|
18
|
+
provenance?: Record<string, unknown>;
|
|
19
|
+
metadata?: Record<string, unknown>;
|
|
20
|
+
observedAt?: string;
|
|
21
|
+
};
|
|
22
|
+
export type MemoryDecision = {
|
|
23
|
+
action: MemoryDecisionAction;
|
|
24
|
+
reason: string;
|
|
25
|
+
recordId?: string;
|
|
26
|
+
kind?: MemoryKind;
|
|
27
|
+
scope?: MemoryScope;
|
|
28
|
+
confidence?: number;
|
|
29
|
+
ttlDays?: number;
|
|
30
|
+
retrievalPriority?: number;
|
|
31
|
+
reviewRequired?: boolean;
|
|
32
|
+
};
|
|
33
|
+
export type MemoryRecord = {
|
|
34
|
+
id: string;
|
|
35
|
+
namespace: string;
|
|
36
|
+
canonicalKey: string;
|
|
37
|
+
kind: MemoryKind;
|
|
38
|
+
scope: MemoryScope;
|
|
39
|
+
status: MemoryRecordStatus;
|
|
40
|
+
content: string;
|
|
41
|
+
summary?: string;
|
|
42
|
+
confidence: number;
|
|
43
|
+
sourceType?: string;
|
|
44
|
+
sourceRefs: string[];
|
|
45
|
+
tags: string[];
|
|
46
|
+
sensitivity: MemorySensitivity;
|
|
47
|
+
metadata: Record<string, unknown>;
|
|
48
|
+
createdAt: string;
|
|
49
|
+
observedAt: string;
|
|
50
|
+
lastConfirmedAt: string;
|
|
51
|
+
expiresAt?: string;
|
|
52
|
+
provenance: Record<string, unknown>;
|
|
53
|
+
revision: number;
|
|
54
|
+
supersedes: string[];
|
|
55
|
+
conflictsWith: string[];
|
|
56
|
+
retrievalPriority: number;
|
|
57
|
+
};
|
|
58
|
+
export type MemorizeInput = {
|
|
59
|
+
namespace: string;
|
|
60
|
+
content: string;
|
|
61
|
+
kind?: MemoryKind;
|
|
62
|
+
scope?: MemoryScope;
|
|
63
|
+
summary?: string;
|
|
64
|
+
confidence?: number;
|
|
65
|
+
tags?: string[];
|
|
66
|
+
sensitivity?: MemorySensitivity;
|
|
67
|
+
sourceType?: string;
|
|
68
|
+
sourceRef?: string;
|
|
69
|
+
metadata?: Record<string, unknown>;
|
|
70
|
+
provenance?: Record<string, unknown>;
|
|
71
|
+
observedAt?: string;
|
|
72
|
+
retrievalPriority?: number;
|
|
73
|
+
};
|
|
74
|
+
export type MemorySubmitResult = {
|
|
75
|
+
candidate: MemoryCandidate;
|
|
76
|
+
decision: MemoryDecision;
|
|
77
|
+
record?: MemoryRecord;
|
|
78
|
+
};
|
|
79
|
+
export type RecallInput = {
|
|
80
|
+
namespace: string;
|
|
81
|
+
query: string;
|
|
82
|
+
limit?: number;
|
|
83
|
+
kinds?: MemoryKind[];
|
|
84
|
+
scopes?: MemoryScope[];
|
|
85
|
+
statuses?: MemoryRecordStatus[];
|
|
86
|
+
};
|
|
87
|
+
export type MemoryRecallResult = {
|
|
88
|
+
records: MemoryRecord[];
|
|
89
|
+
context: string;
|
|
90
|
+
};
|
|
91
|
+
export type MemoryStoreSnapshot = {
|
|
92
|
+
namespace: string;
|
|
93
|
+
records: MemoryRecord[];
|
|
94
|
+
exportedAt: string;
|
|
95
|
+
};
|
|
96
|
+
export type MemoryPersistenceAdapter = {
|
|
97
|
+
load(namespace: string): Promise<MemoryRecord[]>;
|
|
98
|
+
save(snapshot: MemoryStoreSnapshot): Promise<void>;
|
|
99
|
+
};
|
|
100
|
+
export type MemoryMaintenanceAction = "mark_stale" | "archive" | "refresh" | "supersede";
|
|
101
|
+
export type MemoryMaintenanceOperation = {
|
|
102
|
+
action: MemoryMaintenanceAction;
|
|
103
|
+
recordId: string;
|
|
104
|
+
reason: string;
|
|
105
|
+
replacementRecordId?: string;
|
|
106
|
+
};
|
|
107
|
+
export type MemoryMaintenanceResult = {
|
|
108
|
+
operation: MemoryMaintenanceOperation;
|
|
109
|
+
record?: MemoryRecord;
|
|
110
|
+
applied: boolean;
|
|
111
|
+
reason: string;
|
|
112
|
+
};
|
|
113
|
+
export type ListMemoriesInput = {
|
|
114
|
+
namespace: string;
|
|
115
|
+
kinds?: MemoryKind[];
|
|
116
|
+
scopes?: MemoryScope[];
|
|
117
|
+
statuses?: MemoryRecordStatus[];
|
|
118
|
+
};
|
|
119
|
+
export type UpdateMemoryInput = {
|
|
120
|
+
id: string;
|
|
121
|
+
content?: string;
|
|
122
|
+
summary?: string;
|
|
123
|
+
status?: MemoryRecordStatus;
|
|
124
|
+
confidence?: number;
|
|
125
|
+
tags?: string[];
|
|
126
|
+
metadata?: Record<string, unknown>;
|
|
127
|
+
};
|
|
128
|
+
export type MemoryPolicy = {
|
|
129
|
+
decide(candidate: MemoryCandidate): MemoryDecision;
|
|
130
|
+
};
|
|
131
|
+
export type RuntimeMemoryStore = {
|
|
132
|
+
submitCandidate(candidate: MemoryCandidate): Promise<MemorySubmitResult>;
|
|
133
|
+
memorize(input: MemorizeInput): Promise<MemoryRecord>;
|
|
134
|
+
recall(input: RecallInput): Promise<MemoryRecallResult>;
|
|
135
|
+
list(input: ListMemoriesInput): Promise<MemoryRecord[]>;
|
|
136
|
+
update(input: UpdateMemoryInput): Promise<MemoryRecord | undefined>;
|
|
137
|
+
archive(id: string, reason?: string): Promise<MemoryRecord | undefined>;
|
|
138
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { type IncomingMessage, type ServerResponse } from "node:http";
|
|
2
|
+
import { type StableHarnessRuntime } from "@stable-harness/core";
|
|
3
|
+
export declare function createHttpServer(runtime: StableHarnessRuntime): import("node:http").Server<typeof IncomingMessage, typeof ServerResponse>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{createServer as t}from"node:http";import{compileWorkflowPlan as e,projectRuntimeTrace as r,renderWorkflowMermaid as o}from"@stable-harness/core";export function createHttpServer(n){return t(async(t,s)=>{try{if("GET"===t.method&&"/health"===t.url)return void sendJson(s,200,{ok:!0});if("GET"===t.method&&"/inspect"===t.url)return void sendJson(s,200,n.inspect());if("GET"===t.method&&"/requests"===t.url)return void sendJson(s,200,n.listRequests());if("GET"===t.method&&"/sessions"===t.url)return void sendJson(s,200,n.listSessions());const a=function readArtifactList(t){if(!t?.startsWith("/artifacts"))return;const e=new URL(t,"http://stable-harness.local");return"/artifacts"===e.pathname?{...e.searchParams.get("requestId")?{requestId:e.searchParams.get("requestId")}:{},...e.searchParams.get("sessionId")?{sessionId:e.searchParams.get("sessionId")}:{},...e.searchParams.get("agentId")?{agentId:e.searchParams.get("agentId")}:{}}:void 0}(t.url);if("GET"===t.method&&a)return void sendJson(s,200,n.listArtifacts(a));const d=function readArtifactContentId(t){const e=(t??"").match(/^\/artifacts\/([^/]+)\/content$/u);return e?.[1]?decodeURIComponent(e[1]):void 0}(t.url);if("GET"===t.method&&d){const t=n.getArtifact(d),e=n.readArtifact(d);return void sendJson(s,t&&void 0!==e?200:404,t&&void 0!==e?{artifact:t,content:e}:{error:"artifact_content_not_found"})}const i=function readArtifactId(t){const e=(t??"").match(/^\/artifacts\/([^/]+)$/u);return e?.[1]?decodeURIComponent(e[1]):void 0}(t.url);if("GET"===t.method&&i){const t=n.getArtifact(i);return void sendJson(s,t?200:404,t??{error:"artifact_not_found"})}const c=function readApprovalList(t){if(!t?.startsWith("/approvals"))return;const e=new URL(t,"http://stable-harness.local");if("/approvals"!==e.pathname)return;const r=e.searchParams.get("status");return{status:"pending"===r||"approved"===r||"rejected"===r?r:void 0}}(t.url);if("GET"===t.method&&c)return void sendJson(s,200,await n.listApprovals(c.status));const u=function readApprovalDecision(t){const e=(t??"").match(/^\/approvals\/([^/]+)\/(approve|reject)$/u);if(e?.[1]&&e[2])return{id:decodeURIComponent(e[1]),status:"approve"===e[2]?"approved":"rejected"}}(t.url);if("POST"===t.method&&u){const t=await n.resolveApproval(u.id,u.status);return void sendJson(s,t?200:404,t??{error:"approval_not_found"})}if("GET"===t.method&&"/workflows"===t.url)return void sendJson(s,200,n.inspect().workflows);const f=function readWorkflowMermaidId(t){const e=(t??"").match(/^\/workflows\/([^/]+)\/mermaid$/u);return e?.[1]?decodeURIComponent(e[1]):void 0}(t.url);if("GET"===t.method&&f){const t=n.getWorkflow(f);return void sendJson(s,t?200:404,t?{mermaid:o(t)}:{error:"workflow_not_found"})}const l=function readWorkflowPlanId(t){const e=(t??"").match(/^\/workflows\/([^/]+)\/plan$/u);return e?.[1]?decodeURIComponent(e[1]):void 0}(t.url);if("GET"===t.method&&l){const t=n.getWorkflow(l);return void sendJson(s,t?200:404,t?e(t):{error:"workflow_not_found"})}const p=function readRequestInspectionId(t){const e=(t??"").match(/^\/requests\/([^/]+)$/u);return e?.[1]?decodeURIComponent(e[1]):void 0}(t.url);if("GET"===t.method&&p){const t=n.inspectRequest(p);return void sendJson(s,t?200:404,t??{error:"request_not_found"})}const m=function readTraceRequestId(t){const e=(t??"").match(/^\/runs\/([^/]+)\/trace$/u);return e?.[1]?decodeURIComponent(e[1]):void 0}(t.url);if("GET"===t.method&&m){const t=n.getRun(m);return void sendJson(s,t?200:404,t?r(t):{error:"run_not_found"})}const h=function readReplayRequestId(t){const e=(t??"").match(/^\/requests\/([^/]+)\/replay$/u);return e?.[1]?decodeURIComponent(e[1]):void 0}(t.url);if("GET"===t.method&&h){const t=n.exportReplayBundle(h);return void sendJson(s,t?200:404,t??{error:"run_not_found"})}if("POST"===t.method&&"/requests"===t.url){const e=await async function readJson(t){const e=[];for await(const r of t)e.push(Buffer.isBuffer(r)?r:Buffer.from(r));return 0===e.length?{}:JSON.parse(Buffer.concat(e).toString("utf8"))}(t);return void sendJson(s,200,await n.request(function readRuntimeRequest(t){const e=function readToolCall(t){if("object"!=typeof t||null===t)return;const e=t;return"string"==typeof e.toolId?{toolId:e.toolId,args:e.args}:void 0}(t.toolCall),r=function readWorkflow(t){const e=readRecord(t);if(e)return{..."string"==typeof e.workflowId?{workflowId:e.workflowId}:{},..."string"==typeof e.routeId?{routeId:e.routeId}:{},...void 0!==e.input?{input:e.input}:{},..."object"==typeof e.metadata&&e.metadata?{metadata:e.metadata}:{}}}(t.workflow),o=function readMemory(t){const e=readRecord(t);if(e)return{..."string"==typeof e.namespace?{namespace:e.namespace}:{},...!1===e.recall||readRecord(e.recall)?{recall:e.recall}:{},...Array.isArray(e.candidates)?{candidates:e.candidates}:{}}}(t.memory),n=readRecord(t.metadata);return{input:"string"==typeof t.input?t.input:"",..."string"==typeof t.agentId?{agentId:t.agentId}:{},..."string"==typeof t.sessionId?{sessionId:t.sessionId}:{},..."string"==typeof t.requestId?{requestId:t.requestId}:{},..."string"==typeof t.parentRunId?{parentRunId:t.parentRunId}:{},...e?{toolCall:e}:{},...r?{workflow:r}:{},...o?{memory:o}:{},...n?{metadata:n}:{}}}(e)))}sendJson(s,404,{error:"not_found"})}catch(t){sendJson(s,500,{error:t instanceof Error?t.message:String(t)})}})}function readRecord(t){return"object"!=typeof t||null===t||Array.isArray(t)?void 0:t}function sendJson(t,e,r){t.writeHead(e,{"content-type":"application/json"}),t.end(JSON.stringify(r))}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export function createInProcessClient(e){return{request:t=>e.request(t),subscribe:t=>e.subscribe(t),inspect:()=>e.inspect(),getRuntimePolicy:()=>e.getRuntimePolicy(),getWorkflow:t=>e.getWorkflow(t),getRun:t=>e.getRun(t),listArtifacts:t=>e.listArtifacts(t),getArtifact:t=>e.getArtifact(t),readArtifact:t=>e.readArtifact(t),exportReplayBundle:t=>e.exportReplayBundle(t),listRequests:t=>e.listRequests(t),listSessions:()=>e.listSessions(),inspectRequest:t=>e.inspectRequest(t),listApprovals:t=>e.listApprovals(t),getApproval:t=>e.getApproval(t),resolveApproval:(t,s)=>e.resolveApproval(t,s),cancel:(t,s)=>e.cancel(t,s),stop:()=>e.stop()}}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { createInProcessClient } from "./in-process-client.js";
|
|
2
|
+
export { createHttpServer } from "./http-server.js";
|
|
3
|
+
export { createOpenAiCompatibleHttpServer } from "./openai-compatible.js";
|
|
4
|
+
export type { OpenAiCompatibleServerOptions } from "./openai-compatible.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{createInProcessClient}from"./in-process-client.js";export{createHttpServer}from"./http-server.js";export{createOpenAiCompatibleHttpServer}from"./openai-compatible.js";
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type IncomingMessage, type ServerResponse } from "node:http";
|
|
2
|
+
import type { StableHarnessRuntime } from "@stable-harness/core";
|
|
3
|
+
export type OpenAiCompatibleServerOptions = {
|
|
4
|
+
bearerToken?: string;
|
|
5
|
+
corsOrigins?: string[];
|
|
6
|
+
modelAgentMap?: Record<string, string>;
|
|
7
|
+
defaultModel?: string;
|
|
8
|
+
};
|
|
9
|
+
export declare function createOpenAiCompatibleHttpServer(runtime: StableHarnessRuntime, options?: OpenAiCompatibleServerOptions): import("node:http").Server<typeof IncomingMessage, typeof ServerResponse>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{createServer as e}from"node:http";import{createCapabilitiesResponse as r,createModelsResponse as t,resolveAgentId as o,toChatCompletion as n,toRuntimeRequest as a}from"./openai-payload.js";import{createContentChunk as s,createRoleChunk as i,createStopChunk as d,missingFinalDelta as c,writeChatSse as l,writeRuntimeStreamEvent as u,writeSseHeaders as p}from"./openai-stream.js";export function createOpenAiCompatibleHttpServer(f,m={}){const h=function resolveServerOptions(e,r){const t=function readOpenAiProtocolConfig(e){const r=readRecord(e)??{};return readRecord(r.openaiCompatible)??readRecord(r["openai-compatible"])??readRecord(r.openai)??{}}(e.getRuntimePolicy().protocols);return{bearerToken:r.bearerToken??readConfigString(t.bearerToken),corsOrigins:r.corsOrigins??(o=t.corsOrigins,Array.isArray(o)?o.filter(e=>"string"==typeof e&&e.trim().length>0):void 0),modelAgentMap:r.modelAgentMap??readStringRecord(t.modelAgentMap),defaultModel:r.defaultModel??readConfigString(t.defaultModel)};var o}(f,m);return e(async(e,m)=>{try{if(function applyCorsHeaders(e,r,t){const o=function allowedCorsOrigin(e,r){if(e)return r.corsOrigins?.includes("*")?"*":r.corsOrigins?.includes(e)||function isLoopbackOrigin(e){try{const r=new URL(e);return"http:"===r.protocol&&["localhost","127.0.0.1","[::1]"].includes(r.hostname)}catch{return!1}}(e)?e:void 0}(e.headers.origin,t);o&&(r.setHeader("access-control-allow-origin",o),r.setHeader("vary","origin"))}(e,m,h),function handleCors(e,r){return"OPTIONS"===e.method&&(r.writeHead(204,{"access-control-allow-headers":"authorization, content-type, idempotency-key","access-control-allow-methods":"GET, POST, OPTIONS"}),r.end(),!0)}(e,m))return;if(!function isAuthorized(e,r){return!r.bearerToken||e.headers.authorization===`Bearer ${r.bearerToken}`}(e,h))return void sendJson(m,401,{error:{message:"unauthorized",type:"invalid_request_error"}});if("GET"===e.method&&"/v1/models"===e.url)return void sendJson(m,200,t(f,h));if("GET"===e.method&&"/v1/capabilities"===e.url)return void sendJson(m,200,r());const v=function readApprovalList(e){if(!e?.startsWith("/v1/approvals"))return;const r=new URL(e,"http://stable-harness.local");if("/v1/approvals"!==r.pathname)return;const t=r.searchParams.get("status");return{status:"pending"===t||"approved"===t||"rejected"===t?t:void 0}}(e.url);if("GET"===e.method&&v)return void sendJson(m,200,{data:await f.listApprovals(v.status)});const g=function readApprovalDecision(e){const r=(e??"").match(/^\/v1\/approvals\/([^/]+)\/(approve|reject)$/u);if(r?.[1]&&r[2])return{id:decodeURIComponent(r[1]),status:"approve"===r[2]?"approved":"rejected"}}(e.url);if("POST"===e.method&&g){const e=await f.resolveApproval(g.id,g.status);return void sendJson(m,e?200:404,e?{data:e}:{error:{message:"approval_not_found",type:"invalid_request_error"}})}if("POST"===e.method&&"/v1/chat/completions"===e.url)return void await async function handleChatCompletion(e,r,t,f){const m=await async function readJson(e){const r=[];for await(const t of e)r.push(Buffer.isBuffer(t)?t:Buffer.from(t));return 0===r.length?{}:JSON.parse(Buffer.concat(r).toString("utf8"))}(r);if(m.model&&!o(m.model,e,f))return void sendJson(t,404,{error:{message:`model_not_found: ${m.model}`,type:"invalid_request_error"}});const h=a(m,e,f,{sessionId:readHeaderString(r.headers["x-stable-harness-session-id"])});if(m.stream)return void await async function streamChatCompletion(e,r,t,o){p(r,{"access-control-allow-headers":"authorization, content-type, idempotency-key","access-control-allow-methods":"GET, POST, OPTIONS"}),l(r,i(o.requestId,t.model));let n="";const a=e.subscribe(e=>{e.requestId===o.requestId&&(n+=u(r,e,o.requestId,t.model)??"")});try{const a=await e.request(o),i=c(n,a.output);i&&l(r,s(o.requestId,t.model,i)),l(r,d(o.requestId,t.model)),r.write("data: [DONE]\n\n"),r.end()}finally{a()}}(e,t,m,h);const v=await e.request(h);sendJson(t,200,n(m,v))}(f,e,m,h);sendJson(m,404,{error:{message:"not_found",type:"invalid_request_error"}})}catch(e){sendJson(m,400,{error:{message:e instanceof Error?e.message:String(e),type:"invalid_request_error"}})}})}function readRecord(e){return"object"!=typeof e||null===e||Array.isArray(e)?void 0:e}function readStringRecord(e){const r=readRecord(e);if(r)return Object.fromEntries(Object.entries(r).filter(e=>"string"==typeof e[1]))}function readConfigString(e){if("string"!=typeof e||!e.trim())return;const r=e.match(/^\$\{env:([A-Za-z_][A-Za-z0-9_]*)(?::-(.*))?\}$/u);return r?process.env[r[1]]??r[2]:e}function readHeaderString(e){const r=Array.isArray(e)?e[0]:e;return r&&r.trim()?r:void 0}function sendJson(e,r,t,o){e.writeHead(r,{"content-type":"application/json","access-control-allow-headers":"authorization, content-type, idempotency-key","access-control-allow-methods":"GET, POST, OPTIONS"}),e.end(JSON.stringify(t))}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type { RuntimeResponse, StableHarnessRuntime } from "@stable-harness/core";
|
|
2
|
+
import type { OpenAiCompatibleServerOptions } from "./openai-compatible.js";
|
|
3
|
+
export type ChatMessage = {
|
|
4
|
+
role?: string;
|
|
5
|
+
content?: unknown;
|
|
6
|
+
};
|
|
7
|
+
export type ChatCompletionRequest = {
|
|
8
|
+
model?: string;
|
|
9
|
+
messages?: ChatMessage[];
|
|
10
|
+
stream?: boolean;
|
|
11
|
+
user?: string;
|
|
12
|
+
metadata?: Record<string, unknown>;
|
|
13
|
+
};
|
|
14
|
+
export type ChatProtocolContext = {
|
|
15
|
+
sessionId?: string;
|
|
16
|
+
};
|
|
17
|
+
export declare function toRuntimeRequest(body: ChatCompletionRequest, runtime: StableHarnessRuntime, options: OpenAiCompatibleServerOptions, context?: ChatProtocolContext): {
|
|
18
|
+
metadata: {
|
|
19
|
+
protocol: string;
|
|
20
|
+
openaiStream: boolean;
|
|
21
|
+
openaiMessages: {
|
|
22
|
+
role: string;
|
|
23
|
+
content: string;
|
|
24
|
+
}[];
|
|
25
|
+
openaiSessionHistory: boolean;
|
|
26
|
+
model: string | undefined;
|
|
27
|
+
user: string | undefined;
|
|
28
|
+
clientMetadata: Record<string, unknown> | undefined;
|
|
29
|
+
};
|
|
30
|
+
sessionId?: string | undefined;
|
|
31
|
+
input: string;
|
|
32
|
+
requestId: string;
|
|
33
|
+
agentId: string | undefined;
|
|
34
|
+
};
|
|
35
|
+
export declare function resolveAgentId(model: string | undefined, runtime: StableHarnessRuntime, options: OpenAiCompatibleServerOptions): string | undefined;
|
|
36
|
+
export declare function createModelsResponse(runtime: StableHarnessRuntime, options: OpenAiCompatibleServerOptions): {
|
|
37
|
+
object: string;
|
|
38
|
+
data: {
|
|
39
|
+
id: string;
|
|
40
|
+
object: string;
|
|
41
|
+
created: number;
|
|
42
|
+
owned_by: string;
|
|
43
|
+
}[];
|
|
44
|
+
};
|
|
45
|
+
export declare function createCapabilitiesResponse(): {
|
|
46
|
+
object: string;
|
|
47
|
+
endpoints: string[];
|
|
48
|
+
streaming: boolean;
|
|
49
|
+
toolProgressEvents: boolean;
|
|
50
|
+
};
|
|
51
|
+
export declare function toChatCompletion(body: ChatCompletionRequest, result: RuntimeResponse): {
|
|
52
|
+
id: string;
|
|
53
|
+
object: string;
|
|
54
|
+
created: number;
|
|
55
|
+
model: string;
|
|
56
|
+
choices: {
|
|
57
|
+
index: number;
|
|
58
|
+
message: {
|
|
59
|
+
role: string;
|
|
60
|
+
content: string;
|
|
61
|
+
};
|
|
62
|
+
finish_reason: string;
|
|
63
|
+
}[];
|
|
64
|
+
usage: {
|
|
65
|
+
prompt_tokens: number;
|
|
66
|
+
completion_tokens: number;
|
|
67
|
+
total_tokens: number;
|
|
68
|
+
};
|
|
69
|
+
metadata: {
|
|
70
|
+
sessionId: string;
|
|
71
|
+
agentId: string;
|
|
72
|
+
state: import("@stable-harness/core").RuntimeRecordState;
|
|
73
|
+
};
|
|
74
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{randomUUID as e}from"node:crypto";export function toRuntimeRequest(t,n,s,o={}){const r=function messagesToInput(e){if(!Array.isArray(e)||0===e.length)throw new Error("messages must be a non-empty array");return e.map(e=>`${e.role??"user"}: ${contentToText(e.content)}`).join("\n\n")}(t.messages),a=`chatcmpl-${e()}`,i=o.sessionId??function readSessionId(e){const t=e?.sessionId??e?.session_id??e?.conversationId??e?.conversation_id;return"string"==typeof t&&t.trim()?t:void 0}(t.metadata),c=normalizeOpenAiMessages(t.messages),u=i?function prependSessionMessages(e,t,n){if(function hasClientHistory(e){return e.some(e=>"assistant"===e.role)||e.filter(e=>"user"===e.role).length>1}(n))return n;const s=e.listRequests({sessionId:t,state:"completed"}).flatMap(t=>function inspectSessionTurn(e,t){const n=e.inspectRequest(t),s=n?.output?.trim(),o=function lastUserMessage(e){return normalizeOpenAiMessages(Array.isArray(e)?e:void 0).filter(e=>"user"===e.role&&e.content.trim()).at(-1)}(n?.metadata?.openaiMessages)?.content;return o&&s?[{role:"user",content:o},{role:"assistant",content:s}]:[]}(e,t.requestId)).slice(-12);return s.length>0?[...s,...n]:n}(n,i,c):c;return{input:r,requestId:a,agentId:resolveAgentId(t.model,n,s),...i?{sessionId:i}:{},metadata:{protocol:"openai-compatible",openaiStream:!0===t.stream,openaiMessages:u,openaiSessionHistory:u.length>c.length,model:t.model,user:t.user,clientMetadata:t.metadata}}}export function resolveAgentId(e,t,n){if(!e)return;const s=n.modelAgentMap?.[e];return s||(t.inspect().agents.includes(e)?e:void 0)}export function createModelsResponse(e,t){const n=Object.keys(t.modelAgentMap??{});return{object:"list",data:[...new Set([...e.inspect().agents,...n])].sort().map(e=>({id:e,object:"model",created:0,owned_by:"stable-harness"}))}}export function createCapabilitiesResponse(){return{object:"stable_harness.capabilities",endpoints:["/v1/models","/v1/chat/completions","/v1/capabilities"],streaming:!0,toolProgressEvents:!0}}export function toChatCompletion(e,t){return{id:t.requestId,object:"chat.completion",created:Math.floor(Date.now()/1e3),model:e.model??t.agentId,choices:[{index:0,message:{role:"assistant",content:t.output},finish_reason:"stop"}],usage:estimateUsage(e.messages,t.output),metadata:{sessionId:t.sessionId,agentId:t.agentId,state:t.state}}}function normalizeOpenAiMessages(e){return Array.isArray(e)?e.map(e=>({role:e.role??"user",content:contentToText(e.content)})):[]}function contentToText(e){if("string"==typeof e)return e;if(!Array.isArray(e))throw new Error("message content must be a string or content part array");return e.map(contentPartToText).join("\n")}function contentPartToText(e){if("object"!=typeof e||null===e)throw new Error("message content parts must be objects");const t=e;if("text"===t.type&&"string"==typeof t.text)return t.text;const n=t.image_url;if("image_url"===t.type&&"string"==typeof n?.url)return`[image:${n.url}]`;throw new Error("unsupported_content_type")}function estimateUsage(e,t){const n=estimateTokens(Array.isArray(e)?e.map(e=>contentToText(e.content)).join("\n"):""),s=estimateTokens(t);return{prompt_tokens:n,completion_tokens:s,total_tokens:n+s}}function estimateTokens(e){return e.trim()?Math.ceil(1.3*e.trim().split(/\s+/u).length):0}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { ServerResponse } from "node:http";
|
|
2
|
+
import type { RuntimeEvent } from "@stable-harness/core";
|
|
3
|
+
export declare function missingFinalDelta(streamedContent: string, finalOutput: string): string;
|
|
4
|
+
export declare function createRoleChunk(id: string, model: string | undefined): {
|
|
5
|
+
id: string;
|
|
6
|
+
object: string;
|
|
7
|
+
created: number;
|
|
8
|
+
model: string;
|
|
9
|
+
choices: {
|
|
10
|
+
index: number;
|
|
11
|
+
delta: Record<string, unknown>;
|
|
12
|
+
finish_reason: string | null;
|
|
13
|
+
}[];
|
|
14
|
+
};
|
|
15
|
+
export declare function createContentChunk(id: string, model: string | undefined, content: string): {
|
|
16
|
+
id: string;
|
|
17
|
+
object: string;
|
|
18
|
+
created: number;
|
|
19
|
+
model: string;
|
|
20
|
+
choices: {
|
|
21
|
+
index: number;
|
|
22
|
+
delta: Record<string, unknown>;
|
|
23
|
+
finish_reason: string | null;
|
|
24
|
+
}[];
|
|
25
|
+
};
|
|
26
|
+
export declare function createStopChunk(id: string, model: string | undefined): {
|
|
27
|
+
id: string;
|
|
28
|
+
object: string;
|
|
29
|
+
created: number;
|
|
30
|
+
model: string;
|
|
31
|
+
choices: {
|
|
32
|
+
index: number;
|
|
33
|
+
delta: Record<string, unknown>;
|
|
34
|
+
finish_reason: string | null;
|
|
35
|
+
}[];
|
|
36
|
+
};
|
|
37
|
+
export declare function writeRuntimeStreamEvent(response: ServerResponse, event: RuntimeEvent, id: string, model: string | undefined): string | undefined;
|
|
38
|
+
export declare function writeSseHeaders(response: ServerResponse, headers: Record<string, string>): void;
|
|
39
|
+
export declare function writeChatSse(response: ServerResponse, body: unknown): void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export function missingFinalDelta(e,t){return e?!t||e.includes(t)?"":t.startsWith(e)?t.slice(e.length):t:t}export function createRoleChunk(e,t){return createChunk(e,t,{role:"assistant"},null)}export function createContentChunk(e,t,n){return createChunk(e,t,{content:n},null)}export function createStopChunk(e,t){return createChunk(e,t,{},"stop")}export function writeRuntimeStreamEvent(e,t,n,r){const o=function readAdapterDelta(e){if("runtime.adapter.event"!==e.type||"object"!=typeof e.event||null===e.event)return;const t=e.event;return"agent.output.delta"===t.phase&&"string"==typeof t.text?t.text:void 0}(t);if(o)return writeChatSse(e,createContentChunk(n,r,o)),o;!function writeProgressEvent(e,t){const n=function readToolProgress(e){if("runtime.tool.direct.started"===e.type||"runtime.tool.direct.completed"===e.type)return{request_id:e.requestId,session_id:e.sessionId,agent_id:e.agentId,type:e.type,tool_id:e.toolId};if("runtime.adapter.event"!==e.type||"object"!=typeof e.event||null===e.event)return;const t=e.event,n="agent.tool.start"===t.phase||"agent.tool.result"===t.phase?t.phase:void 0,r="string"==typeof t.toolId?t.toolId:void 0;return n&&r?{request_id:e.requestId,session_id:e.sessionId,agent_id:e.agentId,type:n,tool_id:r,adapter:t.adapter}:void 0}(t);n&&writeSse(e,"stable_harness.tool.progress",n)}(e,t),function writeNarrationEvent(e,t){"runtime.progress.narration"===t.type&&writeSse(e,"stable_harness.progress.narration",{request_id:t.requestId,session_id:t.sessionId,agent_id:t.agentId,type:t.type,message:t.message,provider:t.provider,source_event_types:t.sourceEventTypes,source_event_ids:t.sourceEventIds,model:t.model,style:t.style})}(e,t)}export function writeSseHeaders(e,t){e.writeHead(200,{"content-type":"text/event-stream","cache-control":"no-cache",connection:"keep-alive",...t})}export function writeChatSse(e,t){e.write(`data: ${JSON.stringify(t)}\n\n`)}function createChunk(e,t,n,r){return{id:e,object:"chat.completion.chunk",created:Math.floor(Date.now()/1e3),model:t??"stable-harness",choices:[{index:0,delta:n,finish_reason:r}]}}function writeSse(e,t,n){e.write(`event: ${t}\n`),e.write(`data: ${JSON.stringify(n)}\n\n`)}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@stable-harness/protocols",
|
|
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
|
+
"@stable-harness/core": "0.0.1"
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { BetterToolLike, RepairFunction, RepairModelLike, RepairPolicy } from "@botbotgo/better-call";
|
|
2
|
+
import type { ToolArgumentGuard, ToolArgumentIssue, ToolGatewayContext, ToolGatewayTool } from "./types.js";
|
|
3
|
+
type ToolGatewayRuntimeTool = ToolGatewayTool & {
|
|
4
|
+
validationTool?: BetterToolLike;
|
|
5
|
+
};
|
|
6
|
+
export type BetterCallArgumentRepairOptions = {
|
|
7
|
+
mode?: "guard" | "repair" | "review";
|
|
8
|
+
repair?: RepairFunction;
|
|
9
|
+
repairModel?: RepairModelLike;
|
|
10
|
+
repairPolicy?: RepairPolicy;
|
|
11
|
+
};
|
|
12
|
+
export type ToolArgumentGuardOptions = {
|
|
13
|
+
betterCall?: BetterCallArgumentRepairOptions;
|
|
14
|
+
};
|
|
15
|
+
export type BetterCallToolSelectionRepair = {
|
|
16
|
+
toolId: string;
|
|
17
|
+
args: unknown;
|
|
18
|
+
};
|
|
19
|
+
export declare class ToolArgumentValidationError extends Error {
|
|
20
|
+
readonly toolId: string;
|
|
21
|
+
readonly issues: ToolArgumentIssue[];
|
|
22
|
+
constructor(toolId: string, issues: ToolArgumentIssue[]);
|
|
23
|
+
}
|
|
24
|
+
export declare function createDefaultArgumentGuard(options?: ToolArgumentGuardOptions): ToolArgumentGuard;
|
|
25
|
+
export declare function assertToolArguments(tool: ToolGatewayTool, args: unknown, context: ToolGatewayContext, guard: ToolArgumentGuard): Promise<unknown>;
|
|
26
|
+
export declare function prepareBetterCallTools(tools: ToolGatewayTool[], options: BetterCallArgumentRepairOptions | undefined): ToolGatewayRuntimeTool[];
|
|
27
|
+
export declare function repairBetterCallToolSelection(input: {
|
|
28
|
+
toolId: string;
|
|
29
|
+
args: unknown;
|
|
30
|
+
tools: ToolGatewayTool[];
|
|
31
|
+
options: BetterCallArgumentRepairOptions | undefined;
|
|
32
|
+
}): Promise<BetterCallToolSelectionRepair | undefined>;
|
|
33
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{BetterToolValidationError as o,betterTools as t,defaultRepair as e,reliableToolCalls as a}from"@botbotgo/better-call";import{isRecord as r,validateWithZodSchema as i}from"./schema-validation.js";export class ToolArgumentValidationError extends Error{toolId;issues;constructor(o,t){super(`Tool argument validation failed for ${o}: ${t.map(o=>`${o.path} ${o.message}`).join("; ")}`),this.toolId=o,this.issues=t,this.name="ToolArgumentValidationError"}}export function createDefaultArgumentGuard(t={}){return{async validate(e){const a=e.tool.validateArgs?await e.tool.validateArgs({args:e.args,context:e.context}):{action:"allow",args:e.args};if("reject"===a.action)return a;const r=await async function validateWithBetterCall(t,e,a){const r=i(t.schema,e);if(void 0===t.schema)return r??{action:"allow",args:e};const l=await async function invokeBetterCallValidation(t,e,a){try{return{action:"allow",args:await createBetterCallValidationTool(t,a).invoke(e)}}catch(t){if(t instanceof o)return{action:"reject",reason:"BetterCall validation failed",issues:t.issues.map(toToolArgumentIssue)};throw t}}(t,"allow"===r?.action?r.args:e,a);return r?"allow"===r.action?l:"reject"===l.action?r:i(t.schema,l.args)||l:l}(e.tool,a.args,t.betterCall);return"reject"===r.action?r:"repair"===a.action?{...a,args:r.args}:r}}}export function assertToolArguments(o,t,e,a){return Promise.resolve(a.validate({tool:o,args:t,context:e})).then(t=>{if("reject"===t.action)throw new ToolArgumentValidationError(o.id,t.issues);return t.args})}export function prepareBetterCallTools(o,e){const a=t(o.map(toBetterCallTool),toBetterToolsOptions(e));return o.map((o,t)=>({...o,validationTool:a[t]}))}export async function repairBetterCallToolSelection(o){const t=function resolveRepair(o){return o?.repair??(o?.repairModel?e(o.repairModel):void 0)}(o.options);if(!t||0===o.tools.length)return;const i=await a({userInput:JSON.stringify({tool:o.toolId,args:o.args}),tools:o.tools.map(toToolDefinition),calls:[{tool:o.toolId,args:(l=o.args,r(l)?l:{input:l})}],repair:t,repairPolicy:o.options?.repairPolicy??{allowCoercion:!0,allowClamp:!0,allowArrayStringSplit:!0,allowModelRepair:!0},mode:o.options?.mode??"repair"});var l;const n=i.ok?i.calls.find(t=>o.tools.some(o=>o.id===t.tool)):void 0;return n?{toolId:n.tool,args:n.args}:void 0}function createBetterCallValidationTool(o,e){return o.validationTool??t([toBetterCallTool(o)],toBetterToolsOptions(e))[0]}function toBetterCallTool(o){return{name:o.id,description:o.description,schema:o.schema,invoke:o=>o}}function toToolDefinition(o){return{name:o.id,description:o.description,schema:o.schema}}function toToolArgumentIssue(o){return{path:o.path.replace(/^\$\.calls\[\d+\]\.args/u,"$"),message:o.message,expected:void 0===o.expected?void 0:String(o.expected),actual:o.actual}}function toBetterToolsOptions(o){return{mode:o?.mode??"repair",repair:o?.repair,repairModel:o?.repairModel,repairPolicy:o?.repairPolicy??{allowCoercion:!0,allowClamp:!0,allowArrayStringSplit:!0,allowModelRepair:!0}}}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { ToolGateway, ToolGatewayTool } from "./types.js";
|
|
2
|
+
import type { ToolArgumentGuardOptions } from "./argument-guard.js";
|
|
3
|
+
export type ToolGatewayOptions = ToolArgumentGuardOptions;
|
|
4
|
+
export declare function createInMemoryToolGateway(tools: ToolGatewayTool[], options?: ToolGatewayOptions): ToolGateway;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{assertToolArguments as o,createDefaultArgumentGuard as t,prepareBetterCallTools as e,repairBetterCallToolSelection as r,ToolArgumentValidationError as a}from"./argument-guard.js";export function createInMemoryToolGateway(l,i={}){const s=new Map(e(l,i.betterCall).map(o=>[o.id,o])),n=t(i),repairToolCall=async o=>{const t=o.allowedToolIds?new Set(o.allowedToolIds):void 0,e=[...s.values()].filter(o=>!t||t.has(o.id));return r({toolId:o.toolId,args:o.args,tools:e,options:withRequestRepairModel(i.betterCall,o.repairModel)})};return{list:()=>[...s.values()],get:o=>s.get(o),repairToolCall:repairToolCall,async invoke(t){const e=s.has(t.toolId)?void 0:await repairToolCall(t),r=e?.toolId??t.toolId,l=s.get(r);if(!l)throw new Error(`Tool is not registered: ${t.toolId}`);const i=await async function assertToolArgumentsWithRepair(t){try{return await o(t.tool,t.initialArgs,t.request.context,t.guard)}catch(e){if(!(e instanceof a))throw e;const r=await t.repairToolCall({...t.request,args:t.initialArgs,allowedToolIds:[t.tool.id]});if(!r||r.toolId!==t.tool.id)throw e;return o(t.tool,r.args,t.request.context,t.guard)}}({request:t,tool:l,initialArgs:e?.args??t.args,repairToolCall:repairToolCall,guard:n});return{toolId:l.id,output:await l.invoke(i,t.context)}}}}function withRequestRepairModel(o,t){return!t||o?.repair||o?.repairModel?o:{...o,mode:o?.mode??"repair",repairModel:t}}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { createDefaultArgumentGuard, ToolArgumentValidationError } from "./argument-guard.js";
|
|
2
|
+
export { createInMemoryToolGateway } from "./in-memory.js";
|
|
3
|
+
export { createModuleToolGateway } from "./module-loader.js";
|
|
4
|
+
export type { BetterCallArgumentRepairOptions, ToolArgumentGuardOptions } from "./argument-guard.js";
|
|
5
|
+
export type { ToolGatewayOptions } from "./in-memory.js";
|
|
6
|
+
export type { ModuleToolDescriptor } from "./module-loader.js";
|
|
7
|
+
export type { ToolArgumentGuard, ToolArgumentGuardResult, ToolArgumentIssue, ToolArgumentValidator, ToolGateway, ToolGatewayContext, ToolGatewayInvokeRequest, ToolGatewayInvokeResult, ToolGatewayRepairRequest, ToolGatewayRepairResult, ToolGatewayTool, } from "./types.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{createDefaultArgumentGuard,ToolArgumentValidationError}from"./argument-guard.js";export{createInMemoryToolGateway}from"./in-memory.js";export{createModuleToolGateway}from"./module-loader.js";
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ToolGatewayOptions } from "./in-memory.js";
|
|
2
|
+
import type { ToolGateway } from "./types.js";
|
|
3
|
+
export type ModuleToolDescriptor = {
|
|
4
|
+
id: string;
|
|
5
|
+
name?: string;
|
|
6
|
+
description?: string;
|
|
7
|
+
schema?: unknown;
|
|
8
|
+
sourcePath?: string;
|
|
9
|
+
};
|
|
10
|
+
export declare function createModuleToolGateway(input: {
|
|
11
|
+
tools: Iterable<ModuleToolDescriptor>;
|
|
12
|
+
options?: ToolGatewayOptions;
|
|
13
|
+
}): Promise<ToolGateway>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import o from"node:path";import{pathToFileURL as e}from"node:url";import{createInMemoryToolGateway as t}from"./in-memory.js";export async function createModuleToolGateway(o){const e=[];for(const t of o.tools){const o=await loadModuleTool(t);o&&e.push(o)}return t(e,o.options)}async function loadModuleTool(t){if(!t.sourcePath)return;const n=await import(e(o.resolve(t.sourcePath)).href),r=n[t.name??t.id]??n.default;return function hasInvoke(o){return"object"==typeof o&&null!==o&&"invoke"in o&&"function"==typeof o.invoke}(r)?{id:t.id,description:t.description??r.description,schema:t.schema??r.schema,validateArgs:r.validateArgs,invoke:(o,e)=>async function invokeWithWorkspaceCwd(o,e,t){const n=process.cwd();try{return process.chdir(t.workspaceRoot),await o(e,t)}finally{process.chdir(n)}}(r.invoke,o,e)}:void 0}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{normalizeArgsBySchema as e}from"@botbotgo/better-call";export function validateWithZodSchema(t,o){return isZodLike(t)?toZodGuardResult(t.safeParse(o??{})):function isZodShape(e){return isRecord(e)&&Object.values(e).length>0&&Object.values(e).every(isZodLike)}(t)?function validateWithZodShape(t,o){const r=function normalizeZodShapeArgs(t,o){const r=isRecord(o)?o:{};return e(t,r,{allowCoercion:!0,allowClamp:!0,allowArrayStringSplit:!0}).args}(t,o),a={},s=[];for(const[e,o]of Object.entries(t)){const t=o.safeParse(r[e]);t.success?void 0!==t.data&&(a[e]=t.data):s.push(...t.error.issues.map(t=>({...t,path:[e,...t.path]})))}return s.length>0?toZodGuardResult({success:!1,error:{issues:s}}):{action:"allow",args:a}}(t,o):void 0}export function isRecord(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}function toZodGuardResult(e){return e.success?{action:"allow",args:e.data}:{action:"reject",reason:"Zod schema validation failed",issues:e.error.issues.map(e=>{return{path:(t=e.path,t.length>0?`$.${t.map(String).join(".")}`:"$"),message:e.message,expected:"schema"};var t})}}function isZodLike(e){return isRecord(e)&&"function"==typeof e.safeParse}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
export type ToolGatewayContext = {
|
|
2
|
+
workspaceRoot: string;
|
|
3
|
+
requestId: string;
|
|
4
|
+
sessionId: string;
|
|
5
|
+
agentId: string;
|
|
6
|
+
requestInput?: string;
|
|
7
|
+
observedEvidence?: string;
|
|
8
|
+
approvalIds?: string[];
|
|
9
|
+
sandbox?: ToolGatewaySandboxDecision;
|
|
10
|
+
};
|
|
11
|
+
export type ToolGatewaySandboxDecision = {
|
|
12
|
+
action: "allow" | "deny";
|
|
13
|
+
profile?: string;
|
|
14
|
+
reason?: string;
|
|
15
|
+
policyId?: string;
|
|
16
|
+
metadata?: Record<string, unknown>;
|
|
17
|
+
};
|
|
18
|
+
export type ToolGatewayTool = {
|
|
19
|
+
id: string;
|
|
20
|
+
description?: string;
|
|
21
|
+
schema?: unknown;
|
|
22
|
+
validateArgs?: ToolArgumentValidator;
|
|
23
|
+
invoke(args: unknown, context: ToolGatewayContext): Promise<unknown>;
|
|
24
|
+
};
|
|
25
|
+
export type ToolArgumentIssue = {
|
|
26
|
+
path: string;
|
|
27
|
+
message: string;
|
|
28
|
+
expected?: string;
|
|
29
|
+
actual?: unknown;
|
|
30
|
+
};
|
|
31
|
+
export type ToolArgumentGuardResult = {
|
|
32
|
+
action: "allow";
|
|
33
|
+
args: unknown;
|
|
34
|
+
} | {
|
|
35
|
+
action: "repair";
|
|
36
|
+
args: unknown;
|
|
37
|
+
reason: string;
|
|
38
|
+
issues: ToolArgumentIssue[];
|
|
39
|
+
} | {
|
|
40
|
+
action: "reject";
|
|
41
|
+
reason: string;
|
|
42
|
+
issues: ToolArgumentIssue[];
|
|
43
|
+
};
|
|
44
|
+
export type ToolArgumentGuard = {
|
|
45
|
+
validate(input: {
|
|
46
|
+
tool: ToolGatewayTool;
|
|
47
|
+
args: unknown;
|
|
48
|
+
context: ToolGatewayContext;
|
|
49
|
+
}): Promise<ToolArgumentGuardResult> | ToolArgumentGuardResult;
|
|
50
|
+
};
|
|
51
|
+
export type ToolArgumentValidator = (input: {
|
|
52
|
+
args: unknown;
|
|
53
|
+
context: ToolGatewayContext;
|
|
54
|
+
}) => Promise<ToolArgumentGuardResult> | ToolArgumentGuardResult;
|
|
55
|
+
export type ToolGatewayInvokeRequest = {
|
|
56
|
+
toolId: string;
|
|
57
|
+
args?: unknown;
|
|
58
|
+
repairModel?: {
|
|
59
|
+
invoke(input: unknown): Promise<unknown> | unknown;
|
|
60
|
+
};
|
|
61
|
+
context: ToolGatewayContext;
|
|
62
|
+
};
|
|
63
|
+
export type ToolGatewayRepairRequest = ToolGatewayInvokeRequest & {
|
|
64
|
+
allowedToolIds?: string[];
|
|
65
|
+
};
|
|
66
|
+
export type ToolGatewayInvokeResult = {
|
|
67
|
+
toolId: string;
|
|
68
|
+
output: unknown;
|
|
69
|
+
};
|
|
70
|
+
export type ToolGatewayRepairResult = {
|
|
71
|
+
toolId: string;
|
|
72
|
+
args: unknown;
|
|
73
|
+
};
|
|
74
|
+
export type ToolGateway = {
|
|
75
|
+
list(): ToolGatewayTool[];
|
|
76
|
+
get(toolId: string): ToolGatewayTool | undefined;
|
|
77
|
+
repairToolCall?(request: ToolGatewayRepairRequest): Promise<ToolGatewayRepairResult | undefined>;
|
|
78
|
+
invoke(request: ToolGatewayInvokeRequest): Promise<ToolGatewayInvokeResult>;
|
|
79
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{};
|
|
@@ -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)}:{}}}
|