Speed up targeted opencode tests

Reduce avoidable setup costs in slow opencode tests while preserving reviewed coverage and recording the benchmark evidence for follow-up test-suite work.
This commit is contained in:
Kit Langton
2026-05-18 12:18:29 -04:00
committed by GitHub
parent 0a945219a9
commit 896ad7b884
18 changed files with 737 additions and 575 deletions

View File

@@ -433,317 +433,290 @@ const boot = Effect.fn("test.boot")(function* (input?: { title?: string }) {
// Loop semantics
it.instance(
"loop exits immediately when last assistant has stop finish",
() =>
Effect.gen(function* () {
const { llm } = yield* useServerConfig(providerCfg)
const prompt = yield* SessionPrompt.Service
const sessions = yield* Session.Service
const chat = yield* sessions.create({ title: "Pinned" })
yield* seed(chat.id, { finish: "stop" })
it.instance("loop exits immediately when last assistant has stop finish", () =>
Effect.gen(function* () {
const { llm } = yield* useServerConfig(providerCfg)
const prompt = yield* SessionPrompt.Service
const sessions = yield* Session.Service
const chat = yield* sessions.create({ title: "Pinned" })
yield* seed(chat.id, { finish: "stop" })
const result = yield* prompt.loop({ sessionID: chat.id })
expect(result.info.role).toBe("assistant")
if (result.info.role === "assistant") expect(result.info.finish).toBe("stop")
expect(yield* llm.calls).toBe(0)
}),
{ git: true },
const result = yield* prompt.loop({ sessionID: chat.id })
expect(result.info.role).toBe("assistant")
if (result.info.role === "assistant") expect(result.info.finish).toBe("stop")
expect(yield* llm.calls).toBe(0)
}),
)
it.instance(
"loop calls LLM and returns assistant message",
() =>
Effect.gen(function* () {
const { llm } = yield* useServerConfig(providerCfg)
const prompt = yield* SessionPrompt.Service
const sessions = yield* Session.Service
const chat = yield* sessions.create({
title: "Pinned",
permission: [{ permission: "*", pattern: "*", action: "allow" }],
})
yield* prompt.prompt({
sessionID: chat.id,
agent: "build",
noReply: true,
parts: [{ type: "text", text: "hello" }],
})
yield* llm.text("world")
it.instance("loop calls LLM and returns assistant message", () =>
Effect.gen(function* () {
const { llm } = yield* useServerConfig(providerCfg)
const prompt = yield* SessionPrompt.Service
const sessions = yield* Session.Service
const chat = yield* sessions.create({
title: "Pinned",
permission: [{ permission: "*", pattern: "*", action: "allow" }],
})
yield* prompt.prompt({
sessionID: chat.id,
agent: "build",
noReply: true,
parts: [{ type: "text", text: "hello" }],
})
yield* llm.text("world")
const result = yield* prompt.loop({ sessionID: chat.id })
expect(result.info.role).toBe("assistant")
const parts = result.parts.filter((p) => p.type === "text")
expect(parts.some((p) => p.type === "text" && p.text === "world")).toBe(true)
expect(yield* llm.hits).toHaveLength(1)
}),
{ git: true },
const result = yield* prompt.loop({ sessionID: chat.id })
expect(result.info.role).toBe("assistant")
const parts = result.parts.filter((p) => p.type === "text")
expect(parts.some((p) => p.type === "text" && p.text === "world")).toBe(true)
expect(yield* llm.hits).toHaveLength(1)
}),
)
it.instance(
"prompt emits v2 prompted and synthetic events",
() =>
Effect.gen(function* () {
yield* useServerConfig(providerCfg)
const prompt = yield* SessionPrompt.Service
const sessions = yield* Session.Service
const chat = yield* sessions.create({ title: "Pinned" })
it.instance("prompt emits v2 prompted and synthetic events", () =>
Effect.gen(function* () {
yield* useServerConfig(providerCfg)
const prompt = yield* SessionPrompt.Service
const sessions = yield* Session.Service
const chat = yield* sessions.create({ title: "Pinned" })
yield* prompt.prompt({
sessionID: chat.id,
agent: "build",
noReply: true,
parts: [
{ type: "text", text: "hello v2" },
{
type: "file",
mime: "text/plain",
filename: "note.txt",
url: "data:text/plain;base64,bm90ZSBjb250ZW50",
},
],
})
const messages = yield* SessionV2.Service.use((session) => session.messages({ sessionID: chat.id })).pipe(
Effect.provide(SessionV2.layer),
)
const row = Database.use((db) =>
db.select().from(SessionMessageTable).where(Database.eq(SessionMessageTable.session_id, chat.id)).get(),
)
expect(messages.find((message) => message.type === "user")).toMatchObject({ type: "user", text: "hello v2" })
expect(typeof row?.data.time.created).toBe("number")
expect(messages).toEqual(
expect.arrayContaining([
expect.objectContaining({ type: "synthetic", text: expect.stringContaining("Called the Read tool") }),
expect.objectContaining({ type: "synthetic", text: "note content" }),
]),
)
}),
{ git: true },
)
it.instance(
"static loop returns assistant text through local provider",
() =>
Effect.gen(function* () {
const { llm } = yield* useServerConfig(providerCfg)
const prompt = yield* SessionPrompt.Service
const sessions = yield* Session.Service
const session = yield* sessions.create({
title: "Prompt provider",
permission: [{ permission: "*", pattern: "*", action: "allow" }],
})
yield* prompt.prompt({
sessionID: session.id,
agent: "build",
noReply: true,
parts: [{ type: "text", text: "hello" }],
})
yield* llm.text("world")
const result = yield* prompt.loop({ sessionID: session.id })
expect(result.info.role).toBe("assistant")
expect(result.parts.some((part) => part.type === "text" && part.text === "world")).toBe(true)
expect(yield* llm.hits).toHaveLength(1)
expect(yield* llm.pending).toBe(0)
}),
{ git: true },
)
it.instance(
"static loop consumes queued replies across turns",
() =>
Effect.gen(function* () {
const { llm } = yield* useServerConfig(providerCfg)
const prompt = yield* SessionPrompt.Service
const sessions = yield* Session.Service
const session = yield* sessions.create({
title: "Prompt provider turns",
permission: [{ permission: "*", pattern: "*", action: "allow" }],
})
yield* prompt.prompt({
sessionID: session.id,
agent: "build",
noReply: true,
parts: [{ type: "text", text: "hello one" }],
})
yield* llm.text("world one")
const first = yield* prompt.loop({ sessionID: session.id })
expect(first.info.role).toBe("assistant")
expect(first.parts.some((part) => part.type === "text" && part.text === "world one")).toBe(true)
yield* prompt.prompt({
sessionID: session.id,
agent: "build",
noReply: true,
parts: [{ type: "text", text: "hello two" }],
})
yield* llm.text("world two")
const second = yield* prompt.loop({ sessionID: session.id })
expect(second.info.role).toBe("assistant")
expect(second.parts.some((part) => part.type === "text" && part.text === "world two")).toBe(true)
expect(yield* llm.hits).toHaveLength(2)
expect(yield* llm.pending).toBe(0)
}),
{ git: true },
)
it.instance(
"loop continues when finish is tool-calls",
() =>
Effect.gen(function* () {
const { llm } = yield* useServerConfig(providerCfg)
const prompt = yield* SessionPrompt.Service
const sessions = yield* Session.Service
const session = yield* sessions.create({
title: "Pinned",
permission: [{ permission: "*", pattern: "*", action: "allow" }],
})
yield* prompt.prompt({
sessionID: session.id,
agent: "build",
noReply: true,
parts: [{ type: "text", text: "hello" }],
})
yield* llm.tool("first", { value: "first" })
yield* llm.text("second")
const result = yield* prompt.loop({ sessionID: session.id })
expect(yield* llm.calls).toBe(2)
expect(result.info.role).toBe("assistant")
if (result.info.role === "assistant") {
expect(result.parts.some((part) => part.type === "text" && part.text === "second")).toBe(true)
expect(result.info.finish).toBe("stop")
}
}),
{ git: true },
)
it.instance(
"glob tool keeps instance context during prompt runs",
() =>
Effect.gen(function* () {
const { dir, llm } = yield* useServerConfig(providerCfg)
const prompt = yield* SessionPrompt.Service
const sessions = yield* Session.Service
const session = yield* sessions.create({
title: "Glob context",
permission: [{ permission: "*", pattern: "*", action: "allow" }],
})
const file = path.join(dir, "probe.txt")
yield* writeText(file, "probe")
yield* prompt.prompt({
sessionID: session.id,
agent: "build",
noReply: true,
parts: [{ type: "text", text: "find text files" }],
})
yield* llm.tool("glob", { pattern: "**/*.txt" })
yield* llm.text("done")
const result = yield* prompt.loop({ sessionID: session.id })
expect(result.info.role).toBe("assistant")
const msgs = yield* MessageV2.filterCompactedEffect(session.id)
const tool = msgs
.flatMap((msg) => msg.parts)
.find(
(part): part is CompletedToolPart =>
part.type === "tool" && part.tool === "glob" && part.state.status === "completed",
)
if (!tool) return
expect(tool.state.output).toContain(file)
expect(tool.state.output).not.toContain("No context found for instance")
expect(result.parts.some((part) => part.type === "text" && part.text === "done")).toBe(true)
}),
{ git: true },
)
it.instance(
"loop continues when finish is stop but assistant has tool parts",
() =>
Effect.gen(function* () {
const { llm } = yield* useServerConfig(providerCfg)
const prompt = yield* SessionPrompt.Service
const sessions = yield* Session.Service
const session = yield* sessions.create({
title: "Pinned",
permission: [{ permission: "*", pattern: "*", action: "allow" }],
})
yield* prompt.prompt({
sessionID: session.id,
agent: "build",
noReply: true,
parts: [{ type: "text", text: "hello" }],
})
yield* llm.push(reply().tool("first", { value: "first" }).stop())
yield* llm.text("second")
const result = yield* prompt.loop({ sessionID: session.id })
expect(yield* llm.calls).toBe(2)
expect(result.info.role).toBe("assistant")
if (result.info.role === "assistant") {
expect(result.parts.some((part) => part.type === "text" && part.text === "second")).toBe(true)
expect(result.info.finish).toBe("stop")
}
}),
{ git: true },
)
it.instance(
"failed subtask preserves metadata on error tool state",
() =>
Effect.gen(function* () {
const { llm } = yield* useServerConfig((url) => ({
...providerCfg(url),
agent: {
general: {
model: "test/missing-model",
},
yield* prompt.prompt({
sessionID: chat.id,
agent: "build",
noReply: true,
parts: [
{ type: "text", text: "hello v2" },
{
type: "file",
mime: "text/plain",
filename: "note.txt",
url: "data:text/plain;base64,bm90ZSBjb250ZW50",
},
}))
const prompt = yield* SessionPrompt.Service
const sessions = yield* Session.Service
const chat = yield* sessions.create({ title: "Pinned" })
yield* llm.tool("task", {
description: "inspect bug",
prompt: "look into the cache key path",
subagent_type: "general",
})
yield* llm.text("done")
const msg = yield* user(chat.id, "hello")
yield* addSubtask(chat.id, msg.id)
],
})
const result = yield* prompt.loop({ sessionID: chat.id })
expect(result.info.role).toBe("assistant")
expect(yield* llm.calls).toBe(2)
const messages = yield* SessionV2.Service.use((session) => session.messages({ sessionID: chat.id })).pipe(
Effect.provide(SessionV2.layer),
)
const row = Database.use((db) =>
db.select().from(SessionMessageTable).where(Database.eq(SessionMessageTable.session_id, chat.id)).get(),
)
expect(messages.find((message) => message.type === "user")).toMatchObject({ type: "user", text: "hello v2" })
expect(typeof row?.data.time.created).toBe("number")
expect(messages).toEqual(
expect.arrayContaining([
expect.objectContaining({ type: "synthetic", text: expect.stringContaining("Called the Read tool") }),
expect.objectContaining({ type: "synthetic", text: "note content" }),
]),
)
}),
)
const msgs = yield* MessageV2.filterCompactedEffect(chat.id)
const taskMsg = msgs.find((item) => item.info.role === "assistant" && item.info.agent === "general")
expect(taskMsg?.info.role).toBe("assistant")
if (!taskMsg || taskMsg.info.role !== "assistant") return
it.instance("static loop returns assistant text through local provider", () =>
Effect.gen(function* () {
const { llm } = yield* useServerConfig(providerCfg)
const prompt = yield* SessionPrompt.Service
const sessions = yield* Session.Service
const session = yield* sessions.create({
title: "Prompt provider",
permission: [{ permission: "*", pattern: "*", action: "allow" }],
})
const tool = errorTool(taskMsg.parts)
if (!tool) return
yield* prompt.prompt({
sessionID: session.id,
agent: "build",
noReply: true,
parts: [{ type: "text", text: "hello" }],
})
expect(tool.state.error).toContain("Tool execution failed")
expect(tool.state.metadata).toBeDefined()
expect(tool.state.metadata?.sessionId).toBeDefined()
expect(tool.state.metadata?.model).toEqual({
providerID: ProviderID.make("test"),
modelID: ModelID.make("missing-model"),
})
}),
{ git: true },
yield* llm.text("world")
const result = yield* prompt.loop({ sessionID: session.id })
expect(result.info.role).toBe("assistant")
expect(result.parts.some((part) => part.type === "text" && part.text === "world")).toBe(true)
expect(yield* llm.hits).toHaveLength(1)
expect(yield* llm.pending).toBe(0)
}),
)
it.instance("static loop consumes queued replies across turns", () =>
Effect.gen(function* () {
const { llm } = yield* useServerConfig(providerCfg)
const prompt = yield* SessionPrompt.Service
const sessions = yield* Session.Service
const session = yield* sessions.create({
title: "Prompt provider turns",
permission: [{ permission: "*", pattern: "*", action: "allow" }],
})
yield* prompt.prompt({
sessionID: session.id,
agent: "build",
noReply: true,
parts: [{ type: "text", text: "hello one" }],
})
yield* llm.text("world one")
const first = yield* prompt.loop({ sessionID: session.id })
expect(first.info.role).toBe("assistant")
expect(first.parts.some((part) => part.type === "text" && part.text === "world one")).toBe(true)
yield* prompt.prompt({
sessionID: session.id,
agent: "build",
noReply: true,
parts: [{ type: "text", text: "hello two" }],
})
yield* llm.text("world two")
const second = yield* prompt.loop({ sessionID: session.id })
expect(second.info.role).toBe("assistant")
expect(second.parts.some((part) => part.type === "text" && part.text === "world two")).toBe(true)
expect(yield* llm.hits).toHaveLength(2)
expect(yield* llm.pending).toBe(0)
}),
)
it.instance("loop continues when finish is tool-calls", () =>
Effect.gen(function* () {
const { llm } = yield* useServerConfig(providerCfg)
const prompt = yield* SessionPrompt.Service
const sessions = yield* Session.Service
const session = yield* sessions.create({
title: "Pinned",
permission: [{ permission: "*", pattern: "*", action: "allow" }],
})
yield* prompt.prompt({
sessionID: session.id,
agent: "build",
noReply: true,
parts: [{ type: "text", text: "hello" }],
})
yield* llm.tool("first", { value: "first" })
yield* llm.text("second")
const result = yield* prompt.loop({ sessionID: session.id })
expect(yield* llm.calls).toBe(2)
expect(result.info.role).toBe("assistant")
if (result.info.role === "assistant") {
expect(result.parts.some((part) => part.type === "text" && part.text === "second")).toBe(true)
expect(result.info.finish).toBe("stop")
}
}),
)
it.instance("glob tool keeps instance context during prompt runs", () =>
Effect.gen(function* () {
const { dir, llm } = yield* useServerConfig(providerCfg)
const prompt = yield* SessionPrompt.Service
const sessions = yield* Session.Service
const session = yield* sessions.create({
title: "Glob context",
permission: [{ permission: "*", pattern: "*", action: "allow" }],
})
const file = path.join(dir, "probe.txt")
yield* writeText(file, "probe")
yield* prompt.prompt({
sessionID: session.id,
agent: "build",
noReply: true,
parts: [{ type: "text", text: "find text files" }],
})
yield* llm.tool("glob", { pattern: "**/*.txt" })
yield* llm.text("done")
const result = yield* prompt.loop({ sessionID: session.id })
expect(result.info.role).toBe("assistant")
const msgs = yield* MessageV2.filterCompactedEffect(session.id)
const tool = msgs
.flatMap((msg) => msg.parts)
.find(
(part): part is CompletedToolPart =>
part.type === "tool" && part.tool === "glob" && part.state.status === "completed",
)
if (!tool) return
expect(tool.state.output).toContain(file)
expect(tool.state.output).not.toContain("No context found for instance")
expect(result.parts.some((part) => part.type === "text" && part.text === "done")).toBe(true)
}),
)
it.instance("loop continues when finish is stop but assistant has tool parts", () =>
Effect.gen(function* () {
const { llm } = yield* useServerConfig(providerCfg)
const prompt = yield* SessionPrompt.Service
const sessions = yield* Session.Service
const session = yield* sessions.create({
title: "Pinned",
permission: [{ permission: "*", pattern: "*", action: "allow" }],
})
yield* prompt.prompt({
sessionID: session.id,
agent: "build",
noReply: true,
parts: [{ type: "text", text: "hello" }],
})
yield* llm.push(reply().tool("first", { value: "first" }).stop())
yield* llm.text("second")
const result = yield* prompt.loop({ sessionID: session.id })
expect(yield* llm.calls).toBe(2)
expect(result.info.role).toBe("assistant")
if (result.info.role === "assistant") {
expect(result.parts.some((part) => part.type === "text" && part.text === "second")).toBe(true)
expect(result.info.finish).toBe("stop")
}
}),
)
it.instance("failed subtask preserves metadata on error tool state", () =>
Effect.gen(function* () {
const { llm } = yield* useServerConfig((url) => ({
...providerCfg(url),
agent: {
general: {
model: "test/missing-model",
},
},
}))
const prompt = yield* SessionPrompt.Service
const sessions = yield* Session.Service
const chat = yield* sessions.create({ title: "Pinned" })
yield* llm.tool("task", {
description: "inspect bug",
prompt: "look into the cache key path",
subagent_type: "general",
})
yield* llm.text("done")
const msg = yield* user(chat.id, "hello")
yield* addSubtask(chat.id, msg.id)
const result = yield* prompt.loop({ sessionID: chat.id })
expect(result.info.role).toBe("assistant")
expect(yield* llm.calls).toBe(2)
const msgs = yield* MessageV2.filterCompactedEffect(chat.id)
const taskMsg = msgs.find((item) => item.info.role === "assistant" && item.info.agent === "general")
expect(taskMsg?.info.role).toBe("assistant")
if (!taskMsg || taskMsg.info.role !== "assistant") return
const tool = errorTool(taskMsg.parts)
if (!tool) return
expect(tool.state.error).toContain("Tool execution failed")
expect(tool.state.metadata).toBeDefined()
expect(tool.state.metadata?.sessionId).toBeDefined()
expect(tool.state.metadata?.model).toEqual({
providerID: ProviderID.make("test"),
modelID: ModelID.make("missing-model"),
})
}),
)
it.instance(
@@ -778,7 +751,6 @@ it.instance(
yield* prompt.cancel(chat.id)
yield* Fiber.await(fiber)
}),
{ git: true },
5_000,
)
@@ -823,7 +795,6 @@ it.instance(
yield* prompt.cancel(chat.id)
yield* Fiber.await(fiber)
}),
{ git: true },
10_000,
)
@@ -848,7 +819,6 @@ it.instance(
yield* Fiber.await(fiber)
expect((yield* status.get(chat.id)).type).toBe("idle")
}),
{ git: true },
3_000,
)
@@ -877,7 +847,6 @@ it.instance(
expect(exit.value.info.role).toBe("assistant")
}
}),
{ git: true },
3_000,
)
@@ -904,7 +873,6 @@ it.instance(
}
}
}),
{ git: true },
3_000,
)
@@ -994,7 +962,6 @@ race.instance(
expect(lastAssistant.info.parentID).toBe(lastUser?.info.id)
}
}),
{ git: true },
3_000,
)
@@ -1041,7 +1008,7 @@ it.instance(
expect(taskMsg.info.time.completed).toBeDefined()
expect(taskMsg.info.finish).toBeDefined()
}),
{ git: true, config: cfg },
{ config: cfg },
30_000,
)
@@ -1077,7 +1044,6 @@ it.instance(
expect((yield* status.get(chat.id)).type).toBe("idle")
expect((yield* status.get(childID)).type).toBe("idle")
}),
{ git: true },
10_000,
)
@@ -1111,22 +1077,19 @@ it.instance(
// Queue semantics
it.instance(
"concurrent loop callers get same result",
() =>
Effect.gen(function* () {
const { prompt, run, chat } = yield* boot()
yield* seed(chat.id, { finish: "stop" })
it.instance("concurrent loop callers get same result", () =>
Effect.gen(function* () {
const { prompt, run, chat } = yield* boot()
yield* seed(chat.id, { finish: "stop" })
const [a, b] = yield* Effect.all([prompt.loop({ sessionID: chat.id }), prompt.loop({ sessionID: chat.id })], {
concurrency: "unbounded",
})
const [a, b] = yield* Effect.all([prompt.loop({ sessionID: chat.id }), prompt.loop({ sessionID: chat.id })], {
concurrency: "unbounded",
})
expect(a.info.id).toBe(b.info.id)
expect(a.info.role).toBe("assistant")
yield* run.assertNotBusy(chat.id)
}),
{ git: true },
expect(a.info.id).toBe(b.info.id)
expect(a.info.role).toBe("assistant")
yield* run.assertNotBusy(chat.id)
}),
)
it.instance(
@@ -1147,7 +1110,6 @@ it.instance(
expect(a.info.id).toBe(b.info.id)
expect(a.info.role).toBe("assistant")
}),
{ git: true },
3_000,
)
@@ -1216,7 +1178,6 @@ it.instance(
expect(inputs).toHaveLength(2)
expect(JSON.stringify(inputs.at(-1)?.messages)).toContain("second")
}),
{ git: true },
3_000,
)
@@ -1246,22 +1207,18 @@ it.instance(
yield* prompt.cancel(chat.id)
yield* Fiber.await(fiber)
}),
{ git: true },
3_000,
)
it.instance(
"assertNotBusy succeeds when idle",
() =>
Effect.gen(function* () {
const run = yield* SessionRunState.Service
const sessions = yield* Session.Service
it.instance("assertNotBusy succeeds when idle", () =>
Effect.gen(function* () {
const run = yield* SessionRunState.Service
const sessions = yield* Session.Service
const chat = yield* sessions.create({})
const exit = yield* run.assertNotBusy(chat.id).pipe(Effect.exit)
expect(Exit.isSuccess(exit)).toBe(true)
}),
{ git: true },
const chat = yield* sessions.create({})
const exit = yield* run.assertNotBusy(chat.id).pipe(Effect.exit)
expect(Exit.isSuccess(exit)).toBe(true)
}),
)
// Shell semantics
@@ -1290,7 +1247,6 @@ it.instance(
yield* prompt.cancel(chat.id)
yield* Fiber.await(fiber)
}),
{ git: true },
3_000,
)
@@ -1315,7 +1271,7 @@ unix(
expect(tool.state.metadata.output).toContain("err")
yield* run.assertNotBusy(chat.id)
}),
{ git: true, config: cfg },
{ config: cfg },
)
unix(
@@ -1339,7 +1295,7 @@ unix(
expect(tool.state.metadata.output).toContain(dir)
yield* run.assertNotBusy(chat.id)
}),
{ git: true, config: cfg },
{ config: cfg },
)
unix(
@@ -1361,7 +1317,7 @@ unix(
expect(tool.state.output).toContain("configured")
}),
),
{ git: true, config: { ...cfg, shell: "bash" } },
{ config: { ...cfg, shell: "bash" } },
30_000,
)
@@ -1386,7 +1342,7 @@ unix(
expect(tool.state.metadata.output).toContain(parent)
yield* run.assertNotBusy(chat.id)
}),
{ git: true, config: cfg },
{ config: cfg },
)
unix(
@@ -1412,7 +1368,7 @@ unix(
expect(tool.state.metadata.output).toContain("README.md")
yield* run.assertNotBusy(chat.id)
}),
{ git: true, config: cfg },
{ config: cfg },
)
unix(
@@ -1434,7 +1390,7 @@ unix(
expect(tool.state.metadata.output).toContain("not found")
yield* run.assertNotBusy(chat.id)
}),
{ git: true, config: cfg },
{ config: cfg },
)
unix(
@@ -1462,7 +1418,7 @@ unix(
expect(Exit.isSuccess(exit)).toBe(true)
}),
),
{ git: true, config: cfg },
{ config: cfg },
30_000,
)
@@ -1572,7 +1528,6 @@ unix(
expect(JSON.stringify(inputs.at(-1)?.messages)).toContain("configured")
}),
),
{ git: true },
30_000,
)
@@ -1808,7 +1763,7 @@ it.instance(
const exit = yield* Fiber.await(fiber)
expect(Exit.isFailure(exit)).toBe(true)
}),
{ git: true, config: cfg },
{ config: cfg },
30_000,
)
@@ -1843,7 +1798,7 @@ it.instance(
const exit = yield* Fiber.await(fiber)
expect(Exit.isFailure(exit)).toBe(true)
}),
{ git: true, config: cfg },
{ config: cfg },
30_000,
)
@@ -1882,7 +1837,7 @@ it.instance(
yield* sessions.remove(session.id)
}),
{ git: true, config: cfg },
{ config: cfg },
)
it.instance(
@@ -1924,7 +1879,7 @@ it.instance(
yield* sessions.remove(session.id)
}),
{ git: true, config: cfg },
{ config: cfg },
)
it.instance(
@@ -1973,7 +1928,6 @@ it.instance(
expect(agents.map((agent) => agent.name)).toEqual(["build"])
}),
{
git: true,
config: {
...cfg,
reference: {
@@ -2013,7 +1967,6 @@ it.instance(
yield* sessions.remove(session.id)
}),
{
git: true,
config: {
...cfg,
reference: {
@@ -2079,7 +2032,6 @@ it.instance(
yield* sessions.remove(session.id)
}),
{
git: true,
config: {
...cfg,
reference: {
@@ -2128,31 +2080,28 @@ it.instance(
// Regression: empty assistant turn loop
it.instance(
"does not loop empty assistant turns for a simple reply",
() =>
Effect.gen(function* () {
const { llm } = yield* useServerConfig(providerCfg)
const prompt = yield* SessionPrompt.Service
const sessions = yield* Session.Service
const session = yield* sessions.create({ title: "Prompt regression" })
it.instance("does not loop empty assistant turns for a simple reply", () =>
Effect.gen(function* () {
const { llm } = yield* useServerConfig(providerCfg)
const prompt = yield* SessionPrompt.Service
const sessions = yield* Session.Service
const session = yield* sessions.create({ title: "Prompt regression" })
yield* llm.text("packages/opencode/src/session/processor.ts")
yield* llm.text("packages/opencode/src/session/processor.ts")
const result = yield* prompt.prompt({
sessionID: session.id,
agent: "build",
parts: [{ type: "text", text: "Where is SessionProcessor?" }],
})
const result = yield* prompt.prompt({
sessionID: session.id,
agent: "build",
parts: [{ type: "text", text: "Where is SessionProcessor?" }],
})
expect(result.info.role).toBe("assistant")
expect(result.parts.some((part) => part.type === "text" && part.text.includes("processor.ts"))).toBe(true)
expect(result.info.role).toBe("assistant")
expect(result.parts.some((part) => part.type === "text" && part.text.includes("processor.ts"))).toBe(true)
const msgs = yield* sessions.messages({ sessionID: session.id })
expect(msgs.filter((msg) => msg.info.role === "assistant")).toHaveLength(1)
expect(yield* llm.calls).toBe(1)
}),
{ git: true },
const msgs = yield* sessions.messages({ sessionID: session.id })
expect(msgs.filter((msg) => msg.info.role === "assistant")).toHaveLength(1)
expect(yield* llm.calls).toBe(1)
}),
)
it.instance(
@@ -2193,7 +2142,6 @@ it.instance(
expect(last.info.error?.name).toBe("MessageAbortedError")
}
}),
{ git: true },
3_000,
)
@@ -2244,7 +2192,6 @@ it.instance(
yield* sessions.remove(session.id)
}),
{
git: true,
config: {
...cfg,
provider: {
@@ -2297,7 +2244,6 @@ it.instance(
}
}
}),
{ git: true },
30_000,
)
@@ -2326,7 +2272,6 @@ it.instance(
}
}
}),
{ git: true },
30_000,
)
@@ -2356,6 +2301,5 @@ it.instance(
}
}
}),
{ git: true },
30_000,
)