fixture fix, untested
This commit is contained in:
1 parent
efe3e46973
commit
b285e581ea
2 files changed
+159
No files matched your search
@@ -0,0 +1,94 @@
|
||||
// P3: generate real harness config through buildBundle; credentials never enter disk artifacts.
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { mkdirSync, readFileSync, statSync } from 'node:fs';
|
||||
import { join } from 'node:path';
|
||||
import { buildBundle } from '../src/bundle.mjs';
|
||||
import { HARNESS, REPO_SKILLS, resolvedFor, scratch } from './helpers.mjs';
|
||||
|
||||
const models = {
|
||||
a: { provider: 'proxy', model: 'claude-fixture', route: 'anthropic' },
|
||||
z: { provider: 'proxy', model: 'glm-fixture', route: 'glm' },
|
||||
g: { provider: 'proxy', model: 'gpt-fixture', route: 'codex' },
|
||||
};
|
||||
function build(t, selection, proxy, declared = models) {
|
||||
const root = scratch(t, 'p332-'), runDir = join(root, 'run');
|
||||
mkdirSync(runDir, { mode: 0o700 });
|
||||
const resolved = resolvedFor(t, 'pm', doc => {
|
||||
doc.roles.pm.vars = { ...doc.roles.pm.vars, harness: 'pi', model: selection };
|
||||
});
|
||||
const bundle = buildBundle({
|
||||
dir: join(runDir, 'bundle'), resolved, models: declared,
|
||||
contract: '# Fixture\n', harness: HARNESS.pi, harnessVersion: 'fixture',
|
||||
skillsDir: REPO_SKILLS, proxy,
|
||||
session: { run: 'r332', launchedBy: 'chief', workspace: join(root, 'ws'),
|
||||
toolSocket: join(runDir, 'tools.sock'), turnMarker: join(runDir, 'turn.done') },
|
||||
});
|
||||
const file = join(runDir, 'home', '.pi', 'agent', 'models.json');
|
||||
return { ...bundle, file, runDir, text: readFileSync(file, 'utf8') };
|
||||
}
|
||||
function assertSafe(value) {
|
||||
if (typeof value === 'string') assert.ok(!value.startsWith('!'), value);
|
||||
else if (value && typeof value === 'object') for (const item of Object.values(value)) assertSafe(item);
|
||||
}
|
||||
|
||||
test('P3 Anthropic route uses messages at proxy root and the declared model id', t => {
|
||||
const b = build(t, 'a', { baseUrl: 'http://127.0.0.1:12345', key: 'fx332-agent-a' });
|
||||
const { anthropic } = JSON.parse(b.text).providers;
|
||||
assert.equal(anthropic.api, 'anthropic-messages');
|
||||
assert.equal(anthropic.baseUrl, 'http://127.0.0.1:12345');
|
||||
assert.deepEqual(anthropic.models.map(m => m.id), ['claude-fixture']);
|
||||
assert.equal(b.env.PI_PROVIDER, 'anthropic');
|
||||
assert.equal(b.env.PI_MODEL, 'claude-fixture');
|
||||
});
|
||||
|
||||
test('P3 GLM route uses completions at proxy /v1 with explicit z.ai compatibility', t => {
|
||||
const b = build(t, 'z', { baseUrl: 'http://127.0.0.1:12345', key: 'fx332-agent-a' });
|
||||
const glm = JSON.parse(b.text).providers['mosaic-proxy-glm'];
|
||||
assert.equal(glm.api, 'openai-completions');
|
||||
assert.equal(glm.baseUrl, 'http://127.0.0.1:12345/v1');
|
||||
assert.deepEqual(glm.models.map(m => m.id), ['glm-fixture']);
|
||||
assert.equal(glm.compat.thinkingFormat, 'zai');
|
||||
assert.equal(glm.compat.zaiToolStream, true);
|
||||
assert.equal(b.env.PI_PROVIDER, 'mosaic-proxy-glm');
|
||||
});
|
||||
|
||||
test('P3 GPT route selects a stack-owned provider instead of pi Codex OAuth', t => {
|
||||
const b = build(t, 'g', { baseUrl: 'http://127.0.0.1:12345', key: 'fx332-agent-a' });
|
||||
const providers = JSON.parse(b.text).providers;
|
||||
assert.equal(Object.hasOwn(providers, 'openai-codex'), false);
|
||||
const gpt = providers['mosaic-proxy-codex'];
|
||||
assert.equal(gpt.baseUrl, 'http://127.0.0.1:12345/v1');
|
||||
assert.deepEqual(gpt.models.map(m => m.id), ['gpt-fixture']);
|
||||
assert.equal(b.env.PI_PROVIDER, 'mosaic-proxy-codex');
|
||||
// Assert the one chosen API after the authorized pinned-binary probe, before this file first runs.
|
||||
});
|
||||
|
||||
test('P3 models file is private, references the one session key, and stores no executable values or keys', t => {
|
||||
const key = 'fx332-agent-a';
|
||||
const b = build(t, 'a', { baseUrl: 'http://127.0.0.1:12345', key });
|
||||
const document = JSON.parse(b.text);
|
||||
assert.deepEqual(Object.keys(document.providers).sort(), ['anthropic', 'mosaic-proxy-codex', 'mosaic-proxy-glm']);
|
||||
for (const provider of Object.values(document.providers)) assert.equal(provider.apiKey, '$ANTHROPIC_API_KEY');
|
||||
assertSafe(document);
|
||||
assert.ok(!b.text.includes(key));
|
||||
assert.equal(b.env.ANTHROPIC_API_KEY, key);
|
||||
assert.equal(statSync(b.file).mode & 0o777, 0o600);
|
||||
for (const dir of ['home', 'home/.pi', 'home/.pi/agent']) assert.equal(statSync(join(b.runDir, dir)).mode & 0o777, 0o700);
|
||||
for (const file of Object.values(b.files)) assert.ok(!readFileSync(file, 'utf8').includes(key), file);
|
||||
assert.ok(!JSON.stringify(b.manifest).includes(key));
|
||||
});
|
||||
|
||||
test('P3 every launch regenerates proxy port, declared models and own key without caching', t => {
|
||||
const first = build(t, 'a', { baseUrl: 'http://127.0.0.1:12345', key: 'fx332-agent-a' });
|
||||
const second = build(t, 'a', { baseUrl: 'http://127.0.0.1:23456', key: 'fx332-agent-b' }, {
|
||||
a: { provider: 'proxy', model: 'changed-model-id', route: 'anthropic' },
|
||||
});
|
||||
assert.equal(second.env.ANTHROPIC_API_KEY, 'fx332-agent-b');
|
||||
assert.ok(!JSON.stringify(second).includes('fx332-agent-a'));
|
||||
const { providers } = JSON.parse(second.text);
|
||||
assert.deepEqual(Object.keys(providers), ['anthropic']);
|
||||
assert.equal(providers.anthropic.baseUrl, 'http://127.0.0.1:23456');
|
||||
assert.deepEqual(providers.anthropic.models.map(m => m.id), ['changed-model-id']);
|
||||
assert.equal(JSON.parse(first.text).providers.anthropic.baseUrl, 'http://127.0.0.1:12345');
|
||||
});
|
||||
@@ -0,0 +1,65 @@
|
||||
// P3: run real harness exports through the plug-in loader, with made-up session keys only.
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { chmodSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs';
|
||||
import { tmpdir } from 'node:os';
|
||||
import { join } from 'node:path';
|
||||
import { createLoader } from '../src/loader.mjs';
|
||||
import { sessionEnv } from '../../seat/src/session.mjs';
|
||||
|
||||
async function harness(name) {
|
||||
const loader = createLoader({ log() {} });
|
||||
const result = await loader.load({ harness: [name] });
|
||||
assert.deepEqual(result.refused, []);
|
||||
return loader.modules('harness')[0];
|
||||
}
|
||||
function scratch(t) {
|
||||
const root = mkdtempSync(join(tmpdir(), 'p332-'));
|
||||
t.after(() => rmSync(root, { recursive: true, force: true }));
|
||||
return root;
|
||||
}
|
||||
const policy = { tools: [], typed: [] };
|
||||
const session = { model: 'claude-fixture', thinking: 'low' };
|
||||
|
||||
test('P3 Claude env receives the session proxy URL and key, without another agent or host credential', async () => {
|
||||
const claude = await harness('claude-code');
|
||||
const host = { CLAUDE_CODE_OAUTH_TOKEN: 'fx332-host', OPENAI_API_KEY: 'fx332-upstream' };
|
||||
for (const [run, key] of [['r332a', 'fx332-agent-a'], ['r332b', 'fx332-agent-b']]) {
|
||||
const proxy = { baseUrl: 'http://127.0.0.1:12345', key };
|
||||
const env = { ...sessionEnv(host, run, proxy), ...claude.env({ files: {}, policy, session, proxy }) };
|
||||
assert.equal(env.ANTHROPIC_BASE_URL, 'http://127.0.0.1:12345');
|
||||
assert.equal(env.ANTHROPIC_AUTH_TOKEN, key);
|
||||
assert.equal(Object.hasOwn(env, 'CLAUDE_CODE_OAUTH_TOKEN'), false);
|
||||
assert.equal(Object.hasOwn(env, 'OPENAI_API_KEY'), false);
|
||||
const other = run === 'r332a' ? 'fx332-agent-b' : 'fx332-agent-a';
|
||||
assert.ok(!Object.values(env).includes(other));
|
||||
}
|
||||
});
|
||||
|
||||
test('P3 Claude preflight accepts a proxy key without a host provider credential', async t => {
|
||||
const claude = await harness('claude-code');
|
||||
const root = scratch(t), binary = join(root, 'claude');
|
||||
writeFileSync(binary, '#!/bin/sh\nexit 0\n');
|
||||
chmodSync(binary, 0o700);
|
||||
assert.equal(claude.preflight({ env: { MOSAIC_CLAUDE_BIN: binary }, proxy: {
|
||||
baseUrl: 'http://127.0.0.1:12345', key: 'fx332-agent-a',
|
||||
} }), null);
|
||||
});
|
||||
|
||||
test('P3 pi refuses no-session-credential with no provider key', async () => {
|
||||
const pi = await harness('pi');
|
||||
assert.equal(pi.preflight({ env: {} })?.code, 'no-session-credential');
|
||||
});
|
||||
|
||||
test('P3 pi refuses no-session-credential with only a Claude OAuth token', async () => {
|
||||
const pi = await harness('pi');
|
||||
assert.equal(pi.preflight({ env: { CLAUDE_CODE_OAUTH_TOKEN: 'fx332-oauth' } })?.code, 'no-session-credential');
|
||||
});
|
||||
|
||||
test('P3 pi accepts its own provider key or a session proxy key', async () => {
|
||||
const pi = await harness('pi');
|
||||
for (const name of ['ANTHROPIC_API_KEY', 'OPENAI_API_KEY', 'OPENROUTER_API_KEY', 'ZAI_API_KEY']) {
|
||||
assert.equal(pi.preflight({ env: { [name]: 'fx332-own' } }), null, name);
|
||||
}
|
||||
assert.equal(pi.preflight({ env: {}, proxy: { baseUrl: 'http://127.0.0.1:12345', key: 'fx332-agent-a' } }), null);
|
||||
});
|
||||
Reference in new issue
Block a user