| 273 |
274
|
|
}),
|
| 274 |
275
|
|
);
|
| 275 |
276
|
|
|
| 276 |
|
- |
const configured = new OxAlphaReplySource({
|
|
277
|
+ |
const configured = new ChatApiReplySource({
|
| 277 |
278
|
|
origin: "https://openagents.test",
|
| 278 |
279
|
|
token: "test-token",
|
| 279 |
280
|
|
reasoning: "high",
|
| 280 |
281
|
|
});
|
| 281 |
282
|
|
await collect(configured, "do the thing");
|
| 282 |
283
|
|
|
| 283 |
|
- |
expect(seen[0]).toEqual({ message: "do the thing", reasoning: "high" });
|
|
284
|
+ |
expect(seen[0]).toEqual({
|
|
285
|
+ |
message: "do the thing",
|
|
286
|
+ |
model: defaultBackend().id,
|
|
287
|
+ |
reasoning: "high",
|
|
288
|
+ |
});
|
|
289
|
+ |
});
|
|
290
|
+ |
|
|
291
|
+ |
it("reports the label of the backend it is set to", () => {
|
|
292
|
+ |
expect(source().model).toBe(defaultBackend().label);
|
|
293
|
+ |
expect(source().backendId).toBe(defaultBackend().id);
|
|
294
|
+ |
});
|
|
295
|
+ |
|
|
296
|
+ |
it("sends the backend it was constructed with", async () => {
|
|
297
|
+ |
const seen: Array<Record<string, unknown>> = [];
|
|
298
|
+ |
let page = 0;
|
|
299
|
+ |
vi.stubGlobal(
|
|
300
|
+ |
"fetch",
|
|
301
|
+ |
vi.fn((url: URL, init?: RequestInit) => {
|
|
302
|
+ |
if (url.pathname.endsWith("/chat/turns")) {
|
|
303
|
+ |
seen.push(JSON.parse(String(init?.body)) as Record<string, unknown>);
|
|
304
|
+ |
return Promise.resolve(json(202, { turn: { id: "run-1" } }));
|
|
305
|
+ |
}
|
|
306
|
+ |
// The source snapshots the log before it submits, so the first read
|
|
307
|
+ |
// has to predate the turn or it counts the reply as already seen.
|
|
308
|
+ |
const events =
|
|
309
|
+ |
page++ === 0
|
|
310
|
+ |
? []
|
|
311
|
+ |
: [
|
|
312
|
+ |
{ run_id: "run-1", sequence: 1, type: "text_delta", payload: { value: "hi" } },
|
|
313
|
+ |
{ run_id: "run-1", sequence: 2, type: "response_completed", payload: {} },
|
|
314
|
+ |
];
|
|
315
|
+ |
return Promise.resolve(json(200, { events }));
|
|
316
|
+ |
}),
|
|
317
|
+ |
);
|
|
318
|
+ |
|
|
319
|
+ |
const gemini = new ChatApiReplySource({
|
|
320
|
+ |
origin: "https://openagents.test",
|
|
321
|
+ |
token: "test-token",
|
|
322
|
+ |
backend: findBackend("gemini-3.7-flash"),
|
|
323
|
+ |
});
|
|
324
|
+ |
|
|
325
|
+ |
expect(gemini.model).toBe("Gemini 3.7 Flash");
|
|
326
|
+ |
expect(await collect(gemini, "hello")).toBe("hi");
|
|
327
|
+ |
expect(seen[0]?.["model"]).toBe("gemini-3.7-flash");
|
| 284 |
328
|
|
});
|
| 285 |
329
|
|
|
| 286 |
|
- |
it("reports the model it runs on", () => {
|
| 287 |
|
- |
expect(source().model).toBe("stealth/ox-alpha");
|
|
330
|
+ |
it("cycles through every backend and wraps back to the first", () => {
|
|
331
|
+ |
const cycling = source();
|
|
332
|
+ |
const labels = CODER_BACKENDS.map(() => cycling.cycleBackend());
|
|
333
|
+ |
|
|
334
|
+ |
// Every backend is reachable, and the last cycle returns to the start, so
|
|
335
|
+ |
// a third entry needs no second key.
|
|
336
|
+ |
expect(new Set(labels).size).toBe(CODER_BACKENDS.length);
|
|
337
|
+ |
expect(cycling.model).toBe(defaultBackend().label);
|
| 288 |
338
|
|
});
|
| 289 |
339
|
|
|
| 290 |
340
|
|
it("says that its turns land in the account's one shared conversation", () => {
|