源码快照 @ 2026-09-02 (source-only, 剔除非源码素材)
This commit is contained in:
@@ -0,0 +1,153 @@
|
||||
import assert from "node:assert/strict";
|
||||
|
||||
import {
|
||||
findFreePort,
|
||||
makeClient,
|
||||
parseArgs,
|
||||
spawnOpencodeServe,
|
||||
waitForHealthy,
|
||||
} from "./_util.mjs";
|
||||
|
||||
const args = parseArgs(process.argv.slice(2));
|
||||
const directory = args.get("dir") ?? process.cwd();
|
||||
|
||||
const port = await findFreePort();
|
||||
const server = await spawnOpencodeServe({ directory, port });
|
||||
|
||||
const results = {
|
||||
ok: true,
|
||||
baseUrl: server.baseUrl,
|
||||
directory: server.cwd,
|
||||
steps: [],
|
||||
};
|
||||
|
||||
function step(name, fn) {
|
||||
results.steps.push({ name, status: "running" });
|
||||
const idx = results.steps.length - 1;
|
||||
|
||||
return Promise.resolve()
|
||||
.then(fn)
|
||||
.then((data) => {
|
||||
results.steps[idx] = { name, status: "ok", data };
|
||||
})
|
||||
.catch((e) => {
|
||||
results.ok = false;
|
||||
results.steps[idx] = {
|
||||
name,
|
||||
status: "error",
|
||||
error: e instanceof Error ? e.message : String(e),
|
||||
};
|
||||
throw e;
|
||||
});
|
||||
}
|
||||
|
||||
function getMessageSessionId(message) {
|
||||
if (message && typeof message.sessionID === "string") return message.sessionID;
|
||||
if (message && message.info && typeof message.info.sessionID === "string") return message.info.sessionID;
|
||||
return null;
|
||||
}
|
||||
|
||||
function extractLastText(messages) {
|
||||
const list = Array.isArray(messages) ? messages.slice() : [];
|
||||
for (let i = list.length - 1; i >= 0; i -= 1) {
|
||||
const msg = list[i];
|
||||
const parts = Array.isArray(msg?.parts) ? msg.parts : [];
|
||||
for (let p = parts.length - 1; p >= 0; p -= 1) {
|
||||
const part = parts[p];
|
||||
if (part && part.type === "text" && typeof part.text === "string") {
|
||||
return part.text;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
const client = makeClient({ baseUrl: server.baseUrl, directory: server.cwd });
|
||||
await waitForHealthy(client);
|
||||
|
||||
let sessionA;
|
||||
let sessionB;
|
||||
|
||||
await step("session.create A", async () => {
|
||||
sessionA = await client.session.create({ title: "OpenWork session A" });
|
||||
assert.ok(sessionA?.id);
|
||||
return { id: sessionA.id };
|
||||
});
|
||||
|
||||
await step("session.create B", async () => {
|
||||
sessionB = await client.session.create({ title: "OpenWork session B" });
|
||||
assert.ok(sessionB?.id);
|
||||
return { id: sessionB.id };
|
||||
});
|
||||
|
||||
await step("session.prompt A", async () => {
|
||||
await client.session.prompt({
|
||||
sessionID: sessionA.id,
|
||||
noReply: true,
|
||||
parts: [{ type: "text", text: "Hello from session A" }],
|
||||
});
|
||||
return { sessionID: sessionA.id };
|
||||
});
|
||||
|
||||
await step("session.prompt B", async () => {
|
||||
await client.session.prompt({
|
||||
sessionID: sessionB.id,
|
||||
noReply: true,
|
||||
parts: [{ type: "text", text: "Hello from session B" }],
|
||||
});
|
||||
return { sessionID: sessionB.id };
|
||||
});
|
||||
|
||||
await step("session.messages A", async () => {
|
||||
const messages = await client.session.messages({ sessionID: sessionA.id, limit: 50 });
|
||||
assert.ok(Array.isArray(messages));
|
||||
for (const msg of messages) {
|
||||
const msgSessionId = getMessageSessionId(msg);
|
||||
assert.equal(msgSessionId, sessionA.id);
|
||||
}
|
||||
const text = extractLastText(messages);
|
||||
assert.ok(text && text.includes("session A"));
|
||||
return { count: messages.length };
|
||||
});
|
||||
|
||||
await step("session.messages B", async () => {
|
||||
const messages = await client.session.messages({ sessionID: sessionB.id, limit: 50 });
|
||||
assert.ok(Array.isArray(messages));
|
||||
for (const msg of messages) {
|
||||
const msgSessionId = getMessageSessionId(msg);
|
||||
assert.equal(msgSessionId, sessionB.id);
|
||||
}
|
||||
const text = extractLastText(messages);
|
||||
assert.ok(text && text.includes("session B"));
|
||||
return { count: messages.length };
|
||||
});
|
||||
|
||||
await step("session.messages switch", async () => {
|
||||
const [messagesA, messagesB] = await Promise.all([
|
||||
client.session.messages({ sessionID: sessionA.id, limit: 50 }),
|
||||
client.session.messages({ sessionID: sessionB.id, limit: 50 }),
|
||||
]);
|
||||
|
||||
const textA = extractLastText(messagesA);
|
||||
const textB = extractLastText(messagesB);
|
||||
|
||||
assert.ok(textA && textA.includes("session A"));
|
||||
assert.ok(textB && textB.includes("session B"));
|
||||
|
||||
return { aCount: messagesA.length, bCount: messagesB.length };
|
||||
});
|
||||
|
||||
console.log(JSON.stringify(results, null, 2));
|
||||
} catch (e) {
|
||||
const message = e instanceof Error ? e.message : String(e);
|
||||
results.ok = false;
|
||||
results.error = message;
|
||||
results.stderr = server.getStderr();
|
||||
results.stdout = server.getStdout?.() ?? "";
|
||||
results.serverExit = server.getExitInfo?.() ?? null;
|
||||
console.error(JSON.stringify(results, null, 2));
|
||||
process.exitCode = 1;
|
||||
} finally {
|
||||
await server.close();
|
||||
}
|
||||
Reference in New Issue
Block a user