@parall/codex-agent 1.45.0 → 1.47.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/dispatch.d.ts +58 -13
- package/dist/dispatch.d.ts.map +1 -1
- package/dist/dispatch.js +343 -67
- package/dist/index.js +10 -8
- package/dist/instructions-refresh.d.ts +136 -0
- package/dist/instructions-refresh.d.ts.map +1 -0
- package/dist/instructions-refresh.js +244 -0
- package/dist/jsonrpc-client.d.ts +49 -1
- package/dist/jsonrpc-client.d.ts.map +1 -1
- package/dist/jsonrpc-client.js +77 -5
- package/dist/server-requests.d.ts +10 -0
- package/dist/server-requests.d.ts.map +1 -0
- package/dist/server-requests.js +39 -0
- package/dist/session-manager.d.ts +12 -0
- package/dist/session-manager.d.ts.map +1 -1
- package/dist/session-manager.js +53 -3
- package/dist/turn-sink.d.ts +3 -0
- package/dist/turn-sink.d.ts.map +1 -1
- package/dist/turn-sink.js +5 -0
- package/dist/workspace.d.ts.map +1 -1
- package/dist/workspace.js +5 -6
- package/package.json +4 -4
- package/src/dispatch.ts +388 -83
- package/src/index.ts +10 -7
- package/src/instructions-refresh.ts +367 -0
- package/src/jsonrpc-client.ts +109 -7
- package/src/server-requests.ts +40 -0
- package/src/session-manager.ts +74 -6
- package/src/turn-sink.ts +6 -0
- package/src/workspace.ts +5 -6
|
@@ -13,10 +13,22 @@ export declare class CodexSessionManager {
|
|
|
13
13
|
private readonly stateFilePath;
|
|
14
14
|
private readonly logger?;
|
|
15
15
|
private readonly threadIds;
|
|
16
|
+
private readonly effectiveInstructionsShas;
|
|
16
17
|
constructor(mainSessionKey: string, stateFilePath: string, logger?: Logger | undefined);
|
|
17
18
|
isMain(sessionKey: string): boolean;
|
|
18
19
|
getThreadId(sessionKey: string): string | undefined;
|
|
19
20
|
recordThreadId(sessionKey: string, threadId: string): void;
|
|
21
|
+
/**
|
|
22
|
+
* Record a freshly-STARTED thread together with the sha of the
|
|
23
|
+
* instructions baked into it — one atomic state-file write. Two separate
|
|
24
|
+
* writes (thread id, then sha) would leave a crash window whose survivor
|
|
25
|
+
* looks exactly like a pre-tracking legacy file, and the reconcile path
|
|
26
|
+
* deliberately does NOT compact legacy state — a stale thread would then
|
|
27
|
+
* be recorded as carrying instructions it never saw.
|
|
28
|
+
*/
|
|
29
|
+
recordStartedThread(sessionKey: string, threadId: string, effectiveSha: string | undefined): void;
|
|
30
|
+
getEffectiveInstructionsSha(sessionKey: string): string | undefined;
|
|
31
|
+
recordEffectiveInstructionsSha(sessionKey: string, sha: string): void;
|
|
20
32
|
createForkSessionKey(): ForkSessionHandle;
|
|
21
33
|
cleanupFork(sessionKey: string): void;
|
|
22
34
|
/** Clear the main thread id when app-server rejects it (stale / deleted). */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-manager.d.ts","sourceRoot":"","sources":["../src/session-manager.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"session-manager.d.ts","sourceRoot":"","sources":["../src/session-manager.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAuB5D,KAAK,MAAM,GAAG;IAAE,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC;AAE9C;;;;;GAKG;AACH,qBAAa,mBAAmB;IAK5B,QAAQ,CAAC,cAAc,EAAE,MAAM;IAC/B,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;IAN1B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA6B;IACvD,OAAO,CAAC,QAAQ,CAAC,yBAAyB,CAA6B;gBAG5D,cAAc,EAAE,MAAM,EACd,aAAa,EAAE,MAAM,EACrB,MAAM,CAAC,EAAE,MAAM,YAAA;IAKlC,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO;IAInC,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAInD,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;IAcnD;;;;;;;OAOG;IACH,mBAAmB,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,SAAS;IAY1F,2BAA2B,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAInE,8BAA8B,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM;IAO9D,oBAAoB,IAAI,iBAAiB;IAOzC,WAAW,CAAC,UAAU,EAAE,MAAM;IAK9B,6EAA6E;IAC7E,eAAe;IAYf,OAAO,CAAC,OAAO;IA6Bf,OAAO,CAAC,OAAO;CAuBhB"}
|
package/dist/session-manager.js
CHANGED
|
@@ -11,6 +11,7 @@ export class CodexSessionManager {
|
|
|
11
11
|
stateFilePath;
|
|
12
12
|
logger;
|
|
13
13
|
threadIds = new Map();
|
|
14
|
+
effectiveInstructionsShas = new Map();
|
|
14
15
|
constructor(mainSessionKey, stateFilePath, logger) {
|
|
15
16
|
this.mainSessionKey = mainSessionKey;
|
|
16
17
|
this.stateFilePath = stateFilePath;
|
|
@@ -24,9 +25,45 @@ export class CodexSessionManager {
|
|
|
24
25
|
return this.threadIds.get(sessionKey);
|
|
25
26
|
}
|
|
26
27
|
recordThreadId(sessionKey, threadId) {
|
|
28
|
+
// An effective-instructions sha is a fact about one specific thread.
|
|
29
|
+
// Recording a DIFFERENT thread id under the same session invalidates it;
|
|
30
|
+
// re-recording the same id (the resume path) must preserve it, or every
|
|
31
|
+
// bridge restart would trigger a redundant refresh.
|
|
32
|
+
if (this.threadIds.get(sessionKey) !== threadId) {
|
|
33
|
+
this.effectiveInstructionsShas.delete(sessionKey);
|
|
34
|
+
}
|
|
35
|
+
this.threadIds.set(sessionKey, threadId);
|
|
36
|
+
if (sessionKey === this.mainSessionKey) {
|
|
37
|
+
this.persist();
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Record a freshly-STARTED thread together with the sha of the
|
|
42
|
+
* instructions baked into it — one atomic state-file write. Two separate
|
|
43
|
+
* writes (thread id, then sha) would leave a crash window whose survivor
|
|
44
|
+
* looks exactly like a pre-tracking legacy file, and the reconcile path
|
|
45
|
+
* deliberately does NOT compact legacy state — a stale thread would then
|
|
46
|
+
* be recorded as carrying instructions it never saw.
|
|
47
|
+
*/
|
|
48
|
+
recordStartedThread(sessionKey, threadId, effectiveSha) {
|
|
27
49
|
this.threadIds.set(sessionKey, threadId);
|
|
50
|
+
if (effectiveSha) {
|
|
51
|
+
this.effectiveInstructionsShas.set(sessionKey, effectiveSha);
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
this.effectiveInstructionsShas.delete(sessionKey);
|
|
55
|
+
}
|
|
56
|
+
if (sessionKey === this.mainSessionKey) {
|
|
57
|
+
this.persist();
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
getEffectiveInstructionsSha(sessionKey) {
|
|
61
|
+
return this.effectiveInstructionsShas.get(sessionKey);
|
|
62
|
+
}
|
|
63
|
+
recordEffectiveInstructionsSha(sessionKey, sha) {
|
|
64
|
+
this.effectiveInstructionsShas.set(sessionKey, sha);
|
|
28
65
|
if (sessionKey === this.mainSessionKey) {
|
|
29
|
-
this.persist(
|
|
66
|
+
this.persist();
|
|
30
67
|
}
|
|
31
68
|
}
|
|
32
69
|
createForkSessionKey() {
|
|
@@ -37,10 +74,12 @@ export class CodexSessionManager {
|
|
|
37
74
|
}
|
|
38
75
|
cleanupFork(sessionKey) {
|
|
39
76
|
this.threadIds.delete(sessionKey);
|
|
77
|
+
this.effectiveInstructionsShas.delete(sessionKey);
|
|
40
78
|
}
|
|
41
79
|
/** Clear the main thread id when app-server rejects it (stale / deleted). */
|
|
42
80
|
clearMainThread() {
|
|
43
81
|
this.threadIds.delete(this.mainSessionKey);
|
|
82
|
+
this.effectiveInstructionsShas.delete(this.mainSessionKey);
|
|
44
83
|
try {
|
|
45
84
|
fs.rmSync(this.stateFilePath, { force: true });
|
|
46
85
|
}
|
|
@@ -56,6 +95,10 @@ export class CodexSessionManager {
|
|
|
56
95
|
typeof parsed.threadId === 'string' &&
|
|
57
96
|
parsed.threadId.trim()) {
|
|
58
97
|
this.threadIds.set(this.mainSessionKey, parsed.threadId.trim());
|
|
98
|
+
if (typeof parsed.effectiveInstructionsSha === 'string' &&
|
|
99
|
+
parsed.effectiveInstructionsSha.trim()) {
|
|
100
|
+
this.effectiveInstructionsShas.set(this.mainSessionKey, parsed.effectiveInstructionsSha.trim());
|
|
101
|
+
}
|
|
59
102
|
}
|
|
60
103
|
}
|
|
61
104
|
catch (error) {
|
|
@@ -64,7 +107,10 @@ export class CodexSessionManager {
|
|
|
64
107
|
}
|
|
65
108
|
}
|
|
66
109
|
}
|
|
67
|
-
persist(
|
|
110
|
+
persist() {
|
|
111
|
+
const threadId = this.threadIds.get(this.mainSessionKey);
|
|
112
|
+
if (!threadId)
|
|
113
|
+
return;
|
|
68
114
|
// Atomic write: truncate-in-place risks leaving a half-written / zero-byte
|
|
69
115
|
// state file if the process dies between `open(O_TRUNC)` and the final
|
|
70
116
|
// fsync. Since this file is the sole source of cross-restart `resume`
|
|
@@ -74,7 +120,11 @@ export class CodexSessionManager {
|
|
|
74
120
|
try {
|
|
75
121
|
fs.mkdirSync(path.dirname(this.stateFilePath), { recursive: true });
|
|
76
122
|
const tmpPath = `${this.stateFilePath}.tmp`;
|
|
77
|
-
|
|
123
|
+
const state = { runtimeKey: this.mainSessionKey, threadId };
|
|
124
|
+
const effectiveSha = this.effectiveInstructionsShas.get(this.mainSessionKey);
|
|
125
|
+
if (effectiveSha)
|
|
126
|
+
state.effectiveInstructionsSha = effectiveSha;
|
|
127
|
+
fs.writeFileSync(tmpPath, JSON.stringify(state, null, 2));
|
|
78
128
|
fs.renameSync(tmpPath, this.stateFilePath);
|
|
79
129
|
}
|
|
80
130
|
catch (error) {
|
package/dist/turn-sink.d.ts
CHANGED
|
@@ -19,5 +19,8 @@ export declare class TurnSink {
|
|
|
19
19
|
push(envelope: TurnEventEnvelope): void;
|
|
20
20
|
next(): Promise<TurnEventEnvelope>;
|
|
21
21
|
close(): void;
|
|
22
|
+
/** True once close() ran — the sink's terminal state (queued envelopes may
|
|
23
|
+
* still drain via next()). */
|
|
24
|
+
get isClosed(): boolean;
|
|
22
25
|
}
|
|
23
26
|
//# sourceMappingURL=turn-sink.d.ts.map
|
package/dist/turn-sink.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"turn-sink.d.ts","sourceRoot":"","sources":["../src/turn-sink.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD,MAAM,MAAM,iBAAiB,GACzB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,YAAY,CAAA;CAAE,GACxC;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GACvC;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvC,mEAAmE;AACnE,qBAAa,QAAQ;IACnB,QAAQ,CAAC,MAAM,cAAqB;IACpC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA2B;IACjD,OAAO,CAAC,QAAQ,CAAqD;IACrE,OAAO,CAAC,MAAM,CAAS;IAEvB,IAAI,CAAC,QAAQ,EAAE,iBAAiB;IAWhC,IAAI,IAAI,OAAO,CAAC,iBAAiB,CAAC;IAelC,KAAK;
|
|
1
|
+
{"version":3,"file":"turn-sink.d.ts","sourceRoot":"","sources":["../src/turn-sink.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD,MAAM,MAAM,iBAAiB,GACzB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,YAAY,CAAA;CAAE,GACxC;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GACvC;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvC,mEAAmE;AACnE,qBAAa,QAAQ;IACnB,QAAQ,CAAC,MAAM,cAAqB;IACpC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA2B;IACjD,OAAO,CAAC,QAAQ,CAAqD;IACrE,OAAO,CAAC,MAAM,CAAS;IAEvB,IAAI,CAAC,QAAQ,EAAE,iBAAiB;IAWhC,IAAI,IAAI,OAAO,CAAC,iBAAiB,CAAC;IAelC,KAAK;IAOL;kCAC8B;IAC9B,IAAI,QAAQ,IAAI,OAAO,CAEtB;CACF"}
|
package/dist/turn-sink.js
CHANGED
package/dist/workspace.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../src/workspace.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAIxD;;;;;;;;;GASG;AACH,eAAO,MAAM,mBAAmB;;;;CAI/B,CAAC;AAUF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;AACH,wBAAgB,cAAc,CAC5B,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE;IAAE,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;CAAE,GAAG,SAAS,EAChD,EAAE,EAAE,MAAM,IAAI,GACb,IAAI,CAkJN;AAED;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,EAAE;IACnC,oBAAoB,CAAC,EAAE,MAAM,IAAI,CAAC;IAClC,mBAAmB,CAAC,EAAE,MAAM,IAAI,CAAC;IACjC,iBAAiB,CAAC,EAAE,MAAM,IAAI,CAAC;CAC3B,CAAC;AAuJP;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,OAAO,CAK/E;AAED;;;;;;;;;;;;;GAaG;AACH;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAerD;AAED,wEAAwE;AACxE,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AA0BD,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,GAAG,CAAC,EAAE;IAAE,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;CAAE,EACrC,IAAI,CAAC,EAAE,yBAAyB,GAC/B,IAAI,CAEN;
|
|
1
|
+
{"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../src/workspace.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAIxD;;;;;;;;;GASG;AACH,eAAO,MAAM,mBAAmB;;;;CAI/B,CAAC;AAUF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;AACH,wBAAgB,cAAc,CAC5B,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE;IAAE,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;CAAE,GAAG,SAAS,EAChD,EAAE,EAAE,MAAM,IAAI,GACb,IAAI,CAkJN;AAED;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,EAAE;IACnC,oBAAoB,CAAC,EAAE,MAAM,IAAI,CAAC;IAClC,mBAAmB,CAAC,EAAE,MAAM,IAAI,CAAC;IACjC,iBAAiB,CAAC,EAAE,MAAM,IAAI,CAAC;CAC3B,CAAC;AAuJP;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,OAAO,CAK/E;AAED;;;;;;;;;;;;;GAaG;AACH;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAerD;AAED,wEAAwE;AACxE,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AA0BD,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,GAAG,CAAC,EAAE;IAAE,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;CAAE,EACrC,IAAI,CAAC,EAAE,yBAAyB,GAC/B,IAAI,CAEN;AAiFD,wBAAgB,sBAAsB,CACpC,YAAY,EAAE,MAAM,EACpB,aAAa,CAAC,EAAE,aAAa,EAC7B,mBAAmB,CAAC,EAAE,MAAM,EAAE,GAC7B,MAAM,CAwBR;AAED,wBAAgB,oBAAoB,CAClC,YAAY,EAAE,MAAM,EACpB,GAAG,CAAC,EAAE;IAAE,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;CAAE,EACrC,aAAa,CAAC,EAAE,aAAa,EAC7B,mBAAmB,CAAC,EAAE,MAAM,EAAE,GAC7B,MAAM,CA+BR"}
|
package/dist/workspace.js
CHANGED
|
@@ -547,12 +547,11 @@ function systemPromptCopyPath(workspaceDir) {
|
|
|
547
547
|
// guide, before skill references; empty/absent = no capability section.
|
|
548
548
|
// Split out from ensureCodexWorkspace so the bridge can rebuild the prompt on
|
|
549
549
|
// a platform-config heat-update and hand the new value to
|
|
550
|
-
// adapter.updateConfig
|
|
551
|
-
//
|
|
552
|
-
//
|
|
553
|
-
//
|
|
554
|
-
//
|
|
555
|
-
// docs/tech-debt/codex-persisted-thread-prompt-refresh.md.
|
|
550
|
+
// adapter.updateConfig. Delivery to threads is the adapter's job: baked into
|
|
551
|
+
// new threads at thread/start; converged onto the persisted main thread via
|
|
552
|
+
// the lazy restart's fresh-process thread/resume (canonical configuration)
|
|
553
|
+
// plus an explicit compaction (model-visible context) — see
|
|
554
|
+
// src/instructions-refresh.ts for the two-plane semantics.
|
|
556
555
|
// Throws on failure BY DESIGN — at boot the prompt is mandatory, so a write
|
|
557
556
|
// failure must fail startup loudly; the refresh hot path wraps this in
|
|
558
557
|
// try/catch and retries next refresh.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@parall/codex-agent",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.47.0",
|
|
4
4
|
"description": "Codex CLI bridge runtime for self-hosted Parall agents",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -25,9 +25,9 @@
|
|
|
25
25
|
"src"
|
|
26
26
|
],
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@parall/agent-core": "1.
|
|
29
|
-
"@parall/
|
|
30
|
-
"@parall/
|
|
28
|
+
"@parall/agent-core": "1.47.0",
|
|
29
|
+
"@parall/sdk": "1.47.0",
|
|
30
|
+
"@parall/cli": "1.47.0"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"@types/node": "^22.0.0",
|