86 lines
3.1 KiB
JavaScript
86 lines
3.1 KiB
JavaScript
import { insertActionLog } from '../db.js'
|
|
import { emitEvent } from '../events.js'
|
|
import { classifyTool } from './tool-policy.js'
|
|
import { previewValue, safeJsonStringify } from './tool-utils.js'
|
|
|
|
function getExecutionSource(context = {}) {
|
|
return context.source || context.trigger || (context.autonomous ? 'autonomous' : 'llm')
|
|
}
|
|
function summarizeToolExecution(name, args = {}) {
|
|
switch (name) {
|
|
case 'read_file':
|
|
return `read_file(${args.path || args.filename || args.file_path || '?'})`
|
|
case 'list_dir':
|
|
return `list_dir(${args.path || args.dir || args.directory || '.'})`
|
|
case 'write_file':
|
|
return `write_file(${args.path || args.filename || args.file_path || '?'})`
|
|
case 'delete_file':
|
|
return `delete_file(${args.path || args.filename || args.file_path || '?'})`
|
|
case 'make_dir':
|
|
return `make_dir(${args.path || args.dir || args.directory || '?'})`
|
|
case 'exec_command':
|
|
return `exec_command(${String(args.command || args.cmd || '?').slice(0, 100)})`
|
|
case 'fetch_url':
|
|
case 'browser_read':
|
|
return `${name}(${String(args.url || args.link || args.href || '?').slice(0, 120)})`
|
|
case 'web_search':
|
|
return `web_search(${String(args.query || args.q || args.keyword || '?').slice(0, 120)})`
|
|
case 'send_message':
|
|
case 'express':
|
|
return `${name} -> ${args.target_id || '(unknown)'}`
|
|
case 'upsert_memory': {
|
|
const count = Array.isArray(args.memories) ? args.memories.length : 0
|
|
return `upsert_memory(${count})`
|
|
}
|
|
default:
|
|
return name
|
|
}
|
|
}
|
|
|
|
export function inferToolStatus(result) {
|
|
const text = String(result ?? '').trim()
|
|
if (!text) return 'ok'
|
|
try {
|
|
const parsed = JSON.parse(text)
|
|
return parsed?.ok === false ? 'error' : 'ok'
|
|
} catch {}
|
|
return /^(错误|请求失败|执行失败|命令超时|命令执行失败|閿欒|璇锋眰澶辫触|鎵ц澶辫触|鍛戒护瓒呮椂|鍛戒护鎵ц澶辫触)/.test(text) ? 'error' : 'ok'
|
|
}
|
|
|
|
export function writeToolAuditLog({ name, args, context, policy, status, result = '', error = '', startedAt }) {
|
|
const durationMs = Date.now() - startedAt
|
|
const detailParts = []
|
|
if (policy?.reason) detailParts.push(`policy=${policy.reason}`)
|
|
const argPreview = previewValue(args, 160)
|
|
if (argPreview && argPreview !== '{}') detailParts.push(`args=${argPreview}`)
|
|
const resultPreview = previewValue(result || error, 220)
|
|
if (resultPreview) detailParts.push(`result=${resultPreview}`)
|
|
|
|
try {
|
|
insertActionLog({
|
|
timestamp: new Date(startedAt).toISOString(),
|
|
tool: name,
|
|
summary: summarizeToolExecution(name, args),
|
|
detail: detailParts.join(' | '),
|
|
status,
|
|
risk: policy?.risk || classifyTool(name),
|
|
argsJson: safeJsonStringify(args),
|
|
resultPreview,
|
|
error,
|
|
durationMs,
|
|
source: getExecutionSource(context),
|
|
})
|
|
} catch (err) {
|
|
console.warn(`[audit] failed to persist tool audit log: ${err.message}`)
|
|
}
|
|
|
|
emitEvent('tool_audit', {
|
|
tool: name,
|
|
status,
|
|
risk: policy?.risk || classifyTool(name),
|
|
summary: summarizeToolExecution(name, args),
|
|
duration_ms: durationMs,
|
|
source: getExecutionSource(context),
|
|
})
|
|
}
|