@slashfi/agents-sdk 0.6.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.
@@ -18,7 +18,7 @@
18
18
  * const registry = createAgentRegistry();
19
19
  * registry.register(createIntegrationsAgent({
20
20
  * store: myIntegrationStore,
21
- * callbackBaseUrl: 'https://myapp.com/integrations/callback',
21
+ * callbackBaseUrl: 'https://myapp.com/oauth/callback',
22
22
  * }));
23
23
  * ```
24
24
  */
@@ -99,7 +99,11 @@ export interface IntegrationApiConfig {
99
99
  export interface ProviderConfig {
100
100
  id: string;
101
101
  name: string;
102
- type: "rest" | "graphql" | "agent-registry";
102
+ /**
103
+ * Agent path that handles this integration type.
104
+ * @integrations dispatches setup/connect/call to that agent's integrationMethods.
105
+ */
106
+ agentPath: string;
103
107
  /**
104
108
  * Scope of the integration:
105
109
  * - 'user': per-user tokens (Slack, Notion, Linear)
@@ -108,7 +112,7 @@ export interface ProviderConfig {
108
112
  scope?: "user" | "tenant";
109
113
  docs?: { llmsTxt?: string; human?: string[] };
110
114
  auth?: IntegrationOAuthConfig;
111
- api: IntegrationApiConfig;
115
+ api?: IntegrationApiConfig;
112
116
  }
113
117
 
114
118
  // ============================================
@@ -131,18 +135,9 @@ export interface GraphqlCallInput {
131
135
  variables?: Record<string, unknown>;
132
136
  }
133
137
 
134
- export interface AgentRegistryCallInput {
135
- provider: string;
136
- type: "agent-registry";
137
- agent: string;
138
- tool: string;
139
- params?: Record<string, unknown>;
140
- }
141
-
142
138
  export type IntegrationCallInput =
143
139
  | RestCallInput
144
- | GraphqlCallInput
145
- | AgentRegistryCallInput;
140
+ | GraphqlCallInput;
146
141
 
147
142
  // ============================================
148
143
  // User Connection (stored token)
@@ -273,6 +268,7 @@ function buildAuthHeaders(
273
268
  config: ProviderConfig,
274
269
  accessToken: string,
275
270
  ): Record<string, string> {
271
+ if (!config.api) return {};
276
272
  const { auth } = config.api;
277
273
  const headerName = auth.headerName ?? "Authorization";
278
274
  const prefix = auth.prefix ?? "Bearer";
@@ -433,7 +429,7 @@ async function executeRestCall(
433
429
  input: RestCallInput,
434
430
  accessToken: string,
435
431
  ): Promise<unknown> {
436
- const url = new URL(input.path, config.api.baseUrl);
432
+ const url = new URL(input.path, config.api?.baseUrl);
437
433
  if (input.query) {
438
434
  for (const [k, v] of Object.entries(input.query)) {
439
435
  url.searchParams.set(k, v);
@@ -442,7 +438,7 @@ async function executeRestCall(
442
438
 
443
439
  const headers: Record<string, string> = {
444
440
  ...buildAuthHeaders(config, accessToken),
445
- ...(config.api.defaultHeaders ?? {}),
441
+ ...(config.api?.defaultHeaders ?? {}),
446
442
  };
447
443
 
448
444
  if (input.body) {
@@ -471,9 +467,10 @@ async function executeGraphqlCall(
471
467
  const headers: Record<string, string> = {
472
468
  "Content-Type": "application/json",
473
469
  ...buildAuthHeaders(config, accessToken),
474
- ...(config.api.defaultHeaders ?? {}),
470
+ ...(config.api?.defaultHeaders ?? {}),
475
471
  };
476
472
 
473
+ if (!config.api?.baseUrl) throw new Error("No baseUrl configured for this provider");
477
474
  const response = await fetch(config.api.baseUrl, {
478
475
  method: "POST",
479
476
  headers,
@@ -500,7 +497,7 @@ export interface IntegrationsAgentOptions {
500
497
 
501
498
  /**
502
499
  * Base URL for OAuth callbacks.
503
- * The callback URL will be: `${callbackBaseUrl}/${providerId}`
500
+ * The OAuth redirect_uri. Provider is encoded in the state param.
504
501
  */
505
502
  callbackBaseUrl?: string;
506
503
  }
@@ -539,10 +536,9 @@ export function createIntegrationsAgent(
539
536
  description: "Provider ID (e.g. 'linear', 'notion')",
540
537
  },
541
538
  name: { type: "string", description: "Display name" },
542
- type: {
539
+ agentPath: {
543
540
  type: "string",
544
- enum: ["rest", "graphql", "agent-registry"],
545
- description: "Integration type",
541
+ description: "Agent path that handles this integration (e.g. '@remote-registry', '@databases'). Omit for simple REST/GraphQL integrations.",
546
542
  },
547
543
  scope: {
548
544
  type: "string",
@@ -647,7 +643,7 @@ export function createIntegrationsAgent(
647
643
  const config: ProviderConfig = {
648
644
  id: input.id,
649
645
  name: input.name,
650
- type: input.type,
646
+ agentPath: input.agentPath,
651
647
  scope: input.scope,
652
648
  docs: input.docs,
653
649
  auth: input.auth,
@@ -696,7 +692,7 @@ export function createIntegrationsAgent(
696
692
  providers: providers.map((p) => ({
697
693
  id: p.id,
698
694
  name: p.name,
699
- type: p.type,
695
+ agentPath: p.agentPath,
700
696
  scope: p.scope ?? "user",
701
697
  hasOAuth: !!p.auth,
702
698
  connected: connections.some((c) => c.providerId === p.id),
@@ -763,7 +759,7 @@ export function createIntegrationsAgent(
763
759
  return { error: "No callbackBaseUrl configured for OAuth flows" };
764
760
 
765
761
  const oauth = config.auth;
766
- const redirectUri = `${callbackBaseUrl}/${config.id}`;
762
+ const redirectUri = callbackBaseUrl;
767
763
  const userId = input.userId ?? ctx.callerId;
768
764
 
769
765
  // Resolve client ID from secret store
@@ -806,7 +802,7 @@ export function createIntegrationsAgent(
806
802
  redirect_uri: redirectUri,
807
803
  response_type: "code",
808
804
  ...(scopeStr ? { scope: scopeStr } : {}),
809
- state: input.state ?? JSON.stringify({ userId, providerId: config.id, redirectUrl: input.redirectUrl ?? "/" }),
805
+ state: input.state ?? btoa(JSON.stringify({ userId, providerId: config.id, redirectUrl: input.redirectUrl ?? "/" })),
810
806
  ...(oauth.authUrlExtraParams ?? {}),
811
807
  });
812
808
 
@@ -831,8 +827,8 @@ export function createIntegrationsAgent(
831
827
  provider: { type: "string", description: "Provider ID" },
832
828
  type: {
833
829
  type: "string",
834
- enum: ["rest", "graphql", "agent-registry"],
835
- description: "Call type",
830
+ enum: ["rest", "graphql"],
831
+ description: "Call type (rest or graphql)",
836
832
  },
837
833
  // REST fields
838
834
  method: {
@@ -924,7 +920,7 @@ export function createIntegrationsAgent(
924
920
  }
925
921
  }
926
922
 
927
- // Execute the call
923
+ // Execute the call based on type
928
924
  switch (input.type) {
929
925
  case "rest":
930
926
  return executeRestCall(
@@ -952,27 +948,8 @@ export function createIntegrationsAgent(
952
948
  accessToken,
953
949
  );
954
950
 
955
- case "agent-registry": {
956
- // For agent-registry, forward the call to the remote agent server
957
- const baseUrl = config.api.baseUrl;
958
- const response = await fetch(`${baseUrl}/call`, {
959
- method: "POST",
960
- headers: {
961
- "Content-Type": "application/json",
962
- ...buildAuthHeaders(config, accessToken),
963
- },
964
- body: JSON.stringify({
965
- action: "execute_tool",
966
- path: input.agent,
967
- tool: input.tool,
968
- params: input.params ?? {},
969
- }),
970
- });
971
- return response.json();
972
- }
973
-
974
951
  default:
975
- return { error: `Unknown integration type: ${input.type}` };
952
+ return { error: `Unknown call type: ${input.type}. Use 'rest' or 'graphql'.` };
976
953
  }
977
954
  },
978
955
  });
@@ -1013,7 +990,7 @@ export function createIntegrationsAgent(
1013
990
  let userId = ctx.callerId;
1014
991
  if (input.state) {
1015
992
  try {
1016
- const parsed = JSON.parse(input.state);
993
+ const parsed = JSON.parse(atob(input.state));
1017
994
  if (parsed.userId) userId = parsed.userId;
1018
995
  } catch {}
1019
996
  }
@@ -1030,7 +1007,7 @@ export function createIntegrationsAgent(
1030
1007
  return { error: "Failed to resolve client credentials." };
1031
1008
  }
1032
1009
 
1033
- const redirectUri = `${callbackBaseUrl}/${config.id}`;
1010
+ const redirectUri = callbackBaseUrl;
1034
1011
  const result = await exchangeCodeForToken(
1035
1012
  config,
1036
1013
  input.code,
@@ -1175,7 +1152,7 @@ export function createIntegrationsAgent(
1175
1152
  });
1176
1153
 
1177
1154
  // Build callback URL from callbackBaseUrl
1178
- const baseUrl = callbackBaseUrl?.replace(/\/integrations\/callback$/, "") ?? "";
1155
+ const baseUrl = callbackBaseUrl?.replace(/\/oauth\/callback$/, "").replace(/\/integrations\/callback$/, "") ?? "";
1179
1156
 
1180
1157
  return {
1181
1158
  url: `${baseUrl}/secrets/form/${token}`,