You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maka.apache.org by as...@apache.org on 2026/08/26 14:57:57 UTC
(maka) 06/26: refactor(desktop): separate message admission from exact turns
This is an automated email from the ASF dual-hosted git repository.
Astro-Han pushed a commit to branch fix/canonical-message-projection
in repository https://gitbox.apache.org/repos/asf/maka.git
commit da2a2fac59f1554f2dc0297e02c03c0970f4b50d
Author: AstroHan <le...@outlook.com>
AuthorDate: Wed Aug 26 04:25:42 2026 +0800
refactor(desktop): separate message admission from exact turns
Generated-by: Codex
---
.../workhub-coordination-host-scope.test.ts | 25 -----
apps/desktop/src/preload/bridge-contract.d.ts | 62 +++++++----
apps/desktop/src/preload/preload.ts | 115 +++++++++------------
.../desktop/src/renderer/app-shell-chat-actions.ts | 36 +++++--
.../platform/desktop/create-workbar-services.ts | 8 +-
.../renderer/workhub-coordination-host-scope.ts | 31 +-----
6 files changed, 119 insertions(+), 158 deletions(-)
diff --git a/apps/desktop/src/main/__tests__/workhub-coordination-host-scope.test.ts b/apps/desktop/src/main/__tests__/workhub-coordination-host-scope.test.ts
index 3f65c2e55..0a4e014fe 100644
--- a/apps/desktop/src/main/__tests__/workhub-coordination-host-scope.test.ts
+++ b/apps/desktop/src/main/__tests__/workhub-coordination-host-scope.test.ts
@@ -122,31 +122,6 @@ test('WorkHub candidates follow the resolved Coordination Session Host only', as
stop();
});
-test('WorkHub rejects an ordinary message admission at its exact Turn adapter', async () => {
- const sessionId = desktopSessionKey({ hostId: 'host-a', sessionId: 'ordinary-a' });
- const sessions = scopeWorkHubSessionsToCoordinationHost(
- {
- list: async () => [ordinarySession(sessionId)],
- listTurns: async () => [],
- create: async () => ordinarySession(sessionId),
- send: async () => ({
- ok: true,
- disposition: 'steering',
- messageId: 'message-1',
- }),
- stop: async () => undefined,
- subscribeChanges: () => () => undefined,
- },
- { sessionId, isCurrent: () => true },
- async () => ordinarySession(sessionId),
- );
-
- await assert.rejects(
- sessions.send(sessionId, { type: 'send', turnId: 'turn-1', text: 'coordinate' }),
- /ordinary message admission/,
- );
-});
-
function ordinarySession(id: string): Awaited<ReturnType<WorkHubDesktopSessionBridge['list']>>[number] {
return {
id,
diff --git a/apps/desktop/src/preload/bridge-contract.d.ts b/apps/desktop/src/preload/bridge-contract.d.ts
index 1afdfe448..57cbbacdb 100644
--- a/apps/desktop/src/preload/bridge-contract.d.ts
+++ b/apps/desktop/src/preload/bridge-contract.d.ts
@@ -801,25 +801,22 @@ export interface MakaBridge {
completeHostIds: string[];
}>;
create(input?: CreateSessionRequestInput): Promise<DesktopSessionSummary>;
- send(
+ submitMessage(
sessionId: string,
- command:
- | SessionCommand
- | {
- type: 'send';
- messageId?: string;
- turnId?: string;
- text: string;
- displayText?: string;
- skillIds?: string[];
- attachmentItems?: RendererIngestInput[];
- retainedAttachments?: import('@maka/core/events').AttachmentRef[];
- turnOrchestration?: TurnOrchestration;
- quotes?: import('@maka/core/events').QuoteRef[];
- workspaceFileReferences?: Array<
- Pick<import('@maka/core/events').InlineReference, 'value' | 'start'>
- >;
- },
+ command: {
+ type: 'send';
+ messageId: string;
+ text: string;
+ displayText?: string;
+ skillIds?: string[];
+ attachmentItems?: RendererIngestInput[];
+ retainedAttachments?: import('@maka/core/events').AttachmentRef[];
+ turnOrchestration?: never;
+ quotes?: import('@maka/core/events').QuoteRef[];
+ workspaceFileReferences?: Array<
+ Pick<import('@maka/core/events').InlineReference, 'value' | 'start'>
+ >;
+ },
): Promise<
| {
ok: true;
@@ -830,6 +827,35 @@ export interface MakaBridge {
inlineReferences: import('@maka/core/events').InlineReference[];
skillInvocation: import('@maka/runtime/skill-invocation').SkillInvocationResult;
}
+ | {
+ ok: false;
+ reason: 'skill_invocation_failed';
+ skillInvocation: import('@maka/runtime/skill-invocation').SkillInvocationResult;
+ }
+ | {
+ ok: false;
+ reason: 'outcome_unknown';
+ messageId: string;
+ skillInvocation: import('@maka/runtime/skill-invocation').SkillInvocationResult;
+ }
+ >;
+ send(
+ sessionId: string,
+ command: {
+ type: 'send';
+ turnId: string;
+ text: string;
+ displayText?: string;
+ skillIds?: string[];
+ attachmentItems?: RendererIngestInput[];
+ retainedAttachments?: import('@maka/core/events').AttachmentRef[];
+ turnOrchestration?: TurnOrchestration;
+ quotes?: import('@maka/core/events').QuoteRef[];
+ workspaceFileReferences?: Array<
+ Pick<import('@maka/core/events').InlineReference, 'value' | 'start'>
+ >;
+ },
+ ): Promise<
| {
ok: true;
turnId: string;
diff --git a/apps/desktop/src/preload/preload.ts b/apps/desktop/src/preload/preload.ts
index ae313ebd1..d646d8aa1 100644
--- a/apps/desktop/src/preload/preload.ts
+++ b/apps/desktop/src/preload/preload.ts
@@ -854,6 +854,47 @@ async function createDesktopSessionOnScope(
return projectSessionSummary(scope, session);
}
+function sendDesktopSessionCommand(
+ sessionId: string,
+ command: Parameters<MakaBridge['sessions']['submitMessage']>[1],
+): ReturnType<MakaBridge['sessions']['submitMessage']>;
+function sendDesktopSessionCommand(
+ sessionId: string,
+ command: Parameters<MakaBridge['sessions']['send']>[1],
+): ReturnType<MakaBridge['sessions']['send']>;
+async function sendDesktopSessionCommand(
+ sessionId: string,
+ command:
+ | Parameters<MakaBridge['sessions']['submitMessage']>[1]
+ | Parameters<MakaBridge['sessions']['send']>[1],
+): Promise<
+ | Awaited<ReturnType<MakaBridge['sessions']['submitMessage']>>
+ | Awaited<ReturnType<MakaBridge['sessions']['send']>>
+> {
+ const session = await runtimeHostSessionRef(sessionId);
+ const send = async (input: SessionCommand | Record<string, unknown>) => {
+ const result = (await ipcRenderer.invoke(
+ 'sessions:send',
+ session.scope,
+ session.sessionId,
+ input,
+ )) as
+ | Awaited<ReturnType<MakaBridge['sessions']['submitMessage']>>
+ | Awaited<ReturnType<MakaBridge['sessions']['send']>>;
+ return result.ok
+ ? {
+ ...result,
+ attachments: projectDesktopAttachmentRefs(session.scope, result.attachments),
+ }
+ : result;
+ };
+ if (command.type === 'send' && 'attachmentItems' in command && command.attachmentItems) {
+ const encoded = await encodeIngestItems(command.attachmentItems as RendererIngestInput[]);
+ return send({ ...command, attachmentItems: encoded });
+ }
+ return send(command);
+}
+
function sendActiveRuntimeHost(channel: string, ...args: unknown[]): void {
void activeRuntimeHostRef()
.then((scope) => ipcRenderer.send(channel, scope, ...args))
@@ -1644,75 +1685,11 @@ const makaBridge = {
const scope = await activeRuntimeHostRef();
return createDesktopSessionOnScope(scope, input);
},
- async send(
- sessionId: string,
- command:
- | SessionCommand
- | {
- type: 'send';
- messageId?: string;
- turnId?: string;
- text: string;
- displayText?: string;
- skillIds?: string[];
- attachmentItems?: RendererIngestInput[];
- retainedAttachments?: AttachmentRef[];
- turnOrchestration?: TurnOrchestration;
- quotes?: QuoteRef[];
- workspaceFileReferences?: Array<Pick<InlineReference, 'value' | 'start'>>;
- },
- ): Promise<
- | {
- ok: true;
- disposition: 'turn_started' | 'steering' | 'followup';
- messageId: string;
- turnId?: string;
- attachments: AttachmentRef[];
- inlineReferences: InlineReference[];
- skillInvocation: import('@maka/runtime/skill-invocation').SkillInvocationResult;
- }
- | {
- ok: true;
- turnId: string;
- attachments: AttachmentRef[];
- inlineReferences: InlineReference[];
- skillInvocation: import('@maka/runtime/skill-invocation').SkillInvocationResult;
- }
- | {
- ok: false;
- reason: 'skill_invocation_failed';
- skillInvocation: import('@maka/runtime/skill-invocation').SkillInvocationResult;
- }
- | {
- ok: false;
- reason: 'outcome_unknown';
- messageId: string;
- skillInvocation: import('@maka/runtime/skill-invocation').SkillInvocationResult;
- }
- > {
- const session = await runtimeHostSessionRef(sessionId);
- const send = async (input: SessionCommand | Record<string, unknown>) => {
- const result = await ipcRenderer.invoke(
- 'sessions:send',
- session.scope,
- session.sessionId,
- input,
- ) as Awaited<ReturnType<MakaBridge['sessions']['send']>>;
- return result.ok
- ? {
- ...result,
- attachments: projectDesktopAttachmentRefs(session.scope, result.attachments),
- }
- : result;
- };
- if (command.type === 'send' && 'attachmentItems' in command && command.attachmentItems) {
- const encoded = await encodeIngestItems(command.attachmentItems as RendererIngestInput[]);
- return send({
- ...command,
- attachmentItems: encoded,
- });
- }
- return send(command);
+ submitMessage(sessionId, command) {
+ return sendDesktopSessionCommand(sessionId, command);
+ },
+ send(sessionId, command) {
+ return sendDesktopSessionCommand(sessionId, command);
},
compact(sessionId: string): Promise<OperationOutput<'context.compact'>> {
return invokeSessionRuntimeHost('sessions:compact', sessionId);
diff --git a/apps/desktop/src/renderer/app-shell-chat-actions.ts b/apps/desktop/src/renderer/app-shell-chat-actions.ts
index ecd8b5864..1af50bf4e 100644
--- a/apps/desktop/src/renderer/app-shell-chat-actions.ts
+++ b/apps/desktop/src/renderer/app-shell-chat-actions.ts
@@ -388,12 +388,10 @@ export function createAppShellChatActions(deps: {
pending && pending.length > 0
? retainedAttachmentRefs(pending)
: undefined;
- const sendResult = await window.maka.sessions.send(session.id, {
- type: 'send',
- ...(options.turnOrchestration ? { turnId: messageId } : { messageId }),
+ const sendCommand = {
+ type: 'send' as const,
text,
...(options.displayText ? { displayText: options.displayText } : {}),
- ...(options.turnOrchestration ? { turnOrchestration: options.turnOrchestration } : {}),
...(attachmentItems && attachmentItems.length > 0 ? { attachmentItems } : {}),
...(retainedAttachments && retainedAttachments.length > 0
? { retainedAttachments }
@@ -402,7 +400,17 @@ export function createAppShellChatActions(deps: {
...(options.workspaceFileReferences && options.workspaceFileReferences.length > 0
? { workspaceFileReferences: [...options.workspaceFileReferences] }
: {}),
- });
+ };
+ const sendResult = options.turnOrchestration
+ ? await window.maka.sessions.send(session.id, {
+ ...sendCommand,
+ turnId: messageId,
+ turnOrchestration: options.turnOrchestration,
+ })
+ : await window.maka.sessions.submitMessage(session.id, {
+ ...sendCommand,
+ messageId,
+ });
if (!sendResult.ok) {
if (sendResult.reason === 'outcome_unknown') {
unsentSessionId = undefined;
@@ -494,12 +502,10 @@ export function createAppShellChatActions(deps: {
pending && pending.length > 0
? retainedAttachmentRefs(pending)
: undefined;
- const sendResult = await window.maka.sessions.send(sessionId, {
- type: 'send',
- ...(options.turnOrchestration ? { turnId: messageId } : { messageId }),
+ const sendCommand = {
+ type: 'send' as const,
text,
...(options.displayText ? { displayText: options.displayText } : {}),
- ...(options.turnOrchestration ? { turnOrchestration: options.turnOrchestration } : {}),
...(attachmentItems && attachmentItems.length > 0 ? { attachmentItems } : {}),
...(retainedAttachments && retainedAttachments.length > 0
? { retainedAttachments }
@@ -508,7 +514,17 @@ export function createAppShellChatActions(deps: {
...(options.workspaceFileReferences && options.workspaceFileReferences.length > 0
? { workspaceFileReferences: [...options.workspaceFileReferences] }
: {}),
- });
+ };
+ const sendResult = options.turnOrchestration
+ ? await window.maka.sessions.send(sessionId, {
+ ...sendCommand,
+ turnId: messageId,
+ turnOrchestration: options.turnOrchestration,
+ })
+ : await window.maka.sessions.submitMessage(sessionId, {
+ ...sendCommand,
+ messageId,
+ });
if (!sendResult.ok) {
if (sendResult.reason === 'outcome_unknown') return true;
removeOptimisticUserMessage(sessionId, messageId);
diff --git a/apps/desktop/src/renderer/platform/desktop/create-workbar-services.ts b/apps/desktop/src/renderer/platform/desktop/create-workbar-services.ts
index 9a342118e..2cfd56a22 100644
--- a/apps/desktop/src/renderer/platform/desktop/create-workbar-services.ts
+++ b/apps/desktop/src/renderer/platform/desktop/create-workbar-services.ts
@@ -119,13 +119,7 @@ export function createDesktopWorkbarServices(
bridge.sessions.cleanupSessionCopy(sessionId),
abandonSessionCopy: (sourceSessionId, copyId) =>
bridge.sessions.abandonSessionCopy(sourceSessionId, copyId),
- send: async (sessionId, command) => {
- const result = await bridge.sessions.send(sessionId, command);
- if (result.ok && 'disposition' in result) {
- throw new Error('Side Conversation send crossed the ordinary message adapter');
- }
- return result;
- },
+ send: (sessionId, command) => bridge.sessions.send(sessionId, command),
stop: (sessionId, target) =>
bridge.sessions.stop(
sessionId,
diff --git a/apps/desktop/src/renderer/workhub-coordination-host-scope.ts b/apps/desktop/src/renderer/workhub-coordination-host-scope.ts
index 84ad982a4..55ebdb1c9 100644
--- a/apps/desktop/src/renderer/workhub-coordination-host-scope.ts
+++ b/apps/desktop/src/renderer/workhub-coordination-host-scope.ts
@@ -29,16 +29,9 @@ export interface WorkHubCoordinationHostAuthority {
readonly isCurrent: () => boolean;
}
-type WorkHubDesktopSessionSourceBridge = Omit<WorkHubDesktopSessionBridge, 'send'> & {
- send(
- sessionId: string,
- command: { type: 'send'; turnId: string; text: string },
- ): Promise<unknown>;
-};
-
/** Restricts the transitional WorkHub router to the Coordination Session's Host. */
export function scopeWorkHubSessionsToCoordinationHost(
- sessions: WorkHubDesktopSessionSourceBridge,
+ sessions: WorkHubDesktopSessionBridge,
coordination: WorkHubCoordinationHostAuthority,
createOnCoordinationHost: WorkHubCoordinationHostSessionCreator,
): WorkHubDesktopSessionBridge {
@@ -87,27 +80,7 @@ export function scopeWorkHubSessionsToCoordinationHost(
},
async send(sessionId: string, command: { type: 'send'; turnId: string; text: string }) {
requireTargetHost(sessionId);
- const result = await sessions.send(sessionId, command);
- if (!result || typeof result !== 'object' || !('ok' in result)) {
- throw new Error('WorkHub exact Turn send returned an invalid result');
- }
- if (result.ok === false && 'reason' in result && typeof result.reason === 'string') {
- return { ok: false as const, reason: result.reason };
- }
- if (
- result.ok === true &&
- !('disposition' in result) &&
- 'turnId' in result &&
- typeof result.turnId === 'string' &&
- (!('steered' in result) || result.steered === true)
- ) {
- return {
- ok: true as const,
- turnId: result.turnId,
- ...('steered' in result ? { steered: true as const } : {}),
- };
- }
- throw new Error('WorkHub exact Turn send returned an ordinary message admission');
+ return sessions.send(sessionId, command);
},
async stop(
sessionId: string,
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org
For additional commands, e-mail: commits-help@maka.apache.org