wip: desparate models fucking around

This commit is contained in:
2026-02-26 00:13:52 +01:00
parent 021cddefa3
commit 2a923c7e48
16 changed files with 684 additions and 113 deletions

View File

@@ -192,4 +192,49 @@ describe('assistantPanelSpec', () => {
expect(result).not.toBeNull();
expect(result?.elements).toHaveLength(7);
});
it('parses canonical protocol envelope JSON and extracts assistant text plus ui spec', () => {
const raw = JSON.stringify({
protocolVersion: '2.0',
assistantText: 'Here is your chart.',
ui: {
specVersion: '1',
elements: [
{
type: 'chart',
chartType: 'bar',
data: {
labels: ['aside', 'article'],
datasets: [{ data: [181, 53] }],
},
},
{
type: 'text',
content: 'Breakdown details',
},
],
},
intent: 'summarize',
needsInput: { required: false, fields: [] },
actions: [],
confidence: 0.9,
traceId: 'trace-1',
});
const result = extractAssistantResponseContent(raw);
expect(result.displayText).toBe('Here is your chart.');
expect(result.panelSpec).not.toBeNull();
expect(result.panelSpec?.elements[0]).toMatchObject({
type: 'chart',
series: [
{ label: 'aside', value: 181 },
{ label: 'article', value: 53 },
],
});
expect(result.panelSpec?.elements[1]).toEqual({
type: 'text',
text: 'Breakdown details',
});
});
});

View File

@@ -0,0 +1,56 @@
import { describe, expect, it } from 'vitest';
import { buildActionPoliciesFromEnvelope } from '../../../src/renderer/navigation/protocolActionPolicies';
describe('buildActionPoliciesFromEnvelope', () => {
it('preserves server-provided action policies', () => {
const result = buildActionPoliciesFromEnvelope({
actions: [
{
id: 'a1',
action: 'openSettings',
policy: 'confirm',
requiresConfirmation: true,
},
],
needsInput: {
required: false,
fields: [],
},
});
expect(result).toEqual({
openSettings: 'confirm',
});
});
it('adds confirm policy for submitNeedsInput when clarification is required', () => {
const result = buildActionPoliciesFromEnvelope({
actions: [],
needsInput: {
required: true,
fields: [{ key: 'date', label: 'Date', inputType: 'date' }],
},
});
expect(result.submitNeedsInput).toBe('confirm');
});
it('does not override explicit server policy for submitNeedsInput', () => {
const result = buildActionPoliciesFromEnvelope({
actions: [
{
id: 'a1',
action: 'submitNeedsInput',
policy: 'danger',
requiresConfirmation: true,
},
],
needsInput: {
required: true,
fields: [{ key: 'title', label: 'Title', inputType: 'text' }],
},
});
expect(result.submitNeedsInput).toBe('danger');
});
});

View File

@@ -44,9 +44,34 @@ describe('pythonApiContractV1', () => {
});
});
it('documents chat.sendMessage protocol envelope return contract and metadata input', () => {
expect(getPythonApiMethodContract('chat.sendMessage')).toEqual({
method: 'chat.sendMessage',
description: 'Send message to chat conversation.',
params: [
{
name: 'conversationId',
type: 'string',
required: true,
},
{
name: 'message',
type: 'string',
required: true,
},
{
name: 'metadata',
type: 'object',
required: false,
},
],
returns: "{ success: boolean; message?: string; envelope?: ProtocolResponseEnvelope; protocolVersion?: '2.0'; traceId?: string; warnings?: string[]; error?: string }",
});
});
it('contains semantic version metadata for compatibility checks', () => {
expect(BDS_PYTHON_API_CONTRACT_V1).toMatchObject({
version: '1.4.0',
version: '1.5.0',
generatedAt: expect.any(String),
});
});
@@ -56,6 +81,7 @@ describe('pythonApiContractV1', () => {
expect.objectContaining({ name: 'PostData' }),
expect.objectContaining({ name: 'MediaData' }),
expect.objectContaining({ name: 'ProjectData' }),
expect.objectContaining({ name: 'ProtocolResponseEnvelope' }),
expect.objectContaining({ name: 'ProtocolTelemetrySnapshot' }),
]));
});
@@ -76,7 +102,7 @@ describe('generatePythonApiModuleV1', () => {
expect(moduleCode).toContain('async def search(self, query):');
expect(moduleCode).toContain('async def get_project_metadata(self):');
expect(moduleCode).toContain('async def get_conversations(self):');
expect(moduleCode).toContain('async def send_message(self, conversation_id, message):');
expect(moduleCode).toContain('async def send_message(self, conversation_id, message, metadata=None):');
expect(moduleCode).toContain('class BdsApi:');
expect(moduleCode).toContain('bds = BdsApi(_transport)');
});