chore: fix all biome lint errors
- Auto-fix string concatenation → template literals - Remove unused imports - Prefix unused function with underscore - Format fixes across multiple files
This commit is contained in:
@@ -1,7 +1,10 @@
|
|||||||
{
|
{
|
||||||
"name": "@uncaged/cli-workflow",
|
"name": "@uncaged/cli-workflow",
|
||||||
"version": "0.3.16",
|
"version": "0.3.16",
|
||||||
"files": ["dist", "package.json"],
|
"files": [
|
||||||
|
"dist",
|
||||||
|
"package.json"
|
||||||
|
],
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"bin": {
|
"bin": {
|
||||||
"uncaged-workflow": "src/cli.ts"
|
"uncaged-workflow": "src/cli.ts"
|
||||||
@@ -20,4 +23,4 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "bun test"
|
"test": "bun test"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import { err, ok, type Result } from "@uncaged/workflow-protocol";
|
|||||||
|
|
||||||
import { pathExists } from "../../fs-utils.js";
|
import { pathExists } from "../../fs-utils.js";
|
||||||
import type { CmdInitWorkspaceSuccess } from "./types.js";
|
import type { CmdInitWorkspaceSuccess } from "./types.js";
|
||||||
import { validateWorkspaceSegment } from "./validate.js";
|
|
||||||
|
|
||||||
function rootPackageJson(workspaceName: string): string {
|
function rootPackageJson(workspaceName: string): string {
|
||||||
return `${JSON.stringify(
|
return `${JSON.stringify(
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { existsSync } from "node:fs";
|
import { existsSync } from "node:fs";
|
||||||
|
import { resolve as resolvePath } from "node:path";
|
||||||
import { stdin as input, stdout as output } from "node:process";
|
import { stdin as input, stdout as output } from "node:process";
|
||||||
import { createInterface } from "node:readline/promises";
|
import { createInterface } from "node:readline/promises";
|
||||||
import { resolve as resolvePath } from "node:path";
|
|
||||||
|
|
||||||
import { err, ok, type Result } from "@uncaged/workflow-protocol";
|
import { err, ok, type Result } from "@uncaged/workflow-protocol";
|
||||||
|
|
||||||
@@ -10,6 +10,7 @@ import { createLogger } from "@uncaged/workflow-util";
|
|||||||
import { printCliError, printCliLine, printCliWarn } from "../../cli-output.js";
|
import { printCliError, printCliLine, printCliWarn } from "../../cli-output.js";
|
||||||
|
|
||||||
const setupDispatchLog = createLogger({ sink: { kind: "stderr" } });
|
const setupDispatchLog = createLogger({ sink: { kind: "stderr" } });
|
||||||
|
|
||||||
import { loadPresetProviders } from "./preset-providers.js";
|
import { loadPresetProviders } from "./preset-providers.js";
|
||||||
import { cmdSetup, printSetupSummary } from "./setup.js";
|
import { cmdSetup, printSetupSummary } from "./setup.js";
|
||||||
import type { SetupCliArgs } from "./types.js";
|
import type { SetupCliArgs } from "./types.js";
|
||||||
@@ -201,11 +202,8 @@ async function promptSecret(label: string): Promise<string> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Fetch available models from an OpenAI-compatible /models endpoint. */
|
/** Fetch available models from an OpenAI-compatible /models endpoint. */
|
||||||
async function fetchAvailableModels(
|
async function fetchAvailableModels(baseUrl: string, apiKey: string): Promise<string[]> {
|
||||||
baseUrl: string,
|
const url = `${baseUrl.replace(/\/+$/, "")}/models`;
|
||||||
apiKey: string,
|
|
||||||
): Promise<string[]> {
|
|
||||||
const url = baseUrl.replace(/\/+$/, "") + "/models";
|
|
||||||
try {
|
try {
|
||||||
const res = await fetch(url, {
|
const res = await fetch(url, {
|
||||||
headers: { Authorization: `Bearer ${apiKey}` },
|
headers: { Authorization: `Bearer ${apiKey}` },
|
||||||
@@ -228,7 +226,10 @@ async function fetchAvailableModels(
|
|||||||
.filter((id) => !NON_CHAT_RE.test(id))
|
.filter((id) => !NON_CHAT_RE.test(id))
|
||||||
.sort();
|
.sort();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
setupDispatchLog("V8NQ4JT6", `fetch models failed: ${e instanceof Error ? e.message : String(e)}`);
|
setupDispatchLog(
|
||||||
|
"V8NQ4JT6",
|
||||||
|
`fetch models failed: ${e instanceof Error ? e.message : String(e)}`,
|
||||||
|
);
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,45 +5,43 @@ import { parse as parseYaml } from "yaml";
|
|||||||
|
|
||||||
import type { PresetProvider } from "./types.js";
|
import type { PresetProvider } from "./types.js";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
type RawPresetEntry = {
|
type RawPresetEntry = {
|
||||||
name: unknown;
|
name: unknown;
|
||||||
label: unknown;
|
label: unknown;
|
||||||
baseUrl: unknown;
|
baseUrl: unknown;
|
||||||
};
|
};
|
||||||
|
|
||||||
function isRawEntry(v: unknown): v is RawPresetEntry {
|
function isRawEntry(v: unknown): v is RawPresetEntry {
|
||||||
if (typeof v !== "object" || v === null) return false;
|
if (typeof v !== "object" || v === null) return false;
|
||||||
const o = v as Record<string, unknown>;
|
const o = v as Record<string, unknown>;
|
||||||
return typeof o.name === "string" && typeof o.label === "string" && typeof o.baseUrl === "string";
|
return typeof o.name === "string" && typeof o.label === "string" && typeof o.baseUrl === "string";
|
||||||
}
|
}
|
||||||
|
|
||||||
let cached: ReadonlyArray<PresetProvider> | null = null;
|
let cached: ReadonlyArray<PresetProvider> | null = null;
|
||||||
|
|
||||||
export function loadPresetProviders(): ReadonlyArray<PresetProvider> {
|
export function loadPresetProviders(): ReadonlyArray<PresetProvider> {
|
||||||
if (cached !== null) return cached;
|
if (cached !== null) return cached;
|
||||||
|
|
||||||
const yamlPath = join(import.meta.dirname, "providers.yaml");
|
const yamlPath = join(import.meta.dirname, "providers.yaml");
|
||||||
const raw = readFileSync(yamlPath, "utf8");
|
const raw = readFileSync(yamlPath, "utf8");
|
||||||
const parsed: unknown = parseYaml(raw);
|
const parsed: unknown = parseYaml(raw);
|
||||||
|
|
||||||
if (!Array.isArray(parsed)) {
|
if (!Array.isArray(parsed)) {
|
||||||
throw new Error(`providers.yaml: expected array, got ${typeof parsed}`);
|
throw new Error(`providers.yaml: expected array, got ${typeof parsed}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const result: PresetProvider[] = [];
|
const result: PresetProvider[] = [];
|
||||||
for (const entry of parsed) {
|
for (const entry of parsed) {
|
||||||
if (!isRawEntry(entry)) {
|
if (!isRawEntry(entry)) {
|
||||||
throw new Error(`providers.yaml: invalid entry: ${JSON.stringify(entry)}`);
|
throw new Error(`providers.yaml: invalid entry: ${JSON.stringify(entry)}`);
|
||||||
}
|
}
|
||||||
result.push({
|
result.push({
|
||||||
name: entry.name as string,
|
name: entry.name as string,
|
||||||
label: entry.label as string,
|
label: entry.label as string,
|
||||||
baseUrl: entry.baseUrl as string,
|
baseUrl: entry.baseUrl as string,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
cached = result;
|
cached = result;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,8 +13,6 @@ import type { CmdSetupSuccess, SetupCliArgs } from "./types.js";
|
|||||||
|
|
||||||
const setupLog = createLogger({ sink: { kind: "stderr" } });
|
const setupLog = createLogger({ sink: { kind: "stderr" } });
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function mergeWorkflowConfig(
|
function mergeWorkflowConfig(
|
||||||
prev: WorkflowConfig | null,
|
prev: WorkflowConfig | null,
|
||||||
input: SetupCliArgs,
|
input: SetupCliArgs,
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
{
|
{
|
||||||
"name": "@uncaged/workflow-agent-cursor",
|
"name": "@uncaged/workflow-agent-cursor",
|
||||||
"version": "0.3.16",
|
"version": "0.3.16",
|
||||||
"files": ["dist", "package.json"],
|
"files": [
|
||||||
|
"dist",
|
||||||
|
"package.json"
|
||||||
|
],
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "src/index.ts",
|
"main": "src/index.ts",
|
||||||
"types": "src/index.ts",
|
"types": "src/index.ts",
|
||||||
@@ -16,4 +19,4 @@
|
|||||||
"@uncaged/workflow-util-agent": "workspace:*",
|
"@uncaged/workflow-util-agent": "workspace:*",
|
||||||
"zod": "^4.0.0"
|
"zod": "^4.0.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
{
|
{
|
||||||
"name": "@uncaged/workflow-agent-hermes",
|
"name": "@uncaged/workflow-agent-hermes",
|
||||||
"version": "0.3.16",
|
"version": "0.3.16",
|
||||||
"files": ["dist", "package.json"],
|
"files": [
|
||||||
|
"dist",
|
||||||
|
"package.json"
|
||||||
|
],
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "src/index.ts",
|
"main": "src/index.ts",
|
||||||
"types": "src/index.ts",
|
"types": "src/index.ts",
|
||||||
@@ -12,4 +15,4 @@
|
|||||||
"@uncaged/workflow-runtime": "workspace:*",
|
"@uncaged/workflow-runtime": "workspace:*",
|
||||||
"@uncaged/workflow-util-agent": "workspace:*"
|
"@uncaged/workflow-util-agent": "workspace:*"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
{
|
{
|
||||||
"name": "@uncaged/workflow-agent-llm",
|
"name": "@uncaged/workflow-agent-llm",
|
||||||
"version": "0.3.16",
|
"version": "0.3.16",
|
||||||
"files": ["dist", "package.json"],
|
"files": [
|
||||||
|
"dist",
|
||||||
|
"package.json"
|
||||||
|
],
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "src/index.ts",
|
"main": "src/index.ts",
|
||||||
"types": "src/index.ts",
|
"types": "src/index.ts",
|
||||||
@@ -11,4 +14,4 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@uncaged/workflow-runtime": "workspace:*"
|
"@uncaged/workflow-runtime": "workspace:*"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { describe, expect, test } from "bun:test";
|
import { describe, expect, test } from "bun:test";
|
||||||
|
import { ok, START, type ThreadContext, type WorkflowRuntime } from "@uncaged/workflow-protocol";
|
||||||
import type { LlmFn, ToolDefinition } from "@uncaged/workflow-reactor";
|
import type { LlmFn, ToolDefinition } from "@uncaged/workflow-reactor";
|
||||||
import { ok } from "@uncaged/workflow-protocol";
|
|
||||||
import { START, type ThreadContext, type WorkflowRuntime } from "@uncaged/workflow-protocol";
|
|
||||||
import * as z from "zod/v4";
|
import * as z from "zod/v4";
|
||||||
|
|
||||||
import { createReactAdapter } from "../src/create-react-adapter.js";
|
import { createReactAdapter } from "../src/create-react-adapter.js";
|
||||||
@@ -39,10 +38,12 @@ const STUB_RUNTIME: WorkflowRuntime = {
|
|||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
|
||||||
const TEST_SCHEMA = z.object({
|
const TEST_SCHEMA = z
|
||||||
summary: z.string(),
|
.object({
|
||||||
score: z.number(),
|
summary: z.string(),
|
||||||
}).meta({ title: "resolve", description: "Submit the final result." });
|
score: z.number(),
|
||||||
|
})
|
||||||
|
.meta({ title: "resolve", description: "Submit the final result." });
|
||||||
|
|
||||||
function makeChatResponse(content: string | null, toolCalls: unknown[] | null): string {
|
function makeChatResponse(content: string | null, toolCalls: unknown[] | null): string {
|
||||||
const message: Record<string, unknown> = { role: "assistant" };
|
const message: Record<string, unknown> = { role: "assistant" };
|
||||||
@@ -156,7 +157,9 @@ describe("createReactAdapter", () => {
|
|||||||
callCount += 1;
|
callCount += 1;
|
||||||
if (callCount === 1) {
|
if (callCount === 1) {
|
||||||
// Invalid: score should be number, not string
|
// Invalid: score should be number, not string
|
||||||
return ok(makeToolCallResponse("resolve", { summary: "bad", score: "not-a-number" }, "call_1"));
|
return ok(
|
||||||
|
makeToolCallResponse("resolve", { summary: "bad", score: "not-a-number" }, "call_1"),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return ok(makeToolCallResponse("resolve", { summary: "fixed", score: 10 }, "call_2"));
|
return ok(makeToolCallResponse("resolve", { summary: "fixed", score: 10 }, "call_2"));
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { describe, test, expect, afterAll } from "bun:test";
|
import { afterAll, describe, expect, test } from "bun:test";
|
||||||
import { readFileTool, writeFileTool, patchFileTool, shellExecTool } from "../src/tools/index.js";
|
|
||||||
import { join } from "node:path";
|
|
||||||
import { tmpdir } from "node:os";
|
|
||||||
import { readFileSync, unlinkSync, mkdirSync } from "node:fs";
|
|
||||||
import { randomBytes } from "node:crypto";
|
import { randomBytes } from "node:crypto";
|
||||||
|
import { mkdirSync, readFileSync, unlinkSync } from "node:fs";
|
||||||
|
import { tmpdir } from "node:os";
|
||||||
|
import { join } from "node:path";
|
||||||
|
import { patchFileTool, readFileTool, shellExecTool, writeFileTool } from "../src/tools/index.js";
|
||||||
|
|
||||||
const TMP_DIR = join(tmpdir(), `tools-test-${randomBytes(4).toString("hex")}`);
|
const TMP_DIR = join(tmpdir(), `tools-test-${randomBytes(4).toString("hex")}`);
|
||||||
mkdirSync(TMP_DIR, { recursive: true });
|
mkdirSync(TMP_DIR, { recursive: true });
|
||||||
@@ -14,9 +14,17 @@ const cleanupFiles: string[] = [];
|
|||||||
|
|
||||||
afterAll(() => {
|
afterAll(() => {
|
||||||
for (const f of cleanupFiles) {
|
for (const f of cleanupFiles) {
|
||||||
try { unlinkSync(f); } catch { /* ignore */ }
|
try {
|
||||||
|
unlinkSync(f);
|
||||||
|
} catch {
|
||||||
|
/* ignore */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
unlinkSync(TMP_DIR);
|
||||||
|
} catch {
|
||||||
|
/* ignore */
|
||||||
}
|
}
|
||||||
try { unlinkSync(TMP_DIR); } catch { /* ignore */ }
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("read_file", () => {
|
describe("read_file", () => {
|
||||||
@@ -26,7 +34,9 @@ describe("read_file", () => {
|
|||||||
const content = "line1\nline2\nline3\n";
|
const content = "line1\nline2\nline3\n";
|
||||||
require("node:fs").writeFileSync(p, content);
|
require("node:fs").writeFileSync(p, content);
|
||||||
|
|
||||||
const result = await readFileTool.handler(JSON.stringify({ path: p, offset: null, limit: null }));
|
const result = await readFileTool.handler(
|
||||||
|
JSON.stringify({ path: p, offset: null, limit: null }),
|
||||||
|
);
|
||||||
expect(result).toContain("1|line1");
|
expect(result).toContain("1|line1");
|
||||||
expect(result).toContain("2|line2");
|
expect(result).toContain("2|line2");
|
||||||
expect(result).toContain("3|line3");
|
expect(result).toContain("3|line3");
|
||||||
@@ -42,7 +52,9 @@ describe("read_file", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("returns error for missing file", async () => {
|
test("returns error for missing file", async () => {
|
||||||
const result = await readFileTool.handler(JSON.stringify({ path: "/nonexistent/file.txt", offset: null, limit: null }));
|
const result = await readFileTool.handler(
|
||||||
|
JSON.stringify({ path: "/nonexistent/file.txt", offset: null, limit: null }),
|
||||||
|
);
|
||||||
expect(result).toContain("Error:");
|
expect(result).toContain("Error:");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -64,7 +76,9 @@ describe("patch_file", () => {
|
|||||||
cleanupFiles.push(p);
|
cleanupFiles.push(p);
|
||||||
require("node:fs").writeFileSync(p, "foo bar baz");
|
require("node:fs").writeFileSync(p, "foo bar baz");
|
||||||
|
|
||||||
const result = await patchFileTool.handler(JSON.stringify({ path: p, old_string: "bar", new_string: "qux" }));
|
const result = await patchFileTool.handler(
|
||||||
|
JSON.stringify({ path: p, old_string: "bar", new_string: "qux" }),
|
||||||
|
);
|
||||||
expect(result).toContain("Successfully");
|
expect(result).toContain("Successfully");
|
||||||
expect(readFileSync(p, "utf-8")).toBe("foo qux baz");
|
expect(readFileSync(p, "utf-8")).toBe("foo qux baz");
|
||||||
});
|
});
|
||||||
@@ -74,7 +88,9 @@ describe("patch_file", () => {
|
|||||||
cleanupFiles.push(p);
|
cleanupFiles.push(p);
|
||||||
require("node:fs").writeFileSync(p, "foo");
|
require("node:fs").writeFileSync(p, "foo");
|
||||||
|
|
||||||
const result = await patchFileTool.handler(JSON.stringify({ path: p, old_string: "xyz", new_string: "abc" }));
|
const result = await patchFileTool.handler(
|
||||||
|
JSON.stringify({ path: p, old_string: "xyz", new_string: "abc" }),
|
||||||
|
);
|
||||||
expect(result).toContain("not found");
|
expect(result).toContain("not found");
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -83,14 +99,18 @@ describe("patch_file", () => {
|
|||||||
cleanupFiles.push(p);
|
cleanupFiles.push(p);
|
||||||
require("node:fs").writeFileSync(p, "aaa bbb aaa");
|
require("node:fs").writeFileSync(p, "aaa bbb aaa");
|
||||||
|
|
||||||
const result = await patchFileTool.handler(JSON.stringify({ path: p, old_string: "aaa", new_string: "ccc" }));
|
const result = await patchFileTool.handler(
|
||||||
|
JSON.stringify({ path: p, old_string: "aaa", new_string: "ccc" }),
|
||||||
|
);
|
||||||
expect(result).toContain("not unique");
|
expect(result).toContain("not unique");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("shell_exec", () => {
|
describe("shell_exec", () => {
|
||||||
test("runs echo", async () => {
|
test("runs echo", async () => {
|
||||||
const result = await shellExecTool.handler(JSON.stringify({ command: "echo hello", timeout: null }));
|
const result = await shellExecTool.handler(
|
||||||
|
JSON.stringify({ command: "echo hello", timeout: null }),
|
||||||
|
);
|
||||||
expect(result.trim()).toBe("hello");
|
expect(result.trim()).toBe("hello");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
{
|
{
|
||||||
"name": "@uncaged/workflow-agent-react",
|
"name": "@uncaged/workflow-agent-react",
|
||||||
"version": "0.3.16",
|
"version": "0.3.16",
|
||||||
"files": ["dist", "package.json"],
|
"files": [
|
||||||
|
"dist",
|
||||||
|
"package.json"
|
||||||
|
],
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "src/index.ts",
|
"main": "src/index.ts",
|
||||||
"types": "src/index.ts",
|
"types": "src/index.ts",
|
||||||
@@ -25,4 +28,4 @@
|
|||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"zod": "^4.0.0"
|
"zod": "^4.0.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
export { createReactAdapter } from "./create-react-adapter.js";
|
export { createReactAdapter } from "./create-react-adapter.js";
|
||||||
export type { ReactAdapterConfig, ReactToolHandler } from "./types.js";
|
|
||||||
export { defaultTools, defaultToolHandler } from "./tools/index.js";
|
|
||||||
export type { ToolEntry, ToolHandler } from "./tools/index.js";
|
export type { ToolEntry, ToolHandler } from "./tools/index.js";
|
||||||
|
export { defaultToolHandler, defaultTools } from "./tools/index.js";
|
||||||
|
export type { ReactAdapterConfig, ReactToolHandler } from "./types.js";
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import type { ToolDefinition } from "@uncaged/workflow-reactor";
|
import type { ToolDefinition } from "@uncaged/workflow-reactor";
|
||||||
import type { ToolEntry } from "./types.js";
|
|
||||||
import { readFileTool } from "./read-file.js";
|
|
||||||
import { writeFileTool } from "./write-file.js";
|
|
||||||
import { patchFileTool } from "./patch-file.js";
|
import { patchFileTool } from "./patch-file.js";
|
||||||
|
import { readFileTool } from "./read-file.js";
|
||||||
import { shellExecTool } from "./shell-exec.js";
|
import { shellExecTool } from "./shell-exec.js";
|
||||||
|
import type { ToolEntry } from "./types.js";
|
||||||
|
import { writeFileTool } from "./write-file.js";
|
||||||
|
|
||||||
const ALL_TOOLS: ToolEntry[] = [readFileTool, writeFileTool, patchFileTool, shellExecTool];
|
const ALL_TOOLS: ToolEntry[] = [readFileTool, writeFileTool, patchFileTool, shellExecTool];
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
export { readFileTool } from "./read-file.js";
|
export { defaultToolHandler, defaultTools } from "./defaults.js";
|
||||||
export { writeFileTool } from "./write-file.js";
|
|
||||||
export { patchFileTool } from "./patch-file.js";
|
export { patchFileTool } from "./patch-file.js";
|
||||||
|
export { readFileTool } from "./read-file.js";
|
||||||
export { shellExecTool } from "./shell-exec.js";
|
export { shellExecTool } from "./shell-exec.js";
|
||||||
export { defaultTools, defaultToolHandler } from "./defaults.js";
|
|
||||||
export type { ToolEntry, ToolHandler } from "./types.js";
|
export type { ToolEntry, ToolHandler } from "./types.js";
|
||||||
|
export { writeFileTool } from "./write-file.js";
|
||||||
|
|||||||
@@ -30,7 +30,10 @@ export const patchFileTool: ToolEntry = {
|
|||||||
if (secondIdx !== -1) {
|
if (secondIdx !== -1) {
|
||||||
return `Error: old_string is not unique in ${parsed.path} (found multiple occurrences)`;
|
return `Error: old_string is not unique in ${parsed.path} (found multiple occurrences)`;
|
||||||
}
|
}
|
||||||
const updated = content.slice(0, firstIdx) + parsed.new_string + content.slice(firstIdx + parsed.old_string.length);
|
const updated =
|
||||||
|
content.slice(0, firstIdx) +
|
||||||
|
parsed.new_string +
|
||||||
|
content.slice(firstIdx + parsed.old_string.length);
|
||||||
await writeFile(parsed.path, updated);
|
await writeFile(parsed.path, updated);
|
||||||
return `Successfully patched ${parsed.path}`;
|
return `Successfully patched ${parsed.path}`;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|||||||
@@ -11,7 +11,10 @@ export const readFileTool: ToolEntry = {
|
|||||||
type: "object",
|
type: "object",
|
||||||
properties: {
|
properties: {
|
||||||
path: { type: "string", description: "Path to the file to read" },
|
path: { type: "string", description: "Path to the file to read" },
|
||||||
offset: { type: ["number", "null"], description: "Start line number (1-indexed, default: 1)" },
|
offset: {
|
||||||
|
type: ["number", "null"],
|
||||||
|
description: "Start line number (1-indexed, default: 1)",
|
||||||
|
},
|
||||||
limit: { type: ["number", "null"], description: "Max lines to read (default: all)" },
|
limit: { type: ["number", "null"], description: "Max lines to read (default: all)" },
|
||||||
},
|
},
|
||||||
required: ["path"],
|
required: ["path"],
|
||||||
@@ -20,12 +23,17 @@ export const readFileTool: ToolEntry = {
|
|||||||
},
|
},
|
||||||
handler: async (args: string): Promise<string> => {
|
handler: async (args: string): Promise<string> => {
|
||||||
try {
|
try {
|
||||||
const parsed = JSON.parse(args) as { path: string; offset: number | null; limit: number | null };
|
const parsed = JSON.parse(args) as {
|
||||||
|
path: string;
|
||||||
|
offset: number | null;
|
||||||
|
limit: number | null;
|
||||||
|
};
|
||||||
const content = await readFile(parsed.path, "utf-8");
|
const content = await readFile(parsed.path, "utf-8");
|
||||||
const allLines = content.split("\n");
|
const allLines = content.split("\n");
|
||||||
const offset = parsed.offset ?? 1;
|
const offset = parsed.offset ?? 1;
|
||||||
const start = Math.max(0, offset - 1);
|
const start = Math.max(0, offset - 1);
|
||||||
const end = parsed.limit != null ? Math.min(allLines.length, start + parsed.limit) : allLines.length;
|
const end =
|
||||||
|
parsed.limit != null ? Math.min(allLines.length, start + parsed.limit) : allLines.length;
|
||||||
const lines = allLines.slice(start, end);
|
const lines = allLines.slice(start, end);
|
||||||
return lines.map((line, i) => `${start + i + 1}|${line}`).join("\n");
|
return lines.map((line, i) => `${start + i + 1}|${line}`).join("\n");
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|||||||
@@ -31,13 +31,20 @@ export const shellExecTool: ToolEntry = {
|
|||||||
});
|
});
|
||||||
return output.length > MAX_OUTPUT ? `${output.slice(0, MAX_OUTPUT)}\n...(truncated)` : output;
|
return output.length > MAX_OUTPUT ? `${output.slice(0, MAX_OUTPUT)}\n...(truncated)` : output;
|
||||||
} catch (err: unknown) {
|
} catch (err: unknown) {
|
||||||
if (err && typeof err === "object" && "status" in err && (err as { status: unknown }).status === null) {
|
if (
|
||||||
|
err &&
|
||||||
|
typeof err === "object" &&
|
||||||
|
"status" in err &&
|
||||||
|
(err as { status: unknown }).status === null
|
||||||
|
) {
|
||||||
return "Error: command timed out";
|
return "Error: command timed out";
|
||||||
}
|
}
|
||||||
if (err && typeof err === "object" && "stderr" in err) {
|
if (err && typeof err === "object" && "stderr" in err) {
|
||||||
const e = err as { stderr: string; stdout: string; status: number };
|
const e = err as { stderr: string; stdout: string; status: number };
|
||||||
const combined = `${e.stdout ?? ""}${e.stderr ?? ""}`;
|
const combined = `${e.stdout ?? ""}${e.stderr ?? ""}`;
|
||||||
return combined.length > MAX_OUTPUT ? `${combined.slice(0, MAX_OUTPUT)}\n...(truncated)` : combined || `Error: command exited with status ${e.status}`;
|
return combined.length > MAX_OUTPUT
|
||||||
|
? `${combined.slice(0, MAX_OUTPUT)}\n...(truncated)`
|
||||||
|
: combined || `Error: command exited with status ${e.status}`;
|
||||||
}
|
}
|
||||||
return `Error: ${err instanceof Error ? err.message : String(err)}`;
|
return `Error: ${err instanceof Error ? err.message : String(err)}`;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
{
|
{
|
||||||
"name": "@uncaged/workflow-cas",
|
"name": "@uncaged/workflow-cas",
|
||||||
"version": "0.3.16",
|
"version": "0.3.16",
|
||||||
"files": ["dist", "package.json"],
|
"files": [
|
||||||
|
"dist",
|
||||||
|
"package.json"
|
||||||
|
],
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "bun test"
|
"test": "bun test"
|
||||||
@@ -21,4 +24,4 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/bun": "latest"
|
"@types/bun": "latest"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
{
|
{
|
||||||
"name": "@uncaged/workflow-dashboard",
|
"name": "@uncaged/workflow-dashboard",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"files": ["dist", "package.json"],
|
"files": [
|
||||||
|
"dist",
|
||||||
|
"package.json"
|
||||||
|
],
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@@ -26,4 +29,4 @@
|
|||||||
"typescript": "^6.0.3",
|
"typescript": "^6.0.3",
|
||||||
"vite": "^8.0.11"
|
"vite": "^8.0.11"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,7 +70,6 @@ export function LoginPage({ onLogin }: Props) {
|
|||||||
borderColor: "var(--color-border)",
|
borderColor: "var(--color-border)",
|
||||||
color: "var(--color-text)",
|
color: "var(--color-text)",
|
||||||
}}
|
}}
|
||||||
autoFocus
|
|
||||||
/>
|
/>
|
||||||
{error && (
|
{error && (
|
||||||
<p className="text-xs mb-3" style={{ color: "var(--color-error)" }}>
|
<p className="text-xs mb-3" style={{ color: "var(--color-error)" }}>
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import type {
|
|||||||
} from "@uncaged/workflow-runtime";
|
} from "@uncaged/workflow-runtime";
|
||||||
|
|
||||||
import { executeThread } from "../src/engine/engine.js";
|
import { executeThread } from "../src/engine/engine.js";
|
||||||
import type { ExecuteThreadIo, ExecuteThreadOptions } from "../src/engine/types.js";
|
import type { ExecuteThreadOptions } from "../src/engine/types.js";
|
||||||
|
|
||||||
const TEST_REGISTRY_YAML = `config:
|
const TEST_REGISTRY_YAML = `config:
|
||||||
maxDepth: 3
|
maxDepth: 3
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
{
|
{
|
||||||
"name": "@uncaged/workflow-execute",
|
"name": "@uncaged/workflow-execute",
|
||||||
"version": "0.3.16",
|
"version": "0.3.16",
|
||||||
"files": ["dist", "package.json"],
|
"files": [
|
||||||
|
"dist",
|
||||||
|
"package.json"
|
||||||
|
],
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"exports": {
|
"exports": {
|
||||||
".": {
|
".": {
|
||||||
@@ -27,4 +30,4 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"zod": "^4.0.0"
|
"zod": "^4.0.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,17 +59,26 @@ export function workflowAsAgent(
|
|||||||
|
|
||||||
const registryResult = await readWorkflowRegistry(storageRoot);
|
const registryResult = await readWorkflowRegistry(storageRoot);
|
||||||
if (!registryResult.ok) {
|
if (!registryResult.ok) {
|
||||||
return { output: `ERROR: failed to read workflow registry: ${registryResult.error.message}`, childThread: null };
|
return {
|
||||||
|
output: `ERROR: failed to read workflow registry: ${registryResult.error.message}`,
|
||||||
|
childThread: null,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const maxDepth = workflowAsAgentMaxDepth(registryResult.value.config);
|
const maxDepth = workflowAsAgentMaxDepth(registryResult.value.config);
|
||||||
if (nextDepth > maxDepth) {
|
if (nextDepth > maxDepth) {
|
||||||
return { output: `ERROR: workflow-as-agent depth limit exceeded (max ${maxDepth})`, childThread: null };
|
return {
|
||||||
|
output: `ERROR: workflow-as-agent depth limit exceeded (max ${maxDepth})`,
|
||||||
|
childThread: null,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const entry = getRegisteredWorkflow(registryResult.value, workflowName);
|
const entry = getRegisteredWorkflow(registryResult.value, workflowName);
|
||||||
if (entry === null) {
|
if (entry === null) {
|
||||||
return { output: `ERROR: workflow "${workflowName}" not found in registry`, childThread: null };
|
return {
|
||||||
|
output: `ERROR: workflow "${workflowName}" not found in registry`,
|
||||||
|
childThread: null,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const bundlePath = join(storageRoot, "bundles", `${entry.hash}.esm.js`);
|
const bundlePath = join(storageRoot, "bundles", `${entry.hash}.esm.js`);
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
{
|
{
|
||||||
"name": "@uncaged/workflow-gateway",
|
"name": "@uncaged/workflow-gateway",
|
||||||
"version": "0.3.16",
|
"version": "0.3.16",
|
||||||
"files": ["dist", "package.json"],
|
"files": [
|
||||||
|
"dist",
|
||||||
|
"package.json"
|
||||||
|
],
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"exports": {
|
"exports": {
|
||||||
".": "./src/index.ts",
|
".": "./src/index.ts",
|
||||||
@@ -18,4 +21,4 @@
|
|||||||
"@cloudflare/workers-types": "^4.20260425.1",
|
"@cloudflare/workers-types": "^4.20260425.1",
|
||||||
"wrangler": "^4.20.0"
|
"wrangler": "^4.20.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
{
|
{
|
||||||
"name": "@uncaged/workflow-protocol",
|
"name": "@uncaged/workflow-protocol",
|
||||||
"version": "0.3.16",
|
"version": "0.3.16",
|
||||||
"files": ["dist", "package.json"],
|
"files": [
|
||||||
|
"dist",
|
||||||
|
"package.json"
|
||||||
|
],
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"exports": {
|
"exports": {
|
||||||
".": {
|
".": {
|
||||||
@@ -20,4 +23,4 @@
|
|||||||
"zod": "^4.0.0",
|
"zod": "^4.0.0",
|
||||||
"typescript": "^5.8.3"
|
"typescript": "^5.8.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,9 +30,9 @@ export type {
|
|||||||
Result,
|
Result,
|
||||||
RoleDefinition,
|
RoleDefinition,
|
||||||
RoleFn,
|
RoleFn,
|
||||||
RoleResult,
|
|
||||||
RoleMeta,
|
RoleMeta,
|
||||||
RoleOutput,
|
RoleOutput,
|
||||||
|
RoleResult,
|
||||||
RoleStep,
|
RoleStep,
|
||||||
StartStep,
|
StartStep,
|
||||||
ThreadContext,
|
ThreadContext,
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
{
|
{
|
||||||
"name": "@uncaged/workflow-reactor",
|
"name": "@uncaged/workflow-reactor",
|
||||||
"version": "0.3.16",
|
"version": "0.3.16",
|
||||||
"files": ["dist", "package.json"],
|
"files": [
|
||||||
|
"dist",
|
||||||
|
"package.json"
|
||||||
|
],
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"exports": {
|
"exports": {
|
||||||
".": {
|
".": {
|
||||||
@@ -19,4 +22,4 @@
|
|||||||
"zod": "^4.0.0",
|
"zod": "^4.0.0",
|
||||||
"typescript": "^5.8.3"
|
"typescript": "^5.8.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
{
|
{
|
||||||
"name": "@uncaged/workflow-register",
|
"name": "@uncaged/workflow-register",
|
||||||
"version": "0.3.16",
|
"version": "0.3.16",
|
||||||
"files": ["dist", "package.json"],
|
"files": [
|
||||||
|
"dist",
|
||||||
|
"package.json"
|
||||||
|
],
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"exports": {
|
"exports": {
|
||||||
".": {
|
".": {
|
||||||
@@ -24,4 +27,4 @@
|
|||||||
"zod": "^4.0.0",
|
"zod": "^4.0.0",
|
||||||
"typescript": "^5.8.3"
|
"typescript": "^5.8.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
{
|
{
|
||||||
"name": "@uncaged/workflow-runtime",
|
"name": "@uncaged/workflow-runtime",
|
||||||
"version": "0.3.16",
|
"version": "0.3.16",
|
||||||
"files": ["dist", "package.json"],
|
"files": [
|
||||||
|
"dist",
|
||||||
|
"package.json"
|
||||||
|
],
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "src/index.ts",
|
"main": "src/index.ts",
|
||||||
"types": "src/index.ts",
|
"types": "src/index.ts",
|
||||||
@@ -18,4 +21,4 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"zod": "^4.0.0"
|
"zod": "^4.0.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ function resolveExtractedRefs(
|
|||||||
return extractRefsFn(meta as Record<string, unknown>);
|
return extractRefsFn(meta as Record<string, unknown>);
|
||||||
}
|
}
|
||||||
|
|
||||||
function mergeUniqueHashes(a: readonly string[], b: readonly string[]): string[] {
|
function _mergeUniqueHashes(a: readonly string[], b: readonly string[]): string[] {
|
||||||
const seen = new Set<string>();
|
const seen = new Set<string>();
|
||||||
const out: string[] = [];
|
const out: string[] = [];
|
||||||
for (const h of [...a, ...b]) {
|
for (const h of [...a, ...b]) {
|
||||||
@@ -83,7 +83,10 @@ async function advanceOneRound<M extends RoleMeta>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const adapter = adapterForRole(binding, next);
|
const adapter = adapterForRole(binding, next);
|
||||||
const roleFn = adapter(roleDef.systemPrompt, roleDef.schema as z.ZodType<Record<string, unknown>>);
|
const roleFn = adapter(
|
||||||
|
roleDef.systemPrompt,
|
||||||
|
roleDef.schema as z.ZodType<Record<string, unknown>>,
|
||||||
|
);
|
||||||
const result = await roleFn(modCtx as unknown as ThreadContext, runtime);
|
const result = await roleFn(modCtx as unknown as ThreadContext, runtime);
|
||||||
const meta = result.meta;
|
const meta = result.meta;
|
||||||
|
|
||||||
|
|||||||
@@ -20,9 +20,9 @@ export type {
|
|||||||
Result,
|
Result,
|
||||||
RoleDefinition,
|
RoleDefinition,
|
||||||
RoleFn,
|
RoleFn,
|
||||||
RoleResult,
|
|
||||||
RoleMeta,
|
RoleMeta,
|
||||||
RoleOutput,
|
RoleOutput,
|
||||||
|
RoleResult,
|
||||||
RoleStep,
|
RoleStep,
|
||||||
StartStep,
|
StartStep,
|
||||||
ThreadContext,
|
ThreadContext,
|
||||||
|
|||||||
@@ -24,9 +24,9 @@ export type {
|
|||||||
Result,
|
Result,
|
||||||
RoleDefinition,
|
RoleDefinition,
|
||||||
RoleFn,
|
RoleFn,
|
||||||
RoleResult,
|
|
||||||
RoleMeta,
|
RoleMeta,
|
||||||
RoleOutput,
|
RoleOutput,
|
||||||
|
RoleResult,
|
||||||
RoleStep,
|
RoleStep,
|
||||||
StartStep,
|
StartStep,
|
||||||
ThreadContext,
|
ThreadContext,
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
{
|
{
|
||||||
"name": "@uncaged/workflow-template-develop",
|
"name": "@uncaged/workflow-template-develop",
|
||||||
"version": "0.3.16",
|
"version": "0.3.16",
|
||||||
"files": ["dist", "package.json"],
|
"files": [
|
||||||
|
"dist",
|
||||||
|
"package.json"
|
||||||
|
],
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"exports": {
|
"exports": {
|
||||||
".": {
|
".": {
|
||||||
@@ -20,4 +23,4 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@uncaged/workflow-protocol": "workspace:*"
|
"@uncaged/workflow-protocol": "workspace:*"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -215,10 +215,7 @@ describe("solveIssueWorkflowDefinition + createWorkflow", () => {
|
|||||||
});
|
});
|
||||||
const gen = run(makeThread("task"), {
|
const gen = run(makeThread("task"), {
|
||||||
cas,
|
cas,
|
||||||
extract: createExtract(
|
extract: createExtract({ baseUrl: "http://127.0.0.1:9", apiKey: "", model: "test" }, { cas }),
|
||||||
{ baseUrl: "http://127.0.0.1:9", apiKey: "", model: "test" },
|
|
||||||
{ cas },
|
|
||||||
),
|
|
||||||
});
|
});
|
||||||
const first = await gen.next();
|
const first = await gen.next();
|
||||||
expect(first.done).toBe(false);
|
expect(first.done).toBe(false);
|
||||||
@@ -261,10 +258,7 @@ describe("solveIssueWorkflowDefinition + createWorkflow", () => {
|
|||||||
});
|
});
|
||||||
const gen = run(makeThread("task"), {
|
const gen = run(makeThread("task"), {
|
||||||
cas,
|
cas,
|
||||||
extract: createExtract(
|
extract: createExtract({ baseUrl: "http://127.0.0.1:9", apiKey: "", model: "test" }, { cas }),
|
||||||
{ baseUrl: "http://127.0.0.1:9", apiKey: "", model: "test" },
|
|
||||||
{ cas },
|
|
||||||
),
|
|
||||||
});
|
});
|
||||||
await gen.next();
|
await gen.next();
|
||||||
expect(calls).toEqual(["preparer"]);
|
expect(calls).toEqual(["preparer"]);
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
{
|
{
|
||||||
"name": "@uncaged/workflow-template-solve-issue",
|
"name": "@uncaged/workflow-template-solve-issue",
|
||||||
"version": "0.3.16",
|
"version": "0.3.16",
|
||||||
"files": ["dist", "package.json"],
|
"files": [
|
||||||
|
"dist",
|
||||||
|
"package.json"
|
||||||
|
],
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"exports": {
|
"exports": {
|
||||||
".": {
|
".": {
|
||||||
@@ -22,4 +25,4 @@
|
|||||||
"@uncaged/workflow-execute": "workspace:*",
|
"@uncaged/workflow-execute": "workspace:*",
|
||||||
"@uncaged/workflow-protocol": "workspace:*"
|
"@uncaged/workflow-protocol": "workspace:*"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
{
|
{
|
||||||
"name": "@uncaged/workflow-util-agent",
|
"name": "@uncaged/workflow-util-agent",
|
||||||
"version": "0.3.16",
|
"version": "0.3.16",
|
||||||
"files": ["dist", "package.json"],
|
"files": [
|
||||||
|
"dist",
|
||||||
|
"package.json"
|
||||||
|
],
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "src/index.ts",
|
"main": "src/index.ts",
|
||||||
"types": "src/index.ts",
|
"types": "src/index.ts",
|
||||||
@@ -19,4 +22,4 @@
|
|||||||
"@uncaged/workflow-cas": "workspace:*",
|
"@uncaged/workflow-cas": "workspace:*",
|
||||||
"zod": "^4.0.0"
|
"zod": "^4.0.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
{
|
{
|
||||||
"name": "@uncaged/workflow-util",
|
"name": "@uncaged/workflow-util",
|
||||||
"version": "0.3.16",
|
"version": "0.3.16",
|
||||||
"files": ["dist", "package.json"],
|
"files": [
|
||||||
|
"dist",
|
||||||
|
"package.json"
|
||||||
|
],
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"exports": {
|
"exports": {
|
||||||
".": {
|
".": {
|
||||||
@@ -15,4 +18,4 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"typescript": "^5.8.3"
|
"typescript": "^5.8.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user