@songsid/agend 2.1.7-beta.7 → 2.1.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.
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import Database from "better-sqlite3";
|
|
2
2
|
/** Columns the lookup depends on; any missing one means "schema unreadable". */
|
|
3
|
-
export declare const CODEX_THREAD_COLUMNS: readonly ["id", "cwd", "source", "archived", "has_user_event", "recency_at_ms", "updated_at_ms"];
|
|
3
|
+
export declare const CODEX_THREAD_COLUMNS: readonly ["id", "cwd", "source", "archived", "has_user_event", "first_user_message", "rollout_path", "recency_at_ms", "updated_at_ms"];
|
|
4
4
|
export type ExactCwdSession = {
|
|
5
5
|
kind: "found";
|
|
6
6
|
id: string;
|
|
@@ -36,8 +36,37 @@ export declare function openCodexStateReadonly(path: string): Database.Database;
|
|
|
36
36
|
* Newest interactive thread recorded for exactly this directory. Exact
|
|
37
37
|
* equality only: a prefix or LIKE match would take a subdirectory's (or a
|
|
38
38
|
* similarly named sibling's) session.
|
|
39
|
+
*
|
|
40
|
+
* "Has anything in it" was checked against real Codex data (#1017), not
|
|
41
|
+
* inferred from a column name:
|
|
42
|
+
* - `has_user_event` does NOT mean that. Real 0.157 sessions with a first
|
|
43
|
+
* message and millions of tokens carry 0. Filtering on it matched no real
|
|
44
|
+
* session, so every restart silently started a new conversation.
|
|
45
|
+
* - `tokens_used > 0` drops real sessions too: a provider that reports no
|
|
46
|
+
* token usage leaves it at 0, as does a restart during the first turn.
|
|
47
|
+
* - A non-empty `first_user_message` proves content, but an empty one does
|
|
48
|
+
* not prove the opposite: a real 38-turn session (0.156.1) and `/goal`-first
|
|
49
|
+
* sessions (openai/codex#28423) have empty list metadata. For those the
|
|
50
|
+
* rollout decides whether a turn ever ran. A thread nobody used (e.g. an
|
|
51
|
+
* untouched fork) holds only `session_meta`/`thread_settings_applied`; any
|
|
52
|
+
* turn — however its first input was delivered, including hidden goal
|
|
53
|
+
* context — writes `task_started`, a `turn_context` or a `response_item`.
|
|
54
|
+
* tests/fixtures/codex-real-threads.json holds the real rows behind this.
|
|
39
55
|
*/
|
|
40
|
-
export declare function findExactCwdCodexSession(stateDbPath: string, workingDirectory: string, open?: (path: string) => Database.Database): ExactCwdSession;
|
|
56
|
+
export declare function findExactCwdCodexSession(stateDbPath: string, workingDirectory: string, open?: (path: string) => Database.Database, rolloutHasTurn?: (path: string) => boolean): ExactCwdSession;
|
|
57
|
+
/**
|
|
58
|
+
* Whether a Codex rollout (JSONL) may hold a conversation. Read-only, in
|
|
59
|
+
* chunks, stopping at the first entry that is not part of an untouched thread
|
|
60
|
+
* — in real rollouts a turn entry follows the ~22 KB session_meta line.
|
|
61
|
+
*
|
|
62
|
+
* "No" needs proof: the file has the known untouched shape and nothing else
|
|
63
|
+
* (`session_meta` + `thread_settings_applied`). Every other entry — a turn,
|
|
64
|
+
* an entry type from a newer Codex, a line this code cannot parse — counts
|
|
65
|
+
* as yes: resuming a doubtful thread fails loudly, skipping a real one
|
|
66
|
+
* silently loses the conversation. A missing or unreadable rollout cannot be
|
|
67
|
+
* resumed, so it counts as no.
|
|
68
|
+
*/
|
|
69
|
+
export declare function rolloutRecordsTurn(path: string): boolean;
|
|
41
70
|
/**
|
|
42
71
|
* The directory's git common dir: a string for a repo, null for "not a git
|
|
43
72
|
* repository", "unknown" for anything else (timeout, git missing, …).
|
|
@@ -12,12 +12,13 @@
|
|
|
12
12
|
* docs/design/984-codex-exact-cwd-resume.zh-TW.md.
|
|
13
13
|
*/
|
|
14
14
|
import { execFileSync } from "node:child_process";
|
|
15
|
-
import { realpathSync } from "node:fs";
|
|
15
|
+
import { closeSync, openSync, readSync, realpathSync } from "node:fs";
|
|
16
16
|
import { resolve } from "node:path";
|
|
17
|
+
import { StringDecoder } from "node:string_decoder";
|
|
17
18
|
import Database from "better-sqlite3";
|
|
18
19
|
/** Columns the lookup depends on; any missing one means "schema unreadable". */
|
|
19
20
|
export const CODEX_THREAD_COLUMNS = [
|
|
20
|
-
"id", "cwd", "source", "archived", "has_user_event", "recency_at_ms", "updated_at_ms",
|
|
21
|
+
"id", "cwd", "source", "archived", "has_user_event", "first_user_message", "rollout_path", "recency_at_ms", "updated_at_ms",
|
|
21
22
|
];
|
|
22
23
|
const SESSION_ID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
23
24
|
/**
|
|
@@ -41,8 +42,24 @@ function cwdCandidates(workingDirectory) {
|
|
|
41
42
|
* Newest interactive thread recorded for exactly this directory. Exact
|
|
42
43
|
* equality only: a prefix or LIKE match would take a subdirectory's (or a
|
|
43
44
|
* similarly named sibling's) session.
|
|
45
|
+
*
|
|
46
|
+
* "Has anything in it" was checked against real Codex data (#1017), not
|
|
47
|
+
* inferred from a column name:
|
|
48
|
+
* - `has_user_event` does NOT mean that. Real 0.157 sessions with a first
|
|
49
|
+
* message and millions of tokens carry 0. Filtering on it matched no real
|
|
50
|
+
* session, so every restart silently started a new conversation.
|
|
51
|
+
* - `tokens_used > 0` drops real sessions too: a provider that reports no
|
|
52
|
+
* token usage leaves it at 0, as does a restart during the first turn.
|
|
53
|
+
* - A non-empty `first_user_message` proves content, but an empty one does
|
|
54
|
+
* not prove the opposite: a real 38-turn session (0.156.1) and `/goal`-first
|
|
55
|
+
* sessions (openai/codex#28423) have empty list metadata. For those the
|
|
56
|
+
* rollout decides whether a turn ever ran. A thread nobody used (e.g. an
|
|
57
|
+
* untouched fork) holds only `session_meta`/`thread_settings_applied`; any
|
|
58
|
+
* turn — however its first input was delivered, including hidden goal
|
|
59
|
+
* context — writes `task_started`, a `turn_context` or a `response_item`.
|
|
60
|
+
* tests/fixtures/codex-real-threads.json holds the real rows behind this.
|
|
44
61
|
*/
|
|
45
|
-
export function findExactCwdCodexSession(stateDbPath, workingDirectory, open = openCodexStateReadonly) {
|
|
62
|
+
export function findExactCwdCodexSession(stateDbPath, workingDirectory, open = openCodexStateReadonly, rolloutHasTurn = rolloutRecordsTurn) {
|
|
46
63
|
let db = null;
|
|
47
64
|
try {
|
|
48
65
|
db = open(stateDbPath);
|
|
@@ -51,15 +68,27 @@ export function findExactCwdCodexSession(stateDbPath, workingDirectory, open = o
|
|
|
51
68
|
if (missing.length > 0)
|
|
52
69
|
return { kind: "unreadable", reason: `threads schema missing: ${missing.join(", ")}` };
|
|
53
70
|
const [first, second = first] = cwdCandidates(workingDirectory);
|
|
54
|
-
|
|
55
|
-
|
|
71
|
+
// Every thread of this directory, newest first, until one has content —
|
|
72
|
+
// no page limit, so a run of empty threads cannot hide an older session.
|
|
73
|
+
const rows = db.prepare(`
|
|
74
|
+
SELECT id, has_user_event, first_user_message, rollout_path FROM threads
|
|
56
75
|
WHERE cwd IN (?, ?)
|
|
57
76
|
AND source = 'cli'
|
|
58
77
|
AND archived = 0
|
|
59
|
-
AND has_user_event = 1
|
|
60
78
|
ORDER BY recency_at_ms DESC, updated_at_ms DESC, id DESC
|
|
61
|
-
|
|
62
|
-
|
|
79
|
+
`).iterate(first, second);
|
|
80
|
+
let row;
|
|
81
|
+
for (const r of rows) {
|
|
82
|
+
// Any sign of content is enough; only a thread with none is skipped.
|
|
83
|
+
// has_user_event = 1 is what the #984 lookup accepted, so keeping it
|
|
84
|
+
// means this lookup never resumes less than that one did.
|
|
85
|
+
if (r.has_user_event === 1
|
|
86
|
+
|| (typeof r.first_user_message === "string" && r.first_user_message !== "")
|
|
87
|
+
|| (typeof r.rollout_path === "string" && rolloutHasTurn(r.rollout_path))) {
|
|
88
|
+
row = r;
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
63
92
|
if (!row)
|
|
64
93
|
return { kind: "none" };
|
|
65
94
|
// A malformed id means the schema no longer means what we think it does.
|
|
@@ -79,6 +108,74 @@ export function findExactCwdCodexSession(stateDbPath, workingDirectory, open = o
|
|
|
79
108
|
catch { /* already closed */ }
|
|
80
109
|
}
|
|
81
110
|
}
|
|
111
|
+
/** Rollouts are read in chunks of this size until a turn entry or the end. */
|
|
112
|
+
const ROLLOUT_CHUNK_BYTES = 256 * 1024;
|
|
113
|
+
/**
|
|
114
|
+
* The entries of a thread nobody used. Real untouched threads (e.g. a fork)
|
|
115
|
+
* hold exactly `session_meta` and `event_msg:thread_settings_applied`.
|
|
116
|
+
*/
|
|
117
|
+
function isUntouchedThreadEntry(entry) {
|
|
118
|
+
return entry.type === "session_meta"
|
|
119
|
+
|| (entry.type === "event_msg" && entry.payload?.type === "thread_settings_applied");
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Whether a Codex rollout (JSONL) may hold a conversation. Read-only, in
|
|
123
|
+
* chunks, stopping at the first entry that is not part of an untouched thread
|
|
124
|
+
* — in real rollouts a turn entry follows the ~22 KB session_meta line.
|
|
125
|
+
*
|
|
126
|
+
* "No" needs proof: the file has the known untouched shape and nothing else
|
|
127
|
+
* (`session_meta` + `thread_settings_applied`). Every other entry — a turn,
|
|
128
|
+
* an entry type from a newer Codex, a line this code cannot parse — counts
|
|
129
|
+
* as yes: resuming a doubtful thread fails loudly, skipping a real one
|
|
130
|
+
* silently loses the conversation. A missing or unreadable rollout cannot be
|
|
131
|
+
* resumed, so it counts as no.
|
|
132
|
+
*/
|
|
133
|
+
export function rolloutRecordsTurn(path) {
|
|
134
|
+
let fd = null;
|
|
135
|
+
try {
|
|
136
|
+
fd = openSync(path, "r");
|
|
137
|
+
const buf = Buffer.alloc(ROLLOUT_CHUNK_BYTES);
|
|
138
|
+
// A multi-byte character may straddle two chunks; the decoder holds it.
|
|
139
|
+
const decoder = new StringDecoder("utf8");
|
|
140
|
+
let pending = "";
|
|
141
|
+
let position = 0;
|
|
142
|
+
let recognised = false;
|
|
143
|
+
for (;;) {
|
|
144
|
+
const read = readSync(fd, buf, 0, ROLLOUT_CHUNK_BYTES, position);
|
|
145
|
+
position += read;
|
|
146
|
+
const text = pending + (read === 0 ? decoder.end() : decoder.write(buf.subarray(0, read)));
|
|
147
|
+
const lines = text.split("\n");
|
|
148
|
+
pending = read === 0 ? "" : lines.pop() ?? "";
|
|
149
|
+
for (const line of lines) {
|
|
150
|
+
if (!line.trim())
|
|
151
|
+
continue;
|
|
152
|
+
let entry;
|
|
153
|
+
try {
|
|
154
|
+
entry = JSON.parse(line);
|
|
155
|
+
}
|
|
156
|
+
catch {
|
|
157
|
+
return true;
|
|
158
|
+
} // unparseable: not provably empty
|
|
159
|
+
if (!isUntouchedThreadEntry(entry))
|
|
160
|
+
return true;
|
|
161
|
+
if (entry.type === "session_meta")
|
|
162
|
+
recognised = true;
|
|
163
|
+
}
|
|
164
|
+
if (read === 0)
|
|
165
|
+
return !recognised;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
catch {
|
|
169
|
+
return false;
|
|
170
|
+
}
|
|
171
|
+
finally {
|
|
172
|
+
if (fd !== null)
|
|
173
|
+
try {
|
|
174
|
+
closeSync(fd);
|
|
175
|
+
}
|
|
176
|
+
catch { /* already closed */ }
|
|
177
|
+
}
|
|
178
|
+
}
|
|
82
179
|
export const defaultGitCommonDir = dir => {
|
|
83
180
|
try {
|
|
84
181
|
return execFileSync("git", ["-C", dir, "rev-parse", "--path-format=absolute", "--git-common-dir"], {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codex-session-lookup.js","sourceRoot":"","sources":["../../src/backend/codex-session-lookup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"codex-session-lookup.js","sourceRoot":"","sources":["../../src/backend/codex-session-lookup.ts"],"names":[],"mappings":"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"}
|