You've already forked agentic-coding-workflow
修改
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
// - accumulate events into a ref array
|
||||
// - expose sessionStatus + connection-state status
|
||||
import { ref, onScopeDispose, type Ref } from 'vue'
|
||||
import { openSessionWS, type AcpEvent } from '@/api/acp'
|
||||
import { openSessionWS, acpApi, type AcpEvent, type PermissionRequest } from '@/api/acp'
|
||||
import { useAuthStore } from '@/stores/auth'
|
||||
|
||||
export type StreamStatus = 'idle' | 'connecting' | 'streaming' | 'closed' | 'error'
|
||||
@@ -15,12 +15,26 @@ export interface UseAcpStreamReturn {
|
||||
status: Ref<StreamStatus>
|
||||
sessionStatus: Ref<SessionStatus>
|
||||
events: Ref<AcpEvent[]>
|
||||
pendingPermissions: Ref<PermissionRequest[]>
|
||||
prompt: (text: string, agentSessionID: string) => void
|
||||
cancel: (agentSessionID: string) => void
|
||||
reconnect: () => void
|
||||
close: () => void
|
||||
}
|
||||
|
||||
// 把控制帧(ID=0)的 payload 归一为对象,无论 WS 传来字符串还是已解析对象。
|
||||
function decodePayload(raw: unknown): Record<string, unknown> {
|
||||
if (typeof raw === 'string') {
|
||||
try {
|
||||
return JSON.parse(raw) as Record<string, unknown>
|
||||
} catch {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
if (raw && typeof raw === 'object') return raw as Record<string, unknown>
|
||||
return {}
|
||||
}
|
||||
|
||||
interface ServerStateEvent {
|
||||
kind: 'state'
|
||||
status: SessionStatus
|
||||
@@ -34,8 +48,18 @@ export function useAcpStream(sessionId: string): UseAcpStreamReturn {
|
||||
const status = ref<StreamStatus>('idle')
|
||||
const sessionStatus = ref<SessionStatus>('starting')
|
||||
const events = ref<AcpEvent[]>([])
|
||||
const pendingPermissions = ref<PermissionRequest[]>([])
|
||||
const lastEventID = ref(0)
|
||||
|
||||
function upsertPermission(p: PermissionRequest) {
|
||||
if (!pendingPermissions.value.some((x) => x.id === p.id)) {
|
||||
pendingPermissions.value.push(p)
|
||||
}
|
||||
}
|
||||
function removePermission(reqID: string) {
|
||||
pendingPermissions.value = pendingPermissions.value.filter((x) => x.id !== reqID)
|
||||
}
|
||||
|
||||
let ws: WebSocket | null = null
|
||||
let retried = 0
|
||||
let manualClose = false
|
||||
@@ -53,6 +77,13 @@ export function useAcpStream(sessionId: string): UseAcpStreamReturn {
|
||||
sock.onopen = () => {
|
||||
status.value = 'streaming'
|
||||
retried = 0
|
||||
// 控制帧(permission_*)不落 acp_events,重连不补发;连上后主动拉取当前待审。
|
||||
acpApi.sessions
|
||||
.permissions(sessionId)
|
||||
.then((list) => {
|
||||
for (const p of list) upsertPermission(p)
|
||||
})
|
||||
.catch(() => {})
|
||||
}
|
||||
|
||||
sock.onmessage = (ev: MessageEvent) => {
|
||||
@@ -65,6 +96,28 @@ export function useAcpStream(sessionId: string): UseAcpStreamReturn {
|
||||
if (!parsed || typeof parsed !== 'object') return
|
||||
const obj = parsed as Record<string, unknown>
|
||||
|
||||
// 权限请求/决议控制帧(不进 events 流,单独维护 pendingPermissions)。
|
||||
if (obj.kind === 'permission_request') {
|
||||
const p = decodePayload(obj.payload)
|
||||
upsertPermission({
|
||||
id: String(p.request_id ?? ''),
|
||||
session_id: String(p.session_id ?? ''),
|
||||
tool_name: String(p.tool_name ?? ''),
|
||||
tool_call: p.tool_call,
|
||||
options: Array.isArray(p.options)
|
||||
? (p.options as { id: string; name?: string }[])
|
||||
: [],
|
||||
status: String(p.status ?? 'pending'),
|
||||
created_at: String(p.created_at ?? ''),
|
||||
})
|
||||
return
|
||||
}
|
||||
if (obj.kind === 'permission_resolved') {
|
||||
const p = decodePayload(obj.payload)
|
||||
removePermission(String(p.request_id ?? ''))
|
||||
return
|
||||
}
|
||||
|
||||
// Initial state event from server
|
||||
if (obj.kind === 'state') {
|
||||
const s = (parsed as ServerStateEvent).status
|
||||
@@ -156,5 +209,5 @@ export function useAcpStream(sessionId: string): UseAcpStreamReturn {
|
||||
connect()
|
||||
onScopeDispose(close)
|
||||
|
||||
return { status, sessionStatus, events, prompt, cancel, reconnect, close }
|
||||
return { status, sessionStatus, events, pendingPermissions, prompt, cancel, reconnect, close }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user