mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-09-17 07:17:18 +00:00
feat(runner): unify plugin execution across agents and event processors
This commit is contained in:
@@ -4,17 +4,22 @@ import { loadFixtureItems } from "../fixtures.ts";
|
||||
import { dirname, join } from "node:path";
|
||||
import { existsSync, readFileSync } from "node:fs";
|
||||
|
||||
function fixtureRows(root: string, skill: string | undefined): ReturnType<typeof loadFixtureItems> {
|
||||
function fixtureRows(
|
||||
root: string,
|
||||
skill: string | undefined,
|
||||
): ReturnType<typeof loadFixtureItems> {
|
||||
return loadFixtureItems(root, skill);
|
||||
}
|
||||
|
||||
function qaAgentRunnerSourceFindings(item: ReturnType<typeof loadFixtureItems>["items"][number]) {
|
||||
if (!item.checks.includes("qa_agent_runner_source") || !item.exists) return [];
|
||||
function qaRunnerSourceFindings(
|
||||
item: ReturnType<typeof loadFixtureItems>["items"][number],
|
||||
) {
|
||||
if (!item.checks.includes("qa_runner_source") || !item.exists) return [];
|
||||
const root = dirname(item.absolute_path);
|
||||
const required = [
|
||||
"main.py",
|
||||
"components/agent_runner/default.yaml",
|
||||
"components/agent_runner/default.py",
|
||||
"components/runner/default.yaml",
|
||||
"components/runner/default.py",
|
||||
"assets/icon.svg",
|
||||
];
|
||||
const missing = required
|
||||
@@ -28,15 +33,21 @@ function qaAgentRunnerSourceFindings(item: ReturnType<typeof loadFixtureItems>["
|
||||
if (missing.length > 0) return missing;
|
||||
|
||||
const manifest = readFileSync(item.absolute_path, "utf8");
|
||||
const runnerYaml = readFileSync(join(root, "components/agent_runner/default.yaml"), "utf8");
|
||||
const runnerPy = readFileSync(join(root, "components/agent_runner/default.py"), "utf8");
|
||||
const runnerYaml = readFileSync(
|
||||
join(root, "components/runner/default.yaml"),
|
||||
"utf8",
|
||||
);
|
||||
const runnerPy = readFileSync(
|
||||
join(root, "components/runner/default.py"),
|
||||
"utf8",
|
||||
);
|
||||
const requiredText = [
|
||||
[manifest, "AgentRunner", "manifest.yaml"],
|
||||
[manifest, "QAAgentRunnerPlugin", "manifest.yaml"],
|
||||
[runnerYaml, "kind: AgentRunner", "components/agent_runner/default.yaml"],
|
||||
[runnerYaml, "DefaultAgentRunner", "components/agent_runner/default.yaml"],
|
||||
[runnerPy, "QA_AGENT_RUNNER_OK", "components/agent_runner/default.py"],
|
||||
[runnerPy, "QA_AGENT_RUNNER_CONTROLLED_FAILURE", "components/agent_runner/default.py"],
|
||||
[manifest, "Runner", "manifest.yaml"],
|
||||
[manifest, "QARunnerPlugin", "manifest.yaml"],
|
||||
[runnerYaml, "kind: Runner", "components/runner/default.yaml"],
|
||||
[runnerYaml, "DefaultRunner", "components/runner/default.yaml"],
|
||||
[runnerPy, "QA_RUNNER_OK", "components/runner/default.py"],
|
||||
[runnerPy, "QA_RUNNER_CONTROLLED_FAILURE", "components/runner/default.py"],
|
||||
];
|
||||
return requiredText
|
||||
.filter(([text, needle]) => !text.includes(needle))
|
||||
@@ -49,16 +60,22 @@ function qaAgentRunnerSourceFindings(item: ReturnType<typeof loadFixtureItems>["
|
||||
}));
|
||||
}
|
||||
|
||||
function zipPackageFindings(item: ReturnType<typeof loadFixtureItems>["items"][number]) {
|
||||
function zipPackageFindings(
|
||||
item: ReturnType<typeof loadFixtureItems>["items"][number],
|
||||
) {
|
||||
if (!item.checks.includes("zip_package") || !item.exists) return [];
|
||||
const header = readFileSync(item.absolute_path).subarray(0, 4).toString("binary");
|
||||
const header = readFileSync(item.absolute_path)
|
||||
.subarray(0, 4)
|
||||
.toString("binary");
|
||||
if (header === "PK\u0003\u0004" || header === "PK\u0005\u0006") return [];
|
||||
return [{
|
||||
severity: "fail",
|
||||
kind: "fixture_check_invalid_zip",
|
||||
id: item.id,
|
||||
path: item.path,
|
||||
}];
|
||||
return [
|
||||
{
|
||||
severity: "fail",
|
||||
kind: "fixture_check_invalid_zip",
|
||||
id: item.id,
|
||||
path: item.path,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
export function commandFixtureList(ctx: CommandContext): number {
|
||||
@@ -72,14 +89,16 @@ export function commandFixtureList(ctx: CommandContext): number {
|
||||
}
|
||||
|
||||
for (const item of result.items) {
|
||||
console.log([
|
||||
item.skill,
|
||||
item.id,
|
||||
item.kind,
|
||||
item.exists ? "present" : "missing",
|
||||
item.path,
|
||||
item.title,
|
||||
].join("\t"));
|
||||
console.log(
|
||||
[
|
||||
item.skill,
|
||||
item.id,
|
||||
item.kind,
|
||||
item.exists ? "present" : "missing",
|
||||
item.path,
|
||||
item.title,
|
||||
].join("\t"),
|
||||
);
|
||||
}
|
||||
for (const error of result.errors) console.error(`ERROR: ${error}`);
|
||||
return result.errors.length > 0 ? 1 : 0;
|
||||
@@ -90,7 +109,11 @@ export function commandFixtureCheck(ctx: CommandContext): number {
|
||||
const skill = positional[0];
|
||||
const result = fixtureRows(ctx.root, skill);
|
||||
const findings = [
|
||||
...result.errors.map((error) => ({ severity: "fail", kind: "invalid_manifest", detail: error })),
|
||||
...result.errors.map((error) => ({
|
||||
severity: "fail",
|
||||
kind: "invalid_manifest",
|
||||
detail: error,
|
||||
})),
|
||||
...result.items
|
||||
.filter((item) => !item.exists)
|
||||
.map((item) => ({
|
||||
@@ -100,11 +123,13 @@ export function commandFixtureCheck(ctx: CommandContext): number {
|
||||
path: item.path,
|
||||
absolute_path: item.absolute_path,
|
||||
})),
|
||||
...result.items.flatMap(qaAgentRunnerSourceFindings),
|
||||
...result.items.flatMap(qaRunnerSourceFindings),
|
||||
...result.items.flatMap(zipPackageFindings),
|
||||
];
|
||||
const report = {
|
||||
status: findings.some((finding) => finding.severity === "fail") ? "fail" : "pass",
|
||||
status: findings.some((finding) => finding.severity === "fail")
|
||||
? "fail"
|
||||
: "pass",
|
||||
fixture_count: result.items.length,
|
||||
findings,
|
||||
fixtures: result.items,
|
||||
@@ -120,12 +145,18 @@ export function commandFixtureCheck(ctx: CommandContext): number {
|
||||
console.log("");
|
||||
console.log("## Fixtures");
|
||||
for (const item of result.items) {
|
||||
console.log(`- ${item.id}: ${item.exists ? "present" : "missing"} (${item.path})`);
|
||||
console.log(
|
||||
`- ${item.id}: ${item.exists ? "present" : "missing"} (${item.path})`,
|
||||
);
|
||||
}
|
||||
console.log("");
|
||||
console.log("## Findings");
|
||||
if (findings.length === 0) console.log("- None.");
|
||||
else for (const finding of findings) console.log(`- [${finding.severity}] ${finding.kind}: ${"detail" in finding ? finding.detail : finding.id}`);
|
||||
else
|
||||
for (const finding of findings)
|
||||
console.log(
|
||||
`- [${finding.severity}] ${finding.kind}: ${"detail" in finding ? finding.detail : finding.id}`,
|
||||
);
|
||||
}
|
||||
|
||||
return report.status === "pass" ? 0 : 1;
|
||||
|
||||
+668
-232
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user