@slashfi/agents-sdk 0.76.0 → 0.77.1

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.
Files changed (59) hide show
  1. package/dist/adk-tools.d.ts +2 -2
  2. package/dist/adk-tools.d.ts.map +1 -1
  3. package/dist/adk-tools.js +9 -18
  4. package/dist/adk-tools.js.map +1 -1
  5. package/dist/adk.js +190 -120
  6. package/dist/adk.js.map +1 -1
  7. package/dist/agent-definitions/config.d.ts.map +1 -1
  8. package/dist/agent-definitions/config.js +12 -14
  9. package/dist/agent-definitions/config.js.map +1 -1
  10. package/dist/cjs/adk-tools.js +9 -18
  11. package/dist/cjs/adk-tools.js.map +1 -1
  12. package/dist/cjs/agent-definitions/config.js +12 -14
  13. package/dist/cjs/agent-definitions/config.js.map +1 -1
  14. package/dist/cjs/config-store.js +527 -30
  15. package/dist/cjs/config-store.js.map +1 -1
  16. package/dist/cjs/define-config.js +5 -7
  17. package/dist/cjs/define-config.js.map +1 -1
  18. package/dist/cjs/index.js.map +1 -1
  19. package/dist/cjs/materialize.js +1 -1
  20. package/dist/cjs/materialize.js.map +1 -1
  21. package/dist/cjs/mcp-client.js +98 -0
  22. package/dist/cjs/mcp-client.js.map +1 -1
  23. package/dist/cjs/registry-consumer.js +69 -11
  24. package/dist/cjs/registry-consumer.js.map +1 -1
  25. package/dist/config-store.d.ts +39 -4
  26. package/dist/config-store.d.ts.map +1 -1
  27. package/dist/config-store.js +528 -31
  28. package/dist/config-store.js.map +1 -1
  29. package/dist/define-config.d.ts +65 -18
  30. package/dist/define-config.d.ts.map +1 -1
  31. package/dist/define-config.js +5 -7
  32. package/dist/define-config.js.map +1 -1
  33. package/dist/index.d.ts +1 -1
  34. package/dist/index.d.ts.map +1 -1
  35. package/dist/index.js.map +1 -1
  36. package/dist/materialize.js +1 -1
  37. package/dist/materialize.js.map +1 -1
  38. package/dist/mcp-client.d.ts +44 -0
  39. package/dist/mcp-client.d.ts.map +1 -1
  40. package/dist/mcp-client.js +95 -0
  41. package/dist/mcp-client.js.map +1 -1
  42. package/dist/registry-consumer.d.ts +1 -1
  43. package/dist/registry-consumer.d.ts.map +1 -1
  44. package/dist/registry-consumer.js +69 -11
  45. package/dist/registry-consumer.js.map +1 -1
  46. package/dist/validate.d.ts +8 -8
  47. package/package.json +1 -1
  48. package/src/adk-tools.ts +11 -18
  49. package/src/adk.ts +78 -11
  50. package/src/agent-definitions/config.ts +15 -16
  51. package/src/config-store.test.ts +212 -0
  52. package/src/config-store.ts +615 -37
  53. package/src/consumer.test.ts +7 -7
  54. package/src/define-config.ts +69 -20
  55. package/src/index.ts +1 -0
  56. package/src/materialize.ts +1 -1
  57. package/src/mcp-client.ts +121 -0
  58. package/src/ref-naming.test.ts +115 -90
  59. package/src/registry-consumer.ts +75 -13
@@ -12,7 +12,7 @@
12
12
  *
13
13
  * const config = defineConfig({
14
14
  * registries: ['https://registry.slash.com'],
15
- * refs: ['notion', { ref: 'postgres', as: 'prod-db', config: { url: '...' } }],
15
+ * refs: ['notion', { ref: 'postgres', name: 'prod-db', config: { url: '...' } }],
16
16
  * });
17
17
  *
18
18
  * const consumer = await createRegistryConsumer(config);
@@ -41,6 +41,8 @@ import type {
41
41
  import type { CallAgentRequest } from "./call-agent-schema.js";
42
42
  import type { FetchFn } from "./fetch-types.js";
43
43
  import type { SecuritySchemeSummary, CallAgentResponse } from "./types.js";
44
+ import { AdkError } from "./adk-error.js";
45
+ import { parseWwwAuthenticate } from "./mcp-client.js";
44
46
  import {
45
47
  isSecretUri,
46
48
  normalizeRef,
@@ -391,12 +393,19 @@ async function listFromMcpServer(
391
393
  ...(params && { params }),
392
394
  }),
393
395
  });
396
+ if (res.status === 401) throwRegistryAuthError(serverUrl, res);
394
397
  if (!res.ok) {
395
- throw new Error(`MCP call to ${serverUrl} failed: ${res.status}`);
398
+ const body = await res.text().catch(() => "");
399
+ throwRegistryCallError(serverUrl, res.status, body);
396
400
  }
397
401
  const json = (await res.json()) as { result?: unknown; error?: { message: string } };
398
402
  if (json.error) {
399
- throw new Error(`MCP RPC error: ${json.error.message}`);
403
+ throw new AdkError({
404
+ code: "registry_rpc_error",
405
+ message: `Registry at ${serverUrl} returned an RPC error: ${json.error.message}`,
406
+ hint: "Check the tool name and parameters, or inspect the registry.",
407
+ details: { url: serverUrl, rpcError: json.error.message },
408
+ });
400
409
  }
