sortie-dogs 0.14.5 → 0.14.7
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/.agents/skills/sortie-dogs/SKILL.md +1 -1
- package/README.md +18 -10
- package/dist/asset-version.d.ts +2 -2
- package/dist/asset-version.js +2 -2
- package/dist/cli/codex-mission.d.ts +1 -1
- package/dist/cli/codex-mission.js +2 -1
- package/dist/core/mission-context.d.ts +16 -0
- package/dist/core/mission-context.js +42 -4
- package/dist/core/operator-mission.js +3 -2
- package/dist/plugin/index.js +5 -1
- package/dist/plugin/model-cost.d.ts +3 -3
- package/dist/plugin/model-cost.js +6 -3
- package/dist/plugin/profiled.js +15 -8
- package/dist/plugin/v2.js +35 -5
- package/dist/runtime-assets-v010.js +2 -1
- package/dist/runtime-mission-assets.js +26 -1
- package/package.json +1 -1
|
@@ -32,7 +32,7 @@ Use the natural-language Mission route on POSIX and Windows:
|
|
|
32
32
|
|
|
33
33
|
Forward `--model`, `--effort`, or `--permissions` only when the user selected those values. Never silently widen the native permission profile. If an existing Mission is reported, resume only its exact root with `--resume`; do not launch replacement work.
|
|
34
34
|
|
|
35
|
-
Leave `--model` unset to retain role-specific defaults: Sol 6.1 Operator/Coordinator/Reviewer and
|
|
35
|
+
Leave `--model` unset to retain role-specific defaults: Sol 6.1 Operator/Coordinator/Reviewer and ordinary Terra 6.1 Standard/max Worker (no Fast/priority). Scout and dedicated Luna routes remain unchanged. The Codex adapter retains the shared Luna-fast alias mapping to native `gpt-6-luna` plus the `priority` (Fast) service tier. Fast consumes subscription limits faster than Standard; no metered API fallback is allowed.
|
|
36
36
|
|
|
37
37
|
On Windows the same Mission command resolves existing PowerShell 7 automatically. Add `--trusted-pwsh <absolute-pwsh.exe>` only when an exact existing executable needs to be selected; do not add a separate shell preflight or approval step.
|
|
38
38
|
|
package/README.md
CHANGED
|
@@ -19,8 +19,8 @@ evidence-backed result, not more agents for their own sake.
|
|
|
19
19
|
[](https://www.npmjs.com/package/sortie-dogs)
|
|
20
20
|
[](LICENSE)
|
|
21
21
|
|
|
22
|
-
**Current release: [v0.14.
|
|
23
|
-
· [Release notes](docs/release-v0.14.
|
|
22
|
+
**Current release: [v0.14.7](https://github.com/zufall-upon/Sortie-dogs/releases/tag/v0.14.7)**
|
|
23
|
+
· [Release notes](docs/release-v0.14.7.md) · [Execution vision](docs/v0.14.0-execution-vision.md)
|
|
24
24
|
|
|
25
25
|
[Quick start](#quick-start) · [Workflow](#mission-workflow) · [Models](#default-models) ·
|
|
26
26
|
[Measured results](#measured-results) · [Configuration](#configuration) · [Documentation](#documentation)
|
|
@@ -57,7 +57,7 @@ Use an existing Codex CLI signed in with **ChatGPT**. On Windows, PowerShell **7
|
|
|
57
57
|
available; POSIX uses bash. Sortie does not install Codex, start login or use a metered API fallback.
|
|
58
58
|
|
|
59
59
|
```sh
|
|
60
|
-
npm install --save-dev sortie-dogs@0.14.
|
|
60
|
+
npm install --save-dev sortie-dogs@0.14.7
|
|
61
61
|
npx --no-install sortie-dogs codex init .
|
|
62
62
|
```
|
|
63
63
|
|
|
@@ -86,7 +86,7 @@ bridge. [Codex guide: SDK, permissions, progress, resume and manifest route](doc
|
|
|
86
86
|
Use **OpenCode V2**. In the target project:
|
|
87
87
|
|
|
88
88
|
```sh
|
|
89
|
-
npm install --save-dev sortie-dogs@0.14.
|
|
89
|
+
npm install --save-dev sortie-dogs@0.14.7
|
|
90
90
|
npx --no-install sortie-dogs init .
|
|
91
91
|
```
|
|
92
92
|
|
|
@@ -144,9 +144,12 @@ one. Required success checks, missing commands and active/unstarted operations s
|
|
|
144
144
|
## Default models
|
|
145
145
|
|
|
146
146
|
- **Operator / Coordinator / Reviewer / Advisor:** GPT-6.1 Sol, `xhigh`.
|
|
147
|
-
- **Worker
|
|
148
|
-
- **
|
|
149
|
-
- **
|
|
147
|
+
- **Worker:** GPT-6.1 Terra Standard, `max` (no Fast/priority).
|
|
148
|
+
- **Scout / dedicated Luna Worker:** Luna Fast, `max`, unchanged.
|
|
149
|
+
- **OpenCode:** ordinary Worker `openai/gpt-6.1-terra#max`; management/review
|
|
150
|
+
`openai/gpt-6.1-sol#xhigh`.
|
|
151
|
+
- **Codex:** ordinary Worker native `gpt-6.1-terra` / `max`, Standard; management/review
|
|
152
|
+
`gpt-6.1-sol` / `xhigh`. The retained Luna-fast alias maps to native
|
|
150
153
|
`gpt-6-luna` / `max` with separate `serviceTier: "priority"` (Fast).
|
|
151
154
|
|
|
152
155
|
Explicit host model selections remain authoritative. OpenCode routing and Codex native settings
|
|
@@ -242,8 +245,8 @@ Install the desired package version and rerun **your host's** initializer:
|
|
|
242
245
|
|
|
243
246
|
An OpenCode config-local bridge may resolve a separate package; npm-global update alone does not
|
|
244
247
|
update it. [Global/update instructions](docs/configuration.md#global-availability).
|
|
245
|
-
The current Mission asset marker is `0.14.
|
|
246
|
-
`0.
|
|
248
|
+
The current Mission asset marker is `0.14.7-visible-recovery-v1`; the Codex skill marker is
|
|
249
|
+
`0.14.6-codex-skill-v1`. Installed markers alone do not prove a running host reloaded the new version.
|
|
247
250
|
|
|
248
251
|
There is no supported uninstall command. Remove the dependency and only known Sortie-owned paths;
|
|
249
252
|
follow the [manual removal guide](docs/uninstall.md), never delete the entire `.opencode` directory.
|
|
@@ -258,9 +261,14 @@ follow the [manual removal guide](docs/uninstall.md), never delete the entire `.
|
|
|
258
261
|
[SWE-bench history](docs/benchmarks/swebench-lite-history.md) · [Historical local case study](docs/benchmark-reference.md).
|
|
259
262
|
- **Development:** [Testing](docs/testing.md) · [CLI testing](docs/cli-testing.md) ·
|
|
260
263
|
[Windows tests](docs/windows-tests.md) · [Release routine](docs/release-batch.md).
|
|
261
|
-
- **Releases:** [v0.14.5](docs/release-v0.14.5.md) · [v0.14.4](docs/release-v0.14.4.md) · [v0.14.3](docs/release-v0.14.3.md) · [v0.14.2](docs/release-v0.14.2.md) · [v0.14.1](docs/release-v0.14.1.md) · [v0.14.0](docs/release-v0.14.0.md) · [v0.13.22](docs/release-v0.13.22.md) · [v0.13.21](docs/release-v0.13.21.md) · [v0.13.20](docs/release-v0.13.20.md) · [v0.13.19](docs/release-v0.13.19.md) · [v0.13.18](docs/release-v0.13.18.md) · [v0.13.17](docs/release-v0.13.17.md) · [v0.13.16](docs/release-v0.13.16.md) · [v0.13.15](docs/release-v0.13.15.md) · [v0.13.14](docs/release-v0.13.14.md) · [v0.13.13](docs/release-v0.13.13.md) · [v0.13.12](docs/release-v0.13.12.md) · [v0.13.11](docs/release-v0.13.11.md) · [v0.13.10](docs/release-v0.13.10.md) ·
|
|
264
|
+
- **Releases:** [v0.14.7](docs/release-v0.14.7.md) · [v0.14.6](docs/release-v0.14.6.md) · [v0.14.5](docs/release-v0.14.5.md) · [v0.14.4](docs/release-v0.14.4.md) · [v0.14.3](docs/release-v0.14.3.md) · [v0.14.2](docs/release-v0.14.2.md) · [v0.14.1](docs/release-v0.14.1.md) · [v0.14.0](docs/release-v0.14.0.md) · [v0.13.22](docs/release-v0.13.22.md) · [v0.13.21](docs/release-v0.13.21.md) · [v0.13.20](docs/release-v0.13.20.md) · [v0.13.19](docs/release-v0.13.19.md) · [v0.13.18](docs/release-v0.13.18.md) · [v0.13.17](docs/release-v0.13.17.md) · [v0.13.16](docs/release-v0.13.16.md) · [v0.13.15](docs/release-v0.13.15.md) · [v0.13.14](docs/release-v0.13.14.md) · [v0.13.13](docs/release-v0.13.13.md) · [v0.13.12](docs/release-v0.13.12.md) · [v0.13.11](docs/release-v0.13.11.md) · [v0.13.10](docs/release-v0.13.10.md) ·
|
|
262
265
|
[v0.13.9](docs/release-v0.13.9.md) · [All GitHub releases](https://github.com/zufall-upon/Sortie-dogs/releases).
|
|
263
266
|
|
|
267
|
+
## Support
|
|
268
|
+
|
|
269
|
+
[GitHub Sponsors](https://github.com/sponsors/zufall-upon) — sponsorships become available
|
|
270
|
+
once the maintainer's Sponsors profile is approved and published.
|
|
271
|
+
|
|
264
272
|
## Community
|
|
265
273
|
|
|
266
274
|
[Contributing](CONTRIBUTING.md) · [Code of conduct](CODE_OF_CONDUCT.md) ·
|
package/dist/asset-version.d.ts
CHANGED
|
@@ -3,6 +3,6 @@
|
|
|
3
3
|
* installed project marker without importing every asset body.
|
|
4
4
|
*/
|
|
5
5
|
export declare const RUNTIME_ASSET_VERSION = "0.3.89-completion-proof-v1";
|
|
6
|
-
export declare const V010_RUNTIME_ASSET_VERSION = "0.14.
|
|
7
|
-
export declare const CODEX_SKILL_ASSET_VERSION = "0.
|
|
6
|
+
export declare const V010_RUNTIME_ASSET_VERSION = "0.14.7-visible-recovery-v1";
|
|
7
|
+
export declare const CODEX_SKILL_ASSET_VERSION = "0.14.6-codex-skill-v1";
|
|
8
8
|
export type RuntimeAssetVersion = typeof RUNTIME_ASSET_VERSION | typeof V010_RUNTIME_ASSET_VERSION | typeof CODEX_SKILL_ASSET_VERSION;
|
package/dist/asset-version.js
CHANGED
|
@@ -3,5 +3,5 @@
|
|
|
3
3
|
* installed project marker without importing every asset body.
|
|
4
4
|
*/
|
|
5
5
|
export const RUNTIME_ASSET_VERSION = "0.3.89-completion-proof-v1";
|
|
6
|
-
export const V010_RUNTIME_ASSET_VERSION = "0.14.
|
|
7
|
-
export const CODEX_SKILL_ASSET_VERSION = "0.
|
|
6
|
+
export const V010_RUNTIME_ASSET_VERSION = "0.14.7-visible-recovery-v1";
|
|
7
|
+
export const CODEX_SKILL_ASSET_VERSION = "0.14.6-codex-skill-v1";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { CodexTurnEvent } from "../codex/app-server.js";
|
|
2
|
-
export declare const CODEX_MISSION_USAGE = "Usage: sortie-dogs codex mission --prompt <text>\n [--resume <root-thread-id>] [--project-root <path>] [--executable <codex>] [--model <model>] [--effort <effort>] [--permissions <native-profile>] [--trusted-pwsh <absolute-pwsh.exe>]\n\nRuns the existing Mission Operator, Coordinator, Worker and Reviewer through Codex.\n--model and --effort explicitly override all roles; otherwise packaged role defaults apply.\n--permissions explicitly selects an existing native profile; omission retains native defaults.\nWindows uses existing PowerShell 7; --trusted-pwsh pins its absolute executable path.\nThe packaged Luna-fast
|
|
2
|
+
export declare const CODEX_MISSION_USAGE = "Usage: sortie-dogs codex mission --prompt <text>\n [--resume <root-thread-id>] [--project-root <path>] [--executable <codex>] [--model <model>] [--effort <effort>] [--permissions <native-profile>] [--trusted-pwsh <absolute-pwsh.exe>]\n\nRuns the existing Mission Operator, Coordinator, Worker and Reviewer through Codex.\n--model and --effort explicitly override all roles; otherwise packaged role defaults apply.\n--permissions explicitly selects an existing native profile; omission retains native defaults.\nWindows uses existing PowerShell 7; --trusted-pwsh pins its absolute executable path.\nThe packaged ordinary worker uses native gpt-6.1-terra/max, Standard (no Fast/priority).\nThe retained Luna-fast alias maps to native gpt-6-luna with the priority (Fast) service tier.\nUses existing ChatGPT authentication and native Codex permissions.";
|
|
3
3
|
export declare function runCodexMissionCommand(argv: readonly string[]): Promise<number>;
|
|
4
4
|
/** Bounded user-facing progress; do not dump control packets or hidden reasoning. */
|
|
5
5
|
export declare function codexMissionProgress(event: CodexTurnEvent & {
|
|
@@ -6,7 +6,8 @@ Runs the existing Mission Operator, Coordinator, Worker and Reviewer through Cod
|
|
|
6
6
|
--model and --effort explicitly override all roles; otherwise packaged role defaults apply.
|
|
7
7
|
--permissions explicitly selects an existing native profile; omission retains native defaults.
|
|
8
8
|
Windows uses existing PowerShell 7; --trusted-pwsh pins its absolute executable path.
|
|
9
|
-
The packaged
|
|
9
|
+
The packaged ordinary worker uses native gpt-6.1-terra/max, Standard (no Fast/priority).
|
|
10
|
+
The retained Luna-fast alias maps to native gpt-6-luna with the priority (Fast) service tier.
|
|
10
11
|
Uses existing ChatGPT authentication and native Codex permissions.`;
|
|
11
12
|
export async function runCodexMissionCommand(argv) {
|
|
12
13
|
if (argv.length === 1 && argv[0] === "--help") {
|
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
export interface MissionAttachment {
|
|
2
|
+
index: number;
|
|
3
|
+
part_id?: string;
|
|
4
|
+
mime?: string;
|
|
5
|
+
filename?: string;
|
|
6
|
+
url: string;
|
|
7
|
+
path?: string;
|
|
8
|
+
sha256?: string;
|
|
9
|
+
}
|
|
1
10
|
export interface PublicMissionContext {
|
|
2
11
|
id: string;
|
|
3
12
|
role: "user" | "assistant";
|
|
@@ -12,6 +21,7 @@ export interface PublicMissionContext {
|
|
|
12
21
|
exit?: number;
|
|
13
22
|
time?: unknown;
|
|
14
23
|
}[];
|
|
24
|
+
attachments?: MissionAttachment[];
|
|
15
25
|
}
|
|
16
26
|
export interface MissionContextSource {
|
|
17
27
|
session_id: string;
|
|
@@ -20,6 +30,9 @@ export interface MissionContextSource {
|
|
|
20
30
|
entries: number;
|
|
21
31
|
observed_at: string;
|
|
22
32
|
history_available: boolean;
|
|
33
|
+
attachments?: (MissionAttachment & {
|
|
34
|
+
message_id: string;
|
|
35
|
+
})[];
|
|
23
36
|
}
|
|
24
37
|
export interface MissionContinuity {
|
|
25
38
|
sources: MissionContextSource[];
|
|
@@ -70,4 +83,7 @@ export declare function missionContextView(source: MissionContextSource, entries
|
|
|
70
83
|
entries: number;
|
|
71
84
|
observed_at: string;
|
|
72
85
|
history_available: boolean;
|
|
86
|
+
attachments?: (MissionAttachment & {
|
|
87
|
+
message_id: string;
|
|
88
|
+
})[];
|
|
73
89
|
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
2
|
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
3
3
|
import { join } from "node:path";
|
|
4
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
4
5
|
const record = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
5
6
|
/** Public task data only. Keep exact text/results in a lazy snapshot, not private reasoning. */
|
|
6
7
|
export function publicMissionContext(messages) {
|
|
@@ -11,6 +12,11 @@ export function publicMissionContext(messages) {
|
|
|
11
12
|
const parts = message.parts.filter(record);
|
|
12
13
|
const text = parts.filter(part => part.type === "text" && part.synthetic !== true && typeof part.text === "string")
|
|
13
14
|
.map(part => part.text).join("\n");
|
|
15
|
+
const attachments = info.role === "user" ? parts.filter(part => part.type === "file" && typeof part.url === "string")
|
|
16
|
+
.map((part, index) => ({ index, url: part.url,
|
|
17
|
+
...(typeof part.id === "string" ? { part_id: part.id } : {}),
|
|
18
|
+
...(typeof part.mime === "string" ? { mime: part.mime } : {}),
|
|
19
|
+
...(typeof part.filename === "string" ? { filename: part.filename } : {}) })) : [];
|
|
14
20
|
const tools = parts.flatMap(part => {
|
|
15
21
|
if (part.type !== "tool" || typeof part.tool !== "string" || !record(part.state))
|
|
16
22
|
return [];
|
|
@@ -23,17 +29,47 @@ export function publicMissionContext(messages) {
|
|
|
23
29
|
...(typeof metadata.exit === "number" ? { exit: metadata.exit } : {}),
|
|
24
30
|
...(part.time !== undefined ? { time: part.time } : {}) }];
|
|
25
31
|
});
|
|
26
|
-
return text.trim() || tools.length ? [{ id: info.id, role: info.role, text, tools
|
|
32
|
+
return text.trim() || tools.length || attachments.length ? [{ id: info.id, role: info.role, text, tools,
|
|
33
|
+
...(attachments.length ? { attachments } : {}) }] : [];
|
|
27
34
|
});
|
|
28
35
|
}
|
|
36
|
+
/** Store inline bytes once, not megabytes of base64 in every prompt/contract. No network fetch or new permission. */
|
|
37
|
+
async function retainAttachment(directory, attachment) {
|
|
38
|
+
if (!attachment.url.startsWith("data:")) {
|
|
39
|
+
try {
|
|
40
|
+
return attachment.url.startsWith("file:") ? { ...attachment, path: fileURLToPath(attachment.url) } : attachment;
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
return attachment;
|
|
44
|
+
} // Keep a host-specific URI usable on its owning host, not a new admission gate.
|
|
45
|
+
}
|
|
46
|
+
const comma = attachment.url.indexOf(",");
|
|
47
|
+
if (comma < 0)
|
|
48
|
+
return attachment;
|
|
49
|
+
const header = attachment.url.slice(0, comma), data = attachment.url.slice(comma + 1);
|
|
50
|
+
const bytes = /;base64$/i.test(header) ? Buffer.from(data, "base64") : Buffer.from(decodeURIComponent(data));
|
|
51
|
+
const sha256 = createHash("sha256").update(bytes).digest("hex");
|
|
52
|
+
const extension = { "image/png": ".png", "image/jpeg": ".jpg", "image/gif": ".gif", "image/webp": ".webp",
|
|
53
|
+
"application/pdf": ".pdf", "text/plain": ".txt" }[attachment.mime ?? ""] ?? ".bin";
|
|
54
|
+
const path = join(directory, "attachments", `${sha256}${extension}`);
|
|
55
|
+
await mkdir(join(directory, "attachments"), { recursive: true });
|
|
56
|
+
await writeFile(path, bytes, { flag: "wx" }).catch(error => {
|
|
57
|
+
if (error.code !== "EEXIST")
|
|
58
|
+
throw error;
|
|
59
|
+
});
|
|
60
|
+
return { ...attachment, url: pathToFileURL(path).href, path, sha256 };
|
|
61
|
+
}
|
|
29
62
|
/** Preserve earlier available entries when the host later returns a compacted/partial history. */
|
|
30
63
|
export async function retainMissionContext(directory, sessionID, messages, previous) {
|
|
31
64
|
const current = publicMissionContext(messages);
|
|
32
65
|
const retained = previous ? await readFile(previous.path, "utf8")
|
|
33
66
|
.then(content => JSON.parse(content).entries).catch(() => undefined) : undefined;
|
|
34
67
|
const merged = new Map((retained ?? []).map(entry => [entry.id, entry]));
|
|
35
|
-
for (const entry of current)
|
|
36
|
-
|
|
68
|
+
for (const entry of current) {
|
|
69
|
+
const attachments = entry.attachments ? await Promise.all(entry.attachments.map(file => retainAttachment(directory, file)))
|
|
70
|
+
: merged.get(entry.id)?.attachments;
|
|
71
|
+
merged.set(entry.id, { ...entry, ...(attachments?.length ? { attachments } : {}) });
|
|
72
|
+
}
|
|
37
73
|
const entries = [...merged.values()];
|
|
38
74
|
const content = JSON.stringify({ session_id: sessionID, entries }, null, 2) + "\n";
|
|
39
75
|
const sha256 = createHash("sha256").update(content).digest("hex");
|
|
@@ -42,8 +78,10 @@ export async function retainMissionContext(directory, sessionID, messages, previ
|
|
|
42
78
|
await mkdir(directory, { recursive: true });
|
|
43
79
|
await writeFile(path, content);
|
|
44
80
|
}
|
|
81
|
+
const attachments = entries.flatMap(entry => (entry.attachments ?? []).map(file => ({ message_id: entry.id, ...file })));
|
|
45
82
|
return { source: { session_id: sessionID, path, sha256, entries: entries.length,
|
|
46
|
-
observed_at: new Date().toISOString(), history_available: current.length > 0
|
|
83
|
+
observed_at: new Date().toISOString(), history_available: current.length > 0,
|
|
84
|
+
...(attachments.length ? { attachments } : {}) }, entries };
|
|
47
85
|
}
|
|
48
86
|
/** Small inline view, with explicit pointers to every omitted byte in the exact snapshot. */
|
|
49
87
|
export function missionContextView(source, entries, suppliedRequestIDs = []) {
|
|
@@ -338,7 +338,7 @@ export class OperatorMissionRuntime {
|
|
|
338
338
|
corrections: (state.corrections ?? []).map(({ initialPrompt: _prompt, inlineReview: _inline, ...correction }) => correction),
|
|
339
339
|
retained_review: state.review ? { run_id: state.review.runID, verdict: state.review.verdict,
|
|
340
340
|
mode: state.review.mode, author: state.review.child, result: state.review.result, self_recheck: state.review.selfRecheck } : null,
|
|
341
|
-
guidance: "Current original_requests/requirements govern; older plans remain historical. Continue from known decisions, environment, completed work, retained findings and failures. A new plan or author does not resolve findings or turn self-recheck into independent approval. Read snapshot JSON entries by message/call IDs only for a relevant gap. Recheck mutable facts when needed or conflicting; do not repeat unchanged setup/investigation/checks merely because ownership changed. Successful evidence remains with its actual author/call and input bindings; historical results are not new authority." } };
|
|
341
|
+
guidance: "Current original_requests/requirements govern; older plans remain historical. Original attachments are in sources[].attachments, ordered within each message; read their path/URL when relevant, not a prose substitute. Message IDs and indices preserve provenance, not an inferred mapping to user-assigned image numbers. Continue from known decisions, environment, completed work, retained findings and failures. A new plan or author does not resolve findings or turn self-recheck into independent approval. Read snapshot JSON entries by message/call IDs only for a relevant gap. Recheck mutable facts when needed or conflicting; do not repeat unchanged setup/investigation/checks merely because ownership changed. Successful evidence remains with its actual author/call and input bindings; historical results are not new authority." } };
|
|
342
342
|
}
|
|
343
343
|
async load(file) {
|
|
344
344
|
try {
|
|
@@ -870,6 +870,7 @@ export async function missionAcceptanceSummary(mission, run, operators, observe)
|
|
|
870
870
|
}
|
|
871
871
|
})));
|
|
872
872
|
return { original_requests: mission.requests, requirements: mission.requirements,
|
|
873
|
+
original_attachments: (mission.continuity?.sources ?? []).flatMap(source => (source.attachments ?? []).map(file => ({ session_id: source.session_id, ...file }))),
|
|
873
874
|
operation: missionOperationSummary(mission),
|
|
874
875
|
history: { status: missingAnchors.length ? "unavailable" : history.status,
|
|
875
876
|
...(history.reason ? { reason: history.reason } : missingAnchors.length ? { reason: "accepted-handoff-anchor-unavailable" } : {}),
|
|
@@ -887,7 +888,7 @@ export async function missionAcceptanceSummary(mission, run, operators, observe)
|
|
|
887
888
|
observation: mission.deliveryObservation && mission.deliveryObservation.run_id === current?.runID ? mission.deliveryObservation : null,
|
|
888
889
|
observation_source: "persisted operator Git lifecycle and formal validation records; no new Git inspection",
|
|
889
890
|
clean: mission.deliveryObservation && mission.deliveryObservation.run_id === current?.runID ? mission.deliveryObservation.clean : "not independently observed by this projection" },
|
|
890
|
-
interpretation: "Compare original requests with the submitted candidate and actual evidence. Historical PASS is not current PASS. Inspect concrete gaps, not routine archive searches or full source rereads. Existing completion and Review guards still apply." };
|
|
891
|
+
interpretation: "Compare original requests (including relevant original attachments) with the submitted candidate and what the actual evidence exercises. Functional PASS, Review PASS, or an honestly recorded unverified limitation does not establish a required visual comparison. If a mandatory outcome remains unmet, continue authorized retrieval, inspection or correction without waiting for the user. Optional caveats, valid alternative checks and reusable evidence need not block acceptance; do not reject on the word unverified alone or repeat all checks yourself. No new approval, proof file, extra Reviewer, universal screenshots or pixel-exact matching is required. Historical PASS is not current PASS. Inspect concrete gaps, not routine archive searches or full source rereads. Existing completion and Review guards still apply." };
|
|
891
892
|
}
|
|
892
893
|
export function missionReviewIndependent(mission, child) {
|
|
893
894
|
return child !== undefined && !mission.sourceAuthors?.includes(child) &&
|
package/dist/plugin/index.js
CHANGED
|
@@ -8488,12 +8488,16 @@ export const SortieDogsPlugin = async (input, options) => {
|
|
|
8488
8488
|
return settled;
|
|
8489
8489
|
},
|
|
8490
8490
|
releaseDirectUnit: async (actor) => {
|
|
8491
|
-
await releaseWriteGate(actor);
|
|
8491
|
+
const released = JSON.parse(await releaseWriteGate(actor));
|
|
8492
|
+
if (released.status === "denied")
|
|
8493
|
+
throw new Error(`mission-direct-release:${released.reason}`);
|
|
8492
8494
|
releaseSessionEnforcement(actor);
|
|
8493
8495
|
},
|
|
8494
8496
|
assertDirectUnitQuiescent: async (actor) => {
|
|
8495
8497
|
if (activeSessions.get(actor)?.inFlightCalls.size)
|
|
8496
8498
|
throw new Error("mission-direct-tools-running");
|
|
8499
|
+
if (bindingOperations.has(actor))
|
|
8500
|
+
throw new Error("mission-direct-binding-in-flight");
|
|
8497
8501
|
},
|
|
8498
8502
|
failDirectUnit: async (root, actor) => {
|
|
8499
8503
|
const direct = await input.runtimeBridge?.directMissionExecution?.(actor);
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
export declare const MODEL_COST_PRICING_SNAPSHOT: {
|
|
2
|
-
readonly checkedAt: "2026-
|
|
2
|
+
readonly checkedAt: "2026-10-27";
|
|
3
3
|
readonly currency: "USD";
|
|
4
4
|
readonly unit: "1M tokens";
|
|
5
|
-
readonly sources: readonly ["https://developers.openai.com/api/docs/pricing", "https://developers.openai.com/api/docs/models/gpt-6-astra", "https://developers.openai.com/api/docs/models/gpt-6-sol", "https://developers.openai.com/api/docs/models/gpt-6.1-sol", "https://developers.openai.com/api/docs/models/gpt-6-luna", "https://developers.openai.com/api/docs/guides/fast-mode", "https://developers.openai.com/api/docs/models/gpt-5.6-sol", "https://developers.openai.com/api/docs/models/gpt-5.6-terra", "https://developers.openai.com/api/docs/models/gpt-5.6-luna", "https://platform.claude.com/docs/en/about-claude/pricing"];
|
|
6
|
-
readonly assumptions: readonly ["OpenAI Standard pricing; requests above 272,000 total input/cache tokens use 2x input/cache and 1.5x output pricing.", "Anthropic Standard pricing with the 5-minute cache-write rate; Batch, Flex, regional, tool, and subscription charges are excluded.", "variant and serviceTier are separate; model variants do not alter the selected Standard token price.", "GPT-6 Sol, GPT-6.1 Sol, and GPT-6 Luna use their official Standard schedules; the OpenCode gpt-6-luna-fast selector sends API model gpt-6-luna with priority service tier.", "For GPT-6 Sol, GPT-6.1 Sol, and GPT-6 Luna, Fast mode (service_tier fast or priority, including the gpt-6.1-sol-fast selector) multiplies applicable Standard rates by 2, including cache and long-context multipliers.", "gpt-5.6-luna-fast is retained only as a compatibility price for historical host catalog entries; it has no published model page and is exactly twice the GPT-5.6 Luna Standard schedule."];
|
|
5
|
+
readonly sources: readonly ["https://developers.openai.com/api/docs/pricing", "https://developers.openai.com/api/docs/models/gpt-6-astra", "https://developers.openai.com/api/docs/models/gpt-6-sol", "https://developers.openai.com/api/docs/models/gpt-6.1-sol", "https://developers.openai.com/api/docs/models/gpt-6.1-terra", "https://developers.openai.com/api/docs/models/gpt-6-luna", "https://developers.openai.com/api/docs/guides/fast-mode", "https://developers.openai.com/api/docs/models/gpt-5.6-sol", "https://developers.openai.com/api/docs/models/gpt-5.6-terra", "https://developers.openai.com/api/docs/models/gpt-5.6-luna", "https://platform.claude.com/docs/en/about-claude/pricing"];
|
|
6
|
+
readonly assumptions: readonly ["OpenAI Standard pricing; requests above 272,000 total input/cache tokens use 2x input/cache and 1.5x output pricing.", "Anthropic Standard pricing with the 5-minute cache-write rate; Batch, Flex, regional, tool, and subscription charges are excluded.", "variant and serviceTier are separate; model variants do not alter the selected Standard token price.", "GPT-6.1 Terra Standard uses $1 input, $0.05 cache read, $1.25 30-minute cache write and $5 output per 1M tokens; subscription usage/limits are separate from this API-equivalent estimate.", "GPT-6 Sol, GPT-6.1 Sol, and GPT-6 Luna use their official Standard schedules; the OpenCode gpt-6-luna-fast selector sends API model gpt-6-luna with priority service tier.", "For GPT-6 Sol, GPT-6.1 Sol, GPT-6.1 Terra, and GPT-6 Luna, Fast mode (service_tier fast or priority, including the gpt-6.1-sol-fast selector) multiplies applicable Standard rates by 2, including cache and long-context multipliers.", "gpt-5.6-luna-fast is retained only as a compatibility price for historical host catalog entries; it has no published model page and is exactly twice the GPT-5.6 Luna Standard schedule."];
|
|
7
7
|
};
|
|
8
8
|
export interface ModelCostUsage {
|
|
9
9
|
readonly providerID: string | undefined;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export const MODEL_COST_PRICING_SNAPSHOT = {
|
|
2
|
-
checkedAt: "2026-
|
|
2
|
+
checkedAt: "2026-10-27",
|
|
3
3
|
currency: "USD",
|
|
4
4
|
unit: "1M tokens",
|
|
5
5
|
sources: [
|
|
@@ -7,6 +7,7 @@ export const MODEL_COST_PRICING_SNAPSHOT = {
|
|
|
7
7
|
"https://developers.openai.com/api/docs/models/gpt-6-astra",
|
|
8
8
|
"https://developers.openai.com/api/docs/models/gpt-6-sol",
|
|
9
9
|
"https://developers.openai.com/api/docs/models/gpt-6.1-sol",
|
|
10
|
+
"https://developers.openai.com/api/docs/models/gpt-6.1-terra",
|
|
10
11
|
"https://developers.openai.com/api/docs/models/gpt-6-luna",
|
|
11
12
|
"https://developers.openai.com/api/docs/guides/fast-mode",
|
|
12
13
|
"https://developers.openai.com/api/docs/models/gpt-5.6-sol",
|
|
@@ -18,8 +19,9 @@ export const MODEL_COST_PRICING_SNAPSHOT = {
|
|
|
18
19
|
"OpenAI Standard pricing; requests above 272,000 total input/cache tokens use 2x input/cache and 1.5x output pricing.",
|
|
19
20
|
"Anthropic Standard pricing with the 5-minute cache-write rate; Batch, Flex, regional, tool, and subscription charges are excluded.",
|
|
20
21
|
"variant and serviceTier are separate; model variants do not alter the selected Standard token price.",
|
|
22
|
+
"GPT-6.1 Terra Standard uses $1 input, $0.05 cache read, $1.25 30-minute cache write and $5 output per 1M tokens; subscription usage/limits are separate from this API-equivalent estimate.",
|
|
21
23
|
"GPT-6 Sol, GPT-6.1 Sol, and GPT-6 Luna use their official Standard schedules; the OpenCode gpt-6-luna-fast selector sends API model gpt-6-luna with priority service tier.",
|
|
22
|
-
"For GPT-6 Sol, GPT-6.1 Sol, and GPT-6 Luna, Fast mode (service_tier fast or priority, including the gpt-6.1-sol-fast selector) multiplies applicable Standard rates by 2, including cache and long-context multipliers.",
|
|
24
|
+
"For GPT-6 Sol, GPT-6.1 Sol, GPT-6.1 Terra, and GPT-6 Luna, Fast mode (service_tier fast or priority, including the gpt-6.1-sol-fast selector) multiplies applicable Standard rates by 2, including cache and long-context multipliers.",
|
|
23
25
|
"gpt-5.6-luna-fast is retained only as a compatibility price for historical host catalog entries; it has no published model page and is exactly twice the GPT-5.6 Luna Standard schedule.",
|
|
24
26
|
],
|
|
25
27
|
};
|
|
@@ -27,6 +29,7 @@ const OPENAI = {
|
|
|
27
29
|
"gpt-6-astra": { input: 10, cacheRead: 1, cacheWrite: 12.5, output: 50 },
|
|
28
30
|
"gpt-6-sol": { input: 2, cacheRead: 0.2, cacheWrite: 2.5, output: 10 },
|
|
29
31
|
"gpt-6.1-sol": { input: 2, cacheRead: 0.1, cacheWrite: 2.5, output: 10 },
|
|
32
|
+
"gpt-6.1-terra": { input: 1, cacheRead: 0.05, cacheWrite: 1.25, output: 5 },
|
|
30
33
|
"gpt-6-luna": { input: 0.1, cacheRead: 0.01, cacheWrite: 0.125, output: 0.5 },
|
|
31
34
|
"gpt-5.6-sol": { input: 4, cacheRead: 0.4, cacheWrite: 5, output: 20 },
|
|
32
35
|
"gpt-5.6": { input: 4, cacheRead: 0.4, cacheWrite: 5, output: 20 },
|
|
@@ -49,7 +52,7 @@ export function estimateModelUsageCost(usage) {
|
|
|
49
52
|
const sol61FastAlias = usage.providerID?.toLowerCase() === "openai" && usage.modelID === "gpt-6.1-sol-fast";
|
|
50
53
|
const alias = lunaFastAlias || sol61FastAlias;
|
|
51
54
|
const fast = alias || (["fast", "priority"].includes(usage.serviceTier?.toLowerCase() ?? "") &&
|
|
52
|
-
usage.providerID?.toLowerCase() === "openai" && ["gpt-6-sol", "gpt-6.1-sol", "gpt-6-luna"].includes(usage.modelID ?? ""));
|
|
55
|
+
usage.providerID?.toLowerCase() === "openai" && ["gpt-6-sol", "gpt-6.1-sol", "gpt-6.1-terra", "gpt-6-luna"].includes(usage.modelID ?? ""));
|
|
53
56
|
if (usage.serviceTier !== undefined && !(fast ? ["standard", "default", "fast", "priority"] : ["standard", "default"]).includes(usage.serviceTier.toLowerCase())) {
|
|
54
57
|
return { status: "unpriced", reason: "unsupported-service-tier" };
|
|
55
58
|
}
|
package/dist/plugin/profiled.js
CHANGED
|
@@ -36,7 +36,8 @@ const SERIAL_OPTIONAL_ARGUMENTS = new Map([
|
|
|
36
36
|
"scope", "trigger", "cause", "prevention", "evidence", "evidenceRef", "id", "promotedRef", "confirmation",
|
|
37
37
|
])],
|
|
38
38
|
]);
|
|
39
|
-
const PREVIEW_WORKER_ROUTE = Object.freeze({ model: "openai/gpt-6-
|
|
39
|
+
const PREVIEW_WORKER_ROUTE = Object.freeze({ model: "openai/gpt-6.1-terra", variant: "max" });
|
|
40
|
+
const PREVIEW_LUNA_WORKER_ROUTE = Object.freeze({ model: "openai/gpt-6-luna-fast", variant: "max" });
|
|
40
41
|
const PREVIEW_SCOUT_ROUTE = Object.freeze({ model: "openai/gpt-6-luna-fast", variant: "max" });
|
|
41
42
|
/**
|
|
42
43
|
* Contract authorship, not throughput. Qualification observed a cheaper operations model emit
|
|
@@ -49,7 +50,7 @@ const PREVIEW_PRIMARY_ROUTE = Object.freeze({ model: "openai/gpt-6.1-sol", varia
|
|
|
49
50
|
const PREVIEW_REVIEW_ROUTE = Object.freeze({ model: "openai/gpt-6.1-sol", variant: "xhigh" });
|
|
50
51
|
/** Every preview route the profile can bind a role to. Catalog declaration reads this one list. */
|
|
51
52
|
const PREVIEW_ROUTES = Object.freeze([
|
|
52
|
-
PREVIEW_PRIMARY_ROUTE, PREVIEW_WORKER_ROUTE, PREVIEW_SCOUT_ROUTE, PREVIEW_OPERATIONS_ROUTE,
|
|
53
|
+
PREVIEW_PRIMARY_ROUTE, PREVIEW_WORKER_ROUTE, PREVIEW_LUNA_WORKER_ROUTE, PREVIEW_SCOUT_ROUTE, PREVIEW_OPERATIONS_ROUTE,
|
|
53
54
|
PREVIEW_REVIEW_ROUTE,
|
|
54
55
|
]);
|
|
55
56
|
function missionReportReview(mission, runID) {
|
|
@@ -1492,8 +1493,8 @@ export function createProfiledPlugin(profile, assetVersion) {
|
|
|
1492
1493
|
}
|
|
1493
1494
|
async function stop(root, reason, retireRoot = true) {
|
|
1494
1495
|
const directActor = (await operators.read(root))?.units.find(unit => unit.status === "running" && unit.directExecution)?.directExecution?.actor;
|
|
1495
|
-
|
|
1496
|
-
|
|
1496
|
+
// Stopping owned execution does not write its artifacts. Its existing reservation
|
|
1497
|
+
// is reconciled by cancelChildren, even when activation never acquired a writer.
|
|
1497
1498
|
if (retireRoot)
|
|
1498
1499
|
retired.add(root);
|
|
1499
1500
|
if (retireRoot)
|
|
@@ -2289,7 +2290,9 @@ export function createProfiledPlugin(profile, assetVersion) {
|
|
|
2289
2290
|
record(part.state.metadata) && ["running", "pending", "unknown"].includes(String(part.state.metadata.status)))) {
|
|
2290
2291
|
return JSON.stringify({ status: "direct-handoff-awaits-tools", next_action: "Finish the existing native command before handing off this unit; retain its result and continue here or delegate afterwards." });
|
|
2291
2292
|
}
|
|
2292
|
-
|
|
2293
|
+
// Yielding execution is management, not an artifact write. In particular, a
|
|
2294
|
+
// direct admission can exist even when its writer could not bind because another
|
|
2295
|
+
// live owner overlaps. Do not require that contested binding to hand it off.
|
|
2293
2296
|
const mission = await missions.retainContext(root, actor, history, notes);
|
|
2294
2297
|
await operators.handoffDirect(root, actor, await missions.handoffContext(mission));
|
|
2295
2298
|
}
|
|
@@ -3599,7 +3602,7 @@ export function createProfiledPlugin(profile, assetVersion) {
|
|
|
3599
3602
|
else if (args.status === "blocked" || args.status === "needs-decision") {
|
|
3600
3603
|
// This owner is stopping its direct work, not validating it. Keep the
|
|
3601
3604
|
// failed checks/candidate and settle its existing reservation once.
|
|
3602
|
-
const direct = await
|
|
3605
|
+
const direct = await directExecution(context.sessionID);
|
|
3603
3606
|
if (direct)
|
|
3604
3607
|
await control.failDirectUnit(root, context.sessionID);
|
|
3605
3608
|
}
|
|
@@ -3811,7 +3814,7 @@ export function createProfiledPlugin(profile, assetVersion) {
|
|
|
3811
3814
|
const agent = record(agents[name]) ? agents[name] : undefined;
|
|
3812
3815
|
if (!agent)
|
|
3813
3816
|
continue;
|
|
3814
|
-
const route = role === "dog-scout" ? PREVIEW_SCOUT_ROUTE :
|
|
3817
|
+
const route = role === "dog-scout" ? PREVIEW_SCOUT_ROUTE : PREVIEW_LUNA_WORKER_ROUTE;
|
|
3815
3818
|
agent.model ??= route.model;
|
|
3816
3819
|
if (agent.variant === undefined && agent.model === route.model)
|
|
3817
3820
|
agent.variant = route.variant;
|
|
@@ -4014,7 +4017,11 @@ export function createProfiledPlugin(profile, assetVersion) {
|
|
|
4014
4017
|
throw new Error(RUNTIME_PROFILE_SESSION_INACTIVE);
|
|
4015
4018
|
if (request.tool.startsWith("sortie_") && !request.tool.startsWith(profile.toolPrefix))
|
|
4016
4019
|
throw new Error("runtime-profile-tool-mismatch");
|
|
4017
|
-
|
|
4020
|
+
// Management can reconcile, yield, stop or report the owner's admission.
|
|
4021
|
+
// They must remain reachable when its artifact binding is the thing in conflict.
|
|
4022
|
+
// Ordinary tools and the parts of planning that actually write still activate it.
|
|
4023
|
+
const direct = request.tool === status || request.tool === planUnits || request.tool === cancel || request.tool === submitMission
|
|
4024
|
+
? await directExecution(request.sessionID) : await activateDirect(request.sessionID);
|
|
4018
4025
|
const writer = who.role === "dog-worker" || !!direct || !!await reviewerCorrection(request.sessionID);
|
|
4019
4026
|
if (who.role === "dog-reviewer" && writer) {
|
|
4020
4027
|
const correction = (await reviewerCorrection(request.sessionID));
|
package/dist/plugin/v2.js
CHANGED
|
@@ -90,6 +90,22 @@ function legacyPart(value, session, message) {
|
|
|
90
90
|
...(time ? { time: { start: time.ran ?? time.created, end: time.completed } } : {}),
|
|
91
91
|
...(output === undefined ? {} : { output }) } };
|
|
92
92
|
}
|
|
93
|
+
/** Resolved V2 files carry the original bytes, even when their source URI is no longer readable. */
|
|
94
|
+
function legacyUserParts(text, files, session, message) {
|
|
95
|
+
return [{ id: `${message}-text`, sessionID: session, messageID: message, type: "text", text },
|
|
96
|
+
...array(files).flatMap((file, index) => {
|
|
97
|
+
if (!record(file))
|
|
98
|
+
return [];
|
|
99
|
+
const mime = string(file.mime) ?? "application/octet-stream";
|
|
100
|
+
const url = typeof file.data === "string" ? `data:${mime};base64,${file.data}`
|
|
101
|
+
: string(file.uri); // The prompt hook runs before URI resolution.
|
|
102
|
+
if (!url)
|
|
103
|
+
return [];
|
|
104
|
+
return [{ id: `${message}-file-${index}`, sessionID: session, messageID: message, type: "file", mime, url,
|
|
105
|
+
...(typeof file.name === "string" ? { filename: file.name } : {}),
|
|
106
|
+
...(record(file.source) ? { source: file.source } : {}) }];
|
|
107
|
+
})];
|
|
108
|
+
}
|
|
93
109
|
function legacyMessage(value, session, agent) {
|
|
94
110
|
if (!record(value) || typeof value.id !== "string" || typeof value.type !== "string")
|
|
95
111
|
return undefined;
|
|
@@ -97,7 +113,7 @@ function legacyMessage(value, session, agent) {
|
|
|
97
113
|
const originalAgent = record(value.metadata) ? string(value.metadata.agent) ?? agent : agent;
|
|
98
114
|
if (value.type === "user") {
|
|
99
115
|
return { info: { id, sessionID: session, role: "user", agent: originalAgent, time: value.time },
|
|
100
|
-
parts:
|
|
116
|
+
parts: legacyUserParts(String(value.text ?? ""), value.files, session, id) };
|
|
101
117
|
}
|
|
102
118
|
if (value.type !== "assistant") {
|
|
103
119
|
if (value.type === "synthetic")
|
|
@@ -289,8 +305,22 @@ function toolContentText(content) {
|
|
|
289
305
|
return values.length === 0 ? undefined : values.join("\n");
|
|
290
306
|
}
|
|
291
307
|
function replaceToolContent(result, text) {
|
|
292
|
-
|
|
293
|
-
|
|
308
|
+
if (toolContentText(result.content) === text)
|
|
309
|
+
return result;
|
|
310
|
+
if (typeof result.content === "string")
|
|
311
|
+
return { ...result, content: text };
|
|
312
|
+
let replaced = false;
|
|
313
|
+
const content = array(result.content).flatMap(item => {
|
|
314
|
+
if (!record(item) || item.type !== "text" || typeof item.text !== "string")
|
|
315
|
+
return [item];
|
|
316
|
+
if (replaced)
|
|
317
|
+
return [];
|
|
318
|
+
replaced = true;
|
|
319
|
+
return [{ ...item, text }];
|
|
320
|
+
});
|
|
321
|
+
// Only the legacy textual projection changed. Native file/image blocks must still reach
|
|
322
|
+
// the host's model-input lowering, including images returned through Code Mode.
|
|
323
|
+
return { ...result, content: replaced ? content : [...content, { type: "text", text }] };
|
|
294
324
|
}
|
|
295
325
|
function assistantText(message) {
|
|
296
326
|
if (!record(message) || message.type !== "assistant" || message.finish !== "stop" || typeof message.id !== "string")
|
|
@@ -542,7 +572,7 @@ async function registerV2Hooks(context, hooks, background, liveState) {
|
|
|
542
572
|
["dog-reviewer-v010", "gpt-6.1-sol", "xhigh"],
|
|
543
573
|
["dog-scout-v010", "gpt-6-luna-fast", "max"],
|
|
544
574
|
["dog-luna-worker-v010", "gpt-6-luna-fast", "max"],
|
|
545
|
-
["dog-worker-v010", "gpt-6-
|
|
575
|
+
["dog-worker-v010", "gpt-6.1-terra", "max"],
|
|
546
576
|
])
|
|
547
577
|
editor.update(name, agent => { agent.model ??= { providerID: "openai", id, variant }; });
|
|
548
578
|
editor.update("dog-reviewer-v010", agent => {
|
|
@@ -784,7 +814,7 @@ async function registerV2Hooks(context, hooks, background, liveState) {
|
|
|
784
814
|
selectedChildModels.add(String(event.sessionID));
|
|
785
815
|
}
|
|
786
816
|
const output = { message: { id: String(event.messageID ?? ""), agent: string(info.agent), model },
|
|
787
|
-
parts:
|
|
817
|
+
parts: legacyUserParts(legacyText, event.prompt.files, String(event.sessionID), String(event.messageID ?? "")) };
|
|
788
818
|
await hooks["chat.message"]({ sessionID: String(event.sessionID), messageID: String(event.messageID ?? ""),
|
|
789
819
|
...(typeof info.agent === "string" ? { agent: info.agent } : {}), model }, output);
|
|
790
820
|
await reconcileCorrectionPermissions(String(event.sessionID));
|
|
@@ -427,7 +427,8 @@ export const runtimeAssets = Object.freeze([
|
|
|
427
427
|
content = content.replace("mode: subagent\n", "mode: subagent\nhidden: true\n");
|
|
428
428
|
}
|
|
429
429
|
if (["dog-worker", "dog-luna-worker", "dog-scout"].includes(asset.name)) {
|
|
430
|
-
|
|
430
|
+
const model = asset.name === "dog-worker" ? "openai/gpt-6.1-terra#max" : "openai/gpt-6-luna-fast#max";
|
|
431
|
+
content = content.replace("mode: subagent\n", `mode: subagent\nmodel: ${model}\n`);
|
|
431
432
|
}
|
|
432
433
|
if (["dog-reviewer", "dog-advisor"].includes(asset.name)) {
|
|
433
434
|
content = content.replace("mode: subagent\n", "mode: subagent\nmodel: openai/gpt-6.1-sol#xhigh\n");
|
|
@@ -155,6 +155,17 @@ ${MISSION_DEPENDENCY_WORKFLOW}
|
|
|
155
155
|
SAME mission before any Worker starts, retains its Coordinator and cumulative spend, and checks
|
|
156
156
|
old children before preparing a Worker. This is not permission to discard unchanged acceptance:
|
|
157
157
|
if the scope is uncertain, ask the user which requirements remain instead of inferring a replacement.
|
|
158
|
+
When execution management is inconsistent or manifest-overlap blocks the owning direct writer,
|
|
159
|
+
explain the observed stop, what can be reconciled, and that the existing requirements, results,
|
|
160
|
+
checks and cumulative spend remain. Offer to recover and continue in ordinary conversation;
|
|
161
|
+
an ordinary affirmative reply or a request to self-recover is enough. No hidden command or ID is
|
|
162
|
+
needed from the user, and ordinary autonomous recovery does not require a new approval.
|
|
163
|
+
Inspect operator_status to reconcile only native-proven ended work. If this session owns a quiescent
|
|
164
|
+
direct admission that cannot bind, plan_units with executor: "worker" and no units yields that same
|
|
165
|
+
unit and reservation without acquiring the contested writer. Explain the result and continue the
|
|
166
|
+
returned Task when its write scope is available. A genuinely live or unproven other owner is not
|
|
167
|
+
released: wait or separate work, and do not dispatch repeated conflicting attempts. Do not invent
|
|
168
|
+
terminal state, validation success, a fresh Mission, or a budget reset.
|
|
158
169
|
If a Coordinator reports mission-replan-worker-still-active after an interrupted native Task,
|
|
159
170
|
it cannot call cancel_operator (root-only). Inspect operator_status and the native Task outcome.
|
|
160
171
|
If the Worker is still active, wait, not duplicate. If the user chose to stop/replan, root calls
|
|
@@ -216,7 +227,17 @@ ${MISSION_DEPENDENCY_WORKFLOW}
|
|
|
216
227
|
and cumulative budget. Use its Coordinator Task only for real coordination, contract discovery or
|
|
217
228
|
correction that cannot be handled directly. Never replace an active Worker or ask for routine approval.
|
|
218
229
|
4. After the review decision (including a justified low-risk skip), compare the completion candidate
|
|
219
|
-
|
|
230
|
+
against the original request, real source and observed evidence before final acceptance.
|
|
231
|
+
Include relevant original attachments: continuity sources retain ordered, message-linked read references
|
|
232
|
+
to the original bytes, not a descriptive substitute. Retrieve/inspect those references when needed.
|
|
233
|
+
Judge what each existing check actually exercises. Functional PASS, Review PASS, or honestly retaining
|
|
234
|
+
an unverified caveat does not establish a required visual comparison. If a mandatory outcome is unmet,
|
|
235
|
+
continue authorized retrieval, inspection or correction without waiting for a user reminder or approval.
|
|
236
|
+
Choose the effective method/author; reuse applicable evidence rather than repeat every check yourself.
|
|
237
|
+
Optional caveats and valid alternative verification can permit acceptance: the word unverified alone
|
|
238
|
+
is not a stop rule. This adds no approval gate, proof file, extra Reviewer, universal screenshot duty
|
|
239
|
+
or pixel-exact matching requirement. Keep autonomy, efficiency and visibility: report the actual gap
|
|
240
|
+
and next action, not an unsupported completion claim or a new restriction on ordinary work.
|
|
220
241
|
For a Coordinator ready candidate, use operator_status's acceptance_summary: verbatim original
|
|
221
242
|
requests, anchored cumulative formal validation, current review disposition (author self-recheck
|
|
222
243
|
is not independent approval) and recorded delivery state.
|
|
@@ -484,6 +505,10 @@ in this SAME session when your existing context makes that efficient. You are no
|
|
|
484
505
|
Use the Operator's preferred_executor as a starting recommendation. Start useful work with available context;
|
|
485
506
|
do not investigate merely to confirm the recommendation. Adapt through actual work, honoring explicit user choices.
|
|
486
507
|
Use plan_units with executor: "self" for direct work, or start_direct_unit for an already prepared unit.
|
|
508
|
+
If a direct admission cannot bind because of manifest-overlap, operator_status and plan_units with
|
|
509
|
+
executor: "worker" and no units remain management operations: yield only this quiescent owner, retain
|
|
510
|
+
its checks and reservation, and wait for a real conflicting writer rather than evicting it. Continue
|
|
511
|
+
the same Mission and actual remaining work; do not create another Mission to clear the conflict.
|
|
487
512
|
The host binds your native check results to the candidate; finish_direct_unit closes that work without
|
|
488
513
|
a Worker handoff. Independent Review and Operator final acceptance still follow. This is not limited to
|
|
489
514
|
micro-edits. Delegate to the configured Worker when that reduces work/cost or provides useful separation.
|