feat: complete WorkBuddy parity and Windows release workflow
This commit is contained in:
1 parent
143516b3a8
commit
d5512df549
434 files changed
+54977
-1854
No files matched your search
@@ -15,6 +15,7 @@ interface PersistenceTestState {
|
||||
cancelOutputEmitted: boolean
|
||||
useOmp: boolean
|
||||
fallbackHistory: ChatMessage[] | null
|
||||
fallbackWireHistory?: Array<{ role: string; content: string }>
|
||||
}
|
||||
|
||||
const TEST_STATE_KEY = '__YCODE_CHAT_PERSISTENCE_TEST__'
|
||||
@@ -112,7 +113,11 @@ async function main(): Promise<void> {
|
||||
export const app = {
|
||||
getPath: (name) => name === 'userData' ? state.userData : state.userData,
|
||||
getName: () => 'YCode',
|
||||
getVersion: () => '0.1.0'
|
||||
getVersion: () => '0.1.0',
|
||||
isPackaged: false, isReady: () => true,
|
||||
getAppPath: () => state.userData,
|
||||
getLoginItemSettings: () => ({ openAtLogin: false }),
|
||||
setLoginItemSettings: () => {}
|
||||
};
|
||||
export const safeStorage = {
|
||||
isEncryptionAvailable: () => false,
|
||||
@@ -124,6 +129,7 @@ async function main(): Promise<void> {
|
||||
};
|
||||
export const dialog = { showOpenDialog: async () => ({ canceled: true, filePaths: [] }) };
|
||||
export const shell = { openPath: async () => '' };
|
||||
export const powerSaveBlocker = { start: () => 1, stop: () => true, isStarted: () => false };
|
||||
export class BrowserWindow {}
|
||||
export class WebContentsView {}
|
||||
`
|
||||
@@ -139,6 +145,7 @@ async function main(): Promise<void> {
|
||||
const emit = (kernel, frame) => kernel.emit('event', frame);
|
||||
export class OmpKernel extends EventEmitter {
|
||||
constructor() { super(); }
|
||||
setThinkingLevel() { return Promise.resolve(); }
|
||||
setHostTools() { return Promise.resolve({ type: 'response', success: true, data: { toolNames: [] } }); }
|
||||
send() { return Promise.resolve({ type: 'response', success: true, data: { messages: [] } }); }
|
||||
prompt(message) {
|
||||
@@ -152,11 +159,13 @@ async function main(): Promise<void> {
|
||||
});
|
||||
} else {
|
||||
setImmediate(() => {
|
||||
emit(this, { type: 'message_end', message: { role: 'assistant', usage: { input: 1200, output: 10, totalTokens: 1210 } } });
|
||||
emit(this, { type: 'message_update', assistantMessageEvent: { type: 'text_delta', delta: 'before' } });
|
||||
emit(this, { type: 'tool_execution_start', toolCall: { id: toolId, name: 'read_file', args: { path: 'large.txt' } } });
|
||||
emit(this, { type: 'tool_execution_update', toolCall: { id: toolId, partialResult: fullOutput } });
|
||||
emit(this, { type: 'message_update', assistantMessageEvent: { type: 'text_delta', delta: 'after' } });
|
||||
emit(this, { type: 'tool_execution_end', toolCall: { id: toolId, name: 'read_file', result: { content: [{ type: 'text', text: fullOutput }], isError: false }, success: true } });
|
||||
emit(this, { type: 'message_end', message: { role: 'assistant', usage: { contextTokens: 12800, input: 12000, cacheRead: 800, output: 200, totalTokens: 13000 } } });
|
||||
emit(this, { type: 'agent_end', yielded: true });
|
||||
});
|
||||
}
|
||||
@@ -180,6 +189,7 @@ async function main(): Promise<void> {
|
||||
const state = globalThis.${TEST_STATE_KEY};
|
||||
export async function runTurn(options) {
|
||||
state.fallbackHistory = options.history;
|
||||
state.fallbackWireHistory = options.wireHistory;
|
||||
const content = 'fallback response';
|
||||
options.emit({ runId: options.runId, type: 'text', delta: content });
|
||||
options.emit({ runId: options.runId, type: 'done', content, tools: [] });
|
||||
@@ -208,6 +218,9 @@ async function main(): Promise<void> {
|
||||
return Promise.resolve(handler({}, ...args))
|
||||
}
|
||||
|
||||
await invoke('models:save', { id: 'usage-snapshot-model', name: 'Usage snapshot model', providerId: 'custom',
|
||||
model: 'usage-test', baseUrl: 'http://127.0.0.1:1/v1', authMode: 'none', maxInputTokens: 64000 })
|
||||
await invoke('models:select', 'usage-snapshot-model')
|
||||
const normalSession = (await invoke('session:create', 'ordered persistence')) as { id: string }
|
||||
await invoke('chat:send', { sessionId: normalSession.id, text: 'persist-order' })
|
||||
const normalMessages = await waitForMessages(invoke, normalSession.id, (messages) => assistant(messages).status === 'done')
|
||||
@@ -231,6 +244,13 @@ async function main(): Promise<void> {
|
||||
'the summary may be truncated while full output remains intact')
|
||||
|
||||
const diskNormalAssistant = assistant(await readDiskMessages(state.userData, normalSession.id))
|
||||
assert.deepEqual(normalAssistant.contextUsage, {
|
||||
usage: { inputTokens: 12800, outputTokens: 200, totalTokens: 13000, cachedTokens: 800 }, contextWindow: 64000,
|
||||
modelId:'usage-snapshot-model',requestId:normalAssistant.requestId,source:'upstream',sampledAt:normalAssistant.contextUsage?.sampledAt
|
||||
}, 'latest tool-round input is a sample, not the sum of all round usage')
|
||||
assert.ok((normalAssistant.contextUsage?.sampledAt??0)>=normalAssistant.createdAt,'the persisted sample identifies its observation time')
|
||||
assert.deepEqual(diskNormalAssistant.contextUsage, normalAssistant.contextUsage,
|
||||
'the checkpoint whitelist must persist the upstream sample and frozen denominator together')
|
||||
assert.deepEqual(diskNormalAssistant.parts, expectedParts, 'disk JSON should retain text/tool/text order')
|
||||
assert.ok((diskNormalAssistant.tools?.[0].output?.length ?? 0) > 600,
|
||||
'disk JSON should retain output beyond the summary limit')
|
||||
@@ -246,6 +266,7 @@ async function main(): Promise<void> {
|
||||
id: 'fallback-user',
|
||||
role: 'user',
|
||||
content: 'old request',
|
||||
quotes: [{ id: 'saved-table', sourceId: 'table-source', kind: 'table', markdown: '| name | value |\n| --- | --- |\n| A | 42 |', preview: 'A 42' }],
|
||||
createdAt: Date.now(),
|
||||
status: 'done'
|
||||
})
|
||||
@@ -267,6 +288,8 @@ async function main(): Promise<void> {
|
||||
assert.equal(assistant(fallbackMessages).content, 'fallback response')
|
||||
assert.deepEqual(state.fallbackHistory?.map((message) => message.content), ['old request', 'old answer'],
|
||||
'the fallback loop should receive previously persisted user and assistant messages')
|
||||
assert.equal(state.fallbackWireHistory?.[0].content, 'old request\n\n| name | value |\n| --- | --- |\n| A | 42 |',
|
||||
'the next fallback request must include the exact previously quoted table snapshot')
|
||||
state.useOmp = true
|
||||
|
||||
const cancelSession = (await invoke('session:create', 'cancelled persistence')) as { id: string }
|
||||
|
||||
Reference in new issue
Block a user