pull/6319/head
Dax Raad 2026-01-01 16:48:50 -05:00
parent 16c615fd47
commit 82a8ba6822
6 changed files with 35 additions and 54 deletions

View File

@ -10,6 +10,7 @@
"options": {},
},
},
"permission": "ask",
"mcp": {
"context7": {
"type": "remote",

View File

@ -71,19 +71,19 @@ export namespace ACP {
this.config.sdk.event.subscribe({ directory }).then(async (events) => {
for await (const event of events.stream) {
switch (event.type) {
case "permission.updated":
case "permission.asked":
try {
const permission = event.properties
const res = await this.connection
.requestPermission({
sessionId,
toolCall: {
toolCallId: permission.callID ?? permission.id,
toolCallId: permission.tool?.callID ?? permission.id,
status: "pending",
title: permission.message,
title: permission.permission,
rawInput: permission.metadata,
kind: toToolKind(permission.type),
locations: toLocations(permission.type, permission.metadata),
kind: toToolKind(permission.permission),
locations: toLocations(permission.permission, permission.metadata),
},
options,
})
@ -93,28 +93,25 @@ export namespace ACP {
permissionID: permission.id,
sessionID: permission.sessionID,
})
await this.config.sdk.permission.respond({
sessionID: permission.sessionID,
permissionID: permission.id,
response: "reject",
await this.config.sdk.permission.reply({
requestID: permission.id,
reply: "reject",
directory,
})
return
})
if (!res) return
if (res.outcome.outcome !== "selected") {
await this.config.sdk.permission.respond({
sessionID: permission.sessionID,
permissionID: permission.id,
response: "reject",
await this.config.sdk.permission.reply({
requestID: permission.id,
reply: "reject",
directory,
})
return
}
await this.config.sdk.permission.respond({
sessionID: permission.sessionID,
permissionID: permission.id,
response: res.outcome.optionId as "once" | "always" | "reject",
await this.config.sdk.permission.reply({
requestID: permission.id,
reply: res.outcome.optionId as "once" | "always" | "reject",
directory,
})
} catch (err) {

View File

@ -202,7 +202,7 @@ export const RunCommand = cmd({
break
}
if (event.type === "permission.next.asked") {
if (event.type === "permission.asked") {
const permission = event.properties
if (permission.sessionID !== sessionID) continue
const result = await select({

View File

@ -97,7 +97,7 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
sdk.event.listen((e) => {
const event = e.details
switch (event.type) {
case "permission.next.replied": {
case "permission.replied": {
const requests = store.permission[event.properties.sessionID]
if (!requests) break
const match = Binary.search(requests, event.properties.requestID, (r) => r.id)
@ -112,7 +112,7 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
break
}
case "permission.next.asked": {
case "permission.asked": {
const request = event.properties
const requests = store.permission[request.sessionID]
if (!requests) {

View File

@ -107,8 +107,17 @@ export function Session() {
const { theme } = useTheme()
const promptRef = usePromptRef()
const session = createMemo(() => sync.session.get(route.sessionID)!)
const children = createMemo(() => {
const parentID = session()?.parentID ?? session()?.id
return sync.data.session
.filter((x) => x.parentID === parentID || x.id === parentID)
.toSorted((a, b) => (a.id < b.id ? -1 : a.id > b.id ? 1 : 0))
})
const messages = createMemo(() => sync.data.message[route.sessionID] ?? [])
const permissions = createMemo(() => sync.data.permission[route.sessionID] ?? [])
const permissions = createMemo(() => {
if (session().parentID) return sync.data.permission[route.sessionID] ?? []
return children().flatMap((x) => sync.data.permission[x.id] ?? [])
})
const pending = createMemo(() => {
return messages().findLast((x) => x.role === "assistant" && !x.time.completed)?.id
@ -176,28 +185,6 @@ export function Session() {
}
})
// Auto-navigate to whichever session currently needs permission input
createEffect(() => {
const currentSession = session()
if (!currentSession) return
const currentPermissions = permissions()
let targetID = currentPermissions.length > 0 ? currentSession.id : undefined
if (!targetID) {
const child = sync.data.session.find(
(x) => x.parentID === currentSession.id && (sync.data.permission[x.id]?.length ?? 0) > 0,
)
if (child) targetID = child.id
}
if (targetID && targetID !== currentSession.id) {
navigate({
type: "session",
sessionID: targetID,
})
}
})
let scroll: ScrollBoxRenderable
let prompt: PromptRef
const keybind = useKeybind()
@ -257,18 +244,14 @@ export function Session() {
const local = useLocal()
function moveChild(direction: number) {
const parentID = session()?.parentID ?? session()?.id
let children = sync.data.session
.filter((x) => x.parentID === parentID || x.id === parentID)
.toSorted((a, b) => (a.id < b.id ? -1 : a.id > b.id ? 1 : 0))
if (children.length === 1) return
let next = children.findIndex((x) => x.id === session()?.id) + direction
if (next >= children.length) next = 0
if (next < 0) next = children.length - 1
if (children[next]) {
if (children().length === 1) return
let next = children().findIndex((x) => x.id === session()?.id) + direction
if (next >= children().length) next = 0
if (next < 0) next = children().length - 1
if (children()[next]) {
navigate({
type: "session",
sessionID: children[next].id,
sessionID: children()[next].id,
})
}
}

View File

@ -646,7 +646,7 @@ export namespace SessionPrompt {
async ask(req) {
await PermissionNext.ask({
...req,
sessionID: input.session.parentID ?? input.session.id,
sessionID: input.session.id,
tool: { messageID: input.processor.message.id, callID: options.toolCallId },
ruleset: PermissionNext.merge(input.agent.permission, input.session.permission ?? []),
})