mirror of
https://github.com/block/buzz.git
synced 2026-10-29 21:41:33 +00:00
Signed-off-by: BetterCallSol <886fabdb38ceb1aede220bc237b7bb34736490f12a7d79e235e5ecfd63a36514@buzz.block.builderlab.xyz>
234 lines
19 KiB
TypeScript
234 lines
19 KiB
TypeScript
import { runtimeBindings } from '../src/settings-runtime.ts';
|
|
import { createServer } from 'node:http';
|
|
import { once } from 'node:events';
|
|
import { addDatabricks } from '../src/databricks.ts';
|
|
import { wrapManagement, unwrapManagement } from '../src/nostr-codec.ts';
|
|
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import { mkdtempSync, mkdirSync, rmSync, existsSync, readFileSync, realpathSync, writeFileSync } from 'node:fs';
|
|
import { join } from 'node:path';
|
|
import { fileURLToPath } from 'node:url';
|
|
import { tmpdir } from 'node:os';
|
|
import { finalizeEvent } from 'nostr-tools/pure';
|
|
import { nsecEncode } from 'nostr-tools/nip19';
|
|
import { registerAgent, agentNsec, addOpenAI, addProvider } from '../src/settings-credentials.ts';
|
|
import { readSettings, saveSettings, settingsId } from '../src/settings.ts';
|
|
import { profileFromEvents } from '../src/agent-profile.ts';
|
|
import { isolatedFileCredentials } from './isolated-file-credentials.ts';
|
|
import { newKey, publicKey, message, serializeManagement, seal, open, type Message } from '../src/protocol.ts';
|
|
import { openAIModels } from '../src/settings-models.ts';
|
|
import { host, provision, type Setup, bindingFingerprint } from '../src/host.ts';
|
|
import { createGenesis } from '../src/assignment.ts';
|
|
import { writePrivate } from '../src/storage.ts';
|
|
|
|
function fixture(t: test.TestContext) { const root = realpathSync(mkdtempSync(join(tmpdir(),'beehive-pairing-cli-settings-'))); t.after(() => rmSync(root,{ recursive: true, force: true })); return root; }
|
|
const sleep = (ms: number) => new Promise(r => setTimeout(r,ms));
|
|
async function wait(fn: () => boolean) { for(let n=0;n<150;n++) { if(fn()) return; await sleep(20); } throw Error('Fixture wait expired'); }
|
|
|
|
test('identity-only nsec registration verifies retained keys and preserves public-only state', t => {
|
|
const root = fixture(t), credentials = isolatedFileCredentials(join(root,'keys.json')), secret = newKey();
|
|
assert.equal(agentNsec(nsecEncode(Buffer.from(secret,'hex'))),secret);
|
|
assert.throws(() => agentNsec(secret),/nsec/);
|
|
const row = registerAgent(root,secret,credentials,{ profileState: 'none' });
|
|
assert.equal(row.publicKey,publicKey(secret));
|
|
assert.equal(existsSync(join(root,'setup.json')),false);
|
|
assert.equal(existsSync(join(root,'journal.json')),false);
|
|
assert.equal(readSettings(root).providers.length,0);
|
|
assert.equal(readSettings(root).runtimes.length,0);
|
|
assert.ok(!readFileSync(join(root,'settings.json'),'utf8').includes(secret));
|
|
registerAgent(root,secret,credentials,{ profileState: 'unavailable' });
|
|
assert.equal(readSettings(root).revision,1);
|
|
credentials.remove(row.key);
|
|
assert.throws(() => registerAgent(root,secret,credentials,{ profileState: 'none' }),/missing/);
|
|
assert.equal(readSettings(root).revision,1);
|
|
const other = newKey();
|
|
assert.throws(() => registerAgent(root,other,{ read: () => null, create() {}, remove() {} },{ profileState: 'none' }),/missing/);
|
|
assert.equal(readSettings(root).agents.length,1);
|
|
assert.ok(readFileSync(join(root,'credential-attempts.json'),'utf8').includes(publicKey(other)));
|
|
});
|
|
|
|
test('signed profile selects valid latest metadata, strips controls and does not invent names', () => {
|
|
const secret = newKey(), author = publicKey(secret), now = Math.floor(Date.now()/1000);
|
|
const event = finalizeEvent({ kind: 0, created_at: now, tags: [], content: JSON.stringify({ name: 'Fixture\u001b[31m', about: 'hello' }) },Buffer.from(secret,'hex'));
|
|
assert.equal(profileFromEvents([event],author,'wss://fixture.invalid').profileState,'found');
|
|
assert.equal(profileFromEvents([event],publicKey(newKey()),'wss://fixture.invalid').profileState,'none');
|
|
assert.equal(profileFromEvents([{ ...event, content: '{}' }],author,'wss://fixture.invalid').profileState,'none');
|
|
const empty = finalizeEvent({ kind: 0, created_at: now, tags: [], content: '{}' },Buffer.from(secret,'hex'));
|
|
assert.equal(profileFromEvents([empty],author,'wss://fixture.invalid').profile?.name,undefined);
|
|
});
|
|
|
|
test('OpenAI verifies store before public commit; listing is bounded and custom is independent', async t => {
|
|
const root = fixture(t); let stored: string | null = null;
|
|
assert.throws(() => addOpenAI(root,'Fixture','synthetic',{ read: () => null, create() {} }),/verification/);
|
|
assert.equal(readSettings(root).providers.length,0);
|
|
addOpenAI(root,'Fixture','synthetic',{ read: () => stored, create(_ref,value) { stored = value; } });
|
|
const catalog = readSettings(root), provider = catalog.providers[0]!;
|
|
assert.ok(!readFileSync(join(root,'settings.json'),'utf8').includes('synthetic'));
|
|
const models = await openAIModels('synthetic',new AbortController().signal,async (_url,options) => {
|
|
assert.equal((options?.headers as Record<string,string>).Authorization,'Bearer synthetic');
|
|
return new Response(JSON.stringify({ data: [{ id: 'gpt-5' },{ id: 'gpt-5-2026-01-01' },{ id: 'text-embedding-3-small' }] }));
|
|
});
|
|
assert.deepEqual(models,['gpt-5']);
|
|
await assert.rejects(openAIModels('synthetic',new AbortController().signal,async () => new Response('',{ status: 403 })),/unavailable/);
|
|
saveSettings(root,{ ...catalog,runtimes: [{ id: settingsId(), name: 'Custom', harness: 'buzz-agent', executable: process.execPath, providerId: provider.id, model: 'unknown-custom-model' }] },catalog.revision);
|
|
assert.equal(readSettings(root).runtimes[0]?.model,'unknown-custom-model');
|
|
assert.throws(() => saveSettings(root,catalog,catalog.revision),/changed/);
|
|
});
|
|
|
|
for (const providerType of ['openai','databricks_v2','codex-openai','anthropic','openai-compat','openrouter'] as const) test(`${providerType} saved runtime reaches host Save/new Start while the prior active run remains immutable`, async t => {
|
|
const root = fixture(t), owner = newKey(), agent = newKey(), hostKey = publicKey(newKey());
|
|
const codex = providerType === 'codex-openai';
|
|
const added = ['anthropic','openai-compat','openrouter'].includes(providerType);
|
|
const home = root, config = root;
|
|
const setup: Setup = { host: hostKey, ownerSecret: owner, agentSecret: agent, runner: realpathSync(process.execPath), args: ['-e','setInterval(()=>{},1000)'], workspace: root, serviceHome: home, configDirectory: config, mode: 'fixture' };
|
|
provision(root,setup,createGenesis(publicKey(owner),publicKey(agent),hostKey));
|
|
let receive: (m: Message) => void = () => {}; const reports: Message[] = [];
|
|
const transport = { binding: { host: hostKey, owner: publicKey(owner) }, validate() {}, connect(_url: string,_secret: string,handle: (m: Message) => void) { receive = handle; return { ready: Promise.resolve(), send(m: Message) { reports.push(m); }, close() {} }; } };
|
|
let providerReads = 0;
|
|
const running = await host(root,'ws://127.0.0.1',undefined,transport,undefined,async (input,signal) => { signal.throwIfAborted(); assert.equal((input as any).provider,providerType === 'openai' || codex ? 'openai-compat' : providerType); if (providerType === 'databricks_v2') assert.equal((input as any).host,'https://fixture.example'); providerReads++; return {ok:true,secret:codex ? 'fixture-codex-private-key' : 'synthetic-provider-key'}; });
|
|
t.after(() => running.close());
|
|
const start = message('start',hostKey,publicKey(agent),0); receive(start);
|
|
await wait(() => reports.some(m => m.type === 'inventory' && m.body.phase === 'running'));
|
|
const active = reports.filter(m => m.type === 'inventory').at(-1)!.body.actualRun;
|
|
let stored: string | null = null;
|
|
if (added) addProvider(root,'Fixture','synthetic',{read:()=>stored,create:(_r,v)=>{stored=v;}},providerType as 'anthropic'|'openai-compat'|'openrouter','https://fixture.example/v1',providerType === 'openai-compat' ? 'responses' : undefined);
|
|
else if (providerType !== 'databricks_v2') addOpenAI(root,'Fixture','synthetic',{ read: () => stored, create(_r,v) { stored = v; } });
|
|
else await addDatabricks(root,'Fixture','https://fixture.example',new AbortController().signal);
|
|
const prior = readSettings(root), id = settingsId();
|
|
const model = codex ? 'custom-codex-model' : added ? (providerType === 'anthropic' ? 'claude-sonnet-4-5' : 'unknown-custom-model') : providerType === 'openai' ? 'gpt-5' : 'databricks-gpt-5-4';
|
|
const executable = join(root,'fixture-buzz-agent');
|
|
writeFileSync(executable,`#!/bin/sh\n[ \"$REVIEW_MODE\" = synthetic ] || exit 10\n[ \"$BUZZ_AGENT_THINKING_EFFORT\" = high ] || exit 9\nexec '${process.execPath}' '${fileURLToPath(new URL('./acp-fixture.ts',import.meta.url))}' ${providerType === 'openai' ? 'openai' : 'databricks-os'}\n`,{mode:0o700});
|
|
let requests = 0;
|
|
if (added) {
|
|
const keyName = providerType === 'anthropic' ? 'ANTHROPIC_API_KEY' : providerType === 'openrouter' ? 'OPENROUTER_API_KEY' : 'OPENAI_COMPAT_API_KEY';
|
|
const server = createServer(async (req,res) => {
|
|
assert.equal(req.method,'POST'); assert.equal(req.url, providerType === 'anthropic' ? '/v1/messages' : providerType === 'openrouter' ? '/v1/chat/completions' : '/v1/responses');
|
|
assert.equal(req.headers.authorization,'Bearer synthetic-provider-key');
|
|
let body=''; for await (const chunk of req) body+=chunk;
|
|
assert.deepEqual(JSON.parse(body),{model,...(providerType === 'anthropic' ? {} : {effort:'high'})}); requests++; res.end('{}');
|
|
});
|
|
server.listen(0,'127.0.0.1'); await once(server,'listening');
|
|
t.after(()=>new Promise<void>(resolve=>server.close(()=>resolve())));
|
|
const endpoint = `http://127.0.0.1:${(server.address() as any).port}` + (providerType === 'anthropic' ? '/v1/messages' : providerType === 'openrouter' ? '/v1/chat/completions' : '/v1/responses');
|
|
writeFileSync(executable,`#!${process.execPath}
|
|
if (process.env.BUZZ_AGENT_PROVIDER !== ${JSON.stringify(providerType)} || process.env.REVIEW_MODE !== 'synthetic') throw Error('Wrong binding');
|
|
const response = await fetch(${JSON.stringify(endpoint)},{method:'POST',headers:{authorization:'Bearer '+process.env[${JSON.stringify(keyName)}]},body:JSON.stringify({model:process.env.BUZZ_AGENT_MODEL,effort:process.env.BUZZ_AGENT_THINKING_EFFORT})});
|
|
if (!response.ok) throw Error('Synthetic provider refused');
|
|
process.argv[2]='saved-provider';
|
|
await import(${JSON.stringify(new URL('./acp-fixture.ts',import.meta.url).href)});
|
|
`,{mode:0o700});
|
|
}
|
|
if (codex) {
|
|
const server = createServer(async (req,res) => {
|
|
assert.equal(req.method,'POST'); assert.equal(req.url,'/v1/responses');
|
|
assert.equal(req.headers.authorization,'Bearer fixture-codex-private-key');
|
|
let body = ''; for await (const chunk of req) body += chunk;
|
|
assert.equal(JSON.parse(body).model,model); requests++;
|
|
res.end('{"output":[]}');
|
|
});
|
|
server.listen(0,'127.0.0.1'); await once(server,'listening');
|
|
t.after(() => new Promise<void>(resolve => server.close(() => resolve())));
|
|
const endpoint = `http://127.0.0.1:${(server.address() as any).port}/v1/responses`;
|
|
writeFileSync(join(root,'mode'),'ok');
|
|
writeFileSync(executable,`#!${process.execPath}
|
|
if (process.env.REVIEW_MODE !== 'synthetic') throw Error('Missing selected runtime environment');
|
|
const response = await fetch(${JSON.stringify(endpoint)}, {method:'POST',headers:{authorization:'Bearer '+process.env.OPENAI_API_KEY},body:JSON.stringify({model:JSON.parse(process.env.CODEX_CONFIG).model})});
|
|
if (!response.ok) throw Error('Synthetic provider rejected');
|
|
await import(${JSON.stringify(new URL('./conversation-harness-fixture.ts',import.meta.url).href)});
|
|
`,{mode:0o700});
|
|
}
|
|
saveSettings(root,{ ...prior, runtimes: [{ id, name: 'Future', environment: {REVIEW_MODE:'synthetic'}, harness: codex ? 'codex' : 'buzz-agent', executable, providerId: prior.providers[0]!.id, model, ...(codex ? {cli:realpathSync(process.execPath)} : providerType === 'anthropic' ? {} : {effort:'high'}) }] },prior.revision);
|
|
const projected = runtimeBindings(setup,readSettings(root))[`runtime:${id}`]!;
|
|
if (codex) { assert.notEqual(projected.serviceHome,root); assert.equal(existsSync(projected.serviceHome!),false); }
|
|
await wait(() => running.settingsRevision === 2);
|
|
await wait(() => reports.some(m => m.type === 'inventory' && (m.body.harnessSetups as any[]).some(r => r.id === `runtime:${id}`)));
|
|
const inventory = reports.filter(m => m.type === 'inventory').at(-1)!;
|
|
assert.deepEqual(inventory.body.actualRun,active);
|
|
const binding = (inventory.body.harnessSetups as any[]).find(r => r.id === `runtime:${id}`);
|
|
const save = message('save',hostKey,publicKey(agent),inventory.revision,{ model, workspace: root, profile: 'default', harnessSetup: { id: binding.id, fingerprint: binding.fingerprint } });
|
|
receive(save); await wait(() => reports.some(m => m.body.operation === save.id));
|
|
assert.equal(reports.find(m => m.body.operation === save.id)?.body.result,'saved; running configuration unchanged');
|
|
assert.deepEqual(reports.filter(m => m.type === 'inventory').at(-1)!.body.actualRun,active);
|
|
if (codex) assert.equal(existsSync(projected.serviceHome!),false,'Save is configuration-only');
|
|
const current = reports.filter(m => m.type === 'inventory').at(-1)!;
|
|
const stop = message('stop',hostKey,publicKey(agent),current.revision); receive(stop); await wait(() => reports.some(m => m.body.operation === stop.id));
|
|
const stopped = reports.filter(m => m.type === 'inventory').at(-1)!;
|
|
assert.equal(stopped.body.phase,'stopped');
|
|
const nextStart = message('start',hostKey,publicKey(agent),stopped.revision); receive(nextStart); await wait(() => reports.some(m => m.body.operation === nextStart.id));
|
|
assert.equal(reports.find(m => m.body.operation === nextStart.id)?.body.result,'accepted');
|
|
assert.equal((reports.filter(m => m.type === 'inventory').at(-1)!.body.actualRun as any).selection.model,model);
|
|
assert.equal(providerReads,1);
|
|
if (added) { assert.equal(requests,1); assert.ok(!readFileSync(join(root,'journal.json'),'utf8').includes('synthetic-provider-key')); }
|
|
if (codex) { assert.equal(requests,1); assert.ok(!readFileSync(join(root,'journal.json'),'utf8').includes('fixture-codex-private-key')); }
|
|
assert.ok(!JSON.stringify(reports).includes('synthetic-provider-key'));
|
|
assert.ok(!readFileSync(join(root,'journal.json'),'utf8').includes('synthetic-provider-key'));
|
|
const invalid = { ...readSettings(root), revision: 3, runtimes: [] }; writePrivate(join(root,'settings.json'),invalid);
|
|
await sleep(2100); assert.equal(running.settingsRevision,2,'invalid replacement retains effective catalog');
|
|
await running.close();
|
|
if (codex) {
|
|
assert.equal(existsSync(projected.serviceHome!),true,'Stop retains managed state');
|
|
assert.equal(existsSync(projected.configDirectory!),true);
|
|
}
|
|
});
|
|
|
|
test('oversized projected inventory retains loaded catalog and serializable reports, including on reopen', async t => {
|
|
const root = fixture(t), owner = newKey(), agent = newKey(), hostKey = publicKey(newKey());
|
|
// Long real paths repeat in each wire row; 100 short public records are not a wire budget.
|
|
const setup: Setup = { host: hostKey, ownerSecret: owner, agentSecret: agent, runner: realpathSync(process.execPath), args: [], workspace: root, allowedWorkspaces: [root, ...Array.from({length: 12}, (_, i) => join(root, `workspace-${i}-` + 'x'.repeat(120)))], serviceHome: root, configDirectory: root, mode: 'fixture' };
|
|
provision(root,setup,createGenesis(publicKey(owner),publicKey(agent),hostKey));
|
|
const reports: Message[] = [];
|
|
const transport = { binding: {host: hostKey, owner: publicKey(owner)}, validate() {}, connect() { return { ready: Promise.resolve(), send(m: Message) { serializeManagement(m); reports.push(m); }, close() {} }; } };
|
|
const running = await host(root,'ws://127.0.0.1',undefined,transport);
|
|
t.after(() => running.close());
|
|
let stored: string | null = null;
|
|
addOpenAI(root,'Fixture','synthetic',{read: () => stored, create(_r,v) { stored = v; }});
|
|
const prior = readSettings(root);
|
|
const row = {id: settingsId(), name: 'Fitting', harness: 'buzz-agent' as const, executable: realpathSync(process.execPath), providerId: prior.providers[0]!.id, model: 'm'.repeat(200)};
|
|
saveSettings(root,{...prior, runtimes: [row]},prior.revision);
|
|
await wait(() => running.settingsRevision === 2);
|
|
const fitting = reports.filter(m => m.type === 'inventory').at(-1)!;
|
|
assert.equal((fitting.body.harnessSetups as unknown[]).length,2);
|
|
// Both production codecs accept the actual fitting inventory.
|
|
assert.deepEqual(open(seal(fitting,owner),owner),JSON.parse(serializeManagement(fitting)));
|
|
assert.deepEqual(unwrapManagement(wrapManagement(fitting,Buffer.from(owner,'hex'),publicKey(agent)),Buffer.from(agent,'hex')).message,JSON.parse(serializeManagement(fitting)));
|
|
const saved = readSettings(root);
|
|
saveSettings(root,{...saved,runtimes: [...saved.runtimes,...Array.from({length: 18}, () => ({...row,id:settingsId()}))]},saved.revision);
|
|
assert.equal(readSettings(root).revision,3,'public save is retained, not falsely reported loaded');
|
|
const before = reports.length;
|
|
await sleep(2100);
|
|
assert.equal(running.settingsRevision,2);
|
|
assert.ok(reports.length > before,'prior inventory continues to publish');
|
|
assert.deepEqual(reports.filter(m => m.type === 'inventory').at(-1)!.body.harnessSetups,fitting.body.harnessSetups);
|
|
await running.close();
|
|
await assert.rejects(host(root,'ws://127.0.0.1',undefined,transport),/bounded wire size/);
|
|
assert.equal(existsSync(join(root,'host.lock')),false,'failed startup releases only its own lock');
|
|
});
|
|
|
|
test('shared management serializer preserves the exact UTF-8 wire limit for both producers', () => {
|
|
const secret = newKey(), recipient = newKey();
|
|
const m = message('inventory',publicKey(secret),publicKey(recipient),0,{ padding: '' });
|
|
const overhead = Buffer.byteLength(JSON.stringify(m));
|
|
m.body.padding = 'a'.repeat(32768-overhead);
|
|
assert.equal(Buffer.byteLength(serializeManagement(m)),32768);
|
|
assert.deepEqual(open(seal(m,secret),secret),m);
|
|
assert.deepEqual(unwrapManagement(wrapManagement(m,Buffer.from(secret,'hex'),publicKey(recipient)),Buffer.from(recipient,'hex')).message,m);
|
|
m.body.padding += 'é';
|
|
assert.throws(() => serializeManagement(m),/bounded wire size/);
|
|
assert.throws(() => seal(m,secret),/bounded wire size/);
|
|
assert.throws(() => wrapManagement(m,Buffer.from(secret,'hex'),publicKey(recipient)),/bounded wire size/);
|
|
});
|
|
|
|
test('legacy registration gains one runtime link without replacing identity or definitions',t=>{
|
|
const root=fixture(t),credentials=isolatedFileCredentials(join(root,'keys.json')),secret=newKey();
|
|
let providerSecret:string|null=null;
|
|
addOpenAI(root,'Fixture','synthetic',{read:()=>providerSecret,create:(_r,v)=>{providerSecret=v;}});
|
|
const prior=readSettings(root),runtime={id:'runtime-one',name:'Runtime',harness:'buzz-agent' as const,executable:process.execPath,providerId:prior.providers[0]!.id,model:'gpt-5'};
|
|
saveSettings(root,{...prior,runtimes:[runtime,{...runtime,id:'runtime-two'}]},prior.revision);
|
|
const original=registerAgent(root,secret,credentials,{profileState:'none'}),before=readSettings(root);
|
|
const linked=registerAgent(root,secret,credentials,{profileState:'unavailable'},runtime.id,before.revision);
|
|
assert.deepEqual(linked,{...original,runtimeId:runtime.id});assert.deepEqual(readSettings(root).runtimes,before.runtimes);
|
|
assert.deepEqual(registerAgent(root,secret,credentials,{profileState:'none'},'runtime-two'),linked,'registration retains identity and initial choice; host Save owns runtime changes');
|
|
assert.throws(()=>registerAgent(root,secret,credentials,{profileState:'none'},runtime.id,before.revision),/changed/);
|
|
assert.equal(readSettings(root).revision,before.revision+1);
|
|
});
|