feat: add vault ai agent permission modes
This commit is contained in:
@@ -1,7 +1,17 @@
|
||||
import { useCallback, useMemo, useState } from 'react'
|
||||
import { useCallback, useMemo, useState, useSyncExternalStore } from 'react'
|
||||
import type { AiAgentId, AiAgentReadiness } from '../lib/aiAgents'
|
||||
import {
|
||||
aiAgentPermissionModeMarker,
|
||||
normalizeAiAgentPermissionMode,
|
||||
type AiAgentPermissionMode,
|
||||
} from '../lib/aiAgentPermissionMode'
|
||||
import { useCliAiAgent, type AgentFileCallbacks } from '../hooks/useCliAiAgent'
|
||||
import type { VaultEntry } from '../types'
|
||||
import {
|
||||
getVaultConfig,
|
||||
subscribeVaultConfig,
|
||||
updateVaultConfigField,
|
||||
} from '../utils/vaultConfigStore'
|
||||
import {
|
||||
type NoteListItem,
|
||||
type NoteReference,
|
||||
@@ -32,8 +42,10 @@ export interface AiPanelController {
|
||||
linkedEntries: ReturnType<typeof useAiPanelContextSnapshot>['linkedEntries']
|
||||
hasContext: boolean
|
||||
isActive: boolean
|
||||
permissionMode: AiAgentPermissionMode
|
||||
handleSend: (text: string, references: NoteReference[]) => void
|
||||
handleNavigateWikilink: (target: string) => void
|
||||
handlePermissionModeChange: (mode: AiAgentPermissionMode) => void
|
||||
handleNewChat: () => void
|
||||
}
|
||||
|
||||
@@ -44,6 +56,26 @@ function resolveAgentReady(
|
||||
return (readiness ?? (ready ? 'ready' : 'missing')) === 'ready'
|
||||
}
|
||||
|
||||
function useVaultAiAgentPermissionMode(): AiAgentPermissionMode {
|
||||
const vaultConfig = useSyncExternalStore(subscribeVaultConfig, getVaultConfig)
|
||||
return normalizeAiAgentPermissionMode(vaultConfig.ai_agent_permission_mode)
|
||||
}
|
||||
|
||||
function useAgentFileCallbacks({
|
||||
onFileCreated,
|
||||
onFileModified,
|
||||
onVaultChanged,
|
||||
}: Pick<
|
||||
UseAiPanelControllerArgs,
|
||||
'onFileCreated' | 'onFileModified' | 'onVaultChanged'
|
||||
>): AgentFileCallbacks {
|
||||
return useMemo<AgentFileCallbacks>(() => ({
|
||||
onFileCreated,
|
||||
onFileModified,
|
||||
onVaultChanged,
|
||||
}), [onFileCreated, onFileModified, onVaultChanged])
|
||||
}
|
||||
|
||||
export function useAiPanelController({
|
||||
vaultPath,
|
||||
defaultAiAgent,
|
||||
@@ -71,15 +103,13 @@ export function useAiPanelController({
|
||||
noteListFilter,
|
||||
})
|
||||
|
||||
const fileCallbacks = useMemo<AgentFileCallbacks>(() => ({
|
||||
onFileCreated,
|
||||
onFileModified,
|
||||
onVaultChanged,
|
||||
}), [onFileCreated, onFileModified, onVaultChanged])
|
||||
const fileCallbacks = useAgentFileCallbacks({ onFileCreated, onFileModified, onVaultChanged })
|
||||
const permissionMode = useVaultAiAgentPermissionMode()
|
||||
|
||||
const agent = useCliAiAgent(vaultPath, contextPrompt, fileCallbacks, {
|
||||
agent: defaultAiAgent,
|
||||
agentReady: resolveAgentReady(defaultAiAgentReadiness, defaultAiAgentReady),
|
||||
permissionMode,
|
||||
})
|
||||
const hasContext = !!activeEntry
|
||||
const isActive = agent.status === 'thinking' || agent.status === 'tool-executing'
|
||||
@@ -94,6 +124,14 @@ export function useAiPanelController({
|
||||
onOpenNote?.(target)
|
||||
}, [onOpenNote])
|
||||
|
||||
const handlePermissionModeChange = useCallback((mode: AiAgentPermissionMode) => {
|
||||
const nextMode = normalizeAiAgentPermissionMode(mode)
|
||||
if (isActive || nextMode === permissionMode) return
|
||||
|
||||
updateVaultConfigField('ai_agent_permission_mode', nextMode)
|
||||
agent.addLocalMarker(aiAgentPermissionModeMarker(nextMode))
|
||||
}, [agent, isActive, permissionMode])
|
||||
|
||||
const handleNewChat = useCallback(() => {
|
||||
agent.clearConversation()
|
||||
setInput('')
|
||||
@@ -106,8 +144,10 @@ export function useAiPanelController({
|
||||
linkedEntries,
|
||||
hasContext,
|
||||
isActive,
|
||||
permissionMode,
|
||||
handleSend,
|
||||
handleNavigateWikilink,
|
||||
handlePermissionModeChange,
|
||||
handleNewChat,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user