Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion openbot/agent-ag2/tests/test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,12 +185,20 @@ def test_a_run_reaches_the_model_the_setup_screen_chose(monkeypatch, provider, c
assert seen == [expected]


def _anthropic_key(headers):
# anthropic 2.x sends the key as a Bearer token; older SDKs send x-api-key.
bearer = headers.get("authorization", "")
if bearer.startswith("Bearer "):
return bearer.removeprefix("Bearer ")
return headers.get("x-api-key")


def test_an_anthropic_key_uses_the_official_endpoint_when_compose_sets_a_blank_url(monkeypatch):
seen = []

async def respond(transport, request):
body = json.loads(request.content)
seen.append((str(request.url), request.headers.get("x-api-key"), body["model"]))
seen.append((str(request.url), _anthropic_key(request.headers), body["model"]))
return httpx2.Response(
200,
request=request,
Expand Down
29 changes: 24 additions & 5 deletions openbot/agent-langgraph-agui/tests/test_provider_boundaries.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import json
import os
import re
import shutil
import subprocess
import sys
Expand All @@ -12,6 +13,7 @@

import httpx2
import pytest
from anthropic import Anthropic

sys.path.insert(0, str(Path(__file__).resolve().parents[1]))

Expand Down Expand Up @@ -337,8 +339,14 @@ async def test_anthropic_selection_reaches_anthropic_boundary_without_openai_key
assert result["messages"][0].content == "anthropic proof"
assert "OPENAI_API_KEY" not in os.environ
assert captured[0]["url"] == "http://127.0.0.1:4311/v1/messages"
assert captured[0]["headers"]["x-api-key"] == "sk-ant-openbot-ci"
assert captured[0]["headers"]["anthropic-version"] == "2023-06-01"
# Anthropic 2.3 uses Bearer authentication; older SDKs send x-api-key.
headers = captured[0]["headers"]
assert (
headers.get("x-api-key") == "sk-ant-openbot-ci"
or headers.get("authorization") == "Bearer sk-ant-openbot-ci"
)
with Anthropic(api_key="sk-ant-openbot-ci") as sdk:
assert headers["anthropic-version"] == sdk.default_headers["anthropic-version"]
assert captured[0]["body"]["model"] == request_model
assert captured[0]["body"]["messages"] == [
{"role": "user", "content": "Say hello."}
Expand Down Expand Up @@ -469,6 +477,11 @@ async def test_openai_keeps_a_skill_turn_beside_the_message_it_was_picked_for(
]



def _without_api_version(path):
# google-genai 3.x calls the v1 API; older SDKs call v1beta.
return re.sub(r"^/v1(beta)?/", "/", path)

@pytest.mark.asyncio
@pytest.mark.parametrize(
("provider", "model"),
Expand Down Expand Up @@ -497,9 +510,12 @@ async def test_google_provider_reaches_google_genai_boundary(
)

assert result["messages"][0].content == "google loopback proof"
assert captured == [
assert [
{**request, "path": _without_api_version(request["path"])}
for request in captured
] == [
{
"path": "/v1beta/models/gemini-2.5-flash:generateContent",
"path": "/models/gemini-2.5-flash:generateContent",
"x_goog_api_key_present": True,
"body": {
"contents": [
Expand Down Expand Up @@ -545,7 +561,10 @@ async def test_google_spec_model_reaches_google_request(

assert result["messages"][0].content == "google loopback proof"
assert len(captured) == 1
assert captured[0]["path"] == "/v1beta/models/gemini-spec-model:generateContent"
assert (
_without_api_version(captured[0]["path"])
== "/models/gemini-spec-model:generateContent"
)


def _write_synthetic_chatgpt_store(path: Path):
Expand Down
10 changes: 9 additions & 1 deletion openbot/agent-microsoft/tests/test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,14 +182,22 @@ def test_a_run_reaches_the_model_the_setup_screen_chose(monkeypatch, provider, c
assert seen == [expected]


def _anthropic_key(headers):
# anthropic 2.x sends the key as a Bearer token; older SDKs send x-api-key.
bearer = headers.get("authorization", "")
if bearer.startswith("Bearer "):
return bearer.removeprefix("Bearer ")
return headers.get("x-api-key")


def test_an_anthropic_key_uses_the_official_endpoint_when_compose_sets_a_blank_url(monkeypatch):
seen = []
provider_seen = []
provider_app = _provider_app(provider_seen)

async def respond(transport, request):
seen.append(
(request.url.scheme, request.url.host, request.url.path, request.headers.get("x-api-key"))
(request.url.scheme, request.url.host, request.url.path, _anthropic_key(request.headers))
)
async with httpx2.ASGITransport(app=provider_app) as local_provider:
return await local_provider.handle_async_request(request)
Expand Down
6 changes: 5 additions & 1 deletion openbot/app/tests/self-host-banner.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { authKeys } from "@/lib/auth/queries";
import { deploymentKeys } from "@/lib/deployment/queries";
import { userPreferencesQueryOptions } from "@/lib/settings/message-list";
import type { UserPreferences } from "@openbot/shared/user-preferences";
import { settleReactWork } from "./settle-react-work";

const originalFetch = globalThis.fetch;
const clients: QueryClient[] = [];
Expand Down Expand Up @@ -50,7 +51,10 @@ afterEach(() => {
clients.length = 0;
globalThis.fetch = originalFetch;
});
afterAll(() => GlobalRegistrator.unregister());
afterAll(async () => {
await settleReactWork();
GlobalRegistrator.unregister();
});

const banner = { name: "Self-host OpenDuet" } as const;

Expand Down
9 changes: 4 additions & 5 deletions openbot/server/tests/channel-routes.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -722,12 +722,11 @@ describe("the first day's date", () => {
return { channel: channel(), claimed: true };
},
});
const response = await post(store, {
agentId: "agent-1",
date: "2026-10-26",
});
// The server drops a date more than a day from its own clock, so the date follows the clock.
const date = new Date().toISOString().slice(0, 10);
const response = await post(store, { agentId: "agent-1", date });
expect(response.status).toBe(200);
expect(calls).toEqual([[actor, "agent-1", undefined, "2026-10-26"]]);
expect(calls).toEqual([[actor, "agent-1", undefined, date]]);
});

/*
Expand Down
Loading