@faapi/faapi 6.29.0 → 6.31.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 +113 -3
- package/dist/cli/index.js.map +1 -1
- package/dist/{contextTypes-DhagvRH_.d.ts → contextTypes-BKQsSVMv.d.ts} +10 -1
- package/dist/index.d.ts +48 -31
- package/dist/index.js +119 -9
- package/dist/index.js.map +1 -1
- package/dist/{routeTypes-0rwuIws-.d.ts → routeTypes-Cc0P3CcU.d.ts} +1 -1
- package/dist/testing.d.ts +2 -2
- package/dist/workerEntry.d.ts +1 -1
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -3237,9 +3237,20 @@ function extractAgentMetadata(program, filePath, pathMeta) {
|
|
|
3237
3237
|
agents,
|
|
3238
3238
|
model,
|
|
3239
3239
|
maxTurns,
|
|
3240
|
-
inputDescription
|
|
3240
|
+
inputDescription,
|
|
3241
|
+
inputTypeName: findInputDeclaration(sourceFile) ? "Input" : void 0
|
|
3241
3242
|
};
|
|
3242
3243
|
}
|
|
3244
|
+
function findInputDeclaration(sourceFile) {
|
|
3245
|
+
let found = false;
|
|
3246
|
+
ts11.forEachChild(sourceFile, (node) => {
|
|
3247
|
+
if (found) return;
|
|
3248
|
+
if ((ts11.isInterfaceDeclaration(node) || ts11.isTypeAliasDeclaration(node)) && node.name.text === "Input") {
|
|
3249
|
+
found = true;
|
|
3250
|
+
}
|
|
3251
|
+
});
|
|
3252
|
+
return found;
|
|
3253
|
+
}
|
|
3243
3254
|
function findRunExportOwner(sourceFile) {
|
|
3244
3255
|
let result = null;
|
|
3245
3256
|
ts11.forEachChild(sourceFile, (node) => {
|
|
@@ -3464,6 +3475,7 @@ function serializeAgents(agents, dist = "dist") {
|
|
|
3464
3475
|
model: a.model,
|
|
3465
3476
|
maxTurns: a.maxTurns,
|
|
3466
3477
|
inputDescription: a.inputDescription,
|
|
3478
|
+
inputTypeName: a.inputTypeName,
|
|
3467
3479
|
filePath: toProdFilePath(a.filePath, dist)
|
|
3468
3480
|
}));
|
|
3469
3481
|
}
|
|
@@ -3484,7 +3496,8 @@ function hydrateAgents(manifest) {
|
|
|
3484
3496
|
agents: a.agents ?? void 0,
|
|
3485
3497
|
model: a.model ?? void 0,
|
|
3486
3498
|
maxTurns: a.maxTurns ?? void 0,
|
|
3487
|
-
inputDescription: a.inputDescription ?? void 0
|
|
3499
|
+
inputDescription: a.inputDescription ?? void 0,
|
|
3500
|
+
inputTypeName: a.inputTypeName ?? void 0
|
|
3488
3501
|
}));
|
|
3489
3502
|
}
|
|
3490
3503
|
function validateAgentList(metadata) {
|
|
@@ -3530,8 +3543,66 @@ async function generateAgentArtifacts(agents, rootDir, dist) {
|
|
|
3530
3543
|
const serialized = serializeAgents(metadata, dist);
|
|
3531
3544
|
const agentsPath = path15.resolve(rootDir, dist, AGENTS_FILE);
|
|
3532
3545
|
await writeAgentsModule(serialized, agentsPath);
|
|
3546
|
+
await generateAgentZodArtifacts(metadata, programByFile, rootDir, dist);
|
|
3533
3547
|
return metadata;
|
|
3534
3548
|
}
|
|
3549
|
+
async function generateAgentZodArtifacts(metadata, programByFile, rootDir, dist) {
|
|
3550
|
+
const declared = metadata.filter((a) => a.inputTypeName);
|
|
3551
|
+
if (declared.length === 0) return;
|
|
3552
|
+
const resolversByFile = /* @__PURE__ */ new Map();
|
|
3553
|
+
const sources = [];
|
|
3554
|
+
for (const agent of declared) {
|
|
3555
|
+
const absPath = path15.resolve(rootDir, agent.filePath);
|
|
3556
|
+
const program = programByFile.get(absPath);
|
|
3557
|
+
if (!program) {
|
|
3558
|
+
throw new Error(
|
|
3559
|
+
`agent "${agent.name}" \u6E90\u6587\u4EF6\u4E0D\u5728 Program \u4E2D: ${agent.filePath}\u2014\u2014\u65E0\u6CD5\u751F\u6210\u5165\u53C2 schema`
|
|
3560
|
+
);
|
|
3561
|
+
}
|
|
3562
|
+
if (!resolversByFile.has(absPath)) {
|
|
3563
|
+
resolversByFile.set(absPath, createLazyTypeResolver(program, absPath));
|
|
3564
|
+
}
|
|
3565
|
+
const typeInfo = extractTypeInfo(program, absPath, agent.inputTypeName);
|
|
3566
|
+
sources.push({
|
|
3567
|
+
name: agent.name,
|
|
3568
|
+
filePath: absPath,
|
|
3569
|
+
schemaName: agent.inputTypeName,
|
|
3570
|
+
typeInfo
|
|
3571
|
+
});
|
|
3572
|
+
}
|
|
3573
|
+
await generateZodArtifacts(sources, {
|
|
3574
|
+
generateFileSource: generateAgentSchemaFileSource,
|
|
3575
|
+
resolversByFile,
|
|
3576
|
+
rootDir,
|
|
3577
|
+
dist
|
|
3578
|
+
});
|
|
3579
|
+
}
|
|
3580
|
+
function generateAgentSchemaFileSource(sources, resolveType, helpersImportPath) {
|
|
3581
|
+
const lines = ["import { z } from 'zod';"];
|
|
3582
|
+
const schemaBlocks = [];
|
|
3583
|
+
for (const source of sources) {
|
|
3584
|
+
if (!source.typeInfo) continue;
|
|
3585
|
+
const block = [`// agent ${source.name} \u2192 ${source.schemaName}`];
|
|
3586
|
+
const schemaCode = generateZodSchemaSource(
|
|
3587
|
+
source.typeInfo,
|
|
3588
|
+
resolveType,
|
|
3589
|
+
source.schemaName,
|
|
3590
|
+
false
|
|
3591
|
+
).replace(/^import \{ z \} from 'zod';\s*\n\s*\n/, "");
|
|
3592
|
+
block.push(schemaCode);
|
|
3593
|
+
block.push("");
|
|
3594
|
+
schemaBlocks.push(block.join("\n"));
|
|
3595
|
+
}
|
|
3596
|
+
const allSchemaCode = schemaBlocks.join("\n");
|
|
3597
|
+
if (helpersImportPath && usesCoerceHelpers(allSchemaCode)) {
|
|
3598
|
+
lines.push(
|
|
3599
|
+
`import { coerceNumber, coerceBoolean, coerceMap, coerceSet } from '${helpersImportPath}';`
|
|
3600
|
+
);
|
|
3601
|
+
}
|
|
3602
|
+
lines.push("");
|
|
3603
|
+
lines.push(...schemaBlocks);
|
|
3604
|
+
return lines.join("\n").replace(/\n+$/, "\n");
|
|
3605
|
+
}
|
|
3535
3606
|
var AGENTS_FILE;
|
|
3536
3607
|
var init_generateAgentArtifacts = __esm({
|
|
3537
3608
|
"src/cli/generateAgentArtifacts.ts"() {
|
|
@@ -3540,6 +3611,9 @@ var init_generateAgentArtifacts = __esm({
|
|
|
3540
3611
|
init_createProgram();
|
|
3541
3612
|
init_prodPaths();
|
|
3542
3613
|
init_atomicWrite();
|
|
3614
|
+
init_extractHandlerTypes();
|
|
3615
|
+
init_generateZodSchema();
|
|
3616
|
+
init_generateZodArtifacts();
|
|
3543
3617
|
AGENTS_FILE = "faapi-agents.js";
|
|
3544
3618
|
}
|
|
3545
3619
|
});
|
|
@@ -3548,6 +3622,31 @@ var init_generateAgentArtifacts = __esm({
|
|
|
3548
3622
|
import fg4 from "fast-glob";
|
|
3549
3623
|
import path16 from "path";
|
|
3550
3624
|
import fs12 from "fs";
|
|
3625
|
+
function detectIgnoredMetaFields(source, strictHit) {
|
|
3626
|
+
const declared = /* @__PURE__ */ new Set();
|
|
3627
|
+
for (const line of source.split("\n")) {
|
|
3628
|
+
const trimmed = line.trim();
|
|
3629
|
+
if (trimmed.startsWith("//")) continue;
|
|
3630
|
+
for (const field of ALL_META_FIELDS) {
|
|
3631
|
+
if (new RegExp(`\\b${field}\\s*:`).test(trimmed)) declared.add(field);
|
|
3632
|
+
}
|
|
3633
|
+
}
|
|
3634
|
+
return ALL_META_FIELDS.filter((field) => declared.has(field) && !strictHit[field]);
|
|
3635
|
+
}
|
|
3636
|
+
function warnIgnoredMetaFields(name, fields) {
|
|
3637
|
+
for (const field of fields) {
|
|
3638
|
+
if (STRING_META_FIELDS.includes(field)) {
|
|
3639
|
+
console.warn(
|
|
3640
|
+
`[faapi] Task "${name}" declares "${field}" but its value is not a string literal \u2014 the declaration was ignored and the task will not be cron-scheduled. Meta values are extracted from source code without importing it, so only literal values are recognized: use a quoted literal (cron: '0 3 * * *'), not an expression or a dynamic value.`
|
|
3641
|
+
);
|
|
3642
|
+
} else {
|
|
3643
|
+
const consequence = field === "timeoutMs" ? " and the task will run in-process with no timeout" : "";
|
|
3644
|
+
console.warn(
|
|
3645
|
+
`[faapi] Task "${name}" declares "${field}" but its value is not a numeric literal \u2014 the declaration was ignored${consequence}. Meta values are extracted from source code without importing it, so only literal values are recognized (underscores allowed, e.g. 1_800_000); expressions like 30 * 60_000 or dynamic values are not supported.`
|
|
3646
|
+
);
|
|
3647
|
+
}
|
|
3648
|
+
}
|
|
3649
|
+
}
|
|
3551
3650
|
function parseNumericLiteral(raw) {
|
|
3552
3651
|
return Number(raw.replace(/_/g, ""));
|
|
3553
3652
|
}
|
|
@@ -3607,11 +3706,19 @@ async function scanTasks(rootDir, patterns) {
|
|
|
3607
3706
|
manifest.timeoutMs = value;
|
|
3608
3707
|
}
|
|
3609
3708
|
if (graceMs !== void 0) manifest.graceMs = parseNumericLiteral(graceMs);
|
|
3709
|
+
const strictHit = {
|
|
3710
|
+
cron: cron !== void 0,
|
|
3711
|
+
concurrency: concurrency !== void 0,
|
|
3712
|
+
retries: retries !== void 0,
|
|
3713
|
+
timeoutMs: timeoutMs !== void 0,
|
|
3714
|
+
graceMs: graceMs !== void 0
|
|
3715
|
+
};
|
|
3716
|
+
warnIgnoredMetaFields(name, detectIgnoredMetaFields(source, strictHit));
|
|
3610
3717
|
tasks.push(manifest);
|
|
3611
3718
|
}
|
|
3612
3719
|
return tasks.sort((a, b) => a.name.localeCompare(b.name));
|
|
3613
3720
|
}
|
|
3614
|
-
var TASK_PATTERNS, TASK_FILENAME, CRON_RE, NUM_LITERAL, CONCURRENCY_RE, RETRIES_RE, TIMEOUT_MS_RE, GRACE_MS_RE, MIN_ISOLATED_TIMEOUT_MS, MAX_ISOLATED_TIMEOUT_MS;
|
|
3721
|
+
var TASK_PATTERNS, TASK_FILENAME, CRON_RE, NUM_LITERAL, CONCURRENCY_RE, RETRIES_RE, TIMEOUT_MS_RE, GRACE_MS_RE, NUMERIC_META_FIELDS, STRING_META_FIELDS, ALL_META_FIELDS, MIN_ISOLATED_TIMEOUT_MS, MAX_ISOLATED_TIMEOUT_MS;
|
|
3615
3722
|
var init_scanTasks = __esm({
|
|
3616
3723
|
"src/task/scanTasks.ts"() {
|
|
3617
3724
|
"use strict";
|
|
@@ -3623,6 +3730,9 @@ var init_scanTasks = __esm({
|
|
|
3623
3730
|
RETRIES_RE = new RegExp(`(?:^|\\n)\\s*retries:\\s*${NUM_LITERAL}`);
|
|
3624
3731
|
TIMEOUT_MS_RE = new RegExp(`(?:^|\\n)\\s*timeoutMs:\\s*${NUM_LITERAL}`);
|
|
3625
3732
|
GRACE_MS_RE = new RegExp(`(?:^|\\n)\\s*graceMs:\\s*${NUM_LITERAL}`);
|
|
3733
|
+
NUMERIC_META_FIELDS = ["concurrency", "retries", "timeoutMs", "graceMs"];
|
|
3734
|
+
STRING_META_FIELDS = ["cron"];
|
|
3735
|
+
ALL_META_FIELDS = [...NUMERIC_META_FIELDS, ...STRING_META_FIELDS];
|
|
3626
3736
|
MIN_ISOLATED_TIMEOUT_MS = 6e4;
|
|
3627
3737
|
MAX_ISOLATED_TIMEOUT_MS = 23 * 60 * 6e4;
|
|
3628
3738
|
}
|