oasis_test 0.1.37 → 0.1.39
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/index.js +162 -46
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -25136,10 +25136,12 @@ async function startOasisServer(opts) {
|
|
|
25136
25136
|
if (!body.actorId) {
|
|
25137
25137
|
throw new ApiError(400, "CHAT_ACTOR_REQUIRED", "\u8111\u66B4\u5BF9\u8BDD\u5FC5\u987B\u9009\u62E9\u4E00\u4E2A\u6570\u5B57\u5458\u5DE5");
|
|
25138
25138
|
}
|
|
25139
|
+
const inheritedRuntimeSessionId = !body.sessionId && body.chatSessionId && opts.chatSession ? await opts.chatSession.getSession(body.chatSessionId).catch(() => null).then((s2) => s2 && s2.humanActorId === actor ? s2.runtimeSessionId ?? void 0 : void 0) : void 0;
|
|
25140
|
+
const effectiveSessionId = body.sessionId ?? inheritedRuntimeSessionId;
|
|
25139
25141
|
const session = await opts.dispatchChat({
|
|
25140
25142
|
actorId: body.actorId,
|
|
25141
25143
|
message: body.message,
|
|
25142
|
-
...
|
|
25144
|
+
...effectiveSessionId ? { sessionId: effectiveSessionId } : {},
|
|
25143
25145
|
...body.chatSessionId ? { chatSessionId: body.chatSessionId } : {},
|
|
25144
25146
|
...body.workspace ? { workspace: body.workspace } : {},
|
|
25145
25147
|
...currentCompanyId !== void 0 ? { companyId: currentCompanyId } : {},
|
|
@@ -25164,26 +25166,52 @@ async function startOasisServer(opts) {
|
|
|
25164
25166
|
...persistAttachments.length ? { attachments: persistAttachments } : {}
|
|
25165
25167
|
}).catch(() => void 0);
|
|
25166
25168
|
}
|
|
25169
|
+
let assistantMsgId;
|
|
25170
|
+
if (chatStore && persistTarget) {
|
|
25171
|
+
const { randomUUID: randomUUID19 } = await import("node:crypto");
|
|
25172
|
+
const id = randomUUID19();
|
|
25173
|
+
await chatStore.appendMessage({
|
|
25174
|
+
id,
|
|
25175
|
+
sessionId: persistTarget.id,
|
|
25176
|
+
role: "assistant",
|
|
25177
|
+
content: "",
|
|
25178
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
25179
|
+
status: "running",
|
|
25180
|
+
...session.runId ? { runId: session.runId } : {}
|
|
25181
|
+
}).then(() => {
|
|
25182
|
+
assistantMsgId = id;
|
|
25183
|
+
}).catch(() => void 0);
|
|
25184
|
+
}
|
|
25167
25185
|
let assistantText = "";
|
|
25168
25186
|
let persisted = false;
|
|
25169
25187
|
let live = null;
|
|
25170
25188
|
const localParts = [];
|
|
25171
25189
|
const collectedParts = () => (live ? live.bufferedParts() : localParts).filter((p2) => p2.type !== "done");
|
|
25172
|
-
const finalizeAssistant = async () => {
|
|
25190
|
+
const finalizeAssistant = async (status = "done") => {
|
|
25173
25191
|
if (persisted || !chatStore || !persistTarget) return;
|
|
25174
25192
|
persisted = true;
|
|
25175
25193
|
const parts = collectedParts();
|
|
25176
|
-
if (
|
|
25177
|
-
|
|
25178
|
-
|
|
25179
|
-
|
|
25180
|
-
|
|
25181
|
-
|
|
25182
|
-
|
|
25183
|
-
|
|
25184
|
-
|
|
25185
|
-
|
|
25186
|
-
|
|
25194
|
+
if (assistantMsgId) {
|
|
25195
|
+
await chatStore.updateMessage(assistantMsgId, {
|
|
25196
|
+
content: assistantText,
|
|
25197
|
+
status,
|
|
25198
|
+
...parts.length ? { parts } : {},
|
|
25199
|
+
...session.runId ? { runId: session.runId } : {}
|
|
25200
|
+
}).catch(() => void 0);
|
|
25201
|
+
} else {
|
|
25202
|
+
if (!assistantText && !session.runId && parts.length === 0) return;
|
|
25203
|
+
const { randomUUID: randomUUID19 } = await import("node:crypto");
|
|
25204
|
+
await chatStore.appendMessage({
|
|
25205
|
+
id: randomUUID19(),
|
|
25206
|
+
sessionId: persistTarget.id,
|
|
25207
|
+
role: "assistant",
|
|
25208
|
+
content: assistantText,
|
|
25209
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
25210
|
+
status,
|
|
25211
|
+
...session.runId ? { runId: session.runId } : {},
|
|
25212
|
+
...parts.length ? { parts } : {}
|
|
25213
|
+
}).catch(() => void 0);
|
|
25214
|
+
}
|
|
25187
25215
|
await chatStore.updateSession(persistTarget.id, {
|
|
25188
25216
|
// 优先落 runtime-native id(codex rollout / ACP session/new 返回),让下一轮 resume
|
|
25189
25217
|
// 能命中 runtime 认可的 id;claude-code 等接受任意外部 id 的仍回退 session.id 兼容原行为。
|
|
@@ -25213,11 +25241,13 @@ async function startOasisServer(opts) {
|
|
|
25213
25241
|
}
|
|
25214
25242
|
}) : null;
|
|
25215
25243
|
let localSeq = 0;
|
|
25244
|
+
let ckptDirty = false;
|
|
25216
25245
|
const writeToRes = (part) => {
|
|
25217
25246
|
if (!res.destroyed) res.write(`${JSON.stringify(part)}
|
|
25218
25247
|
`);
|
|
25219
25248
|
};
|
|
25220
25249
|
const emit = (part) => {
|
|
25250
|
+
ckptDirty = true;
|
|
25221
25251
|
if (live) return live.emit(part);
|
|
25222
25252
|
const withSeq = { ...part, seq: ++localSeq };
|
|
25223
25253
|
if (part.type !== "done") localParts.push(withSeq);
|
|
@@ -25233,6 +25263,13 @@ async function startOasisServer(opts) {
|
|
|
25233
25263
|
});
|
|
25234
25264
|
res.flushHeaders();
|
|
25235
25265
|
stopKeepalive = startStreamKeepalive(res);
|
|
25266
|
+
const ckptTimer = setInterval(() => {
|
|
25267
|
+
if (!ckptDirty || !assistantMsgId || !chatStore) return;
|
|
25268
|
+
ckptDirty = false;
|
|
25269
|
+
const parts = collectedParts();
|
|
25270
|
+
void chatStore.updateMessage(assistantMsgId, { content: assistantText, status: "running", ...parts.length ? { parts } : {} }).catch(() => void 0);
|
|
25271
|
+
}, 2e3);
|
|
25272
|
+
ckptTimer.unref?.();
|
|
25236
25273
|
if (live) detachViewer = live.subscribe(writeToRes);
|
|
25237
25274
|
let sawTextOutput = false;
|
|
25238
25275
|
session.onOutput((chunk) => {
|
|
@@ -25253,7 +25290,8 @@ async function startOasisServer(opts) {
|
|
|
25253
25290
|
emit({ type: "error", text: err instanceof Error ? err.message : String(err) });
|
|
25254
25291
|
}
|
|
25255
25292
|
finished = true;
|
|
25256
|
-
|
|
25293
|
+
clearInterval(ckptTimer);
|
|
25294
|
+
await finalizeAssistant(errored ? "error" : "done");
|
|
25257
25295
|
emit({ type: "done", sessionId: session.id });
|
|
25258
25296
|
live?.finish(errored ? "error" : "done");
|
|
25259
25297
|
stopKeepalive?.();
|
|
@@ -28896,6 +28934,17 @@ var init_dev_store = __esm({
|
|
|
28896
28934
|
this.messages.set(m2.sessionId, list);
|
|
28897
28935
|
return record5;
|
|
28898
28936
|
}
|
|
28937
|
+
async updateMessage(id, patch) {
|
|
28938
|
+
for (const list of this.messages.values()) {
|
|
28939
|
+
const item = list.find((x2) => x2.id === id);
|
|
28940
|
+
if (!item) continue;
|
|
28941
|
+
if (patch.content !== void 0) item.content = patch.content;
|
|
28942
|
+
if (patch.parts !== void 0) item.parts = patch.parts;
|
|
28943
|
+
if (patch.status !== void 0) item.status = patch.status;
|
|
28944
|
+
if (patch.runId !== void 0) item.runId = patch.runId;
|
|
28945
|
+
return;
|
|
28946
|
+
}
|
|
28947
|
+
}
|
|
28899
28948
|
async listMessages(sessionId, limit) {
|
|
28900
28949
|
const list = (this.messages.get(sessionId) ?? []).sort((a, b2) => a.seq - b2.seq);
|
|
28901
28950
|
return limit ? list.slice(-limit) : list;
|
|
@@ -28944,6 +28993,10 @@ var init_dev_store = __esm({
|
|
|
28944
28993
|
this.save();
|
|
28945
28994
|
return record5;
|
|
28946
28995
|
}
|
|
28996
|
+
async updateMessage(id, patch) {
|
|
28997
|
+
await super.updateMessage(id, patch);
|
|
28998
|
+
this.save();
|
|
28999
|
+
}
|
|
28947
29000
|
async linkWorkOrder(sessionId, workOrderId) {
|
|
28948
29001
|
await super.linkWorkOrder(sessionId, workOrderId);
|
|
28949
29002
|
this.save();
|
|
@@ -37926,6 +37979,31 @@ function codexSessionsRoot() {
|
|
|
37926
37979
|
}
|
|
37927
37980
|
return "";
|
|
37928
37981
|
}
|
|
37982
|
+
function codexRolloutExists(sessionId, root = codexSessionsRoot()) {
|
|
37983
|
+
if (!sessionId || !root) return false;
|
|
37984
|
+
const suffix = `-${sessionId}.jsonl`;
|
|
37985
|
+
let hit = false;
|
|
37986
|
+
const walk = (d) => {
|
|
37987
|
+
if (hit) return;
|
|
37988
|
+
let ents;
|
|
37989
|
+
try {
|
|
37990
|
+
ents = fs8.readdirSync(d, { withFileTypes: true });
|
|
37991
|
+
} catch {
|
|
37992
|
+
return;
|
|
37993
|
+
}
|
|
37994
|
+
for (const ent of ents) {
|
|
37995
|
+
if (hit) return;
|
|
37996
|
+
const p2 = path8.join(d, ent.name);
|
|
37997
|
+
if (ent.isDirectory()) walk(p2);
|
|
37998
|
+
else if (ent.isFile() && ent.name.startsWith("rollout-") && ent.name.endsWith(suffix)) {
|
|
37999
|
+
hit = true;
|
|
38000
|
+
return;
|
|
38001
|
+
}
|
|
38002
|
+
}
|
|
38003
|
+
};
|
|
38004
|
+
walk(root);
|
|
38005
|
+
return hit;
|
|
38006
|
+
}
|
|
37929
38007
|
function listRecentRollouts(root, sinceMs) {
|
|
37930
38008
|
const margin = sinceMs - 6e4;
|
|
37931
38009
|
const found = [];
|
|
@@ -38176,7 +38254,9 @@ var init_codex = __esm({
|
|
|
38176
38254
|
const task = job.bundle.files["TASK.md"];
|
|
38177
38255
|
if (!task) throw new Error("bundle \u7F3A TASK.md\uFF08\u88C5\u914D\u5668\u5951\u7EA6\uFF09");
|
|
38178
38256
|
const prompt = job.systemPrompt ? ["# System Prompt", job.systemPrompt, "", "# Task", task].join("\n") : task;
|
|
38179
|
-
const isResume = Boolean(
|
|
38257
|
+
const isResume = Boolean(
|
|
38258
|
+
job.resumeRuntimeSession && job.runtimeSessionId && codexRolloutExists(job.runtimeSessionId)
|
|
38259
|
+
);
|
|
38180
38260
|
const args = [
|
|
38181
38261
|
"exec",
|
|
38182
38262
|
"-C",
|
|
@@ -40216,39 +40296,47 @@ function nodesDomain(deps) {
|
|
|
40216
40296
|
if (msg.type !== "hello") return;
|
|
40217
40297
|
const d = hub.connectedDaemons().find((c) => c.daemonId === daemonId);
|
|
40218
40298
|
if (!d) return;
|
|
40219
|
-
|
|
40220
|
-
|
|
40221
|
-
|
|
40222
|
-
|
|
40223
|
-
|
|
40224
|
-
nodeVersion: d.meta.nodeVersion ?? "unknown",
|
|
40225
|
-
status: "online",
|
|
40226
|
-
// revives a previously soft-deleted node
|
|
40227
|
-
lastSeenAt: now(),
|
|
40228
|
-
enrolledAt: existing?.enrolledAt ?? now(),
|
|
40229
|
-
...d.meta.nodeName ? { name: d.meta.nodeName } : existing?.name ? { name: existing.name } : {}
|
|
40230
|
-
});
|
|
40231
|
-
for (const cap of msg.meta.runtimes) {
|
|
40232
|
-
await nodeStore.addRuntimeIfAbsent({
|
|
40233
|
-
id: `runtime:${daemonId}:${cap.kind}`,
|
|
40234
|
-
nodeId: daemonId,
|
|
40235
|
-
kind: cap.kind,
|
|
40299
|
+
try {
|
|
40300
|
+
if (msg.meta.runtimes) {
|
|
40301
|
+
const existing = await nodeStore.getNode(daemonId);
|
|
40302
|
+
await nodeStore.upsertNode({
|
|
40303
|
+
id: daemonId,
|
|
40236
40304
|
hostname: d.meta.hostname,
|
|
40237
|
-
|
|
40238
|
-
...cap.version ? { version: cap.version } : {},
|
|
40305
|
+
nodeVersion: d.meta.nodeVersion ?? "unknown",
|
|
40239
40306
|
status: "online",
|
|
40240
|
-
|
|
40307
|
+
// revives a previously soft-deleted node
|
|
40308
|
+
lastSeenAt: now(),
|
|
40309
|
+
enrolledAt: existing?.enrolledAt ?? now(),
|
|
40310
|
+
...d.meta.nodeName ? { name: d.meta.nodeName } : existing?.name ? { name: existing.name } : {}
|
|
40241
40311
|
});
|
|
40312
|
+
for (const cap of msg.meta.runtimes) {
|
|
40313
|
+
await nodeStore.addRuntimeIfAbsent({
|
|
40314
|
+
id: `runtime:${daemonId}:${cap.kind}`,
|
|
40315
|
+
nodeId: daemonId,
|
|
40316
|
+
kind: cap.kind,
|
|
40317
|
+
hostname: d.meta.hostname,
|
|
40318
|
+
...cap.binary ? { binary: cap.binary } : {},
|
|
40319
|
+
...cap.version ? { version: cap.version } : {},
|
|
40320
|
+
status: "online",
|
|
40321
|
+
lastSeenAt: now()
|
|
40322
|
+
});
|
|
40323
|
+
}
|
|
40324
|
+
await nodeStore.setNodeRuntimesOnline(daemonId, true);
|
|
40325
|
+
} else {
|
|
40326
|
+
await nodeStore.setNodeOnline(daemonId, true);
|
|
40327
|
+
await nodeStore.setNodeRuntimesOnline(daemonId, true);
|
|
40242
40328
|
}
|
|
40243
|
-
|
|
40244
|
-
|
|
40245
|
-
await nodeStore.setNodeOnline(daemonId, true);
|
|
40246
|
-
await nodeStore.setNodeRuntimesOnline(daemonId, true);
|
|
40329
|
+
} catch (err) {
|
|
40330
|
+
console.warn(`[nodes] hello \u5904\u7406\u5931\u8D25(node=${daemonId})\uFF1A${err instanceof Error ? err.message : String(err)}`);
|
|
40247
40331
|
}
|
|
40248
40332
|
});
|
|
40249
40333
|
hub.onDaemonDisconnected = async (daemonId) => {
|
|
40250
|
-
|
|
40251
|
-
|
|
40334
|
+
try {
|
|
40335
|
+
await nodeStore.setNodeOnline(daemonId, false);
|
|
40336
|
+
await nodeStore.setNodeRuntimesOnline(daemonId, false);
|
|
40337
|
+
} catch (err) {
|
|
40338
|
+
console.warn(`[nodes] disconnect \u5904\u7406\u5931\u8D25(node=${daemonId})\uFF1A${err instanceof Error ? err.message : String(err)}`);
|
|
40339
|
+
}
|
|
40252
40340
|
};
|
|
40253
40341
|
}
|
|
40254
40342
|
return (router) => {
|
|
@@ -54232,6 +54320,7 @@ var PostgresChatSessionStore = class _PostgresChatSessionStore {
|
|
|
54232
54320
|
await pool.query(`ALTER TABLE "${s2}".chat_messages ADD COLUMN IF NOT EXISTS run_id text`);
|
|
54233
54321
|
await pool.query(`ALTER TABLE "${s2}".chat_messages ADD COLUMN IF NOT EXISTS parts jsonb`);
|
|
54234
54322
|
await pool.query(`ALTER TABLE "${s2}".chat_messages ADD COLUMN IF NOT EXISTS attachments jsonb`);
|
|
54323
|
+
await pool.query(`ALTER TABLE "${s2}".chat_messages ADD COLUMN IF NOT EXISTS status text`);
|
|
54235
54324
|
await pool.query(`ALTER TABLE "${s2}".chat_sessions ADD COLUMN IF NOT EXISTS workspace text`);
|
|
54236
54325
|
await pool.query(`
|
|
54237
54326
|
WITH ranked AS (
|
|
@@ -54297,11 +54386,11 @@ var PostgresChatSessionStore = class _PostgresChatSessionStore {
|
|
|
54297
54386
|
async appendMessage(m2) {
|
|
54298
54387
|
const insert = async () => {
|
|
54299
54388
|
const r = await this.pool.query(
|
|
54300
|
-
`INSERT INTO ${this.s}.chat_messages (id, session_id, role, content, seq, created_at, run_id, parts, attachments)
|
|
54301
|
-
SELECT $1,$2,$3,$4, COALESCE(MAX(seq),0)+1, $5,$6,$7,$8
|
|
54389
|
+
`INSERT INTO ${this.s}.chat_messages (id, session_id, role, content, seq, created_at, run_id, parts, attachments, status)
|
|
54390
|
+
SELECT $1,$2,$3,$4, COALESCE(MAX(seq),0)+1, $5,$6,$7,$8,$9
|
|
54302
54391
|
FROM ${this.s}.chat_messages WHERE session_id = $2
|
|
54303
54392
|
RETURNING seq`,
|
|
54304
|
-
[m2.id, m2.sessionId, m2.role, m2.content, m2.createdAt, m2.runId ?? null, m2.parts !== void 0 ? JSON.stringify(m2.parts) : null, m2.attachments !== void 0 ? JSON.stringify(m2.attachments) : null]
|
|
54393
|
+
[m2.id, m2.sessionId, m2.role, m2.content, m2.createdAt, m2.runId ?? null, m2.parts !== void 0 ? JSON.stringify(m2.parts) : null, m2.attachments !== void 0 ? JSON.stringify(m2.attachments) : null, m2.status ?? null]
|
|
54305
54394
|
);
|
|
54306
54395
|
return Number(r.rows[0].seq);
|
|
54307
54396
|
};
|
|
@@ -54315,6 +54404,29 @@ var PostgresChatSessionStore = class _PostgresChatSessionStore {
|
|
|
54315
54404
|
}
|
|
54316
54405
|
}
|
|
54317
54406
|
}
|
|
54407
|
+
async updateMessage(id, patch) {
|
|
54408
|
+
const sets = [];
|
|
54409
|
+
const args = [];
|
|
54410
|
+
if (patch.content !== void 0) {
|
|
54411
|
+
args.push(patch.content);
|
|
54412
|
+
sets.push(`content = $${args.length}`);
|
|
54413
|
+
}
|
|
54414
|
+
if (patch.parts !== void 0) {
|
|
54415
|
+
args.push(JSON.stringify(patch.parts));
|
|
54416
|
+
sets.push(`parts = $${args.length}`);
|
|
54417
|
+
}
|
|
54418
|
+
if (patch.status !== void 0) {
|
|
54419
|
+
args.push(patch.status);
|
|
54420
|
+
sets.push(`status = $${args.length}`);
|
|
54421
|
+
}
|
|
54422
|
+
if (patch.runId !== void 0) {
|
|
54423
|
+
args.push(patch.runId);
|
|
54424
|
+
sets.push(`run_id = $${args.length}`);
|
|
54425
|
+
}
|
|
54426
|
+
if (sets.length === 0) return;
|
|
54427
|
+
args.push(id);
|
|
54428
|
+
await this.pool.query(`UPDATE ${this.s}.chat_messages SET ${sets.join(", ")} WHERE id = $${args.length}`, args);
|
|
54429
|
+
}
|
|
54318
54430
|
async listMessages(sessionId, limit) {
|
|
54319
54431
|
const limitClause = limit ? `LIMIT ${limit}` : "";
|
|
54320
54432
|
const r = await this.pool.query(
|
|
@@ -54358,7 +54470,8 @@ var rowToMessage = (row) => ({
|
|
|
54358
54470
|
createdAt: new Date(row.created_at).toISOString(),
|
|
54359
54471
|
...row.run_id != null ? { runId: row.run_id } : {},
|
|
54360
54472
|
...row.parts != null ? { parts: row.parts } : {},
|
|
54361
|
-
...row.attachments != null ? { attachments: row.attachments } : {}
|
|
54473
|
+
...row.attachments != null ? { attachments: row.attachments } : {},
|
|
54474
|
+
...row.status != null ? { status: row.status } : {}
|
|
54362
54475
|
});
|
|
54363
54476
|
|
|
54364
54477
|
// ../storage/src/postgres-nodes.ts
|
|
@@ -55062,6 +55175,9 @@ async function startServe(opts) {
|
|
|
55062
55175
|
return service.listSkillFiles(skillId);
|
|
55063
55176
|
}
|
|
55064
55177
|
});
|
|
55178
|
+
process.on("unhandledRejection", (reason) => {
|
|
55179
|
+
console.error(`[serve] unhandledRejection\uFF08\u5DF2\u515C\u5E95\uFF0C\u4E0D\u5D29\u8FDB\u7A0B\uFF09\uFF1A${reason instanceof Error ? reason.stack ?? reason.message : String(reason)}`);
|
|
55180
|
+
});
|
|
55065
55181
|
const server = await startOasisServer({
|
|
55066
55182
|
kernel: engine.kernel,
|
|
55067
55183
|
blobs: engine.blobs,
|
|
@@ -58005,7 +58121,7 @@ ${res.warning}`);
|
|
|
58005
58121
|
}
|
|
58006
58122
|
|
|
58007
58123
|
// src/index.ts
|
|
58008
|
-
var PKG_VERSION = true ? "0.1.
|
|
58124
|
+
var PKG_VERSION = true ? "0.1.39" : "dev";
|
|
58009
58125
|
var OASIS_DIR = path18.join(os10.homedir(), ".oasis");
|
|
58010
58126
|
var CONFIG_FILE = path18.join(OASIS_DIR, "node-config.json");
|
|
58011
58127
|
var PID_FILE = path18.join(OASIS_DIR, "node.pid");
|