wave-agent-sdk 0.14.2 → 0.14.4
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/builtin/skills/settings/SKILL.md +1 -1
- package/builtin/skills/settings/SKILLS.md +3 -0
- package/builtin/skills/settings/SUBAGENTS.md +21 -2
- package/dist/managers/aiManager.d.ts +3 -0
- package/dist/managers/aiManager.d.ts.map +1 -1
- package/dist/managers/aiManager.js +107 -82
- package/dist/managers/forkedAgentManager.d.ts +1 -0
- package/dist/managers/forkedAgentManager.d.ts.map +1 -1
- package/dist/managers/forkedAgentManager.js +1 -0
- package/dist/managers/pluginManager.d.ts +1 -0
- package/dist/managers/pluginManager.d.ts.map +1 -1
- package/dist/managers/pluginManager.js +7 -0
- package/dist/managers/subagentManager.d.ts +6 -0
- package/dist/managers/subagentManager.d.ts.map +1 -1
- package/dist/managers/subagentManager.js +36 -0
- package/dist/services/autoMemoryService.d.ts.map +1 -1
- package/dist/services/autoMemoryService.js +1 -0
- package/dist/services/pluginLoader.d.ts +5 -0
- package/dist/services/pluginLoader.d.ts.map +1 -1
- package/dist/services/pluginLoader.js +29 -0
- package/dist/types/plugins.d.ts +2 -0
- package/dist/types/plugins.d.ts.map +1 -1
- package/dist/utils/constants.d.ts +2 -2
- package/dist/utils/constants.d.ts.map +1 -1
- package/dist/utils/constants.js +2 -2
- package/dist/utils/convertMessagesForAPI.d.ts.map +1 -1
- package/dist/utils/convertMessagesForAPI.js +27 -8
- package/dist/utils/stringUtils.d.ts +8 -0
- package/dist/utils/stringUtils.d.ts.map +1 -1
- package/dist/utils/stringUtils.js +45 -0
- package/dist/utils/subagentParser.d.ts +8 -1
- package/dist/utils/subagentParser.d.ts.map +1 -1
- package/dist/utils/subagentParser.js +18 -3
- package/package.json +1 -1
- package/src/managers/aiManager.ts +141 -110
- package/src/managers/forkedAgentManager.ts +3 -0
- package/src/managers/pluginManager.ts +10 -0
- package/src/managers/subagentManager.ts +49 -0
- package/src/services/autoMemoryService.ts +1 -0
- package/src/services/pluginLoader.ts +37 -0
- package/src/types/plugins.ts +2 -0
- package/src/utils/constants.ts +2 -2
- package/src/utils/convertMessagesForAPI.ts +31 -9
- package/src/utils/stringUtils.ts +43 -0
- package/src/utils/subagentParser.ts +31 -4
|
@@ -93,7 +93,7 @@ For detailed guidance on creating subagents, see [SUBAGENTS.md](${WAVE_SKILL_DIR
|
|
|
93
93
|
|
|
94
94
|
### 9. Plugins
|
|
95
95
|
|
|
96
|
-
Plugins bundle skills, hooks, MCP servers, LSP servers, and
|
|
96
|
+
Plugins bundle skills, hooks, MCP servers, LSP servers, commands, and subagents into a reusable package. You can install plugins locally or from a marketplace.
|
|
97
97
|
For detailed guidance on creating plugins and marketplaces, see [PLUGINS.md](${WAVE_SKILL_DIR}/PLUGINS.md).
|
|
98
98
|
|
|
99
99
|
### 10. Other Settings
|
|
@@ -42,6 +42,9 @@ When this skill is invoked, follow these steps:
|
|
|
42
42
|
- `allowed-tools`: (Optional) List of tools the skill can use.
|
|
43
43
|
- `context: fork`: (Optional) Run the skill in a separate subagent.
|
|
44
44
|
- `agent`: (Optional) Specify the subagent type (default: `general-purpose`).
|
|
45
|
+
- `disable-model-invocation`: (Optional, default: `false`) Set to `true` to hide the skill from the AI's available skills list. The skill can still be invoked by users via slash commands.
|
|
46
|
+
- `user-invocable`: (Optional, default: `true`) Set to `false` to hide the skill from the `/` slash command menu. The AI can still invoke it unless `disable-model-invocation` is also set.
|
|
47
|
+
- `model`: (Optional) Override the AI model used for skill execution (e.g., `"gpt-4o"`, `"o3-mini"`).
|
|
45
48
|
|
|
46
49
|
## Skill Locations
|
|
47
50
|
|
|
@@ -39,12 +39,31 @@ You are a specialized subagent for a specific task. Your goal is to:
|
|
|
39
39
|
|
|
40
40
|
## Subagent Locations
|
|
41
41
|
|
|
42
|
-
Wave looks for subagents in
|
|
42
|
+
Wave looks for subagents in three locations:
|
|
43
43
|
|
|
44
44
|
1. **User Subagents**: `~/.wave/agents/` (Available in all projects)
|
|
45
45
|
2. **Project Subagents**: `.wave/agents/` (Specific to the current project)
|
|
46
|
+
3. **Plugin Agents**: `agents/` within an installed plugin directory (Scoped to the plugin)
|
|
46
47
|
|
|
47
|
-
Project subagents take precedence over user subagents with the same name.
|
|
48
|
+
Project subagents take precedence over user subagents with the same name. Plugin agents are namespaced with the plugin name (e.g., `pluginName:agentName`) to avoid collisions.
|
|
49
|
+
|
|
50
|
+
## Plugin Agents
|
|
51
|
+
|
|
52
|
+
Plugins can define their own subagents in an `agents/` directory within the plugin. These agents can reference their parent plugin's directory using the `${WAVE_PLUGIN_ROOT}` template variable, which is substituted at load time.
|
|
53
|
+
|
|
54
|
+
For example, a plugin at `/path/to/my-plugin/` with `agents/researcher.md`:
|
|
55
|
+
|
|
56
|
+
```markdown
|
|
57
|
+
---
|
|
58
|
+
name: researcher
|
|
59
|
+
description: A research agent that uses the plugin's knowledge base
|
|
60
|
+
tools: ["Read", "Glob"]
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
You are a research assistant. Access plugin resources at ${WAVE_PLUGIN_ROOT}/data.
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
After loading, `${WAVE_PLUGIN_ROOT}` is replaced with `/path/to/my-plugin/`, and the agent is registered as `my-plugin:researcher`.
|
|
48
67
|
|
|
49
68
|
## Delegating to Subagents
|
|
50
69
|
|
|
@@ -14,6 +14,8 @@ export interface AIManagerOptions {
|
|
|
14
14
|
stream?: boolean;
|
|
15
15
|
/**Optional model override (e.g. for subagents) */
|
|
16
16
|
modelOverride?: string;
|
|
17
|
+
/**Optional max turns limit to prevent runaway recursion (e.g. for auto-memory extraction) */
|
|
18
|
+
maxTurns?: number;
|
|
17
19
|
}
|
|
18
20
|
export declare class AIManager {
|
|
19
21
|
private container;
|
|
@@ -29,6 +31,7 @@ export declare class AIManager {
|
|
|
29
31
|
private modelOverride?;
|
|
30
32
|
private _onCwdChange?;
|
|
31
33
|
private consecutiveCompactionFailures;
|
|
34
|
+
private readonly maxTurns?;
|
|
32
35
|
constructor(container: Container, options: AIManagerOptions);
|
|
33
36
|
private get toolManager();
|
|
34
37
|
private get messageManager();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"aiManager.d.ts","sourceRoot":"","sources":["../../src/managers/aiManager.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACV,aAAa,EACb,WAAW,EACX,KAAK,EAGN,MAAM,mBAAmB,CAAC;AAY3B,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"aiManager.d.ts","sourceRoot":"","sources":["../../src/managers/aiManager.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,6 +5,7 @@ import { parseTaskNotificationXml } from "../utils/notificationXml.js";
|
|
|
5
5
|
import { calculateComprehensiveTotalTokens } from "../utils/tokenCalculation.js";
|
|
6
6
|
import * as fs from "node:fs/promises";
|
|
7
7
|
import { buildSystemPrompt } from "../prompts/index.js";
|
|
8
|
+
import { recoverTruncatedJson } from "../utils/stringUtils.js";
|
|
8
9
|
import { logger } from "../utils/globalLogger.js";
|
|
9
10
|
export class AIManager {
|
|
10
11
|
// Service overrides
|
|
@@ -23,6 +24,7 @@ export class AIManager {
|
|
|
23
24
|
this.callbacks = options.callbacks ?? {};
|
|
24
25
|
this.modelOverride = options.modelOverride;
|
|
25
26
|
this._onCwdChange = options.callbacks?.onCwdChange; // Initialize onCwdChange
|
|
27
|
+
this.maxTurns = options.maxTurns;
|
|
26
28
|
}
|
|
27
29
|
get toolManager() {
|
|
28
30
|
return this.container.get("ToolManager");
|
|
@@ -584,35 +586,45 @@ export class AIManager {
|
|
|
584
586
|
const toolName = functionToolCall.function?.name || "";
|
|
585
587
|
// Safely parse tool parameters, handle tools without parameters
|
|
586
588
|
let toolArgs = {};
|
|
589
|
+
let jsonRecovered = false;
|
|
587
590
|
const argsString = functionToolCall.function?.arguments?.trim();
|
|
588
591
|
if (!argsString || argsString === "") {
|
|
589
592
|
// Tool without parameters, use empty object
|
|
590
593
|
toolArgs = {};
|
|
591
594
|
}
|
|
592
595
|
else {
|
|
596
|
+
let recoveredArgs = argsString;
|
|
593
597
|
try {
|
|
594
598
|
toolArgs = JSON.parse(argsString);
|
|
595
599
|
}
|
|
596
|
-
catch
|
|
597
|
-
//
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
600
|
+
catch {
|
|
601
|
+
// Attempt to recover truncated JSON (e.g., missing closing braces)
|
|
602
|
+
recoveredArgs = recoverTruncatedJson(argsString);
|
|
603
|
+
try {
|
|
604
|
+
toolArgs = JSON.parse(recoveredArgs);
|
|
605
|
+
jsonRecovered = true;
|
|
606
|
+
logger.warn(`Recovered truncated JSON for tool "${toolName}"`);
|
|
607
|
+
}
|
|
608
|
+
catch (parseError) {
|
|
609
|
+
let errorMessage = `Failed to parse tool arguments`;
|
|
610
|
+
if (result.finish_reason === "length") {
|
|
611
|
+
errorMessage +=
|
|
612
|
+
" (output truncated, please reduce your output)";
|
|
613
|
+
}
|
|
614
|
+
logger?.error(errorMessage, parseError);
|
|
615
|
+
this.messageManager.updateToolBlock({
|
|
616
|
+
id: toolId,
|
|
617
|
+
parameters: argsString,
|
|
618
|
+
result: errorMessage,
|
|
619
|
+
success: false,
|
|
620
|
+
error: errorMessage,
|
|
621
|
+
stage: "end",
|
|
622
|
+
name: toolName,
|
|
623
|
+
compactParams: "",
|
|
624
|
+
timestamp: Date.now(),
|
|
625
|
+
});
|
|
626
|
+
return;
|
|
602
627
|
}
|
|
603
|
-
logger?.error(errorMessage, parseError);
|
|
604
|
-
this.messageManager.updateToolBlock({
|
|
605
|
-
id: toolId,
|
|
606
|
-
parameters: argsString,
|
|
607
|
-
result: errorMessage,
|
|
608
|
-
success: false,
|
|
609
|
-
error: errorMessage,
|
|
610
|
-
stage: "end",
|
|
611
|
-
name: toolName,
|
|
612
|
-
compactParams: "",
|
|
613
|
-
timestamp: Date.now(),
|
|
614
|
-
});
|
|
615
|
-
return;
|
|
616
628
|
}
|
|
617
629
|
}
|
|
618
630
|
const compactParams = this.generateCompactParams(toolName, toolArgs);
|
|
@@ -681,12 +693,18 @@ export class AIManager {
|
|
|
681
693
|
};
|
|
682
694
|
// Execute tool
|
|
683
695
|
const toolResult = await this.toolManager.execute(functionToolCall.function?.name || "", toolArgs, context);
|
|
696
|
+
// Build result content, adding truncation warning if JSON was recovered
|
|
697
|
+
let toolResultContent = toolResult.content ||
|
|
698
|
+
(toolResult.error ? `Error: ${toolResult.error}` : "");
|
|
699
|
+
if (jsonRecovered) {
|
|
700
|
+
toolResultContent +=
|
|
701
|
+
"\n\n⚠️ Tool arguments were truncated (likely exceeded max output tokens). Please reduce your output or split into multiple tool calls.";
|
|
702
|
+
}
|
|
684
703
|
// Update message state - tool execution completed
|
|
685
704
|
this.messageManager.updateToolBlock({
|
|
686
705
|
id: toolId,
|
|
687
706
|
parameters: argsString,
|
|
688
|
-
result:
|
|
689
|
-
(toolResult.error ? `Error: ${toolResult.error}` : ""),
|
|
707
|
+
result: toolResultContent,
|
|
690
708
|
success: toolResult.success,
|
|
691
709
|
error: toolResult.error,
|
|
692
710
|
stage: "end",
|
|
@@ -727,75 +745,82 @@ export class AIManager {
|
|
|
727
745
|
this.messageManager.finalizeStreamingBlocks();
|
|
728
746
|
// Check if there are tool operations or response was truncated, if so automatically initiate next AI service call
|
|
729
747
|
if (toolCalls.length > 0 || result.finish_reason === "length") {
|
|
730
|
-
//
|
|
731
|
-
if (this.
|
|
732
|
-
|
|
733
|
-
if (snapshots.length > 0) {
|
|
734
|
-
this.messageManager.addFileHistoryBlock(snapshots);
|
|
735
|
-
}
|
|
748
|
+
// Check maxTurns limit before recursing
|
|
749
|
+
if (this.maxTurns && recursionDepth + 1 >= this.maxTurns) {
|
|
750
|
+
logger?.debug(`Max turns (${this.maxTurns}) reached, stopping recursion.`);
|
|
736
751
|
}
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
if (hasBackgrounded) {
|
|
745
|
-
logger?.info("Some tools were manually backgrounded, stopping recursion.");
|
|
746
|
-
}
|
|
747
|
-
else if (!isCurrentlyAborted) {
|
|
748
|
-
// If response was truncated, add a hidden continuation message
|
|
749
|
-
if (result.finish_reason === "length") {
|
|
750
|
-
this.messageManager.addUserMessage({
|
|
751
|
-
content: "Output token limit hit. Resume directly — no apology, no recap of what you were doing. Pick up mid-thought if that is where the cut happened. Break remaining work into smaller pieces.",
|
|
752
|
-
isMeta: true,
|
|
753
|
-
});
|
|
752
|
+
else {
|
|
753
|
+
// Record committed snapshots to message history
|
|
754
|
+
if (this.reversionManager) {
|
|
755
|
+
const snapshots = this.reversionManager.getAndClearCommittedSnapshots();
|
|
756
|
+
if (snapshots.length > 0) {
|
|
757
|
+
this.messageManager.addFileHistoryBlock(snapshots);
|
|
758
|
+
}
|
|
754
759
|
}
|
|
755
|
-
//
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
760
|
+
// Check interruption status
|
|
761
|
+
const isCurrentlyAborted = abortController.signal.aborted ||
|
|
762
|
+
toolAbortController.signal.aborted;
|
|
763
|
+
// Check if all tools were manually backgrounded
|
|
764
|
+
const lastMessage = this.messageManager.getMessages()[this.messageManager.getMessages().length - 1];
|
|
765
|
+
const toolBlocks = lastMessage?.blocks.filter((block) => block.type === "tool") || [];
|
|
766
|
+
const hasBackgrounded = toolBlocks.length > 0 &&
|
|
767
|
+
toolBlocks.some((block) => block.isManuallyBackgrounded);
|
|
768
|
+
if (hasBackgrounded) {
|
|
769
|
+
logger?.info("Some tools were manually backgrounded, stopping recursion.");
|
|
770
|
+
}
|
|
771
|
+
else if (!isCurrentlyAborted) {
|
|
772
|
+
// If response was truncated, add a hidden continuation message
|
|
773
|
+
if (result.finish_reason === "length") {
|
|
774
|
+
this.messageManager.addUserMessage({
|
|
775
|
+
content: "Output token limit hit. Resume directly — no apology, no recap of what you were doing. Pick up mid-thought if that is where the cut happened. Break remaining work into smaller pieces.",
|
|
776
|
+
isMeta: true,
|
|
777
|
+
});
|
|
768
778
|
}
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
779
|
+
// Duplicate Tool Call Detection
|
|
780
|
+
if (toolCalls.length > 0) {
|
|
781
|
+
const messages = this.messageManager.getMessages();
|
|
782
|
+
// Find the most recent assistant message BEFORE the current one that has tool blocks
|
|
783
|
+
// The current assistant message is messages[messages.length - 1]
|
|
784
|
+
let previousAssistantWithTools;
|
|
785
|
+
for (let i = messages.length - 2; i >= 0; i--) {
|
|
786
|
+
const msg = messages[i];
|
|
787
|
+
if (msg.role === "assistant" &&
|
|
788
|
+
msg.blocks.some((b) => b.type === "tool")) {
|
|
789
|
+
previousAssistantWithTools = msg;
|
|
790
|
+
break;
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
if (previousAssistantWithTools) {
|
|
794
|
+
const previousToolBlocks = previousAssistantWithTools.blocks.filter((b) => b.type === "tool");
|
|
795
|
+
for (const currentToolCall of toolCalls) {
|
|
796
|
+
const currentName = currentToolCall.function?.name;
|
|
797
|
+
const currentArgs = currentToolCall.function?.arguments;
|
|
798
|
+
const isDuplicate = previousToolBlocks.some((prevBlock) => prevBlock.name === currentName &&
|
|
799
|
+
prevBlock.parameters === currentArgs);
|
|
800
|
+
if (isDuplicate && currentName) {
|
|
801
|
+
const toolId = currentToolCall.id;
|
|
802
|
+
const lastMessage = messages[messages.length - 1];
|
|
803
|
+
const toolBlock = lastMessage.blocks.find((b) => b.type === "tool" && b.id === toolId);
|
|
804
|
+
if (toolBlock) {
|
|
805
|
+
const warning = `\n\nNote: You just called this tool with the same arguments in the previous turn. Please ensure you are not in a loop and consider if you need to change your approach.`;
|
|
806
|
+
this.messageManager.updateToolBlock({
|
|
807
|
+
id: toolId,
|
|
808
|
+
result: (toolBlock.result || "") + warning,
|
|
809
|
+
stage: "end",
|
|
810
|
+
});
|
|
811
|
+
}
|
|
787
812
|
}
|
|
788
813
|
}
|
|
789
814
|
}
|
|
790
815
|
}
|
|
816
|
+
// Recursively call AI service, increment recursion depth, and pass same configuration
|
|
817
|
+
await this.sendAIMessage({
|
|
818
|
+
recursionDepth: recursionDepth + 1,
|
|
819
|
+
model,
|
|
820
|
+
allowedRules,
|
|
821
|
+
maxTokens,
|
|
822
|
+
});
|
|
791
823
|
}
|
|
792
|
-
// Recursively call AI service, increment recursion depth, and pass same configuration
|
|
793
|
-
await this.sendAIMessage({
|
|
794
|
-
recursionDepth: recursionDepth + 1,
|
|
795
|
-
model,
|
|
796
|
-
allowedRules,
|
|
797
|
-
maxTokens,
|
|
798
|
-
});
|
|
799
824
|
}
|
|
800
825
|
}
|
|
801
826
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"forkedAgentManager.d.ts","sourceRoot":"","sources":["../../src/managers/forkedAgentManager.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AAEzB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAEjD,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAmB,KAAK,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC9E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAE9D,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC;IAC3B,MAAM,EAAE,SAAS,GAAG,WAAW,GAAG,QAAQ,CAAC;CAC5C;AAED,MAAM,WAAW,2BAA2B;IAC1C,yBAAyB,CAAC,EAAE,CAAC,OAAO,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;CACnE;AAED,qBAAa,kBAAkB;IAK3B,OAAO,CAAC,SAAS;IAJnB,OAAO,CAAC,WAAW,CAAuC;IAC1D,OAAO,CAAC,SAAS,CAA8B;gBAGrC,SAAS,EAAE,SAAS,EAC5B,OAAO,GAAE;QAAE,SAAS,CAAC,EAAE,2BAA2B,CAAA;KAAO;IAK3D,OAAO,KAAK,eAAe,GAE1B;IAED;;;OAGG;IACG,cAAc,CAClB,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,OAAO,EAAE,EACnB,UAAU,EAAE;QACV,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;QACxB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,sBAAsB,CAAC,EAAE,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"forkedAgentManager.d.ts","sourceRoot":"","sources":["../../src/managers/forkedAgentManager.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AAEzB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAEjD,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAmB,KAAK,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC9E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAE9D,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC;IAC3B,MAAM,EAAE,SAAS,GAAG,WAAW,GAAG,QAAQ,CAAC;CAC5C;AAED,MAAM,WAAW,2BAA2B;IAC1C,yBAAyB,CAAC,EAAE,CAAC,OAAO,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;CACnE;AAED,qBAAa,kBAAkB;IAK3B,OAAO,CAAC,SAAS;IAJnB,OAAO,CAAC,WAAW,CAAuC;IAC1D,OAAO,CAAC,SAAS,CAA8B;gBAGrC,SAAS,EAAE,SAAS,EAC5B,OAAO,GAAE;QAAE,SAAS,CAAC,EAAE,2BAA2B,CAAA;KAAO;IAK3D,OAAO,KAAK,eAAe,GAE1B;IAED;;;OAGG;IACG,cAAc,CAClB,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,OAAO,EAAE,EACnB,UAAU,EAAE;QACV,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;QACxB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,sBAAsB,CAAC,EAAE,cAAc,CAAC;QACxC,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,EACD,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,CAAC;YA0BJ,WAAW;IA6EzB;;OAEG;IACH,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAazB;;OAEG;IACH,OAAO,IAAI,IAAI;IASf;;OAEG;IACH,cAAc,IAAI,gBAAgB,EAAE;IAIpC,OAAO,CAAC,YAAY;CAKrB"}
|
|
@@ -48,6 +48,7 @@ export class ForkedAgentManager {
|
|
|
48
48
|
allowedTools: parameters.allowedTools,
|
|
49
49
|
model: parameters.model,
|
|
50
50
|
permissionModeOverride: parameters.permissionModeOverride,
|
|
51
|
+
maxTurns: parameters.maxTurns,
|
|
51
52
|
}, false);
|
|
52
53
|
// Pre-load the message manager with conversation history
|
|
53
54
|
instance.messageManager.setMessages(messages);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pluginManager.d.ts","sourceRoot":"","sources":["../../src/managers/pluginManager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"pluginManager.d.ts","sourceRoot":"","sources":["../../src/managers/pluginManager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAWzD,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAElD,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC1C;AAED,qBAAa,aAAa;IAMtB,OAAO,CAAC,SAAS;IALnB,OAAO,CAAC,OAAO,CAA6B;IAC5C,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,cAAc,CAA0B;gBAGtC,SAAS,EAAE,SAAS,EAC5B,OAAO,EAAE,oBAAoB;IAM/B,OAAO,KAAK,YAAY,GAEvB;IAED,OAAO,KAAK,WAAW,GAEtB;IAED,OAAO,KAAK,UAAU,GAErB;IAED,OAAO,KAAK,UAAU,GAErB;IAED,OAAO,KAAK,mBAAmB,GAE9B;IAED,OAAO,KAAK,oBAAoB,GAE/B;IAED,OAAO,KAAK,eAAe,GAE1B;IAED;;OAEG;IACH,oBAAoB,CAAC,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAInE;;OAEG;YACW,oBAAoB;IA0ElC;;OAEG;YACW,gBAAgB;IAgE9B;;;OAGG;IACG,WAAW,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAmBzD;;OAEG;IACH,UAAU,IAAI,MAAM,EAAE;IAItB;;OAEG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;CAG5C"}
|
|
@@ -27,6 +27,9 @@ export class PluginManager {
|
|
|
27
27
|
get configurationService() {
|
|
28
28
|
return this.container.get("ConfigurationService");
|
|
29
29
|
}
|
|
30
|
+
get subagentManager() {
|
|
31
|
+
return this.container.get("SubagentManager");
|
|
32
|
+
}
|
|
30
33
|
/**
|
|
31
34
|
* Update enabled plugins configuration
|
|
32
35
|
*/
|
|
@@ -106,6 +109,7 @@ export class PluginManager {
|
|
|
106
109
|
path: absolutePath,
|
|
107
110
|
commands: PluginLoader.loadCommands(absolutePath),
|
|
108
111
|
skills: await PluginLoader.loadSkills(absolutePath),
|
|
112
|
+
agents: await PluginLoader.loadAgents(absolutePath),
|
|
109
113
|
lspConfig: await PluginLoader.loadLspConfig(absolutePath),
|
|
110
114
|
mcpConfig: await PluginLoader.loadMcpConfig(absolutePath),
|
|
111
115
|
hooksConfig: await PluginLoader.loadHooksConfig(absolutePath),
|
|
@@ -132,6 +136,9 @@ export class PluginManager {
|
|
|
132
136
|
if (this.hookManager && plugin.hooksConfig) {
|
|
133
137
|
this.hookManager.registerPluginHooks(plugin.path, plugin.hooksConfig);
|
|
134
138
|
}
|
|
139
|
+
if (this.subagentManager && plugin.agents.length > 0) {
|
|
140
|
+
this.subagentManager.registerPluginAgents(plugin.name, plugin.agents);
|
|
141
|
+
}
|
|
135
142
|
this.plugins.set(manifest.name, plugin);
|
|
136
143
|
logger?.info(`Loaded plugin: ${manifest.name} v${manifest.version}`);
|
|
137
144
|
}
|
|
@@ -77,6 +77,11 @@ export declare class SubagentManager {
|
|
|
77
77
|
* Find subagent by exact name match
|
|
78
78
|
*/
|
|
79
79
|
findSubagent(name: string): Promise<SubagentConfiguration | null>;
|
|
80
|
+
/**
|
|
81
|
+
* Register plugin agents into the cached configurations.
|
|
82
|
+
* Names each agent as `pluginName:agentName` to avoid collisions.
|
|
83
|
+
*/
|
|
84
|
+
registerPluginAgents(pluginName: string, agents: SubagentConfiguration[]): void;
|
|
80
85
|
/**
|
|
81
86
|
* Create a new subagent instance with isolated managers
|
|
82
87
|
*/
|
|
@@ -88,6 +93,7 @@ export declare class SubagentManager {
|
|
|
88
93
|
model?: string;
|
|
89
94
|
stream?: boolean;
|
|
90
95
|
permissionModeOverride?: PermissionMode;
|
|
96
|
+
maxTurns?: number;
|
|
91
97
|
}, runInBackground?: boolean, onUpdate?: () => void): Promise<SubagentInstance>;
|
|
92
98
|
/**
|
|
93
99
|
* Execute agent using subagent instance
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"subagentManager.d.ts","sourceRoot":"","sources":["../../src/managers/subagentManager.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"subagentManager.d.ts","sourceRoot":"","sources":["../../src/managers/subagentManager.ts"],"names":[],"mappings":"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"}
|
|
@@ -88,9 +88,44 @@ export class SubagentManager {
|
|
|
88
88
|
* Find subagent by exact name match
|
|
89
89
|
*/
|
|
90
90
|
async findSubagent(name) {
|
|
91
|
+
// Check cached configurations first (includes plugin agents)
|
|
92
|
+
if (this.cachedConfigurations !== null) {
|
|
93
|
+
const cached = this.cachedConfigurations.find((config) => config.name === name);
|
|
94
|
+
if (cached)
|
|
95
|
+
return cached;
|
|
96
|
+
}
|
|
97
|
+
// Fall back to filesystem scan for non-plugin agents
|
|
91
98
|
const { findSubagentByName } = await import("../utils/subagentParser.js");
|
|
92
99
|
return findSubagentByName(name, this.workdir);
|
|
93
100
|
}
|
|
101
|
+
/**
|
|
102
|
+
* Register plugin agents into the cached configurations.
|
|
103
|
+
* Names each agent as `pluginName:agentName` to avoid collisions.
|
|
104
|
+
*/
|
|
105
|
+
registerPluginAgents(pluginName, agents) {
|
|
106
|
+
if (this.cachedConfigurations === null) {
|
|
107
|
+
// Should not happen if initialization order is correct
|
|
108
|
+
this.cachedConfigurations = [];
|
|
109
|
+
}
|
|
110
|
+
// Remove any previously registered agents for this plugin (by name prefix)
|
|
111
|
+
this.cachedConfigurations = this.cachedConfigurations.filter((config) => !config.name.startsWith(`${pluginName}:`));
|
|
112
|
+
for (const agent of agents) {
|
|
113
|
+
const namespacedName = `${pluginName}:${agent.name}`;
|
|
114
|
+
const namespacedAgent = {
|
|
115
|
+
...agent,
|
|
116
|
+
name: namespacedName,
|
|
117
|
+
// Safety net: substitute any remaining ${WAVE_PLUGIN_ROOT} placeholders
|
|
118
|
+
systemPrompt: agent.systemPrompt.replace(/\$\{WAVE_PLUGIN_ROOT\}/g, agent.pluginRoot ?? ""),
|
|
119
|
+
};
|
|
120
|
+
this.cachedConfigurations.push(namespacedAgent);
|
|
121
|
+
}
|
|
122
|
+
// Re-sort by priority then name
|
|
123
|
+
this.cachedConfigurations.sort((a, b) => {
|
|
124
|
+
if (a.priority !== b.priority)
|
|
125
|
+
return a.priority - b.priority;
|
|
126
|
+
return a.name.localeCompare(b.name);
|
|
127
|
+
});
|
|
128
|
+
}
|
|
94
129
|
/**
|
|
95
130
|
* Create a new subagent instance with isolated managers
|
|
96
131
|
*/
|
|
@@ -168,6 +203,7 @@ export class SubagentManager {
|
|
|
168
203
|
subagentType: parameters.subagent_type, // Pass subagent type for hook context
|
|
169
204
|
modelOverride: parameters.model || configuration.model, // Pass model override
|
|
170
205
|
stream: parameters.stream ?? this.stream, // Pass streaming mode flag
|
|
206
|
+
maxTurns: parameters.maxTurns, // Pass maxTurns limit
|
|
171
207
|
callbacks: {
|
|
172
208
|
onUsageAdded: this.onUsageAdded,
|
|
173
209
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"autoMemoryService.d.ts","sourceRoot":"","sources":["../../src/services/autoMemoryService.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAUlD;;;GAGG;AACH,qBAAa,iBAAiB;IAIhB,OAAO,CAAC,SAAS;IAH7B,OAAO,CAAC,mBAAmB,CAAuB;IAClD,OAAO,CAAC,wBAAwB,CAAa;gBAEzB,SAAS,EAAE,SAAS;IAExC,OAAO,KAAK,cAAc,GAEzB;IAED,OAAO,KAAK,kBAAkB,GAE7B;IAED,OAAO,KAAK,aAAa,GAExB;IAED,OAAO,KAAK,oBAAoB,GAE/B;IAED;;OAEG;IACG,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAqE/C;;OAEG;YACW,aAAa;
|
|
1
|
+
{"version":3,"file":"autoMemoryService.d.ts","sourceRoot":"","sources":["../../src/services/autoMemoryService.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAUlD;;;GAGG;AACH,qBAAa,iBAAiB;IAIhB,OAAO,CAAC,SAAS;IAH7B,OAAO,CAAC,mBAAmB,CAAuB;IAClD,OAAO,CAAC,wBAAwB,CAAa;gBAEzB,SAAS,EAAE,SAAS;IAExC,OAAO,KAAK,cAAc,GAEzB;IAED,OAAO,KAAK,kBAAkB,GAE7B;IAED,OAAO,KAAK,aAAa,GAExB;IAED,OAAO,KAAK,oBAAoB,GAE/B;IAED;;OAEG;IACG,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAqE/C;;OAEG;YACW,aAAa;CA4D5B"}
|
|
@@ -128,6 +128,7 @@ export class AutoMemoryService {
|
|
|
128
128
|
],
|
|
129
129
|
model: "fastModel", // Use fast model for background tasks to reduce latency and cost
|
|
130
130
|
permissionModeOverride: "dontAsk", // Auto-deny out-of-scope writes without prompting user
|
|
131
|
+
maxTurns: 5, // Limit turns to prevent verification rabbit-holes
|
|
131
132
|
}, `${prompt}\n\nThe memory directory for this project is: ${memoryDir}`);
|
|
132
133
|
logger.debug("Auto-memory extraction started in background.");
|
|
133
134
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { PluginManifest, CustomSlashCommand, Skill, LspConfig, McpConfig, PartialHookConfiguration } from "../types/index.js";
|
|
2
|
+
import { type SubagentConfiguration } from "../utils/subagentParser.js";
|
|
2
3
|
export declare class PluginLoader {
|
|
3
4
|
/**
|
|
4
5
|
* Load and validate a plugin manifest from a directory
|
|
@@ -27,6 +28,10 @@ export declare class PluginLoader {
|
|
|
27
28
|
* Load hooks configuration from a plugin
|
|
28
29
|
*/
|
|
29
30
|
static loadHooksConfig(pluginPath: string): Promise<PartialHookConfiguration | undefined>;
|
|
31
|
+
/**
|
|
32
|
+
* Load agent configurations from a plugin's agents directory
|
|
33
|
+
*/
|
|
34
|
+
static loadAgents(pluginPath: string): Promise<SubagentConfiguration[]>;
|
|
30
35
|
/**
|
|
31
36
|
* Validate the plugin manifest structure
|
|
32
37
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pluginLoader.d.ts","sourceRoot":"","sources":["../../src/services/pluginLoader.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,KAAK,EACL,SAAS,EACT,SAAS,EACT,wBAAwB,EACzB,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"pluginLoader.d.ts","sourceRoot":"","sources":["../../src/services/pluginLoader.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,KAAK,EACL,SAAS,EACT,SAAS,EACT,wBAAwB,EACzB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAEL,KAAK,qBAAqB,EAC3B,MAAM,4BAA4B,CAAC;AAIpC,qBAAa,YAAY;IACvB;;;OAGG;WACU,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IA6CtE;;;OAGG;IACH,MAAM,CAAC,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,kBAAkB,EAAE;IAK7D;;;OAGG;WACU,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;IAuC7D;;OAEG;WACU,aAAa,CACxB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;IAUjC;;OAEG;WACU,aAAa,CACxB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;IAUjC;;OAEG;WACU,eAAe,CAC1B,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,wBAAwB,GAAG,SAAS,CAAC;IAgBhD;;OAEG;WACU,UAAU,CACrB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,qBAAqB,EAAE,CAAC;IA2BnC;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,gBAAgB;CAgBhC"}
|
|
@@ -2,7 +2,9 @@ import * as fs from "fs/promises";
|
|
|
2
2
|
import * as path from "path";
|
|
3
3
|
import { scanCommandsDirectory } from "../utils/customCommands.js";
|
|
4
4
|
import { parseSkillFile } from "../utils/skillParser.js";
|
|
5
|
+
import { parseAgentFile, } from "../utils/subagentParser.js";
|
|
5
6
|
import { resolveMcpConfig } from "../managers/mcpManager.js";
|
|
7
|
+
import { logger } from "../utils/globalLogger.js";
|
|
6
8
|
export class PluginLoader {
|
|
7
9
|
/**
|
|
8
10
|
* Load and validate a plugin manifest from a directory
|
|
@@ -135,6 +137,33 @@ export class PluginLoader {
|
|
|
135
137
|
return undefined;
|
|
136
138
|
}
|
|
137
139
|
}
|
|
140
|
+
/**
|
|
141
|
+
* Load agent configurations from a plugin's agents directory
|
|
142
|
+
*/
|
|
143
|
+
static async loadAgents(pluginPath) {
|
|
144
|
+
const agentsPath = path.join(pluginPath, "agents");
|
|
145
|
+
const agents = [];
|
|
146
|
+
try {
|
|
147
|
+
const entries = await fs.readdir(agentsPath, { withFileTypes: true });
|
|
148
|
+
for (const entry of entries) {
|
|
149
|
+
if (entry.isFile() && entry.name.endsWith(".md")) {
|
|
150
|
+
const agentFilePath = path.join(agentsPath, entry.name);
|
|
151
|
+
try {
|
|
152
|
+
const config = parseAgentFile(agentFilePath, "plugin", pluginPath);
|
|
153
|
+
agents.push(config);
|
|
154
|
+
}
|
|
155
|
+
catch (parseError) {
|
|
156
|
+
// Log error but continue with other files
|
|
157
|
+
logger?.warn(`Warning: ${parseError instanceof Error ? parseError.message : String(parseError)}`);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
catch {
|
|
163
|
+
// agents directory might not exist
|
|
164
|
+
}
|
|
165
|
+
return agents;
|
|
166
|
+
}
|
|
138
167
|
/**
|
|
139
168
|
* Validate the plugin manifest structure
|
|
140
169
|
*/
|
package/dist/types/plugins.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { Skill } from "./skills.js";
|
|
|
3
3
|
import { LspConfig } from "./lsp.js";
|
|
4
4
|
import { McpConfig } from "./mcp.js";
|
|
5
5
|
import { PartialHookConfiguration } from "./configuration.js";
|
|
6
|
+
import { SubagentConfiguration } from "../utils/subagentParser.js";
|
|
6
7
|
/**
|
|
7
8
|
* Plugin manifest structure (.wave-plugin/plugin.json)
|
|
8
9
|
*/
|
|
@@ -28,6 +29,7 @@ export interface Plugin extends PluginManifest {
|
|
|
28
29
|
path: string;
|
|
29
30
|
commands: CustomSlashCommand[];
|
|
30
31
|
skills: Skill[];
|
|
32
|
+
agents: SubagentConfiguration[];
|
|
31
33
|
lspConfig?: LspConfig;
|
|
32
34
|
mcpConfig?: McpConfig;
|
|
33
35
|
hooksConfig?: PartialHookConfiguration;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugins.d.ts","sourceRoot":"","sources":["../../src/types/plugins.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"plugins.d.ts","sourceRoot":"","sources":["../../src/types/plugins.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAEnE;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE;QACP,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,MAAM,WAAW,MAAO,SAAQ,cAAc;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,kBAAkB,EAAE,CAAC;IAC/B,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,MAAM,EAAE,qBAAqB,EAAE,CAAC;IAChC,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,WAAW,CAAC,EAAE,wBAAwB,CAAC;CACxC"}
|
|
@@ -21,6 +21,6 @@ export declare const USER_MEMORY_FILE: string;
|
|
|
21
21
|
/**
|
|
22
22
|
* AI related constants
|
|
23
23
|
*/
|
|
24
|
-
export declare const DEFAULT_WAVE_MAX_INPUT_TOKENS =
|
|
25
|
-
export declare const DEFAULT_WAVE_MAX_OUTPUT_TOKENS =
|
|
24
|
+
export declare const DEFAULT_WAVE_MAX_INPUT_TOKENS = 128000;
|
|
25
|
+
export declare const DEFAULT_WAVE_MAX_OUTPUT_TOKENS = 16384;
|
|
26
26
|
//# sourceMappingURL=constants.d.ts.map
|