feat: make ollama host configurable in goose2 (#8912)
This commit is contained in:
@@ -122,6 +122,10 @@ fn apply_ollama_options(payload: &mut Value, model_config: &ModelConfig) {
|
||||
}
|
||||
}
|
||||
|
||||
fn ollama_host_configured(config: &crate::config::Config) -> bool {
|
||||
config.get_param::<String>("OLLAMA_HOST").is_ok()
|
||||
}
|
||||
|
||||
impl OllamaProvider {
|
||||
pub async fn from_env(model: ModelConfig) -> Result<Self> {
|
||||
let config = crate::config::Config::global();
|
||||
@@ -262,6 +266,10 @@ impl ProviderDef for OllamaProvider {
|
||||
true
|
||||
}
|
||||
|
||||
fn inventory_configured() -> bool {
|
||||
ollama_host_configured(crate::config::Config::global())
|
||||
}
|
||||
|
||||
fn inventory_identity() -> Result<InventoryIdentityInput> {
|
||||
let config = crate::config::Config::global();
|
||||
Ok(
|
||||
@@ -465,6 +473,51 @@ fn stream_ollama(response: Response, mut log: RequestLog) -> Result<MessageStrea
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_ollama_host_default_does_not_mark_inventory_configured() {
|
||||
let _guard = env_lock::lock_env([("OLLAMA_HOST", None::<&str>)]);
|
||||
let config_file = tempfile::NamedTempFile::new().unwrap();
|
||||
let secrets_file = tempfile::NamedTempFile::new().unwrap();
|
||||
let config = crate::config::Config::new_with_config_paths(
|
||||
vec![config_file.path().to_path_buf()],
|
||||
secrets_file.path(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert!(!ollama_host_configured(&config));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ollama_host_env_marks_inventory_configured() {
|
||||
let _guard = env_lock::lock_env([("OLLAMA_HOST", Some("http://127.0.0.1:11435"))]);
|
||||
let config_file = tempfile::NamedTempFile::new().unwrap();
|
||||
let secrets_file = tempfile::NamedTempFile::new().unwrap();
|
||||
let config = crate::config::Config::new_with_config_paths(
|
||||
vec![config_file.path().to_path_buf()],
|
||||
secrets_file.path(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert!(ollama_host_configured(&config));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ollama_host_config_marks_inventory_configured() {
|
||||
let _guard = env_lock::lock_env([("OLLAMA_HOST", None::<&str>)]);
|
||||
let config_file = tempfile::NamedTempFile::new().unwrap();
|
||||
let secrets_file = tempfile::NamedTempFile::new().unwrap();
|
||||
let config = crate::config::Config::new_with_config_paths(
|
||||
vec![config_file.path().to_path_buf()],
|
||||
secrets_file.path(),
|
||||
)
|
||||
.unwrap();
|
||||
config
|
||||
.set_param("OLLAMA_HOST", "http://127.0.0.1:11435")
|
||||
.unwrap();
|
||||
|
||||
assert!(ollama_host_configured(&config));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_apply_ollama_options_uses_input_limit() {
|
||||
let _guard = env_lock::lock_env([("GOOSE_INPUT_LIMIT", Some("8192"))]);
|
||||
|
||||
@@ -1,5 +1,26 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { resolveAgentProviderCatalogId } from "./providerCatalog";
|
||||
import {
|
||||
getCatalogEntry,
|
||||
resolveAgentProviderCatalogId,
|
||||
} from "./providerCatalog";
|
||||
|
||||
describe("provider catalog", () => {
|
||||
it("exposes Ollama host configuration", () => {
|
||||
const ollama = getCatalogEntry("ollama");
|
||||
|
||||
expect(ollama?.setupMethod).toBe("config_fields");
|
||||
expect(ollama?.fields).toEqual([
|
||||
{
|
||||
key: "OLLAMA_HOST",
|
||||
label: "Host",
|
||||
secret: false,
|
||||
required: true,
|
||||
placeholder: "localhost or http://localhost:11434",
|
||||
defaultValue: "http://localhost:11434",
|
||||
},
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("resolveAgentProviderCatalogId", () => {
|
||||
it("matches direct catalog ids", () => {
|
||||
|
||||
@@ -6,7 +6,6 @@ import {
|
||||
} from "./providerCatalogAliases";
|
||||
|
||||
export const PROVIDER_CATALOG: ProviderCatalogEntry[] = [
|
||||
// ── Agent providers ──────────────────────────────────────────────
|
||||
{
|
||||
id: "goose",
|
||||
displayName: "Goose",
|
||||
@@ -92,7 +91,6 @@ export const PROVIDER_CATALOG: ProviderCatalogEntry[] = [
|
||||
showOnlyWhenInstalled: true,
|
||||
},
|
||||
|
||||
// ── Model providers (power Goose) ────────────────────────────────
|
||||
{
|
||||
id: "anthropic",
|
||||
displayName: "Anthropic",
|
||||
@@ -164,8 +162,18 @@ export const PROVIDER_CATALOG: ProviderCatalogEntry[] = [
|
||||
id: "ollama",
|
||||
displayName: "Ollama",
|
||||
category: "model",
|
||||
description: "Run models locally",
|
||||
setupMethod: "local",
|
||||
description: "Run local or self-hosted models",
|
||||
setupMethod: "config_fields",
|
||||
fields: [
|
||||
{
|
||||
key: "OLLAMA_HOST",
|
||||
label: "Host",
|
||||
secret: false,
|
||||
required: true,
|
||||
placeholder: "localhost or http://localhost:11434",
|
||||
defaultValue: "http://localhost:11434",
|
||||
},
|
||||
],
|
||||
docsUrl: "https://ollama.com",
|
||||
tier: "promoted",
|
||||
},
|
||||
|
||||
@@ -73,6 +73,37 @@ describe("ModelProviderRow", () => {
|
||||
]);
|
||||
});
|
||||
|
||||
it("pre-fills and saves provider field defaults", async () => {
|
||||
const user = userEvent.setup();
|
||||
|
||||
render(
|
||||
<ModelProviderRow
|
||||
provider={modelProvider("ollama", "not_configured")}
|
||||
onGetConfig={onGetConfig}
|
||||
onSaveFields={onSaveFields}
|
||||
onRemoveConfig={onRemoveConfig}
|
||||
onCompleteNativeSetup={onCompleteNativeSetup}
|
||||
/>,
|
||||
);
|
||||
|
||||
await user.click(screen.getByRole("button", { name: /ollama/i }));
|
||||
|
||||
expect(
|
||||
await screen.findByDisplayValue("http://localhost:11434"),
|
||||
).toBeVisible();
|
||||
|
||||
await user.click(screen.getByRole("button", { name: /^save$/i }));
|
||||
|
||||
await waitFor(() => expect(onSaveFields).toHaveBeenCalledTimes(1));
|
||||
expect(onSaveFields).toHaveBeenCalledWith([
|
||||
{
|
||||
key: "OLLAMA_HOST",
|
||||
value: "http://localhost:11434",
|
||||
isSecret: false,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it("shows the connected row while model inventory is still loading", async () => {
|
||||
const user = userEvent.setup();
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ export function createDraftValues(
|
||||
if (field.secret) {
|
||||
return [field.key, ""];
|
||||
}
|
||||
return [field.key, currentValue?.value ?? ""];
|
||||
return [field.key, currentValue?.value ?? field.defaultValue ?? ""];
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ export interface ProviderField {
|
||||
secret: boolean;
|
||||
required: boolean;
|
||||
placeholder?: string;
|
||||
defaultValue?: string;
|
||||
}
|
||||
|
||||
export interface ProviderFieldValue {
|
||||
|
||||
Reference in New Issue
Block a user