@cortexkit/opencode-magic-context 0.44.3 → 0.44.4
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/{derive-budgets-vjmvh6pz.js → derive-budgets-ncwn1jk9.js} +2 -2
- package/dist/features/magic-context/dreamer/map-memories.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/verify.d.ts.map +1 -1
- package/dist/features/magic-context/memory/embedding-openai.d.ts +1 -0
- package/dist/features/magic-context/memory/embedding-openai.d.ts.map +1 -1
- package/dist/features/magic-context/memory/project-identity.d.ts +5 -4
- package/dist/features/magic-context/memory/project-identity.d.ts.map +1 -1
- package/dist/features/magic-context/storage-db.d.ts +6 -1
- package/dist/features/magic-context/storage-db.d.ts.map +1 -1
- package/dist/features/magic-context/v22-deferred-backfill.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-render-epoch.d.ts +12 -1
- package/dist/hooks/magic-context/compartment-render-epoch.d.ts.map +1 -1
- package/dist/hooks/magic-context/drop-stale-reduce-calls.d.ts.map +1 -1
- package/dist/hooks/magic-context/event-resolvers.d.ts +7 -0
- package/dist/hooks/magic-context/event-resolvers.d.ts.map +1 -1
- package/dist/hooks/magic-context/heuristic-cleanup.d.ts.map +1 -1
- package/dist/hooks/magic-context/inject-compartments.d.ts +5 -0
- package/dist/hooks/magic-context/inject-compartments.d.ts.map +1 -1
- package/dist/hooks/magic-context/module-wire.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-chunk.d.ts +4 -2
- package/dist/hooks/magic-context/read-session-chunk.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-raw.d.ts +2 -2
- package/dist/hooks/magic-context/read-session-raw.d.ts.map +1 -1
- package/dist/hooks/magic-context/tokenizer-calibration.d.ts +1 -1
- package/dist/hooks/magic-context/tool-drop-target.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +1 -0
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform.d.ts.map +1 -1
- package/dist/{index-q5p1aqvv.js → index-mrc0twf3.js} +10 -4
- package/dist/{index-9y5p0d50.js → index-msqr3x6m.js} +1 -1
- package/dist/{index-y5145x8k.js → index-n96ag4rk.js} +15 -1
- package/dist/{index-dgg5y7er.js → index-qm36k34q.js} +55 -12
- package/dist/{index-yhm60r53.js → index-sqp1hz9v.js} +180 -36
- package/dist/{index-rdsaxnf2.js → index-wprsye9w.js} +1 -1
- package/dist/{index-nf9sk8sh.js → index-zx7pmr39.js} +2 -2
- package/dist/index.js +88 -35
- package/dist/plugin/rpc-handlers.d.ts.map +1 -1
- package/dist/{read-session-chunk-n072mcq4.js → read-session-chunk-339hg90t.js} +2 -2
- package/dist/{recomp-orchestrator-19tr6zya.js → recomp-orchestrator-0ers6smx.js} +5 -5
- package/dist/shared/rpc-utils.d.ts +7 -0
- package/dist/shared/rpc-utils.d.ts.map +1 -1
- package/dist/shared/transcript.d.ts +2 -0
- package/dist/shared/transcript.d.ts.map +1 -1
- package/dist/shared/user-answer.d.ts +4 -0
- package/dist/shared/user-answer.d.ts.map +1 -0
- package/dist/{transform-postprocess-phase-z2mfc5w1.js → transform-postprocess-phase-ttdkrm6r.js} +5 -5
- package/dist/v2/hooks/payload.d.ts.map +1 -1
- package/dist/v2/hooks/store.d.ts +1 -1
- package/dist/v2/hooks/store.d.ts.map +1 -1
- package/dist/v2/server.js +334 -70
- package/dist/v2/store-reader.d.ts +2 -1
- package/dist/v2/store-reader.d.ts.map +1 -1
- package/dist/{wrapup-orchestrator-sy4m56a7.js → wrapup-orchestrator-x0jvvrqn.js} +6 -6
- package/package.json +1 -1
- package/src/shared/rpc-utils.test.ts +27 -2
- package/src/shared/rpc-utils.ts +44 -15
- package/src/shared/tag-transcript.ts +4 -1
- package/src/shared/transcript.ts +3 -0
- package/src/shared/user-answer.test.ts +40 -0
- package/src/shared/user-answer.ts +17 -0
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { RawMessageOrdinalAnchor } from "../hooks/magic-context/read-session-raw";
|
|
1
2
|
/** Compatibility export; shared/opencode-db-path.ts is the single filename authority. */
|
|
2
3
|
export declare function sourceDatabaseFilename(channel: string, env?: NodeJS.ProcessEnv): string;
|
|
3
4
|
/** GA data root resolved by the shared host-generation-aware resolver. */
|
|
@@ -103,7 +104,7 @@ export declare class V2StoreReader {
|
|
|
103
104
|
* includes non-conversation rows, so the CTE maps the two ordinal boundaries
|
|
104
105
|
* to seq values without hydrating any row outside the requested page.
|
|
105
106
|
*/
|
|
106
|
-
messagePage(sessionID: string, afterOrdinal: number, limit: number, finalWatermark: number): StoreRow[];
|
|
107
|
+
messagePage(sessionID: string, afterOrdinal: number, limit: number, finalWatermark: number, after?: RawMessageOrdinalAnchor): StoreRow[];
|
|
107
108
|
messageCount(sessionID: string): number;
|
|
108
109
|
/**
|
|
109
110
|
* One page of host sessions with the directory each was created in, in
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store-reader.d.ts","sourceRoot":"","sources":["../../src/v2/store-reader.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"store-reader.d.ts","sourceRoot":"","sources":["../../src/v2/store-reader.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
runManagedWrapup2
|
|
3
|
-
} from "./index-
|
|
4
|
-
import"./index-
|
|
5
|
-
import"./index-
|
|
3
|
+
} from "./index-zx7pmr39.js";
|
|
4
|
+
import"./index-wprsye9w.js";
|
|
5
|
+
import"./index-sqp1hz9v.js";
|
|
6
6
|
import"./index-sd3egckz.js";
|
|
7
|
-
import"./index-
|
|
7
|
+
import"./index-msqr3x6m.js";
|
|
8
8
|
import"./index-33q7s9y2.js";
|
|
9
|
-
import"./index-
|
|
10
|
-
import"./index-
|
|
9
|
+
import"./index-qm36k34q.js";
|
|
10
|
+
import"./index-n96ag4rk.js";
|
|
11
11
|
import"./index-4an2p8qa.js";
|
|
12
12
|
import"./index-kr5qehbd.js";
|
|
13
13
|
import"./index-jdxxq8cz.js";
|
package/package.json
CHANGED
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
inspectLivePiProcesses,
|
|
13
13
|
isPidAlive,
|
|
14
14
|
isPidIdentityPlausible,
|
|
15
|
+
parseTasklistOutput,
|
|
15
16
|
type RpcPortFileRecord,
|
|
16
17
|
readProcessProbeEvidence,
|
|
17
18
|
} from "./rpc-utils";
|
|
@@ -441,7 +442,7 @@ describe("isPidAlive", () => {
|
|
|
441
442
|
expect(calls).toEqual([
|
|
442
443
|
{
|
|
443
444
|
file: "tasklist",
|
|
444
|
-
args: ["/FO", "CSV", "/FI", `PID eq ${PID}`],
|
|
445
|
+
args: ["/FO", "CSV", "/NH", "/FI", `PID eq ${PID}`],
|
|
445
446
|
stdio: ["ignore", "pipe", "pipe"],
|
|
446
447
|
},
|
|
447
448
|
]);
|
|
@@ -623,7 +624,9 @@ describe("isPidIdentityPlausible", () => {
|
|
|
623
624
|
});
|
|
624
625
|
|
|
625
626
|
expect(isPidIdentityPlausible(record(0))).toBe("plausible");
|
|
626
|
-
expect(calls).toEqual([
|
|
627
|
+
expect(calls).toEqual([
|
|
628
|
+
{ file: "tasklist", args: ["/FO", "CSV", "/NH", "/FI", `PID eq ${PID}`] },
|
|
629
|
+
]);
|
|
627
630
|
|
|
628
631
|
calls.length = 0;
|
|
629
632
|
expect(isPidIdentityPlausible(record(NOW_MS))).toBe("inconclusive");
|
|
@@ -639,3 +642,25 @@ describe("isPidIdentityPlausible", () => {
|
|
|
639
642
|
]);
|
|
640
643
|
});
|
|
641
644
|
});
|
|
645
|
+
|
|
646
|
+
test("Spanish tasklist no-match is not running", () => {
|
|
647
|
+
const output =
|
|
648
|
+
"INFORMACIÓN: no hay tareas ejecutándose que coincidan con los\ncriterios especificados.";
|
|
649
|
+
expect(parseTasklistOutput(output)).toEqual([]);
|
|
650
|
+
__setRpcIdentityTestHooks({ platform: "win32", execFileSync: psOutput(output) });
|
|
651
|
+
expect(isPidAlive(PID)).toBe("dead");
|
|
652
|
+
});
|
|
653
|
+
|
|
654
|
+
test("German tasklist no-match is not running", () => {
|
|
655
|
+
expect(
|
|
656
|
+
parseTasklistOutput(
|
|
657
|
+
"INFORMATION: Es werden keine Aufgaben mit den angegebenen Kriterien ausgeführt.",
|
|
658
|
+
),
|
|
659
|
+
).toEqual([]);
|
|
660
|
+
});
|
|
661
|
+
|
|
662
|
+
test("tasklist CSV live process is running", () => {
|
|
663
|
+
expect(parseTasklistOutput('"opencode.exe","1234","Console","1","10,000 K"')).toEqual([
|
|
664
|
+
{ pid: 1234, command: "opencode.exe" },
|
|
665
|
+
]);
|
|
666
|
+
});
|
package/src/shared/rpc-utils.ts
CHANGED
|
@@ -121,8 +121,6 @@ const WINDOWS_CIM_PROBE_TIMEOUT_MS = 5_000;
|
|
|
121
121
|
const WINDOWS_PROCESS_SNAPSHOT_TTL_MS = 2_000;
|
|
122
122
|
const MAX_ANCESTOR_WALK_DEPTH = 16;
|
|
123
123
|
const OPEN_CODE_COMMAND_MARKERS = ["opencode", "node", "bun", "electron"];
|
|
124
|
-
const TASKLIST_NO_TASKS_PATTERN =
|
|
125
|
-
/^INFO:\s+No tasks are running which match the specified criteria\.?$/im;
|
|
126
124
|
const WINDOWS_CIM_COMMAND =
|
|
127
125
|
"Get-CimInstance Win32_Process | Select-Object ProcessId,ParentProcessId,Name,CommandLine,CreationDate | ConvertTo-Json -Compress";
|
|
128
126
|
const PI_HARNESS_ARC_MARKERS = [
|
|
@@ -270,34 +268,39 @@ function parseCsvLine(line: string): string[] | null {
|
|
|
270
268
|
return fields;
|
|
271
269
|
}
|
|
272
270
|
|
|
273
|
-
function parseTasklistOutput(output: string): ProcessListEntry[] | null {
|
|
271
|
+
export function parseTasklistOutput(output: string): ProcessListEntry[] | null {
|
|
274
272
|
const entries: ProcessListEntry[] = [];
|
|
275
|
-
|
|
273
|
+
|
|
276
274
|
for (const rawLine of output.split(/\r?\n/)) {
|
|
277
275
|
const line = rawLine.trim();
|
|
278
276
|
if (!line) continue;
|
|
279
|
-
|
|
277
|
+
|
|
280
278
|
const fields = parseCsvLine(line);
|
|
281
279
|
if (!fields) continue;
|
|
282
280
|
if (fields[1]?.trim().toLowerCase() === "pid") {
|
|
283
|
-
sawHeader = true;
|
|
284
281
|
continue;
|
|
285
282
|
}
|
|
286
283
|
const pid = Number(fields[1]);
|
|
287
284
|
if (!Number.isInteger(pid) || pid <= 0 || !fields[0]) continue;
|
|
288
285
|
entries.push({ pid, command: fields[0] });
|
|
289
286
|
}
|
|
290
|
-
|
|
287
|
+
// Successful tasklist commands return localized prose when no PID matches.
|
|
288
|
+
// Only CSV PID fields are evidence of a live process; failures are caught by the caller.
|
|
289
|
+
return entries;
|
|
291
290
|
}
|
|
292
291
|
|
|
293
292
|
function readWindowsProcess(pid: number): { state: PidLiveness; command?: string } {
|
|
294
293
|
try {
|
|
295
|
-
const output = rpcIdentityExecFileSync(
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
294
|
+
const output = rpcIdentityExecFileSync(
|
|
295
|
+
"tasklist",
|
|
296
|
+
["/FO", "CSV", "/NH", "/FI", `PID eq ${pid}`],
|
|
297
|
+
{
|
|
298
|
+
encoding: "utf8",
|
|
299
|
+
timeout: PS_PROBE_TIMEOUT_MS,
|
|
300
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
301
|
+
windowsHide: true,
|
|
302
|
+
},
|
|
303
|
+
);
|
|
301
304
|
const entries = parseTasklistOutput(String(output));
|
|
302
305
|
if (entries === null) return { state: "inconclusive" };
|
|
303
306
|
const process = entries.find((entry) => entry.pid === pid);
|
|
@@ -632,7 +635,11 @@ function tryReadWindowsCimSnapshot(exec: typeof execFileSync): ProcessSnapshot |
|
|
|
632
635
|
|
|
633
636
|
function tryReadWindowsTasklistSnapshot(): ProcessSnapshot | null {
|
|
634
637
|
try {
|
|
635
|
-
const output = execProcessList(rpcProcessListExecFileSync, "tasklist", [
|
|
638
|
+
const output = execProcessList(rpcProcessListExecFileSync, "tasklist", [
|
|
639
|
+
"/FO",
|
|
640
|
+
"CSV",
|
|
641
|
+
"/NH",
|
|
642
|
+
]);
|
|
636
643
|
const entries = parseTasklistOutput(output);
|
|
637
644
|
if (entries === null) return null;
|
|
638
645
|
const facts = entries.map((entry) => ({
|
|
@@ -921,7 +928,11 @@ export function inspectProcessesAsync(forceFresh = false): Promise<AsyncProcessI
|
|
|
921
928
|
}
|
|
922
929
|
if (!snapshot) {
|
|
923
930
|
const entries = parseTasklistOutput(
|
|
924
|
-
await asyncProcessExec(
|
|
931
|
+
await asyncProcessExec(
|
|
932
|
+
"tasklist",
|
|
933
|
+
["/FO", "CSV", "/NH"],
|
|
934
|
+
PS_PROBE_TIMEOUT_MS,
|
|
935
|
+
),
|
|
925
936
|
);
|
|
926
937
|
if (entries)
|
|
927
938
|
snapshot = snapshotFromFacts(
|
|
@@ -986,3 +997,21 @@ export function inspectProcessesAsync(forceFresh = false): Promise<AsyncProcessI
|
|
|
986
997
|
});
|
|
987
998
|
return asyncInspection;
|
|
988
999
|
}
|
|
1000
|
+
|
|
1001
|
+
/** Take one fresh Windows process snapshot with command time limits for synchronous callers. */
|
|
1002
|
+
export function inspectWindowsProcessesSync(): AsyncProcessInspection {
|
|
1003
|
+
const snapshot =
|
|
1004
|
+
tryReadWindowsCimSnapshot(rpcProcessListExecFileSync) ?? tryReadWindowsTasklistSnapshot();
|
|
1005
|
+
const byPid = new Map(snapshot?.facts.map((fact) => [fact.pid, fact]));
|
|
1006
|
+
return {
|
|
1007
|
+
pi: snapshot ? classifyLivePiSnapshot(snapshot) : { state: "unreadable", processIds: [] },
|
|
1008
|
+
...(snapshot
|
|
1009
|
+
? { processSnapshot: { source: snapshot.source, facts: snapshot.facts } }
|
|
1010
|
+
: {}),
|
|
1011
|
+
evidence: (pid) => ({
|
|
1012
|
+
startTime: byPid.get(pid)?.startTime ?? null,
|
|
1013
|
+
commandLine: byPid.get(pid)?.commandLine ?? byPid.get(pid)?.imageName ?? null,
|
|
1014
|
+
}),
|
|
1015
|
+
liveness: (pid) => (byPid.has(pid) ? "alive" : snapshot ? "dead" : "inconclusive"),
|
|
1016
|
+
};
|
|
1017
|
+
}
|
|
@@ -1275,7 +1275,7 @@ function buildAggregateTarget(
|
|
|
1275
1275
|
return any ? "truncated" : "absent";
|
|
1276
1276
|
},
|
|
1277
1277
|
// Open invocations still belong to the current turn; only complete arcs reclaim.
|
|
1278
|
-
canDrop: complete,
|
|
1278
|
+
canDrop: () => complete() && !occurrences.some((occ) => occ.part.hasUserAnswer?.()),
|
|
1279
1279
|
requiresToolArcSkeleton,
|
|
1280
1280
|
// Non-mutating read of the invocation input (the tool_use occurrence
|
|
1281
1281
|
// carries the arguments). Used by smart-drops supersession selection.
|
|
@@ -1375,6 +1375,9 @@ function buildToolTarget(
|
|
|
1375
1375
|
// drop() replaces an invocation part's arguments with a marker, so a
|
|
1376
1376
|
// new drop of one keeps its real arguments instead.
|
|
1377
1377
|
cannotRemove: () => part.setToolInput !== undefined,
|
|
1378
|
+
// Without a paired tool call, an answer marker can forbid automatic dropping,
|
|
1379
|
+
// but must not make ordinary results newly eligible for automatic reclaim.
|
|
1380
|
+
...(part.hasUserAnswer?.() ? { canDrop: () => false } : {}),
|
|
1378
1381
|
inputStringBytes(): number | null {
|
|
1379
1382
|
return part.setToolInput ? toolInputStringBytes(part.getToolInput?.() ?? null) : 0;
|
|
1380
1383
|
},
|
package/src/shared/transcript.ts
CHANGED
|
@@ -78,6 +78,9 @@ export interface TranscriptPart {
|
|
|
78
78
|
/** Discriminator for filter logic. Stable across mutations. */
|
|
79
79
|
readonly kind: TranscriptPartKind;
|
|
80
80
|
|
|
81
|
+
/** True when the host marks this tool result as carrying a user's answer. */
|
|
82
|
+
hasUserAnswer?(): boolean;
|
|
83
|
+
|
|
81
84
|
/**
|
|
82
85
|
* Best-effort identifier for cross-pass tracking. May be:
|
|
83
86
|
* - OpenCode part ID (e.g. "prt_..."), stable across passes.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { expect, it } from "bun:test";
|
|
2
|
+
import cases from "../../../../tests/fixtures/user-answer-metadata.json";
|
|
3
|
+
import { hasUserAnswerMetadata, toolPartHasUserAnswer } from "./user-answer";
|
|
4
|
+
|
|
5
|
+
it("TS/Rust parity recognizes structural host answer metadata", () => {
|
|
6
|
+
for (const test of cases) {
|
|
7
|
+
expect(hasUserAnswerMetadata(test.metadata)).toBe(test.protected);
|
|
8
|
+
expect(toolPartHasUserAnswer({ state: { metadata: test.metadata } })).toBe(test.protected);
|
|
9
|
+
expect(toolPartHasUserAnswer({ details: test.metadata })).toBe(test.protected);
|
|
10
|
+
}
|
|
11
|
+
expect(toolPartHasUserAnswer({ tool: "question", state: { output: "no marker" } })).toBe(false);
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it("OpenCode CK sidecars preserve answer provenance without changing block identities", async () => {
|
|
15
|
+
const { encodeOpenCodeMessagesToCk } = await import("../hooks/magic-context/module-wire");
|
|
16
|
+
const message = {
|
|
17
|
+
info: { id: "m", role: "assistant" },
|
|
18
|
+
parts: [
|
|
19
|
+
{
|
|
20
|
+
type: "tool",
|
|
21
|
+
tool: "renamed-question",
|
|
22
|
+
callID: "q",
|
|
23
|
+
state: {
|
|
24
|
+
status: "completed",
|
|
25
|
+
input: {},
|
|
26
|
+
output: "answer",
|
|
27
|
+
metadata: { answers: [["yes"]] },
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
],
|
|
31
|
+
};
|
|
32
|
+
const answered = encodeOpenCodeMessagesToCk([message]);
|
|
33
|
+
const plain = structuredClone(message);
|
|
34
|
+
Reflect.deleteProperty(plain.parts[0].state, "metadata");
|
|
35
|
+
const ordinary = encodeOpenCodeMessagesToCk([plain]);
|
|
36
|
+
expect(answered[0].ck.content).toEqual(ordinary[0].ck.content);
|
|
37
|
+
expect(answered[0].ck.provider_extras).toEqual({
|
|
38
|
+
opencode: { user_answer_block_indices: [1] },
|
|
39
|
+
});
|
|
40
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { isRecord } from "./record-type-guard";
|
|
2
|
+
|
|
3
|
+
/** Host-owned answer metadata, independent of the tool's registered name. */
|
|
4
|
+
export function hasUserAnswerMetadata(value: unknown): boolean {
|
|
5
|
+
if (!isRecord(value)) return false;
|
|
6
|
+
if (value.userAnswer === true) return true;
|
|
7
|
+
if (Array.isArray(value.answers)) return true;
|
|
8
|
+
if (typeof value.answer === "string") return true;
|
|
9
|
+
if (Array.isArray(value.selectedOptions) || typeof value.customInput === "string") return true;
|
|
10
|
+
return Array.isArray(value.results) && value.results.some(hasUserAnswerMetadata);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function toolPartHasUserAnswer(part: unknown): boolean {
|
|
14
|
+
if (!isRecord(part)) return false;
|
|
15
|
+
const state = isRecord(part.state) ? part.state : undefined;
|
|
16
|
+
return hasUserAnswerMetadata(state?.metadata) || hasUserAnswerMetadata(part.details);
|
|
17
|
+
}
|