Task Summary
sendMessage is the largest untested region in the whole service: lines 475–712 of
texera-agent.ts, 238 of the file's 292 uncovered lines. The existing 26-test spec stops at the
model boundary and never enters it, which leaves the ReAct loop, its usage accounting, its branch
bookkeeping, and every one of its failure paths unexercised.
None of that needs the network. ai@7.0.48 ships MockLanguageModelV4 from the ai/test export,
and it satisfies the same LanguageModel type TexeraAgentConfig already accepts — so the loop can
be driven in-process, with fetch spied on as a tripwire to prove no call escapes.
Five traps are worth writing down, because each one produces a test that passes while asserting
nothing:
LanguageModelV4Usage is nested. A flat { inputTokens: 11 } is silently discarded and
every usage assertion then passes against a gutted mapping.
LanguageModelV4FinishReason is an object ({ unified, raw }), not a string. A bare
finishReason: "stop" runs fine under bun test and fails tsc --noEmit.
- A tool call's
input must be a JSON string, not an object.
- Setting a delegate config makes the first turn refresh from the backend, and that refresh
replaces the whole workflow — operators seeded directly on the agent are wiped, so they have to
arrive through the fetch stub.
maxSteps: 0 is an infinite loop. stepCountIs(0) never fires. Do not write that test; it
hangs the suite rather than failing it.
Only getStepsById (line 261) would remain uncovered, and it has no call site anywhere in the repo.
Task Type
Task Summary
sendMessageis the largest untested region in the whole service: lines 475–712 oftexera-agent.ts, 238 of the file's 292 uncovered lines. The existing 26-test spec stops at themodel boundary and never enters it, which leaves the ReAct loop, its usage accounting, its branch
bookkeeping, and every one of its failure paths unexercised.
None of that needs the network.
ai@7.0.48shipsMockLanguageModelV4from theai/testexport,and it satisfies the same
LanguageModeltypeTexeraAgentConfigalready accepts — so the loop canbe driven in-process, with
fetchspied on as a tripwire to prove no call escapes.Five traps are worth writing down, because each one produces a test that passes while asserting
nothing:
LanguageModelV4Usageis nested. A flat{ inputTokens: 11 }is silently discarded andevery usage assertion then passes against a gutted mapping.
LanguageModelV4FinishReasonis an object ({ unified, raw }), not a string. A barefinishReason: "stop"runs fine underbun testand failstsc --noEmit.inputmust be a JSON string, not an object.replaces the whole workflow — operators seeded directly on the agent are wiped, so they have to
arrive through the
fetchstub.maxSteps: 0is an infinite loop.stepCountIs(0)never fires. Do not write that test; ithangs the suite rather than failing it.
Only
getStepsById(line 261) would remain uncovered, and it has no call site anywhere in the repo.Task Type