mirror of
https://github.com/hanzoai/mcp.git
synced 2026-10-15 12:30:12 +00:00
kai: the key goes to the configured API alone
The kai tool took kai_url from the call and sent HANZO_API_KEY to it, with the repository's file names, branches and commit subjects. A model, or text it read, could name any host. The URL is now HANZO_API_BASE (or api.hanzo.ai) plus /v1, in the Rust tool and the TypeScript one alike, and kai_url is gone from the schema.
This commit is contained in:
@@ -31,10 +31,6 @@
|
||||
"type": "boolean",
|
||||
"description": "Ask Kai when several actions or values remain (default true). false declines them instead."
|
||||
},
|
||||
"kai_url": {
|
||||
"type": "string",
|
||||
"description": "Decisions API base, default HANZO_API_BASE or https://api.hanzo.ai, plus /v1"
|
||||
},
|
||||
"model": {
|
||||
"type": "string",
|
||||
"description": "Decision model (default kai)"
|
||||
|
||||
@@ -81,7 +81,8 @@ fn call(api: &HanzoApi, action: &str, p: &Value) -> Result<Value, String> {
|
||||
_ => {
|
||||
let request = text(p, "request").ok_or("request required")?;
|
||||
let cwd = text(p, "cwd").map(PathBuf::from).or_else(|| std::env::current_dir().ok()).ok_or("cwd required")?;
|
||||
let url = text(p, "kai_url").map(str::to_string).unwrap_or_else(|| format!("{}/v1", api.base_url().trim_end_matches('/')));
|
||||
// The key goes to the configured API alone: a call never names where it is sent.
|
||||
let url = format!("{}/v1", api.base_url().trim_end_matches('/'));
|
||||
let kai = (p.get("ask").and_then(Value::as_bool) != Some(false)).then(|| Kai::new(&url, text(p, "model").unwrap_or("kai"), api.key().map(str::to_string)));
|
||||
let store = text(p, "cache").map(PathBuf::from).map(|d| Store::open(&d)).transpose()?;
|
||||
let mut cfg = Config::default();
|
||||
|
||||
@@ -31,10 +31,6 @@
|
||||
"type": "boolean",
|
||||
"description": "Ask Kai when several actions or values remain (default true). false declines them instead."
|
||||
},
|
||||
"kai_url": {
|
||||
"type": "string",
|
||||
"description": "Decisions API base, default HANZO_API_BASE or https://api.hanzo.ai, plus /v1"
|
||||
},
|
||||
"model": {
|
||||
"type": "string",
|
||||
"description": "Decision model (default kai)"
|
||||
|
||||
@@ -47,10 +47,6 @@ export const kaiActionSchema = {
|
||||
"type": "boolean",
|
||||
"description": "Ask Kai when several actions or values remain (default true). false declines them instead."
|
||||
},
|
||||
"kai_url": {
|
||||
"type": "string",
|
||||
"description": "Decisions API base, default HANZO_API_BASE or https://api.hanzo.ai, plus /v1"
|
||||
},
|
||||
"model": {
|
||||
"type": "string",
|
||||
"description": "Decision model (default kai)"
|
||||
@@ -92,7 +88,8 @@ export function argv(args: any): string[] {
|
||||
const out = ['kai', action, '--cwd', args.cwd || process.cwd(), '--request', String(args.request)];
|
||||
if (args.ask !== false) {
|
||||
const base = (process.env.HANZO_API_BASE || 'https://api.hanzo.ai').replace(/\/+$/, '');
|
||||
out.push('--kai', args.kai_url || `${base}/v1`, '--model', args.model || 'kai');
|
||||
// The key goes to the configured API alone: a call never names where it is sent.
|
||||
out.push('--kai', `${base}/v1`, '--model', args.model || 'kai');
|
||||
if (process.env.HANZO_API_KEY) out.push('--key-env', 'HANZO_API_KEY');
|
||||
}
|
||||
if (args.cache) out.push('--cache', args.cache);
|
||||
|
||||
@@ -30,9 +30,17 @@ describe('kai (Kai Actions)', () => {
|
||||
expect(argv({ cwd: '/w/ws', request: 'Run the tests', ask: false, approve: true, prove: true, cache: '/c', min_margin: 0.2 })).toEqual([...base, '--cache', '/c', '--approve', 'grant', '--prove', '--min-margin', '0.2']);
|
||||
expect(argv({ action: 'list' })).toEqual(['kai', 'list']);
|
||||
expect(argv({ action: 'triggers', request: 'x' })).toEqual(['kai', 'triggers', '--request', 'x']);
|
||||
const asking = argv({ cwd: '/w/ws', request: 'x', kai_url: 'http://127.0.0.1:18977/v1' });
|
||||
expect(asking).toContain('--kai');
|
||||
expect(asking[asking.indexOf('--kai') + 1]).toBe('http://127.0.0.1:18977/v1');
|
||||
const was = process.env.HANZO_API_BASE;
|
||||
process.env.HANZO_API_BASE = 'http://127.0.0.1:18977';
|
||||
try {
|
||||
const asking = argv({ cwd: '/w/ws', request: 'x', kai_url: 'https://evil.example/v1' });
|
||||
expect(asking).toContain('--kai');
|
||||
expect(asking[asking.indexOf('--kai') + 1]).toBe('http://127.0.0.1:18977/v1');
|
||||
expect(asking).not.toContain('https://evil.example/v1');
|
||||
} finally {
|
||||
if (was === undefined) delete process.env.HANZO_API_BASE;
|
||||
else process.env.HANZO_API_BASE = was;
|
||||
}
|
||||
});
|
||||
|
||||
test('the tool says so when there is no native runtime, and when a call is malformed', async () => {
|
||||
|
||||
Reference in New Issue
Block a user