@faapi/faapi 6.30.0 → 6.32.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/index.js CHANGED
@@ -1126,6 +1126,8 @@ var init_resolveInjection = __esm({
1126
1126
  // 任务子系统:TaskClient(入队/查询)
1127
1127
  log: "log",
1128
1128
  // 请求级日志器(ctx.log 同一实例:scope http,自动带 requestId 等字段)
1129
+ llm: "llm",
1130
+ // 轻量 LLM 补全通道(@faapi/agent 插件注册到 registries.llm;未加载时 undefined)
1129
1131
  // raw 系:恒原始输入(无 schema、无校验、管线永不转换),与 query/params/body
1130
1132
  // 的「校验转换后」口径二分互补
1131
1133
  rawQuery: "rawQuery",
@@ -1970,6 +1972,20 @@ function createAgentHandleStore() {
1970
1972
  }
1971
1973
  };
1972
1974
  }
1975
+ function createLlmChannelStore() {
1976
+ let current = null;
1977
+ return {
1978
+ register(channel) {
1979
+ current = channel;
1980
+ },
1981
+ get() {
1982
+ return current ?? void 0;
1983
+ },
1984
+ clear() {
1985
+ current = null;
1986
+ }
1987
+ };
1988
+ }
1973
1989
  function createTaskHandleStore() {
1974
1990
  let currentFactory = null;
1975
1991
  return {
@@ -2026,7 +2042,8 @@ function createAppRegistries() {
2026
2042
  const task = createTaskRegistry();
2027
2043
  const agentHandle = createAgentHandleStore();
2028
2044
  const taskHandle = createTaskHandleStore();
2029
- return { tool, agent, skill, task, agentHandle, taskHandle };
2045
+ const llm = createLlmChannelStore();
2046
+ return { tool, agent, skill, task, agentHandle, taskHandle, llm };
2030
2047
  }
2031
2048
  var defaultRegistries = createAppRegistries();
2032
2049
 
@@ -2240,6 +2257,7 @@ async function runTaskInWorker(options) {
2240
2257
  job: taskCtx.job
2241
2258
  },
2242
2259
  registries: options.registries,
2260
+ llms: options.llms,
2243
2261
  log: options.log
2244
2262
  });
