wave-agent-sdk 0.16.3 → 0.16.5

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/index.d.ts CHANGED
@@ -22,4 +22,6 @@ export * from "./utils/gitUtils.js";
22
22
  export * from "./utils/nameGenerator.js";
23
23
  export * from "./utils/worktreeSession.js";
24
24
  export * from "./types/index.js";
25
+ export * from "./tools/buildTool.js";
26
+ export type { ToolPlugin, ToolResult, ToolContext } from "./tools/types.js";
25
27
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,mBAAmB,CAAC;AAClC,cAAc,2BAA2B,CAAC;AAG1C,cAAc,sBAAsB,CAAC;AAGrC,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC;AACjC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,4BAA4B,CAAC;AAG3C,cAAc,uBAAuB,CAAC;AACtC,cAAc,kCAAkC,CAAC;AACjD,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,iBAAiB,CAAC;AAChC,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,wBAAwB,CAAC;AACvC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,qBAAqB,CAAC;AACpC,cAAc,0BAA0B,CAAC;AACzC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,mBAAmB,CAAC;AAClC,cAAc,2BAA2B,CAAC;AAG1C,cAAc,sBAAsB,CAAC;AAGrC,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC;AACjC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,4BAA4B,CAAC;AAG3C,cAAc,uBAAuB,CAAC;AACtC,cAAc,kCAAkC,CAAC;AACjD,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,iBAAiB,CAAC;AAChC,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,wBAAwB,CAAC;AACvC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,qBAAqB,CAAC;AACpC,cAAc,0BAA0B,CAAC;AACzC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,kBAAkB,CAAC;AAGjC,cAAc,sBAAsB,CAAC;AACrC,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC"}
package/dist/index.js CHANGED
@@ -26,3 +26,5 @@ export * from "./utils/gitUtils.js";
26
26
  export * from "./utils/nameGenerator.js";
27
27
  export * from "./utils/worktreeSession.js";
28
28
  export * from "./types/index.js";
29
+ // Export tool building utilities
30
+ export * from "./tools/buildTool.js";
@@ -10,16 +10,32 @@ export interface McpManagerOptions {
10
10
  logger?: Logger;
11
11
  /** Pre-configured MCP servers passed from constructor options */
12
12
  mcpServers?: Record<string, McpServerConfig>;
13
+ /** Wave server URL for resolving ${WAVE_SERVER_URL} templates in MCP configs */
14
+ serverUrl?: string;
15
+ /** SSO token for resolving ${WAVE_SSO_TOKEN} templates in MCP configs */
16
+ ssoToken?: string;
13
17
  }
18
+ export declare function expandEnvVars(value: string): string;
14
19
  /**
15
- * Expand environment variables in a string value.
16
- * Supports ${VAR} and ${VAR:-default} patterns.
20
+ * Context for resolving Wave-specific MCP template variables.
17
21
  */
18
- export declare function expandEnvVars(value: string): string;
22
+ export interface McpResolverContext {
23
+ serverUrl?: string;
24
+ ssoToken?: string;
25
+ }
26
+ /**
27
+ * Walk a single McpServerConfig and replace Wave template variables.
28
+ * Only replaces ${WAVE_SERVER_URL} and ${WAVE_SSO_TOKEN} — does not touch
29
+ * arbitrary env vars (that is what expandEnvVars handles).
30
+ */
31
+ export declare function resolveMcpTemplates(config: McpServerConfig, ctx: McpResolverContext): McpServerConfig;
19
32
  /**
20
- * Walk an MCP config and expand env vars in all string fields.
33
+ * Walk an MCP config and resolve variables in all string fields.
34
+ * Applies two steps in order:
35
+ * 1. expandEnvVars — resolves ${VAR} from process.env
36
+ * 2. resolveMcpTemplates — resolves ${WAVE_SERVER_URL}, ${WAVE_SSO_TOKEN} from context
21
37
  */
