gongxiangp2/apps/detail-agent-pi/test/rule-context.test.mjs
WuYongJie 1b6425b552 feat(desktop): connect native Pi sessions with scoped rules and recovery
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.
2026-10-22 10:49:58 +08:00

29 lines
2.4 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import test from 'node:test';
import assert from 'node:assert/strict';
import { ruleContext, taskFor } from '../src/rule-context.mjs';
import { responseUsage } from '../src/usage.mjs';
const binding = { brandId: 'b', shopId: 's', categoryId: 'c', brandName: '顾家', version: 'v1',
brandSnapshot: { tone: '温暖克制', fontFamily: 'Noto Sans SC', visualRules: { part: '## 人物选择与连续性\n连续场景人物一致。' } },
rules: ['品牌调性:温暖克制', 'part:## 人物选择与连续性\n连续场景人物一致。', '当前品类电脑桌', '登记模块:首屏、参数图'],
templateSnapshot: { id: 'gj', screens: [{ title: '参数图' }] } };
test('context injects one copy and loads template/brand detail on demand', () => {
const copy = JSON.stringify(ruleContext(binding, { task: 'copy' }));
assert.match(copy, /温暖克制/); assert.match(copy, /电脑桌/); assert.doesNotMatch(copy, /连续场景|登记模块|templateSnapshot/);
const image = JSON.stringify(ruleContext(binding, { task: 'image' }));
assert.equal(image.split('连续场景人物一致').length - 1, 1); assert.match(image, /templateSnapshot/);
assert.equal(ruleContext(binding, { task: 'plan' }).templateSnapshot.screens, undefined);
assert.equal(binding.templateSnapshot.screens.length, 1);
assert.match(JSON.stringify(ruleContext(binding, { topic: 'brand' })), /连续场景/);
assert.equal(taskFor('生成六图总览方案'), 'plan'); assert.equal(taskFor('修改画布图层'), 'canvas');
assert.equal(taskFor('记住最新颜色,不要修改画布'), 'chat');
assert.equal(taskFor('请精简卖点文案,不改画布,不要生图'), 'copy');
});
test('cache metrics use returned counts, never substitute missing fields with zero', () => {
const raw = 'data: {"usage":{"prompt_tokens":100,"prompt_tokens_details":{"cached_tokens":64}}}\n\ndata: [DONE]\n';
assert.deepEqual(responseUsage(raw), { inputTokens: 100, cachedTokens: 64, cacheRate: 0.64 });
assert.equal(responseUsage('{"usage":{"prompt_tokens":100}}').cacheRate, null);
assert.equal(responseUsage('{}').cachedTokens, null);
const anthropic = 'data: {"message":{"usage":{"input_tokens":20,"cache_read_input_tokens":70,"cache_creation_input_tokens":10}}}\n\ndata: {"usage":{"output_tokens":12}}';
assert.deepEqual(responseUsage(anthropic), { inputTokens:100, cachedTokens:70, cacheRate:0.7 });
});