@slashfi/agents-sdk 0.82.0 → 0.84.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.
@@ -57,11 +57,24 @@ function ensureWrite(path: string, content: string): void {
57
57
  writeFileSync(path, content, "utf-8");
58
58
  }
59
59
 
60
- function toKebabCase(name: string): string {
61
- return name
62
- .replace(/[^a-zA-Z0-9]+/g, "-")
63
- .replace(/^-|-$/g, "")
64
- .toLowerCase();
60
+ /**
61
+ * Sanitize a tool name for use as a filename — strictly conservative.
62
+ * Replaces only characters that would break filesystems (`/`, `\`, NUL)
63
+ * with `_`. Camel case, dashes, underscores, dots, and the actual tool
64
+ * name are preserved verbatim so:
65
+ *
66
+ * - `find ~/.adk/refs/<ref>/tools` shows the canonical tool names
67
+ * (e.g. `listMessages.tool.md`, not `listmessages.tool.md`).
68
+ * - Agents copying a slug from the filename can paste it into
69
+ * `adk ref call <ref> <tool>` without round-tripping through a
70
+ * case-folding step.
71
+ *
72
+ * Registries already mint tool names that are valid identifiers
73
+ * (camelCase, snake_case, kebab-case), so this rarely substitutes
74
+ * anything in practice — it's a safety net for malformed names.
75
+ */
76
+ function toFilenameSlug(name: string): string {
77
+ return name.replace(/[/\\\0]/g, "_");
65
78
  }
66
79
 
67
80
  function pascalCase(s: string): string {
@@ -257,9 +270,12 @@ export async function materializeRef(
257
270
 
258
271
  // Write .tool.md files (primary output — readable by LLMs)
259
272
  for (const tool of tools) {
260
- const safeName = toKebabCase(tool.name);
261
- ensureWrite(join(toolsDir, `${safeName}.tool.md`), generateToolMd(tool));
262
- ensureWrite(join(toolsDir, `${safeName}.tool.json`), JSON.stringify(tool, null, 2));
273
+ const slug = toFilenameSlug(tool.name);
274
+ ensureWrite(join(toolsDir, `${slug}.tool.md`), generateToolMd(tool));
275
+ ensureWrite(
276
+ join(toolsDir, `${slug}.tool.json`),
277
+ JSON.stringify(tool, null, 2),
278
+ );
263
279
  }
264
280
  toolCount = tools.length;
265
281
 
@@ -478,11 +494,20 @@ export function generateRootTypes(
478
494
  lines.push(` T extends _AdkToolsOf<A>,`);
479
495
  lines.push(`> = AdkAgentRegistry[A][T] extends { params: infer P } ? P : Record<string, unknown>;`);
480
496
  lines.push(``);
497
+ // adk.ref.call resolves to a discriminated success/error envelope.
498
+ // Typing this here (instead of as `Promise<unknown>`) lets scripts do
499
+ // `if (res.success) { res.result… }` without casting to `any`. The
500
+ // success.result stays `unknown` since registries don't publish output
501
+ // schemas — narrowing it is the script's responsibility.
502
+ lines.push(`type _AdkCallResult =`);
503
+ lines.push(` | { success: true; result: unknown }`);
504
+ lines.push(` | { success: false; error: string };`);
505
+ lines.push(``);
481
506
  lines.push(`declare const adk: {`);
482
507
  lines.push(` ref: {`);
483
508
  lines.push(` call<A extends _AdkAgentPath, T extends _AdkToolsOf<A>>(`);
484
509
  lines.push(` name: A, tool: T, params: _AdkParamsOf<A, T>`);
485
- lines.push(` ): Promise<unknown>;`);
510
+ lines.push(` ): Promise<_AdkCallResult>;`);
486
511
  lines.push(` };`);
487
512
  lines.push(`};`);
488
513
  lines.push(``);