AkurAI Build
Menu

popagent

public

Latest change 2e130a8a1e2fe03c4f67c554cd717c335dca3d71 - Add provider-agnostic guard trimming a dangling assistant tail before the wire by AkurAI Build

import { describe, expect, test } from "bun:test";
import { agentRuntimeSettings } from "./agent-runtime-settings";
import { createLocalModelFetch, FREE_MODEL_ROUTE, LOCAL_MODEL_ROUTE, listModelCatalog, normalizeChatRequest, runtimeModelId, resolveModel, trimDanglingAssistantWireTail } from "./models";

describe("resolveModel", () => {
  test("requires an explicit model id", () => {
    expect(resolveModel("test/model").modelId).toBe("test/model");
  });

  test("resolves an explicit model id", () => {
    expect(resolveModel("cc/claude-sonnet-5").modelId).toBe("cc/claude-sonnet-5");
  });

  test("maps persisted runtime sources to the local and free routes", () => {
    expect(runtimeModelId("ignored/model", "local")).toBe(LOCAL_MODEL_ROUTE);
    expect(runtimeModelId("ignored/model", "openrouter-free")).toBe(FREE_MODEL_ROUTE);
    expect(runtimeModelId("configured/model", "configured")).toBe("configured/model");
  });
});

describe("normalizeChatRequest", () => {
  test("merges leading system messages for the local Ornith chat template", () => {
    const body = {
      model: "titan/ornith-1.0-9b-mtp-q4_k_m",
      messages: [
        { role: "system", content: "Agent instructions" },
        { role: "system", content: "Workspace instructions" },
        { role: "user", content: "hi" },
      ],
    };

    expect(normalizeChatRequest(body)).toEqual({
      model: "titan/ornith-1.0-9b-mtp-q4_k_m",
      messages: [
        { role: "system", content: "Agent instructions\n\nWorkspace instructions" },
        { role: "user", content: "hi" },
      ],
    });
  });

  test("preserves multi-system requests for compatible models", () => {
    const body = { model: "cx/gpt-5.6-sol", messages: [
      { role: "system", content: "One" },
      { role: "system", content: "Two" },
    ] };
    expect(normalizeChatRequest(body)).toBe(body);
  });

  test("preserves a request that already ends on a non-assistant message", () => {
    const body = { model: "no-think/cc/claude-sonnet-5", messages: [
      { role: "user", content: "Report status" },
      { role: "assistant", content: null, tool_calls: [{ id: "call-1", type: "function", function: { name: "read", arguments: "{}" } }] },
      { role: "tool", tool_call_id: "call-1", content: "ok" },
    ] };
    expect(normalizeChatRequest(body)).toBe(body);
  });
});

describe("trimDanglingAssistantWireTail", () => {
  test("drops a trailing assistant message with unresolved tool calls", () => {
    const body = { model: "no-think/cc/claude-sonnet-5", messages: [
      { role: "user", content: "Report status" },
      { role: "assistant", content: "Working on it" },
      { role: "assistant", content: null, tool_calls: [{ id: "call-1", type: "function", function: { name: "read", arguments: "{}" } }] },
    ] };
    expect(trimDanglingAssistantWireTail(body)).toEqual({
      model: "no-think/cc/claude-sonnet-5",
      messages: [{ role: "user", content: "Report status" }],
    });
  });

  test("returns the same request when it already ends on a non-assistant message", () => {
    const body = { model: "any/model", messages: [
      { role: "user", content: "Hi" },
      { role: "assistant", content: "Hello" },
      { role: "user", content: "Continue" },
    ] };
    expect(trimDanglingAssistantWireTail(body)).toBe(body);
  });

  test("ignores requests without a messages array", () => {
    const body = { model: "any/model" };
    expect(trimDanglingAssistantWireTail(body)).toBe(body);
  });
});

describe("createLocalModelFetch", () => {
  test("queues local streams FIFO and removes aborted waiters", async () => {
    const gates = [
      Promise.withResolvers<void>(),
      Promise.withResolvers<void>(),
      Promise.withResolvers<void>(),
    ];
    const firstPairStarted = Promise.withResolvers<void>();
    const thirdStarted = Promise.withResolvers<void>();
    const started: string[] = [];
    let active = 0;
    let peak = 0;
    const upstream = (async (_input: RequestInfo | URL, init?: RequestInit) => {
      const body = JSON.parse(String(init?.body)) as { messages: Array<{ content: string }> };
      const label = body.messages[0]!.content;
      const gate = gates[started.length]!;
      started.push(label);
      active++;
      peak = Math.max(peak, active);
      if (started.length === 2) firstPairStarted.resolve();
      if (started.length === 3) thirdStarted.resolve();
      return new Response(new ReadableStream({
        async pull(controller) {
          await gate.promise;
          active--;
          controller.enqueue(new TextEncoder().encode(label));
          controller.close();
        },
      }));
    }) as typeof fetch;
    const queuedFetch = createLocalModelFetch(upstream, 2);
    const run = (label: string, signal?: AbortSignal) => queuedFetch("http://router/v1/chat/completions", {
      method: "POST",
      signal,
      body: JSON.stringify({
        model: LOCAL_MODEL_ROUTE,
        messages: [{ role: "user", content: label }],
      }),
    }).then((response) => response.text());

    const first = run("first");
    const second = run("second");
    const aborted = new AbortController();
    const cancelled = run("cancelled", aborted.signal);
    const third = run("third");
    await firstPairStarted.promise;
    expect(started).toEqual(["first", "second"]);
    expect(peak).toBe(2);

    aborted.abort();
    await expect(cancelled).rejects.toBeInstanceOf(DOMException);
    gates[0]!.resolve();
    expect(await first).toBe("first");
    await thirdStarted.promise;
    expect(started).toEqual(["first", "second", "third"]);
    expect(peak).toBe(2);

    gates[1]!.resolve();
    gates[2]!.resolve();
    expect(await Promise.all([second, third])).toEqual(["second", "third"]);
  });
});

describe("listModelCatalog", () => {
  test("returns context windows for the configured default model", async () => {
    const configured = await agentRuntimeSettings.get();
    const catalog = await listModelCatalog();
    expect(catalog.models).toContain(configured.defaultModel);
    expect(catalog.contextWindows[configured.defaultModel]).toBeGreaterThan(0);
    expect(catalog.models).toEqual([...new Set(catalog.models)]);
  });
});