Track the fixed PhotoCraft source baseline with the existing native client integration. Use the actual Pi SDK for normal sends, durable session recovery, demand-loaded enterprise rules and checked undoable canvas tools. Retain request identities and never resend unknown inference. Include local packaging and real-call acceptance evidence.
51 lines
4.0 KiB
JavaScript
51 lines
4.0 KiB
JavaScript
import fs from 'node:fs/promises';
|
|
import path from 'node:path';
|
|
import assert from 'node:assert/strict';
|
|
import { atomic, digest } from '../src/store.mjs';
|
|
import { responseUsage } from '../src/usage.mjs';
|
|
import { auditResponse } from '../src/response-audit.mjs';
|
|
|
|
// Read-only evidence roll-up: this script cannot dispatch any model request.
|
|
const output = path.resolve(process.argv[2]);
|
|
const native = JSON.parse(await fs.readFile(path.join(output, 'native-process.json'), 'utf8'));
|
|
const scopes = await fs.readdir(path.join(native.profile, 'jiansun/accounts')); assert.equal(scopes.length, 1);
|
|
const account = path.join(native.profile, 'jiansun/accounts', scopes[0]);
|
|
const projects = await fs.readdir(path.join(account, 'projects')); assert.equal(projects.length, 1);
|
|
const project = projects[0], storeRoot = path.join(account, 'projects', project, 'agent', scopes[0], project);
|
|
const current = JSON.parse(await fs.readFile(path.join(storeRoot, 'current.json'), 'utf8'));
|
|
const store = path.join(storeRoot, current.bindingHash);
|
|
const events = (await fs.readFile(path.join(store, 'events.jsonl'), 'utf8')).trim().split('\n').map(JSON.parse);
|
|
const requestDir = path.join(account, 'pi-validation', project, 'requests'), records = [];
|
|
for (const file of await fs.readdir(requestDir)) {
|
|
const receipt = JSON.parse(await fs.readFile(path.join(requestDir, file), 'utf8'));
|
|
assert.equal(receipt.phase, 'complete'); assert.equal(receipt.terminal, true);
|
|
const payload = JSON.parse(await fs.readFile(path.join(store, 'payloads', receipt.id + '.json'), 'utf8'));
|
|
assert.equal(digest(payload), receipt.bodyHash);
|
|
const raw = Buffer.from(receipt.raw, 'base64').toString('utf8');
|
|
const usage = responseUsage(raw), audit = auditResponse(raw, receipt.model.protocol);
|
|
records.push({ id: receipt.id, requestId: receipt.requestId, model: receipt.model.id, bodyHashMatches: true, phase: receipt.phase,
|
|
...usage, requestChars: JSON.stringify(payload).length, toolNames: audit.calls.map(c => c.name) });
|
|
}
|
|
const known = records.filter(r => r.inputTokens !== null && r.cachedTokens !== null);
|
|
const total = known.reduce((v, r) => ({ input: v.input + r.inputTokens, cache: v.cache + r.cachedTokens }), { input: 0, cache: 0 });
|
|
const seed = JSON.parse(await fs.readFile(path.join(output, 'long-prepare-passed.json'), 'utf8'));
|
|
const phases = {};
|
|
for (const phase of ['correction', 'outline', 'canvas', 'long-recall', 'restart-recall', 'handover', 'tool-live']) {
|
|
const result = JSON.parse(await fs.readFile(path.join(output, `${phase}-passed.json`), 'utf8'));
|
|
assert.notEqual(result.passed, false); phases[phase] = { passed: true };
|
|
}
|
|
const recovery = JSON.parse(await fs.readFile(path.join(output, 'interrupt-recovery-passed.json'), 'utf8'));
|
|
assert.equal(recovery.recoveryPosts, 0);
|
|
const summary = { at: new Date().toISOString(), model: 'grok-4.7', normalClientSendUsesPi: true, realUserInstructionsWithGeneration: 9,
|
|
preflightFailureWithoutModelPost: 1, generationRequests: records.length, completedRequests: records.length, unknownNewRequests: 0,
|
|
nativeRequestBodyHashMatches: true, constructedHistoryMessages: seed.constructedHistoryMessages,
|
|
automaticCompactions: events.filter(e => e.type === 'automatic_compaction_completed').length,
|
|
actualGuiRestart: true, phases, recovery, bindingHash: current.bindingHash,
|
|
maxInputTokens: Math.max(...records.map(r => r.inputTokens || 0)),
|
|
maxProjectedInputChars: Math.max(...events.filter(e => e.type === 'context_budget').map(e => e.inputChars)),
|
|
cache: { source: '98k-returned-usage', requestsWithMetrics: known.length, requestsWithoutMetrics: records.length - known.length,
|
|
totalInputTokens: total.input, cachedTokens: total.cache, weightedRate: total.input ? total.cache / total.input : null,
|
|
minRequestRate: Math.min(...known.map(r => r.cacheRate)), maxRequestRate: Math.max(...known.map(r => r.cacheRate)), billingVerified: false }, records };
|
|
await atomic(path.join(output, 'final-client-summary.json'), summary);
|
|
console.log(JSON.stringify({ ...summary, records: undefined }));
|