2245
2263
  } catch (err) {
@@ -2592,6 +2610,9 @@ function createTaskQueue(deps) {
2592
2610
  job: { id: job.id, name: job.name, attempt: job.attempt }
2593
2611
  },
2594
2612
  registries: snapshotRegistries(),
2613
+ // agent.llms 纯数据快照随 workerData 下发,worker 内动态加载 @faapi/agent
2614
+ // 重建轻量补全通道(taskCtx.llm)——llms 未配置时不传
2615
+ llms: deps.llms,
2595
2616
  // 日志配置随 workerData 下发(纯数据),worker 内联重建 taskCtx.log,
2596
2617
  // 条目回传宿主走统一管道(scope/fields 与进程内路径一致)
2597
2618
  log: {
@@ -2621,6 +2642,8 @@ function createTaskQueue(deps) {
2621
2642
  config: deps.config,
2622
2643
  job: { id: job.id, name: job.name, attempt: job.attempt },
2623
2644
  registries: registriesView,
2645
+ // 轻量补全通道惰性读取(插件晚于队列构造注册,执行时刻取值才可见)
2646
+ llm: deps.llm?.get(),
2624
2647
  log: createLogger(`task:${job.name}`, {
2625
2648
  fields: { jobId: job.id, task: job.name, attempt: job.attempt }
2626
2649
  }),
@@ -3926,18 +3949,18 @@ function getDist() {
3926
3949
  }
3927
3950
  return process.env.FAAPI_DIST ?? "dist";
3928
3951
  }
3929
- function getToolSchemaPath(tool, rootDir) {
3952
+ function getToolSchemaPath(ref, rootDir) {
3930
3953
  const dist = getDist();
3931
- return getRuntimeSchemaPath(tool.filePath, dist, rootDir ?? process.cwd());
3954
+ return getRuntimeSchemaPath(ref.filePath, dist, rootDir ?? process.cwd());
3932
3955
  }
3933
- async function loadToolSchema(tool, rootDir) {
3934
- if (!tool.inputTypeName) return void 0;
3935
- const schemaName = `${tool.inputTypeName}Schema`;
3936
- const zodPath = getToolSchemaPath(tool, rootDir);
3956
+ async function loadToolSchema(ref, rootDir) {
3957
+ if (!ref.inputTypeName) return void 0;
3958
+ const schemaName = `${ref.inputTypeName}Schema`;
3959
+ const zodPath = getToolSchemaPath(ref, rootDir);
3937
3960
  if (!existsSync3(zodPath)) return void 0;
3938
3961
  try {
3939
3962
  const mod = await importWithCacheBust(zodPath, isDevOnDemandEnabled());
3940
- const schema = mod[`${tool.inputTypeName}Schema`];
3963
+ const schema = mod[`${ref.inputTypeName}Schema`];
3941
3964
  if (!schema) return void 0;
3942
3965
  return { schema, schemaName };
3943
3966
  } catch {
@@ -5375,6 +5398,10 @@ function getBuiltinInjectionValue(type, ctx, body) {
5375
5398
  // 任务子系统:注入 TaskClient(入队/查询);未注册工厂(无 app 编排)时 undefined
5376
5399
  case "tasks":
5377
5400
  return ctx.registries ? ctx.registries.taskHandle.get(ctx) : void 0;
5401
+ // 轻量 LLM 补全通道:@faapi/agent 插件注册到 registries.llm;与请求上下文无关,
5402
+ // get 无参。插件未加载(或编程式直调 ctx 无 registries)时 undefined
5403
+ case "llm":
5404
+ return ctx.registries ? ctx.registries.llm.get() : void 0;
5378
5405
  // 请求级日志器:与 ctx.log 同一实例(scope http,自动带 requestId/method/path 字段)
5379
5406
  case "log":
5380
5407
  return ctx.log;
@@ -6902,9 +6929,20 @@ function extractAgentMetadata(program, filePath, pathMeta) {
6902
6929
  agents,
6903
6930
  model,
6904
6931
  maxTurns,
6905
- inputDescription
6932
+ inputDescription,
6933
+ inputTypeName: findInputDeclaration(sourceFile) ? "Input" : void 0
6906
6934
  };
6907
6935
  }
6936
+ function findInputDeclaration(sourceFile) {
6937
+ let found = false;
6938
+ ts11.forEachChild(sourceFile, (node) => {
6939
+ if (found) return;
6940
+ if ((ts11.isInterfaceDeclaration(node) || ts11.isTypeAliasDeclaration(node)) && node.name.text === "Input") {
6941
+ found = true;
6942
+ }
6943
+ });
6944
+ return found;
6945
+ }
6908
6946
  function findRunExportOwner(sourceFile) {
6909
6947
  let result = null;
6910
6948
  ts11.forEachChild(sourceFile, (node) => {
@@ -7111,6 +7149,9 @@ function extractStringArrayValue(expr) {
7111
7149
  // src/cli/generateAgentArtifacts.ts
7112
7150
  init_createProgram();
7113
7151
  init_atomicWrite();
7152
+ init_extractHandlerTypes();
7153
+ init_generateZodSchema();
7154
+ init_generateZodArtifacts();
7114
7155
  var AGENTS_FILE = "faapi-agents.js";
7115
7156
  function serializeAgents(agents, dist = "dist") {
7116
7157
  return agents.map((a) => ({
@@ -7123,6 +7164,7 @@ function serializeAgents(agents, dist = "dist") {
7123
7164
  model: a.model,
7124
7165
  maxTurns: a.maxTurns,
7125
7166
  inputDescription: a.inputDescription,
7167
+ inputTypeName: a.inputTypeName,
7126
7168
  filePath: toProdFilePath(a.filePath, dist)
7127
7169
  }));
7128
7170
  }
@@ -7143,7 +7185,8 @@ function hydrateAgents(manifest) {
7143
7185
  agents: a.agents ?? void 0,
7144
7186
  model: a.model ?? void 0,
7145
7187
  maxTurns: a.maxTurns ?? void 0,
7146
- inputDescription: a.inputDescription ?? void 0
7188
+ inputDescription: a.inputDescription ?? void 0,
7189
+ inputTypeName: a.inputTypeName ?? void 0
7147
7190
  }));
7148
7191
  }
7149
7192
  function validateAgentList(metadata) {
@@ -7189,8 +7232,66 @@ async function generateAgentArtifacts(agents, rootDir, dist) {
7189
7232
  const serialized = serializeAgents(metadata, dist);
7190
7233
  const agentsPath = path24.resolve(rootDir, dist, AGENTS_FILE);
7191
7234
  await writeAgentsModule(serialized, agentsPath);
7235
+ await generateAgentZodArtifacts(metadata, programByFile, rootDir, dist);
7192
7236
  return metadata;
7193
7237
  }
7238
+ async function generateAgentZodArtifacts(metadata, programByFile, rootDir, dist) {
7239
+ const declared = metadata.filter((a) => a.inputTypeName);
7240
+ if (declared.length === 0) return;
7241
+ const resolversByFile = /* @__PURE__ */ new Map();
7242
+ const sources = [];
7243
+ for (const agent of declared) {
7244
+ const absPath = path24.resolve(rootDir, agent.filePath);
7245
+ const program = programByFile.get(absPath);
7246
+ if (!program) {
7247
+ throw new Error(
7248
+ `agent "${agent.name}" \u6E90\u6587\u4EF6\u4E0D\u5728 Program \u4E2D: ${agent.filePath}\u2014\u2014\u65E0\u6CD5\u751F\u6210\u5165\u53C2 schema`
7249
+ );
7250
+ }
7251
+ if (!resolversByFile.has(absPath)) {
7252
+ resolversByFile.set(absPath, createLazyTypeResolver(program, absPath));
7253
+ }
7254
+ const typeInfo = extractTypeInfo(program, absPath, agent.inputTypeName);
7255
+ sources.push({
7256
+ name: agent.name,
7257
+ filePath: absPath,
7258
+ schemaName: agent.inputTypeName,
7259
+ typeInfo
7260
+ });
7261
+ }
7262
+ await generateZodArtifacts(sources, {
7263
+ generateFileSource: generateAgentSchemaFileSource,
7264
+ resolversByFile,
7265
+ rootDir,
7266
+ dist
7267
+ });
7268
+ }
7269
+ function generateAgentSchemaFileSource(sources, resolveType, helpersImportPath) {
7270
+ const lines = ["import { z } from 'zod';"];
7271
+ const schemaBlocks = [];
7272
+ for (const source of sources) {
7273
+ if (!source.typeInfo) continue;
7274
+ const block = [`// agent ${source.name} \u2192 ${source.schemaName}`];
7275
+ const schemaCode = generateZodSchemaSource(
7276
+ source.typeInfo,
7277
+ resolveType,
7278
+ source.schemaName,
7279
+ false
7280
+ ).replace(/^import \{ z \} from 'zod';\s*\n\s*\n/, "");
7281
+ block.push(schemaCode);
7282
+ block.push("");
7283
+ schemaBlocks.push(block.join("\n"));
7284
+ }
7285
+ const allSchemaCode = schemaBlocks.join("\n");
7286
+ if (helpersImportPath && usesCoerceHelpers(allSchemaCode)) {
7287
+ lines.push(
7288
+ `import { coerceNumber, coerceBoolean, coerceMap, coerceSet } from '${helpersImportPath}';`
7289
+ );
7290
+ }
7291
+ lines.push("");
7292
+ lines.push(...schemaBlocks);
7293
+ return lines.join("\n").replace(/\n+$/, "\n");
7294
+ }
7194
7295
 
7195
7296
  // src/cli/generateTaskArtifacts.ts
7196
7297
  init_generateZodArtifacts();
@@ -7581,6 +7682,10 @@ async function createAppBase(options) {
7581
7682
  config,
7582
7683
  resourcesDir,
7583
7684
  registries: createTaskRegistriesView(registries),
7685
+ // 轻量补全通道:进程内路径经 store 惰性读取(插件注册后的活引用);
7686
+ // 隔离路径传 agent.llms 纯数据快照(worker 内重建)
7687
+ llm: registries.llm,
7688
+ llms: config?.agent?.llms,
7584
7689
  driver: taskDriver,
7585
7690
  onFailed: config?.task?.onFailed
7586
7691
  });
@@ -7718,6 +7823,7 @@ async function createAppBase(options) {
7718
7823
  registries.task.clear();
7719
7824
  registries.agentHandle.clear();
7720
7825
  registries.taskHandle.clear();
7826
+ registries.llm.clear();
7721
7827
  setActiveResourcesDir(null);
7722
7828
  if (!server.listening) {
7723
7829
  app.server = null;