22
- export declare function resolveMcpConfig(config: McpConfig): McpConfig;
38
+ export declare function resolveMcpConfig(config: McpConfig, ctx?: McpResolverContext): McpConfig;
23
39
  export declare class McpManager {
24
40
  private container;
25
41
  private config;
@@ -29,6 +45,7 @@ export declare class McpManager {
29
45
  private workdir;
30
46
  private callbacks;
31
47
  private mcpServers;
48
+ private resolverCtx;
32
49
  constructor(container: Container, options?: McpManagerOptions);
33
50
  /**
34
51
  * Initialize MCP manager with working directory and optionally auto-connect
@@ -1 +1 @@
1
- {"version":3,"file":"mcpManager.d.ts","sourceRoot":"","sources":["../../src/managers/mcpManager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mcpManager.d.ts","sourceRoot":"","sources":["../../src/managers/mcpManager.ts"],"names":[],"mappings":"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"}
@@ -10,20 +10,71 @@ import { logger } from "../utils/globalLogger.js";
10
10
  * Expand environment variables in a string value.
11
11
  * Supports ${VAR} and ${VAR:-default} patterns.
12
12
  */
13
+ const WAVE_TEMPLATE_VARS = ["WAVE_SERVER_URL", "WAVE_SSO_TOKEN"];
13
14
  export function expandEnvVars(value) {
14
15
  return value.replace(/\$\{([^}]+)\}/g, (_match, expr) => {
15
16
  const [varName, ...rest] = expr.split(":-");
16
17
  const defaultValue = rest.join(":-");
18
+ // Skip Wave-specific template variables — they are handled by resolveMcpTemplates
19
+ if (WAVE_TEMPLATE_VARS.includes(varName)) {
20
+ return _match; // return original ${...} string untouched
21
+ }
17
22
  return process.env[varName] ?? defaultValue;
18
23
  });
19
24
  }
20
25
  /**
21
- * Walk an MCP config and expand env vars in all string fields.
26
+ * Walk a single McpServerConfig and replace Wave template variables.
27
+ * Only replaces ${WAVE_SERVER_URL} and ${WAVE_SSO_TOKEN} — does not touch
28
+ * arbitrary env vars (that is what expandEnvVars handles).
29
+ */
30
+ export function resolveMcpTemplates(config, ctx) {
31
+ const resolved = { ...config };
32
+ const replace = (value) => {
33
+ let result = value;
34
+ if (ctx.serverUrl !== undefined) {
35
+ result = result.replace(/\$\{WAVE_SERVER_URL\}/g, ctx.serverUrl);
36
+ }
37
+ if (ctx.ssoToken !== undefined) {
38
+ result = result.replace(/\$\{WAVE_SSO_TOKEN\}/g, ctx.ssoToken);
39
+ }
40
+ return result;
41
+ };
42
+ if (resolved.command) {
43
+ resolved.command = replace(resolved.command);
44
+ }
45
+ if (resolved.args) {
46
+ resolved.args = resolved.args.map(replace);
47
+ }
48
+ if (resolved.env) {
49
+ const resolvedEnv = {};
50
+ for (const [key, val] of Object.entries(resolved.env)) {
51
+ resolvedEnv[key] = replace(val);
52
+ }
53
+ resolved.env = resolvedEnv;
54
+ }
55
+ if (resolved.url) {
56
+ resolved.url = replace(resolved.url);
57
+ }
58
+ if (resolved.headers) {
59
+ const resolvedHeaders = {};
60
+ for (const [key, val] of Object.entries(resolved.headers)) {
61
+ resolvedHeaders[key] = replace(val);
62
+ }
63
+ resolved.headers = resolvedHeaders;
64
+ }
65
+ return resolved;
66
+ }
67
+ /**
68
+ * Walk an MCP config and resolve variables in all string fields.
69
+ * Applies two steps in order:
70
+ * 1. expandEnvVars — resolves ${VAR} from process.env
71
+ * 2. resolveMcpTemplates — resolves ${WAVE_SERVER_URL}, ${WAVE_SSO_TOKEN} from context
22
72
  */
23
- export function resolveMcpConfig(config) {
73
+ export function resolveMcpConfig(config, ctx) {
24
74
  const resolved = { mcpServers: {} };
25
75
  for (const [name, serverConfig] of Object.entries(config.mcpServers)) {
26
- const resolvedServer = { ...serverConfig };
76
+ // Step 1: expand env vars from process.env
77
+ let resolvedServer = { ...serverConfig };
27
78
  if (resolvedServer.command) {
28
79
  resolvedServer.command = expandEnvVars(resolvedServer.command);
29
80
  }
@@ -47,6 +98,10 @@ export function resolveMcpConfig(config) {
47
98
  }
48
99
  resolvedServer.headers = resolvedHeaders;
49
100
  }
101
+ // Step 2: resolve Wave template variables from context
102
+ if (ctx) {
103
+ resolvedServer = resolveMcpTemplates(resolvedServer, ctx);
104
+ }
50
105
  resolved.mcpServers[name] = resolvedServer;
51
106
  }
52
107
  return resolved;
@@ -61,6 +116,10 @@ export class McpManager {
61
116
  this.workdir = "";
62
117
  this.callbacks = options.callbacks || {};
63
118
  this.mcpServers = options.mcpServers;
119
+ this.resolverCtx = {
120
+ serverUrl: options.serverUrl,
121
+ ssoToken: options.ssoToken,
122
+ };
64
123
  }
65
124
  /**
66
125
  * Initialize MCP manager with working directory and optionally auto-connect
@@ -115,7 +174,7 @@ export class McpManager {
115
174
  }
116
175
  try {
117
176
  const configContent = await fs.readFile(this.configPath, "utf-8");
118
- const workspaceConfig = resolveMcpConfig(JSON.parse(configContent));
177
+ const workspaceConfig = resolveMcpConfig(JSON.parse(configContent), this.resolverCtx);
119
178
  // Merge workspace config with any existing config (e.g., from plugins or constructor)
120
179
  // Constructor-provided servers take precedence, then workspace config, then existing config
121
180
  const merged = { mcpServers: {} };
@@ -9,6 +9,8 @@ export interface ToolManagerOptions {
9
9
  container: Container;
10
10
  /** Optional list of tool names to enable */
11
11
  tools?: string[];
12
+ /** Custom tools to register alongside built-in tools */
13
+ customTools?: ToolPlugin[];
12
14
  }
13
15
  /**
14
16
  * Tool Manager
@@ -19,6 +21,7 @@ export interface ToolManagerOptions {
19
21
  declare class ToolManager {
20
22
  private toolsRegistry;
21
23
  private tools?;
24
+ private customTools?;
22
25
  private container;
23
26
  constructor(options: ToolManagerOptions);
24
27
  private get mcpManager();
@@ -1 +1 @@
1
- {"version":3,"file":"toolManager.d.ts","sourceRoot":"","sources":["../../src/managers/toolManager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AA4B7E,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AACjE,OAAO,KAAK,EACV,cAAc,EAGf,MAAM,mBAAmB,CAAC;AAO3B,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAIlD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACxE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAKxD,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,SAAS,CAAC;IACrB,4CAA4C;IAC5C,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;;;;GAKG;AACH,cAAM,WAAW;IACf,OAAO,CAAC,aAAa,CAAiC;IACtD,OAAO,CAAC,KAAK,CAAC,CAAW;IACzB,OAAO,CAAC,SAAS,CAAY;gBAEjB,OAAO,EAAE,kBAAkB;IAKvC,OAAO,KAAK,UAAU,GAErB;IAED;;OAEG;IACI,QAAQ,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI;IAIvC;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACI,sBAAsB,IAAI,IAAI;IAmCrC;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAiBxB;;;;;;;;;;;;OAYG;IACG,OAAO,CACX,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,UAAU,CAAC;IAgJtB,IAAI,IAAI,UAAU,EAAE;IAYpB,cAAc,CAAC,OAAO,CAAC,EAAE;QACvB,kBAAkB,CAAC,EAAE,qBAAqB,EAAE,CAAC;QAC7C,eAAe,CAAC,EAAE,aAAa,EAAE,CAAC;QAClC,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,UAAU,CAAC,EAAE,OAAO,CAAC;QACrB,uEAAuE;QACvE,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;KAC/B,GAAG,0BAA0B,EAAE;IAgEhC;;OAEG;IACI,QAAQ,IAAI,UAAU,EAAE;IAI/B;;OAEG;IACI,iBAAiB,IAAI,cAAc;IAa1C;;;OAGG;IACI,iBAAiB,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI;IAIpD;;OAEG;IACI,oBAAoB,IAAI,iBAAiB,GAAG,SAAS;IAI5D;;OAEG;IACI,oBAAoB,IAAI,MAAM,EAAE;IAcvC;;OAEG;IACI,cAAc,IACjB,OAAO,4BAA4B,EAAE,WAAW,GAChD,SAAS;CAKd;AAGD,OAAO,EAAE,WAAW,EAAE,CAAC"}
1
+ {"version":3,"file":"toolManager.d.ts","sourceRoot":"","sources":["../../src/managers/toolManager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AA4B7E,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AACjE,OAAO,KAAK,EACV,cAAc,EAGf,MAAM,mBAAmB,CAAC;AAO3B,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAIlD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACxE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAKxD,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,SAAS,CAAC;IACrB,4CAA4C;IAC5C,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,wDAAwD;IACxD,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC;CAC5B;AAED;;;;;GAKG;AACH,cAAM,WAAW;IACf,OAAO,CAAC,aAAa,CAAiC;IACtD,OAAO,CAAC,KAAK,CAAC,CAAW;IACzB,OAAO,CAAC,WAAW,CAAC,CAAe;IACnC,OAAO,CAAC,SAAS,CAAY;gBAEjB,OAAO,EAAE,kBAAkB;IAMvC,OAAO,KAAK,UAAU,GAErB;IAED;;OAEG;IACI,QAAQ,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI;IAIvC;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACI,sBAAsB,IAAI,IAAI;IA0CrC;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAiBxB;;;;;;;;;;;;OAYG;IACG,OAAO,CACX,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,UAAU,CAAC;IAgJtB,IAAI,IAAI,UAAU,EAAE;IAYpB,cAAc,CAAC,OAAO,CAAC,EAAE;QACvB,kBAAkB,CAAC,EAAE,qBAAqB,EAAE,CAAC;QAC7C,eAAe,CAAC,EAAE,aAAa,EAAE,CAAC;QAClC,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,UAAU,CAAC,EAAE,OAAO,CAAC;QACrB,uEAAuE;QACvE,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;KAC/B,GAAG,0BAA0B,EAAE;IAgEhC;;OAEG;IACI,QAAQ,IAAI,UAAU,EAAE;IAI/B;;OAEG;IACI,iBAAiB,IAAI,cAAc;IAa1C;;;OAGG;IACI,iBAAiB,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI;IAIpD;;OAEG;IACI,oBAAoB,IAAI,iBAAiB,GAAG,SAAS;IAI5D;;OAEG;IACI,oBAAoB,IAAI,MAAM,EAAE;IAcvC;;OAEG;IACI,cAAc,IACjB,OAAO,4BAA4B,EAAE,WAAW,GAChD,SAAS;CAKd;AAGD,OAAO,EAAE,WAAW,EAAE,CAAC"}
@@ -35,6 +35,7 @@ class ToolManager {
35
35
  this.toolsRegistry = new Map();
36
36
  this.container = options.container;
37
37
  this.tools = options.tools;
38
+ this.customTools = options.customTools;
38
39
  }
39
40
  get mcpManager() {
40
41
  return this.container.get("McpManager");
@@ -100,6 +101,12 @@ class ToolManager {
100
101
  this.toolsRegistry.set(tool.name, tool);
101
102
  }
102
103
  }
104
+ // Register custom tools
105
+ for (const tool of this.customTools || []) {
106
+ if (this.shouldEnableTool(tool.name)) {
107
+ this.toolsRegistry.set(tool.name, tool);
108
+ }
109
+ }
103
110
  }
104
111
  /**
105
112
  * Check if a tool should be enabled based on tools configuration and permission rules
@@ -13,7 +13,7 @@ export declare class AuthService {
13
13
  saveAuth(config: AuthConfig): void;
14
14
  clearAuth(): void;
15
15
  getSSOToken(): string | undefined;
16
- getAiBaseUrl(): string;
16
+ getServerUrl(): string;
17
17
  login(options?: {
18
18
  /** Callback to receive the auth URL (for display in CLI). */
19
19
  onAuthUrl?: (url: string) => void;
@@ -62,22 +62,22 @@ export class AuthService {
62
62
  const config = this.loadAuth();
63
63
  return config.SSO_TOKEN;
64
64
  }
65
- getAiBaseUrl() {
66
- const url = process.env.WAVE_AI_URL;
65
+ getServerUrl() {
66
+ const url = process.env.WAVE_SERVER_URL;
67
67
  if (!url) {
68
- throw new Error("WAVE_AI_URL environment variable is not set. SSO authentication requires this to be configured.");
68
+ throw new Error("WAVE_SERVER_URL environment variable is not set. SSO authentication requires this to be configured.");
69
69
  }
70
70
  return url;
71
71
  }
72
72
  async login(options) {
73
- const aiUrl = this.getAiBaseUrl();
73
+ const serverUrl = this.getServerUrl();
74
74
  // Start local server, open browser, wait for callback or manual input
75
- const { code } = await this.startLocalAuthServer(aiUrl, {
75
+ const { code } = await this.startLocalAuthServer(serverUrl, {
76
76
  onAuthUrl: options?.onAuthUrl,
77
77
  readToken: options?.readToken,
78
78
  });
79
79
  // Exchange authorization code for JWT (includes user info)
80
- const { token, user } = await this.exchangeCode(aiUrl, code);
80
+ const { token, user } = await this.exchangeCode(serverUrl, code);
81
81
  // Save the token and user info (preserve existing keys)
82
82
  const existing = this.loadAuth();
83
83
  this.saveAuth({ ...existing, SSO_TOKEN: token, user });
@@ -87,8 +87,8 @@ export class AuthService {
87
87
  * Exchange a short-lived authorization code for a JWT token.
88
88
  * Returns both the token and user info.
89
89
  */
90
- async exchangeCode(aiUrl, code) {
91
- const exchangeUrl = `${aiUrl}/api/auth/exchange`;
90
+ async exchangeCode(serverUrl, code) {
91
+ const exchangeUrl = `${serverUrl}/api/auth/exchange`;
92
92
  const response = await fetch(exchangeUrl, {
93
93
  method: "POST",
94
94
  headers: { "Content-Type": "application/json" },
@@ -104,7 +104,7 @@ export class AuthService {
104
104
  user: { id: data.user.id, email: data.user.email },
105
105
  };
106
106
  }
107
- startLocalAuthServer(aiUrl, options) {
107
+ startLocalAuthServer(serverUrl, options) {
108
108
  return new Promise((resolve, reject) => {
109
109
  let settled = false;
110
110
  const server = createServer((req, res) => {
@@ -146,7 +146,7 @@ export class AuthService {
146
146
  }
147
147
  const port = address.port;
148
148
  const callbackUrl = `http://127.0.0.1:${port}`;
149
- const authUrl = `${aiUrl}/login?callback_url=${encodeURIComponent(callbackUrl)}`;
149
+ const authUrl = `${serverUrl}/login?callback_url=${encodeURIComponent(callbackUrl)}`;
150
150
  // Notify caller of the auth URL
151
151
  options?.onAuthUrl?.(authUrl);
152
152
  // Try to open browser; if it fails, keep server alive for manual visit
@@ -316,14 +316,14 @@ export class ConfigurationService {
316
316
  * @throws ConfigurationError if required configuration is missing after fallbacks
317
317
  */
318
318
  resolveGatewayConfig(apiKey, baseURL, defaultHeaders, fetchOptions, fetch) {
319
- // Check for SSO token first - if present and AI URL is available, use SSO mode
320
- // AI URL resolution: options > process.env
319
+ // Check for SSO token first - if present and server URL is available, use SSO mode
320
+ // Server URL resolution: options > process.env
321
321
  const ssoToken = this.readSSOToken();
322
- const aiUrl = this.options.aiUrl || process.env.WAVE_AI_URL;
323
- if (ssoToken && aiUrl) {
322
+ const serverUrl = this.options.serverUrl || process.env.WAVE_SERVER_URL;
323
+ if (ssoToken && serverUrl) {
324
324
  return {
325
325
  apiKey: ssoToken,
326
- baseURL: `${aiUrl}/api/v1`,
326
+ baseURL: `${serverUrl}/api/v1`,
327
327
  defaultHeaders: Object.keys(defaultHeaders || {}).length > 0
328
328
  ? defaultHeaders
329
329
  : undefined,
@@ -0,0 +1,22 @@
1
+ import type { ToolPlugin, ToolResult, ToolContext } from "./types.js";
2
+ import type { SubagentConfiguration } from "../utils/subagentParser.js";
3
+ import type { SkillMetadata } from "../types/skills.js";
4
+ export interface ToolDef {
5
+ name: string;
6
+ description: string;
7
+ parameters: Record<string, unknown>;
8
+ required?: string[];
9
+ execute: (args: Record<string, unknown>, context: ToolContext) => Promise<ToolResult>;
10
+ prompt?: string | ((args?: {
11
+ availableSubagents?: SubagentConfiguration[];
12
+ availableSkills?: SkillMetadata[];
13
+ workdir?: string;
14
+ isSubagent?: boolean;
15
+ }) => string);
16
+ formatCompactParams?: (params: Record<string, unknown>, context: ToolContext) => string;
17
+ shouldDefer?: boolean;
18
+ alwaysLoad?: boolean;
19
+ additionalProperties?: boolean;
20
+ }
21
+ export declare function buildTool(def: ToolDef): ToolPlugin;
22
+ //# sourceMappingURL=buildTool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buildTool.d.ts","sourceRoot":"","sources":["../../src/tools/buildTool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEtE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACxE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,OAAO,EAAE,CACP,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,EAAE,WAAW,KACjB,OAAO,CAAC,UAAU,CAAC,CAAC;IACzB,MAAM,CAAC,EACH,MAAM,GACN,CAAC,CAAC,IAAI,CAAC,EAAE;QACP,kBAAkB,CAAC,EAAE,qBAAqB,EAAE,CAAC;QAC7C,eAAe,CAAC,EAAE,aAAa,EAAE,CAAC;QAClC,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,UAAU,CAAC,EAAE,OAAO,CAAC;KACtB,KAAK,MAAM,CAAC,CAAC;IAClB,mBAAmB,CAAC,EAAE,CACpB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,OAAO,EAAE,WAAW,KACjB,MAAM,CAAC;IACZ,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,OAAO,GAAG,UAAU,CAiClD"}
@@ -0,0 +1,33 @@
1
+ export function buildTool(def) {
2
+ const config = {
3
+ type: "function",
4
+ function: {
5
+ name: def.name,
6
+ description: def.description,
7
+ parameters: {
8
+ type: "object",
9
+ properties: def.parameters,
10
+ required: def.required || [],
11
+ additionalProperties: def.additionalProperties ?? false,
12
+ },
13
+ },
14
+ };
15
+ // Normalize prompt: if string, wrap in function
16
+ let promptFn;
17
+ if (typeof def.prompt === "string") {
18
+ const staticPrompt = def.prompt;
19
+ promptFn = () => staticPrompt;
20
+ }
21
+ else {
22
+ promptFn = def.prompt;
23
+ }
24
+ return {
25
+ name: def.name,
26
+ config,
27
+ execute: def.execute,
28
+ prompt: promptFn,
29
+ formatCompactParams: def.formatCompactParams,
30
+ shouldDefer: def.shouldDefer ?? false,
31
+ alwaysLoad: def.alwaysLoad ?? false,
32
+ };
33
+ }
@@ -5,6 +5,7 @@ import type { MessageManagerCallbacks } from "../managers/messageManager.js";
5
5
  import type { BackgroundTaskManagerCallbacks } from "../managers/backgroundTaskManager.js";
6
6
  import type { McpManagerCallbacks } from "../managers/mcpManager.js";
7
7
  import type { SubagentManagerCallbacks } from "../managers/subagentManager.js";
8
+ import type { ToolPlugin } from "../tools/types.js";
8
9
  /**
9
10
  * Configuration options for Agent instances
10
11
  *
@@ -14,8 +15,8 @@ import type { SubagentManagerCallbacks } from "../managers/subagentManager.js";
14
15
  export interface AgentOptions {
15
16
  apiKey?: string;
16
17
  baseURL?: string;
17
- /** Wave AI URL for SSO authentication (fallback to WAVE_AI_URL env var) */
18
- aiUrl?: string;
18
+ /** Wave server URL for SSO authentication (fallback to WAVE_SERVER_URL env var) */
19
+ serverUrl?: string;
19
20
  defaultHeaders?: Record<string, string>;
20
21
  fetchOptions?: ClientOptions["fetchOptions"];
21
22
  fetch?: ClientOptions["fetch"];
@@ -73,6 +74,8 @@ export interface AgentOptions {
73
74
  * Overrides .mcp.json for specified server names.
74
75
  */
75
76
  mcpServers?: Record<string, McpServerConfig>;
77
+ /** Custom tools provided by the SDK user, registered alongside built-in tools */
78
+ customTools?: ToolPlugin[];
76
79
  [key: string]: unknown;
77
80
  }
78
81
  export interface AgentCallbacks extends MessageManagerCallbacks, BackgroundTaskManagerCallbacks, McpManagerCallbacks, SubagentManagerCallbacks {
@@ -1 +1 @@
1
- {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/types/agent.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/types/agent.ts"],"names":[],"mappings":"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"}
@@ -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;AAwB3C,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAM3E,OAAO,KAAK,EAAE,YAAY,EAAmB,MAAM,mBAAmB,CAAC;AACvE,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,CA4QX"}
1
+ {"version":3,"file":"containerSetup.d.ts","sourceRoot":"","sources":["../../src/utils/containerSetup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAwB3C,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAM3E,OAAO,KAAK,EAAE,YAAY,EAAmB,MAAM,mBAAmB,CAAC;AACvE,OAAO,KAAK,EACV,cAAc,EACd,KAAK,EACL,IAAI,EACJ,cAAc,EAEf,MAAM,mBAAmB,CAAC;AAK3B,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,CAiRX"}
@@ -28,6 +28,7 @@ import { AutoMemoryService } from "../services/autoMemoryService.js";
28
28
  import { USER_MEMORY_FILE } from "./constants.js";
29
29
  import { getGitMainRepoRoot } from "./gitUtils.js";
30
30
  import { logger } from "./globalLogger.js";
31
+ import { authService } from "../services/authService.js";
31
32
  export function setupAgentContainer(setupOptions) {
32
33
  const { options, workdir, configurationService, systemPrompt, stream, onBackgroundTasksChange, onTasksChange, onPermissionModeChange, handlePlanModeTransition, setPermissionMode, addPermissionRule, addUsage, } = setupOptions;
33
34
  const callbacks = options.callbacks || {};
@@ -88,9 +89,13 @@ export function setupAgentContainer(setupOptions) {
88
89
  workdir,
89
90
  });
90
91
  container.register("BackgroundTaskManager", backgroundTaskManager);
92
+ const ssoToken = authService.getSSOToken();
93
+ const serverUrl = options.serverUrl || process.env.WAVE_SERVER_URL;
91
94
  const mcpManager = new McpManager(container, {
92
95
  callbacks,
93
96
  mcpServers: options.mcpServers,
97
+ serverUrl,
98
+ ssoToken,
94
99
  });
95
100
  container.register("McpManager", mcpManager);
96
101
  const lspManager = options.lspManager || new LspManager(container);
@@ -175,6 +180,7 @@ export function setupAgentContainer(setupOptions) {
175
180
  const toolManager = new ToolManager({
176
181
  container,
177
182
  tools: options.tools,
183
+ customTools: options.customTools,
178
184
  });
179
185
  container.register("ToolManager", toolManager);
180
186
  container.register("PermissionMode", options.permissionMode);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wave-agent-sdk",
3
- "version": "0.16.3",
3
+ "version": "0.16.5",
4
4
  "description": "SDK for building AI-powered development tools and agents",
5
5
  "keywords": [
6
6
  "ai",
package/src/index.ts CHANGED
@@ -29,3 +29,7 @@ export * from "./utils/gitUtils.js";
29
29
  export * from "./utils/nameGenerator.js";
30
30
  export * from "./utils/worktreeSession.js";
31
31
  export * from "./types/index.js";
32
+
33
+ // Export tool building utilities
34
+ export * from "./tools/buildTool.js";
35
+ export type { ToolPlugin, ToolResult, ToolContext } from "./tools/types.js";
@@ -34,28 +34,106 @@ export interface McpManagerOptions {
34
34
  logger?: Logger;
35
35
  /** Pre-configured MCP servers passed from constructor options */
36
36
  mcpServers?: Record<string, McpServerConfig>;
37
+ /** Wave server URL for resolving ${WAVE_SERVER_URL} templates in MCP configs */
38
+ serverUrl?: string;
39
+ /** SSO token for resolving ${WAVE_SSO_TOKEN} templates in MCP configs */
40
+ ssoToken?: string;
37
41
  }
38
42
 
39
43
  /**
40
44
  * Expand environment variables in a string value.
41
45
  * Supports ${VAR} and ${VAR:-default} patterns.
42
46
  */
47
+ const WAVE_TEMPLATE_VARS = ["WAVE_SERVER_URL", "WAVE_SSO_TOKEN"];
48
+
43
49
  export function expandEnvVars(value: string): string {
44
50
  return value.replace(/\$\{([^}]+)\}/g, (_match, expr: string) => {
45
51
  const [varName, ...rest] = expr.split(":-");
46
52
  const defaultValue = rest.join(":-");
53
+ // Skip Wave-specific template variables — they are handled by resolveMcpTemplates
54
+ if (WAVE_TEMPLATE_VARS.includes(varName)) {
55
+ return _match; // return original ${...} string untouched
56
+ }
47
57
  return process.env[varName] ?? defaultValue;
48
58
  });
49
59
  }
50
60
 
51
61
  /**
52
- * Walk an MCP config and expand env vars in all string fields.
62
+ * Context for resolving Wave-specific MCP template variables.
63
+ */
64
+ export interface McpResolverContext {
65
+ serverUrl?: string; // resolves ${WAVE_SERVER_URL}
66
+ ssoToken?: string; // resolves ${WAVE_SSO_TOKEN}
67
+ }
68
+
69
+ /**
70
+ * Walk a single McpServerConfig and replace Wave template variables.
71
+ * Only replaces ${WAVE_SERVER_URL} and ${WAVE_SSO_TOKEN} — does not touch
72
+ * arbitrary env vars (that is what expandEnvVars handles).
53
73
  */
54
- export function resolveMcpConfig(config: McpConfig): McpConfig {
74
+ export function resolveMcpTemplates(
75
+ config: McpServerConfig,
76
+ ctx: McpResolverContext,
77
+ ): McpServerConfig {
78
+ const resolved: McpServerConfig = { ...config };
79
+
80
+ const replace = (value: string): string => {
81
+ let result = value;
82
+ if (ctx.serverUrl !== undefined) {
83
+ result = result.replace(/\$\{WAVE_SERVER_URL\}/g, ctx.serverUrl);
84
+ }
85
+ if (ctx.ssoToken !== undefined) {
86
+ result = result.replace(/\$\{WAVE_SSO_TOKEN\}/g, ctx.ssoToken);
87
+ }
88
+ return result;
89
+ };
90
+
91
+ if (resolved.command) {
92
+ resolved.command = replace(resolved.command);
93
+ }
94
+
95
+ if (resolved.args) {
96
+ resolved.args = resolved.args.map(replace);
97
+ }
98
+
99
+ if (resolved.env) {
100
+ const resolvedEnv: Record<string, string> = {};
101
+ for (const [key, val] of Object.entries(resolved.env)) {
102
+ resolvedEnv[key] = replace(val);
103
+ }
104
+ resolved.env = resolvedEnv;
105
+ }
106
+
107
+ if (resolved.url) {
108
+ resolved.url = replace(resolved.url);
109
+ }
110
+
111
+ if (resolved.headers) {
112
+ const resolvedHeaders: Record<string, string> = {};
113
+ for (const [key, val] of Object.entries(resolved.headers)) {
114
+ resolvedHeaders[key] = replace(val);
115
+ }
116
+ resolved.headers = resolvedHeaders;
117
+ }
118
+
119
+ return resolved;
120
+ }
121
+
122
+ /**
123
+ * Walk an MCP config and resolve variables in all string fields.
124
+ * Applies two steps in order:
125
+ * 1. expandEnvVars — resolves ${VAR} from process.env
126
+ * 2. resolveMcpTemplates — resolves ${WAVE_SERVER_URL}, ${WAVE_SSO_TOKEN} from context
127
+ */
128
+ export function resolveMcpConfig(
129
+ config: McpConfig,
130
+ ctx?: McpResolverContext,
131
+ ): McpConfig {
55
132
  const resolved: McpConfig = { mcpServers: {} };
56
133
 
57
134
  for (const [name, serverConfig] of Object.entries(config.mcpServers)) {
58
- const resolvedServer: McpServerConfig = { ...serverConfig };
135
+ // Step 1: expand env vars from process.env
136
+ let resolvedServer: McpServerConfig = { ...serverConfig };
59
137
 
60
138
  if (resolvedServer.command) {
61
139
  resolvedServer.command = expandEnvVars(resolvedServer.command);
@@ -85,6 +163,11 @@ export function resolveMcpConfig(config: McpConfig): McpConfig {
85
163
  resolvedServer.headers = resolvedHeaders;
86
164
  }
87
165
 
166
+ // Step 2: resolve Wave template variables from context
167
+ if (ctx) {
168
+ resolvedServer = resolveMcpTemplates(resolvedServer, ctx);
169
+ }
170
+
88
171
  resolved.mcpServers[name] = resolvedServer;
89
172
  }
90
173
 
@@ -100,12 +183,18 @@ export class McpManager {
100
183
  private callbacks: McpManagerCallbacks;
101
184
  private mcpServers: Record<string, McpServerConfig> | undefined;
102
185
 
186
+ private resolverCtx: McpResolverContext | undefined;
187
+
103
188
  constructor(
104
189
  private container: Container,
105
190
  options: McpManagerOptions = {},
106
191
  ) {
107
192
  this.callbacks = options.callbacks || {};
108
193
  this.mcpServers = options.mcpServers;
194
+ this.resolverCtx = {
195
+ serverUrl: options.serverUrl,
196
+ ssoToken: options.ssoToken,
197
+ };
109
198
  }
110
199
 
111
200
  /**
@@ -177,7 +266,10 @@ export class McpManager {
177
266
 
178
267
  try {
179
268
  const configContent = await fs.readFile(this.configPath, "utf-8");
180
- const workspaceConfig = resolveMcpConfig(JSON.parse(configContent));
269
+ const workspaceConfig = resolveMcpConfig(
270
+ JSON.parse(configContent),
271
+ this.resolverCtx,
272
+ );
181
273
 
182
274
  // Merge workspace config with any existing config (e.g., from plugins or constructor)
183
275
  // Constructor-provided servers take precedence, then workspace config, then existing config
@@ -53,6 +53,8 @@ export interface ToolManagerOptions {
53
53
  container: Container;
54
54
  /** Optional list of tool names to enable */
55
55
  tools?: string[];
56
+ /** Custom tools to register alongside built-in tools */
57
+ customTools?: ToolPlugin[];
56
58
  }
57
59
 
58
60
  /**
@@ -64,11 +66,13 @@ export interface ToolManagerOptions {
64
66
  class ToolManager {
65
67
  private toolsRegistry = new Map<string, ToolPlugin>();
66
68
  private tools?: string[];
69
+ private customTools?: ToolPlugin[];
67
70
  private container: Container;
68
71
 
69
72
  constructor(options: ToolManagerOptions) {
70
73
  this.container = options.container;
71
74
  this.tools = options.tools;
75
+ this.customTools = options.customTools;
72
76
  }
73
77
 
74
78
  private get mcpManager(): McpManager {
@@ -138,6 +142,13 @@ class ToolManager {
138
142
  this.toolsRegistry.set(tool.name, tool);
139
143
  }
140
144
  }
145
+
146
+ // Register custom tools
147
+ for (const tool of this.customTools || []) {
148
+ if (this.shouldEnableTool(tool.name)) {
149
+ this.toolsRegistry.set(tool.name, tool);
150
+ }
151
+ }
141
152
  }
142
153
 
143
154
  /**
@@ -79,11 +79,11 @@ export class AuthService {
79
79
  return config.SSO_TOKEN;
80
80
  }
81
81
 
82
- getAiBaseUrl(): string {
83
- const url = process.env.WAVE_AI_URL;
82
+ getServerUrl(): string {
83
+ const url = process.env.WAVE_SERVER_URL;
84
84
  if (!url) {
85
85
  throw new Error(
86
- "WAVE_AI_URL environment variable is not set. SSO authentication requires this to be configured.",
86
+ "WAVE_SERVER_URL environment variable is not set. SSO authentication requires this to be configured.",
87
87
  );
88
88
  }
89
89
  return url;
@@ -95,16 +95,16 @@ export class AuthService {
95
95
  /** Read authorization code manually (e.g. from stdin). Resolves with code or rejects on cancel. */
96
96
  readToken?: () => Promise<string>;
97
97
  }): Promise<string> {
98
- const aiUrl = this.getAiBaseUrl();
98
+ const serverUrl = this.getServerUrl();
99
99
 
100
100
  // Start local server, open browser, wait for callback or manual input
101
- const { code } = await this.startLocalAuthServer(aiUrl, {
101
+ const { code } = await this.startLocalAuthServer(serverUrl, {
102
102
  onAuthUrl: options?.onAuthUrl,
103
103
  readToken: options?.readToken,
104
104
  });
105
105
 
106
106
  // Exchange authorization code for JWT (includes user info)
107
- const { token, user } = await this.exchangeCode(aiUrl, code);
107
+ const { token, user } = await this.exchangeCode(serverUrl, code);
108
108
 
109
109
  // Save the token and user info (preserve existing keys)
110
110
  const existing = this.loadAuth();
@@ -118,10 +118,10 @@ export class AuthService {
118
118
  * Returns both the token and user info.
119
119
  */
120
120
  private async exchangeCode(
121
- aiUrl: string,
121
+ serverUrl: string,
122
122
  code: string,
123
123
  ): Promise<{ token: string; user: AuthUser }> {
124
- const exchangeUrl = `${aiUrl}/api/auth/exchange`;
124
+ const exchangeUrl = `${serverUrl}/api/auth/exchange`;
125
125
  const response = await fetch(exchangeUrl, {
126
126
  method: "POST",
127
127
  headers: { "Content-Type": "application/json" },
@@ -144,7 +144,7 @@ export class AuthService {
144
144
  }
145
145
 
146
146
  private startLocalAuthServer(
147
- aiUrl: string,
147
+ serverUrl: string,
148
148
  options?: {
149
149
  onAuthUrl?: (url: string) => void;
150
150
  readToken?: () => Promise<string>;
@@ -200,7 +200,7 @@ export class AuthService {
200
200
  }
201
201
  const port = address.port;
202
202
  const callbackUrl = `http://127.0.0.1:${port}`;
203
- const authUrl = `${aiUrl}/login?callback_url=${encodeURIComponent(callbackUrl)}`;
203
+ const authUrl = `${serverUrl}/login?callback_url=${encodeURIComponent(callbackUrl)}`;
204
204
 
205
205
  // Notify caller of the auth URL
206
206
  options?.onAuthUrl?.(authUrl);
@@ -408,14 +408,14 @@ export class ConfigurationService {
408
408
  fetchOptions?: ClientOptions["fetchOptions"],
409
409
  fetch?: ClientOptions["fetch"],
410
410
  ): GatewayConfig {
411
- // Check for SSO token first - if present and AI URL is available, use SSO mode
412
- // AI URL resolution: options > process.env
411
+ // Check for SSO token first - if present and server URL is available, use SSO mode
412
+ // Server URL resolution: options > process.env
413
413
  const ssoToken = this.readSSOToken();
414
- const aiUrl = this.options.aiUrl || process.env.WAVE_AI_URL;
415
- if (ssoToken && aiUrl) {
414
+ const serverUrl = this.options.serverUrl || process.env.WAVE_SERVER_URL;
415
+ if (ssoToken && serverUrl) {
416
416
  return {
417
417
  apiKey: ssoToken,
418
- baseURL: `${aiUrl}/api/v1`,
418
+ baseURL: `${serverUrl}/api/v1`,
419
419
  defaultHeaders:
420
420
  Object.keys(defaultHeaders || {}).length > 0
421
421
  ? defaultHeaders
@@ -0,0 +1,65 @@
1
+ import type { ToolPlugin, ToolResult, ToolContext } from "./types.js";
2
+ import { ChatCompletionFunctionTool } from "openai/resources.js";
3
+ import type { SubagentConfiguration } from "../utils/subagentParser.js";
4
+ import type { SkillMetadata } from "../types/skills.js";
5
+
6
+ export interface ToolDef {
7
+ name: string;
8
+ description: string;
9
+ parameters: Record<string, unknown>;
10
+ required?: string[];
11
+ execute: (
12
+ args: Record<string, unknown>,
13
+ context: ToolContext,
14
+ ) => Promise<ToolResult>;
15
+ prompt?:
16
+ | string
17
+ | ((args?: {
18
+ availableSubagents?: SubagentConfiguration[];
19
+ availableSkills?: SkillMetadata[];
20
+ workdir?: string;
21
+ isSubagent?: boolean;
22
+ }) => string);
23
+ formatCompactParams?: (
24
+ params: Record<string, unknown>,
25
+ context: ToolContext,
26
+ ) => string;
27
+ shouldDefer?: boolean;
28
+ alwaysLoad?: boolean;
29
+ additionalProperties?: boolean;
30
+ }
31
+
32
+ export function buildTool(def: ToolDef): ToolPlugin {
33
+ const config: ChatCompletionFunctionTool = {
34
+ type: "function",
35
+ function: {
36
+ name: def.name,
37
+ description: def.description,
38
+ parameters: {
39
+ type: "object",
40
+ properties: def.parameters,
41
+ required: def.required || [],
42
+ additionalProperties: def.additionalProperties ?? false,
43
+ },
44
+ },
45
+ };
46
+
47
+ // Normalize prompt: if string, wrap in function
48
+ let promptFn: ToolPlugin["prompt"];
49
+ if (typeof def.prompt === "string") {
50
+ const staticPrompt = def.prompt;
51
+ promptFn = () => staticPrompt;
52
+ } else {
53
+ promptFn = def.prompt;
54
+ }
55
+
56
+ return {
57
+ name: def.name,
58
+ config,
59
+ execute: def.execute,
60
+ prompt: promptFn,
61
+ formatCompactParams: def.formatCompactParams,
62
+ shouldDefer: def.shouldDefer ?? false,
63
+ alwaysLoad: def.alwaysLoad ?? false,
64
+ };
65
+ }
@@ -14,6 +14,7 @@ import type { MessageManagerCallbacks } from "../managers/messageManager.js";
14
14
  import type { BackgroundTaskManagerCallbacks } from "../managers/backgroundTaskManager.js";
15
15
  import type { McpManagerCallbacks } from "../managers/mcpManager.js";
16
16
  import type { SubagentManagerCallbacks } from "../managers/subagentManager.js";
17
+ import type { ToolPlugin } from "../tools/types.js";
17
18
 
18
19
  /**
19
20
  * Configuration options for Agent instances
@@ -25,8 +26,8 @@ export interface AgentOptions {
25
26
  // Optional configuration with environment fallbacks
26
27
  apiKey?: string;
27
28
  baseURL?: string;
28
- /** Wave AI URL for SSO authentication (fallback to WAVE_AI_URL env var) */
29
- aiUrl?: string;
29
+ /** Wave server URL for SSO authentication (fallback to WAVE_SERVER_URL env var) */
30
+ serverUrl?: string;
30
31
  defaultHeaders?: Record<string, string>;
31
32
  fetchOptions?: ClientOptions["fetchOptions"];
32
33
  fetch?: ClientOptions["fetch"];
@@ -86,6 +87,8 @@ export interface AgentOptions {
86
87
  * Overrides .mcp.json for specified server names.
87
88
  */
88
89
  mcpServers?: Record<string, McpServerConfig>;
90
+ /** Custom tools provided by the SDK user, registered alongside built-in tools */
91
+ customTools?: ToolPlugin[];
89
92
  [key: string]: unknown;
90
93
  }
91
94
 
@@ -38,6 +38,7 @@ import type {
38
38
  } from "../types/index.js";
39
39
 
40
40
  import { logger } from "./globalLogger.js";
41
+ import { authService } from "../services/authService.js";
41
42
 
42
43
  export interface AgentContainerSetupOptions {
43
44
  options: AgentOptions;
@@ -145,11 +146,15 @@ export function setupAgentContainer(
145
146
  });
146
147
  container.register("BackgroundTaskManager", backgroundTaskManager);
147
148
 
149
+ const ssoToken = authService.getSSOToken();
150
+ const serverUrl = options.serverUrl || process.env.WAVE_SERVER_URL;
148
151
  const mcpManager = new McpManager(container, {
149
152
  callbacks,
150
153
  mcpServers: options.mcpServers as
151
154
  | Record<string, McpServerConfig>
152
155
  | undefined,
156
+ serverUrl,
157
+ ssoToken,
153
158
  });
154
159
  container.register("McpManager", mcpManager);
155
160
 
@@ -257,6 +262,7 @@ export function setupAgentContainer(
257
262
  const toolManager = new ToolManager({
258
263
  container,
259
264
  tools: options.tools,
265
+ customTools: options.customTools,
260
266
  });
261
267
  container.register("ToolManager", toolManager);
262
268