feat(rpc): add validated desktop Pi RPC command palette
This commit is contained in:
+48
-10
@@ -24,6 +24,28 @@ function messageText(message: RuntimeView["messages"][number]) {
|
||||
.join("");
|
||||
}
|
||||
|
||||
function reconcilePendingSubmissions(
|
||||
pendingSubmissions: RuntimeView["pendingSubmissions"],
|
||||
messages: RuntimeView["messages"],
|
||||
) {
|
||||
const userMessages = messages
|
||||
.filter((message) => message.role === "user")
|
||||
.map(messageText);
|
||||
const consumed = new Set<number>();
|
||||
return pendingSubmissions.filter((pending) => {
|
||||
for (
|
||||
let index = pending.userMessageCount;
|
||||
index < userMessages.length;
|
||||
index++
|
||||
) {
|
||||
if (consumed.has(index) || userMessages[index] !== pending.text) continue;
|
||||
consumed.add(index);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
export function runtimeView(
|
||||
summary: RuntimeSummary,
|
||||
previous?: RuntimeView,
|
||||
@@ -84,6 +106,7 @@ export const initialWorkspaceState: WorkspaceState = {
|
||||
runtimeOrderByDirectory: {},
|
||||
windowActive: true,
|
||||
resourceWarning: false,
|
||||
defaultNewSessionWorktree: undefined,
|
||||
dismissedCollisionWarning: false,
|
||||
interfaceScale: 1,
|
||||
};
|
||||
@@ -169,6 +192,8 @@ export function reconcileWorkspace(
|
||||
selectedDirectoryPath,
|
||||
dismissedCollisionWarning:
|
||||
persisted?.dismissedCollisionWarning ?? state.dismissedCollisionWarning,
|
||||
defaultNewSessionWorktree:
|
||||
persisted?.defaultNewSessionWorktree ?? state.defaultNewSessionWorktree,
|
||||
interfaceScale: persisted?.interfaceScale ?? state.interfaceScale,
|
||||
};
|
||||
}
|
||||
@@ -319,9 +344,11 @@ export function applyWorkspaceEvent(
|
||||
(String(payload.type ?? "").endsWith("_start") ? 1 : 0),
|
||||
};
|
||||
} else if (type === "queue") {
|
||||
const queueCount = Array.isArray(payload.followUp)
|
||||
? payload.followUp.length
|
||||
: view.summary.queueCount;
|
||||
const queueCount =
|
||||
typeof payload.pendingMessageCount === "number"
|
||||
? payload.pendingMessageCount
|
||||
: (Array.isArray(payload.followUp) ? payload.followUp.length : 0) +
|
||||
(Array.isArray(payload.steering) ? payload.steering.length : 0);
|
||||
view.summary = { ...view.summary, queueCount };
|
||||
view.progress = {
|
||||
...view.progress,
|
||||
@@ -372,13 +399,20 @@ export type WorkspaceAction =
|
||||
| { type: "setWindowActive"; active: boolean }
|
||||
| { type: "setScale"; scale: number }
|
||||
| { type: "setResourceWarning"; value: boolean }
|
||||
| { type: "setDefaultNewSessionWorktree"; worktreePath?: string }
|
||||
| { type: "newSessionLaunch"; launch?: WorkspaceState["newSessionLaunch"] }
|
||||
| { type: "dismissCollisionWarning" }
|
||||
| {
|
||||
type: "submissionAdded";
|
||||
runtimeId: string;
|
||||
submission: RuntimeView["pendingSubmissions"][number];
|
||||
}
|
||||
| { type: "submissionSent"; runtimeId: string; id: number }
|
||||
| {
|
||||
type: "submissionSent";
|
||||
runtimeId: string;
|
||||
id: number;
|
||||
delivery: "prompt" | "follow_up";
|
||||
}
|
||||
| { type: "submissionRemoved"; runtimeId: string; id: number };
|
||||
|
||||
export function workspaceReducer(
|
||||
@@ -438,6 +472,10 @@ export function workspaceReducer(
|
||||
return { ...state, interfaceScale: action.scale };
|
||||
if (action.type === "setResourceWarning")
|
||||
return { ...state, resourceWarning: action.value };
|
||||
if (action.type === "setDefaultNewSessionWorktree")
|
||||
return { ...state, defaultNewSessionWorktree: action.worktreePath };
|
||||
if (action.type === "newSessionLaunch")
|
||||
return { ...state, newSessionLaunch: action.launch };
|
||||
if (action.type === "dismissCollisionWarning")
|
||||
return { ...state, dismissedCollisionWarning: true };
|
||||
const runtimeId = "runtimeId" in action ? action.runtimeId : undefined;
|
||||
@@ -463,11 +501,9 @@ export function workspaceReducer(
|
||||
view.state = action.snapshot.state?.data ?? {};
|
||||
view.stats = action.snapshot.stats?.data ?? {};
|
||||
view.messages = action.snapshot.transcript?.data?.messages ?? [];
|
||||
const receivedUserMessages = view.messages
|
||||
.filter((message) => message.role === "user")
|
||||
.map(messageText);
|
||||
view.pendingSubmissions = view.pendingSubmissions.filter(
|
||||
(pending) => !receivedUserMessages.includes(pending.text),
|
||||
view.pendingSubmissions = reconcilePendingSubmissions(
|
||||
view.pendingSubmissions,
|
||||
view.messages,
|
||||
);
|
||||
view.commands = action.snapshot.commands?.data?.commands ?? [];
|
||||
view.models = action.snapshot.models?.data?.models ?? [];
|
||||
@@ -494,7 +530,9 @@ export function workspaceReducer(
|
||||
view.pendingSubmissions = [...view.pendingSubmissions, action.submission];
|
||||
else if (action.type === "submissionSent")
|
||||
view.pendingSubmissions = view.pendingSubmissions.map((item) =>
|
||||
item.id === action.id ? { ...item, phase: "sent" } : item,
|
||||
item.id === action.id
|
||||
? { ...item, phase: "sent", delivery: action.delivery }
|
||||
: item,
|
||||
);
|
||||
else if (action.type === "submissionRemoved")
|
||||
view.pendingSubmissions = view.pendingSubmissions.filter(
|
||||
|
||||
Reference in New Issue
Block a user