@slashfi/agents-sdk 0.7.0 → 0.8.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/src/server.ts CHANGED
@@ -14,8 +14,10 @@
14
14
  * - list_agents → List registered agents and their tools
15
15
  *
16
16
  * Additional endpoints:
17
- * - POST /oauth/token → OAuth2 client_credentials (when @auth registered)
18
- * - GET /health Health check
17
+ * - POST /oauth/token → OAuth2 client_credentials (when @auth registered)
18
+ * - GET /oauth/callback Unified OAuth callback (provider from state)
19
+ * - GET /integrations/callback/* → Legacy OAuth callback (provider from URL path)
20
+ * - GET /health → Health check
19
21
  *
20
22
  * Auth Integration:
21
23
  * When an `@auth` agent is registered, the server automatically:
@@ -702,13 +704,8 @@ export function createAgentServer(
702
704
  }
703
705
 
704
706
 
705
- // GET /integrations/callback/:provider - OAuth callback
706
- if (path.startsWith("/integrations/callback/") && req.method === "GET") {
707
- const provider = path.split("/integrations/callback/")[1]?.split("?")[0];
708
- if (!provider) {
709
- return addCors(jsonResponse({ error: "Missing provider" }, 400));
710
- }
711
-
707
+ // ---- Shared OAuth callback handler ----
708
+ async function handleIntegrationOAuthCallback(provider: string, req: Request): Promise<Response> {
712
709
  const url = new URL(req.url);
713
710
  const code = url.searchParams.get("code");
714
711
  const state = url.searchParams.get("state");
@@ -726,7 +723,6 @@ export function createAgentServer(
726
723
  return addCors(jsonResponse({ error: "Missing authorization code" }, 400));
727
724
  }
728
725
 
729
- // Call handle_oauth_callback tool on @integrations
730
726
  try {
731
727
  await registry.call({
732
728
  action: "execute_tool",
@@ -741,13 +737,19 @@ export function createAgentServer(
741
737
  },
742
738
  } as any);
743
739
 
744
- // Parse redirect URL from state
740
+ // Parse redirect URL from state (base64-encoded JSON)
745
741
  let redirectUrl = "/";
746
742
  if (state) {
747
743
  try {
748
- const parsed = JSON.parse(state);
744
+ const parsed = JSON.parse(atob(state));
749
745
  if (parsed.redirectUrl) redirectUrl = parsed.redirectUrl;
750
- } catch {}
746
+ } catch {
747
+ // Fallback: try raw JSON for backward compat
748
+ try {
749
+ const parsed = JSON.parse(state);
750
+ if (parsed.redirectUrl) redirectUrl = parsed.redirectUrl;
751
+ } catch {}
752
+ }
751
753
  }
752
754
 
753
755
  const sep = redirectUrl.includes("?") ? "&" : "?";
@@ -760,6 +762,38 @@ export function createAgentServer(
760
762
  }
761
763
  }
762
764
 
765
+ // GET /oauth/callback - Unified OAuth callback (provider from state param)
766
+ if (path === "/oauth/callback" && req.method === "GET") {
767
+ const url = new URL(req.url);
768
+ const state = url.searchParams.get("state");
769
+ let provider: string | undefined;
770
+ if (state) {
771
+ try {
772
+ const parsed = JSON.parse(atob(state));
773
+ provider = parsed.providerId;
774
+ } catch {
775
+ // Fallback: try raw JSON for backward compat
776
+ try {
777
+ const parsed = JSON.parse(state);
778
+ provider = parsed.providerId;
779
+ } catch {}
780
+ }
781
+ }
782
+ if (!provider) {
783
+ return addCors(jsonResponse({ error: "Missing provider in state param" }, 400));
784
+ }
785
+ return handleIntegrationOAuthCallback(provider, req);
786
+ }
787
+
788
+ // GET /integrations/callback/:provider - Legacy OAuth callback (provider from URL path)
789
+ if (path.startsWith("/integrations/callback/") && req.method === "GET") {
790
+ const provider = path.split("/integrations/callback/")[1]?.split("?")[0];
791
+ if (!provider) {
792
+ return addCors(jsonResponse({ error: "Missing provider" }, 400));
793
+ }
794
+ return handleIntegrationOAuthCallback(provider, req);
795
+ }
796
+
763
797
 
764
798
  // GET /secrets/form/:token - Serve hosted secrets form
765
799
  if (path.startsWith("/secrets/form/") && req.method === "GET") {
package/src/types.ts CHANGED
@@ -421,8 +421,21 @@ export interface ToolDefinition<
421
421
 
422
422
  /**
423
423
  * Execute the tool with validated input.
424
+ * Optional — some registries load tool implementations dynamically.
424
425
  */
425
- execute: (input: TInput, ctx: TContext) => Promise<TOutput>;
426
+ execute?: (input: TInput, ctx: TContext) => Promise<TOutput>;
427
+
428
+ /**
429
+ * Path to the tool source file (e.g., '/agents/@clock/timer.tool.ts').
430
+ * Used for tool discovery and prompt composition.
431
+ */
432
+ path?: string;
433
+
434
+ /**
435
+ * Full documentation content for system prompt composition.
436
+ * When set, rendered directly into the agent's system prompt.
437
+ */
438
+ doc?: string;
426
439
  }
427
440
 
428
441
  /**
@@ -473,6 +486,12 @@ export interface AgentDefinition<TContext extends ToolContext = ToolContext> {
473
486
  * by @integrations via standard methods (setup, list, connect, get, update).
474
487
  */
475
488
  integrationMethods?: IntegrationMethods;
489
+
490
+ /**
491
+ * Lazy loader for lifecycle listeners.
492
+ * Called once to load runtime hooks exported from the agent's entrypoint module.
493
+ */
494
+ loadListeners?: () => Promise<unknown>;
476
495
  }
477
496
 
478
497
  // ============================================