@mondaydotcomorg/atp-client 0.19.6 → 0.19.8

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 (40) hide show
  1. package/README.md +4 -1
  2. package/dist/client.d.ts +23 -2
  3. package/dist/client.d.ts.map +1 -1
  4. package/dist/client.js +26 -5
  5. package/dist/client.js.map +1 -1
  6. package/dist/core/api-operations.d.ts +4 -2
  7. package/dist/core/api-operations.d.ts.map +1 -1
  8. package/dist/core/api-operations.js +25 -1
  9. package/dist/core/api-operations.js.map +1 -1
  10. package/dist/core/execution-operations.d.ts +4 -2
  11. package/dist/core/execution-operations.d.ts.map +1 -1
  12. package/dist/core/execution-operations.js +60 -40
  13. package/dist/core/execution-operations.js.map +1 -1
  14. package/dist/core/in-process-session.d.ts +96 -0
  15. package/dist/core/in-process-session.d.ts.map +1 -0
  16. package/dist/core/in-process-session.js +175 -0
  17. package/dist/core/in-process-session.js.map +1 -0
  18. package/dist/core/index.cjs +1192 -0
  19. package/dist/core/index.cjs.map +1 -0
  20. package/dist/core/index.d.ts +1 -0
  21. package/dist/core/index.d.ts.map +1 -1
  22. package/dist/core/index.js +1181 -5
  23. package/dist/core/index.js.map +1 -1
  24. package/dist/core/session.d.ts +24 -1
  25. package/dist/core/session.d.ts.map +1 -1
  26. package/dist/core/session.js.map +1 -1
  27. package/dist/index.cjs +1589 -0
  28. package/dist/index.cjs.map +1 -0
  29. package/dist/index.d.ts +2 -0
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +1577 -6
  32. package/dist/index.js.map +1 -1
  33. package/package.json +12 -7
  34. package/src/client.ts +51 -7
  35. package/src/core/api-operations.ts +38 -3
  36. package/src/core/execution-operations.ts +73 -45
  37. package/src/core/in-process-session.ts +293 -0
  38. package/src/core/index.ts +1 -0
  39. package/src/core/session.ts +20 -1
  40. package/src/index.ts +2 -0
@@ -1,19 +1,26 @@
1
1
  import type { ExecutionResult, ExecutionConfig } from '@mondaydotcomorg/atp-protocol';
2
2
  import { ExecutionStatus, CallbackType } from '@mondaydotcomorg/atp-protocol';
3
3
  import { log } from '@mondaydotcomorg/atp-runtime';
4
- import type { ClientSession } from './session.js';
4
+ import type { ISession } from './session.js';
5
+ import type { InProcessSession } from './in-process-session.js';
5
6
  import type { ServiceProviders } from './service-providers';
6
7
  import { ClientCallbackError } from '../errors.js';
7
8
  import { ProvenanceTokenRegistry } from './provenance-registry.js';
8
9
 
