sortie-dogs 0.12.7 → 0.12.8
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/asset-version.d.ts +1 -1
- package/dist/asset-version.js +1 -1
- package/dist/core/operator-mission.d.ts +2 -0
- package/dist/core/operator-mission.js +31 -7
- package/dist/core/operator-runtime.d.ts +1 -1
- package/dist/core/operator-runtime.js +17 -3
- package/dist/plugin/profiled.d.ts +8 -0
- package/dist/plugin/profiled.js +77 -10
- package/dist/plugin/v2.js +3 -2
- package/package.json +1 -1
package/dist/asset-version.d.ts
CHANGED
|
@@ -3,5 +3,5 @@
|
|
|
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.12.
|
|
6
|
+
export declare const V010_RUNTIME_ASSET_VERSION = "0.12.8-mission-lineage-v1";
|
|
7
7
|
export type RuntimeAssetVersion = typeof RUNTIME_ASSET_VERSION | typeof V010_RUNTIME_ASSET_VERSION;
|
package/dist/asset-version.js
CHANGED
|
@@ -3,4 +3,4 @@
|
|
|
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.12.
|
|
6
|
+
export const V010_RUNTIME_ASSET_VERSION = "0.12.8-mission-lineage-v1";
|
|
@@ -75,6 +75,8 @@ export declare class OperatorMissionRuntime {
|
|
|
75
75
|
capture(root: string, request: MissionRequest): Promise<void>;
|
|
76
76
|
start(root: string, requirements: unknown): Promise<OperatorMission>;
|
|
77
77
|
update(root: string, change: (state: OperatorMission) => void): Promise<OperatorMission>;
|
|
78
|
+
/** Keep a cancelled same-turn run's host-accepted criteria ahead of new mission text. */
|
|
79
|
+
carryForward(root: string, missionID: string, acceptance: readonly string[]): Promise<OperatorMission>;
|
|
78
80
|
task(state: OperatorMission): OperatorTask;
|
|
79
81
|
admit(root: string, callID: string, args: Record<string, unknown>): Promise<OperatorMission>;
|
|
80
82
|
/** Reopen only the exact dispatch whose native Task has a terminal record after a server restart. */
|
|
@@ -58,7 +58,7 @@ export class OperatorMissionRuntime {
|
|
|
58
58
|
async loadMission(root) {
|
|
59
59
|
const state = await this.load(this.file(root));
|
|
60
60
|
if (!state || state.supersededRunID !== undefined || state.runID !== null ||
|
|
61
|
-
!["open", "running", "submitted"].includes(state.phase) || state.requests.length === 0)
|
|
61
|
+
!["open", "running", "submitted", "cancelled"].includes(state.phase) || state.requests.length === 0)
|
|
62
62
|
return state;
|
|
63
63
|
const directory = join(this.projectRoot, this.profile.stateDirectory, "missions");
|
|
64
64
|
let entries;
|
|
@@ -75,13 +75,18 @@ export class OperatorMissionRuntime {
|
|
|
75
75
|
const matches = [];
|
|
76
76
|
for (const name of candidates) {
|
|
77
77
|
const previous = await this.load(join(directory, name));
|
|
78
|
-
if (previous?.root === root && previous.phase === "cancelled" &&
|
|
79
|
-
previous.
|
|
78
|
+
if (previous?.root === root && previous.phase === "cancelled" &&
|
|
79
|
+
(previous.runID !== null || previous.supersededRunID !== undefined) &&
|
|
80
|
+
(previous.runID === null || previous.requests[0]?.id !== state.requests[0].id) &&
|
|
80
81
|
previous.requests.some(request => request.id === state.requests[0].id))
|
|
81
82
|
matches.push(previous);
|
|
82
83
|
}
|
|
83
|
-
if (matches.length === 1)
|
|
84
|
-
|
|
84
|
+
if (matches.length === 1) {
|
|
85
|
+
const predecessor = matches[0].runID ?? matches[0].supersededRunID;
|
|
86
|
+
if (predecessor && (matches[0].runID !== null || await this.archivedRun(root, predecessor))) {
|
|
87
|
+
state.supersededRunID = predecessor;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
85
90
|
return state;
|
|
86
91
|
}
|
|
87
92
|
/** Find exactly one archived cancelled mission that owned this run; ambiguity never grants recovery. */
|
|
@@ -178,8 +183,10 @@ export class OperatorMissionRuntime {
|
|
|
178
183
|
const state = { version: "0.12", id: `mission-${randomUUID()}`, root, requests: [request],
|
|
179
184
|
requirements: requirements.map((text, index) => ({ id: `R${index + 1}`, text })), phase: "open",
|
|
180
185
|
coordinator: null, callID: null, dispatchOpen: false, runID: null, plans: 0, progress: [], submission: null,
|
|
181
|
-
...(previous?.phase === "cancelled" &&
|
|
182
|
-
|
|
186
|
+
...(previous?.phase === "cancelled" &&
|
|
187
|
+
(previous.runID === null || request.id !== previous.requests[0]?.id) &&
|
|
188
|
+
(previous.runID ?? previous.supersededRunID)
|
|
189
|
+
? { supersededRunID: (previous.runID ?? previous.supersededRunID) } : {}) };
|
|
183
190
|
await this.save(this.file(root), state);
|
|
184
191
|
return state;
|
|
185
192
|
});
|
|
@@ -194,6 +201,23 @@ export class OperatorMissionRuntime {
|
|
|
194
201
|
return state;
|
|
195
202
|
});
|
|
196
203
|
}
|
|
204
|
+
/** Keep a cancelled same-turn run's host-accepted criteria ahead of new mission text. */
|
|
205
|
+
carryForward(root, missionID, acceptance) {
|
|
206
|
+
return this.update(root, state => {
|
|
207
|
+
if (state.id !== missionID || state.supersededRunID !== undefined || state.runID !== null ||
|
|
208
|
+
!["open", "running"].includes(state.phase) || (state.dispatchOpen && state.coordinator === null) ||
|
|
209
|
+
acceptance.length === 0 || acceptance.some(text => typeof text !== "string" || !text.trim())) {
|
|
210
|
+
throw new Error("mission-acceptance-carry-forward-unavailable");
|
|
211
|
+
}
|
|
212
|
+
const existing = state.requirements.map(item => item.text);
|
|
213
|
+
if (acceptance.every((text, index) => existing[index] === text))
|
|
214
|
+
return;
|
|
215
|
+
const additions = existing.filter(text => !acceptance.includes(text));
|
|
216
|
+
if (acceptance.length + additions.length > 64)
|
|
217
|
+
throw new Error("mission-requirements-limit: carried acceptance and additions exceed 64");
|
|
218
|
+
state.requirements = [...acceptance, ...additions].map((text, index) => ({ id: `R${index + 1}`, text }));
|
|
219
|
+
});
|
|
220
|
+
}
|
|
197
221
|
task(state) {
|
|
198
222
|
return { subagent_type: profileAgent(this.profile, "dog-operator"), description: state.requirements[0].text.slice(0, 100),
|
|
199
223
|
prompt: `${MISSION_REFERENCE}${JSON.stringify({ r: state.root, m: state.id, h: digest(JSON.stringify(state.requirements)) })}`,
|
|
@@ -245,7 +245,7 @@ export declare class OperatorRuntime {
|
|
|
245
245
|
prepareMission(root: string, raw: unknown, dispatcher?: {
|
|
246
246
|
sessionID: string;
|
|
247
247
|
callID: string;
|
|
248
|
-
}, supersededRunID?: string): Promise<OperatorState>;
|
|
248
|
+
}, supersededRunID?: string, terminalChildren?: readonly string[]): Promise<OperatorState>;
|
|
249
249
|
retireMissionRun(root: string): Promise<void>;
|
|
250
250
|
private prepareOnce;
|
|
251
251
|
operatorTask(state: OperatorState): OperatorTask;
|
|
@@ -678,8 +678,8 @@ export class OperatorRuntime {
|
|
|
678
678
|
}
|
|
679
679
|
}
|
|
680
680
|
/** Mission authority is supplied only by the owning profile, never by a model-authored plan. */
|
|
681
|
-
prepareMission(root, raw, dispatcher, supersededRunID) {
|
|
682
|
-
return this.serial(root, () => this.prepareOnce(root, raw, undefined, { dispatcher, supersededRunID }));
|
|
681
|
+
prepareMission(root, raw, dispatcher, supersededRunID, terminalChildren = []) {
|
|
682
|
+
return this.serial(root, () => this.prepareOnce(root, raw, undefined, { dispatcher, supersededRunID, terminalChildren }));
|
|
683
683
|
}
|
|
684
684
|
retireMissionRun(root) {
|
|
685
685
|
return this.serial(root, async () => {
|
|
@@ -727,9 +727,15 @@ export class OperatorRuntime {
|
|
|
727
727
|
previous.phase === "cancelled";
|
|
728
728
|
if (mission?.supersededRunID !== undefined && !superseding)
|
|
729
729
|
throw new Error("mission-superseded-run-mismatch");
|
|
730
|
+
const terminalChildren = mission?.terminalChildren ?? [];
|
|
731
|
+
const cancelledChildren = previous?.units.flatMap(unit => unit.status === "cancelled" && unit.childSessionID !== null
|
|
732
|
+
? [unit.childSessionID] : []) ?? [];
|
|
730
733
|
if (superseding && previous && (previous.decision !== "explicit-cancellation" || previous.gitLifecycle !== null ||
|
|
731
734
|
previous.repairResidualPaths.length > 0 || previous.priorAcceptedUnits.length > 0 ||
|
|
732
|
-
|
|
735
|
+
terminalChildren.length !== cancelledChildren.length || new Set(terminalChildren).size !== terminalChildren.length ||
|
|
736
|
+
cancelledChildren.some(id => !terminalChildren.includes(id)) || previous.units.some(unit => !["pending", "cancelled"].includes(unit.status) || unit.evidence.length > 0 || unit.resultClass !== null ||
|
|
737
|
+
unit.repairValidation !== null || (unit.status === "pending" && (unit.callID !== null || unit.childSessionID !== null)) ||
|
|
738
|
+
(unit.status === "cancelled" && (unit.childSessionID === null || unit.callID === null))))) {
|
|
733
739
|
throw new Error("mission-superseded-run-has-work: reconcile prior workers and evidence before changing acceptance");
|
|
734
740
|
}
|
|
735
741
|
if (plan.git_lifecycle !== undefined) {
|
|
@@ -743,6 +749,14 @@ export class OperatorRuntime {
|
|
|
743
749
|
// Cancellation stops execution, not the accepted user order. A replacement
|
|
744
750
|
// plan must carry the original ordered criteria; only a completed root clears them.
|
|
745
751
|
const parent = !superseding && previous?.phase === "cancelled" ? previous : undefined;
|
|
752
|
+
if (parent?.decision === "explicit-cancellation") {
|
|
753
|
+
const cancelled = parent.units.flatMap(unit => unit.status === "cancelled" && unit.childSessionID !== null
|
|
754
|
+
? [unit.childSessionID] : []);
|
|
755
|
+
if (cancelled.length > 0 && (new Set(terminalChildren).size !== terminalChildren.length ||
|
|
756
|
+
cancelled.some(id => !terminalChildren.includes(id)))) {
|
|
757
|
+
throw new Error("mission-cancelled-run-worker-not-terminal");
|
|
758
|
+
}
|
|
759
|
+
}
|
|
746
760
|
if (parent?.decision === "operator-contract-repair-unavailable-after-cancel") {
|
|
747
761
|
// The diagnosed transients, not the cancellation itself, block a replacement. Once they are
|
|
748
762
|
// gone the same accepted order may proceed; while they remain the refusal names them exactly.
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type OperatorState } from "../core/operator-runtime.js";
|
|
1
2
|
import { type RuntimeProfile } from "../core/runtime-profile.js";
|
|
2
3
|
import { type OpenCodePlugin } from "./index.js";
|
|
3
4
|
import { type CatalogModel } from "./model-routing.js";
|
|
@@ -20,6 +21,13 @@ export declare function previewModelCatalog(routes?: readonly {
|
|
|
20
21
|
readonly model: string;
|
|
21
22
|
readonly variant: string;
|
|
22
23
|
}[], base?: readonly CatalogModel[]): readonly CatalogModel[];
|
|
24
|
+
/** Native V2 termination and lineage are required before a cancelled Worker loses its old acceptance. */
|
|
25
|
+
export declare function terminalCancelledMissionChildren(profile: RuntimeProfile, root: string, previous: OperatorState, budget: {
|
|
26
|
+
reserved_units: number;
|
|
27
|
+
} | null, host: {
|
|
28
|
+
get(id: string): Promise<unknown>;
|
|
29
|
+
children(id: string): Promise<unknown>;
|
|
30
|
+
}): Promise<string[]>;
|
|
23
31
|
/** One transport namespace around the existing MkII engine; no second write gate or acceptance engine. */
|
|
24
32
|
export declare function createProfiledPlugin(profile: RuntimeProfile, assetVersion: string): OpenCodePlugin;
|
|
25
33
|
export declare const SortieDogsV010Plugin: OpenCodePlugin;
|
package/dist/plugin/profiled.js
CHANGED
|
@@ -82,6 +82,34 @@ export function previewModelCatalog(routes = PREVIEW_ROUTES, base = BUILT_IN_MOD
|
|
|
82
82
|
}
|
|
83
83
|
const record = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
84
84
|
const payload = (value) => record(value) && "data" in value ? value.data : value;
|
|
85
|
+
/** Native V2 termination and lineage are required before a cancelled Worker loses its old acceptance. */
|
|
86
|
+
export async function terminalCancelledMissionChildren(profile, root, previous, budget, host) {
|
|
87
|
+
if (!budget || budget.reserved_units !== 0)
|
|
88
|
+
throw new Error("mission-superseded-run-reservations-pending");
|
|
89
|
+
const oldWorkers = previous.units.flatMap(unit => unit.childSessionID === null ? [] : [unit.childSessionID]);
|
|
90
|
+
if (oldWorkers.length === 0)
|
|
91
|
+
return [];
|
|
92
|
+
const coordinatorID = previous.operatorSessionID;
|
|
93
|
+
const coordinator = coordinatorID && await host.get(coordinatorID);
|
|
94
|
+
if (coordinatorID === null || !record(coordinator) || coordinator.parentID !== root ||
|
|
95
|
+
canonicalAgent(profile, coordinator.agent) !== "dog-operator" || coordinator.outcome !== "interrupted") {
|
|
96
|
+
throw new Error("mission-superseded-coordinator-not-terminal");
|
|
97
|
+
}
|
|
98
|
+
const children = await host.children(coordinatorID);
|
|
99
|
+
if (!Array.isArray(children) || children.length !== oldWorkers.length ||
|
|
100
|
+
children.some(child => !record(child) || !oldWorkers.includes(child.id))) {
|
|
101
|
+
throw new Error("mission-superseded-worker-lineage-unproven");
|
|
102
|
+
}
|
|
103
|
+
for (const id of oldWorkers) {
|
|
104
|
+
const worker = await host.get(id), descendants = await host.children(id);
|
|
105
|
+
if (!record(worker) || worker.parentID !== coordinatorID ||
|
|
106
|
+
!["dog-worker", "dog-luna-worker"].includes(canonicalAgent(profile, worker.agent) ?? "") ||
|
|
107
|
+
worker.outcome !== "interrupted" || !Array.isArray(descendants) || descendants.length !== 0) {
|
|
108
|
+
throw new Error("mission-superseded-worker-not-terminal");
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return oldWorkers;
|
|
112
|
+
}
|
|
85
113
|
const RUNTIME_PROFILE_SESSION_INACTIVE = "runtime-profile-session-inactive: non-profile agents retain native read, edit, patch, shell, and task tools; continue directly without Sortie profile tools";
|
|
86
114
|
const fallbackOptionalSchema = (schema) => record(schema) && schema.type === "string" && typeof schema.optional !== "function"
|
|
87
115
|
? { ...schema, "x-sortie-optional": true }
|
|
@@ -406,6 +434,19 @@ export function createProfiledPlugin(profile, assetVersion) {
|
|
|
406
434
|
}
|
|
407
435
|
return packet;
|
|
408
436
|
}
|
|
437
|
+
async function retainCancelledMissionAcceptance(root, mission, prior) {
|
|
438
|
+
const previous = prior ?? await operators.read(root);
|
|
439
|
+
if (previous?.phase !== "cancelled" || mission.supersededRunID !== undefined || mission.runID !== null)
|
|
440
|
+
return mission;
|
|
441
|
+
// A different original user request needs the explicit, host-proven supersession path.
|
|
442
|
+
// Only the same source can retain a cancelled run's acceptance as a prefix.
|
|
443
|
+
if (previous.sourceRefs[0] !== `user:${mission.requests[0]?.id}` ||
|
|
444
|
+
!previous.sourceRefs.every(ref => mission.requests.some(request => ref === `user:${request.id}`))) {
|
|
445
|
+
throw new Error("mission-cancelled-source-unproven");
|
|
446
|
+
}
|
|
447
|
+
return previous.acceptance.every((text, index) => mission.requirements[index]?.text === text)
|
|
448
|
+
? mission : missions.carryForward(root, mission.id, previous.acceptance);
|
|
449
|
+
}
|
|
409
450
|
async function restorePriorAcceptance(root, state) {
|
|
410
451
|
const succeeded = [...state.units].reverse().find(unit => unit.status === "succeeded");
|
|
411
452
|
const current = succeeded === undefined ? undefined : {
|
|
@@ -1115,21 +1156,24 @@ export function createProfiledPlugin(profile, assetVersion) {
|
|
|
1115
1156
|
} };
|
|
1116
1157
|
const startMission = `${profile.toolPrefix}start_mission`, planUnits = `${profile.toolPrefix}plan_units`, reviewMission = `${profile.toolPrefix}review_mission`, submitMission = `${profile.toolPrefix}submit_mission`, completeMission = `${profile.toolPrefix}complete_mission`, expandUnit = `${profile.toolPrefix}expand_unit`;
|
|
1117
1158
|
const stringList = { type: "array", items: { type: "string" } };
|
|
1118
|
-
tools[startMission] = { description: "Operator: save a few one-line requirements/negative constraints. The original user message, IDs and ownership are captured automatically. Dispatch the returned Coordinator task immediately, or use plan_units for a simple single-unit Fast-lane task.",
|
|
1159
|
+
tools[startMission] = { description: "Operator: save a few one-line requirements/negative constraints. The original user message, IDs and ownership are captured automatically. A cancelled same-turn run's accepted criteria are restored from host state in their exact order before dispatch. Dispatch the returned Coordinator task immediately, or use plan_units for a simple single-unit Fast-lane task.",
|
|
1119
1160
|
args: { requirements: { ...stringList, minItems: 1, maxItems: 64 } }, execute: async (args, context) => {
|
|
1120
1161
|
await requireRoot(context.sessionID);
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1162
|
+
return serializeDispatchTransition(context.sessionID, async () => {
|
|
1163
|
+
await reconcileMissionDispatch(context.sessionID);
|
|
1164
|
+
const mission = await retainCancelledMissionAcceptance(context.sessionID, await missions.start(context.sessionID, args.requirements));
|
|
1165
|
+
return JSON.stringify(mission.dispatchOpen
|
|
1166
|
+
? missionDispatchPacket(mission, await operators.read(context.sessionID))
|
|
1167
|
+
: { mission_id: mission.id, requirements: mission.requirements, task: missions.task(mission),
|
|
1168
|
+
next_action: "Nontrivial: dispatch task now. Simple single-unit work with known scope/check: call plan_units directly. Do not create a proposal or ask for plan approval." });
|
|
1169
|
+
});
|
|
1127
1170
|
} };
|
|
1128
1171
|
async function declareMissionUnits(root, actor, mission, raw, reason) {
|
|
1172
|
+
const previous = await operators.read(root);
|
|
1173
|
+
mission = await retainCancelledMissionAcceptance(root, mission, previous);
|
|
1129
1174
|
const plan = missionPlan(mission, raw);
|
|
1130
1175
|
if (actor === root && (mission.coordinator !== null || plan.units.length !== 1))
|
|
1131
1176
|
throw new Error("mission-coordinator-required: dispatch the returned Coordinator task");
|
|
1132
|
-
const previous = await operators.read(root);
|
|
1133
1177
|
const same = previous?.planHash === createHash("sha256").update(JSON.stringify(plan)).digest("hex");
|
|
1134
1178
|
if (previous && !["completed", "cancelled"].includes(previous.phase) && !same) {
|
|
1135
1179
|
if (!reason?.trim())
|
|
@@ -1139,8 +1183,19 @@ export function createProfiledPlugin(profile, assetVersion) {
|
|
|
1139
1183
|
const budget = await control.currentBudget(root);
|
|
1140
1184
|
if (budget && budget.remaining_units < plan.units.length && !same)
|
|
1141
1185
|
throw new Error("mission-budget-exhausted: report the required cumulative extension to Operator");
|
|
1186
|
+
// Cancellation marks the durable units before interrupting their native sessions. A cancelled
|
|
1187
|
+
// status alone therefore cannot prove the old Worker stopped or its reservation settled.
|
|
1188
|
+
const cancelledPredecessor = previous?.phase === "cancelled" &&
|
|
1189
|
+
(mission.supersededRunID === previous.runID ||
|
|
1190
|
+
(mission.supersededRunID === undefined && previous.decision === "explicit-cancellation" &&
|
|
1191
|
+
previous.units.some(unit => unit.status === "cancelled" && unit.childSessionID !== null)));
|
|
1192
|
+
const terminalChildren = cancelledPredecessor
|
|
1193
|
+
? await terminalCancelledMissionChildren(profile, root, previous, budget, {
|
|
1194
|
+
get: async (id) => payload(await session("get", { path: { id }, query: { directory: input.directory } })),
|
|
1195
|
+
children: async (id) => payload(await session("children", { path: { id }, query: { directory: input.directory } })),
|
|
1196
|
+
}) : [];
|
|
1142
1197
|
const state = await operators.prepareMission(root, plan, actor === root ? undefined
|
|
1143
|
-
: { sessionID: actor, callID: mission.callID }, mission.supersededRunID);
|
|
1198
|
+
: { sessionID: actor, callID: mission.callID }, mission.supersededRunID, terminalChildren);
|
|
1144
1199
|
await restorePriorAcceptance(root, state);
|
|
1145
1200
|
await control.registerGoalDeclaration(root, state.units[0].task.prompt, true);
|
|
1146
1201
|
control.enableUnits(root, state.units.filter(unit => unit.status === "pending").length);
|
|
@@ -1860,8 +1915,20 @@ export function createProfiledPlugin(profile, assetVersion) {
|
|
|
1860
1915
|
},
|
|
1861
1916
|
"experimental.chat.system.transform": async (request, output) => {
|
|
1862
1917
|
const root = await rootFor(request.sessionID) ?? await proposalPromptRoot(request.sessionID);
|
|
1863
|
-
if (!root)
|
|
1918
|
+
if (!root) {
|
|
1919
|
+
const who = await identity(request.sessionID);
|
|
1920
|
+
if (who.parent === undefined && who.role === undefined &&
|
|
1921
|
+
(await missions.read(request.sessionID))?.phase === "cancelled") {
|
|
1922
|
+
// OpenCode retains the same conversation when the user switches agents. A prior
|
|
1923
|
+
// INTERRUPTED report describes only its Sortie run; it cannot revoke Build's
|
|
1924
|
+
// native tools or turn a new independent request into a cancelled mission.
|
|
1925
|
+
(output.system ??= []).push("SORTIE_PROFILE_INACTIVE: This is a non-Sortie agent. " +
|
|
1926
|
+
"Any earlier INTERRUPTED mission or cancelled operator run in this session is historical state of the Sortie profile, " +
|
|
1927
|
+
"not a restriction on this agent's current user request. Use the current agent's native tools for independent work. " +
|
|
1928
|
+
"Do not revive, overwrite or claim completion of that historical Sortie run.");
|
|
1929
|
+
}
|
|
1864
1930
|
return;
|
|
1931
|
+
}
|
|
1865
1932
|
await core["experimental.chat.system.transform"]?.(request, output);
|
|
1866
1933
|
(output.system ??= []).push(`SORTIE_RUNTIME_PROFILE ${profile.id}; marker ${assetVersion}. ` +
|
|
1867
1934
|
`Shared MkII protocol role names are logical: ${protocolMap}. Use only ${profile.toolPrefix} tools for this profile. ` +
|
package/dist/plugin/v2.js
CHANGED
|
@@ -63,13 +63,14 @@ function legacyMessage(value, session, agent) {
|
|
|
63
63
|
if (!record(value) || typeof value.id !== "string" || typeof value.type !== "string")
|
|
64
64
|
return undefined;
|
|
65
65
|
const id = value.id;
|
|
66
|
+
const originalAgent = record(value.metadata) ? string(value.metadata.agent) ?? agent : agent;
|
|
66
67
|
if (value.type === "user") {
|
|
67
|
-
return { info: { id, sessionID: session, role: "user", agent, time: value.time },
|
|
68
|
+
return { info: { id, sessionID: session, role: "user", agent: originalAgent, time: value.time },
|
|
68
69
|
parts: [{ id: `${id}-text`, sessionID: session, messageID: id, type: "text", text: String(value.text ?? "") }] };
|
|
69
70
|
}
|
|
70
71
|
if (value.type !== "assistant") {
|
|
71
72
|
if (value.type === "synthetic")
|
|
72
|
-
return { info: { id, sessionID: session, role: "user", agent, time: value.time },
|
|
73
|
+
return { info: { id, sessionID: session, role: "user", agent: originalAgent, time: value.time },
|
|
73
74
|
parts: [{ id: `${id}-text`, sessionID: session, messageID: id, type: "text", text: String(value.text ?? ""), synthetic: true }] };
|
|
74
75
|
return undefined;
|
|
75
76
|
}
|