harness-dispatch 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +582 -0
- package/config.default.yaml +397 -0
- package/data/coding_benchmarks.json +431 -0
- package/dist/auth.d.ts +9 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +73 -0
- package/dist/auth.js.map +1 -0
- package/dist/billing.d.ts +7 -0
- package/dist/billing.d.ts.map +1 -0
- package/dist/billing.js +201 -0
- package/dist/billing.js.map +1 -0
- package/dist/bin.d.ts +6 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +488 -0
- package/dist/bin.js.map +1 -0
- package/dist/breaker-store.d.ts +31 -0
- package/dist/breaker-store.d.ts.map +1 -0
- package/dist/breaker-store.js +103 -0
- package/dist/breaker-store.js.map +1 -0
- package/dist/circuit-breaker.d.ts +47 -0
- package/dist/circuit-breaker.d.ts.map +1 -0
- package/dist/circuit-breaker.js +102 -0
- package/dist/circuit-breaker.js.map +1 -0
- package/dist/config.d.ts +48 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +1248 -0
- package/dist/config.js.map +1 -0
- package/dist/dashboard/live.d.ts +49 -0
- package/dist/dashboard/live.d.ts.map +1 -0
- package/dist/dashboard/live.js +149 -0
- package/dist/dashboard/live.js.map +1 -0
- package/dist/dispatch-log.d.ts +46 -0
- package/dist/dispatch-log.d.ts.map +1 -0
- package/dist/dispatch-log.js +89 -0
- package/dist/dispatch-log.js.map +1 -0
- package/dist/dispatchers/base.d.ts +55 -0
- package/dist/dispatchers/base.d.ts.map +1 -0
- package/dist/dispatchers/base.js +80 -0
- package/dist/dispatchers/base.js.map +1 -0
- package/dist/dispatchers/generic-cli.d.ts +30 -0
- package/dist/dispatchers/generic-cli.d.ts.map +1 -0
- package/dist/dispatchers/generic-cli.js +471 -0
- package/dist/dispatchers/generic-cli.js.map +1 -0
- package/dist/dispatchers/openai-compatible.d.ts +57 -0
- package/dist/dispatchers/openai-compatible.d.ts.map +1 -0
- package/dist/dispatchers/openai-compatible.js +662 -0
- package/dist/dispatchers/openai-compatible.js.map +1 -0
- package/dist/dispatchers/shared/kill-tree.d.ts +21 -0
- package/dist/dispatchers/shared/kill-tree.d.ts.map +1 -0
- package/dist/dispatchers/shared/kill-tree.js +35 -0
- package/dist/dispatchers/shared/kill-tree.js.map +1 -0
- package/dist/dispatchers/shared/rate-limit-headers.d.ts +22 -0
- package/dist/dispatchers/shared/rate-limit-headers.d.ts.map +1 -0
- package/dist/dispatchers/shared/rate-limit-headers.js +124 -0
- package/dist/dispatchers/shared/rate-limit-headers.js.map +1 -0
- package/dist/dispatchers/shared/stream-subprocess.d.ts +53 -0
- package/dist/dispatchers/shared/stream-subprocess.d.ts.map +1 -0
- package/dist/dispatchers/shared/stream-subprocess.js +274 -0
- package/dist/dispatchers/shared/stream-subprocess.js.map +1 -0
- package/dist/dispatchers/shared/subprocess.d.ts +25 -0
- package/dist/dispatchers/shared/subprocess.d.ts.map +1 -0
- package/dist/dispatchers/shared/subprocess.js +110 -0
- package/dist/dispatchers/shared/subprocess.js.map +1 -0
- package/dist/dispatchers/shared/which-available.d.ts +2 -0
- package/dist/dispatchers/shared/which-available.d.ts.map +1 -0
- package/dist/dispatchers/shared/which-available.js +8 -0
- package/dist/dispatchers/shared/which-available.js.map +1 -0
- package/dist/dispatchers/shared/windows-cmd.d.ts +38 -0
- package/dist/dispatchers/shared/windows-cmd.d.ts.map +1 -0
- package/dist/dispatchers/shared/windows-cmd.js +91 -0
- package/dist/dispatchers/shared/windows-cmd.js.map +1 -0
- package/dist/http/server.d.ts +15 -0
- package/dist/http/server.d.ts.map +1 -0
- package/dist/http/server.js +495 -0
- package/dist/http/server.js.map +1 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +29 -0
- package/dist/index.js.map +1 -0
- package/dist/job-runner.d.ts +19 -0
- package/dist/job-runner.d.ts.map +1 -0
- package/dist/job-runner.js +42 -0
- package/dist/job-runner.js.map +1 -0
- package/dist/jobs.d.ts +116 -0
- package/dist/jobs.d.ts.map +1 -0
- package/dist/jobs.js +542 -0
- package/dist/jobs.js.map +1 -0
- package/dist/leaderboard.d.ts +62 -0
- package/dist/leaderboard.d.ts.map +1 -0
- package/dist/leaderboard.js +287 -0
- package/dist/leaderboard.js.map +1 -0
- package/dist/mcp/config-hot-reload.d.ts +64 -0
- package/dist/mcp/config-hot-reload.d.ts.map +1 -0
- package/dist/mcp/config-hot-reload.js +144 -0
- package/dist/mcp/config-hot-reload.js.map +1 -0
- package/dist/mcp/dispatcher-factory.d.ts +20 -0
- package/dist/mcp/dispatcher-factory.d.ts.map +1 -0
- package/dist/mcp/dispatcher-factory.js +30 -0
- package/dist/mcp/dispatcher-factory.js.map +1 -0
- package/dist/mcp/resources.d.ts +8 -0
- package/dist/mcp/resources.d.ts.map +1 -0
- package/dist/mcp/resources.js +45 -0
- package/dist/mcp/resources.js.map +1 -0
- package/dist/mcp/server.d.ts +36 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +80 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tools.d.ts +171 -0
- package/dist/mcp/tools.d.ts.map +1 -0
- package/dist/mcp/tools.js +658 -0
- package/dist/mcp/tools.js.map +1 -0
- package/dist/observability/index.d.ts +52 -0
- package/dist/observability/index.d.ts.map +1 -0
- package/dist/observability/index.js +111 -0
- package/dist/observability/index.js.map +1 -0
- package/dist/observability/spans.d.ts +47 -0
- package/dist/observability/spans.d.ts.map +1 -0
- package/dist/observability/spans.js +72 -0
- package/dist/observability/spans.js.map +1 -0
- package/dist/quota.d.ts +91 -0
- package/dist/quota.d.ts.map +1 -0
- package/dist/quota.js +331 -0
- package/dist/quota.js.map +1 -0
- package/dist/route-policy.d.ts +24 -0
- package/dist/route-policy.d.ts.map +1 -0
- package/dist/route-policy.js +92 -0
- package/dist/route-policy.js.map +1 -0
- package/dist/router.d.ts +162 -0
- package/dist/router.d.ts.map +1 -0
- package/dist/router.js +878 -0
- package/dist/router.js.map +1 -0
- package/dist/safety.d.ts +7 -0
- package/dist/safety.d.ts.map +1 -0
- package/dist/safety.js +33 -0
- package/dist/safety.js.map +1 -0
- package/dist/status.d.ts +100 -0
- package/dist/status.d.ts.map +1 -0
- package/dist/status.js +228 -0
- package/dist/status.js.map +1 -0
- package/dist/types.d.ts +402 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +9 -0
- package/dist/types.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +13 -0
- package/dist/version.js.map +1 -0
- package/dist/working-dir.d.ts +15 -0
- package/dist/working-dir.d.ts.map +1 -0
- package/dist/working-dir.js +22 -0
- package/dist/working-dir.js.map +1 -0
- package/dist/workspaces.d.ts +19 -0
- package/dist/workspaces.d.ts.map +1 -0
- package/dist/workspaces.js +352 -0
- package/dist/workspaces.js.map +1 -0
- package/package.json +96 -0
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core types for harness-dispatch.
|
|
3
|
+
*
|
|
4
|
+
* These are the cross-cutting types used by dispatchers, the router, the
|
|
5
|
+
* quota tracker, and the MCP surface. Downstream modules (R2/R3/R4) import
|
|
6
|
+
* from here.
|
|
7
|
+
*/
|
|
8
|
+
export type TaskType = "execute" | "plan" | "review" | "local" | "";
|
|
9
|
+
export type ThinkingLevel = "low" | "medium" | "high";
|
|
10
|
+
export type SafetyProfile = "read_only" | "workspace_edit" | "full_auto";
|
|
11
|
+
export type RoutePolicy = "standard" | "local_only" | "approval_required" | "blocked";
|
|
12
|
+
export type BillingProvider = "anthropic" | "openai" | "cursor" | "google" | "local" | "custom";
|
|
13
|
+
export type BillingSurface = "claude_code" | "claude_agent_sdk" | "anthropic_api" | "codex_cli" | "codex_sdk" | "openai_api" | "cursor_agent_cli" | "antigravity_cli" | "gemini_api" | "vertex_ai" | "openai_compatible" | "local_endpoint" | "custom";
|
|
14
|
+
export type AuthSource = "product_login" | "api_key" | "oauth_session" | "local_network" | "configured_endpoint" | "unknown";
|
|
15
|
+
export type BillingKind = "local_compute" | "included_plan_usage" | "included_plan_then_flexible_credits" | "included_credit_then_optional_overage" | "included_usage_then_on_demand" | "metered_api" | "free_quota" | "unknown";
|
|
16
|
+
export type BillingConfidence = "documented" | "inferred" | "unknown" | "unsupported";
|
|
17
|
+
export type EndpointMode = "provider_cloud" | "direct_openai_compatible" | "harness_native_endpoint";
|
|
18
|
+
export type EndpointProvider = "ollama" | "lmstudio" | "openai_compatible" | "anthropic_gateway" | "gemini_proxy" | "custom";
|
|
19
|
+
export type WireProtocol = "openai_chat_completions" | "anthropic_messages" | "gemini_generate_content" | "provider_native" | "unknown";
|
|
20
|
+
export type WorkspacePolicy = "shared" | "shared_locked" | "git_worktree" | "copy";
|
|
21
|
+
export type WorkspaceChangeKind = "added" | "modified" | "deleted";
|
|
22
|
+
export interface WorkspaceFileChange {
|
|
23
|
+
path: string;
|
|
24
|
+
kind: WorkspaceChangeKind;
|
|
25
|
+
}
|
|
26
|
+
export interface WorkspaceRun {
|
|
27
|
+
policy: WorkspacePolicy;
|
|
28
|
+
originalWorkingDir: string;
|
|
29
|
+
effectiveWorkingDir: string;
|
|
30
|
+
isolated: boolean;
|
|
31
|
+
securityBoundary: "none" | "project_state" | "project_state_and_process_cwd";
|
|
32
|
+
workspaceRoot?: string;
|
|
33
|
+
changedFiles?: WorkspaceFileChange[];
|
|
34
|
+
diffSummary?: string;
|
|
35
|
+
cleanupHint?: string;
|
|
36
|
+
notes?: string[];
|
|
37
|
+
}
|
|
38
|
+
export interface RouteBilling {
|
|
39
|
+
provider: BillingProvider;
|
|
40
|
+
surface: BillingSurface;
|
|
41
|
+
authSource: AuthSource;
|
|
42
|
+
kind: BillingKind;
|
|
43
|
+
paidUsagePossible: boolean;
|
|
44
|
+
allowPaidUsage: boolean;
|
|
45
|
+
paidUsageRequiresOptIn: boolean | "unknown";
|
|
46
|
+
confidence: BillingConfidence;
|
|
47
|
+
notes?: string;
|
|
48
|
+
}
|
|
49
|
+
export interface RouteSkip {
|
|
50
|
+
route: string;
|
|
51
|
+
code: "disabled" | "no_dispatcher" | "unavailable" | "circuit_broken" | "paid_blocked" | "unknown_billing" | "route_policy" | "approval_required" | "safety_incompatible" | "workspace_isolation_required";
|
|
52
|
+
message: string;
|
|
53
|
+
}
|
|
54
|
+
export interface DispatchResult {
|
|
55
|
+
output: string;
|
|
56
|
+
service: string;
|
|
57
|
+
success: boolean;
|
|
58
|
+
error?: string;
|
|
59
|
+
rateLimited?: boolean;
|
|
60
|
+
retryAfter?: number;
|
|
61
|
+
rateLimitHeaders?: Record<string, string>;
|
|
62
|
+
durationMs?: number;
|
|
63
|
+
tokensUsed?: {
|
|
64
|
+
input: number;
|
|
65
|
+
output: number;
|
|
66
|
+
};
|
|
67
|
+
skippedRoutes?: RouteSkip[];
|
|
68
|
+
workspace?: WorkspaceRun;
|
|
69
|
+
}
|
|
70
|
+
export interface QuotaInfo {
|
|
71
|
+
service: string;
|
|
72
|
+
used?: number;
|
|
73
|
+
limit?: number;
|
|
74
|
+
remaining?: number;
|
|
75
|
+
resetAt?: string;
|
|
76
|
+
source: "headers" | "api" | "unknown";
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* One line-matching rule for `output.mode: "jsonl_stream"` (see below). A
|
|
80
|
+
* parsed JSON line is tested against `when` (every listed dotted field path
|
|
81
|
+
* must equal the given string); on match, `emit` says what to do with it.
|
|
82
|
+
* Rules are checked in order per line; a line can match more than one rule
|
|
83
|
+
* (e.g. a line can carry both a text field and a usage field).
|
|
84
|
+
*/
|
|
85
|
+
export interface CliEventRule {
|
|
86
|
+
/** Dotted field path -> exact string it must equal, e.g. {"type": "thinking"}. */
|
|
87
|
+
when: Record<string, string>;
|
|
88
|
+
emit: "text" | "tool_use" | "thinking" | "usage" | "error";
|
|
89
|
+
/** For emit: "text" — dotted path to the text; becomes the run's output-so-far. */
|
|
90
|
+
textField?: string;
|
|
91
|
+
/** For emit: "tool_use". */
|
|
92
|
+
nameField?: string;
|
|
93
|
+
inputField?: string;
|
|
94
|
+
/** For emit: "thinking". */
|
|
95
|
+
chunkField?: string;
|
|
96
|
+
/** For emit: "usage" — dotted paths, checked in order, first present wins. */
|
|
97
|
+
inputTokenFields?: string[];
|
|
98
|
+
outputTokenFields?: string[];
|
|
99
|
+
/**
|
|
100
|
+
* For emit: "error" — dotted path to the human-readable error message
|
|
101
|
+
* (e.g. Codex's real `{"type":"error","message":"You've hit your usage
|
|
102
|
+
* limit..."}` frame). Without a rule for this, a structured error frame
|
|
103
|
+
* is silently invisible to the dispatcher — it falls through to raw
|
|
104
|
+
* stdout/stderr text heuristics, which lose the message entirely if
|
|
105
|
+
* stderr happens to carry unrelated CLI banner noise (confirmed
|
|
106
|
+
* 2026-07-24: Codex's real stderr is just "Reading additional input from
|
|
107
|
+
* stdin...", which was shadowing the actual JSON error in stdout).
|
|
108
|
+
*/
|
|
109
|
+
messageField?: string;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Config-driven CLI invocation template — lets a subprocess-based CLI
|
|
113
|
+
* harness be added or redefined with zero bespoke TypeScript, the same way
|
|
114
|
+
* `endpoints:` already does for HTTP-based ones.
|
|
115
|
+
*
|
|
116
|
+
* `args` is a literal command-line argument list, written the same way
|
|
117
|
+
* you'd type it by hand. A handful of reserved `{{name}}` tokens are
|
|
118
|
+
* substituted (or expanded to zero or more real tokens) at dispatch time;
|
|
119
|
+
* everything else passes through verbatim:
|
|
120
|
+
*
|
|
121
|
+
* {{prompt}} the prompt text (one token) — omitted if `stdin: true`
|
|
122
|
+
* {{model}} [model.flag, value] if a model is set, else nothing
|
|
123
|
+
* {{safety}} safety[requested profile] (zero or more tokens)
|
|
124
|
+
* {{working_dir}} [workingDir.flag, dir, ...extraArgsWhenSet] if set, else nothing
|
|
125
|
+
* {{file_dirs}} [fileDirs.flag, dir] repeated once per included file's directory
|
|
126
|
+
* {{native_args}} endpointNativeArgs[endpoint_provider], only when this route
|
|
127
|
+
* is dispatched as endpoint_mode: harness_native_endpoint
|
|
128
|
+
*
|
|
129
|
+
* e.g. Claude Code's real invocation is just:
|
|
130
|
+
* args: ["-p", "{{prompt}}", "--output-format", "json", "{{safety}}", "{{model}}"]
|
|
131
|
+
*/
|
|
132
|
+
export interface CliProtocolConfig {
|
|
133
|
+
args: string[];
|
|
134
|
+
/** Write the prompt to the child's stdin instead of substituting {{prompt}} into args. */
|
|
135
|
+
stdin?: boolean;
|
|
136
|
+
/** Omit if the CLI has no model-override flag. Falls back to the route's static `model:` when no per-call override is given. */
|
|
137
|
+
model?: {
|
|
138
|
+
flag: string;
|
|
139
|
+
};
|
|
140
|
+
/**
|
|
141
|
+
* Omit to rely on the subprocess's cwd only (no explicit flag, e.g. Claude
|
|
142
|
+
* Code). `extraArgsWhenSet` appends more static args only when workingDir
|
|
143
|
+
* is actually non-empty (e.g. Codex's `--skip-git-repo-check`).
|
|
144
|
+
* `fallback: "home"` substitutes the user's home directory when the
|
|
145
|
+
* caller passes an empty workingDir and this CLI has no "just use the
|
|
146
|
+
* current directory" default of its own (e.g. Cursor).
|
|
147
|
+
*/
|
|
148
|
+
workingDir?: {
|
|
149
|
+
flag: string;
|
|
150
|
+
extraArgsWhenSet?: string[];
|
|
151
|
+
fallback?: "home";
|
|
152
|
+
};
|
|
153
|
+
/**
|
|
154
|
+
* Flag repeated once per unique file directory (e.g. Antigravity's
|
|
155
|
+
* `--add-dir <dir>`) — computed the same way for every harness: unique
|
|
156
|
+
* parent directories of absolute `files` entries, excluding workingDir
|
|
157
|
+
* itself. Omit if the CLI has no such concept.
|
|
158
|
+
*/
|
|
159
|
+
fileDirs?: {
|
|
160
|
+
flag: string;
|
|
161
|
+
};
|
|
162
|
+
/** Args appended per requested safety profile (permission-mode flags etc.), via {{safety}}. */
|
|
163
|
+
safety?: Partial<Record<SafetyProfile, string[]>>;
|
|
164
|
+
/**
|
|
165
|
+
* Env var to set to the route's configured `api_key` when present (e.g.
|
|
166
|
+
* "CURSOR_API_KEY", "OPENAI_API_KEY"). If unset in config AND the var is
|
|
167
|
+
* already present in the parent environment, it's explicitly cleared for
|
|
168
|
+
* the child — matches the built-ins' "never leak an ambient key into a
|
|
169
|
+
* subscription-auth call" behavior.
|
|
170
|
+
*/
|
|
171
|
+
apiKeyEnvVar?: string;
|
|
172
|
+
/** Header/bullet used when appending a file list to the prompt text. Omit fileListHeader to skip the append entirely. */
|
|
173
|
+
fileListHeader?: string;
|
|
174
|
+
fileListBullet?: string;
|
|
175
|
+
/** How to turn stdout into a DispatchResult. */
|
|
176
|
+
output: {
|
|
177
|
+
/**
|
|
178
|
+
* - "text": raw stdout is the output, verbatim.
|
|
179
|
+
* - "json_field": parse stdout as one JSON object once the process
|
|
180
|
+
* exits; `fields` (in priority order, dotted paths supported) picks
|
|
181
|
+
* which field holds the answer.
|
|
182
|
+
* - "jsonl_stream": each stdout line is parsed as JSON as it arrives.
|
|
183
|
+
* Without `eventRules`, falls back to concatenating `fields` from
|
|
184
|
+
* every line (a poor-man's approximation). WITH `eventRules`,
|
|
185
|
+
* supports real mid-run tool_use/thinking event surfacing and usage
|
|
186
|
+
* aggregation, declaratively (see CliEventRule).
|
|
187
|
+
*/
|
|
188
|
+
mode: "text" | "json_field" | "jsonl_stream";
|
|
189
|
+
/** Candidate field names to check, in priority order, for json_field/jsonl_stream (dotted paths supported). */
|
|
190
|
+
fields?: string[];
|
|
191
|
+
/**
|
|
192
|
+
* Token-usage extraction for "text"/"json_field" modes (jsonl_stream
|
|
193
|
+
* uses eventRules' emit: "usage" instead).
|
|
194
|
+
*/
|
|
195
|
+
usage?: {
|
|
196
|
+
input: string[];
|
|
197
|
+
output: string[];
|
|
198
|
+
};
|
|
199
|
+
/** jsonl_stream only — see CliEventRule. */
|
|
200
|
+
eventRules?: CliEventRule[];
|
|
201
|
+
/**
|
|
202
|
+
* Explicit error detection for "text"/"json_field" modes (jsonl_stream
|
|
203
|
+
* uses eventRules' emit: "error" instead) — a CLI can exit 0 while its
|
|
204
|
+
* JSON body reports an API-level failure (confirmed 2026-07-24: Claude
|
|
205
|
+
* Code's `is_error`/`api_error_status` fields on an otherwise-0-exit
|
|
206
|
+
* response). `field` is a dotted path to a boolean; when true, the
|
|
207
|
+
* dispatch is forced to success: false regardless of exit code or
|
|
208
|
+
* `successRequiresOutput`, with the message from `messageFields`
|
|
209
|
+
* (falls back to `fields` if omitted).
|
|
210
|
+
*/
|
|
211
|
+
error?: {
|
|
212
|
+
field: string;
|
|
213
|
+
messageFields?: string[];
|
|
214
|
+
};
|
|
215
|
+
};
|
|
216
|
+
/**
|
|
217
|
+
* Default true (matches most CLIs, and Cursor specifically): success
|
|
218
|
+
* requires BOTH exitCode === 0 AND a non-empty parsed output — an exit-0
|
|
219
|
+
* run with nothing parseable is treated as a failure. Set false to match
|
|
220
|
+
* Claude Code / Codex / Antigravity's more lenient contract: success is
|
|
221
|
+
* exitCode === 0 alone, and the output falls back to raw stdout/stderr
|
|
222
|
+
* text when the configured parsing yields nothing.
|
|
223
|
+
*/
|
|
224
|
+
successRequiresOutput?: boolean;
|
|
225
|
+
/**
|
|
226
|
+
* Extra args to prepend when this route is configured with
|
|
227
|
+
* `endpoint_mode: harness_native_endpoint` against a matching
|
|
228
|
+
* `endpoint_provider` (e.g. Codex's `--oss --local-provider ollama`) —
|
|
229
|
+
* config-dependent, not a fixed property of any particular harness.
|
|
230
|
+
*/
|
|
231
|
+
endpointNativeArgs?: Partial<Record<EndpointProvider, string[]>>;
|
|
232
|
+
}
|
|
233
|
+
export interface ServiceConfig {
|
|
234
|
+
name: string;
|
|
235
|
+
enabled: boolean;
|
|
236
|
+
type: "cli" | "openai_compatible";
|
|
237
|
+
harness?: string;
|
|
238
|
+
command?: string;
|
|
239
|
+
apiKey?: string;
|
|
240
|
+
baseUrl?: string;
|
|
241
|
+
model?: string;
|
|
242
|
+
tier: number;
|
|
243
|
+
weight: number;
|
|
244
|
+
cliCapability: number;
|
|
245
|
+
leaderboardModel?: string;
|
|
246
|
+
thinkingLevel?: ThinkingLevel;
|
|
247
|
+
escalateModel?: string;
|
|
248
|
+
escalateOn: TaskType[];
|
|
249
|
+
capabilities: Partial<Record<"execute" | "plan" | "review", number>>;
|
|
250
|
+
/**
|
|
251
|
+
* Maximum output tokens the model can produce in a single dispatch.
|
|
252
|
+
* Callers (Planners, Workers, Reconcilers) use this to size work so it fits
|
|
253
|
+
* without mid-call truncation. A value of `undefined` means "unknown /
|
|
254
|
+
* assume the provider default" — callers that need to chunk conservatively
|
|
255
|
+
* should treat absence as a low bound.
|
|
256
|
+
*/
|
|
257
|
+
maxOutputTokens?: number;
|
|
258
|
+
/**
|
|
259
|
+
* Context window (input + output) in tokens. Used by the
|
|
260
|
+
* `preferLargeContext` route hint and by planners sizing up prompt payloads.
|
|
261
|
+
* Advertised by the provider; may be model-specific when `escalateModel` is
|
|
262
|
+
* in effect — consult the resolved model at dispatch time.
|
|
263
|
+
*/
|
|
264
|
+
maxInputTokens?: number;
|
|
265
|
+
provider?: BillingProvider;
|
|
266
|
+
surface?: BillingSurface;
|
|
267
|
+
authSource?: AuthSource;
|
|
268
|
+
billingKind?: BillingKind;
|
|
269
|
+
paidUsagePossible?: boolean;
|
|
270
|
+
allowPaidUsage?: boolean;
|
|
271
|
+
billingConfidence?: BillingConfidence;
|
|
272
|
+
billingNotes?: string;
|
|
273
|
+
safetyProfile?: SafetyProfile;
|
|
274
|
+
/**
|
|
275
|
+
* The safety level this route ACTUALLY runs at regardless of what's
|
|
276
|
+
* requested — a capability floor, not a preference. E.g. Cursor's print
|
|
277
|
+
* mode always has write+shell capability, so its shipped entry declares
|
|
278
|
+
* `effective_safety: full_auto` and the route is skipped for stricter
|
|
279
|
+
* requests. Declared in config (shipped or user), not hardcoded per
|
|
280
|
+
* harness anywhere in code.
|
|
281
|
+
*/
|
|
282
|
+
effectiveSafety?: SafetyProfile;
|
|
283
|
+
/**
|
|
284
|
+
* Operator-declared known-good model ids for this route (`models:` in
|
|
285
|
+
* config) — surfaced verbatim in status/usage so a calling agent can pick
|
|
286
|
+
* one without guessing. Optional and advisory: hints.model is still
|
|
287
|
+
* forwarded even if it's not in this list.
|
|
288
|
+
*/
|
|
289
|
+
models?: string[];
|
|
290
|
+
/**
|
|
291
|
+
* Free-text pointer to where this route's REAL model catalog lives
|
|
292
|
+
* (`model_hint:` in config) — a docs URL, a CLI command like
|
|
293
|
+
* `cursor-agent --list-models`, or "GET {base_url}/models". Surfaced in
|
|
294
|
+
* status/usage; declared per entry in the shipped config, not hardcoded
|
|
295
|
+
* per harness in code.
|
|
296
|
+
*/
|
|
297
|
+
modelHint?: string;
|
|
298
|
+
endpointMode?: EndpointMode;
|
|
299
|
+
endpointProvider?: EndpointProvider;
|
|
300
|
+
wireProtocol?: WireProtocol;
|
|
301
|
+
workspacePolicy?: WorkspacePolicy;
|
|
302
|
+
/** Required when `harness: "generic"` — see CliProtocolConfig. Ignored otherwise. */
|
|
303
|
+
protocol?: CliProtocolConfig;
|
|
304
|
+
/**
|
|
305
|
+
* Per-service dispatch timeout override in milliseconds. Every dispatcher
|
|
306
|
+
* hard-codes its own default (10 minutes for CLI harnesses, 2 minutes for
|
|
307
|
+
* openai_compatible) with no way to raise it — a long-running review or
|
|
308
|
+
* audit routed to a CLI harness gets killed and its result discarded at
|
|
309
|
+
* exactly the default, regardless of how the caller invoked the task
|
|
310
|
+
* (`code` or `job`). Set this to raise (or lower) the ceiling for a
|
|
311
|
+
* specific route; a per-call `hints.timeoutMs` takes precedence over this.
|
|
312
|
+
*/
|
|
313
|
+
timeoutMs?: number;
|
|
314
|
+
}
|
|
315
|
+
export interface RouterConfig {
|
|
316
|
+
services: Record<string, ServiceConfig>;
|
|
317
|
+
disabled?: readonly string[];
|
|
318
|
+
/**
|
|
319
|
+
* OpenTelemetry traces. OFF by default — purely operator-facing local
|
|
320
|
+
* observability (OTLP to localhost unless redirected); enable only if you
|
|
321
|
+
* run a collector. `HARNESS_DISPATCH_TELEMETRY=1` is the env equivalent.
|
|
322
|
+
*/
|
|
323
|
+
telemetry?: {
|
|
324
|
+
enabled: boolean;
|
|
325
|
+
};
|
|
326
|
+
/** Local artifact retention. jobsDays: how long ~/.harness-dispatch/jobs entries live (default 7). */
|
|
327
|
+
retention?: {
|
|
328
|
+
jobsDays?: number;
|
|
329
|
+
};
|
|
330
|
+
/**
|
|
331
|
+
* Config entries that were silently ignored rather than failing to load —
|
|
332
|
+
* a disabled:/overrides: name that doesn't match any auto-detected route
|
|
333
|
+
* (e.g. left over from before the claude_code -> claude_code_cli-style
|
|
334
|
+
* rename), or a clis: entry with a missing/unrecognized harness or name.
|
|
335
|
+
* Surfaced by `doctor`/`configure` so a stale or typo'd config doesn't go
|
|
336
|
+
* unnoticed forever.
|
|
337
|
+
*/
|
|
338
|
+
configWarnings?: readonly string[];
|
|
339
|
+
}
|
|
340
|
+
export interface RoutingDecision {
|
|
341
|
+
service: string;
|
|
342
|
+
tier: number;
|
|
343
|
+
quotaScore: number;
|
|
344
|
+
qualityScore: number;
|
|
345
|
+
cliCapability: number;
|
|
346
|
+
capabilityScore: number;
|
|
347
|
+
taskType: TaskType;
|
|
348
|
+
model: string | undefined;
|
|
349
|
+
/**
|
|
350
|
+
* Set only when hints.model was provided. true if it matched something
|
|
351
|
+
* this route statically declares (model/leaderboardModel/escalateModel/
|
|
352
|
+
* route name) — false if it was passed through to the dispatcher "blind"
|
|
353
|
+
* because nothing recognized it, which can still work (CLIs often accept
|
|
354
|
+
* arbitrary --model values) or can fail at dispatch time with the
|
|
355
|
+
* harness's own rejection. hints.model is unvalidated by design (see the
|
|
356
|
+
* `code` tool's own description) — this field is how a caller
|
|
357
|
+
* distinguishes "the router picked exactly what I asked for" from "I
|
|
358
|
+
* might have a typo" without guessing from `model` alone.
|
|
359
|
+
*/
|
|
360
|
+
modelHintMatched?: boolean;
|
|
361
|
+
elo: number | undefined;
|
|
362
|
+
finalScore: number;
|
|
363
|
+
reason: string;
|
|
364
|
+
skippedRoutes?: RouteSkip[];
|
|
365
|
+
safetyProfile?: SafetyProfile;
|
|
366
|
+
effectiveSafetyProfile?: SafetyProfile;
|
|
367
|
+
billing?: RouteBilling;
|
|
368
|
+
workspacePolicy?: WorkspacePolicy;
|
|
369
|
+
}
|
|
370
|
+
export interface RouteHints {
|
|
371
|
+
model?: string;
|
|
372
|
+
service?: string;
|
|
373
|
+
preferLargeContext?: boolean;
|
|
374
|
+
taskType?: TaskType;
|
|
375
|
+
harness?: string;
|
|
376
|
+
safetyProfile?: SafetyProfile;
|
|
377
|
+
workspacePolicy?: WorkspacePolicy;
|
|
378
|
+
routePolicy?: RoutePolicy;
|
|
379
|
+
/** Per-call dispatch timeout override in milliseconds. See ServiceConfig.timeoutMs. */
|
|
380
|
+
timeoutMs?: number;
|
|
381
|
+
}
|
|
382
|
+
export type DispatcherEvent = {
|
|
383
|
+
type: "stdout";
|
|
384
|
+
chunk: string;
|
|
385
|
+
} | {
|
|
386
|
+
type: "stderr";
|
|
387
|
+
chunk: string;
|
|
388
|
+
} | {
|
|
389
|
+
type: "tool_use";
|
|
390
|
+
name: string;
|
|
391
|
+
input: unknown;
|
|
392
|
+
} | {
|
|
393
|
+
type: "thinking";
|
|
394
|
+
chunk: string;
|
|
395
|
+
} | {
|
|
396
|
+
type: "completion";
|
|
397
|
+
result: DispatchResult;
|
|
398
|
+
} | {
|
|
399
|
+
type: "error";
|
|
400
|
+
error: string;
|
|
401
|
+
};
|
|
402
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core types for harness-dispatch.
|
|
3
|
+
*
|
|
4
|
+
* These are the cross-cutting types used by dispatchers, the router, the
|
|
5
|
+
* quota tracker, and the MCP surface. Downstream modules (R2/R3/R4) import
|
|
6
|
+
* from here.
|
|
7
|
+
*/
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAaA,eAAO,MAAM,OAAO,QAAuB,CAAC"}
|
package/dist/version.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
const require = createRequire(import.meta.url);
|
|
3
|
+
function readPackageVersion() {
|
|
4
|
+
try {
|
|
5
|
+
const pkg = require("../package.json");
|
|
6
|
+
return typeof pkg.version === "string" ? pkg.version : "0.0.0";
|
|
7
|
+
}
|
|
8
|
+
catch {
|
|
9
|
+
return "0.0.0";
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
export const VERSION = readPackageVersion();
|
|
13
|
+
//# sourceMappingURL=version.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAE/C,SAAS,kBAAkB;IACzB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,OAAO,CAAC,iBAAiB,CAA0B,CAAC;QAChE,OAAO,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;IACjE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,OAAO,CAAC;IACjB,CAAC;AACH,CAAC;AAED,MAAM,CAAC,MAAM,OAAO,GAAG,kBAAkB,EAAE,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `workingDir` is effectively required on every dispatch entry point (MCP
|
|
3
|
+
* tools, jobs, HTTP): when the caller omits it, the task runs in the router
|
|
4
|
+
* server's own process cwd, almost never the project the caller means. That
|
|
5
|
+
* silent wrong-directory execution was a review finding — this resolves the
|
|
6
|
+
* value the same way everywhere and reports back whether it was defaulted so
|
|
7
|
+
* callers can surface a visible warning instead of failing quietly.
|
|
8
|
+
*/
|
|
9
|
+
export interface ResolvedWorkingDir {
|
|
10
|
+
workingDir: string;
|
|
11
|
+
defaulted: boolean;
|
|
12
|
+
}
|
|
13
|
+
export declare function resolveWorkingDir(input: string | undefined): ResolvedWorkingDir;
|
|
14
|
+
export declare function workingDirWarning(resolved: ResolvedWorkingDir): string | undefined;
|
|
15
|
+
//# sourceMappingURL=working-dir.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"working-dir.d.ts","sourceRoot":"","sources":["../src/working-dir.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,kBAAkB,CAK/E;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,kBAAkB,GAAG,MAAM,GAAG,SAAS,CAOlF"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `workingDir` is effectively required on every dispatch entry point (MCP
|
|
3
|
+
* tools, jobs, HTTP): when the caller omits it, the task runs in the router
|
|
4
|
+
* server's own process cwd, almost never the project the caller means. That
|
|
5
|
+
* silent wrong-directory execution was a review finding — this resolves the
|
|
6
|
+
* value the same way everywhere and reports back whether it was defaulted so
|
|
7
|
+
* callers can surface a visible warning instead of failing quietly.
|
|
8
|
+
*/
|
|
9
|
+
export function resolveWorkingDir(input) {
|
|
10
|
+
if (input !== undefined && input !== "") {
|
|
11
|
+
return { workingDir: input, defaulted: false };
|
|
12
|
+
}
|
|
13
|
+
return { workingDir: process.cwd(), defaulted: true };
|
|
14
|
+
}
|
|
15
|
+
export function workingDirWarning(resolved) {
|
|
16
|
+
if (!resolved.defaulted)
|
|
17
|
+
return undefined;
|
|
18
|
+
return (`workingDir was not provided — ran in the router server's own directory ` +
|
|
19
|
+
`(${resolved.workingDir}), which is almost certainly not the intended project. ` +
|
|
20
|
+
`Pass an absolute workingDir on the next call.`);
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=working-dir.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"working-dir.js","sourceRoot":"","sources":["../src/working-dir.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAOH,MAAM,UAAU,iBAAiB,CAAC,KAAyB;IACzD,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE,EAAE,CAAC;QACxC,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IACjD,CAAC;IACD,OAAO,EAAE,UAAU,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;AACxD,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,QAA4B;IAC5D,IAAI,CAAC,QAAQ,CAAC,SAAS;QAAE,OAAO,SAAS,CAAC;IAC1C,OAAO,CACL,yEAAyE;QACzE,IAAI,QAAQ,CAAC,UAAU,yDAAyD;QAChF,+CAA+C,CAChD,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { DispatchResult, SafetyProfile, ServiceConfig, WorkspacePolicy } from "./types.js";
|
|
2
|
+
export interface PreparedWorkspace {
|
|
3
|
+
policy: WorkspacePolicy;
|
|
4
|
+
originalWorkingDir: string;
|
|
5
|
+
effectiveWorkingDir: string;
|
|
6
|
+
files: string[];
|
|
7
|
+
isolated: boolean;
|
|
8
|
+
workspaceRoot?: string;
|
|
9
|
+
finish(result: DispatchResult): Promise<DispatchResult>;
|
|
10
|
+
}
|
|
11
|
+
export declare function workspacePolicyFor(svc: ServiceConfig, safetyProfile: SafetyProfile | undefined, requestedPolicy?: WorkspacePolicy): WorkspacePolicy;
|
|
12
|
+
export declare function isIsolatedWorkspacePolicy(policy: WorkspacePolicy): boolean;
|
|
13
|
+
export declare function prepareWorkspace(opts: {
|
|
14
|
+
routeName: string;
|
|
15
|
+
policy: WorkspacePolicy;
|
|
16
|
+
workingDir: string;
|
|
17
|
+
files: string[];
|
|
18
|
+
}): Promise<PreparedWorkspace>;
|
|
19
|
+
//# sourceMappingURL=workspaces.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspaces.d.ts","sourceRoot":"","sources":["../src/workspaces.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EACV,cAAc,EACd,aAAa,EACb,aAAa,EAEb,eAAe,EAEhB,MAAM,YAAY,CAAC;AA2BpB,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,eAAe,CAAC;IACxB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;CACzD;AAED,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,aAAa,EAClB,aAAa,EAAE,aAAa,GAAG,SAAS,EACxC,eAAe,CAAC,EAAE,eAAe,GAChC,eAAe,CAIjB;AAED,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAE1E;AA4UD,wBAAsB,gBAAgB,CAAC,IAAI,EAAE;IAC3C,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,eAAe,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAU7B"}
|