v2.2-paseo-providers: Paseo provider stack + v2.2.1 pane-scoped chat fixes
Ship Paseo-equivalent provider snapshot, AgentComposerBar, ACP dispatch rewrite with streaming/persist, permission prompts, and agent commands. Follow-up: pane-scoped chat resolution, CoderMessageList tool timeline, WS user-delta replace, and inference orphan tool_call stripping. Archive openspec v2-2; update CHANGELOG and CURRENT. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -13,7 +13,13 @@ import type {
|
||||
Skill,
|
||||
AskUserAnswer,
|
||||
ToolCostStat,
|
||||
Provider,
|
||||
ProviderSnapshotEntry,
|
||||
CoderSendMessageBody,
|
||||
CoderSendMessageResponse,
|
||||
CoderMessageWire,
|
||||
CoderTaskDetail,
|
||||
PermissionPrompt,
|
||||
AgentCommand,
|
||||
} from './types';
|
||||
|
||||
export class ApiError extends Error {
|
||||
@@ -300,7 +306,46 @@ export const api = {
|
||||
models: () => request<ModelInfo[]>('/api/models'),
|
||||
|
||||
coder: {
|
||||
providers: () => request<Provider[]>('/api/coder/providers'),
|
||||
snapshot: (cwd?: string) => {
|
||||
const qs = cwd ? `?cwd=${encodeURIComponent(cwd)}` : '';
|
||||
return request<ProviderSnapshotEntry[]>(`/api/coder/providers/snapshot${qs}`);
|
||||
},
|
||||
refreshProviders: () =>
|
||||
request<{ refreshed: number }>('/api/coder/providers/refresh', { method: 'POST' }),
|
||||
sendMessage: (sessionId: string, body: CoderSendMessageBody) =>
|
||||
request<CoderSendMessageResponse>(`/api/coder/sessions/${sessionId}/messages`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(body),
|
||||
}),
|
||||
getTaskPermission: (taskId: string) =>
|
||||
request<PermissionPrompt>(`/api/coder/tasks/${taskId}/permission`),
|
||||
respondTaskPermission: (taskId: string, optionId: string | null) =>
|
||||
request<{ ok: boolean }>(`/api/coder/tasks/${taskId}/permission`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ option_id: optionId }),
|
||||
}),
|
||||
getTaskCommands: (taskId: string) =>
|
||||
request<{ taskId: string; commands: AgentCommand[] }>(`/api/coder/tasks/${taskId}/commands`),
|
||||
getTask: (taskId: string) =>
|
||||
request<CoderTaskDetail>(`/api/coder/tasks/${taskId}`),
|
||||
listMessages: (sessionId: string, chatId?: string) =>
|
||||
request<CoderMessageWire[]>(
|
||||
`/api/coder/sessions/${sessionId}/messages${chatId ? `?chat_id=${encodeURIComponent(chatId)}` : ''}`,
|
||||
),
|
||||
skillInvoke: (sessionId: string, paneId: string, skillName: string, userMessage: string | null) =>
|
||||
request<{
|
||||
user_message_id: string;
|
||||
assistant_message_id: string;
|
||||
synth_assistant_id: string;
|
||||
tool_message_id: string;
|
||||
}>(`/api/coder/sessions/${sessionId}/skill_invoke`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
pane_id: paneId,
|
||||
skill_name: skillName,
|
||||
user_message: userMessage,
|
||||
}),
|
||||
}),
|
||||
},
|
||||
|
||||
agents: {
|
||||
|
||||
@@ -209,14 +209,95 @@ export interface ModelInfo {
|
||||
export interface ProviderModel {
|
||||
id: string;
|
||||
label: string;
|
||||
description?: string;
|
||||
isDefault?: boolean;
|
||||
thinkingOptions?: ThinkingOption[];
|
||||
defaultThinkingOptionId?: string;
|
||||
}
|
||||
|
||||
export interface Provider {
|
||||
export interface ProviderMode {
|
||||
id: string;
|
||||
label: string;
|
||||
description?: string;
|
||||
isUnattended?: boolean;
|
||||
}
|
||||
|
||||
export interface ThinkingOption {
|
||||
id: string;
|
||||
label: string;
|
||||
isDefault?: boolean;
|
||||
}
|
||||
|
||||
export type ProviderSnapshotStatus = 'ready' | 'error';
|
||||
|
||||
export interface ProviderSnapshotEntry {
|
||||
name: string;
|
||||
label: string;
|
||||
transport: string;
|
||||
status: ProviderSnapshotStatus;
|
||||
installed: boolean;
|
||||
models: ProviderModel[];
|
||||
modes: ProviderMode[];
|
||||
defaultModeId: string | null;
|
||||
commands: AgentCommand[];
|
||||
error?: string;
|
||||
}
|
||||
|
||||
export interface AgentSessionConfig {
|
||||
provider: string;
|
||||
model: string;
|
||||
modeId: string | null;
|
||||
thinkingOptionId: string | null;
|
||||
}
|
||||
|
||||
export interface PermissionPrompt {
|
||||
taskId: string;
|
||||
toolTitle?: string;
|
||||
options: Array<{ optionId: string; label: string }>;
|
||||
}
|
||||
|
||||
export interface AgentCommand {
|
||||
name: string;
|
||||
description?: string;
|
||||
}
|
||||
|
||||
export interface CoderSendMessageBody {
|
||||
content: string;
|
||||
pane_id: string;
|
||||
chat_id?: string;
|
||||
provider?: string;
|
||||
model?: string;
|
||||
mode_id?: string;
|
||||
thinking_option_id?: string;
|
||||
}
|
||||
|
||||
export interface CoderSendMessageResponse {
|
||||
user_message_id?: string;
|
||||
assistant_message_id?: string;
|
||||
task_id?: string;
|
||||
dispatched?: boolean;
|
||||
}
|
||||
|
||||
export interface CoderMessageWire {
|
||||
id: string;
|
||||
role: 'user' | 'assistant' | 'system';
|
||||
content: string;
|
||||
status?: 'streaming' | 'complete' | 'failed';
|
||||
reasoning_text?: string;
|
||||
tool_calls?: Array<{
|
||||
id: string;
|
||||
function: { name: string; arguments: string };
|
||||
}>;
|
||||
}
|
||||
|
||||
export interface CoderTaskDetail {
|
||||
id: string;
|
||||
state: 'pending' | 'running' | 'completed' | 'failed' | 'blocked' | 'cancelled';
|
||||
input: string;
|
||||
output_summary: string | null;
|
||||
agent: string | null;
|
||||
model: string | null;
|
||||
session_id: string | null;
|
||||
}
|
||||
|
||||
export interface SidebarSession {
|
||||
|
||||
@@ -85,6 +85,13 @@ export const DeltaFrame = z.object({
|
||||
content: z.string(),
|
||||
});
|
||||
|
||||
export const ReasoningDeltaFrame = z.object({
|
||||
type: z.literal('reasoning_delta'),
|
||||
message_id: Uuid,
|
||||
chat_id: Uuid.optional(),
|
||||
content: z.string(),
|
||||
});
|
||||
|
||||
export const ToolCallFrame = z.object({
|
||||
type: z.literal('tool_call'),
|
||||
message_id: Uuid,
|
||||
@@ -256,6 +263,37 @@ export const ProjectDeletedFrame = z.object({
|
||||
project_id: Uuid,
|
||||
});
|
||||
|
||||
const PermissionOptionShape = z.object({
|
||||
option_id: z.string(),
|
||||
label: z.string(),
|
||||
});
|
||||
|
||||
export const PermissionRequestedFrame = z.object({
|
||||
type: z.literal('permission_requested'),
|
||||
task_id: Uuid,
|
||||
session_id: Uuid,
|
||||
tool_title: z.string().optional(),
|
||||
options: z.array(PermissionOptionShape),
|
||||
});
|
||||
|
||||
export const PermissionResolvedFrame = z.object({
|
||||
type: z.literal('permission_resolved'),
|
||||
task_id: Uuid,
|
||||
session_id: Uuid,
|
||||
});
|
||||
|
||||
const AgentCommandShape = z.object({
|
||||
name: z.string(),
|
||||
description: z.string().optional(),
|
||||
});
|
||||
|
||||
export const AgentCommandsFrame = z.object({
|
||||
type: z.literal('agent_commands'),
|
||||
task_id: Uuid,
|
||||
session_id: Uuid,
|
||||
commands: z.array(AgentCommandShape),
|
||||
});
|
||||
|
||||
// ---- discriminated union ---------------------------------------------------
|
||||
|
||||
export const WsFrameSchema = z.discriminatedUnion('type', [
|
||||
@@ -263,6 +301,7 @@ export const WsFrameSchema = z.discriminatedUnion('type', [
|
||||
SnapshotFrame,
|
||||
MessageStartedFrame,
|
||||
DeltaFrame,
|
||||
ReasoningDeltaFrame,
|
||||
ToolCallFrame,
|
||||
ToolResultFrame,
|
||||
MessageCompleteFrame,
|
||||
@@ -271,6 +310,9 @@ export const WsFrameSchema = z.discriminatedUnion('type', [
|
||||
ChatRenamedFrame,
|
||||
CompactedFrame,
|
||||
ErrorFrame,
|
||||
PermissionRequestedFrame,
|
||||
PermissionResolvedFrame,
|
||||
AgentCommandsFrame,
|
||||
// per-user
|
||||
ChatStatusFrame,
|
||||
SessionUpdatedFrame,
|
||||
@@ -300,6 +342,7 @@ export const KNOWN_FRAME_TYPES: readonly WsFrame['type'][] = [
|
||||
'snapshot',
|
||||
'message_started',
|
||||
'delta',
|
||||
'reasoning_delta',
|
||||
'tool_call',
|
||||
'tool_result',
|
||||
'message_complete',
|
||||
@@ -308,6 +351,9 @@ export const KNOWN_FRAME_TYPES: readonly WsFrame['type'][] = [
|
||||
'chat_renamed',
|
||||
'compacted',
|
||||
'error',
|
||||
'permission_requested',
|
||||
'permission_resolved',
|
||||
'agent_commands',
|
||||
'chat_status',
|
||||
'session_updated',
|
||||
'session_renamed',
|
||||
|
||||
Reference in New Issue
Block a user