9
10
  export class ExecutionOperations {
10
- private session: ClientSession;
11
+ private session: ISession;
12
+ private inProcessSession?: InProcessSession;
11
13
  private serviceProviders: ServiceProviders;
12
14
  private tokenRegistry: ProvenanceTokenRegistry;
13
15
  private lastExecutionConfig: Partial<ExecutionConfig> | null = null;
14
16
 
15
- constructor(session: ClientSession, serviceProviders: ServiceProviders) {
17
+ constructor(
18
+ session: ISession,
19
+ serviceProviders: ServiceProviders,
20
+ inProcessSession?: InProcessSession
21
+ ) {
16
22
  this.session = session;
23
+ this.inProcessSession = inProcessSession;
17
24
  this.serviceProviders = serviceProviders;
18
25
  this.tokenRegistry = new ProvenanceTokenRegistry();
19
26
  }
@@ -132,24 +139,30 @@ export class ExecutionOperations {
132
139
 
133
140
  this.lastExecutionConfig = executionConfig;
134
141
 
135
- const url = `${this.session.getBaseUrl()}/api/execute`;
136
- const body = JSON.stringify({ code, config: executionConfig });
137
- const headers = await this.session.prepareHeaders('POST', url, body);
142
+ let result: ExecutionResult;
138
143
 
139
- const response = await fetch(url, {
140
- method: 'POST',
141
- headers,
142
- body,
143
- });
144
+ if (this.inProcessSession) {
145
+ result = (await this.inProcessSession.execute(code, executionConfig)) as ExecutionResult;
146
+ } else {
147
+ const url = `${this.session.getBaseUrl()}/api/execute`;
148
+ const body = JSON.stringify({ code, config: executionConfig });
149
+ const headers = await this.session.prepareHeaders('POST', url, body);
144
150
 
145
- this.session.updateToken(response);
151
+ const response = await fetch(url, {
152
+ method: 'POST',
153
+ headers,
154
+ body,
155
+ });
146
156
 
147
- if (!response.ok) {
148
- const error = (await response.json()) as { error: string };
149
- throw new Error(`Execution failed: ${error.error || response.statusText}`);
150
- }
157
+ this.session.updateToken(response);
151
158
 
152
- const result = (await response.json()) as ExecutionResult;
159
+ if (!response.ok) {
160
+ const error = (await response.json()) as { error: string };
161
+ throw new Error(`Execution failed: ${error.error || response.statusText}`);
162
+ }
163
+
164
+ result = (await response.json()) as ExecutionResult;
165
+ }
153
166
 
154
167
  if (result.provenanceTokens && result.provenanceTokens.length > 0) {
155
168
  for (const { token } of result.provenanceTokens) {
@@ -383,24 +396,30 @@ export class ExecutionOperations {
383
396
  async resume(executionId: string, callbackResult: unknown): Promise<ExecutionResult> {
384
397
  await this.session.ensureInitialized();
385
398
 
386
- const url = `${this.session.getBaseUrl()}/api/resume/${executionId}`;
387
- const body = JSON.stringify({ result: callbackResult });
388
- const headers = await this.session.prepareHeaders('POST', url, body);
399
+ let result: ExecutionResult;
389
400
 
390
- const response = await fetch(url, {
391
- method: 'POST',
392
- headers,
393
- body,
394
- });
401
+ if (this.inProcessSession) {
402
+ result = (await this.inProcessSession.resume(executionId, callbackResult)) as ExecutionResult;
403
+ } else {
404
+ const url = `${this.session.getBaseUrl()}/api/resume/${executionId}`;
405
+ const body = JSON.stringify({ result: callbackResult });
406
+ const headers = await this.session.prepareHeaders('POST', url, body);
407
+
408
+ const response = await fetch(url, {
409
+ method: 'POST',
410
+ headers,
411
+ body,
412
+ });
395
413
 
396
- this.session.updateToken(response);
414
+ this.session.updateToken(response);
397
415
 
398
- if (!response.ok) {
399
- const error = (await response.json()) as { error: string };
400
- throw new Error(`Resume failed: ${error.error || response.statusText}`);
401
- }
416
+ if (!response.ok) {
417
+ const error = (await response.json()) as { error: string };
418
+ throw new Error(`Resume failed: ${error.error || response.statusText}`);
419
+ }
402
420
 
403
- const result = (await response.json()) as ExecutionResult;
421
+ result = (await response.json()) as ExecutionResult;
422
+ }
404
423
 
405
424
  if (result.provenanceTokens && result.provenanceTokens.length > 0) {
406
425
  for (const { token } of result.provenanceTokens) {
@@ -428,24 +447,33 @@ export class ExecutionOperations {
428
447
  ): Promise<ExecutionResult> {
429
448
  await this.session.ensureInitialized();
430
449
 
431
- const url = `${this.session.getBaseUrl()}/api/resume/${executionId}`;
432
- const body = JSON.stringify({ results: batchResults });
433
- const headers = await this.session.prepareHeaders('POST', url, body);
450
+ let result: ExecutionResult;
434
451
 
435
- const response = await fetch(url, {
436
- method: 'POST',
437
- headers,
438
- body,
439
- });
452
+ if (this.inProcessSession) {
453
+ result = (await this.inProcessSession.resumeWithBatchResults(
454
+ executionId,
455
+ batchResults
456
+ )) as ExecutionResult;
457
+ } else {
458
+ const url = `${this.session.getBaseUrl()}/api/resume/${executionId}`;
459
+ const body = JSON.stringify({ results: batchResults });
460
+ const headers = await this.session.prepareHeaders('POST', url, body);
440
461
 
441
- this.session.updateToken(response);
462
+ const response = await fetch(url, {
463
+ method: 'POST',
464
+ headers,
465
+ body,
466
+ });
442
467
 
443
- if (!response.ok) {
444
- const error = (await response.json()) as { error: string };
445
- throw new Error(`Batch resume failed: ${error.error || response.statusText}`);
446
- }
468
+ this.session.updateToken(response);
447
469
 
448
- const result = (await response.json()) as ExecutionResult;
470
+ if (!response.ok) {
471
+ const error = (await response.json()) as { error: string };
472
+ throw new Error(`Batch resume failed: ${error.error || response.statusText}`);
473
+ }
474
+
475
+ result = (await response.json()) as ExecutionResult;
476
+ }
449
477
 
450
478
  if (result.provenanceTokens && result.provenanceTokens.length > 0) {
451
479
  for (const { token } of result.provenanceTokens) {
@@ -0,0 +1,293 @@
1
+ import type { ClientToolDefinition } from '@mondaydotcomorg/atp-protocol';
2
+ import type { ISession } from './session.js';
3
+
4
+ interface InProcessServer {
5
+ start(): Promise<void>;
6
+ handleInit(ctx: InProcessRequestContext): Promise<unknown>;
7
+ getDefinitions(ctx?: InProcessRequestContext): Promise<unknown>;
8
+ getRuntimeDefinitions(ctx?: InProcessRequestContext): Promise<string>;
9
+ getInfo(): unknown;
10
+ handleSearch(ctx: InProcessRequestContext): Promise<unknown>;
11
+ handleExplore(ctx: InProcessRequestContext): Promise<unknown>;
12
+ handleExecute(ctx: InProcessRequestContext): Promise<unknown>;
13
+ handleResume(ctx: InProcessRequestContext, executionId: string): Promise<unknown>;
14
+ }
15
+
16
+ interface InProcessRequestContext {
17
+ method: string;
18
+ path: string;
19
+ query: Record<string, string>;
20
+ headers: Record<string, string>;
21
+ body: unknown;
22
+ clientId?: string;
23
+ clientToken?: string;
24
+ userId?: string;
25
+ user?: unknown;
26
+ executionId?: string;
27
+ code?: string;
28
+ validation?: unknown;
29
+ result?: unknown;
30
+ error?: Error;
31
+ logger: { debug: () => void; info: () => void; warn: () => void; error: () => void };
32
+ status: number;
33
+ responseBody: unknown;
34
+ throw(status: number, message: string): never;
35
+ assert(condition: boolean, message: string): asserts condition;
36
+ set(header: string, value: string): void;
37
+ }
38
+
39
+ export class InProcessSession implements ISession {
40
+ private server: InProcessServer;
41
+ private clientId?: string;
42
+ private clientToken?: string;
43
+ private initialized: boolean = false;
44
+ private initPromise?: Promise<void>;
45
+
46
+ constructor(server: InProcessServer) {
47
+ this.server = server;
48
+ }
49
+
50
+ async init(
51
+ clientInfo?: { name?: string; version?: string; [key: string]: unknown },
52
+ tools?: ClientToolDefinition[],
53
+ services?: { hasLLM: boolean; hasApproval: boolean; hasEmbedding: boolean; hasTools: boolean }
54
+ ): Promise<{
55
+ clientId: string;
56
+ token: string;
57
+ expiresAt: number;
58
+ tokenRotateAt: number;
59
+ }> {
60
+ if (this.initPromise) {
61
+ await this.initPromise;
62
+ return {
63
+ clientId: this.clientId!,
64
+ token: this.clientToken!,
65
+ expiresAt: 0,
66
+ tokenRotateAt: 0,
67
+ };
68
+ }
69
+
70
+ this.initPromise = (async () => {
71
+ await this.server.start();
72
+
73
+ const ctx = this.createContext({
74
+ method: 'POST',
75
+ path: '/api/init',
76
+ body: {
77
+ clientInfo,
78
+ tools: tools || [],
79
+ services,
80
+ },
81
+ });
82
+
83
+ const result = (await this.server.handleInit(ctx)) as {
84
+ clientId: string;
85
+ token: string;
86
+ expiresAt: number;
87
+ tokenRotateAt: number;
88
+ };
89
+
90
+ this.clientId = result.clientId;
91
+ this.clientToken = result.token;
92
+ this.initialized = true;
93
+ })();
94
+
95
+ await this.initPromise;
96
+
97
+ return {
98
+ clientId: this.clientId!,
99
+ token: this.clientToken!,
100
+ expiresAt: 0,
101
+ tokenRotateAt: 0,
102
+ };
103
+ }
104
+
105
+ getClientId(): string {
106
+ if (!this.clientId) {
107
+ throw new Error('Client not initialized. Call init() first.');
108
+ }
109
+ return this.clientId;
110
+ }
111
+
112
+ async ensureInitialized(): Promise<void> {
113
+ if (!this.initialized) {
114
+ throw new Error('Client not initialized. Call init() first.');
115
+ }
116
+ }
117
+
118
+ getHeaders(): Record<string, string> {
119
+ const headers: Record<string, string> = {
120
+ 'content-type': 'application/json',
121
+ };
122
+
123
+ if (this.clientId) {
124
+ headers['x-client-id'] = this.clientId;
125
+ }
126
+
127
+ if (this.clientToken) {
128
+ headers['authorization'] = `Bearer ${this.clientToken}`;
129
+ }
130
+
131
+ return headers;
132
+ }
133
+
134
+ getBaseUrl(): string {
135
+ return '';
136
+ }
137
+
138
+ updateToken(_response: Response): void {
139
+ // No-op for in-process - tokens are managed directly
140
+ }
141
+
142
+ async prepareHeaders(
143
+ _method: string,
144
+ _url: string,
145
+ _body?: unknown
146
+ ): Promise<Record<string, string>> {
147
+ return this.getHeaders();
148
+ }
149
+
150
+ async getDefinitions(options?: { apiGroups?: string[] }): Promise<{
151
+ typescript: string;
152
+ version: string;
153
+ apiGroups: string[];
154
+ }> {
155
+ await this.ensureInitialized();
156
+
157
+ const ctx = this.createContext({
158
+ method: 'GET',
159
+ path: '/api/definitions',
160
+ query: options?.apiGroups ? { apiGroups: options.apiGroups.join(',') } : {},
161
+ });
162
+
163
+ return (await this.server.getDefinitions(ctx)) as {
164
+ typescript: string;
165
+ version: string;
166
+ apiGroups: string[];
167
+ };
168
+ }
169
+
170
+ async getRuntimeDefinitions(options?: { apis?: string[] }): Promise<string> {
171
+ await this.ensureInitialized();
172
+
173
+ const ctx = this.createContext({
174
+ method: 'GET',
175
+ path: '/api/runtime',
176
+ query: options?.apis?.length ? { apis: options.apis.join(',') } : {},
177
+ });
178
+
179
+ return await this.server.getRuntimeDefinitions(ctx);
180
+ }
181
+
182
+ async getServerInfo(): Promise<{
183
+ version: string;
184
+ capabilities: Record<string, boolean>;
185
+ }> {
186
+ await this.ensureInitialized();
187
+ return this.server.getInfo() as {
188
+ version: string;
189
+ capabilities: Record<string, boolean>;
190
+ };
191
+ }
192
+
193
+ async search(query: string, options?: Record<string, unknown>): Promise<{ results: unknown[] }> {
194
+ await this.ensureInitialized();
195
+
196
+ const ctx = this.createContext({
197
+ method: 'POST',
198
+ path: '/api/search',
199
+ body: { query, ...options },
200
+ });
201
+
202
+ return (await this.server.handleSearch(ctx)) as { results: unknown[] };
203
+ }
204
+
205
+ async explore(path: string): Promise<unknown> {
206
+ await this.ensureInitialized();
207
+
208
+ const ctx = this.createContext({
209
+ method: 'POST',
210
+ path: '/api/explore',
211
+ body: { path },
212
+ });
213
+
214
+ return await this.server.handleExplore(ctx);
215
+ }
216
+
217
+ async execute(code: string, config?: Record<string, unknown>): Promise<unknown> {
218
+ await this.ensureInitialized();
219
+
220
+ const ctx = this.createContext({
221
+ method: 'POST',
222
+ path: '/api/execute',
223
+ body: { code, config },
224
+ });
225
+
226
+ return await this.server.handleExecute(ctx);
227
+ }
228
+
229
+ async resume(executionId: string, callbackResult: unknown): Promise<unknown> {
230
+ await this.ensureInitialized();
231
+
232
+ const ctx = this.createContext({
233
+ method: 'POST',
234
+ path: `/api/resume/${executionId}`,
235
+ body: { result: callbackResult },
236
+ });
237
+
238
+ return await this.server.handleResume(ctx, executionId);
239
+ }
240
+
241
+ async resumeWithBatchResults(
242
+ executionId: string,
243
+ batchResults: Array<{ id: string; result: unknown }>
244
+ ): Promise<unknown> {
245
+ await this.ensureInitialized();
246
+
247
+ const ctx = this.createContext({
248
+ method: 'POST',
249
+ path: `/api/resume/${executionId}`,
250
+ body: { results: batchResults },
251
+ });
252
+
253
+ return await this.server.handleResume(ctx, executionId);
254
+ }
255
+
256
+ private createContext(options: {
257
+ method: string;
258
+ path: string;
259
+ query?: Record<string, string>;
260
+ body?: unknown;
261
+ }): InProcessRequestContext {
262
+ const noopLogger = {
263
+ debug: () => {},
264
+ info: () => {},
265
+ warn: () => {},
266
+ error: () => {},
267
+ };
268
+
269
+ return {
270
+ method: options.method,
271
+ path: options.path,
272
+ query: options.query || {},
273
+ headers: this.getHeaders(),
274
+ body: options.body,
275
+ clientId: this.clientId,
276
+ clientToken: this.clientToken,
277
+ logger: noopLogger,
278
+ status: 200,
279
+ responseBody: null,
280
+ throw: (status: number, message: string) => {
281
+ const error = new Error(message);
282
+ (error as Error & { status: number }).status = status;
283
+ throw error;
284
+ },
285
+ assert: (condition: boolean, message: string) => {
286
+ if (!condition) {
287
+ throw new Error(message);
288
+ }
289
+ },
290
+ set: () => {},
291
+ };
292
+ }
293
+ }
package/src/core/index.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from './session.js';
2
+ export * from './in-process-session.js';
2
3
  export * from './api-operations.js';
3
4
  export * from './execution-operations.js';
4
5
  export * from './service-providers.js';
@@ -1,7 +1,26 @@
1
1
  import type { ClientHooks } from './types.js';
2
2
  import type { ClientToolDefinition } from '@mondaydotcomorg/atp-protocol';
3
3
 
4
- export class ClientSession {
4
+ export interface ISession {
5
+ init(
6
+ clientInfo?: { name?: string; version?: string; [key: string]: unknown },
7
+ tools?: ClientToolDefinition[],
8
+ services?: { hasLLM: boolean; hasApproval: boolean; hasEmbedding: boolean; hasTools: boolean }
9
+ ): Promise<{
10
+ clientId: string;
11
+ token: string;
12
+ expiresAt: number;
13
+ tokenRotateAt: number;
14
+ }>;
15
+ getClientId(): string;
16
+ ensureInitialized(): Promise<void>;
17
+ getHeaders(): Record<string, string>;
18
+ getBaseUrl(): string;
19
+ updateToken(response: Response): void;
20
+ prepareHeaders(method: string, url: string, body?: unknown): Promise<Record<string, string>>;
21
+ }
22
+
23
+ export class ClientSession implements ISession {
5
24
  private baseUrl: string;
6
25
  private customHeaders: Record<string, string>;
7
26
  private clientId?: string;
package/src/index.ts CHANGED
@@ -9,3 +9,5 @@ export type { RuntimeAPIName } from '@mondaydotcomorg/atp-runtime';
9
9
  export type { Tool, ToolName } from './tools/types.js';
10
10
  export { ToolNames } from './tools/types.js';
11
11
  export type { AgentToolProtocolClientOptions } from './client.js';
12
+ export { InProcessSession } from './core/in-process-session.js';
13
+ export type { ISession } from './core/session.js';