README,src/{observer,schema},test: fix live observer requests
28 unmodified lines2930313233333435363729 unmodified lines28 unmodified lines## configuration
```bashexport PRIME_COMMITMENT_OBSERVER_PROVIDER=googleexport PRIME_COMMITMENT_OBSERVER_MODEL=gemini-3-flash-previewexport PRIME_COMMITMENT_OBSERVER_MODEL=gemini-3.1-flash-liteexport PRIME_COMMITMENT_OBSERVER_TIMEOUT_MS=60000```
Optional variables:29 unmodified lines22 unmodified lines2324252627272829303186 unmodified lines22 unmodified lines
export function configFromEnv(env: NodeJS.ProcessEnv = process.env): ObserverConfig { return { provider: env.PRIME_COMMITMENT_OBSERVER_PROVIDER ?? "google", modelId: env.PRIME_COMMITMENT_OBSERVER_MODEL ?? "gemini-3-flash-preview", modelId: env.PRIME_COMMITMENT_OBSERVER_MODEL ?? "gemini-3.1-flash-lite", apiKey: env.PRIME_COMMITMENT_OBSERVER_API_KEY, baseUrl: env.PRIME_COMMITMENT_OBSERVER_BASE_URL, temperature: env.PRIME_COMMITMENT_OBSERVER_TEMPERATURE ? Number(env.PRIME_COMMITMENT_OBSERVER_TEMPERATURE)86 unmodified lines13 unmodified lines1415161718181920211 unmodified line23242526282728293067 unmodified lines13 unmodified lines additionalProperties: false, properties: { existing: { type: "array", maxItems: MAX_THREADS, items: { type: "object", additionalProperties: false, properties: { id: { type: "string" }, ...threadProperties },1 unmodified line }, }, additions: { type: "array", maxItems: MAX_THREADS, items: { type: "object", additionalProperties: false, properties: threadProperties,67 unmodified lines2 unmodified lines34567789101168 unmodified lines80818283848586878889909192100 unmodified lines2 unmodified linesimport type { AgentMessage } from "@earendil-works/pi-agent-core";import { buildContextBlock, CLEARED_CONTEXT } from "../src/inject.ts";import { buildPacket } from "../src/packet.ts";import { OBSERVER_SYSTEM_PROMPT } from "../src/prompt.ts";import { parseObserverOutput } from "../src/schema.ts";import { parseObserverOutput, OBSERVER_JSON_SCHEMA } from "../src/schema.ts";import { isCommitmentEvent, liveThreads, observationChangesState, replay } from "../src/state.ts";import type { CommitmentEvent, Registry } from "../src/types.ts";
const observation = (overrides: Partial<Extract<CommitmentEvent, { kind: "observation" }>> = {}) => ({68 unmodified lines ]); assert.equal(reopened.threads[0].status, "open");});
test("schema leaves array bounds to local validation", () => { assert.equal("maxItems" in OBSERVER_JSON_SCHEMA.properties.existing, false); assert.equal("maxItems" in OBSERVER_JSON_SCHEMA.properties.additions, false);});
test("schema requires an exact existing-thread census", () => { const valid = JSON.stringify({ existing: [ { id: "t1", canonicalRequest: "one", status: "active" },100 unmodified lines