wave-agent-sdk 0.10.3 → 0.11.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/agent.d.ts +8 -6
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +12 -9
- package/dist/builtin-skills/builtin-skills/loop/SKILL.md +53 -0
- package/dist/builtin-skills/builtin-skills/loop/parsing.ts +159 -0
- package/dist/builtin-skills/builtin-skills/settings/HOOKS.md +82 -0
- package/dist/builtin-skills/{settings → builtin-skills/settings}/SKILL.md +1 -1
- package/dist/builtin-skills/loop/parsing.d.ts +13 -0
- package/dist/builtin-skills/loop/parsing.d.ts.map +1 -0
- package/dist/builtin-skills/loop/parsing.js +125 -0
- package/dist/constants/tools.d.ts +3 -0
- package/dist/constants/tools.d.ts.map +1 -1
- package/dist/constants/tools.js +3 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/managers/aiManager.d.ts +0 -2
- package/dist/managers/aiManager.d.ts.map +1 -1
- package/dist/managers/aiManager.js +53 -14
- package/dist/managers/cronManager.d.ts +19 -0
- package/dist/managers/cronManager.d.ts.map +1 -0
- package/dist/managers/cronManager.js +124 -0
- package/dist/managers/hookManager.d.ts.map +1 -1
- package/dist/managers/hookManager.js +21 -13
- package/dist/managers/liveConfigManager.js +1 -1
- package/dist/managers/mcpManager.d.ts +1 -1
- package/dist/managers/mcpManager.d.ts.map +1 -1
- package/dist/managers/mcpManager.js +10 -2
- package/dist/managers/messageManager.d.ts +0 -1
- package/dist/managers/messageManager.d.ts.map +1 -1
- package/dist/managers/permissionManager.d.ts +27 -7
- package/dist/managers/permissionManager.d.ts.map +1 -1
- package/dist/managers/permissionManager.js +119 -14
- package/dist/managers/slashCommandManager.d.ts.map +1 -1
- package/dist/managers/slashCommandManager.js +11 -0
- package/dist/managers/subagentManager.d.ts +3 -0
- package/dist/managers/subagentManager.d.ts.map +1 -1
- package/dist/managers/subagentManager.js +10 -17
- package/dist/managers/toolManager.d.ts +1 -1
- package/dist/managers/toolManager.d.ts.map +1 -1
- package/dist/managers/toolManager.js +28 -4
- package/dist/services/configurationService.d.ts.map +1 -1
- package/dist/services/configurationService.js +8 -7
- package/dist/services/hook.d.ts.map +1 -1
- package/dist/services/hook.js +3 -10
- package/dist/services/initializationService.js +2 -2
- package/dist/services/jsonlHandler.d.ts.map +1 -1
- package/dist/services/jsonlHandler.js +3 -0
- package/dist/services/reversionService.d.ts +2 -2
- package/dist/services/reversionService.d.ts.map +1 -1
- package/dist/services/reversionService.js +3 -3
- package/dist/services/session.d.ts.map +1 -1
- package/dist/services/session.js +18 -11
- package/dist/tools/agentTool.js +1 -1
- package/dist/tools/bashTool.d.ts.map +1 -1
- package/dist/tools/bashTool.js +33 -12
- package/dist/tools/cronCreateTool.d.ts +3 -0
- package/dist/tools/cronCreateTool.d.ts.map +1 -0
- package/dist/tools/cronCreateTool.js +59 -0
- package/dist/tools/cronDeleteTool.d.ts +3 -0
- package/dist/tools/cronDeleteTool.d.ts.map +1 -0
- package/dist/tools/cronDeleteTool.js +38 -0
- package/dist/tools/cronListTool.d.ts +3 -0
- package/dist/tools/cronListTool.d.ts.map +1 -0
- package/dist/tools/cronListTool.js +30 -0
- package/dist/tools/readTool.d.ts.map +1 -1
- package/dist/tools/readTool.js +8 -32
- package/dist/tools/skillTool.d.ts +0 -3
- package/dist/tools/skillTool.d.ts.map +1 -1
- package/dist/tools/skillTool.js +4 -3
- package/dist/tools/taskOutputTool.d.ts.map +1 -1
- package/dist/tools/taskOutputTool.js +15 -8
- package/dist/tools/types.d.ts +2 -0
- package/dist/tools/types.d.ts.map +1 -1
- package/dist/types/agent.d.ts +10 -0
- package/dist/types/agent.d.ts.map +1 -1
- package/dist/types/configuration.d.ts +1 -1
- package/dist/types/configuration.d.ts.map +1 -1
- package/dist/types/cron.d.ts +10 -0
- package/dist/types/cron.d.ts.map +1 -0
- package/dist/types/cron.js +1 -0
- package/dist/types/hooks.d.ts +1 -5
- package/dist/types/hooks.d.ts.map +1 -1
- package/dist/types/hooks.js +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +1 -0
- package/dist/types/messaging.d.ts +1 -1
- package/dist/types/messaging.d.ts.map +1 -1
- package/dist/utils/containerSetup.d.ts.map +1 -1
- package/dist/utils/containerSetup.js +40 -13
- package/dist/utils/mcpUtils.d.ts +2 -2
- package/dist/utils/mcpUtils.d.ts.map +1 -1
- package/dist/utils/mcpUtils.js +1 -5
- package/package.json +2 -1
- package/src/agent.ts +17 -12
- package/src/builtin-skills/loop/SKILL.md +53 -0
- package/src/builtin-skills/loop/parsing.ts +159 -0
- package/src/builtin-skills/settings/HOOKS.md +44 -57
- package/src/builtin-skills/settings/SKILL.md +1 -1
- package/src/constants/tools.ts +3 -0
- package/src/index.ts +1 -0
- package/src/managers/aiManager.ts +72 -24
- package/src/managers/cronManager.ts +167 -0
- package/src/managers/hookManager.ts +27 -13
- package/src/managers/liveConfigManager.ts +2 -2
- package/src/managers/mcpManager.ts +23 -2
- package/src/managers/messageManager.ts +0 -6
- package/src/managers/permissionManager.ts +154 -18
- package/src/managers/slashCommandManager.ts +12 -0
- package/src/managers/subagentManager.ts +15 -19
- package/src/managers/toolManager.ts +37 -4
- package/src/services/configurationService.ts +8 -7
- package/src/services/hook.ts +5 -11
- package/src/services/initializationService.ts +3 -3
- package/src/services/jsonlHandler.ts +4 -0
- package/src/services/reversionService.ts +9 -4
- package/src/services/session.ts +19 -12
- package/src/tools/agentTool.ts +1 -1
- package/src/tools/bashTool.ts +43 -14
- package/src/tools/cronCreateTool.ts +73 -0
- package/src/tools/cronDeleteTool.ts +47 -0
- package/src/tools/cronListTool.ts +38 -0
- package/src/tools/readTool.ts +11 -33
- package/src/tools/skillTool.ts +6 -4
- package/src/tools/taskOutputTool.ts +14 -8
- package/src/tools/types.ts +2 -0
- package/src/types/agent.ts +10 -0
- package/src/types/configuration.ts +1 -1
- package/src/types/cron.ts +9 -0
- package/src/types/hooks.ts +5 -9
- package/src/types/index.ts +1 -0
- package/src/types/messaging.ts +1 -1
- package/src/utils/containerSetup.ts +50 -16
- package/src/utils/mcpUtils.ts +2 -5
- package/dist/builtin-skills/settings/HOOKS.md +0 -95
package/dist/types/hooks.js
CHANGED
package/dist/types/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,cAAc,WAAW,CAAC;AAG1B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,UAAU,CAAC;AACzB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,cAAc,WAAW,CAAC;AAG1B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,UAAU,CAAC;AACzB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC"}
|
package/dist/types/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"messaging.d.ts","sourceRoot":"","sources":["../../src/types/messaging.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AAEvC,oBAAY,aAAa;IACvB,IAAI,SAAS;IACb,IAAI,SAAS;CACd;AAED,MAAM,WAAW,OAAO;IACtB,EAAE,
|
|
1
|
+
{"version":3,"file":"messaging.d.ts","sourceRoot":"","sources":["../../src/types/messaging.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AAEvC,oBAAY,aAAa;IACvB,IAAI,SAAS;IACb,IAAI,SAAS;CACd;AAED,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC5C;AAED,MAAM,MAAM,YAAY,GACpB,SAAS,GACT,UAAU,GACV,SAAS,GACT,UAAU,GACV,SAAS,GACT,aAAa,GACb,cAAc,GACd,gBAAgB,CAAC;AAErB,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,MAAM,CAAC,EAAE,aAAa,CAAC;CACxB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,MAAM,CAAC,EAAE,KAAK,CAAC;QAEb,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC,CAAC;IACH,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;;OAMG;IACH,KAAK,EAAE,OAAO,GAAG,WAAW,GAAG,SAAS,GAAG,KAAK,CAAC;IACjD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,sBAAsB,CAAC,EAAE,OAAO,CAAC;CAClC;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,OAAO,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,UAAU,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,WAAW,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,cAAc,CAAC;IACrB,SAAS,EAAE,OAAO,gBAAgB,EAAE,YAAY,EAAE,CAAC;CACpD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"containerSetup.d.ts","sourceRoot":"","sources":["../../src/utils/containerSetup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"containerSetup.d.ts","sourceRoot":"","sources":["../../src/utils/containerSetup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAqB3C,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAI3E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,KAAK,EACV,cAAc,EACd,KAAK,EACL,IAAI,EACJ,cAAc,EAEf,MAAM,mBAAmB,CAAC;AAI3B,MAAM,WAAW,0BAA0B;IACzC,OAAO,EAAE,YAAY,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,oBAAoB,EAAE,oBAAoB,CAAC;IAC3C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,OAAO,CAAC;IAGhB,uBAAuB,EAAE,CAAC,KAAK,EAAE,cAAc,EAAE,KAAK,IAAI,CAAC;IAC3D,aAAa,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;IACvC,sBAAsB,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;IACvD,wBAAwB,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;IACzD,iBAAiB,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;IAClD,iBAAiB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACnD,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAClC;AAED,wBAAgB,mBAAmB,CACjC,YAAY,EAAE,0BAA0B,GACvC,SAAS,CAoPX"}
|
|
@@ -14,20 +14,27 @@ import { SkillManager } from "../managers/skillManager.js";
|
|
|
14
14
|
import { SlashCommandManager } from "../managers/slashCommandManager.js";
|
|
15
15
|
import { PluginManager } from "../managers/pluginManager.js";
|
|
16
16
|
import { BangManager } from "../managers/bangManager.js";
|
|
17
|
+
import { CronManager } from "../managers/cronManager.js";
|
|
17
18
|
import { MemoryRuleManager } from "../managers/MemoryRuleManager.js";
|
|
18
19
|
import { ReversionManager } from "../managers/reversionManager.js";
|
|
19
20
|
import { SubagentManager } from "../managers/subagentManager.js";
|
|
20
21
|
import { LiveConfigManager } from "../managers/liveConfigManager.js";
|
|
21
22
|
import { ReversionService } from "../services/reversionService.js";
|
|
22
23
|
import { MemoryService } from "../services/memory.js";
|
|
24
|
+
import { getGitMainRepoRoot } from "./gitUtils.js";
|
|
23
25
|
import { logger } from "./globalLogger.js";
|
|
24
26
|
export function setupAgentContainer(setupOptions) {
|
|
25
27
|
const { options, workdir, configurationService, systemPrompt, stream, onBackgroundTasksChange, onTasksChange, onPermissionModeChange, handlePlanModeTransition, setPermissionMode, addPermissionRule, addUsage, } = setupOptions;
|
|
26
28
|
const callbacks = options.callbacks || {};
|
|
27
29
|
const container = new Container();
|
|
30
|
+
container.register("AgentOptions", options);
|
|
28
31
|
const foregroundTaskManager = new ForegroundTaskManager(container);
|
|
29
32
|
container.register("ForegroundTaskManager", foregroundTaskManager);
|
|
30
33
|
container.register("ConfigurationService", configurationService);
|
|
34
|
+
if (options.worktreeName) {
|
|
35
|
+
container.register("WorktreeName", options.worktreeName);
|
|
36
|
+
container.register("MainRepoRoot", getGitMainRepoRoot(workdir));
|
|
37
|
+
}
|
|
31
38
|
const memoryService = new MemoryService(container);
|
|
32
39
|
container.register("MemoryService", memoryService);
|
|
33
40
|
const memoryRuleManager = new MemoryRuleManager(container, { workdir });
|
|
@@ -75,13 +82,17 @@ export function setupAgentContainer(setupOptions) {
|
|
|
75
82
|
container.register("McpManager", mcpManager);
|
|
76
83
|
const lspManager = options.lspManager || new LspManager(container);
|
|
77
84
|
container.register("LspManager", lspManager);
|
|
78
|
-
const permissionManager = new PermissionManager(container, {
|
|
85
|
+
const permissionManager = new PermissionManager(container, {
|
|
86
|
+
workdir,
|
|
87
|
+
instanceAllowedRules: options.allowedTools,
|
|
88
|
+
instanceDeniedRules: options.disallowedTools,
|
|
89
|
+
});
|
|
79
90
|
if (configurationService.resolveAutoMemoryEnabled()) {
|
|
80
91
|
const autoMemoryDir = memoryService.getAutoMemoryDirectory(workdir);
|
|
81
92
|
permissionManager.addSystemAdditionalDirectory(autoMemoryDir);
|
|
82
93
|
}
|
|
83
94
|
container.register("PermissionManager", permissionManager);
|
|
84
|
-
permissionManager.
|
|
95
|
+
permissionManager.setOnConfiguredPermissionModeChange((mode) => {
|
|
85
96
|
handlePlanModeTransition(mode);
|
|
86
97
|
onPermissionModeChange(mode);
|
|
87
98
|
});
|
|
@@ -94,27 +105,37 @@ export function setupAgentContainer(setupOptions) {
|
|
|
94
105
|
watch: options.watchSkills ?? true,
|
|
95
106
|
});
|
|
96
107
|
container.register("SkillManager", skillManager);
|
|
97
|
-
|
|
108
|
+
const rootSessionId = messageManager.getRootSessionId();
|
|
109
|
+
container.register("ReversionService", new ReversionService(rootSessionId));
|
|
98
110
|
const reversionManager = new ReversionManager(container);
|
|
99
111
|
container.register("ReversionManager", reversionManager);
|
|
100
|
-
const
|
|
112
|
+
const canUseToolWithPermissionRequest = options.canUseTool
|
|
101
113
|
? async (context) => {
|
|
102
114
|
try {
|
|
103
|
-
const
|
|
104
|
-
|
|
105
|
-
event: "Notification",
|
|
115
|
+
const results = await hookManager.executeHooks("PermissionRequest", {
|
|
116
|
+
event: "PermissionRequest",
|
|
106
117
|
projectDir: workdir,
|
|
107
118
|
timestamp: new Date(),
|
|
108
119
|
sessionId: messageManager.getSessionId(),
|
|
109
120
|
transcriptPath: messageManager.getTranscriptPath(),
|
|
110
121
|
cwd: workdir,
|
|
111
|
-
|
|
112
|
-
|
|
122
|
+
toolName: context.toolName,
|
|
123
|
+
toolInput: context.toolInput,
|
|
113
124
|
env: configurationService.getEnvironmentVars(),
|
|
114
125
|
});
|
|
126
|
+
if (results.length > 0) {
|
|
127
|
+
const processResult = hookManager.processHookResults("PermissionRequest", results, messageManager);
|
|
128
|
+
if (processResult.shouldBlock) {
|
|
129
|
+
return {
|
|
130
|
+
behavior: "deny",
|
|
131
|
+
message: processResult.errorMessage ||
|
|
132
|
+
"Permission denied by hook execution",
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
}
|
|
115
136
|
}
|
|
116
137
|
catch (error) {
|
|
117
|
-
logger.warn("Failed to execute
|
|
138
|
+
logger.warn("Failed to execute permission request hooks", {
|
|
118
139
|
toolName: context.toolName,
|
|
119
140
|
error: error instanceof Error ? error.message : String(error),
|
|
120
141
|
});
|
|
@@ -145,9 +166,9 @@ export function setupAgentContainer(setupOptions) {
|
|
|
145
166
|
container.register("ToolManager", toolManager);
|
|
146
167
|
container.register("PermissionMode", options.permissionMode);
|
|
147
168
|
logger.info("Registering CanUseToolCallback", {
|
|
148
|
-
hasCallback: !!
|
|
169
|
+
hasCallback: !!canUseToolWithPermissionRequest,
|
|
149
170
|
});
|
|
150
|
-
container.register("CanUseToolCallback",
|
|
171
|
+
container.register("CanUseToolCallback", canUseToolWithPermissionRequest);
|
|
151
172
|
const liveConfigManager = new LiveConfigManager(container, { workdir });
|
|
152
173
|
container.register("LiveConfigManager", liveConfigManager);
|
|
153
174
|
const subagentManager = new SubagentManager(container, {
|
|
@@ -158,10 +179,13 @@ export function setupAgentContainer(setupOptions) {
|
|
|
158
179
|
onSubagentAssistantContentUpdated: callbacks.onSubagentAssistantContentUpdated,
|
|
159
180
|
onSubagentAssistantReasoningUpdated: callbacks.onSubagentAssistantReasoningUpdated,
|
|
160
181
|
onSubagentToolBlockUpdated: callbacks.onSubagentToolBlockUpdated,
|
|
161
|
-
onSubagentMessagesChange:
|
|
182
|
+
onSubagentMessagesChange: (subagentId, messages) => {
|
|
183
|
+
callbacks.onSubagentMessagesChange?.(subagentId, messages);
|
|
184
|
+
},
|
|
162
185
|
onSubagentLatestTotalTokensChange: callbacks.onSubagentLatestTotalTokensChange,
|
|
163
186
|
},
|
|
164
187
|
onUsageAdded: (usage) => addUsage(usage),
|
|
188
|
+
stream,
|
|
165
189
|
});
|
|
166
190
|
container.register("SubagentManager", subagentManager);
|
|
167
191
|
const aiManager = new AIManager(container, {
|
|
@@ -181,5 +205,8 @@ export function setupAgentContainer(setupOptions) {
|
|
|
181
205
|
container.register("PluginManager", pluginManager);
|
|
182
206
|
const bangManager = new BangManager(container, { workdir });
|
|
183
207
|
container.register("BangManager", bangManager);
|
|
208
|
+
const cronManager = new CronManager(container);
|
|
209
|
+
container.register("CronManager", cronManager);
|
|
210
|
+
cronManager.start();
|
|
184
211
|
return container;
|
|
185
212
|
}
|
package/dist/utils/mcpUtils.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ChatCompletionFunctionTool } from "openai/resources.js";
|
|
2
|
-
import type { ToolPlugin } from "../tools/types.js";
|
|
2
|
+
import type { ToolPlugin, ToolContext } from "../tools/types.js";
|
|
3
3
|
import type { McpTool, McpServerStatus } from "../types/index.js";
|
|
4
4
|
/**
|
|
5
5
|
* Convert MCP tool to OpenAI function tool format
|
|
@@ -8,7 +8,7 @@ export declare function mcpToolToOpenAITool(mcpTool: McpTool, serverName: string
|
|
|
8
8
|
/**
|
|
9
9
|
* Create a tool plugin wrapper for an MCP tool
|
|
10
10
|
*/
|
|
11
|
-
export declare function createMcpToolPlugin(mcpTool: McpTool, serverName: string, executeTool: (name: string, args: Record<string, unknown
|
|
11
|
+
export declare function createMcpToolPlugin(mcpTool: McpTool, serverName: string, executeTool: (name: string, args: Record<string, unknown>, context?: ToolContext) => Promise<{
|
|
12
12
|
success: boolean;
|
|
13
13
|
content: string;
|
|
14
14
|
serverName?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcpUtils.d.ts","sourceRoot":"","sources":["../../src/utils/mcpUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AACjE,OAAO,KAAK,EAAE,UAAU,
|
|
1
|
+
{"version":3,"file":"mcpUtils.d.ts","sourceRoot":"","sources":["../../src/utils/mcpUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AACjE,OAAO,KAAK,EAAE,UAAU,EAAc,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAC7E,OAAO,KAAK,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AA8ClE;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,MAAM,GACjB,0BAA0B,CAgB5B;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,CACX,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,CAAC,EAAE,WAAW,KAClB,OAAO,CAAC;IACX,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACtD,CAAC,GACD,UAAU,CAwBZ;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,eAAe,EAAE,GACzB,eAAe,GAAG,SAAS,CAK7B"}
|
package/dist/utils/mcpUtils.js
CHANGED
|
@@ -59,11 +59,7 @@ export function createMcpToolPlugin(mcpTool, serverName, executeTool) {
|
|
|
59
59
|
config: mcpToolToOpenAITool(mcpTool, serverName),
|
|
60
60
|
async execute(args, context) {
|
|
61
61
|
try {
|
|
62
|
-
|
|
63
|
-
if (context) {
|
|
64
|
-
// Future: Could pass working directory or other context to MCP tools
|
|
65
|
-
}
|
|
66
|
-
const result = await executeTool(prefixedName, args);
|
|
62
|
+
const result = await executeTool(prefixedName, args, context);
|
|
67
63
|
return {
|
|
68
64
|
success: true,
|
|
69
65
|
content: result.content || `Executed ${mcpTool.name}`,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wave-agent-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"description": "SDK for building AI-powered development tools and agents",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@modelcontextprotocol/sdk": "^1.18.2",
|
|
31
31
|
"chokidar": "^5.0.0",
|
|
32
|
+
"cron-parser": "^5.5.0",
|
|
32
33
|
"fuzzysort": "^3.1.0",
|
|
33
34
|
"glob": "^13.0.0",
|
|
34
35
|
"minimatch": "^10.0.3",
|
package/src/agent.ts
CHANGED
|
@@ -6,6 +6,7 @@ import { SubagentManager } from "./managers/subagentManager.js";
|
|
|
6
6
|
import { McpManager } from "./managers/mcpManager.js";
|
|
7
7
|
import { LspManager } from "./managers/lspManager.js";
|
|
8
8
|
import { BangManager } from "./managers/bangManager.js";
|
|
9
|
+
import { CronManager } from "./managers/cronManager.js";
|
|
9
10
|
import { BackgroundTaskManager } from "./managers/backgroundTaskManager.js";
|
|
10
11
|
import { SlashCommandManager } from "./managers/slashCommandManager.js";
|
|
11
12
|
import { PluginManager } from "./managers/pluginManager.js";
|
|
@@ -56,6 +57,7 @@ export class Agent {
|
|
|
56
57
|
private slashCommandManager: SlashCommandManager; // Add slash command manager instance
|
|
57
58
|
private pluginManager: PluginManager; // Add plugin manager instance
|
|
58
59
|
private skillManager: SkillManager; // Add skill manager instance
|
|
60
|
+
private cronManager: CronManager; // Add cron manager instance
|
|
59
61
|
private hookManager: HookManager; // Add hooks manager instance
|
|
60
62
|
private reversionManager: ReversionManager;
|
|
61
63
|
private memoryRuleManager: MemoryRuleManager; // Add memory rule manager instance
|
|
@@ -168,6 +170,7 @@ export class Agent {
|
|
|
168
170
|
this.slashCommandManager = this.container.get("SlashCommandManager")!;
|
|
169
171
|
this.pluginManager = this.container.get("PluginManager")!;
|
|
170
172
|
this.bangManager = this.container.get("BangManager")!;
|
|
173
|
+
this.cronManager = this.container.get("CronManager")!;
|
|
171
174
|
|
|
172
175
|
// Set initial permission mode if provided
|
|
173
176
|
if (options.permissionMode) {
|
|
@@ -411,8 +414,8 @@ export class Agent {
|
|
|
411
414
|
await this.bangManager?.executeCommand(command);
|
|
412
415
|
}
|
|
413
416
|
|
|
414
|
-
public clearMessages(): void {
|
|
415
|
-
this.
|
|
417
|
+
public async clearMessages(): Promise<void> {
|
|
418
|
+
await this.slashCommandManager.executeCommand("clear");
|
|
416
419
|
}
|
|
417
420
|
|
|
418
421
|
/** Unified interrupt method, interrupts both AI messages and command execution */
|
|
@@ -460,6 +463,7 @@ export class Agent {
|
|
|
460
463
|
this.abortAIMessage(); // This will abort tools including Agent tool (subagents)
|
|
461
464
|
this.abortBashCommand();
|
|
462
465
|
this.abortSlashCommand();
|
|
466
|
+
this.cronManager.stop();
|
|
463
467
|
// Cleanup background task manager
|
|
464
468
|
this.backgroundTaskManager.cleanup();
|
|
465
469
|
// Cleanup MCP connections
|
|
@@ -484,16 +488,6 @@ export class Agent {
|
|
|
484
488
|
// Cleanup memory store
|
|
485
489
|
}
|
|
486
490
|
|
|
487
|
-
/**
|
|
488
|
-
* Get a subagent instance by its ID
|
|
489
|
-
* @param subagentId - The ID of the subagent instance
|
|
490
|
-
*/
|
|
491
|
-
public getSubagentInstance(
|
|
492
|
-
subagentId: string,
|
|
493
|
-
): import("./managers/subagentManager.js").SubagentInstance | null {
|
|
494
|
-
return this.subagentManager.getInstance(subagentId);
|
|
495
|
-
}
|
|
496
|
-
|
|
497
491
|
/**
|
|
498
492
|
* Trigger the rewind UI callback
|
|
499
493
|
*/
|
|
@@ -688,6 +682,17 @@ export class Agent {
|
|
|
688
682
|
await this.permissionManager.addPermissionRule(rule);
|
|
689
683
|
}
|
|
690
684
|
|
|
685
|
+
/**
|
|
686
|
+
* Get subagent instance by ID
|
|
687
|
+
* @param subagentId - The ID of the subagent instance
|
|
688
|
+
* @returns The subagent instance or null if not found
|
|
689
|
+
*/
|
|
690
|
+
public getSubagentInstance(
|
|
691
|
+
subagentId: string,
|
|
692
|
+
): import("./managers/subagentManager.js").SubagentInstance | null {
|
|
693
|
+
return this.subagentManager.getInstance(subagentId);
|
|
694
|
+
}
|
|
695
|
+
|
|
691
696
|
/**
|
|
692
697
|
* Get the current task list ID
|
|
693
698
|
*/
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: loop
|
|
3
|
+
description: Parses user input into an interval and prompt, converts the interval to a cron expression, and schedules a recurring task
|
|
4
|
+
allowed-tools: CronCreate, Skill
|
|
5
|
+
---
|
|
6
|
+
# /loop — schedule a recurring prompt
|
|
7
|
+
|
|
8
|
+
Parse the input below into `[interval] <prompt…>` and schedule it with CronCreate.
|
|
9
|
+
|
|
10
|
+
## Parsing (in priority order)
|
|
11
|
+
|
|
12
|
+
1. **Leading token**: if the first whitespace-delimited token matches `^\d+[smhd]$` (e.g. `5m`, `2h`), that's the interval; the rest is the prompt.
|
|
13
|
+
2. **Trailing "every" clause**: otherwise, if the input ends with `every <N><unit>` or `every <N> <unit-word>` (e.g. `every 20m`, `every 5 minutes`, `every 2 hours`), extract that as the interval and strip it from the prompt. Only match when what follows "every" is a time expression — `check every PR` has no interval.
|
|
14
|
+
3. **Default**: otherwise, interval is `10m` and the entire input is the prompt.
|
|
15
|
+
|
|
16
|
+
If the resulting prompt is empty, show usage `/loop [interval] <prompt>` and stop — do not call CronCreate.
|
|
17
|
+
|
|
18
|
+
Examples:
|
|
19
|
+
- `5m /babysit-prs` → interval `5m`, prompt `/babysit-prs` (rule 1)
|
|
20
|
+
- `check the deploy every 20m` → interval `20m`, prompt `check the deploy` (rule 2)
|
|
21
|
+
- `run tests every 5 minutes` → interval `5m`, prompt `run tests` (rule 2)
|
|
22
|
+
- `check the deploy` → interval `10m`, prompt `check the deploy` (rule 3)
|
|
23
|
+
- `check every PR` → interval `10m`, prompt `check every PR` (rule 3 — "every" not followed by time)
|
|
24
|
+
- `5m` → empty prompt → show usage
|
|
25
|
+
|
|
26
|
+
## Interval → cron
|
|
27
|
+
|
|
28
|
+
Supported suffixes: `s` (seconds, rounded up to nearest minute, min 1), `m` (minutes), `h` (hours), `d` (days). Convert:
|
|
29
|
+
|
|
30
|
+
| Interval pattern | Cron expression | Notes |
|
|
31
|
+
|-----------------------|---------------------|------------------------------------------|
|
|
32
|
+
| `Nm` where N ≤ 59 | `*/N * * * *` | every N minutes |
|
|
33
|
+
| `Nm` where N ≥ 60 | `0 */H * * *` | round to hours (H = N/60, must divide 24)|
|
|
34
|
+
| `Nh` where N ≤ 23 | `0 */N * * *` | every N hours |
|
|
35
|
+
| `Nd` | `0 0 */N * *` | every N days at midnight local |
|
|
36
|
+
| `Ns` | treat as `ceil(N/60)m` | cron minimum granularity is 1 minute |
|
|
37
|
+
|
|
38
|
+
**If the interval doesn't cleanly divide its unit** (e.g. `7m` → `*/7 * * * *` gives uneven gaps at :56→:00; `90m` → 1.5h which cron can't express), pick the nearest clean interval and tell the user what you rounded to before scheduling.
|
|
39
|
+
|
|
40
|
+
**Thundering herd prevention**: For approximate requests like "hourly" or "every morning", pick a random minute (e.g., 7) instead of 0 to avoid global sync issues.
|
|
41
|
+
|
|
42
|
+
## Action
|
|
43
|
+
|
|
44
|
+
1. Call CronCreate with:
|
|
45
|
+
- `cron`: the expression from the table above
|
|
46
|
+
- `prompt`: the parsed prompt from above, verbatim (slash commands are passed through unchanged)
|
|
47
|
+
- `recurring`: `true`
|
|
48
|
+
2. Briefly confirm: what's scheduled, the cron expression, the human-readable cadence, that recurring tasks auto-expire after 7 days, and that they can cancel sooner with CronDelete (include the job ID).
|
|
49
|
+
3. **Then immediately execute the parsed prompt now** — don't wait for the first cron fire. If it's a slash command, invoke it via the Skill tool; otherwise act on it directly.
|
|
50
|
+
|
|
51
|
+
## Input
|
|
52
|
+
|
|
53
|
+
$ARGUMENTS
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
export interface ParsedLoop {
|
|
2
|
+
interval: string;
|
|
3
|
+
prompt: string;
|
|
4
|
+
originalInterval?: string;
|
|
5
|
+
roundedTo?: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export function parseLoopInput(
|
|
9
|
+
input: string,
|
|
10
|
+
defaultInterval: string = "10m",
|
|
11
|
+
): ParsedLoop {
|
|
12
|
+
const trimmedInput = input.trim();
|
|
13
|
+
if (!trimmedInput) {
|
|
14
|
+
return { interval: defaultInterval, prompt: "" };
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// 1. Leading token: ^\d+[smhd]$
|
|
18
|
+
const tokens = trimmedInput.split(/\s+/);
|
|
19
|
+
if (tokens[0].match(/^\d+[smhd]$/)) {
|
|
20
|
+
const interval = tokens[0];
|
|
21
|
+
const prompt = tokens.slice(1).join(" ");
|
|
22
|
+
return { interval, prompt };
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// 2. Trailing "every" clause: every <N><unit> or every <N> <unit-word>
|
|
26
|
+
// Units: s, m, h, d, second(s), minute(s), hour(s), day(s)
|
|
27
|
+
const everyRegex =
|
|
28
|
+
/\s+every\s+(\d+)\s*(s|m|h|d|seconds?|minutes?|hours?|days?)$/i;
|
|
29
|
+
const match = trimmedInput.match(everyRegex);
|
|
30
|
+
if (match) {
|
|
31
|
+
const n = match[1];
|
|
32
|
+
const unitWord = match[2].toLowerCase();
|
|
33
|
+
const unit = unitWord[0];
|
|
34
|
+
const interval = `${n}${unit}`;
|
|
35
|
+
const prompt = trimmedInput.substring(0, match.index).trim();
|
|
36
|
+
return { interval, prompt };
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// 3. Default
|
|
40
|
+
return { interval: defaultInterval, prompt: trimmedInput };
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const CLEAN_MINUTES = [1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30];
|
|
44
|
+
const CLEAN_HOURS = [1, 2, 3, 4, 6, 8, 12];
|
|
45
|
+
|
|
46
|
+
function getNearestClean(value: number, cleanValues: number[]): number {
|
|
47
|
+
let nearest = cleanValues[0];
|
|
48
|
+
let minDiff = Math.abs(value - nearest);
|
|
49
|
+
for (const clean of cleanValues) {
|
|
50
|
+
const diff = Math.abs(value - clean);
|
|
51
|
+
if (diff < minDiff) {
|
|
52
|
+
minDiff = diff;
|
|
53
|
+
nearest = clean;
|
|
54
|
+
} else if (diff === minDiff) {
|
|
55
|
+
// If equal diff, prefer the larger one? Or smaller?
|
|
56
|
+
// Let's prefer the larger one to be less frequent
|
|
57
|
+
if (clean > nearest) {
|
|
58
|
+
nearest = clean;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return nearest;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function intervalToCron(interval: string): {
|
|
66
|
+
cron: string;
|
|
67
|
+
roundedTo?: string;
|
|
68
|
+
cadence: string;
|
|
69
|
+
} {
|
|
70
|
+
const match = interval.match(/^(\d+)([smhd])$/);
|
|
71
|
+
if (!match) {
|
|
72
|
+
throw new Error(`Invalid interval format: ${interval}`);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
let n = parseInt(match[1], 10);
|
|
76
|
+
const unit = match[2];
|
|
77
|
+
let roundedTo: string | undefined;
|
|
78
|
+
|
|
79
|
+
if (unit === "s") {
|
|
80
|
+
const minutes = Math.ceil(n / 60);
|
|
81
|
+
const result = intervalToCron(`${minutes}m`);
|
|
82
|
+
return {
|
|
83
|
+
...result,
|
|
84
|
+
roundedTo:
|
|
85
|
+
result.roundedTo || (minutes * 60 !== n ? `${minutes}m` : undefined),
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (unit === "m") {
|
|
90
|
+
if (n >= 60) {
|
|
91
|
+
const hours = Math.round(n / 60);
|
|
92
|
+
const result = intervalToCron(`${hours}h`);
|
|
93
|
+
return {
|
|
94
|
+
...result,
|
|
95
|
+
roundedTo:
|
|
96
|
+
result.roundedTo || (hours * 60 !== n ? `${hours}h` : undefined),
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (!CLEAN_MINUTES.includes(n)) {
|
|
101
|
+
const nearest = getNearestClean(n, CLEAN_MINUTES);
|
|
102
|
+
roundedTo = `${nearest}m`;
|
|
103
|
+
n = nearest;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// For minutes, we use */N. Thundering herd is less of an issue for high frequency,
|
|
107
|
+
// but we could still offset it. However, the spec says "random minute for approximate requests like 'hourly'".
|
|
108
|
+
// So for minutes, we'll stick to */N.
|
|
109
|
+
return {
|
|
110
|
+
cron: `*/${n} * * * *`,
|
|
111
|
+
roundedTo,
|
|
112
|
+
cadence: `every ${n} minute${n > 1 ? "s" : ""}`,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (unit === "h") {
|
|
117
|
+
if (n > 23) {
|
|
118
|
+
const days = Math.round(n / 24);
|
|
119
|
+
const result = intervalToCron(`${days}d`);
|
|
120
|
+
return {
|
|
121
|
+
...result,
|
|
122
|
+
roundedTo:
|
|
123
|
+
result.roundedTo || (days * 24 !== n ? `${days}d` : undefined),
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (!CLEAN_HOURS.includes(n)) {
|
|
128
|
+
const nearest = getNearestClean(n, CLEAN_HOURS);
|
|
129
|
+
roundedTo = `${nearest}h`;
|
|
130
|
+
n = nearest;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Thundering herd prevention: pick a random minute
|
|
134
|
+
const randomMinute = Math.floor(Math.random() * 60);
|
|
135
|
+
return {
|
|
136
|
+
cron: `${randomMinute} */${n} * * *`,
|
|
137
|
+
roundedTo,
|
|
138
|
+
cadence: `every ${n} hour${n > 1 ? "s" : ""}`,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if (unit === "d") {
|
|
143
|
+
if (![1, 2, 3, 4, 5, 6, 7, 10, 14, 30].includes(n)) {
|
|
144
|
+
// For days, we don't have a strict "clean" list in spec, but let's use some common ones if needed.
|
|
145
|
+
// Actually, cron supports any */N for days.
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Thundering herd prevention: pick a random minute and hour
|
|
149
|
+
const randomMinute = Math.floor(Math.random() * 60);
|
|
150
|
+
const randomHour = Math.floor(Math.random() * 24);
|
|
151
|
+
return {
|
|
152
|
+
cron: `${randomMinute} ${randomHour} */${n} * *`,
|
|
153
|
+
roundedTo,
|
|
154
|
+
cadence: `every ${n} day${n > 1 ? "s" : ""}`,
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
throw new Error(`Unsupported unit: ${unit}`);
|
|
159
|
+
}
|