refactor(interact): separate runtime actions from ui projection
This commit is contained in:
@@ -105,6 +105,10 @@ describe("LineUpRuntime", () => {
|
||||
]));
|
||||
const chat = runtime.openApp("chat");
|
||||
expect(chat.app_scope).toBe("chat");
|
||||
expect(chat.runtime.dispatch).toBe(chat.dispatch);
|
||||
expect(chat.runtime.interactions).toBe(chat.interactions);
|
||||
expect(chat.runtime.tasks).toBe(chat.tasks);
|
||||
expect(chat.ui.snapshot).toBe(chat.snapshot);
|
||||
expect(chat.snapshot()).toMatchObject({ app_scope: "chat", active: false });
|
||||
|
||||
await runtime.login(login);
|
||||
|
||||
@@ -253,40 +253,43 @@ export class LineUpRuntime {
|
||||
const app = this.apps.get(appScope);
|
||||
if (!app?.enabled) throw new Error(`The ${appScope} Core App is unavailable.`);
|
||||
if (appScope !== "chat") throw new Error(`The ${appScope} Core App SDK is not registered.`);
|
||||
return {
|
||||
app_scope: "chat",
|
||||
const ui = {
|
||||
snapshot: () => this.chatView(),
|
||||
subscribe: listener => {
|
||||
subscribe: (listener: (view: ChatViewModel) => void) => {
|
||||
this.chatStateListeners.add(listener);
|
||||
listener(this.chatView());
|
||||
return () => this.chatStateListeners.delete(listener);
|
||||
},
|
||||
subscribeEvents: listener => this.onEvent(event => {
|
||||
// Agent content has a separate, scope-checked SDK channel. Keeping it
|
||||
// out of the generic event stream prevents a Chat renderer from
|
||||
// accidentally consuming an unprojected delivery path.
|
||||
subscribeEvents: (listener: (event: Exclude<RuntimeAppEvent, { type: "agent-message" }>) => void) => this.onEvent(event => {
|
||||
if (event.type !== "agent-message") listener(event);
|
||||
}),
|
||||
subscribeAgentMessages: listener => {
|
||||
subscribeAgentMessages: (listener: (message: AgentChatMessage) => void) => {
|
||||
this.chatMessageListeners.add(listener);
|
||||
return () => this.chatMessageListeners.delete(listener);
|
||||
},
|
||||
listAgentMessages: afterMessageID => this.listChatMessages(afterMessageID),
|
||||
acknowledgeAgentMessage: messageID => this.acknowledgeChatMessage(messageID),
|
||||
dispatch: action => this.dispatchChatAction(action),
|
||||
interactions: {
|
||||
submit: (callID, result) => this.submitToolCall(callID, result),
|
||||
cancel: (callID, reason) => this.cancelToolCall(callID, reason),
|
||||
expire: callID => this.expireToolCall(callID),
|
||||
read: callID => this.toolCalls().find(record => record.call_id === callID),
|
||||
loadDraft: callID => this.getToolDraft(callID),
|
||||
saveDraft: (callID, values) => this.saveToolDraft(callID, values),
|
||||
clearDraft: callID => this.clearToolDraft(callID),
|
||||
},
|
||||
tasks: {
|
||||
requestCancel: operationID => this.requestTaskCancel(operationID),
|
||||
read: operationID => this.tasks().find(task => task.operation_id === operationID),
|
||||
},
|
||||
listAgentMessages: (afterMessageID?: string) => this.listChatMessages(afterMessageID),
|
||||
acknowledgeAgentMessage: (messageID: string) => this.acknowledgeChatMessage(messageID),
|
||||
};
|
||||
const interactions = {
|
||||
submit: (callID: string, result: JsonObject) => this.submitToolCall(callID, result),
|
||||
cancel: (callID: string, reason: string) => this.cancelToolCall(callID, reason),
|
||||
expire: (callID: string) => this.expireToolCall(callID),
|
||||
read: (callID: string) => this.toolCalls().find(record => record.call_id === callID),
|
||||
loadDraft: (callID: string) => this.getToolDraft(callID),
|
||||
saveDraft: (callID: string, values: JsonObject) => this.saveToolDraft(callID, values),
|
||||
clearDraft: (callID: string) => this.clearToolDraft(callID),
|
||||
};
|
||||
const tasks = {
|
||||
requestCancel: (operationID: string) => this.requestTaskCancel(operationID),
|
||||
read: (operationID: string) => this.tasks().find(task => task.operation_id === operationID),
|
||||
};
|
||||
const runtime = { dispatch: (action: ChatAction) => this.dispatchChatAction(action), interactions, tasks };
|
||||
return {
|
||||
app_scope: "chat",
|
||||
runtime,
|
||||
ui,
|
||||
...ui,
|
||||
...runtime,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user