// Durable root conversation and console. SQLite stays outside the world. import { BACKGROUND_CONTEXT as context } from '@earendil-works/chord/context'; import { createModels } from '@earendil-works/pi-ai/models'; import { openaiProvider } from '@earendil-works/pi-ai/providers/openai'; import { Harness, createRegistry } from '@earendil-works/pi-durable'; import { CodingTools } from '@earendil-works/pi-durable/tools'; import { openStorage } from './sqlite'; import { environment } from './environment'; if (!process.env.PI_PROXY_BASE_URL || !process.env.PI_PROXY_API_KEY) { throw new Error('PI_PROXY_BASE_URL and PI_PROXY_API_KEY are required'); } const models = createModels(); const provider = openaiProvider(); const model = { id: 'gpt-6.1-sol', name: 'gpt-6.1-sol', provider: 'openai', api: 'openai-responses', baseUrl: `${process.env.PI_PROXY_BASE_URL}/v1`, reasoning: true, input: ['text'], thinkingLevelMap: { off: null, minimal: null }, cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 200000, maxTokens: 4096, }; models.setProvider({ ...provider, baseUrl: model.baseUrl, getModels: () => [model], auth: { apiKey: { name: 'Sausage proxy', resolve: async () => ({ auth: { apiKey: process.env.PI_PROXY_API_KEY, baseUrl: model.baseUrl, headers: { 'Shopify-Usage-Tag': JSON.stringify(['pi', 'sausage']) } }, source: 'PI_PROXY_API_KEY', }) } }, }); const registry = createRegistry(); registry.install(CodingTools); const harness = await Harness.open(await openStorage(globalThis.storagePath), { models, registry, env: (target: any) => environment(target.cwd ?? '/', target.conversationId), }, context); const root = await harness.root(context, { agent: { model: { provider: 'openai', modelId: model.id }, thinkingLevel: 'low', cwd: '/', extensions: [CodingTools] } }); const watch = await root.watch(context); const emitted = new Map(); let partial = ''; const text = (message: any) => message?.content?.filter((b: any) => b.type === 'text').map((b: any) => b.text).join('') ?? ''; const render = (view: any) => { for (const entry of view.entries) { if (entry.kind !== 'pi.assistant') continue; const value = text(entry.model?.[0]); if (emitted.has(entry.id)) continue; if (value.startsWith(partial)) Deno.core.ops.op_output(value.slice(partial.length)); else Deno.core.ops.op_output(value); partial = ''; emitted.set(entry.id, value); } const live = text(view.docs['pi.live']?.generation?.message); if (live.startsWith(partial)) Deno.core.ops.op_output(live.slice(partial.length)); partial = live; }; // Do not replay the historical transcript to the console. for (const entry of watch.value.entries) { if (entry.kind === 'pi.assistant') emitted.set(entry.id, text(entry.model?.[0])); } watch.start((event: any) => { if (event.kind === 'value') render(event.value); }); harness.resume(); await harness.waitForIdle(context); while (true) { const line = await Deno.core.ops.op_input(); if (line === null) break; if (!line.trim()) continue; const submission = await root.submit({ type: 'input', content: line, requestId: crypto.randomUUID() }, context); const result = await submission.wait(context); await harness.waitForIdle(context); const final = await root.watch(context); render(final.value); await final.stop(); Deno.core.ops.op_output('\n'); if (result.status !== 'done') throw new Error(`Run ended: ${JSON.stringify(result)}`); } await watch.stop(); await harness.close(context);