@wrongstack/core 0.308.7 → 0.309.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/dist/coordination/director/director-toolset.d.ts +2 -2
- package/dist/coordination/director-mutation-test-tool.d.ts +29 -0
- package/dist/coordination/director-tools.d.ts +2 -0
- package/dist/coordination/director.d.ts +9 -0
- package/dist/coordination/fleet.d.ts +12 -0
- package/dist/coordination/index.d.ts +1 -1
- package/dist/coordination/index.js +705 -48
- package/dist/coordination/mail-tools.d.ts +10 -6
- package/dist/coordination/mailbox-codecs.d.ts +31 -0
- package/dist/coordination/multi-agent-coordinator.d.ts +14 -0
- package/dist/coordination/multi-agent-timeout.d.ts +11 -1
- package/dist/coordination/mutation-engine.d.ts +74 -0
- package/dist/coordination/subagent-budget.d.ts +54 -0
- package/dist/coordination/subagent-finish.d.ts +78 -0
- package/dist/core/index.js +19 -4
- package/dist/defaults/index.js +699 -51
- package/dist/execution/index.js +238 -16
- package/dist/index.d.ts +1 -1
- package/dist/index.js +862 -178
- package/dist/kernel/events/agent-events.d.ts +31 -2
- package/dist/models/index.js +11 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.js +14 -0
- package/dist/types/multi-agent.d.ts +15 -0
- package/dist/types/provider.d.ts +29 -1
- package/instructions/agents/chaos-monkey.md +57 -0
- package/package.json +3 -3
|
@@ -144,8 +144,8 @@ export interface AgentEventMap {
|
|
|
144
144
|
/**
|
|
145
145
|
* A spawn resolved fewer skills than it selected. Emitted so a skill that
|
|
146
146
|
* silently failed to load — missing from the loader, gated by a capability
|
|
147
|
-
* the subagent lacks, or cut by the prompt budget — is observable instead
|
|
148
|
-
* leaving the agent believing it received guidance it never got.
|
|
147
|
+
* the subagent lacks, or cut by the prompt budget — is observable instead
|
|
148
|
+
* of leaving the agent believing it received guidance it never got.
|
|
149
149
|
*/
|
|
150
150
|
'subagent.skills.dropped': {
|
|
151
151
|
sessionId?: string | undefined;
|
|
@@ -155,6 +155,35 @@ export interface AgentEventMap {
|
|
|
155
155
|
/** skill → reason it was dropped. */
|
|
156
156
|
dropped: Record<string, string>;
|
|
157
157
|
};
|
|
158
|
+
/**
|
|
159
|
+
* In-band graceful-finish request for a background subagent (see
|
|
160
|
+
* coordination/subagent-finish.ts). Emitted on the subagent's OWN EventBus
|
|
161
|
+
* when its wall-clock deadline is crossed — or the leader explicitly asked
|
|
162
|
+
* it to finish (session shutdown) — and the subagent's config opted into
|
|
163
|
+
* `gracefulFinish`. The runner folds the notice into the conversation as a
|
|
164
|
+
* `/btw` note at the next iteration boundary; the model then completes its
|
|
165
|
+
* task in its own turn within the granted grace window. This event is a
|
|
166
|
+
* notification, never an interrupt: nothing aborts when it fires.
|
|
167
|
+
*/
|
|
168
|
+
'subagent.finish_requested': {
|
|
169
|
+
/** Parent/host session id. */
|
|
170
|
+
sessionId?: string | undefined;
|
|
171
|
+
/**
|
|
172
|
+
* Owning subagent id when the budget knows it; omitted when the budget
|
|
173
|
+
* was constructed without one. An empty string would look like an
|
|
174
|
+
* address that matches nothing — the runner treats an omitted id as
|
|
175
|
+
* deliverable (`if (e.subagentId && …)`), so omission is safe.
|
|
176
|
+
*/
|
|
177
|
+
subagentId?: string | undefined;
|
|
178
|
+
/** Why the finish was requested (deadline crossed / leader finished). */
|
|
179
|
+
reason: string;
|
|
180
|
+
/** Epoch ms by which the subagent should have produced its final output. */
|
|
181
|
+
deadlineMs: number;
|
|
182
|
+
/** Granted working-time window in ms. */
|
|
183
|
+
graceMs: number;
|
|
184
|
+
/** Ready-to-read notice text; the loop folds it in as a `/btw` note. */
|
|
185
|
+
notice: string;
|
|
186
|
+
};
|
|
158
187
|
/**
|
|
159
188
|
* A background learning-distillation pass finished for a roster role.
|
|
160
189
|
* Emitted by the fleet host's auto-optimize scheduler so surfaces can show
|
package/dist/models/index.js
CHANGED
|
@@ -877,7 +877,17 @@ function normalizeModelsDevModel(model) {
|
|
|
877
877
|
const reasoningConfig = {
|
|
878
878
|
default: disableSupported ? "enabled" : "always_on",
|
|
879
879
|
disableSupported,
|
|
880
|
-
|
|
880
|
+
// Tri-state (see ReasoningConfig.effortSupported):
|
|
881
|
+
// options present → documented answer (true when effort values exist;
|
|
882
|
+
// an explicitly EMPTY array is a documented "no
|
|
883
|
+
// effort control", not an absent field).
|
|
884
|
+
// field ABSENT → the model is known to reason but its vocabulary is
|
|
885
|
+
// undocumented → `undefined`, so the resolver forwards
|
|
886
|
+
// the request and each wire adapter applies its own
|
|
887
|
+
// transport gating. Sending `false` here would make
|
|
888
|
+
// the resolver claim "does not support effort" — an
|
|
889
|
+
// assertion the catalog never made.
|
|
890
|
+
...raw === void 0 ? {} : { effortSupported: effortLevels.length > 0 },
|
|
881
891
|
effortLevels,
|
|
882
892
|
preserveThinking: model.interleaved ? "always_on" : "unsupported"
|
|
883
893
|
};
|
package/dist/types/index.d.ts
CHANGED
|
@@ -34,7 +34,7 @@ export { BUILTIN_PROMPT_CATEGORIES, isBuiltinCategory, PROMPT_CATEGORY_LABELS }
|
|
|
34
34
|
export type { InstalledPromptEntry, ManifestValidation, PromptManifestData, PromptRegistryManifest, PromptRegistryRef, RegistryDiff, } from './prompt-registry.js';
|
|
35
35
|
export { diffRegistry, validateRegistryManifest } from './prompt-registry.js';
|
|
36
36
|
export type { CacheTtl, Capabilities, JsonSchemaSpec, Provider, ProviderContextLimit, ProviderErrorBody, ProviderErrorKind, ReasoningConfig, ReasoningEffort, ReasoningRequest, Request, RequestCacheControl, Response, ResponseFormat, SafetySetting, StopReason, StreamEvent, Usage, } from './provider.js';
|
|
37
|
-
export { classifyProviderError, effectiveInputTokens, isContextOverflowShaped, isFallbackWorthy, isRetryableKind, ProviderError, StreamHangError, } from './provider.js';
|
|
37
|
+
export { classifyProviderError, effectiveInputTokens, isContextOverflowShaped, isFallbackWorthy, isReasoningEffort, isRetryableKind, ProviderError, REASONING_EFFORT_LEVELS, StreamHangError, } from './provider.js';
|
|
38
38
|
export type { ProviderRunner, RunProviderOptions } from './provider-runner.js';
|
|
39
39
|
export type { Renderer } from './renderer.js';
|
|
40
40
|
export type { SecretScrubber } from './secret-scrubber.js';
|
package/dist/types/index.js
CHANGED
|
@@ -914,6 +914,18 @@ function truncate(s, max) {
|
|
|
914
914
|
var QUOTA_EXHAUSTED_RE = /(?:insufficient|exhausted|depleted|exceeded|no|not enough)[-_\s]*(?:quota|credit|balance)|(?:quota|credit|balance)(?:\s+(?:has|have))?(?:\s+been)?[-_\s]*(?:exhausted|depleted|exceeded|insufficient)|billing[_\s-]*(?:hard[_\s-]*)?limit|payment required|spending limit|plan limit|usage[-_\s]*limit[-_\s]*(?:reached|exceeded)/i;
|
|
915
915
|
|
|
916
916
|
// src/types/provider.ts
|
|
917
|
+
var REASONING_EFFORT_LEVELS = [
|
|
918
|
+
"none",
|
|
919
|
+
"minimal",
|
|
920
|
+
"low",
|
|
921
|
+
"medium",
|
|
922
|
+
"high",
|
|
923
|
+
"xhigh",
|
|
924
|
+
"max"
|
|
925
|
+
];
|
|
926
|
+
function isReasoningEffort(value) {
|
|
927
|
+
return typeof value === "string" && REASONING_EFFORT_LEVELS.includes(value);
|
|
928
|
+
}
|
|
917
929
|
function effectiveInputTokens(usage) {
|
|
918
930
|
return usage.input + (usage.cacheRead ?? 0) + (usage.cacheWrite ?? 0);
|
|
919
931
|
}
|
|
@@ -1346,6 +1358,7 @@ export {
|
|
|
1346
1358
|
ParseError,
|
|
1347
1359
|
PluginError,
|
|
1348
1360
|
ProviderError,
|
|
1361
|
+
REASONING_EFFORT_LEVELS,
|
|
1349
1362
|
SESSION_MARKER_EVENT_TYPES,
|
|
1350
1363
|
SYSTEM_INJECTION_PREFIXES,
|
|
1351
1364
|
SddError,
|
|
@@ -1377,6 +1390,7 @@ export {
|
|
|
1377
1390
|
isImageBlock,
|
|
1378
1391
|
isParseError,
|
|
1379
1392
|
isPluginError,
|
|
1393
|
+
isReasoningEffort,
|
|
1380
1394
|
isRetryableKind,
|
|
1381
1395
|
isSddError,
|
|
1382
1396
|
isSessionError,
|
|
@@ -142,6 +142,21 @@ export interface SubagentConfig {
|
|
|
142
142
|
end: string;
|
|
143
143
|
mode?: 'advisory' | 'enforce' | undefined;
|
|
144
144
|
} | undefined;
|
|
145
|
+
/**
|
|
146
|
+
* Model-driven completion policy. When set, this subagent is NEVER killed
|
|
147
|
+
* by the wall-clock watchdog at its deadline: instead the deadline (or an
|
|
148
|
+
* explicit `Director.requestFinish()`) triggers an in-band
|
|
149
|
+
* `subagent.finish_requested` notification that the agent loop folds into
|
|
150
|
+
* the conversation between tool batches — the model then finishes its task
|
|
151
|
+
* in its own turn within `graceMs` of legitimate working time. Only after
|
|
152
|
+
* that grace window elapses does the existing terminal stop apply, so the
|
|
153
|
+
* subagent still has a bounded maximum lifetime.
|
|
154
|
+
*
|
|
155
|
+
* `undefined` (default) keeps the legacy watchdog behavior unchanged.
|
|
156
|
+
*/
|
|
157
|
+
gracefulFinish?: boolean | {
|
|
158
|
+
graceMs?: number | undefined;
|
|
159
|
+
} | undefined;
|
|
145
160
|
/**
|
|
146
161
|
* Runtime request overrides for THIS subagent. When present, these are merged
|
|
147
162
|
* over the leader's `Config.modelRuntime` before the subagent request pipeline
|
package/dist/types/provider.d.ts
CHANGED
|
@@ -23,6 +23,21 @@ import type { Tool } from './tool.js';
|
|
|
23
23
|
* cached tokens twice and skew cache-hit-ratio reporting.
|
|
24
24
|
*/
|
|
25
25
|
export type ReasoningEffort = 'none' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh' | 'max';
|
|
26
|
+
/**
|
|
27
|
+
* The canonical runtime list of {@link ReasoningEffort} values, in
|
|
28
|
+
* menu/display order. Single source of truth for every surface that needs to
|
|
29
|
+
* iterate the levels (CLI `/settings` + `/setmodel`, the TUI picker, the
|
|
30
|
+
* WebUI dropdown) — import this instead of re-declaring a local array, which
|
|
31
|
+
* is how drift crept in before.
|
|
32
|
+
*
|
|
33
|
+
* `satisfies` pins the literal to the union: a value here core's type doesn't
|
|
34
|
+
* know is a compile error. Note the reverse is NOT caught — core adding a
|
|
35
|
+
* level does not force this array to grow, so consumers validating user input
|
|
36
|
+
* against it must decide deliberately whether to expose the new level.
|
|
37
|
+
*/
|
|
38
|
+
export declare const REASONING_EFFORT_LEVELS: readonly ["none", "minimal", "low", "medium", "high", "xhigh", "max"];
|
|
39
|
+
/** Type guard for untrusted strings (CLI args, WS payloads, config files). */
|
|
40
|
+
export declare function isReasoningEffort(value: unknown): value is ReasoningEffort;
|
|
26
41
|
export type CacheTtl = '5m' | '1h';
|
|
27
42
|
/**
|
|
28
43
|
* Provider-agnostic response-format directive.
|
|
@@ -119,7 +134,20 @@ export interface RequestCacheControl {
|
|
|
119
134
|
export interface ReasoningConfig {
|
|
120
135
|
default: 'enabled' | 'disabled' | 'adaptive' | 'always_on';
|
|
121
136
|
disableSupported: boolean;
|
|
122
|
-
|
|
137
|
+
/**
|
|
138
|
+
* Tri-state effort support:
|
|
139
|
+
* `true` — the catalog documents this model's effort levels
|
|
140
|
+
* (`effortLevels` is authoritative).
|
|
141
|
+
* `false` — the catalog documents effort control as absent
|
|
142
|
+
* (toggle-only or budget_tokens-only reasoning options).
|
|
143
|
+
* `undefined` — the model is known to reason (`reasoning: true`) but its
|
|
144
|
+
* effort vocabulary is not documented. The resolver forwards
|
|
145
|
+
* the requested effort; each wire adapter then applies its
|
|
146
|
+
* own transport-level gating (allowlist, mapping, or omit),
|
|
147
|
+
* so an undocumented model can only match-or-omit — never
|
|
148
|
+
* receive a field shape it did not advertise.
|
|
149
|
+
*/
|
|
150
|
+
effortSupported?: boolean | undefined;
|
|
123
151
|
effortLevels: ReasoningEffort[];
|
|
124
152
|
preserveThinking: 'unsupported' | 'optional' | 'always_on';
|
|
125
153
|
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
You are the Chaos Monkey ("Kaos Maymunu") — a mutation-testing saboteur for the
|
|
2
|
+
WrongStack fleet. Your job is to prove whether a test suite actually pins down
|
|
3
|
+
the code it claims to cover, by deliberately breaking that code and watching
|
|
4
|
+
which mutants survive.
|
|
5
|
+
|
|
6
|
+
Core belief: green tests prove nothing if they cannot detect sabotage. A mutant
|
|
7
|
+
that survives means the tests are fake or insufficient — and that is the most
|
|
8
|
+
valuable finding you can return.
|
|
9
|
+
|
|
10
|
+
## Your task contract
|
|
11
|
+
|
|
12
|
+
The director hands you a mutation plan: an exact list of mutation ids, each with
|
|
13
|
+
file, line, column, kind, original token and replacement token. The plan is
|
|
14
|
+
authoritative — you NEVER invent, move, or "improve" mutations. Your freedom is
|
|
15
|
+
execution order and diagnosis, never the mutation set.
|
|
16
|
+
|
|
17
|
+
## Check pass (per mutant)
|
|
18
|
+
|
|
19
|
+
1. Apply exactly ONE mutation from the plan to its anchored (file, line, column).
|
|
20
|
+
If the anchored token no longer matches `original`, mark the mutant
|
|
21
|
+
`skipped` with the drift as evidence — do not hunt for a "similar" site.
|
|
22
|
+
2. Run the provided test command exactly as given.
|
|
23
|
+
3. Record the outcome:
|
|
24
|
+
- Tests fail → mutant `killed` (quote the first failing assertion).
|
|
25
|
+
- Tests pass → mutant `survived` (this is a weak-test finding, not your failure).
|
|
26
|
+
4. Restore the original source byte-for-byte before moving to the next mutant.
|
|
27
|
+
The suite is only honest if every mutant ran against pristine code except
|
|
28
|
+
its own single mutation.
|
|
29
|
+
|
|
30
|
+
## Hard rules
|
|
31
|
+
|
|
32
|
+
- **One mutation at a time.** Never stack mutants; a stacked run measures nothing.
|
|
33
|
+
- **Always restore.** Your worktree must be clean of sabotage at the end of the
|
|
34
|
+
pass. If restore fails, stop and report which file is left mutated.
|
|
35
|
+
- **Stay inside the plan's files.** No refactors, no fixes, no formatting churn
|
|
36
|
+
— even when the mutated code looks wrong to you. You are the saboteur, not
|
|
37
|
+
the reviewer.
|
|
38
|
+
- **Deterministic.** Same plan + same suite → same report.
|
|
39
|
+
- **One-shot lifecycle.** Finish the assigned pass, submit the report, stop.
|
|
40
|
+
|
|
41
|
+
## Report
|
|
42
|
+
|
|
43
|
+
Submit via `submit_result`, then repeat it as your final text (fenced JSON):
|
|
44
|
+
|
|
45
|
+
```json
|
|
46
|
+
{
|
|
47
|
+
"summary": "<one line: N killed / M survived / K skipped>",
|
|
48
|
+
"mutants": [
|
|
49
|
+
{ "id": "<plan id>", "file": "...", "line": 0, "kind": "...",
|
|
50
|
+
"status": "killed | survived | skipped",
|
|
51
|
+
"evidence": "<failing assertion, or 'suite green' for survivors>" }
|
|
52
|
+
]
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Order survivors first — they are the actionable findings. For each survivor,
|
|
57
|
+
name the boundary or behavior the tests failed to assert.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wrongstack/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.309.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "WrongStack core: kernel, types, defaults, and shared utilities for the WrongStack CLI agent.",
|
|
6
6
|
"repository": {
|
|
@@ -182,8 +182,8 @@
|
|
|
182
182
|
"wrongstackApiVersion": "0.1.10",
|
|
183
183
|
"dependencies": {
|
|
184
184
|
"zod": "4.4.3",
|
|
185
|
-
"@wrongstack/
|
|
186
|
-
"@wrongstack/
|
|
185
|
+
"@wrongstack/kanban": "0.309.0",
|
|
186
|
+
"@wrongstack/persistence": "0.309.0"
|
|
187
187
|
},
|
|
188
188
|
"devDependencies": {
|
|
189
189
|
"@types/node": "^26.2.0",
|