feat: Windows 环境优先使用 PowerShell 工具替代 bash
This commit is contained in:
@@ -9,6 +9,7 @@ import {
|
|||||||
createAgentSessionFromServices,
|
createAgentSessionFromServices,
|
||||||
estimateTokens,
|
estimateTokens,
|
||||||
getAgentDir,
|
getAgentDir,
|
||||||
|
getPowerShellConfig,
|
||||||
SessionManager,
|
SessionManager,
|
||||||
type AgentSession,
|
type AgentSession,
|
||||||
type AgentSessionEvent,
|
type AgentSessionEvent,
|
||||||
@@ -53,7 +54,32 @@ const DELTA_FLUSH_MS = 40
|
|||||||
const CUSTOM_TOOL_NAMES = new Set<string>(browserToolNames)
|
const CUSTOM_TOOL_NAMES = new Set<string>(browserToolNames)
|
||||||
|
|
||||||
/** 需要人工审批的工具名单(高危内置工具;业务演示工具已随 demo-tools.ts 移除) */
|
/** 需要人工审批的工具名单(高危内置工具;业务演示工具已随 demo-tools.ts 移除) */
|
||||||
const TOOLS_REQUIRING_APPROVAL: ReadonlySet<string> = new Set(['bash', 'write', 'edit'])
|
const TOOLS_REQUIRING_APPROVAL: ReadonlySet<string> = new Set(['bash', 'powershell', 'write', 'edit'])
|
||||||
|
|
||||||
|
/** Windows 优先 PowerShell:探测结果进程内缓存(getPowerShellConfig 会 spawnSync where 探测,
|
||||||
|
* 且平台与安装情况不会在应用运行中变化)。探测失败保持 bash(Git Bash)不动。 */
|
||||||
|
let powershellProbe: boolean | null = null
|
||||||
|
|
||||||
|
/** win32 且存在 pwsh/powershell 可执行文件时,把会话的默认 bash 工具换成 powershell,
|
||||||
|
* 模型的 shell 调用走原生 PowerShell 而非 Git Bash。幂等:无 bash 或已换过则原样返回。
|
||||||
|
* 注意不能用 options.tools 传入(那会变成工具白名单,把插件注册的工具全部过滤掉),
|
||||||
|
* 也不能只传四个基础名调 setActiveToolsByName(那会把已激活的扩展工具一并挤掉),
|
||||||
|
* 所以按当前激活名单做替换。 */
|
||||||
|
function preferPowerShell(session: AgentSession): void {
|
||||||
|
if (process.platform !== 'win32') return
|
||||||
|
if (powershellProbe === null) {
|
||||||
|
try {
|
||||||
|
getPowerShellConfig()
|
||||||
|
powershellProbe = true
|
||||||
|
} catch {
|
||||||
|
powershellProbe = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!powershellProbe) return
|
||||||
|
const names = session.getActiveToolNames()
|
||||||
|
if (!names.includes('bash') || names.includes('powershell')) return
|
||||||
|
session.setActiveToolsByName(names.map((name) => (name === 'bash' ? 'powershell' : name)))
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* pi 会话运行时的主进程封装:
|
* pi 会话运行时的主进程封装:
|
||||||
@@ -294,6 +320,8 @@ export class AgentService {
|
|||||||
// 业务工具(browserTools 等)由插件经 pi.registerTool 注册(聚合 extension),
|
// 业务工具(browserTools 等)由插件经 pi.registerTool 注册(聚合 extension),
|
||||||
// 此处不再传 customTools
|
// 此处不再传 customTools
|
||||||
})
|
})
|
||||||
|
// 会话创建是唯一收口点:新建/切换/分叉/重载都会经过这里,统一应用 Windows PowerShell 偏好
|
||||||
|
preferPowerShell(result.session)
|
||||||
return { ...result, services, diagnostics: services.diagnostics }
|
return { ...result, services, diagnostics: services.diagnostics }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ function extractResultText(result: unknown): string {
|
|||||||
function toolMeta(name: string): { icon: keyof typeof STEP_ICONS; label: string } {
|
function toolMeta(name: string): { icon: keyof typeof STEP_ICONS; label: string } {
|
||||||
if (/^read|get|list|查|读|搜/i.test(name)) return { icon: 'read', label: '读取' }
|
if (/^read|get|list|查|读|搜/i.test(name)) return { icon: 'read', label: '读取' }
|
||||||
if (/^write|^edit|^multiedit|写|改|删|建|核/i.test(name)) return { icon: 'write', label: '编辑' }
|
if (/^write|^edit|^multiedit|写|改|删|建|核/i.test(name)) return { icon: 'write', label: '编辑' }
|
||||||
if (/^bash|^shell|^terminal|终端/i.test(name)) return { icon: 'run', label: '终端' }
|
if (/^bash|^shell|^terminal|^powershell|终端/i.test(name)) return { icon: 'run', label: '终端' }
|
||||||
if (/read|get|search|query|fetch|list|查|读|搜/i.test(name)) return { icon: 'read', label: '读取' }
|
if (/read|get|search|query|fetch|list|查|读|搜/i.test(name)) return { icon: 'read', label: '读取' }
|
||||||
if (/write|edit|update|create|delete|patch|save|写|改|删|建|核/i.test(name)) return { icon: 'write', label: '编辑' }
|
if (/write|edit|update|create|delete|patch|save|写|改|删|建|核/i.test(name)) return { icon: 'write', label: '编辑' }
|
||||||
return { icon: 'run', label: name }
|
return { icon: 'run', label: name }
|
||||||
|
|||||||
Reference in New Issue
Block a user