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.
38 lines
3.4 KiB
JavaScript
38 lines
3.4 KiB
JavaScript
import fs from 'node:fs/promises';
|
||
import path from 'node:path';
|
||
import assert from 'node:assert/strict';
|
||
import { randomUUID } from 'node:crypto';
|
||
import { Native98kBroker } from '../src/native-bridge.mjs';
|
||
import { ProjectStore, atomic, digest } from '../src/store.mjs';
|
||
import { resolveRules } from '../src/rules.mjs';
|
||
import { DetailPiAgent } from '../src/agent.mjs';
|
||
|
||
const [originalConfig, outputDir] = process.argv.slice(2);
|
||
if (!originalConfig || !outputDir) throw Error('用法:<已有本地配置> <本次独立只读诊断目录>');
|
||
const output = path.resolve(outputDir), attempt = path.join(output, 'attempt.json');
|
||
if (await fs.access(attempt).then(() => true, () => false)) throw Error('此诊断任务已尝试,禁止重新发送;先检查原记录');
|
||
const prior = JSON.parse(await fs.readFile(originalConfig, 'utf8'));
|
||
const model = JSON.parse(await fs.readFile('output/pi-compatibility-20261021/public-docs/grok-4.7.json', 'utf8'))[0];
|
||
const catalog = JSON.parse(await fs.readFile('output/pi-compatibility-20261021/enterprise-rules.json', 'utf8'));
|
||
const combo = catalog.bindings.find(b => b.id === 'GJ-DESK-DNZ0385'), shop = catalog.shops.find(s => s.id === combo.shopId);
|
||
const binding = resolveRules({ brandId: shop.brandId, shopId: shop.id, categoryId: combo.categoryId }, catalog);
|
||
const headers = model.invocation.headers || {};
|
||
const config = { broker: { ...prior.broker, project: randomUUID(), invocationHeaders: headers }, binding, output, protocolMode: 'native-tools',
|
||
contract: { id: model.id, path: model.invocation.path, headers, sha256: digest(model), source: 'https://api.vip98k.com/api/v2/catalog/models', selection: 'published-current-default', price: model.pricing } };
|
||
await atomic(path.join(output, 'config.local.json'), config);
|
||
const broker = new Native98kBroker(config.broker), info = await broker.info();
|
||
assert.equal(info.model.id, model.id);
|
||
const store = await ProjectStore.open(output, { scope: info.accountScope, project: config.broker.project }, binding);
|
||
const events = [], host = await DetailPiAgent.open({ store, broker, callBudget: 3, onEvent: e => { events.push(e); if (e.type !== 'text_delta') console.log(JSON.stringify(e)); } });
|
||
await atomic(attempt, { project: config.broker.project, createdAt: new Date().toISOString(), purpose: 'new-independent-readonly-context-protocol-diagnostic', oldUnknownNotResent: true });
|
||
try {
|
||
const result = await host.prompt('这是一个新的只读函数协议验收任务。通过标准函数调用context_read读取当前项目规则,读取一次后直接用中文报告店铺、品类、模板编号和字体。不要写成invoke tool文字;不得调用其他工具,不修改任何画布或资料。', { requiredTool: 'context_read' });
|
||
assert.ok(events.some(e => e.type === 'tool_execution_end' && e.toolName === 'context_read' && !e.isError));
|
||
assert.match(result.text, /顾家/); assert.match(result.text, /电脑桌/);
|
||
await atomic(path.join(output, 'result.json'), { passed: true, model: model.id, result, events, oldUnknownNotResent: true, at: new Date().toISOString() });
|
||
console.log(JSON.stringify({ passed: true, ...result }));
|
||
} catch (error) {
|
||
await atomic(path.join(output, 'result.json'), { passed: false, error: error.message, events, inflight: host.inflight, sessionFile: host.manager.getSessionFile(), at: new Date().toISOString() });
|
||
console.error(error.message); process.exitCode = 1;
|
||
} finally { await host.dispose(); }
|