chore: snapshot working tree - pty_exited notifications + in-flight inference WIP

feat(booterm): structured pty_exited WS notifications. Plan-validated, impl-validated, code-reviewed green (contracts build clean, contracts test 29/29, booterm + web typecheck clean).

wip: in-progress inference/provider refactor (agents.ts, provider.ts, new llama-providers.ts, removed llama-args-validator), plus arena, dispatcher, compaction, schema changes.

openspec: pty-exit-notifications complete; x-agent-flags planned (not yet implemented).
This commit is contained in:
2026-06-14 12:48:47 +00:00
parent 0ed506f1da
commit b18de2a331
204 changed files with 25344 additions and 867 deletions

View File

@@ -32,6 +32,10 @@
"./arena": {
"types": "./dist/arena.d.ts",
"default": "./dist/arena.js"
},
"./llama-providers": {
"types": "./dist/llama-providers.d.ts",
"default": "./dist/llama-providers.js"
}
},
"scripts": {

View File

@@ -0,0 +1,179 @@
import { describe, it, expect } from 'vitest';
import {
LlamaProviderSchema,
LlamaProvidersFileSchema,
parseModelRef,
formatModelRef,
} from '../llama-providers.js';
const VALID_PROVIDER = {
id: 'sam-desktop',
label: 'Sam-desktop',
baseUrl: 'http://100.101.41.16:8401',
kind: 'llama-swap',
};
const VALID_MINIMAL_PROVIDER = {
id: 'embedding',
label: 'embedding',
baseUrl: 'http://100.90.172.55:8411',
kind: 'llama-swap',
};
const VALID_FILE = {
defaultProvider: 'sam-desktop',
providers: [VALID_PROVIDER, VALID_MINIMAL_PROVIDER],
};
describe('LlamaProviderSchema', () => {
it('accepts a well-formed provider', () => {
const result = LlamaProviderSchema.safeParse(VALID_PROVIDER);
expect(result.success).toBe(true);
});
it('defaults kind to llama-swap', () => {
const result = LlamaProviderSchema.safeParse({
id: 'test',
label: 'test',
baseUrl: 'http://localhost:8080',
});
expect(result.success).toBe(true);
if (result.success) {
expect(result.data.kind).toBe('llama-swap');
}
});
it('rejects missing id', () => {
const result = LlamaProviderSchema.safeParse({
label: 'test',
baseUrl: 'http://localhost:8080',
});
expect(result.success).toBe(false);
});
it('rejects empty id', () => {
const result = LlamaProviderSchema.safeParse({
id: '',
label: 'test',
baseUrl: 'http://localhost:8080',
});
expect(result.success).toBe(false);
});
it('rejects invalid baseUrl', () => {
const result = LlamaProviderSchema.safeParse({
id: 'test',
label: 'test',
baseUrl: 'not-a-url',
});
expect(result.success).toBe(false);
});
});
describe('LlamaProvidersFileSchema', () => {
it('accepts a well-formed file', () => {
const result = LlamaProvidersFileSchema.safeParse(VALID_FILE);
expect(result.success).toBe(true);
});
it('rejects missing defaultProvider', () => {
const result = LlamaProvidersFileSchema.safeParse({
providers: [VALID_PROVIDER],
});
expect(result.success).toBe(false);
});
it('rejects empty providers array', () => {
const result = LlamaProvidersFileSchema.safeParse({
defaultProvider: 'sam-desktop',
providers: [],
});
expect(result.success).toBe(false);
});
it('rejects when defaultProvider references nonexistent provider id', () => {
// Schema doesn't enforce cross-reference, but the file shape is valid.
const result = LlamaProvidersFileSchema.safeParse({
defaultProvider: 'nonexistent',
providers: [VALID_PROVIDER],
});
expect(result.success).toBe(true);
});
});
describe('parseModelRef', () => {
const defaultProvider = 'sam-desktop';
it('parses composite provider/model', () => {
const result = parseModelRef('sam-desktop/qwen3.6-35b-a3b', defaultProvider);
expect(result).toEqual({
providerId: 'sam-desktop',
wireModelId: 'qwen3.6-35b-a3b',
isLegacyBareId: false,
});
});
it('parses composite with model containing slashes', () => {
const result = parseModelRef('sam-desktop/deepseek/v4-pro', defaultProvider);
expect(result).toEqual({
providerId: 'sam-desktop',
wireModelId: 'deepseek/v4-pro',
isLegacyBareId: false,
});
});
it('resolves bare id to default provider', () => {
const result = parseModelRef('qwen3.6-35b-a3b', defaultProvider);
expect(result).toEqual({
providerId: 'sam-desktop',
wireModelId: 'qwen3.6-35b-a3b',
isLegacyBareId: true,
});
});
it('resolves empty string to default provider', () => {
const result = parseModelRef('', defaultProvider);
expect(result).toEqual({
providerId: 'sam-desktop',
wireModelId: '',
isLegacyBareId: true,
});
});
it('parses embedding provider/model', () => {
const result = parseModelRef('embedding/gemma-4-12b', defaultProvider);
expect(result).toEqual({
providerId: 'embedding',
wireModelId: 'gemma-4-12b',
isLegacyBareId: false,
});
});
it('does not strip provider prefix when first char is slash', () => {
// "/model" has slashIdx=0, so treated as bare id.
const result = parseModelRef('/model', defaultProvider);
expect(result).toEqual({
providerId: 'sam-desktop',
wireModelId: '/model',
isLegacyBareId: true,
});
});
});
describe('formatModelRef', () => {
it('formats provider/model', () => {
expect(formatModelRef('sam-desktop', 'qwen3.6-35b-a3b')).toBe('sam-desktop/qwen3.6-35b-a3b');
});
it('formats provider with model containing slashes', () => {
expect(formatModelRef('sam-desktop', 'deepseek/v4-pro')).toBe('sam-desktop/deepseek/v4-pro');
});
it('round-trips through parseModelRef', () => {
const formatted = formatModelRef('embedding', 'gemma-4-12b');
const parsed = parseModelRef(formatted, 'sam-desktop');
expect(parsed.providerId).toBe('embedding');
expect(parsed.wireModelId).toBe('gemma-4-12b');
expect(parsed.isLegacyBareId).toBe(false);
});
});

View File

@@ -0,0 +1,69 @@
import { z } from 'zod';
/**
* Single local inference provider entry in the shared config file.
* `kind` distinguishes transport families (llama-swap, deepseek, etc.).
*/
export const LlamaProviderSchema = z.object({
id: z.string().min(1),
label: z.string().min(1),
baseUrl: z.string().url(),
kind: z.string().min(1).default('llama-swap'),
});
export type LlamaProvider = z.infer<typeof LlamaProviderSchema>;
/**
* Shape of `/data/llama-providers.json` (or `LLAMA_PROVIDERS_PATH`).
* When the file is absent, app-local loaders synthesize one legacy
* provider from `LLAMA_SWAP_URL`.
*/
export const LlamaProvidersFileSchema = z.object({
defaultProvider: z.string().min(1),
providers: z.array(LlamaProviderSchema).min(1),
});
export type LlamaProvidersFile = z.infer<typeof LlamaProvidersFileSchema>;
// ---------------------------------------------------------------------------
// Pure model-ref helpers (D-2)
// ---------------------------------------------------------------------------
export interface ParsedModelRef {
providerId: string;
wireModelId: string;
isLegacyBareId: boolean;
}
const SEPARATOR = '/';
/**
* Parse a model reference string.
*
* - Composite `"provider/model"` → `{ providerId, wireModelId, isLegacyBareId: false }`
* - Bare `"model"` (no slash) → resolved against `defaultProvider`,
* `{ providerId: defaultProvider, wireModelId: model, isLegacyBareId: true }`
*/
export function parseModelRef(ref: string, defaultProvider: string): ParsedModelRef {
const slashIdx = ref.indexOf('/');
if (slashIdx <= 0) {
// Bare id or empty — resolve to default provider.
return {
providerId: defaultProvider,
wireModelId: ref,
isLegacyBareId: true,
};
}
return {
providerId: ref.slice(0, slashIdx),
wireModelId: ref.slice(slashIdx + 1),
isLegacyBareId: false,
};
}
/**
* Format a provider id + wire model id into the composite `"provider/model"` form.
*/
export function formatModelRef(providerId: string, wireModelId: string): string {
return `${providerId}${SEPARATOR}${wireModelId}`;
}

View File

@@ -473,6 +473,89 @@ export const ToolTraceFinishFrame = z.object({
// Published when the BooCoder detects that multiple worktrees/agents are editing
// the same file concurrently. Advisory only — writes are not blocked.
// ---- BooControl fleet frames -----------------------------------------------
//
// Published by the BooControl host service on the /api/ws/control WS endpoint.
// These frames use a 2-location sync pattern: contracts (WsFrameSchema +
// KNOWN_FRAME_TYPES) + web strict union only. They skip the server's broker
// entirely — control frames relay raw bytes through the proxy, so they never
// flow through the server's InferenceFrame union.
//
// The web strict union is the wire-format gate; missing it silently drops
// frames at JSON parse. The server loose union is NOT updated — adding it
// would be dead code.
// Host liveness state.
const HostLivenessValue = z.enum(['connected', 'reconnecting', 'down']);
// Control fleet snapshot/delta: full snapshot on join + seq-stamped state deltas.
export const ControlFleetFrame = z.object({
type: z.literal('control_fleet'),
seq: z.number().int().nonnegative(),
hosts: z.array(z.object({
providerId: z.string(),
liveness: HostLivenessValue,
lastSeenAt: z.string().nullable(),
seq: z.number().int().nonnegative(),
models: z.array(z.object({
model: z.string(),
state: z.string(),
ts: z.string(),
ttlDeadline: z.string().nullable(),
inflight: z.number().int().nonnegative(),
})),
})),
});
// Control activity: new request rows (live feed).
export const ControlActivityFrame = z.object({
type: z.literal('control_activity'),
seq: z.number().int().nonnegative(),
providerId: z.string(),
entry: z.object({
id: z.number().int(),
ts: z.string(),
model: z.string().nullable(),
reqPath: z.string().nullable(),
statusCode: z.number().nullable(),
durationMs: z.number().nullable(),
}),
});
// Control perf sample: appended samples per host.
export const ControlPerfFrame = z.object({
type: z.literal('control_perf'),
seq: z.number().int().nonnegative(),
providerId: z.string(),
ts: z.string(),
gpu: z.unknown(),
sys: z.unknown(),
});
// Control log: {provider_id, source: proxy|upstream, line} batches.
export const ControlLogFrame = z.object({
type: z.literal('control_log'),
seq: z.number().int().nonnegative(),
providerId: z.string(),
source: z.enum(['proxy', 'upstream', 'model']),
line: z.string(),
});
// Control job: bench/eval run progress events.
export const ControlJobFrame = z.object({
type: z.literal('control_job'),
seq: z.number().int().nonnegative(),
jobType: z.enum(['bench', 'eval', 'action']),
jobId: z.string(),
status: z.enum(['queued', 'running', 'completed', 'failed']),
detail: z.record(z.unknown()).optional(),
});
// ---- collision warning frame (v2.8) ----------------------------------------
//
// Published when the BooCoder detects that multiple worktrees/agents are editing
// the same file concurrently. Advisory only — writes are not blocked.
const ConflictSeverityValue = z.enum(['same_line', 'adjacent_line', 'different_area']);
export const CollisionWarningFrame = z.object({
@@ -483,6 +566,23 @@ export const CollisionWarningFrame = z.object({
severity: ConflictSeverityValue,
});
// ---- pty_exited frame (booterm) ---------------------------------------------
//
// Published by booterm when a PTY process exits. Carries exit code, last output
// lines from the ring buffer, session metadata, and timeout status.
export const PtyExitedFrame = z.object({
type: z.literal('pty_exited'),
session_id: z.string().min(1).max(64),
pane_id: z.string().min(1).max(64),
exit_code: z.number().int(),
last_lines: z.array(z.string()),
session_title: z.string().nullable().optional(),
session_description: z.string().nullable().optional(),
parent_agent: z.string().nullable().optional(),
timed_out: z.boolean(),
});
// ---- channel-delta frames (streaming v2) ----------------------------------
//
// Each channel frame carries a monotonic `seq` counter so the client can
@@ -594,10 +694,18 @@ export const WsFrameSchema = z.discriminatedUnion('type', [
ToolTraceFinishFrame,
// collision warning
CollisionWarningFrame,
// pty_exited (booterm)
PtyExitedFrame,
// channel-delta (streaming v2)
ChannelDeltaFrame,
// inter-agent message
AgentMessageFrame,
// BooControl fleet frames
ControlFleetFrame,
ControlActivityFrame,
ControlPerfFrame,
ControlLogFrame,
ControlJobFrame,
// per-user
ChatStatusFrame,
SessionUpdatedFrame,
@@ -649,6 +757,7 @@ export const KNOWN_FRAME_TYPES: readonly WsFrame['type'][] = [
'tool_trace_start',
'tool_trace_finish',
'collision_warning',
'pty_exited',
'channel_delta',
'agent_message',
'chat_status',
@@ -668,4 +777,10 @@ export const KNOWN_FRAME_TYPES: readonly WsFrame['type'][] = [
'project_unarchived',
'project_updated',
'project_deleted',
// BooControl fleet frames
'control_fleet',
'control_activity',
'control_perf',
'control_log',
'control_job',
] as const;