agent-worker 0.14.0 → 0.15.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/README.md +6 -3
- package/dist/{backends-Cv0oM9Ru.mjs → backends-BYWmuyF9.mjs} +1 -1
- package/dist/{backends-C6WBIn9H.mjs → backends-C7pQwuAx.mjs} +265 -227
- package/dist/cli/index.mjs +648 -393
- package/dist/context-CdcZpO-0.mjs +4 -0
- package/dist/create-tool-gcUuI1FD.mjs +32 -0
- package/dist/index.d.mts +4 -33
- package/dist/index.mjs +21 -20
- package/dist/{memory-provider-0nuDxzYQ.mjs → memory-provider-ZLOKyCxA.mjs} +8 -3
- package/dist/{runner-DV86expc.mjs → runner-DB-b57iZ.mjs} +53 -46
- package/dist/workflow-DQ6Eju4n.mjs +664 -0
- package/package.json +3 -3
- package/dist/context-CzqQeThq.mjs +0 -4
- package/dist/workflow-DogkVjOs.mjs +0 -301
- /package/dist/{display-pretty-BCJq5v9d.mjs → display-pretty-Kyd40DEF.mjs} +0 -0
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { A as MENTION_PATTERN, B as formatProposal, C as DefaultDocumentStore, D as MemoryStorage, E as FileStorage, F as createResourceRef, G as getAgentId, H as createLogTool, I as extractMentions, K as EventLog, L as generateResourceId, M as RESOURCE_PREFIX, N as RESOURCE_SCHEME, O as ContextProviderImpl, P as calculatePriority, R as shouldUseResource, S as DefaultResourceStore, T as DefaultChannelStore, U as formatInbox, V as formatProposalList, W as formatToolParams, _ as FileContextProvider, b as resolveContextDir, j as MESSAGE_LENGTH_THRESHOLD, k as CONTEXT_DEFAULTS, v as createFileContextProvider, w as DefaultInboxStore, x as DefaultStatusStore, y as getDefaultContextDir, z as createContextMCPServer } from "./cli/index.mjs";
|
|
2
|
+
import { n as createMemoryContextProvider, t as MemoryContextProvider } from "./memory-provider-ZLOKyCxA.mjs";
|
|
3
|
+
|
|
4
|
+
export { createFileContextProvider };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { jsonSchema, tool } from "ai";
|
|
2
|
+
|
|
3
|
+
//#region src/agent/tools/create-tool.ts
|
|
4
|
+
/**
|
|
5
|
+
* Type-safe wrapper for AI SDK tool() with JSON Schema.
|
|
6
|
+
*
|
|
7
|
+
* The AI SDK's tool() function has complex generic types that don't align
|
|
8
|
+
* with jsonSchema() return types. This utility absorbs the necessary casts
|
|
9
|
+
* in one place instead of scattering `as unknown` across every tool file.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Create an AI SDK tool with a plain JSON Schema object.
|
|
13
|
+
*
|
|
14
|
+
* Usage:
|
|
15
|
+
* ```ts
|
|
16
|
+
* const myTool = createTool({
|
|
17
|
+
* description: "Do something",
|
|
18
|
+
* schema: { type: "object", properties: { name: { type: "string" } }, required: ["name"] },
|
|
19
|
+
* execute: async (args) => { ... },
|
|
20
|
+
* });
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
function createTool(config) {
|
|
24
|
+
return tool({
|
|
25
|
+
description: config.description,
|
|
26
|
+
inputSchema: jsonSchema(config.schema),
|
|
27
|
+
execute: config.execute
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
//#endregion
|
|
32
|
+
export { createTool as t };
|
package/dist/index.d.mts
CHANGED
|
@@ -6,7 +6,7 @@ import { BashToolkit, CreateBashToolOptions, createBashTool } from "bash-tool";
|
|
|
6
6
|
* Model Translation Maps — Single Source of Truth
|
|
7
7
|
*
|
|
8
8
|
* All backend-specific model naming and translation logic lives here.
|
|
9
|
-
* Both `backends/types.ts` and `workflow/
|
|
9
|
+
* Both `backends/types.ts` and `workflow/loop/types.ts` re-export from this module.
|
|
10
10
|
*/
|
|
11
11
|
/** Backend type (union of all supported backends) */
|
|
12
12
|
type BackendType = "default" | "claude" | "cursor" | "codex" | "opencode" | "mock";
|
|
@@ -48,10 +48,6 @@ interface Backend {
|
|
|
48
48
|
version?: string;
|
|
49
49
|
model?: string;
|
|
50
50
|
};
|
|
51
|
-
/** Set up workspace directory with MCP config for workflow isolation */
|
|
52
|
-
setWorkspace?(workspaceDir: string, mcpConfig: {
|
|
53
|
-
mcpServers: Record<string, unknown>;
|
|
54
|
-
}): void;
|
|
55
51
|
/** Abort any running operations and cleanup resources */
|
|
56
52
|
abort?(): void;
|
|
57
53
|
}
|
|
@@ -516,13 +512,6 @@ declare class ClaudeCodeBackend implements Backend {
|
|
|
516
512
|
private options;
|
|
517
513
|
private currentAbort?;
|
|
518
514
|
constructor(options?: ClaudeCodeOptions);
|
|
519
|
-
/**
|
|
520
|
-
* Set up workspace directory with MCP config
|
|
521
|
-
* Claude uses --mcp-config flag, so we just write the config file
|
|
522
|
-
*/
|
|
523
|
-
setWorkspace(workspaceDir: string, mcpConfig: {
|
|
524
|
-
mcpServers: Record<string, unknown>;
|
|
525
|
-
}): void;
|
|
526
515
|
send(message: string, options?: {
|
|
527
516
|
system?: string;
|
|
528
517
|
}): Promise<BackendResponse>;
|
|
@@ -533,10 +522,6 @@ declare class ClaudeCodeBackend implements Backend {
|
|
|
533
522
|
model?: string;
|
|
534
523
|
};
|
|
535
524
|
private buildArgs;
|
|
536
|
-
/**
|
|
537
|
-
* Set MCP config path (for workflow integration)
|
|
538
|
-
*/
|
|
539
|
-
setMcpConfigPath(path: string): void;
|
|
540
525
|
/**
|
|
541
526
|
* Abort any running claude process
|
|
542
527
|
*/
|
|
@@ -562,13 +547,6 @@ declare class CodexBackend implements Backend {
|
|
|
562
547
|
readonly type: "codex";
|
|
563
548
|
private options;
|
|
564
549
|
constructor(options?: CodexOptions);
|
|
565
|
-
/**
|
|
566
|
-
* Set up workspace directory with MCP config
|
|
567
|
-
* Creates .codex/config.yaml in the workspace with MCP server config
|
|
568
|
-
*/
|
|
569
|
-
setWorkspace(workspaceDir: string, mcpConfig: {
|
|
570
|
-
mcpServers: Record<string, unknown>;
|
|
571
|
-
}): void;
|
|
572
550
|
send(message: string, _options?: {
|
|
573
551
|
system?: string;
|
|
574
552
|
}): Promise<BackendResponse>;
|
|
@@ -605,13 +583,6 @@ declare class CursorBackend implements Backend {
|
|
|
605
583
|
*/
|
|
606
584
|
private resolvedStyle;
|
|
607
585
|
constructor(options?: CursorOptions);
|
|
608
|
-
/**
|
|
609
|
-
* Set up workspace directory with MCP config
|
|
610
|
-
* Creates .cursor/mcp.json in the workspace
|
|
611
|
-
*/
|
|
612
|
-
setWorkspace(workspaceDir: string, mcpConfig: {
|
|
613
|
-
mcpServers: Record<string, unknown>;
|
|
614
|
-
}): void;
|
|
615
586
|
send(message: string, _options?: {
|
|
616
587
|
system?: string;
|
|
617
588
|
}): Promise<BackendResponse>;
|
|
@@ -681,8 +652,8 @@ declare class SdkBackend implements Backend {
|
|
|
681
652
|
* Mock AI Backend for testing
|
|
682
653
|
*
|
|
683
654
|
* In single-agent mode, provides a simple echo send().
|
|
684
|
-
* In workflow mode, the
|
|
685
|
-
* via the mock runner strategy (
|
|
655
|
+
* In workflow mode, the loop handles MCP tool orchestration
|
|
656
|
+
* via the mock runner strategy (loop/mock-runner.ts).
|
|
686
657
|
*/
|
|
687
658
|
declare class MockAIBackend implements Backend {
|
|
688
659
|
private debugLog?;
|
|
@@ -914,4 +885,4 @@ declare function buildGitUrl(spec: ImportSpec): string;
|
|
|
914
885
|
*/
|
|
915
886
|
declare function getSpecDisplayName(spec: ImportSpec): string;
|
|
916
887
|
//#endregion
|
|
917
|
-
export { type AgentMessage, type AgentResponse, AgentWorker
|
|
888
|
+
export { type AgentMessage, type AgentResponse, AgentWorker, type AgentWorkerConfig, type ApprovalCheck, type Backend, type BackendConfig, type BackendOptions, type BackendResponse, type BackendType, type BashToolkit, type BashToolsOptions, ClaudeCodeBackend, type ClaudeCodeOptions, CodexBackend, type CodexOptions, type CreateBashToolOptions, CursorBackend, type CursorOptions, FEEDBACK_PROMPT, FRONTIER_MODELS, type FeedbackEntry, type FeedbackToolOptions, type FeedbackToolResult, type GitProvider, type ImportSpec, type ImportedSkill, type MessageStatus, MockAIBackend, type PendingApproval, SUPPORTED_PROVIDERS, SdkBackend, type SdkBackendOptions, type SendOptions, type SessionConfig, type SessionState, SkillImporter, type SkillMetadata, SkillsProvider, type StepInfo, type SupportedProvider, type TokenUsage, type ToolCall, type ToolInfo, type Transcript, buildGitUrl, checkBackends, createBackend, createBashTool, createBashTools, createBashToolsFromDirectory, createBashToolsFromFiles, createFeedbackTool, createMockBackend, createModel, createModelAsync, createSkillsTool, getSpecDisplayName, listBackends, parseImportSpec };
|
package/dist/index.mjs
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { F as createModelWithProvider, M as SUPPORTED_PROVIDERS, N as createModel, P as createModelAsync, a as createMockBackend, d as CodexBackend, f as ClaudeCodeBackend, i as MockAIBackend, j as FRONTIER_MODELS, n as createBackend, o as SdkBackend, r as listBackends, t as checkBackends, u as CursorBackend } from "./backends-
|
|
2
|
-
import {
|
|
1
|
+
import { F as createModelWithProvider, M as SUPPORTED_PROVIDERS, N as createModel, P as createModelAsync, a as createMockBackend, d as CodexBackend, f as ClaudeCodeBackend, i as MockAIBackend, j as FRONTIER_MODELS, n as createBackend, o as SdkBackend, r as listBackends, t as checkBackends, u as CursorBackend } from "./backends-C7pQwuAx.mjs";
|
|
2
|
+
import { t as createTool } from "./create-tool-gcUuI1FD.mjs";
|
|
3
|
+
import { ToolLoopAgent, stepCountIs } from "ai";
|
|
3
4
|
import { createBashTool } from "bash-tool";
|
|
4
5
|
import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
|
|
5
6
|
import { join, normalize } from "node:path";
|
|
6
|
-
import { parse } from "yaml";
|
|
7
7
|
import { mkdir, readFile, readdir, rm, stat } from "node:fs/promises";
|
|
8
|
+
import { parse } from "yaml";
|
|
8
9
|
import { z } from "zod";
|
|
9
10
|
import { tmpdir } from "node:os";
|
|
10
11
|
import { spawn } from "node:child_process";
|
|
@@ -479,41 +480,41 @@ async function createBashTools(options = {}) {
|
|
|
479
480
|
const { includeReadFile = true, includeWriteFile = true, ...bashOptions } = options;
|
|
480
481
|
const toolkit = await createBashTool(bashOptions);
|
|
481
482
|
const tools = {};
|
|
482
|
-
tools.bash =
|
|
483
|
+
tools.bash = createTool({
|
|
483
484
|
description: "Execute bash commands in a sandboxed environment. Returns stdout, stderr, and exit code.",
|
|
484
|
-
|
|
485
|
+
schema: {
|
|
485
486
|
type: "object",
|
|
486
487
|
properties: { command: {
|
|
487
488
|
type: "string",
|
|
488
489
|
description: "The bash command to execute"
|
|
489
490
|
} },
|
|
490
491
|
required: ["command"]
|
|
491
|
-
}
|
|
492
|
+
},
|
|
492
493
|
execute: async (args) => {
|
|
493
494
|
const bashTool = toolkit.tools.bash;
|
|
494
495
|
if (!bashTool?.execute) throw new Error("Bash tool not available");
|
|
495
496
|
return bashTool.execute(args, {});
|
|
496
497
|
}
|
|
497
498
|
});
|
|
498
|
-
if (includeReadFile) tools.readFile =
|
|
499
|
+
if (includeReadFile) tools.readFile = createTool({
|
|
499
500
|
description: "Read the contents of a file from the sandbox filesystem.",
|
|
500
|
-
|
|
501
|
+
schema: {
|
|
501
502
|
type: "object",
|
|
502
503
|
properties: { path: {
|
|
503
504
|
type: "string",
|
|
504
505
|
description: "The path to the file to read"
|
|
505
506
|
} },
|
|
506
507
|
required: ["path"]
|
|
507
|
-
}
|
|
508
|
+
},
|
|
508
509
|
execute: async (args) => {
|
|
509
510
|
const readFileTool = toolkit.tools.readFile;
|
|
510
511
|
if (!readFileTool?.execute) throw new Error("ReadFile tool not available");
|
|
511
512
|
return readFileTool.execute(args, {});
|
|
512
513
|
}
|
|
513
514
|
});
|
|
514
|
-
if (includeWriteFile) tools.writeFile =
|
|
515
|
+
if (includeWriteFile) tools.writeFile = createTool({
|
|
515
516
|
description: "Write content to a file in the sandbox filesystem. Creates parent directories if needed.",
|
|
516
|
-
|
|
517
|
+
schema: {
|
|
517
518
|
type: "object",
|
|
518
519
|
properties: {
|
|
519
520
|
path: {
|
|
@@ -526,7 +527,7 @@ async function createBashTools(options = {}) {
|
|
|
526
527
|
}
|
|
527
528
|
},
|
|
528
529
|
required: ["path", "content"]
|
|
529
|
-
}
|
|
530
|
+
},
|
|
530
531
|
execute: async (args) => {
|
|
531
532
|
const writeFileTool = toolkit.tools.writeFile;
|
|
532
533
|
if (!writeFileTool?.execute) throw new Error("WriteFile tool not available");
|
|
@@ -595,9 +596,9 @@ function createFeedbackTool(options = {}) {
|
|
|
595
596
|
const { onFeedback, maxEntries = 50 } = options;
|
|
596
597
|
const entries = [];
|
|
597
598
|
return {
|
|
598
|
-
tool:
|
|
599
|
+
tool: createTool({
|
|
599
600
|
description: "Report a workflow improvement need. Use when you hit something inconvenient — a missing tool, an awkward step, or a capability you wished you had.",
|
|
600
|
-
|
|
601
|
+
schema: {
|
|
601
602
|
type: "object",
|
|
602
603
|
properties: {
|
|
603
604
|
target: {
|
|
@@ -627,7 +628,7 @@ function createFeedbackTool(options = {}) {
|
|
|
627
628
|
"type",
|
|
628
629
|
"description"
|
|
629
630
|
]
|
|
630
|
-
}
|
|
631
|
+
},
|
|
631
632
|
execute: async (args) => {
|
|
632
633
|
const validTypes = [
|
|
633
634
|
"missing",
|
|
@@ -663,7 +664,7 @@ const frontmatterSchema = z.object({
|
|
|
663
664
|
description: z.string().min(1).max(1024),
|
|
664
665
|
license: z.string().optional(),
|
|
665
666
|
compatibility: z.string().max(500).optional(),
|
|
666
|
-
metadata: z.record(z.string()).optional(),
|
|
667
|
+
metadata: z.record(z.string(), z.string()).optional(),
|
|
667
668
|
"allowed-tools": z.string().optional()
|
|
668
669
|
});
|
|
669
670
|
var SkillsProvider = class {
|
|
@@ -817,9 +818,9 @@ var SkillsProvider = class {
|
|
|
817
818
|
* Create a Skills tool as an AI SDK tool() object
|
|
818
819
|
*/
|
|
819
820
|
function createSkillsTool(provider) {
|
|
820
|
-
return
|
|
821
|
+
return createTool({
|
|
821
822
|
description: "Interact with available agent skills. Use \"list\" to see all skills with their descriptions, \"view\" to read a complete SKILL.md file, \"readFile\" to read files within a skill directory (e.g., references/, scripts/, assets/).",
|
|
822
|
-
|
|
823
|
+
schema: {
|
|
823
824
|
type: "object",
|
|
824
825
|
properties: {
|
|
825
826
|
operation: {
|
|
@@ -841,7 +842,7 @@ function createSkillsTool(provider) {
|
|
|
841
842
|
}
|
|
842
843
|
},
|
|
843
844
|
required: ["operation"]
|
|
844
|
-
}
|
|
845
|
+
},
|
|
845
846
|
execute: async (args) => {
|
|
846
847
|
const operation = args.operation;
|
|
847
848
|
const skillName = args.skillName;
|
|
@@ -1107,4 +1108,4 @@ var SkillImporter = class {
|
|
|
1107
1108
|
};
|
|
1108
1109
|
|
|
1109
1110
|
//#endregion
|
|
1110
|
-
export { AgentWorker
|
|
1111
|
+
export { AgentWorker, ClaudeCodeBackend, CodexBackend, CursorBackend, FEEDBACK_PROMPT, FRONTIER_MODELS, MockAIBackend, SUPPORTED_PROVIDERS, SdkBackend, SkillImporter, SkillsProvider, buildGitUrl, checkBackends, createBackend, createBashTool, createBashTools, createBashToolsFromDirectory, createBashToolsFromFiles, createFeedbackTool, createMockBackend, createModel, createModelAsync, createSkillsTool, getSpecDisplayName, listBackends, parseImportSpec };
|
|
@@ -1,16 +1,21 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { C as DefaultDocumentStore, D as MemoryStorage, O as ContextProviderImpl, S as DefaultResourceStore, T as DefaultChannelStore, w as DefaultInboxStore, x as DefaultStatusStore } from "./cli/index.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/workflow/context/memory-provider.ts
|
|
4
4
|
/**
|
|
5
5
|
* In-memory ContextProvider for testing.
|
|
6
|
-
* All domain logic is
|
|
6
|
+
* All domain logic is in the composed stores;
|
|
7
7
|
* this class adds test helpers for inspection and cleanup.
|
|
8
8
|
*/
|
|
9
9
|
var MemoryContextProvider = class extends ContextProviderImpl {
|
|
10
10
|
memoryStorage;
|
|
11
11
|
constructor(validAgents) {
|
|
12
12
|
const storage = new MemoryStorage();
|
|
13
|
-
|
|
13
|
+
const channel = new DefaultChannelStore(storage, validAgents);
|
|
14
|
+
const inbox = new DefaultInboxStore(channel, storage);
|
|
15
|
+
const documents = new DefaultDocumentStore(storage);
|
|
16
|
+
const resources = new DefaultResourceStore(storage);
|
|
17
|
+
const status = new DefaultStatusStore(storage);
|
|
18
|
+
super(channel, inbox, documents, resources, status, validAgents);
|
|
14
19
|
this.memoryStorage = storage;
|
|
15
20
|
}
|
|
16
21
|
/** Get underlying MemoryStorage (for testing) */
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import "./backends-
|
|
2
|
-
import
|
|
3
|
-
import { n as
|
|
1
|
+
import "./backends-C7pQwuAx.mjs";
|
|
2
|
+
import "./create-tool-gcUuI1FD.mjs";
|
|
3
|
+
import { K as EventLog, _ as FileContextProvider, g as runWithHttp, i as createSilentLogger, n as createWiredLoop, r as createChannelLogger, s as checkWorkflowIdle, v as createFileContextProvider, z as createContextMCPServer } from "./cli/index.mjs";
|
|
4
|
+
import { n as createMemoryContextProvider } from "./memory-provider-ZLOKyCxA.mjs";
|
|
4
5
|
import { existsSync, mkdirSync } from "node:fs";
|
|
5
6
|
import { join } from "node:path";
|
|
6
7
|
import { tmpdir } from "node:os";
|
|
@@ -31,11 +32,18 @@ function resolveExpression(expression, context) {
|
|
|
31
32
|
const varName = expression.slice(4);
|
|
32
33
|
return context.env?.[varName] ?? process.env[varName];
|
|
33
34
|
}
|
|
35
|
+
if (expression.startsWith("params.")) {
|
|
36
|
+
const paramName = expression.slice(7);
|
|
37
|
+
return context.params?.[paramName];
|
|
38
|
+
}
|
|
34
39
|
if (expression.startsWith("workflow.")) {
|
|
35
40
|
const field = expression.slice(9);
|
|
36
41
|
if (field === "name") return context.workflow?.name;
|
|
37
42
|
if (field === "tag") return context.workflow?.tag;
|
|
38
|
-
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
if (expression.startsWith("source.")) {
|
|
46
|
+
if (expression.slice(7) === "dir") return context.source?.dir;
|
|
39
47
|
return;
|
|
40
48
|
}
|
|
41
49
|
const value = context[expression];
|
|
@@ -44,15 +52,16 @@ function resolveExpression(expression, context) {
|
|
|
44
52
|
/**
|
|
45
53
|
* Create a context from workflow metadata
|
|
46
54
|
*/
|
|
47
|
-
function createContext(workflowName, tag, taskOutputs = {}) {
|
|
55
|
+
function createContext(workflowName, tag, taskOutputs = {}, params, sourceDir) {
|
|
48
56
|
return {
|
|
49
57
|
...taskOutputs,
|
|
50
58
|
env: process.env,
|
|
51
59
|
workflow: {
|
|
52
60
|
name: workflowName,
|
|
53
|
-
tag
|
|
54
|
-
|
|
55
|
-
|
|
61
|
+
tag
|
|
62
|
+
},
|
|
63
|
+
params,
|
|
64
|
+
source: sourceDir ? { dir: sourceDir } : void 0
|
|
56
65
|
};
|
|
57
66
|
}
|
|
58
67
|
|
|
@@ -354,8 +363,8 @@ function createWorkflowProvider(workflow, _workflowName, tag) {
|
|
|
354
363
|
* 4. Runs setup commands
|
|
355
364
|
*/
|
|
356
365
|
async function initWorkflow(config) {
|
|
357
|
-
const { workflow, workflowName: workflowNameParam, tag: tagParam,
|
|
358
|
-
const workflowName = workflowNameParam ??
|
|
366
|
+
const { workflow, workflowName: workflowNameParam, tag: tagParam, onMention, debugLog, feedback: feedbackEnabled, params: paramValues } = config;
|
|
367
|
+
const workflowName = workflowNameParam ?? "global";
|
|
359
368
|
const tag = tagParam ?? "main";
|
|
360
369
|
const logger = config.logger ?? createSilentLogger();
|
|
361
370
|
const startTime = Date.now();
|
|
@@ -407,7 +416,7 @@ async function initWorkflow(config) {
|
|
|
407
416
|
});
|
|
408
417
|
logger.debug(`MCP server: ${httpMcpServer.url}`);
|
|
409
418
|
const setupResults = {};
|
|
410
|
-
const context = createContext(workflow.name, tag, setupResults);
|
|
419
|
+
const context = createContext(workflow.name, tag, setupResults, paramValues, workflow.sourceDir);
|
|
411
420
|
if (workflow.setup && workflow.setup.length > 0) {
|
|
412
421
|
logger.info("Running setup...");
|
|
413
422
|
for (const task of workflow.setup) try {
|
|
@@ -425,7 +434,6 @@ async function initWorkflow(config) {
|
|
|
425
434
|
const interpolatedKickoff = workflow.kickoff ? interpolate(workflow.kickoff, context, (msg) => logger.warn(msg)) : void 0;
|
|
426
435
|
const runtime = {
|
|
427
436
|
name: workflow.name,
|
|
428
|
-
instance: instance ?? `${workflowName}:${tag}`,
|
|
429
437
|
contextDir,
|
|
430
438
|
projectDir,
|
|
431
439
|
contextProvider,
|
|
@@ -477,15 +485,15 @@ async function runSetupTask(task, context, logger) {
|
|
|
477
485
|
}
|
|
478
486
|
}
|
|
479
487
|
/**
|
|
480
|
-
* Run a workflow with agent
|
|
488
|
+
* Run a workflow with agent loops
|
|
481
489
|
*
|
|
482
490
|
* All output flows through the channel. The channel watcher (display layer)
|
|
483
491
|
* filters what to show: --debug includes kind="debug" entries.
|
|
484
492
|
*/
|
|
485
|
-
async function
|
|
486
|
-
const { workflow, workflowName: workflowNameParam, tag: tagParam,
|
|
493
|
+
async function runWorkflowWithLoops(config) {
|
|
494
|
+
const { workflow, workflowName: workflowNameParam, tag: tagParam, debug = false, log = console.log, mode = "run", pollInterval = 5e3, createBackend, feedback: feedbackEnabled, params: paramValues } = config;
|
|
487
495
|
const startTime = Date.now();
|
|
488
|
-
const workflowName = workflowNameParam ??
|
|
496
|
+
const workflowName = workflowNameParam ?? "global";
|
|
489
497
|
const tag = tagParam ?? "main";
|
|
490
498
|
try {
|
|
491
499
|
const { contextProvider, contextDir, persistent } = createWorkflowProvider(workflow, workflowName, tag);
|
|
@@ -497,33 +505,32 @@ async function runWorkflowWithControllers(config) {
|
|
|
497
505
|
});
|
|
498
506
|
logger.info(`Running workflow: ${workflow.name}`);
|
|
499
507
|
logger.info(`Agents: ${Object.keys(workflow.agents).join(", ")}`);
|
|
500
|
-
logger.debug("Starting workflow with
|
|
508
|
+
logger.debug("Starting workflow with loops", {
|
|
501
509
|
mode,
|
|
502
|
-
instance,
|
|
503
510
|
pollInterval
|
|
504
511
|
});
|
|
505
|
-
const
|
|
512
|
+
const loops = /* @__PURE__ */ new Map();
|
|
506
513
|
logger.debug("Initializing workflow runtime...");
|
|
507
514
|
const runtime = await initWorkflow({
|
|
508
515
|
workflow,
|
|
509
|
-
instance,
|
|
510
516
|
startAgent: async () => {},
|
|
511
517
|
logger,
|
|
512
518
|
contextProvider,
|
|
513
519
|
contextDir,
|
|
514
520
|
persistent,
|
|
515
521
|
onMention: (from, target, entry) => {
|
|
516
|
-
const
|
|
517
|
-
if (
|
|
522
|
+
const loop = loops.get(target);
|
|
523
|
+
if (loop) {
|
|
518
524
|
const preview = entry.content.length > 80 ? entry.content.slice(0, 80) + "..." : entry.content;
|
|
519
|
-
logger.debug(`@mention: ${from} → @${target} (state=${
|
|
520
|
-
|
|
521
|
-
} else logger.debug(`@mention: ${from} → @${target} (no
|
|
525
|
+
logger.debug(`@mention: ${from} → @${target} (state=${loop.state}): ${preview}`);
|
|
526
|
+
loop.wake();
|
|
527
|
+
} else logger.debug(`@mention: ${from} → @${target} (no loop found!)`);
|
|
522
528
|
},
|
|
523
529
|
debugLog: (msg) => {
|
|
524
530
|
logger.debug(msg);
|
|
525
531
|
},
|
|
526
|
-
feedback: feedbackEnabled
|
|
532
|
+
feedback: feedbackEnabled,
|
|
533
|
+
params: paramValues
|
|
527
534
|
});
|
|
528
535
|
logger.debug("Runtime initialized", {
|
|
529
536
|
agentNames: runtime.agentNames,
|
|
@@ -532,11 +539,11 @@ async function runWorkflowWithControllers(config) {
|
|
|
532
539
|
logger.info("Starting agents...");
|
|
533
540
|
for (const agentName of runtime.agentNames) {
|
|
534
541
|
const agentDef = workflow.agents[agentName];
|
|
535
|
-
logger.debug(`Creating
|
|
542
|
+
logger.debug(`Creating loop for ${agentName}`, {
|
|
536
543
|
backend: agentDef.backend,
|
|
537
544
|
model: agentDef.model
|
|
538
545
|
});
|
|
539
|
-
const {
|
|
546
|
+
const { loop, backend } = createWiredLoop({
|
|
540
547
|
name: agentName,
|
|
541
548
|
agent: agentDef,
|
|
542
549
|
runtime,
|
|
@@ -546,16 +553,16 @@ async function runWorkflowWithControllers(config) {
|
|
|
546
553
|
logger: logger.child(agentName)
|
|
547
554
|
});
|
|
548
555
|
logger.debug(`Using backend: ${backend.type} for ${agentName}`);
|
|
549
|
-
|
|
550
|
-
await
|
|
551
|
-
logger.debug(`
|
|
556
|
+
loops.set(agentName, loop);
|
|
557
|
+
await loop.start();
|
|
558
|
+
logger.debug(`Loop started: ${agentName}`);
|
|
552
559
|
}
|
|
553
560
|
logger.debug("Sending kickoff message...");
|
|
554
561
|
await runtime.sendKickoff();
|
|
555
562
|
logger.debug("Kickoff sent");
|
|
556
563
|
let channelWatcher;
|
|
557
564
|
if (!config.headless) if (config.prettyDisplay) {
|
|
558
|
-
const { startPrettyDisplay } = await import("./display-pretty-
|
|
565
|
+
const { startPrettyDisplay } = await import("./display-pretty-Kyd40DEF.mjs");
|
|
559
566
|
channelWatcher = startPrettyDisplay({
|
|
560
567
|
contextProvider: runtime.contextProvider,
|
|
561
568
|
agentNames: runtime.agentNames,
|
|
@@ -577,12 +584,12 @@ async function runWorkflowWithControllers(config) {
|
|
|
577
584
|
logger.debug("Running in \"run\" mode, waiting for completion...");
|
|
578
585
|
let idleCheckCount = 0;
|
|
579
586
|
while (true) {
|
|
580
|
-
const isIdle = await checkWorkflowIdle(
|
|
587
|
+
const isIdle = await checkWorkflowIdle(loops, runtime.contextProvider);
|
|
581
588
|
idleCheckCount++;
|
|
582
589
|
if (idleCheckCount % 10 === 0) {
|
|
583
|
-
const states = [...
|
|
590
|
+
const states = [...loops.entries()].map(([n, c]) => `${n}=${c.state}`).join(", ");
|
|
584
591
|
logger.debug(`Idle check #${idleCheckCount}: ${states}`);
|
|
585
|
-
for (const [agentName] of
|
|
592
|
+
for (const [agentName] of loops) {
|
|
586
593
|
const inbox = await runtime.contextProvider.getInbox(agentName);
|
|
587
594
|
if (inbox.length > 0) {
|
|
588
595
|
const unseenCount = inbox.filter((m) => !m.seen).length;
|
|
@@ -602,7 +609,7 @@ async function runWorkflowWithControllers(config) {
|
|
|
602
609
|
await sleep(1e3);
|
|
603
610
|
}
|
|
604
611
|
channelWatcher?.stop();
|
|
605
|
-
await
|
|
612
|
+
await shutdownLoops(loops, logger);
|
|
606
613
|
await runtime.shutdown();
|
|
607
614
|
logger.debug(`Workflow finished in ${Date.now() - startTime}ms`);
|
|
608
615
|
return {
|
|
@@ -621,10 +628,10 @@ async function runWorkflowWithControllers(config) {
|
|
|
621
628
|
duration: Date.now() - startTime,
|
|
622
629
|
mcpUrl: runtime.mcpUrl,
|
|
623
630
|
contextProvider: runtime.contextProvider,
|
|
624
|
-
|
|
631
|
+
loops,
|
|
625
632
|
shutdown: async () => {
|
|
626
633
|
channelWatcher?.stop();
|
|
627
|
-
await
|
|
634
|
+
await shutdownLoops(loops, logger);
|
|
628
635
|
await runtime.shutdown();
|
|
629
636
|
},
|
|
630
637
|
getFeedback: runtime.getFeedback
|
|
@@ -641,16 +648,16 @@ async function runWorkflowWithControllers(config) {
|
|
|
641
648
|
}
|
|
642
649
|
}
|
|
643
650
|
/**
|
|
644
|
-
* Gracefully shutdown all
|
|
651
|
+
* Gracefully shutdown all loops
|
|
645
652
|
*/
|
|
646
|
-
async function
|
|
647
|
-
logger.debug("Stopping
|
|
648
|
-
const stopPromises = [...
|
|
649
|
-
await
|
|
650
|
-
logger.debug(`Stopped
|
|
653
|
+
async function shutdownLoops(loops, logger) {
|
|
654
|
+
logger.debug("Stopping loops...");
|
|
655
|
+
const stopPromises = [...loops.values()].map(async (loop) => {
|
|
656
|
+
await loop.stop();
|
|
657
|
+
logger.debug(`Stopped loop: ${loop.name}`);
|
|
651
658
|
});
|
|
652
659
|
await Promise.all(stopPromises);
|
|
653
|
-
logger.debug("All
|
|
660
|
+
logger.debug("All loops stopped");
|
|
654
661
|
}
|
|
655
662
|
/**
|
|
656
663
|
* Sleep helper
|
|
@@ -660,4 +667,4 @@ function sleep(ms) {
|
|
|
660
667
|
}
|
|
661
668
|
|
|
662
669
|
//#endregion
|
|
663
|
-
export { createWorkflowProvider, initWorkflow, interpolate as n,
|
|
670
|
+
export { createWorkflowProvider, initWorkflow, interpolate as n, runWorkflowWithLoops, shutdownLoops, createContext as t };
|