@faapi/faapi 6.26.0 → 6.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +82 -49
- package/dist/cli/index.js.map +1 -1
- package/dist/{contextTypes-gYf84EXF.d.ts → contextTypes-DhagvRH_.d.ts} +9 -25
- package/dist/index.d.ts +35 -28
- package/dist/index.js +124 -96
- package/dist/index.js.map +1 -1
- package/dist/{routeTypes-DlD6nnbT.d.ts → routeTypes-0rwuIws-.d.ts} +1 -1
- package/dist/testing.d.ts +3 -3
- package/dist/testing.js +59 -77
- package/dist/testing.js.map +1 -1
- package/dist/workerEntry.d.ts +1 -1
- package/dist/workerEntry.js +2 -1
- package/dist/workerEntry.js.map +1 -1
- package/package.json +1 -1
package/dist/workerEntry.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { K as TaskRegistriesSnapshot, i as AgentMetadata, g as ToolMetadata, h as AgentCore, t as LogLevel } from './contextTypes-
|
|
1
|
+
import { K as TaskRegistriesSnapshot, i as AgentMetadata, g as ToolMetadata, h as AgentCore, t as LogLevel } from './contextTypes-DhagvRH_.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* 任务隔离 worker 的真实入口文件(tsup 独立入口 → dist/workerEntry.js)
|
package/dist/workerEntry.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// src/task/workerEntry.ts
|
|
2
2
|
import { parentPort, workerData } from "worker_threads";
|
|
3
|
+
var SUB_AGENT_TOOL_PREFIX = "agent-";
|
|
3
4
|
function buildRegistriesView(snapshot) {
|
|
4
5
|
const agents = new Map((snapshot?.agents ?? []).map((a) => [a.name, a]));
|
|
5
6
|
const tools = new Map((snapshot?.tools ?? []).map((t) => [t.name, t]));
|
|
@@ -14,7 +15,7 @@ function buildRegistriesView(snapshot) {
|
|
|
14
15
|
if (!agent) return void 0;
|
|
15
16
|
return {
|
|
16
17
|
kind: "agent",
|
|
17
|
-
name:
|
|
18
|
+
name: `${SUB_AGENT_TOOL_PREFIX}${agent.name}`,
|
|
18
19
|
agentName: agent.name,
|
|
19
20
|
description: agent.description,
|
|
20
21
|
metadata: agent
|
package/dist/workerEntry.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/task/workerEntry.ts"],"sourcesContent":["import { parentPort, workerData } from 'node:worker_threads';\nimport type { TaskRegistriesSnapshot } from './taskTypes';\nimport type { LogEntry, LogLevel } from '../logger/loggerTypes';\n\n/**\n * 任务隔离 worker 的真实入口文件(tsup 独立入口 → dist/workerEntry.js)\n *\n * 为什么是独立文件而不是宿主生成的 data URL:data URL 模块无法解析裸说明符\n * ('@faapi/faapi'),framework 侧 helper 只能以字符串模板内联(typecheck 覆盖\n * 不到、需对照测试锚定漂移),且求值顺序需人肉控制;真实入口文件是隔离执行的\n * 通行形态(vitest / bullmq / piscina 同款)——入口自身的语句先于对用户任务\n * 模块的动态 import 执行,\"读取根播种先于任务模块求值\"由结构保证。\n *\n * 本文件自包含:值导入仅 node:worker_threads,其余全部 type-only(类型剥离后\n * 擦除)——vitest 场景宿主会回退到 src 源文件直跑(resolveWorkerEntryUrl,见\n * taskWorker.ts),无相对导入链才无扩展名解析问题。读取根经 globalThis +\n * Symbol.for 承载而非模块状态:入口 bundle 与 index bundle 是两份代码副本,\n * globalThis 是唯一跨副本共享面(symbol key 与 utils/readResource 的\n * 'faapi.resources.dir' 一致,两处字面量需同步,readResource.test.ts 契约测试\n * 锚定)。主线程 import 本模块仅取导出的纯函数(bootstrap 被 parentPort 守卫),\n * 真实 worker 由 taskWorker.ts 创建。\n */\n\n/** workerData 契约(taskWorker.ts 构造 worker 时传入) */\nexport interface WorkerEntryData {\n /** 任务产物模块 file:// URL(首次 run 消息时动态 import) */\n moduleUrl: string;\n /** 产物 resources 目录绝对路径(缺省不播种——readResource 未绑定即显式抛错) */\n resourcesDir?: string;\n}\n\n/** worker 错误回传负载(serializeError 的产物,宿主 reviveError 重建) */\nexport interface SerializedWorkerError {\n name: string;\n message: string;\n stack: string | undefined;\n props: Record<string, unknown>;\n}\n\n/**\n * worker 内重建注册表只读视图(语义与宿主 createTaskRegistriesView 一致:\n * 不存在的 tool/agent 名静默跳过、resolveAgentTools 按解析后 name 去重)\n *\n * 快照为纯数据(函数闭包不可跨线程),视图在 worker 内重建。\n */\nexport function buildRegistriesView(snapshot?: TaskRegistriesSnapshot) {\n const agents = new Map((snapshot?.agents ?? []).map((a) => [a.name, a] as const));\n const tools = new Map((snapshot?.tools ?? []).map((t) => [t.name, t] as const));\n const skills = new Map((snapshot?.skills ?? []).map((s) => [s.name, s] as const));\n return {\n agent: {\n getAgent: (name: string) => agents.get(name),\n getAgentEntry: (name: string) => agents.get(name),\n listAgents: () => Array.from(agents.values()),\n asTool: (name: string) => {\n const agent = agents.get(name);\n if (!agent) return undefined;\n return {\n kind: 'agent' as const,\n name: `agent.${agent.name}`,\n agentName: agent.name,\n description: agent.description,\n metadata: agent,\n };\n },\n resolveAgentTools: (name: string) => {\n const agent = agents.get(name);\n const result = new Map<string, TaskRegistriesSnapshot['tools'][number]>();\n if (agent?.tools) {\n for (const toolName of agent.tools) {\n const resolved = tools.get(toolName);\n if (resolved) result.set(resolved.name, resolved);\n }\n }\n return Array.from(result.values());\n },\n resolveSubAgents: (name: string) => {\n const agent = agents.get(name);\n const result: TaskRegistriesSnapshot['agents'] = [];\n if (agent?.agents) {\n for (const subName of agent.agents) {\n const sub = agents.get(subName);\n if (sub) result.push(sub);\n }\n }\n return result;\n },\n },\n tool: {\n get: (name: string) => tools.get(name),\n list: () => Array.from(tools.values()),\n },\n skill: {\n get: (name: string) => skills.get(name),\n list: () => Array.from(skills.values()),\n },\n };\n}\n\n/**\n * worker 内错误序列化(错误保真):Error 按 `{ name, message, stack, props }` 回传——\n * `props` 收集自定义可枚举属性(业务错误类的 code/statusCode 等),宿主侧 reviveError\n * 重建时回填;非 Error 值按 String(err) 归一。结构化克隆只保 message(name/自定义\n * 属性丢失、stack 重新生成),不序列化就无法跨线程保真。\n */\nexport function serializeError(err: unknown): SerializedWorkerError {\n if (err instanceof Error) {\n const props: Record<string, unknown> = {};\n for (const key of Object.keys(err)) {\n props[key] = (err as unknown as Record<string, unknown>)[key];\n }\n return { name: err.name, message: err.message, stack: err.stack, props };\n }\n return { name: 'Error', message: String(err), stack: undefined, props: {} };\n}\n\nconst LOG_RANK: Record<LogLevel, number> = { debug: 0, info: 1, warn: 2, error: 3 };\n\n/**\n * 任务日志器:级别预过滤(level 为 undefined 时不过滤——宿主文件管道默认全量)+\n * scope/fields 组装,条目作为纯数据经 `{ type: 'log' }` 消息回传宿主、由宿主统一\n * sink 输出(语义与主包 createLogger 对齐:child scope `:` 合并、调用处 fields\n * 覆盖构造字段;格式化在宿主侧,不跨线程复制格式代码)。\n *\n * fields 含不可克隆值时丢弃 fields、保底 level/message/scope(降级已记入\n * fallback.md)——日志永不中断任务执行,与 progress 的\"不可克隆按执行错误处理\"\n * 不同。\n */\nexport function createTaskLogger(\n level?: LogLevel,\n scope?: string,\n fields?: Record<string, unknown>,\n) {\n const make = (suffix?: string) => {\n const write = (lvl: LogLevel, message: string, callFields?: Record<string, unknown>) => {\n if (level !== undefined && LOG_RANK[lvl] < LOG_RANK[level]) return;\n const entry: LogEntry = { level: lvl, message, time: new Date().toISOString() };\n const fullScope =\n suffix === undefined ? scope : scope === undefined ? suffix : `${scope}:${suffix}`;\n if (fullScope !== undefined) entry.scope = fullScope;\n if (fields !== undefined || callFields !== undefined) {\n entry.fields = { ...fields, ...callFields };\n }\n try {\n parentPort?.postMessage({ type: 'log', entry });\n } catch {\n entry.fields = { warning: 'log fields not cloneable across worker boundary, dropped' };\n parentPort?.postMessage({ type: 'log', entry });\n }\n };\n return {\n debug: (m: string, f?: Record<string, unknown>) => write('debug', m, f),\n info: (m: string, f?: Record<string, unknown>) => write('info', m, f),\n warn: (m: string, f?: Record<string, unknown>) => write('warn', m, f),\n error: (m: string, f?: Record<string, unknown>) => write('error', m, f),\n child: (cs: string) => make(suffix === undefined ? cs : `${suffix}:${cs}`),\n };\n };\n return make(undefined);\n}\n\n/**\n * worker 侧 bootstrap:播种读取根 + 桥接 run 消息\n *\n * 仅在 worker 线程执行(主线程 import 本模块时 parentPort 为空,只取上面的纯\n * 函数)。任务模块在首次 run 消息时才动态 import(modulePromise 缓存)——播种\n * 语句先于它执行,任务模块顶层代码(top-level await 调用 readResource)读到\n * 的绑定必然已就位。\n */\nfunction bootstrap(): void {\n if (!parentPort) return;\n const data = workerData as WorkerEntryData;\n\n // 播种全局 readResource 读取根(缺省不播种——直接构造队列的测试/嵌入场景,\n // readResource 未绑定即显式抛错)\n if (data.resourcesDir) {\n (globalThis as Record<symbol, string | undefined>)[Symbol.for('faapi.resources.dir')] =\n data.resourcesDir;\n }\n\n let controller: AbortController | null = null;\n let modulePromise: Promise<{ run?: (payload: unknown, taskCtx: unknown) => unknown }> | null =\n null;\n\n parentPort.on(\n 'message',\n (msg: {\n type?: string;\n reason?: string;\n payload?: unknown;\n taskCtx?: Record<string, unknown>;\n registries?: TaskRegistriesSnapshot;\n log?: { level?: LogLevel; scope?: string; fields?: Record<string, unknown> };\n }) => {\n if (msg?.type === 'abort') {\n controller?.abort(new Error(msg.reason));\n return;\n }\n if (msg?.type !== 'run') return;\n controller = new AbortController();\n const { payload, taskCtx } = msg;\n void (async () => {\n try {\n modulePromise ??= import(data.moduleUrl);\n const mod = await modulePromise;\n const run = mod.run;\n if (typeof run !== 'function') {\n parentPort?.postMessage({\n type: 'error',\n error: {\n name: 'Error',\n message: 'Task module has no run export',\n stack: undefined,\n props: {},\n },\n });\n return;\n }\n const registries = buildRegistriesView(msg.registries);\n const progress = (value: unknown) => parentPort?.postMessage({ type: 'progress', value });\n const taskLog = msg.log\n ? createTaskLogger(msg.log.level, msg.log.scope, msg.log.fields)\n : undefined;\n const result = await run(payload, {\n ...taskCtx,\n signal: controller!.signal,\n registries,\n progress,\n log: taskLog,\n });\n parentPort?.postMessage({ type: 'done', result });\n } catch (err) {\n const serialized = serializeError(err);\n try {\n parentPort?.postMessage({ type: 'error', error: serialized });\n } catch {\n // props 含不可克隆值(函数等)时丢弃 props,保底 name/message/stack\n parentPort?.postMessage({\n type: 'error',\n error: {\n name: serialized.name,\n message: serialized.message,\n stack: serialized.stack,\n props: {},\n },\n });\n }\n }\n })();\n },\n );\n}\n\nbootstrap();\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/task/workerEntry.ts"],"sourcesContent":["import { parentPort, workerData } from 'node:worker_threads';\nimport type { TaskRegistriesSnapshot } from './taskTypes';\nimport type { LogEntry, LogLevel } from '../logger/loggerTypes';\n\n/**\n * 任务隔离 worker 的真实入口文件(tsup 独立入口 → dist/workerEntry.js)\n *\n * 为什么是独立文件而不是宿主生成的 data URL:data URL 模块无法解析裸说明符\n * ('@faapi/faapi'),framework 侧 helper 只能以字符串模板内联(typecheck 覆盖\n * 不到、需对照测试锚定漂移),且求值顺序需人肉控制;真实入口文件是隔离执行的\n * 通行形态(vitest / bullmq / piscina 同款)——入口自身的语句先于对用户任务\n * 模块的动态 import 执行,\"读取根播种先于任务模块求值\"由结构保证。\n *\n * 本文件自包含:值导入仅 node:worker_threads,其余全部 type-only(类型剥离后\n * 擦除)——vitest 场景宿主会回退到 src 源文件直跑(resolveWorkerEntryUrl,见\n * taskWorker.ts),无相对导入链才无扩展名解析问题。读取根经 globalThis +\n * Symbol.for 承载而非模块状态:入口 bundle 与 index bundle 是两份代码副本,\n * globalThis 是唯一跨副本共享面(symbol key 与 utils/readResource 的\n * 'faapi.resources.dir' 一致,两处字面量需同步,readResource.test.ts 契约测试\n * 锚定)。主线程 import 本模块仅取导出的纯函数(bootstrap 被 parentPort 守卫),\n * 真实 worker 由 taskWorker.ts 创建。\n */\n\n/** workerData 契约(taskWorker.ts 构造 worker 时传入) */\nexport interface WorkerEntryData {\n /** 任务产物模块 file:// URL(首次 run 消息时动态 import) */\n moduleUrl: string;\n /** 产物 resources 目录绝对路径(缺省不播种——readResource 未绑定即显式抛错) */\n resourcesDir?: string;\n}\n\n/**\n * sub-agent 派发工具名前缀(与 injection/subAgentToolName.ts 的 SUB_AGENT_TOOL_PREFIX\n * 同步——本文件自包含不可值导入,taskWorker.test.ts 断言完整派发名锚定漂移)。\n * 快照内的 agent 名来自文件注册表(scanAgents 构建期已校验字符集),直拼即合法。\n */\nconst SUB_AGENT_TOOL_PREFIX = 'agent-';\n\n/** worker 错误回传负载(serializeError 的产物,宿主 reviveError 重建) */\nexport interface SerializedWorkerError {\n name: string;\n message: string;\n stack: string | undefined;\n props: Record<string, unknown>;\n}\n\n/**\n * worker 内重建注册表只读视图(语义与宿主 createTaskRegistriesView 一致:\n * 不存在的 tool/agent 名静默跳过、resolveAgentTools 按解析后 name 去重)\n *\n * 快照为纯数据(函数闭包不可跨线程),视图在 worker 内重建。\n */\nexport function buildRegistriesView(snapshot?: TaskRegistriesSnapshot) {\n const agents = new Map((snapshot?.agents ?? []).map((a) => [a.name, a] as const));\n const tools = new Map((snapshot?.tools ?? []).map((t) => [t.name, t] as const));\n const skills = new Map((snapshot?.skills ?? []).map((s) => [s.name, s] as const));\n return {\n agent: {\n getAgent: (name: string) => agents.get(name),\n getAgentEntry: (name: string) => agents.get(name),\n listAgents: () => Array.from(agents.values()),\n asTool: (name: string) => {\n const agent = agents.get(name);\n if (!agent) return undefined;\n return {\n kind: 'agent' as const,\n name: `${SUB_AGENT_TOOL_PREFIX}${agent.name}`,\n agentName: agent.name,\n description: agent.description,\n metadata: agent,\n };\n },\n resolveAgentTools: (name: string) => {\n const agent = agents.get(name);\n const result = new Map<string, TaskRegistriesSnapshot['tools'][number]>();\n if (agent?.tools) {\n for (const toolName of agent.tools) {\n const resolved = tools.get(toolName);\n if (resolved) result.set(resolved.name, resolved);\n }\n }\n return Array.from(result.values());\n },\n resolveSubAgents: (name: string) => {\n const agent = agents.get(name);\n const result: TaskRegistriesSnapshot['agents'] = [];\n if (agent?.agents) {\n for (const subName of agent.agents) {\n const sub = agents.get(subName);\n if (sub) result.push(sub);\n }\n }\n return result;\n },\n },\n tool: {\n get: (name: string) => tools.get(name),\n list: () => Array.from(tools.values()),\n },\n skill: {\n get: (name: string) => skills.get(name),\n list: () => Array.from(skills.values()),\n },\n };\n}\n\n/**\n * worker 内错误序列化(错误保真):Error 按 `{ name, message, stack, props }` 回传——\n * `props` 收集自定义可枚举属性(业务错误类的 code/statusCode 等),宿主侧 reviveError\n * 重建时回填;非 Error 值按 String(err) 归一。结构化克隆只保 message(name/自定义\n * 属性丢失、stack 重新生成),不序列化就无法跨线程保真。\n */\nexport function serializeError(err: unknown): SerializedWorkerError {\n if (err instanceof Error) {\n const props: Record<string, unknown> = {};\n for (const key of Object.keys(err)) {\n props[key] = (err as unknown as Record<string, unknown>)[key];\n }\n return { name: err.name, message: err.message, stack: err.stack, props };\n }\n return { name: 'Error', message: String(err), stack: undefined, props: {} };\n}\n\nconst LOG_RANK: Record<LogLevel, number> = { debug: 0, info: 1, warn: 2, error: 3 };\n\n/**\n * 任务日志器:级别预过滤(level 为 undefined 时不过滤——宿主文件管道默认全量)+\n * scope/fields 组装,条目作为纯数据经 `{ type: 'log' }` 消息回传宿主、由宿主统一\n * sink 输出(语义与主包 createLogger 对齐:child scope `:` 合并、调用处 fields\n * 覆盖构造字段;格式化在宿主侧,不跨线程复制格式代码)。\n *\n * fields 含不可克隆值时丢弃 fields、保底 level/message/scope(降级已记入\n * fallback.md)——日志永不中断任务执行,与 progress 的\"不可克隆按执行错误处理\"\n * 不同。\n */\nexport function createTaskLogger(\n level?: LogLevel,\n scope?: string,\n fields?: Record<string, unknown>,\n) {\n const make = (suffix?: string) => {\n const write = (lvl: LogLevel, message: string, callFields?: Record<string, unknown>) => {\n if (level !== undefined && LOG_RANK[lvl] < LOG_RANK[level]) return;\n const entry: LogEntry = { level: lvl, message, time: new Date().toISOString() };\n const fullScope =\n suffix === undefined ? scope : scope === undefined ? suffix : `${scope}:${suffix}`;\n if (fullScope !== undefined) entry.scope = fullScope;\n if (fields !== undefined || callFields !== undefined) {\n entry.fields = { ...fields, ...callFields };\n }\n try {\n parentPort?.postMessage({ type: 'log', entry });\n } catch {\n entry.fields = { warning: 'log fields not cloneable across worker boundary, dropped' };\n parentPort?.postMessage({ type: 'log', entry });\n }\n };\n return {\n debug: (m: string, f?: Record<string, unknown>) => write('debug', m, f),\n info: (m: string, f?: Record<string, unknown>) => write('info', m, f),\n warn: (m: string, f?: Record<string, unknown>) => write('warn', m, f),\n error: (m: string, f?: Record<string, unknown>) => write('error', m, f),\n child: (cs: string) => make(suffix === undefined ? cs : `${suffix}:${cs}`),\n };\n };\n return make(undefined);\n}\n\n/**\n * worker 侧 bootstrap:播种读取根 + 桥接 run 消息\n *\n * 仅在 worker 线程执行(主线程 import 本模块时 parentPort 为空,只取上面的纯\n * 函数)。任务模块在首次 run 消息时才动态 import(modulePromise 缓存)——播种\n * 语句先于它执行,任务模块顶层代码(top-level await 调用 readResource)读到\n * 的绑定必然已就位。\n */\nfunction bootstrap(): void {\n if (!parentPort) return;\n const data = workerData as WorkerEntryData;\n\n // 播种全局 readResource 读取根(缺省不播种——直接构造队列的测试/嵌入场景,\n // readResource 未绑定即显式抛错)\n if (data.resourcesDir) {\n (globalThis as Record<symbol, string | undefined>)[Symbol.for('faapi.resources.dir')] =\n data.resourcesDir;\n }\n\n let controller: AbortController | null = null;\n let modulePromise: Promise<{ run?: (payload: unknown, taskCtx: unknown) => unknown }> | null =\n null;\n\n parentPort.on(\n 'message',\n (msg: {\n type?: string;\n reason?: string;\n payload?: unknown;\n taskCtx?: Record<string, unknown>;\n registries?: TaskRegistriesSnapshot;\n log?: { level?: LogLevel; scope?: string; fields?: Record<string, unknown> };\n }) => {\n if (msg?.type === 'abort') {\n controller?.abort(new Error(msg.reason));\n return;\n }\n if (msg?.type !== 'run') return;\n controller = new AbortController();\n const { payload, taskCtx } = msg;\n void (async () => {\n try {\n modulePromise ??= import(data.moduleUrl);\n const mod = await modulePromise;\n const run = mod.run;\n if (typeof run !== 'function') {\n parentPort?.postMessage({\n type: 'error',\n error: {\n name: 'Error',\n message: 'Task module has no run export',\n stack: undefined,\n props: {},\n },\n });\n return;\n }\n const registries = buildRegistriesView(msg.registries);\n const progress = (value: unknown) => parentPort?.postMessage({ type: 'progress', value });\n const taskLog = msg.log\n ? createTaskLogger(msg.log.level, msg.log.scope, msg.log.fields)\n : undefined;\n const result = await run(payload, {\n ...taskCtx,\n signal: controller!.signal,\n registries,\n progress,\n log: taskLog,\n });\n parentPort?.postMessage({ type: 'done', result });\n } catch (err) {\n const serialized = serializeError(err);\n try {\n parentPort?.postMessage({ type: 'error', error: serialized });\n } catch {\n // props 含不可克隆值(函数等)时丢弃 props,保底 name/message/stack\n parentPort?.postMessage({\n type: 'error',\n error: {\n name: serialized.name,\n message: serialized.message,\n stack: serialized.stack,\n props: {},\n },\n });\n }\n }\n })();\n },\n );\n}\n\nbootstrap();\n"],"mappings":"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","names":[]}
|