Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4234,6 +4234,9 @@ class SessionService : Service() {
// native:set-binding below — has a msg.id, so this replies
// not-implemented-on-mobile rather than no-op'ing.
"native:queue-remove",
// "Send now" on a waiting message — request/response like
// native:queue-remove, so it replies not-implemented-on-mobile.
"native:queue-send-now",
"native:interrupt",
// Stalled-turn Retry. Fire-and-forget (no msg.id) exactly like
// native:send / native:interrupt, so this is a correct no-op here:
Expand Down
14 changes: 7 additions & 7 deletions desktop/line-budgets.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,22 @@
"renderer/dev/workbench/fixtures/marketplace/registry.ts": "generated sample of the marketplace registries (regenerated by a script, not hand-edited)"
},
"budgets": {
"main/ipc-handlers.ts": 5728,
"main/harness/native-session-host.ts": 5296,
"renderer/App.tsx": 4966,
"main/remote-server.ts": 4217,
"main/ipc-handlers.ts": 5731,
"main/harness/native-session-host.ts": 5311,
"renderer/App.tsx": 4981,
"main/remote-server.ts": 4223,
"main/harness/harness-session.ts": 4229,
"renderer/components/SettingsPanel.tsx": 3256,
"renderer/remote-shim.ts": 3176,
"renderer/remote-shim.ts": 3177,
"renderer/state/chat-reducer.ts": 3397,
"renderer/styles/globals.css": 2960,
"renderer/components/SessionStrip.tsx": 2784,
"main/main.ts": 2604,
"shared/types.ts": 2391,
"shared/types.ts": 2394,
"renderer/components/SyncPanel.tsx": 2060,
"main/engine/engine-manager.ts": 2035,
"renderer/components/ResumeBrowser.tsx": 2069,
"main/preload.ts": 1961,
"main/preload.ts": 1963,
"renderer/components/StatusBar.tsx": 1809,
"renderer/components/ToolCard.tsx": 1636
}
Expand Down
2 changes: 1 addition & 1 deletion desktop/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"lint": "oxlint --type-aware",
"postinstall": "node scripts/patch-node-pty.js && node scripts/patch-xterm-webgl-mipmap.js",
"typecheck": "tsgo --noEmit -p tsconfig.json && tsgo --noEmit -p tsconfig.tests.json",
"lint:design": "oxlint -c .oxlintrc.design.json --format default --max-warnings 542"
"lint:design": "oxlint -c .oxlintrc.design.json --format default --max-warnings 537"
},
"keywords": [],
"author": "itsdestin",
Expand Down
66 changes: 66 additions & 0 deletions desktop/src/main/harness/busy-message-boundary.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import type { ModelMessage } from 'ai';
import { finalizeRemainingCalls } from './tool-group-finalization';

export interface BusyMessage {
id: string;
text: string;
attachments: string[];
restore?: () => void;
}

/** WHY: the claim and acceptance are one synchronous boundary. An exception
* returns the unaccepted head to its host, rather than losing a queued send. */
export function claimBusyMessage(
take: (() => BusyMessage | undefined) | undefined,
accept: (item: BusyMessage) => void,
beforeAccept?: () => void,
): boolean {
const item = take?.();
if (!item) return false;
try {
beforeAccept?.();
accept(item);
} catch (err) {
item.restore?.();
throw err;
}
return true;
}

/** WHY: the emitted event is the authority for both live and rebuilt history;
* no synthetic steer or app-generated marker is used for human input. */
export function appendUserHistory(
text: string, attachments: string[], emit: () => string, appGenerated: boolean,
imageParts: (paths: string[]) => Array<{ type: 'file'; mediaType: string; data: Buffer }>,
markAppGenerated: (message: ModelMessage) => ModelMessage,
history: ModelMessage[], origins: Array<string[] | null>, record: (uuid: string) => void,
): void {
const images = imageParts(attachments);
const uuid = emit();
const message = (images.length
? { role: 'user', content: [{ type: 'text', text }, ...images] } as ModelMessage
: { role: 'user', content: text } as ModelMessage);
history.push(appGenerated ? markAppGenerated(message) : message);
origins.push([uuid]);
record(uuid);
}

/** Pair every unstarted call before adding new human input. Already completed
* results stay at the front of the same tool message. */
export function supersedeToolGroup<TCall extends { toolCallId: string; toolName: string }, TPart>(
calls: readonly TCall[], from: number, completed: TPart[], completedOrigins: string[],
emit: (data: { toolUseId: string; toolName: string; toolResult: string; isError: true }) => string,
part: (call: TCall, text: string) => TPart,
record: (uuid: string) => void, commit: (parts: TPart[], origins: string[]) => void,
injectCompleted: (calls: TCall[]) => void,
reason = 'Not run: new user input arrived before this action started.',
afterCompleted?: () => void,
): void {
const remaining = finalizeRemainingCalls(calls, from,
() => reason,
(call, text) => emit({ toolUseId: call.toolCallId, toolName: call.toolName, toolResult: text, isError: true }), part);
remaining.origins.forEach(record);
commit([...completed, ...remaining.parts], [...completedOrigins, ...remaining.origins]);
injectCompleted(calls.slice(0, from));
afterCompleted?.();
}
5 changes: 5 additions & 0 deletions desktop/src/main/harness/eval/run-case.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { ASSISTANT_PRESET } from '../../../shared/harness-manifest';
import { CORE_TOOLS } from '../tools';
import { seedFixtureWorkspace } from './fixture-workspace';
import { assembleSystemPrompt } from '../prompt-assembly';
import { prepareProjectInstructions } from '../injection/project-instructions';
import { resolvePreset } from '../preset-registry';
import { BATTERY_PROMPT } from './battery';
import type { TranscriptEvent } from '../../../shared/types';
Expand Down Expand Up @@ -411,6 +412,9 @@ export async function runCase(opts: RunCaseOpts): Promise<CaseRun> {
const wrapUpPrompt = opts.wrapUpPrompt ?? WRAP_UP_PROMPT;

const fixtureRoot = seedFixtureWorkspace(opts.instructions);
// WHY: evaluator uses the production async inventory, but fixture experiments
// cannot silently inherit real instructions above their disposable root.
const projectInstructionFiles = await prepareProjectInstructions(fixtureRoot, 20_000, fixtureRoot);
const events: TranscriptEvent[] = [];
let toolCalls = 0;
let asks = 0;
Expand Down Expand Up @@ -486,6 +490,7 @@ export async function runCase(opts: RunCaseOpts): Promise<CaseRun> {
presetBody: resolvePreset('assistant').body,
cwd: fixtureRoot,
appVersion: 'eval',
projectInstructionFiles,
}),
// Load-bearing (2026-08-11): omitted, HarnessSession takes fitToContext's
// own 32_768 default, which against this harness's output ceiling left a
Expand Down
Loading
Loading