401
410
  return json.result;
402
411
  }
@@ -466,12 +475,19 @@ async function discoverRegistryViaMcp(
466
475
  ...(params && { params }),
467
476
  }),
468
477
  });
478
+ if (res.status === 401) throwRegistryAuthError(serverUrl, res);
469
479
  if (!res.ok) {
470
- throw new Error(`MCP initialize to ${serverUrl} failed: ${res.status}`);
480
+ const body = await res.text().catch(() => "");
481
+ throwRegistryCallError(serverUrl, res.status, body);
471
482
  }
472
483
  const json = (await res.json()) as { result?: unknown; error?: { message: string } };
473
484
  if (json.error) {
474
- throw new Error(`MCP RPC error: ${json.error.message}`);
485
+ throw new AdkError({
486
+ code: "registry_rpc_error",
487
+ message: `Registry at ${serverUrl} returned an RPC error: ${json.error.message}`,
488
+ hint: "Check the registry URL and that the server speaks MCP.",
489
+ details: { url: serverUrl, rpcError: json.error.message },
490
+ });
475
491
  }
476
492
  return json.result;
477
493
  }
@@ -513,6 +529,45 @@ async function discoverRegistryViaMcp(
513
529
  };
514
530
  }
515
531
 
532
+ /**
533
+ * Throw a typed auth error with context parsed from the challenge. Used when
534
+ * any MCP call returns 401, so callers see a friendly message pointing at
535
+ * `adk registry auth` rather than a bare "MCP call failed: 401".
536
+ */
537
+ function throwRegistryAuthError(
538
+ serverUrl: string,
539
+ res: Response,
540
+ ): never {
541
+ const wwwAuth = res.headers.get("www-authenticate") ?? "";
542
+ const { scheme, params } = parseWwwAuthenticate(wwwAuth);
543
+ throw new AdkError({
544
+ code: "registry_auth_required",
545
+ message: `Registry at ${serverUrl} returned 401 Unauthorized.`,
546
+ hint: `Run: adk registry auth <name> --token <token>`,
547
+ details: {
548
+ url: serverUrl,
549
+ scheme,
550
+ realm: params.realm,
551
+ resourceMetadataUrl: params.resource_metadata,
552
+ status: 401,
553
+ },
554
+ });
555
+ }
556
+
557
+ /** Wrap a generic MCP failure (non-401) in an AdkError so CLI callers get a typed error. */
558
+ function throwRegistryCallError(
559
+ serverUrl: string,
560
+ status: number,
561
+ body: string,
562
+ ): never {
563
+ throw new AdkError({
564
+ code: "registry_call_failed",
565
+ message: `Registry at ${serverUrl} returned ${status}.`,
566
+ hint: "Check the registry URL and that the server is reachable.",
567
+ details: { url: serverUrl, status, body: body.slice(0, 500) },
568
+ });
569
+ }
570
+
516
571
  /**
517
572
  * Call a tool on a direct MCP server.
518
573
  */
@@ -542,12 +597,19 @@ async function callMcpTool(
542
597
  params: { name: toolName, arguments: params },
543
598
  }),
544
599
  });
600
+ if (res.status === 401) throwRegistryAuthError(serverUrl, res);
545
601
  if (!res.ok) {
546
- throw new Error(`MCP tool call failed: ${res.status}`);
602
+ const body = await res.text().catch(() => "");
603
+ throwRegistryCallError(serverUrl, res.status, body);
547
604
  }
548
605
  const json = (await res.json()) as { result?: unknown; error?: { message: string } };
549
606
  if (json.error) {
550
- throw new Error(`MCP RPC error: ${json.error.message}`);
607
+ throw new AdkError({
608
+ code: "registry_rpc_error",
609
+ message: `Registry at ${serverUrl} returned an RPC error: ${json.error.message}`,
610
+ hint: "Check the tool name and parameters, or inspect the registry.",
611
+ details: { url: serverUrl, rpcError: json.error.message },
612
+ });
551
613
  }
552
614
 
553
615
  // Extract text content
@@ -977,19 +1039,19 @@ export async function createRegistryConsumer(
977
1039
  },
978
1040
 
979
1041
  async browse(registryUrl?: string, query?: string): Promise<AgentListEntry[]> {
980
- // List agents from a specific registry, or all registries if not specified
1042
+ // List agents from a specific registry, or all registries if not specified.
1043
+ // Errors from any target propagate — previously allSettled silently
1044
+ // dropped rejections (including 401s), so browsing an unreachable or
1045
+ // unauthenticated registry returned 0 agents with no indication why.
981
1046
  const targets = registryUrl
982
1047
  ? resolvedRegistries.filter(
983
1048
  (r) => r.url === registryUrl || r.name === registryUrl,
984
1049
  )
985
1050
  : resolvedRegistries;
986
- // Pass query to server for BM25 search
987
- const results = await Promise.allSettled(
1051
+ const results = await Promise.all(
988
1052
  targets.map((t) => listFromRegistry(t, query)),
989
1053
  );
990
- return results.flatMap((r) =>
991
- r.status === "fulfilled" ? r.value : [],
992
- );
1054
+ return results.flat();
993
1055
  },
994
1056
 
995
1057
  async inspect(