Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@

### Changed

- Made typed `request()` the sole direct Runtime Host operation API; removed the 17 forwarding
aliases from direct and reconnecting connections while preserving status validation,
subscriptions, capabilities, listeners, lifecycle, and close behavior.
- Collapsed the RuntimeRunner/Flow/Invocation shell into `RuntimeKernel`; backend dispatch,
terminal coalescing, stop/drain, and durable continuation admission now have one production
owner, immutable request snapshots remain enforced at AgentRun acceptance and backend dispatch,
Expand Down
2 changes: 1 addition & 1 deletion apps/desktop/src/main/runtime-host-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1150,7 +1150,7 @@ export class DesktopRuntimeHostClient {
}

queryHostDiagnostics(): Promise<OperationOutput<"host.diagnostics.query">> {
return this.connection.queryHostDiagnostics(2_000);
return this.connection.request('host.diagnostics.query', {}, 2_000);
}

prepareHostRetirement(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1606,7 +1606,6 @@ class FakeConnection {
hostEpoch: 'host-1',
request: <K extends DirectRequestOperationKey>(operation: K, input: OperationInput<K>) =>
this.request(operation, input),
startTurn: (input) => this.request('turn.start', input),
openSessionSubscription: async () => {
const subscription = this.subscriptions[this.openedSubscriptions];
this.openedSubscriptions += 1;
Expand Down
4 changes: 2 additions & 2 deletions packages/cli/src/runtime-host-service-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1068,7 +1068,7 @@ export async function verifyRuntimeHostManagedServiceReady(
const status = await connected.connection.status(Math.max(1, remaining));
if (status.state === 'ready') {
const [diagnostics, service] = await Promise.all([
connected.connection.queryHostDiagnostics(),
connected.connection.request('host.diagnostics.query', {}),
backend.status(),
]);
if (service.active && service.pid !== null && diagnostics.pid === service.pid) return;
Expand Down Expand Up @@ -1118,7 +1118,7 @@ async function prepareRuntimeHostRetirement(
}
const hostEpoch = connected.connection.hostEpoch;
try {
const diagnostics = await connected.connection.queryHostDiagnostics();
const diagnostics = await connected.connection.request('host.diagnostics.query', {});
if (diagnostics.pid !== expectedPid) {
throw new RuntimeHostServiceManagerError(
'retirement_failed',
Expand Down
4 changes: 2 additions & 2 deletions packages/cli/src/runtime-host-session-driver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ export interface RuntimeHostMakaSessionDriverInput {

type RuntimeHostSessionDriverConnection = Pick<
RuntimeHostConnection,
'hostEpoch' | 'openSessionSubscription' | 'request' | 'startTurn'
'hostEpoch' | 'openSessionSubscription' | 'request'
>;

export interface RuntimeHostMakaSessionDriver extends MakaSessionDriver {
Expand Down Expand Up @@ -286,7 +286,7 @@ class RuntimeHostMakaSessionDriverImpl implements RuntimeHostMakaSessionDriver {
...(options.turnOrchestration ? { turnOrchestration: options.turnOrchestration } : {}),
...(options.maxSteps !== undefined ? { maxSteps: options.maxSteps } : {}),
};
const result = await this.#connection.startTurn(startInput);
const result = await this.#connection.request('turn.start', startInput);
if (result.kind === 'blocked') {
throw new SkillInvocationBlockedError(result.skillInvocation);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ test('concurrent responses remain framed and correlated in reverse completion or
async ({ connectClient }) => {
const client = await connectClient();
const requests = Array.from({ length: requestCount }, (_, index) =>
client.queryTurn({ sessionId: 'session', turnId: `turn-${index}` }, 5_000),
client.request('turn.query', { sessionId: 'session', turnId: `turn-${index}` }, 5_000),
);
try {
await withTimeout(
Expand Down Expand Up @@ -257,7 +257,7 @@ test('the Client backpressures a healthy request burst at the Host connection li
async ({ connectClient }) => {
const client = await connectClient();
const requests = Array.from({ length: requestCount }, (_, index) =>
client.queryTurn({ sessionId: 'session', turnId: `burst-${index}` }, 5_000),
client.request('turn.query', { sessionId: 'session', turnId: `burst-${index}` }, 5_000),
);
try {
await withTimeout(firstWaveEntered.promise, 1_000, 'first request wave was not admitted');
Expand Down Expand Up @@ -656,7 +656,7 @@ test('an admitted operation settles without connection or residency leakage afte
async ({ connectClient }) => {
const client = await connectClient();
const requestFailure = client
.queryTurn({ sessionId: 'session', turnId: 'disconnect' }, 5_000)
.request('turn.query', { sessionId: 'session', turnId: 'disconnect' }, 5_000)
.then(
() => undefined,
(error: unknown) => error,
Expand Down Expand Up @@ -698,7 +698,7 @@ test('an admitted command reports an unknown outcome when its connection closes'
}),
async ({ connectClient }) => {
const client = await connectClient();
const command = client.startTurn({
const command = client.request('turn.start', {
sessionId: 'session',
turnId: 'interrupted-command',
content: { text: 'start' },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,19 +84,19 @@ test('two Clients share Daily Review config, generation, and restart recovery',
owner = undefined;
[desktop, tui] = await Promise.all([connect(root), connect(root)]);

const initial = await desktop.queryDailyReview({ kind: 'config' });
const initial = await desktop.request('daily-review.query', { kind: 'config' });
assert.deepEqual(initial, {
kind: 'config',
revision: 0,
config: { enabled: false, executeTime: '08:00', modelKey: '' },
});
const mutations = await Promise.all([
desktop.mutateDailyReview({
desktop.request('daily-review.mutate', {
kind: 'update_config',
expectedRevision: 0,
config: { enabled: false, executeTime: '09:00', modelKey: '' },
}),
tui.mutateDailyReview({
tui.request('daily-review.mutate', {
kind: 'update_config',
expectedRevision: 0,
config: { enabled: false, executeTime: '10:00', modelKey: '' },
Expand All @@ -105,8 +105,8 @@ test('two Clients share Daily Review config, generation, and restart recovery',
assert.equal(mutations.filter((result) => result.kind === 'config_committed').length, 1);
assert.equal(mutations.filter((result) => result.kind === 'revision_conflict').length, 1);
assert.deepEqual(
await desktop.queryDailyReview({ kind: 'config' }),
await tui.queryDailyReview({ kind: 'config' }),
await desktop.request('daily-review.query', { kind: 'config' }),
await tui.request('daily-review.query', { kind: 'config' }),
);

const run = {
Expand All @@ -117,15 +117,15 @@ test('two Clients share Daily Review config, generation, and restart recovery',
replaceExisting: false,
};
const [desktopRun, tuiRun] = await Promise.all([
desktop.mutateDailyReview(run),
tui.mutateDailyReview(run),
desktop.request('daily-review.mutate', run),
tui.request('daily-review.mutate', run),
]);
assert.deepEqual(tuiRun, desktopRun);
assert.equal(desktopRun.kind, 'archive');
if (desktopRun.kind !== 'archive') return;
assert.equal(desktopRun.archive.status, 'no_data');

const noModel = await desktop.mutateDailyReview({
const noModel = await desktop.request('daily-review.mutate', {
...run,
offsetDays: 0,
modelKeyOverride: 'missing-provider::missing-model',
Expand All @@ -135,7 +135,7 @@ test('two Clients share Daily Review config, generation, and restart recovery',
assert.equal(noModel.archive.status, 'no_model');
assert.equal(noModel.archive.totals.requestCount, 1);

const enabled = await desktop.mutateDailyReview({
const enabled = await desktop.request('daily-review.mutate', {
kind: 'update_config',
expectedRevision: 1,
config: {
Expand Down Expand Up @@ -164,14 +164,14 @@ test('two Clients share Daily Review config, generation, and restart recovery',
owner = undefined;
tui = await connect(root);
assert.deepEqual(
await tui.queryDailyReview({
await tui.request('daily-review.query', {
kind: 'archive',
archiveId: desktopRun.archive.id,
}),
{ kind: 'archive', archive: desktopRun.archive },
);
assert.deepEqual(
await tui.queryDailyReview({
await tui.request('daily-review.query', {
kind: 'archive',
archiveId: scheduled.id,
}),
Expand Down Expand Up @@ -201,15 +201,15 @@ async function waitForScheduledArchive(
): Promise<DailyReviewArchive> {
const deadline = Date.now() + 5_000;
while (Date.now() < deadline) {
const page = await connection.queryDailyReview({
const page = await connection.request('daily-review.query', {
kind: 'archives',
beforeArchiveId: null,
limit: 10,
});
if (page.kind === 'archives') {
const scheduled = page.archives.find((archive) => archive.trigger === 'cron');
if (scheduled) {
const result = await connection.queryDailyReview({
const result = await connection.request('daily-review.query', {
kind: 'archive',
archiveId: scheduled.id,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ test('two Clients and a restarted production Host share one Deep Research projec
[desktop, tui] = await Promise.all([connect(root), connect(root)]);

const [desktopProjection, tuiProjection] = await Promise.all([
desktop.queryDeepResearch({ sessionId: session.id }),
tui.queryDeepResearch({ sessionId: session.id }),
desktop.request('deep-research.query', { sessionId: session.id }),
tui.request('deep-research.query', { sessionId: session.id }),
]);
assert.deepEqual(tuiProjection, desktopProjection);
assert.equal(desktopProjection.kind, 'snapshot');
Expand Down Expand Up @@ -128,7 +128,10 @@ test('two Clients and a restarted production Host share one Deep Research projec
owner = undefined;
tui = await connect(root);

assert.deepEqual(await tui.queryDeepResearch({ sessionId: session.id }), desktopProjection);
assert.deepEqual(
await tui.request('deep-research.query', { sessionId: session.id }),
desktopProjection,
);
} finally {
await Promise.allSettled([desktop?.close(), tui?.close()]);
await host?.close().catch(() => undefined);
Expand Down
Loading
Loading