@kaiban/sdk 0.3.1 → 0.4.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/README.md +14 -91
- package/dist/cjs/lib/client.js +0 -2
- package/dist/cjs/lib/http/HttpClient.js +1 -5
- package/dist/cjs/lib/http/errors.js +4 -70
- package/dist/cjs/lib/resources/AgentsClient.js +0 -28
- package/dist/cjs/lib/resources/BoardsClient.js +0 -42
- package/dist/cjs/types/entities/activities.js +2 -0
- package/dist/esm/lib/client.js +0 -2
- package/dist/esm/lib/http/HttpClient.js +2 -6
- package/dist/esm/lib/http/errors.js +3 -67
- package/dist/esm/lib/resources/AgentsClient.js +0 -28
- package/dist/esm/lib/resources/BoardsClient.js +0 -42
- package/dist/esm/types/entities/activities.js +2 -0
- package/dist/types/lib/client.d.ts +0 -3
- package/dist/types/lib/http/errors.d.ts +2 -26
- package/dist/types/lib/resources/AgentsClient.d.ts +0 -26
- package/dist/types/lib/resources/BoardsClient.d.ts +1 -34
- package/dist/types/types/entities/activities.d.ts +3 -5
- package/dist/types/types/entities/agent.d.ts +14 -14
- package/dist/types/types/entities/board.d.ts +10 -16
- package/dist/types/types/entities/card.d.ts +13 -22
- package/dist/types/types/entities/external-channel.d.ts +1 -1
- package/dist/types/types/entities/team.d.ts +2 -3
- package/package.json +3 -3
- package/dist/cjs/lib/resources/TeamMembersClient.js +0 -102
- package/dist/esm/lib/resources/TeamMembersClient.js +0 -98
- package/dist/types/lib/resources/TeamMembersClient.d.ts +0 -89
package/README.md
CHANGED
|
@@ -35,12 +35,11 @@ The SDK provides clients for the following API resources:
|
|
|
35
35
|
|
|
36
36
|
### Available Resource Clients
|
|
37
37
|
|
|
38
|
-
- **agents**: `list`, `listAll`, `get`, `
|
|
39
|
-
- **teamMembers**: `list`, `listAll`, `get`
|
|
38
|
+
- **agents**: `list`, `listAll`, `get`, `update`, `createFeedback`, `listSupervisorFeedback`
|
|
40
39
|
- **cards**: `list`, `listAll`, `get`, `create`, `update`, `delete`, `moveToColumn`, `createActivity`, `createBatchActivities`, `listActivities`, `listAllActivities`
|
|
41
40
|
- **activities**: `list`, `listAll`, `create`, `createBatch`
|
|
42
41
|
- **teams**: `list`, `listAll`, `get`
|
|
43
|
-
- **boards**: `list`, `listAll`, `get
|
|
42
|
+
- **boards**: `list`, `listAll`, `get`
|
|
44
43
|
- **resources**: `list`, `listAll`, `get`
|
|
45
44
|
- **external_channels**: `list`, `listAll`, `get`
|
|
46
45
|
- **costs**: `calculateCosts` (offline utility for model cost calculations)
|
|
@@ -286,9 +285,6 @@ import {
|
|
|
286
285
|
ValidationError,
|
|
287
286
|
UnauthorizedError,
|
|
288
287
|
RateLimitError,
|
|
289
|
-
BadGatewayError,
|
|
290
|
-
GatewayTimeoutError,
|
|
291
|
-
UnavailableError,
|
|
292
288
|
TimeoutError,
|
|
293
289
|
AbortedError,
|
|
294
290
|
} from '@kaiban/sdk';
|
|
@@ -303,44 +299,22 @@ try {
|
|
|
303
299
|
} catch (err) {
|
|
304
300
|
if (err instanceof NotFoundError) {
|
|
305
301
|
console.error('Card not found:', err.message);
|
|
306
|
-
console.error('Error code:', err.code); //
|
|
307
|
-
console.error('Request ID:', err.meta?.request_id);
|
|
308
|
-
console.error('Timestamp:', err.meta?.timestamp);
|
|
302
|
+
console.error('Error code:', err.code); // Optional error code from API
|
|
309
303
|
} else if (err instanceof ValidationError) {
|
|
310
304
|
console.error('Validation failed:', err.message);
|
|
311
|
-
console.error('
|
|
312
|
-
// ValidationError.details includes issues array
|
|
313
|
-
if (err.details?.issues) {
|
|
314
|
-
err.details.issues.forEach((issue) => {
|
|
315
|
-
console.error(` - ${issue.path.join('.')}: ${issue.message}`);
|
|
316
|
-
});
|
|
317
|
-
}
|
|
305
|
+
console.error('Details:', err.details); // Additional error details from API
|
|
318
306
|
} else if (err instanceof BadRequestError) {
|
|
319
307
|
console.error('Invalid request:', err.message);
|
|
320
|
-
console.error('Error code:', err.code); // 'invalid_argument'
|
|
321
308
|
} else if (err instanceof UnauthorizedError) {
|
|
322
309
|
console.error('Authentication required:', err.message);
|
|
323
|
-
console.error('Error code:', err.code); // 'unauthenticated'
|
|
324
310
|
} else if (err instanceof RateLimitError) {
|
|
325
311
|
console.error('Rate limit exceeded:', err.message);
|
|
326
|
-
console.error('Error code:', err.code); // 'rate_limit_exceeded'
|
|
327
|
-
} else if (err instanceof BadGatewayError) {
|
|
328
|
-
console.error('Bad gateway:', err.message);
|
|
329
|
-
console.error('Error code:', err.code); // 'bad_gateway'
|
|
330
|
-
} else if (err instanceof GatewayTimeoutError) {
|
|
331
|
-
console.error('Gateway timeout:', err.message);
|
|
332
|
-
console.error('Error code:', err.code); // 'gateway_timeout'
|
|
333
|
-
} else if (err instanceof UnavailableError) {
|
|
334
|
-
console.error('Service unavailable:', err.message);
|
|
335
|
-
console.error('Error code:', err.code); // 'service_unavailable'
|
|
336
312
|
} else if (err instanceof TimeoutError) {
|
|
337
313
|
console.error('Request timed out');
|
|
338
314
|
} else if (err instanceof AbortedError) {
|
|
339
315
|
console.error('Request was cancelled');
|
|
340
316
|
} else if (err instanceof ApiError) {
|
|
341
317
|
console.error('API error:', err.message);
|
|
342
|
-
console.error('Error code:', err.code);
|
|
343
|
-
console.error('Details:', err.details);
|
|
344
318
|
} else {
|
|
345
319
|
console.error('Unexpected error:', err);
|
|
346
320
|
}
|
|
@@ -349,29 +323,20 @@ try {
|
|
|
349
323
|
|
|
350
324
|
### Available Error Classes
|
|
351
325
|
|
|
352
|
-
- **`ApiError`**: Base class for all API errors (includes `code`, `message`, `details
|
|
353
|
-
- **`BadRequestError`**: 400 - Invalid request format or parameters
|
|
354
|
-
- **`ValidationError`**: 422 - Request validation failed
|
|
355
|
-
- **`UnauthorizedError`**: 401 - Authentication required or failed
|
|
356
|
-
- **`ForbiddenError`**: 403 - Insufficient permissions
|
|
357
|
-
- **`NotFoundError`**: 404 - Resource not found
|
|
358
|
-
- **`ConflictError`**: 409 - Resource conflict
|
|
359
|
-
- **`RateLimitError`**: 429 - Too many requests
|
|
360
|
-
- **`
|
|
361
|
-
- **`
|
|
362
|
-
- **`GatewayTimeoutError`**: 504 - Gateway timeout (`gateway_timeout`)
|
|
363
|
-
- **`ServerError`**: 500 - Internal server error (`internal`)
|
|
326
|
+
- **`ApiError`**: Base class for all API errors (includes `code`, `message`, `details` properties)
|
|
327
|
+
- **`BadRequestError`**: 400 - Invalid request format or parameters
|
|
328
|
+
- **`ValidationError`**: 422 - Request validation failed
|
|
329
|
+
- **`UnauthorizedError`**: 401 - Authentication required or failed
|
|
330
|
+
- **`ForbiddenError`**: 403 - Insufficient permissions
|
|
331
|
+
- **`NotFoundError`**: 404 - Resource not found
|
|
332
|
+
- **`ConflictError`**: 409 - Resource conflict
|
|
333
|
+
- **`RateLimitError`**: 429 - Too many requests
|
|
334
|
+
- **`UnavailableError`**: 502, 503, 504 - Service temporarily unavailable
|
|
335
|
+
- **`ServerError`**: 500 or other server errors
|
|
364
336
|
- **`TimeoutError`**: Request exceeded configured timeout
|
|
365
337
|
- **`AbortedError`**: Request was cancelled via AbortSignal
|
|
366
338
|
- **`HttpError`**: Low-level HTTP error (includes `status`, `url`, `body` properties)
|
|
367
339
|
|
|
368
|
-
All API errors include:
|
|
369
|
-
|
|
370
|
-
- `code`: Backend error code (e.g., `validation_error`, `not_found`)
|
|
371
|
-
- `message`: Human-readable error message
|
|
372
|
-
- `details`: Optional error details (for `ValidationError`, includes `issues[]` array)
|
|
373
|
-
- `meta`: Request metadata with `request_id?` and `timestamp`
|
|
374
|
-
|
|
375
340
|
## Examples by resource
|
|
376
341
|
|
|
377
342
|
### Agents
|
|
@@ -393,19 +358,6 @@ for await (const agent of client.agents.listAll({ limit: 100 })) {
|
|
|
393
358
|
// Get agent by id
|
|
394
359
|
const agent = await client.agents.get('agent-123');
|
|
395
360
|
|
|
396
|
-
// Create a new agent
|
|
397
|
-
const newAgent = await client.agents.create({
|
|
398
|
-
name: 'SupportAgent',
|
|
399
|
-
description: 'Handles support tickets',
|
|
400
|
-
team_id: 'team_123',
|
|
401
|
-
owner_id: 'user_123',
|
|
402
|
-
created_by: 'user_123',
|
|
403
|
-
type: 'a2a',
|
|
404
|
-
status: 'active',
|
|
405
|
-
monthly_budget: 200,
|
|
406
|
-
examples: [],
|
|
407
|
-
});
|
|
408
|
-
|
|
409
361
|
// Update agent
|
|
410
362
|
const updated = await client.agents.update('agent-123', {
|
|
411
363
|
name: 'Updated Name',
|
|
@@ -448,24 +400,6 @@ for await (const team of client.teams.listAll()) {
|
|
|
448
400
|
const team = await client.teams.get('team-123');
|
|
449
401
|
```
|
|
450
402
|
|
|
451
|
-
### Team Members
|
|
452
|
-
|
|
453
|
-
```ts
|
|
454
|
-
// List team members with pagination
|
|
455
|
-
const result = await client.teamMembers.list({
|
|
456
|
-
limit: 20,
|
|
457
|
-
order_by: '-joined_at',
|
|
458
|
-
});
|
|
459
|
-
|
|
460
|
-
// Iterate through all team members
|
|
461
|
-
for await (const member of client.teamMembers.listAll({ limit: 100 })) {
|
|
462
|
-
console.log(member.id, member.user_id, member.role);
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
// Get a specific team member
|
|
466
|
-
const member = await client.teamMembers.get('tm-123');
|
|
467
|
-
```
|
|
468
|
-
|
|
469
403
|
### Boards
|
|
470
404
|
|
|
471
405
|
```ts
|
|
@@ -479,17 +413,6 @@ for await (const board of client.boards.listAll()) {
|
|
|
479
413
|
|
|
480
414
|
// Get a specific board
|
|
481
415
|
const board = await client.boards.get('board-123');
|
|
482
|
-
|
|
483
|
-
// Create a new board
|
|
484
|
-
const newBoard = await client.boards.create({
|
|
485
|
-
name: 'Sales',
|
|
486
|
-
team_id: 'team_123',
|
|
487
|
-
owner_id: 'user_123',
|
|
488
|
-
created_by: 'user_123',
|
|
489
|
-
description: 'Manage pipeline',
|
|
490
|
-
columns: [],
|
|
491
|
-
// agent_ids, member_ids, and allowed_roles are optional (default to [])
|
|
492
|
-
});
|
|
493
416
|
```
|
|
494
417
|
|
|
495
418
|
### Cards
|
package/dist/cjs/lib/client.js
CHANGED
|
@@ -9,7 +9,6 @@ const CardsClient_1 = require("./resources/CardsClient");
|
|
|
9
9
|
const ExternalChannelsClient_1 = require("./resources/ExternalChannelsClient");
|
|
10
10
|
const ModelCost_1 = require("./resources/ModelCost");
|
|
11
11
|
const ResourcesClient_1 = require("./resources/ResourcesClient");
|
|
12
|
-
const TeamMembersClient_1 = require("./resources/TeamMembersClient");
|
|
13
12
|
const TeamsClient_1 = require("./resources/TeamsClient");
|
|
14
13
|
/**
|
|
15
14
|
* Create a Kaiban SDK client instance
|
|
@@ -47,7 +46,6 @@ function createKaibanClient(config) {
|
|
|
47
46
|
cards: new CardsClient_1.CardsClient(http),
|
|
48
47
|
activities: new ActivitiesClient_1.ActivitiesClient(http),
|
|
49
48
|
teams: new TeamsClient_1.TeamsClient(http),
|
|
50
|
-
teamMembers: new TeamMembersClient_1.TeamMembersClient(http),
|
|
51
49
|
boards: new BoardsClient_1.BoardsClient(http),
|
|
52
50
|
resources: new ResourcesClient_1.ResourcesClient(http),
|
|
53
51
|
external_channels: new ExternalChannelsClient_1.ExternalChannelsClient(http),
|
|
@@ -165,11 +165,7 @@ class HttpClient {
|
|
|
165
165
|
if (err instanceof errors_1.RateLimitError)
|
|
166
166
|
return retryCfg.retryOn?.includes(429) ?? false;
|
|
167
167
|
if (err instanceof errors_1.UnavailableError)
|
|
168
|
-
return retryCfg.retryOn?.
|
|
169
|
-
if (err instanceof errors_1.BadGatewayError)
|
|
170
|
-
return retryCfg.retryOn?.includes(502) ?? false;
|
|
171
|
-
if (err instanceof errors_1.GatewayTimeoutError)
|
|
172
|
-
return retryCfg.retryOn?.includes(504) ?? false;
|
|
168
|
+
return retryCfg.retryOn?.some((c) => c === 502 || c === 503 || c === 504) ?? false;
|
|
173
169
|
if (err instanceof errors_1.ServerError)
|
|
174
170
|
return retryCfg.retryOn?.includes(500) ?? false;
|
|
175
171
|
return false;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ServerError = exports.
|
|
3
|
+
exports.ServerError = exports.UnavailableError = exports.RateLimitError = exports.ConflictError = exports.NotFoundError = exports.ForbiddenError = exports.UnauthorizedError = exports.ValidationError = exports.BadRequestError = exports.ApiError = exports.AbortedError = exports.TimeoutError = exports.HttpError = void 0;
|
|
4
4
|
exports.mapHttpToSdkError = mapHttpToSdkError;
|
|
5
5
|
class HttpError extends Error {
|
|
6
6
|
constructor(message, status, url, body) {
|
|
@@ -32,7 +32,6 @@ class ApiError extends Error {
|
|
|
32
32
|
this.name = 'ApiError';
|
|
33
33
|
this.code = shape.code;
|
|
34
34
|
this.details = shape.details;
|
|
35
|
-
this.meta = shape.meta;
|
|
36
35
|
}
|
|
37
36
|
}
|
|
38
37
|
exports.ApiError = ApiError;
|
|
@@ -47,7 +46,6 @@ class ValidationError extends ApiError {
|
|
|
47
46
|
constructor(shape) {
|
|
48
47
|
super(shape);
|
|
49
48
|
this.name = 'ValidationError';
|
|
50
|
-
this.details = shape.details;
|
|
51
49
|
}
|
|
52
50
|
}
|
|
53
51
|
exports.ValidationError = ValidationError;
|
|
@@ -93,20 +91,6 @@ class UnavailableError extends ApiError {
|
|
|
93
91
|
}
|
|
94
92
|
}
|
|
95
93
|
exports.UnavailableError = UnavailableError;
|
|
96
|
-
class BadGatewayError extends ApiError {
|
|
97
|
-
constructor(shape) {
|
|
98
|
-
super(shape);
|
|
99
|
-
this.name = 'BadGatewayError';
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
exports.BadGatewayError = BadGatewayError;
|
|
103
|
-
class GatewayTimeoutError extends ApiError {
|
|
104
|
-
constructor(shape) {
|
|
105
|
-
super(shape);
|
|
106
|
-
this.name = 'GatewayTimeoutError';
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
exports.GatewayTimeoutError = GatewayTimeoutError;
|
|
110
94
|
class ServerError extends ApiError {
|
|
111
95
|
constructor(shape) {
|
|
112
96
|
super(shape);
|
|
@@ -115,38 +99,8 @@ class ServerError extends ApiError {
|
|
|
115
99
|
}
|
|
116
100
|
exports.ServerError = ServerError;
|
|
117
101
|
// Map HTTP response status and body to human-friendly SDK errors
|
|
118
|
-
// Uses backend error code when available, falls back to HTTP status mapping
|
|
119
102
|
function mapHttpToSdkError(status, body) {
|
|
120
103
|
const shape = normalizeBody(body);
|
|
121
|
-
// If backend provided an explicit error code, use it to determine error type
|
|
122
|
-
if (shape.code) {
|
|
123
|
-
switch (shape.code) {
|
|
124
|
-
case 'invalid_argument':
|
|
125
|
-
return new BadRequestError(shape);
|
|
126
|
-
case 'unauthenticated':
|
|
127
|
-
return new UnauthorizedError(shape);
|
|
128
|
-
case 'permission_denied':
|
|
129
|
-
return new ForbiddenError(shape);
|
|
130
|
-
case 'not_found':
|
|
131
|
-
return new NotFoundError(shape);
|
|
132
|
-
case 'conflict':
|
|
133
|
-
return new ConflictError(shape);
|
|
134
|
-
case 'validation_error':
|
|
135
|
-
return new ValidationError(shape);
|
|
136
|
-
case 'rate_limit_exceeded':
|
|
137
|
-
return new RateLimitError(shape);
|
|
138
|
-
case 'bad_gateway':
|
|
139
|
-
return new BadGatewayError(shape);
|
|
140
|
-
case 'service_unavailable':
|
|
141
|
-
return new UnavailableError(shape);
|
|
142
|
-
case 'gateway_timeout':
|
|
143
|
-
return new GatewayTimeoutError(shape);
|
|
144
|
-
case 'internal':
|
|
145
|
-
default:
|
|
146
|
-
return new ServerError(shape);
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
// Fallback to HTTP status code mapping if no backend code provided
|
|
150
104
|
switch (status) {
|
|
151
105
|
case 400:
|
|
152
106
|
return new BadRequestError(shape);
|
|
@@ -163,20 +117,14 @@ function mapHttpToSdkError(status, body) {
|
|
|
163
117
|
case 429:
|
|
164
118
|
return new RateLimitError(shape);
|
|
165
119
|
case 502:
|
|
166
|
-
return new BadGatewayError(shape);
|
|
167
120
|
case 503:
|
|
168
|
-
return new UnavailableError(shape);
|
|
169
121
|
case 504:
|
|
170
|
-
return new
|
|
122
|
+
return new UnavailableError(shape);
|
|
171
123
|
case 500:
|
|
172
124
|
default:
|
|
173
125
|
return new ServerError(shape);
|
|
174
126
|
}
|
|
175
127
|
}
|
|
176
|
-
/**
|
|
177
|
-
* Normalizes error response body to ApiErrorShape
|
|
178
|
-
* Backend returns: { error: { code, message, details? }, meta: { request_id?, timestamp } }
|
|
179
|
-
*/
|
|
180
128
|
function normalizeBody(body) {
|
|
181
129
|
if (!body)
|
|
182
130
|
return { message: 'Unknown error' };
|
|
@@ -184,26 +132,12 @@ function normalizeBody(body) {
|
|
|
184
132
|
return { message: body };
|
|
185
133
|
if (typeof body === 'object') {
|
|
186
134
|
const anyBody = body;
|
|
187
|
-
|
|
188
|
-
if (anyBody['error'] && typeof anyBody['error'] === 'object') {
|
|
189
|
-
const errorObj = anyBody['error'];
|
|
190
|
-
const meta = anyBody['meta'];
|
|
191
|
-
return {
|
|
192
|
-
code: errorObj['code'],
|
|
193
|
-
message: errorObj['message'] || 'Request failed',
|
|
194
|
-
details: errorObj['details'],
|
|
195
|
-
meta,
|
|
196
|
-
};
|
|
197
|
-
}
|
|
198
|
-
// Fallback: try to extract from flat structure (legacy support)
|
|
199
|
-
const code = anyBody['code'] ||
|
|
200
|
-
anyBody['error'];
|
|
135
|
+
const code = anyBody['code'] || anyBody['error'];
|
|
201
136
|
const message = anyBody['message'] ||
|
|
202
137
|
anyBody['error_description'] ||
|
|
203
138
|
'Request failed';
|
|
204
139
|
const details = anyBody['details'];
|
|
205
|
-
|
|
206
|
-
return { code, message, details, meta };
|
|
140
|
+
return { code, message, details };
|
|
207
141
|
}
|
|
208
142
|
return { message: 'Request failed' };
|
|
209
143
|
}
|
|
@@ -105,34 +105,6 @@ class AgentsClient {
|
|
|
105
105
|
get(id, options) {
|
|
106
106
|
return this.http.get(`/agent/${encodeURIComponent(id)}`, options);
|
|
107
107
|
}
|
|
108
|
-
/**
|
|
109
|
-
* Create a new agent
|
|
110
|
-
*
|
|
111
|
-
* @param data - Agent creation data
|
|
112
|
-
* @param options - Optional request configuration
|
|
113
|
-
*
|
|
114
|
-
* @returns The newly created agent object
|
|
115
|
-
*
|
|
116
|
-
* @throws {Error} If creation fails
|
|
117
|
-
*
|
|
118
|
-
* @example
|
|
119
|
-
* ```typescript
|
|
120
|
-
* const agent = await client.agents.create({
|
|
121
|
-
* name: 'SupportAgent',
|
|
122
|
-
* description: 'Handles support tickets',
|
|
123
|
-
* team_id: 'team_123',
|
|
124
|
-
* owner_id: 'user_123',
|
|
125
|
-
* created_by: 'user_123',
|
|
126
|
-
* type: 'a2a',
|
|
127
|
-
* status: 'active',
|
|
128
|
-
* monthly_budget: 200,
|
|
129
|
-
* examples: []
|
|
130
|
-
* });
|
|
131
|
-
* ```
|
|
132
|
-
*/
|
|
133
|
-
create(data, options) {
|
|
134
|
-
return this.http.post('/agents', data, options);
|
|
135
|
-
}
|
|
136
108
|
/**
|
|
137
109
|
* Update an agent's properties
|
|
138
110
|
*
|
|
@@ -74,47 +74,5 @@ class BoardsClient {
|
|
|
74
74
|
get(id, options) {
|
|
75
75
|
return this.http.get(`/board/${encodeURIComponent(id)}`, options);
|
|
76
76
|
}
|
|
77
|
-
/**
|
|
78
|
-
* Create a new board
|
|
79
|
-
*
|
|
80
|
-
* @param data - Board creation data
|
|
81
|
-
* @param data.name - The board name
|
|
82
|
-
* @param data.team_id - The team this board belongs to
|
|
83
|
-
* @param data.owner_id - The owner of the board
|
|
84
|
-
* @param data.created_by - The user creating the board
|
|
85
|
-
* @param data.description - Board description
|
|
86
|
-
* @param data.agent_ids - Array of agent IDs
|
|
87
|
-
* @param data.member_ids - Array of member IDs
|
|
88
|
-
* @param data.allowed_roles - Array of allowed roles
|
|
89
|
-
* @param data.columns - Array of columns
|
|
90
|
-
* @param options - Optional request configuration
|
|
91
|
-
*
|
|
92
|
-
* @returns The newly created board
|
|
93
|
-
*
|
|
94
|
-
* @throws {Error} If creation fails
|
|
95
|
-
*
|
|
96
|
-
* @example
|
|
97
|
-
* ```typescript
|
|
98
|
-
* const board = await client.boards.create({
|
|
99
|
-
* name: 'Sales',
|
|
100
|
-
* team_id: 'team_123',
|
|
101
|
-
* owner_id: 'user_123',
|
|
102
|
-
* created_by: 'user_123',
|
|
103
|
-
* description: 'Manage pipeline',
|
|
104
|
-
* columns: []
|
|
105
|
-
* // agent_ids, member_ids, and allowed_roles are optional (default to [])
|
|
106
|
-
* });
|
|
107
|
-
* ```
|
|
108
|
-
*/
|
|
109
|
-
create(data, options) {
|
|
110
|
-
// Default empty arrays for optional fields
|
|
111
|
-
const payload = {
|
|
112
|
-
...data,
|
|
113
|
-
agent_ids: data.agent_ids ?? [],
|
|
114
|
-
member_ids: data.member_ids ?? [],
|
|
115
|
-
allowed_roles: data.allowed_roles ?? [],
|
|
116
|
-
};
|
|
117
|
-
return this.http.post('/boards', payload, options);
|
|
118
|
-
}
|
|
119
77
|
}
|
|
120
78
|
exports.BoardsClient = BoardsClient;
|
|
@@ -24,6 +24,8 @@ exports.ActivityType = {
|
|
|
24
24
|
CARD_CLONED: 'card_cloned',
|
|
25
25
|
CARD_COLUMN_CHANGED: 'card_column_changed',
|
|
26
26
|
// A2A task status activities
|
|
27
|
+
// "submitted" | "working" | "input-required" | "completed" | "canceled" | "failed" | "rejected"
|
|
28
|
+
// | "auth-required" | "unknown"
|
|
27
29
|
A2A_TASK_STATUS_SUBMITTED: 'submitted',
|
|
28
30
|
A2A_TASK_STATUS_WORKING: 'working',
|
|
29
31
|
A2A_TASK_STATUS_INPUT_REQUIRED: 'required',
|
package/dist/esm/lib/client.js
CHANGED
|
@@ -6,7 +6,6 @@ import { CardsClient } from './resources/CardsClient.js';
|
|
|
6
6
|
import { ExternalChannelsClient } from './resources/ExternalChannelsClient.js';
|
|
7
7
|
import { ModelCost } from './resources/ModelCost.js';
|
|
8
8
|
import { ResourcesClient } from './resources/ResourcesClient.js';
|
|
9
|
-
import { TeamMembersClient } from './resources/TeamMembersClient.js';
|
|
10
9
|
import { TeamsClient } from './resources/TeamsClient.js';
|
|
11
10
|
/**
|
|
12
11
|
* Create a Kaiban SDK client instance
|
|
@@ -44,7 +43,6 @@ export function createKaibanClient(config) {
|
|
|
44
43
|
cards: new CardsClient(http),
|
|
45
44
|
activities: new ActivitiesClient(http),
|
|
46
45
|
teams: new TeamsClient(http),
|
|
47
|
-
teamMembers: new TeamMembersClient(http),
|
|
48
46
|
boards: new BoardsClient(http),
|
|
49
47
|
resources: new ResourcesClient(http),
|
|
50
48
|
external_channels: new ExternalChannelsClient(http),
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AbortedError,
|
|
1
|
+
import { AbortedError, RateLimitError, ServerError, TimeoutError, UnavailableError, mapHttpToSdkError, } from './errors.js';
|
|
2
2
|
function buildQuery(query) {
|
|
3
3
|
if (!query)
|
|
4
4
|
return '';
|
|
@@ -162,11 +162,7 @@ export class HttpClient {
|
|
|
162
162
|
if (err instanceof RateLimitError)
|
|
163
163
|
return retryCfg.retryOn?.includes(429) ?? false;
|
|
164
164
|
if (err instanceof UnavailableError)
|
|
165
|
-
return retryCfg.retryOn?.
|
|
166
|
-
if (err instanceof BadGatewayError)
|
|
167
|
-
return retryCfg.retryOn?.includes(502) ?? false;
|
|
168
|
-
if (err instanceof GatewayTimeoutError)
|
|
169
|
-
return retryCfg.retryOn?.includes(504) ?? false;
|
|
165
|
+
return retryCfg.retryOn?.some((c) => c === 502 || c === 503 || c === 504) ?? false;
|
|
170
166
|
if (err instanceof ServerError)
|
|
171
167
|
return retryCfg.retryOn?.includes(500) ?? false;
|
|
172
168
|
return false;
|
|
@@ -25,7 +25,6 @@ export class ApiError extends Error {
|
|
|
25
25
|
this.name = 'ApiError';
|
|
26
26
|
this.code = shape.code;
|
|
27
27
|
this.details = shape.details;
|
|
28
|
-
this.meta = shape.meta;
|
|
29
28
|
}
|
|
30
29
|
}
|
|
31
30
|
export class BadRequestError extends ApiError {
|
|
@@ -38,7 +37,6 @@ export class ValidationError extends ApiError {
|
|
|
38
37
|
constructor(shape) {
|
|
39
38
|
super(shape);
|
|
40
39
|
this.name = 'ValidationError';
|
|
41
|
-
this.details = shape.details;
|
|
42
40
|
}
|
|
43
41
|
}
|
|
44
42
|
export class UnauthorizedError extends ApiError {
|
|
@@ -77,18 +75,6 @@ export class UnavailableError extends ApiError {
|
|
|
77
75
|
this.name = 'UnavailableError';
|
|
78
76
|
}
|
|
79
77
|
}
|
|
80
|
-
export class BadGatewayError extends ApiError {
|
|
81
|
-
constructor(shape) {
|
|
82
|
-
super(shape);
|
|
83
|
-
this.name = 'BadGatewayError';
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
export class GatewayTimeoutError extends ApiError {
|
|
87
|
-
constructor(shape) {
|
|
88
|
-
super(shape);
|
|
89
|
-
this.name = 'GatewayTimeoutError';
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
78
|
export class ServerError extends ApiError {
|
|
93
79
|
constructor(shape) {
|
|
94
80
|
super(shape);
|
|
@@ -96,38 +82,8 @@ export class ServerError extends ApiError {
|
|
|
96
82
|
}
|
|
97
83
|
}
|
|
98
84
|
// Map HTTP response status and body to human-friendly SDK errors
|
|
99
|
-
// Uses backend error code when available, falls back to HTTP status mapping
|
|
100
85
|
export function mapHttpToSdkError(status, body) {
|
|
101
86
|
const shape = normalizeBody(body);
|
|
102
|
-
// If backend provided an explicit error code, use it to determine error type
|
|
103
|
-
if (shape.code) {
|
|
104
|
-
switch (shape.code) {
|
|
105
|
-
case 'invalid_argument':
|
|
106
|
-
return new BadRequestError(shape);
|
|
107
|
-
case 'unauthenticated':
|
|
108
|
-
return new UnauthorizedError(shape);
|
|
109
|
-
case 'permission_denied':
|
|
110
|
-
return new ForbiddenError(shape);
|
|
111
|
-
case 'not_found':
|
|
112
|
-
return new NotFoundError(shape);
|
|
113
|
-
case 'conflict':
|
|
114
|
-
return new ConflictError(shape);
|
|
115
|
-
case 'validation_error':
|
|
116
|
-
return new ValidationError(shape);
|
|
117
|
-
case 'rate_limit_exceeded':
|
|
118
|
-
return new RateLimitError(shape);
|
|
119
|
-
case 'bad_gateway':
|
|
120
|
-
return new BadGatewayError(shape);
|
|
121
|
-
case 'service_unavailable':
|
|
122
|
-
return new UnavailableError(shape);
|
|
123
|
-
case 'gateway_timeout':
|
|
124
|
-
return new GatewayTimeoutError(shape);
|
|
125
|
-
case 'internal':
|
|
126
|
-
default:
|
|
127
|
-
return new ServerError(shape);
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
// Fallback to HTTP status code mapping if no backend code provided
|
|
131
87
|
switch (status) {
|
|
132
88
|
case 400:
|
|
133
89
|
return new BadRequestError(shape);
|
|
@@ -144,20 +100,14 @@ export function mapHttpToSdkError(status, body) {
|
|
|
144
100
|
case 429:
|
|
145
101
|
return new RateLimitError(shape);
|
|
146
102
|
case 502:
|
|
147
|
-
return new BadGatewayError(shape);
|
|
148
103
|
case 503:
|
|
149
|
-
return new UnavailableError(shape);
|
|
150
104
|
case 504:
|
|
151
|
-
return new
|
|
105
|
+
return new UnavailableError(shape);
|
|
152
106
|
case 500:
|
|
153
107
|
default:
|
|
154
108
|
return new ServerError(shape);
|
|
155
109
|
}
|
|
156
110
|
}
|
|
157
|
-
/**
|
|
158
|
-
* Normalizes error response body to ApiErrorShape
|
|
159
|
-
* Backend returns: { error: { code, message, details? }, meta: { request_id?, timestamp } }
|
|
160
|
-
*/
|
|
161
111
|
function normalizeBody(body) {
|
|
162
112
|
if (!body)
|
|
163
113
|
return { message: 'Unknown error' };
|
|
@@ -165,26 +115,12 @@ function normalizeBody(body) {
|
|
|
165
115
|
return { message: body };
|
|
166
116
|
if (typeof body === 'object') {
|
|
167
117
|
const anyBody = body;
|
|
168
|
-
|
|
169
|
-
if (anyBody['error'] && typeof anyBody['error'] === 'object') {
|
|
170
|
-
const errorObj = anyBody['error'];
|
|
171
|
-
const meta = anyBody['meta'];
|
|
172
|
-
return {
|
|
173
|
-
code: errorObj['code'],
|
|
174
|
-
message: errorObj['message'] || 'Request failed',
|
|
175
|
-
details: errorObj['details'],
|
|
176
|
-
meta,
|
|
177
|
-
};
|
|
178
|
-
}
|
|
179
|
-
// Fallback: try to extract from flat structure (legacy support)
|
|
180
|
-
const code = anyBody['code'] ||
|
|
181
|
-
anyBody['error'];
|
|
118
|
+
const code = anyBody['code'] || anyBody['error'];
|
|
182
119
|
const message = anyBody['message'] ||
|
|
183
120
|
anyBody['error_description'] ||
|
|
184
121
|
'Request failed';
|
|
185
122
|
const details = anyBody['details'];
|
|
186
|
-
|
|
187
|
-
return { code, message, details, meta };
|
|
123
|
+
return { code, message, details };
|
|
188
124
|
}
|
|
189
125
|
return { message: 'Request failed' };
|
|
190
126
|
}
|
|
@@ -102,34 +102,6 @@ export class AgentsClient {
|
|
|
102
102
|
get(id, options) {
|
|
103
103
|
return this.http.get(`/agent/${encodeURIComponent(id)}`, options);
|
|
104
104
|
}
|
|
105
|
-
/**
|
|
106
|
-
* Create a new agent
|
|
107
|
-
*
|
|
108
|
-
* @param data - Agent creation data
|
|
109
|
-
* @param options - Optional request configuration
|
|
110
|
-
*
|
|
111
|
-
* @returns The newly created agent object
|
|
112
|
-
*
|
|
113
|
-
* @throws {Error} If creation fails
|
|
114
|
-
*
|
|
115
|
-
* @example
|
|
116
|
-
* ```typescript
|
|
117
|
-
* const agent = await client.agents.create({
|
|
118
|
-
* name: 'SupportAgent',
|
|
119
|
-
* description: 'Handles support tickets',
|
|
120
|
-
* team_id: 'team_123',
|
|
121
|
-
* owner_id: 'user_123',
|
|
122
|
-
* created_by: 'user_123',
|
|
123
|
-
* type: 'a2a',
|
|
124
|
-
* status: 'active',
|
|
125
|
-
* monthly_budget: 200,
|
|
126
|
-
* examples: []
|
|
127
|
-
* });
|
|
128
|
-
* ```
|
|
129
|
-
*/
|
|
130
|
-
create(data, options) {
|
|
131
|
-
return this.http.post('/agents', data, options);
|
|
132
|
-
}
|
|
133
105
|
/**
|
|
134
106
|
* Update an agent's properties
|
|
135
107
|
*
|
|
@@ -71,46 +71,4 @@ export class BoardsClient {
|
|
|
71
71
|
get(id, options) {
|
|
72
72
|
return this.http.get(`/board/${encodeURIComponent(id)}`, options);
|
|
73
73
|
}
|
|
74
|
-
/**
|
|
75
|
-
* Create a new board
|
|
76
|
-
*
|
|
77
|
-
* @param data - Board creation data
|
|
78
|
-
* @param data.name - The board name
|
|
79
|
-
* @param data.team_id - The team this board belongs to
|
|
80
|
-
* @param data.owner_id - The owner of the board
|
|
81
|
-
* @param data.created_by - The user creating the board
|
|
82
|
-
* @param data.description - Board description
|
|
83
|
-
* @param data.agent_ids - Array of agent IDs
|
|
84
|
-
* @param data.member_ids - Array of member IDs
|
|
85
|
-
* @param data.allowed_roles - Array of allowed roles
|
|
86
|
-
* @param data.columns - Array of columns
|
|
87
|
-
* @param options - Optional request configuration
|
|
88
|
-
*
|
|
89
|
-
* @returns The newly created board
|
|
90
|
-
*
|
|
91
|
-
* @throws {Error} If creation fails
|
|
92
|
-
*
|
|
93
|
-
* @example
|
|
94
|
-
* ```typescript
|
|
95
|
-
* const board = await client.boards.create({
|
|
96
|
-
* name: 'Sales',
|
|
97
|
-
* team_id: 'team_123',
|
|
98
|
-
* owner_id: 'user_123',
|
|
99
|
-
* created_by: 'user_123',
|
|
100
|
-
* description: 'Manage pipeline',
|
|
101
|
-
* columns: []
|
|
102
|
-
* // agent_ids, member_ids, and allowed_roles are optional (default to [])
|
|
103
|
-
* });
|
|
104
|
-
* ```
|
|
105
|
-
*/
|
|
106
|
-
create(data, options) {
|
|
107
|
-
// Default empty arrays for optional fields
|
|
108
|
-
const payload = {
|
|
109
|
-
...data,
|
|
110
|
-
agent_ids: data.agent_ids ?? [],
|
|
111
|
-
member_ids: data.member_ids ?? [],
|
|
112
|
-
allowed_roles: data.allowed_roles ?? [],
|
|
113
|
-
};
|
|
114
|
-
return this.http.post('/boards', payload, options);
|
|
115
|
-
}
|
|
116
74
|
}
|