Merge branch 'main' into fix/issue-2954-image-maxbytes-config
This commit is contained in:
commit
f212d1bc8c
@ -69,6 +69,7 @@ Status: unreleased.
|
||||
- **BREAKING:** Gateway auth mode "none" is removed; gateway now requires token/password (Tailscale Serve identity still allowed).
|
||||
|
||||
### Fixes
|
||||
- Agents: inherit provider baseUrl/api for inline models. (#2740) Thanks @lploc94.
|
||||
- Memory Search: keep auto provider model defaults and only include remote when configured. (#2576) Thanks @papago2355.
|
||||
- macOS: auto-scroll to bottom when sending a new message while scrolled up. (#2471) Thanks @kennyklee.
|
||||
- Web UI: auto-expand the chat compose textarea while typing (with sensible max height). (#2950) Thanks @shivamraut101.
|
||||
|
||||
@ -1,6 +1,12 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
|
||||
import { buildInlineProviderModels } from "./model.js";
|
||||
vi.mock("@mariozechner/pi-coding-agent", () => ({
|
||||
discoverAuthStorage: vi.fn(() => ({ mocked: true })),
|
||||
discoverModels: vi.fn(() => ({ find: vi.fn(() => null) })),
|
||||
}));
|
||||
|
||||
import type { MoltbotConfig } from "../../config/config.js";
|
||||
import { buildInlineProviderModels, resolveModel } from "./model.js";
|
||||
|
||||
const makeModel = (id: string) => ({
|
||||
id,
|
||||
@ -15,15 +21,110 @@ const makeModel = (id: string) => ({
|
||||
describe("buildInlineProviderModels", () => {
|
||||
it("attaches provider ids to inline models", () => {
|
||||
const providers = {
|
||||
" alpha ": { models: [makeModel("alpha-model")] },
|
||||
beta: { models: [makeModel("beta-model")] },
|
||||
" alpha ": { baseUrl: "http://alpha.local", models: [makeModel("alpha-model")] },
|
||||
beta: { baseUrl: "http://beta.local", models: [makeModel("beta-model")] },
|
||||
};
|
||||
|
||||
const result = buildInlineProviderModels(providers);
|
||||
|
||||
expect(result).toEqual([
|
||||
{ ...makeModel("alpha-model"), provider: "alpha" },
|
||||
{ ...makeModel("beta-model"), provider: "beta" },
|
||||
{
|
||||
...makeModel("alpha-model"),
|
||||
provider: "alpha",
|
||||
baseUrl: "http://alpha.local",
|
||||
api: undefined,
|
||||
},
|
||||
{
|
||||
...makeModel("beta-model"),
|
||||
provider: "beta",
|
||||
baseUrl: "http://beta.local",
|
||||
api: undefined,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it("inherits baseUrl from provider when model does not specify it", () => {
|
||||
const providers = {
|
||||
custom: {
|
||||
baseUrl: "http://localhost:8000",
|
||||
models: [makeModel("custom-model")],
|
||||
},
|
||||
};
|
||||
|
||||
const result = buildInlineProviderModels(providers);
|
||||
|
||||
expect(result).toHaveLength(1);
|
||||
expect(result[0].baseUrl).toBe("http://localhost:8000");
|
||||
});
|
||||
|
||||
it("inherits api from provider when model does not specify it", () => {
|
||||
const providers = {
|
||||
custom: {
|
||||
baseUrl: "http://localhost:8000",
|
||||
api: "anthropic-messages",
|
||||
models: [makeModel("custom-model")],
|
||||
},
|
||||
};
|
||||
|
||||
const result = buildInlineProviderModels(providers);
|
||||
|
||||
expect(result).toHaveLength(1);
|
||||
expect(result[0].api).toBe("anthropic-messages");
|
||||
});
|
||||
|
||||
it("model-level api takes precedence over provider-level api", () => {
|
||||
const providers = {
|
||||
custom: {
|
||||
baseUrl: "http://localhost:8000",
|
||||
api: "openai-responses",
|
||||
models: [{ ...makeModel("custom-model"), api: "anthropic-messages" as const }],
|
||||
},
|
||||
};
|
||||
|
||||
const result = buildInlineProviderModels(providers);
|
||||
|
||||
expect(result).toHaveLength(1);
|
||||
expect(result[0].api).toBe("anthropic-messages");
|
||||
});
|
||||
|
||||
it("inherits both baseUrl and api from provider config", () => {
|
||||
const providers = {
|
||||
custom: {
|
||||
baseUrl: "http://localhost:10000",
|
||||
api: "anthropic-messages",
|
||||
models: [makeModel("claude-opus-4.5")],
|
||||
},
|
||||
};
|
||||
|
||||
const result = buildInlineProviderModels(providers);
|
||||
|
||||
expect(result).toHaveLength(1);
|
||||
expect(result[0]).toMatchObject({
|
||||
provider: "custom",
|
||||
baseUrl: "http://localhost:10000",
|
||||
api: "anthropic-messages",
|
||||
name: "claude-opus-4.5",
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("resolveModel", () => {
|
||||
it("includes provider baseUrl in fallback model", () => {
|
||||
const cfg = {
|
||||
models: {
|
||||
providers: {
|
||||
custom: {
|
||||
baseUrl: "http://localhost:9000",
|
||||
models: [],
|
||||
},
|
||||
},
|
||||
},
|
||||
} as MoltbotConfig;
|
||||
|
||||
const result = resolveModel("custom", "missing-model", "/tmp/agent", cfg);
|
||||
|
||||
expect(result.model?.baseUrl).toBe("http://localhost:9000");
|
||||
expect(result.model?.provider).toBe("custom");
|
||||
expect(result.model?.id).toBe("missing-model");
|
||||
});
|
||||
});
|
||||
|
||||
@ -8,15 +8,25 @@ import { DEFAULT_CONTEXT_TOKENS } from "../defaults.js";
|
||||
import { normalizeModelCompat } from "../model-compat.js";
|
||||
import { normalizeProviderId } from "../model-selection.js";
|
||||
|
||||
type InlineModelEntry = ModelDefinitionConfig & { provider: string };
|
||||
type InlineModelEntry = ModelDefinitionConfig & { provider: string; baseUrl?: string };
|
||||
type InlineProviderConfig = {
|
||||
baseUrl?: string;
|
||||
api?: ModelDefinitionConfig["api"];
|
||||
models?: ModelDefinitionConfig[];
|
||||
};
|
||||
|
||||
export function buildInlineProviderModels(
|
||||
providers: Record<string, { models?: ModelDefinitionConfig[] }>,
|
||||
providers: Record<string, InlineProviderConfig>,
|
||||
): InlineModelEntry[] {
|
||||
return Object.entries(providers).flatMap(([providerId, entry]) => {
|
||||
const trimmed = providerId.trim();
|
||||
if (!trimmed) return [];
|
||||
return (entry?.models ?? []).map((model) => ({ ...model, provider: trimmed }));
|
||||
return (entry?.models ?? []).map((model) => ({
|
||||
...model,
|
||||
provider: trimmed,
|
||||
baseUrl: entry?.baseUrl,
|
||||
api: model.api ?? entry?.api,
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
@ -72,6 +82,7 @@ export function resolveModel(
|
||||
name: modelId,
|
||||
api: providerCfg?.api ?? "openai-responses",
|
||||
provider,
|
||||
baseUrl: providerCfg?.baseUrl,
|
||||
reasoning: false,
|
||||
input: ["text"],
|
||||
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
||||
|
||||
Loading…
Reference in New Issue
Block a user