v0.4.0: 工具与审批(业务工具骨架 + Approval Card)
This commit is contained in:
@@ -13,6 +13,8 @@ import {
|
||||
type CreateAgentSessionRuntimeFactory,
|
||||
type SessionInfo
|
||||
} from '@earendil-works/pi-coding-agent'
|
||||
import { ApprovalService, createApprovalExtension } from './approval'
|
||||
import { demoTools, TOOLS_REQUIRING_APPROVAL } from '../tools/demo-tools'
|
||||
import type {
|
||||
AgentUiEvent,
|
||||
AppSettings,
|
||||
@@ -41,6 +43,7 @@ export class AgentService {
|
||||
private attached: AgentSession | null = null
|
||||
private unsubscribeAttached: (() => void) | null = null
|
||||
private settings: AppSettings = { systemPrompt: '' }
|
||||
readonly approvals = new ApprovalService()
|
||||
|
||||
private get cwd(): string {
|
||||
return app.getPath('home')
|
||||
@@ -74,6 +77,11 @@ export class AgentService {
|
||||
return () => this.listeners.delete(fn)
|
||||
}
|
||||
|
||||
/** 供 IPC 层主动广播事件(如审批结果同步到所有窗口) */
|
||||
broadcastEvent(event: AgentUiEvent): void {
|
||||
this.emit(event)
|
||||
}
|
||||
|
||||
private emit(event: AgentUiEvent): void {
|
||||
for (const fn of this.listeners) {
|
||||
try {
|
||||
@@ -110,13 +118,23 @@ export class AgentService {
|
||||
const cwd = this.cwd
|
||||
const agentDir = getAgentDir()
|
||||
this.settings = this.loadSettings()
|
||||
const initialServices = await createAgentSessionServices({
|
||||
cwd,
|
||||
agentDir,
|
||||
resourceLoaderOptions: this.settings.systemPrompt.trim()
|
||||
? { systemPrompt: this.settings.systemPrompt }
|
||||
: undefined
|
||||
// 审批拦截:TOOLS_REQUIRING_APPROVAL 名单内的工具调用需经渲染层 Approval Card 确认
|
||||
this.approvals.onRequest((request) => {
|
||||
this.emit({ type: 'approval_request', request })
|
||||
})
|
||||
this.approvals.onSettle((id, approved, timedOut) => {
|
||||
this.emit({ type: 'approval_settled', id, approved, timedOut })
|
||||
})
|
||||
const buildServices = (targetCwd: string, targetAgentDir: string) =>
|
||||
createAgentSessionServices({
|
||||
cwd: targetCwd,
|
||||
agentDir: targetAgentDir,
|
||||
resourceLoaderOptions: {
|
||||
...(this.settings.systemPrompt.trim() ? { systemPrompt: this.settings.systemPrompt } : {}),
|
||||
extensionFactories: [createApprovalExtension(this.approvals, TOOLS_REQUIRING_APPROVAL)]
|
||||
}
|
||||
})
|
||||
const initialServices = await buildServices(cwd, agentDir)
|
||||
|
||||
// 每次切换/新建时由 runtime 调用;cwd 变化时重建服务,否则复用
|
||||
const factory: CreateAgentSessionRuntimeFactory = async ({
|
||||
@@ -128,8 +146,13 @@ export class AgentService {
|
||||
const services =
|
||||
nextCwd === initialServices.cwd && nextAgentDir === initialServices.agentDir
|
||||
? initialServices
|
||||
: await createAgentSessionServices({ cwd: nextCwd, agentDir: nextAgentDir })
|
||||
const result = await createAgentSessionFromServices({ services, sessionManager, sessionStartEvent })
|
||||
: await buildServices(nextCwd, nextAgentDir)
|
||||
const result = await createAgentSessionFromServices({
|
||||
services,
|
||||
sessionManager,
|
||||
sessionStartEvent,
|
||||
customTools: demoTools
|
||||
})
|
||||
return { ...result, services, diagnostics: services.diagnostics }
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user