@mondaydotcomorg/atp-client 0.23.0 → 0.23.2

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.
@@ -1 +1 @@
1
- {"version":3,"file":"explore-api.d.ts","sourceRoot":"","sources":["../../src/tools/explore-api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,EAAa,KAAK,IAAI,EAAE,MAAM,YAAY,CAAC;AAElD,eAAO,MAAM,qBAAqB;;;;;;EAMhC,CAAC;AAEH,KAAK,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAkB7D,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,uBAAuB,GAAG,IAAI,CAAC,eAAe,CAAC,CA+C3F"}
1
+ {"version":3,"file":"explore-api.d.ts","sourceRoot":"","sources":["../../src/tools/explore-api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,EAAa,KAAK,IAAI,EAAE,MAAM,YAAY,CAAC;AAElD,eAAO,MAAM,qBAAqB;;;;;;EAMhC,CAAC;AAEH,KAAK,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAM7D,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,uBAAuB,GAAG,IAAI,CAAC,eAAe,CAAC,CAyB3F"}
@@ -20,33 +20,11 @@ export function createExploreApiTool(client) {
20
20
  const results = await Promise.all(pathsToExplore.map(async (path) => {
21
21
  try {
22
22
  const result = await client.exploreAPI(path);
23
- if (result.type === 'directory') {
24
- return {
25
- success: true,
26
- type: 'directory',
27
- path: result.path,
28
- items: result.items,
29
- };
30
- }
31
- else {
32
- return {
33
- success: true,
34
- type: 'function',
35
- name: result.name,
36
- description: result.description,
37
- definition: result.definition,
38
- group: result.group,
39
- path: result.path,
40
- };
41
- }
23
+ return { success: true, ...result };
42
24
  }
43
25
  catch (error) {
44
26
  const message = error instanceof Error ? error.message : String(error);
45
- return {
46
- success: false,
47
- path,
48
- error: message,
49
- };
27
+ return { success: false, path, error: message };
50
28
  }
51
29
  }));
52
30
  return JSON.stringify(results, null, 2);
@@ -1 +1 @@
1
- {"version":3,"file":"explore-api.js","sourceRoot":"","sources":["../../src/tools/explore-api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAErD,OAAO,EAAE,SAAS,EAAa,MAAM,YAAY,CAAC;AAElD,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC7C,KAAK,EAAE,CAAC;SACN,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;SAC/C,QAAQ,CACR,6GAA6G,CAC7G;CACF,CAAC,CAAC;AAgBH,SAAS,cAAc,CAAC,KAAwB;IAC/C,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,MAA+B;IACnE,OAAO;QACN,IAAI,EAAE,SAAS,CAAC,WAAW;QAC3B,WAAW,EACV,4NAA4N;QAC7N,WAAW,EAAE,eAAe,CAAC,qBAAqB,CAAQ;QAC1D,SAAS,EAAE,qBAAqB;QAChC,IAAI,EAAE,KAAK,EAAE,KAAsB,EAAE,EAAE;YACtC,MAAM,cAAc,GAAG,cAAc,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAEnD,MAAM,OAAO,GAAoB,MAAM,OAAO,CAAC,GAAG,CACjD,cAAc,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;gBACjC,IAAI,CAAC;oBACJ,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;oBAE7C,IAAI,MAAM,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;wBACjC,OAAO;4BACN,OAAO,EAAE,IAAI;4BACb,IAAI,EAAE,WAAoB;4BAC1B,IAAI,EAAE,MAAM,CAAC,IAAI;4BACjB,KAAK,EAAE,MAAM,CAAC,KAAK;yBACnB,CAAC;oBACH,CAAC;yBAAM,CAAC;wBACP,OAAO;4BACN,OAAO,EAAE,IAAI;4BACb,IAAI,EAAE,UAAmB;4BACzB,IAAI,EAAE,MAAM,CAAC,IAAI;4BACjB,WAAW,EAAE,MAAM,CAAC,WAAW;4BAC/B,UAAU,EAAE,MAAM,CAAC,UAAU;4BAC7B,KAAK,EAAE,MAAM,CAAC,KAAK;4BACnB,IAAI,EAAE,MAAM,CAAC,IAAI;yBACjB,CAAC;oBACH,CAAC;gBACF,CAAC;gBAAC,OAAO,KAAc,EAAE,CAAC;oBACzB,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;oBACvE,OAAO;wBACN,OAAO,EAAE,KAAK;wBACd,IAAI;wBACJ,KAAK,EAAE,OAAO;qBACd,CAAC;gBACH,CAAC;YACF,CAAC,CAAC,CACF,CAAC;YAEF,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QACzC,CAAC;KACD,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"explore-api.js","sourceRoot":"","sources":["../../src/tools/explore-api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAErD,OAAO,EAAE,SAAS,EAAa,MAAM,YAAY,CAAC;AAElD,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC7C,KAAK,EAAE,CAAC;SACN,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;SAC/C,QAAQ,CACR,6GAA6G,CAC7G;CACF,CAAC,CAAC;AAIH,SAAS,cAAc,CAAC,KAAwB;IAC/C,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,MAA+B;IACnE,OAAO;QACN,IAAI,EAAE,SAAS,CAAC,WAAW;QAC3B,WAAW,EACV,4NAA4N;QAC7N,WAAW,EAAE,eAAe,CAAC,qBAAqB,CAAQ;QAC1D,SAAS,EAAE,qBAAqB;QAChC,IAAI,EAAE,KAAK,EAAE,KAAsB,EAAE,EAAE;YACtC,MAAM,cAAc,GAAG,cAAc,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAEnD,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAChC,cAAc,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;gBACjC,IAAI,CAAC;oBACJ,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;oBAC7C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,MAAM,EAAE,CAAC;gBACrC,CAAC;gBAAC,OAAO,KAAc,EAAE,CAAC;oBACzB,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;oBACvE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;gBACjD,CAAC;YACF,CAAC,CAAC,CACF,CAAC;YAEF,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QACzC,CAAC;KACD,CAAC;AACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mondaydotcomorg/atp-client",
3
- "version": "0.23.0",
3
+ "version": "0.23.2",
4
4
  "description": "Client SDK for Agent Tool Protocol",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -48,8 +48,8 @@
48
48
  },
49
49
  "license": "MIT",
50
50
  "dependencies": {
51
- "@mondaydotcomorg/atp-protocol": "0.22.0",
52
- "@mondaydotcomorg/atp-runtime": "0.22.0",
51
+ "@mondaydotcomorg/atp-protocol": "0.22.1",
52
+ "@mondaydotcomorg/atp-runtime": "0.22.1",
53
53
  "undici": "*",
54
54
  "zod-to-json-schema": "^3.24.6"
55
55
  },
package/src/client.ts CHANGED
@@ -43,7 +43,6 @@ interface InProcessServer {
43
43
  handleExplore(ctx: unknown): Promise<unknown>;
44
44
  handleExecute(ctx: unknown): Promise<unknown>;
45
45
  handleResume(ctx: unknown, executionId: string): Promise<unknown>;
46
- handleTokenRefresh(ctx: unknown): Promise<unknown>;
47
46
  }
48
47
 
49
48
  /**
@@ -29,6 +29,15 @@ export interface ISession {
29
29
  setTokenRefreshConfig(config: Partial<TokenRefreshConfig>): void;
30
30
  }
31
31
 
32
+ /**
33
+ * Stored init parameters for re-initialization during token refresh.
34
+ */
35
+ export interface StoredInitParams {
36
+ clientInfo?: { name?: string; version?: string; [key: string]: unknown };
37
+ tools?: ClientToolDefinition[];
38
+ services?: { hasLLM: boolean; hasApproval: boolean; hasEmbedding: boolean; hasTools: boolean };
39
+ }
40
+
32
41
  /**
33
42
  * Base session class with shared token management logic.
34
43
  * Subclasses implement the transport-specific operations (HTTP vs in-process).
@@ -40,12 +49,13 @@ export abstract class BaseSession implements ISession {
40
49
  protected tokenRotateAt?: number;
41
50
  protected initPromise?: Promise<void>;
42
51
  protected refreshPromise?: Promise<void>;
52
+ protected storedInitParams?: StoredInitParams;
43
53
  protected tokenRefreshConfig: TokenRefreshConfig = {
44
54
  enabled: true,
45
55
  bufferMs: 1000,
46
56
  };
47
57
 
48
- constructor(tokenRefreshConfig?: Partial<TokenRefreshConfig>) {
58
+ protected constructor(tokenRefreshConfig?: Partial<TokenRefreshConfig>) {
49
59
  if (tokenRefreshConfig) {
50
60
  this.tokenRefreshConfig = { ...this.tokenRefreshConfig, ...tokenRefreshConfig };
51
61
  }
@@ -81,9 +91,25 @@ export abstract class BaseSession implements ISession {
81
91
  abstract prepareHeaders(method: string, url: string, body?: unknown): Promise<Record<string, string>>;
82
92
 
83
93
  /**
84
- * Perform the actual token refresh - must be implemented by subclass
94
+ * Perform token refresh by re-initializing the session.
95
+ * Resets the init guard and calls init() again with the stored params,
96
+ * effectively creating a fresh session without depending on the old
97
+ * session still existing in the server's cache.
85
98
  */
86
- protected abstract doRefreshToken(): Promise<void>;
99
+ protected async doRefreshToken(): Promise<void> {
100
+ if (!this.storedInitParams) {
101
+ throw new Error('Cannot refresh token: init params not stored. Was init() called?');
102
+ }
103
+
104
+ // Reset the init guard so init() runs a fresh handshake
105
+ this.initPromise = undefined;
106
+
107
+ await this.init(
108
+ this.storedInitParams.clientInfo,
109
+ this.storedInitParams.tools,
110
+ this.storedInitParams.services,
111
+ );
112
+ }
87
113
 
88
114
  /**
89
115
  * Gets the unique client ID.
@@ -118,8 +144,8 @@ export abstract class BaseSession implements ISession {
118
144
  * This is called automatically before requests when autoRefresh is enabled.
119
145
  * Uses a shared promise to prevent concurrent refresh requests.
120
146
  *
121
- * Note: Even expired tokens can be refreshed as long as the server session
122
- * still exists. The server accepts expired JWTs for the refresh endpoint.
147
+ * Refresh works by re-initializing the session (calling init() again),
148
+ * so it does not depend on the old session still existing in the server's cache.
123
149
  */
124
150
  async refreshTokenIfNeeded(): Promise<void> {
125
151
  // Skip if auto-refresh is disabled
@@ -163,9 +189,10 @@ export abstract class BaseSession implements ISession {
163
189
  }
164
190
 
165
191
  /**
166
- * Check if URL should skip token refresh (to avoid infinite recursion)
192
+ * Check if URL should skip token refresh (to avoid infinite recursion).
193
+ * Since refresh now calls init(), we only need to guard the init path.
167
194
  */
168
195
  protected shouldSkipRefreshForUrl(url: string): boolean {
169
- return url.includes('/api/token/refresh') || url.includes('/api/init');
196
+ return url.includes('/api/init');
170
197
  }
171
198
  }
@@ -15,7 +15,6 @@ export interface InProcessServer {
15
15
  handleExplore(ctx: InProcessRequestContext): Promise<unknown>;
16
16
  handleExecute(ctx: InProcessRequestContext): Promise<unknown>;
17
17
  handleResume(ctx: InProcessRequestContext, executionId: string): Promise<unknown>;
18
- handleTokenRefresh(ctx: InProcessRequestContext): Promise<unknown>;
19
18
  }
20
19
 
21
20
  /**
@@ -65,6 +64,9 @@ export class InProcessSession extends BaseSession {
65
64
  tools?: ClientToolDefinition[],
66
65
  services?: { hasLLM: boolean; hasApproval: boolean; hasEmbedding: boolean; hasTools: boolean }
67
66
  ): Promise<TokenCredentials> {
67
+ // Store init params so doRefreshToken() can re-init with the same data
68
+ this.storedInitParams = { clientInfo, tools, services };
69
+
68
70
  if (this.initPromise) {
69
71
  await this.initPromise;
70
72
  return {
@@ -133,20 +135,6 @@ export class InProcessSession extends BaseSession {
133
135
  return '';
134
136
  }
135
137
 
136
- /**
137
- * Perform the actual token refresh via in-process server call
138
- */
139
- protected async doRefreshToken(): Promise<void> {
140
- const ctx = await this.createContext({
141
- method: 'POST',
142
- path: '/api/token/refresh',
143
- body: { clientId: this.clientId },
144
- });
145
-
146
- const result = (await this.server.handleTokenRefresh(ctx)) as TokenCredentials;
147
- this.updateTokenState(result);
148
- }
149
-
150
138
  /**
151
139
  * Prepares headers for a request, refreshing token if needed
152
140
  */
@@ -32,6 +32,9 @@ export class ClientSession extends BaseSession {
32
32
  tools?: ClientToolDefinition[],
33
33
  services?: { hasLLM: boolean; hasApproval: boolean; hasEmbedding: boolean; hasTools: boolean }
34
34
  ): Promise<TokenCredentials> {
35
+ // Store init params so doRefreshToken() can re-init with the same data
36
+ this.storedInitParams = { clientInfo, tools, services };
37
+
35
38
  if (this.initPromise) {
36
39
  await this.initPromise;
37
40
  return {
@@ -107,36 +110,6 @@ export class ClientSession extends BaseSession {
107
110
  return this.baseUrl;
108
111
  }
109
112
 
110
- /**
111
- * Perform the actual token refresh via HTTP
112
- */
113
- protected async doRefreshToken(): Promise<void> {
114
- const url = `${this.baseUrl}/api/token/refresh`;
115
- const body = JSON.stringify({ clientId: this.clientId });
116
-
117
- // Use current token for auth, but don't recursively try to refresh
118
- const headers: Record<string, string> = {
119
- 'Content-Type': 'application/json',
120
- ...this.customHeaders,
121
- 'X-Client-ID': this.clientId!,
122
- Authorization: `Bearer ${this.clientToken}`,
123
- };
124
-
125
- const response = await fetch(url, {
126
- method: 'POST',
127
- headers,
128
- body,
129
- });
130
-
131
- if (!response.ok) {
132
- const errorText = await response.text();
133
- throw new Error(`Token refresh failed: ${response.status} ${response.statusText} - ${errorText}`);
134
- }
135
-
136
- const data = (await response.json()) as TokenCredentials;
137
- this.updateTokenState(data);
138
- }
139
-
140
113
  /**
141
114
  * Prepares headers for a request, refreshing token if needed and calling preRequest hook if configured
142
115
  */
@@ -13,18 +13,6 @@ export const exploreApiInputSchema = z.object({
13
13
 
14
14
  type ExploreApiInput = z.infer<typeof exploreApiInputSchema>;
15
15
 
16
- interface ExploreResult {
17
- success: boolean;
18
- path: string;
19
- type?: 'directory' | 'function';
20
- items?: Array<{ name: string; type: string }>;
21
- name?: string;
22
- description?: string;
23
- definition?: unknown;
24
- group?: string;
25
- error?: string;
26
- }
27
-
28
16
  function normalizePaths(paths: string | string[]): string[] {
29
17
  return Array.isArray(paths) ? paths : [paths];
30
18
  }
@@ -39,36 +27,14 @@ export function createExploreApiTool(client: AgentToolProtocolClient): Tool<Expl
39
27
  func: async (input: ExploreApiInput) => {
40
28
  const pathsToExplore = normalizePaths(input.paths);
41
29
 
42
- const results: ExploreResult[] = await Promise.all(
30
+ const results = await Promise.all(
43
31
  pathsToExplore.map(async (path) => {
44
32
  try {
45
33
  const result = await client.exploreAPI(path);
46
-
47
- if (result.type === 'directory') {
48
- return {
49
- success: true,
50
- type: 'directory' as const,
51
- path: result.path,
52
- items: result.items,
53
- };
54
- } else {
55
- return {
56
- success: true,
57
- type: 'function' as const,
58
- name: result.name,
59
- description: result.description,
60
- definition: result.definition,
61
- group: result.group,
62
- path: result.path,
63
- };
64
- }
34
+ return { success: true, ...result };
65
35
  } catch (error: unknown) {
66
36
  const message = error instanceof Error ? error.message : String(error);
67
- return {
68
- success: false,
69
- path,
70
- error: message,
71
- };
37
+ return { success: false, path, error: message };
72
38
  }
73
39
  })
74
40
  );