@agentuity/core 1.0.30 → 1.0.32
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/dist/error.d.ts.map +1 -1
- package/dist/error.js +16 -9
- package/dist/error.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/services/queue.d.ts +98 -0
- package/dist/services/queue.d.ts.map +1 -1
- package/dist/services/queue.js +100 -0
- package/dist/services/queue.js.map +1 -1
- package/dist/services/stream.d.ts +1 -1
- package/dist/services/stream.d.ts.map +1 -1
- package/dist/services/stream.js +6 -11
- package/dist/services/stream.js.map +1 -1
- package/dist/services/task.d.ts +100 -12
- package/dist/services/task.d.ts.map +1 -1
- package/dist/services/task.js +71 -0
- package/dist/services/task.js.map +1 -1
- package/package.json +2 -2
- package/src/error.ts +16 -9
- package/src/index.ts +8 -0
- package/src/services/queue.ts +215 -0
- package/src/services/stream.ts +7 -13
- package/src/services/task.ts +173 -12
package/src/services/queue.ts
CHANGED
|
@@ -108,6 +108,59 @@ export interface QueuePublishResult {
|
|
|
108
108
|
publishedAt: string;
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
+
/**
|
|
112
|
+
* Parameters for creating a queue.
|
|
113
|
+
*
|
|
114
|
+
* @example
|
|
115
|
+
* ```typescript
|
|
116
|
+
* const result = await ctx.queue.createQueue('my-queue', {
|
|
117
|
+
* queueType: 'pubsub',
|
|
118
|
+
* settings: { defaultTtlSeconds: 86400 },
|
|
119
|
+
* });
|
|
120
|
+
* ```
|
|
121
|
+
*/
|
|
122
|
+
export interface QueueCreateParams {
|
|
123
|
+
/**
|
|
124
|
+
* Type of queue to create.
|
|
125
|
+
* - `worker`: Messages are consumed by exactly one consumer with acknowledgment.
|
|
126
|
+
* - `pubsub`: Messages are broadcast to all subscribers.
|
|
127
|
+
* @default 'worker'
|
|
128
|
+
*/
|
|
129
|
+
queueType?: 'worker' | 'pubsub';
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Optional description of the queue's purpose.
|
|
133
|
+
*/
|
|
134
|
+
description?: string;
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Optional settings to customize queue behavior.
|
|
138
|
+
* Only provided fields are applied; others use server defaults.
|
|
139
|
+
*/
|
|
140
|
+
settings?: {
|
|
141
|
+
/** Default time-to-live for messages in seconds. Null means no expiration. */
|
|
142
|
+
defaultTtlSeconds?: number | null;
|
|
143
|
+
/** Time in seconds a message is invisible after being received. */
|
|
144
|
+
defaultVisibilityTimeoutSeconds?: number;
|
|
145
|
+
/** Maximum number of delivery attempts before moving to DLQ. */
|
|
146
|
+
defaultMaxRetries?: number;
|
|
147
|
+
/** Maximum number of messages a single client can process concurrently. */
|
|
148
|
+
maxInFlightPerClient?: number;
|
|
149
|
+
/** Retention period for acknowledged messages in seconds. */
|
|
150
|
+
retentionSeconds?: number;
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Result of creating a queue.
|
|
156
|
+
*/
|
|
157
|
+
export interface QueueCreateResult {
|
|
158
|
+
/** The queue name. */
|
|
159
|
+
name: string;
|
|
160
|
+
/** The queue type ('worker' or 'pubsub'). */
|
|
161
|
+
queueType: string;
|
|
162
|
+
}
|
|
163
|
+
|
|
111
164
|
/**
|
|
112
165
|
* Queue service interface for publishing messages.
|
|
113
166
|
*
|
|
@@ -167,6 +220,49 @@ export interface QueueService {
|
|
|
167
220
|
payload: string | object,
|
|
168
221
|
params?: QueuePublishParams
|
|
169
222
|
): Promise<QueuePublishResult>;
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Create a queue with idempotent semantics.
|
|
226
|
+
*
|
|
227
|
+
* If the queue already exists, this returns successfully without error.
|
|
228
|
+
* Safe to call multiple times — uses an internal cache to avoid redundant API calls.
|
|
229
|
+
*
|
|
230
|
+
* @param queueName - The name of the queue to create
|
|
231
|
+
* @param params - Optional creation parameters (queue type, settings, etc.)
|
|
232
|
+
* @returns The create result with queue name and type
|
|
233
|
+
* @throws {QueueValidationError} If the queue name is invalid
|
|
234
|
+
*
|
|
235
|
+
* @example Creating a worker queue
|
|
236
|
+
* ```typescript
|
|
237
|
+
* const result = await ctx.queue.createQueue('task-queue');
|
|
238
|
+
* ```
|
|
239
|
+
*
|
|
240
|
+
* @example Creating a pubsub queue with settings
|
|
241
|
+
* ```typescript
|
|
242
|
+
* const result = await ctx.queue.createQueue('events', {
|
|
243
|
+
* queueType: 'pubsub',
|
|
244
|
+
* settings: { defaultTtlSeconds: 86400 },
|
|
245
|
+
* });
|
|
246
|
+
* ```
|
|
247
|
+
*/
|
|
248
|
+
createQueue(queueName: string, params?: QueueCreateParams): Promise<QueueCreateResult>;
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Delete a queue.
|
|
252
|
+
*
|
|
253
|
+
* Permanently deletes a queue and all its messages. This action cannot be undone.
|
|
254
|
+
* If the queue has already been deleted or does not exist, a {@link QueueNotFoundError} is thrown.
|
|
255
|
+
*
|
|
256
|
+
* @param queueName - The name of the queue to delete
|
|
257
|
+
* @throws {QueueNotFoundError} If the queue does not exist
|
|
258
|
+
* @throws {QueueValidationError} If the queue name is invalid
|
|
259
|
+
*
|
|
260
|
+
* @example Deleting a queue
|
|
261
|
+
* ```typescript
|
|
262
|
+
* await ctx.queue.deleteQueue('old-queue');
|
|
263
|
+
* ```
|
|
264
|
+
*/
|
|
265
|
+
deleteQueue(queueName: string): Promise<void>;
|
|
170
266
|
}
|
|
171
267
|
|
|
172
268
|
// ============================================================================
|
|
@@ -277,6 +373,7 @@ function validatePayloadInternal(payload: string): void {
|
|
|
277
373
|
export class QueueStorageService implements QueueService {
|
|
278
374
|
#adapter: FetchAdapter;
|
|
279
375
|
#baseUrl: string;
|
|
376
|
+
#knownQueues = new Set<string>();
|
|
280
377
|
|
|
281
378
|
/**
|
|
282
379
|
* Creates a new QueueStorageService.
|
|
@@ -388,4 +485,122 @@ export class QueueStorageService implements QueueService {
|
|
|
388
485
|
|
|
389
486
|
throw await toServiceException('POST', url, res.response);
|
|
390
487
|
}
|
|
488
|
+
|
|
489
|
+
/**
|
|
490
|
+
* @inheritdoc
|
|
491
|
+
*/
|
|
492
|
+
async createQueue(queueName: string, params?: QueueCreateParams): Promise<QueueCreateResult> {
|
|
493
|
+
validateQueueNameInternal(queueName);
|
|
494
|
+
|
|
495
|
+
if (this.#knownQueues.has(queueName)) {
|
|
496
|
+
return {
|
|
497
|
+
name: queueName,
|
|
498
|
+
queueType: params?.queueType ?? 'worker',
|
|
499
|
+
};
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
const url = buildUrl(this.#baseUrl, '/queue/create/2026-01-15');
|
|
503
|
+
|
|
504
|
+
const requestBody: Record<string, unknown> = {
|
|
505
|
+
name: queueName,
|
|
506
|
+
queue_type: params?.queueType ?? 'worker',
|
|
507
|
+
};
|
|
508
|
+
|
|
509
|
+
if (params?.description !== undefined) {
|
|
510
|
+
requestBody.description = params.description;
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
if (params?.settings) {
|
|
514
|
+
const settings: Record<string, unknown> = {};
|
|
515
|
+
if (params.settings.defaultTtlSeconds !== undefined) {
|
|
516
|
+
settings.default_ttl_seconds = params.settings.defaultTtlSeconds;
|
|
517
|
+
}
|
|
518
|
+
if (params.settings.defaultVisibilityTimeoutSeconds !== undefined) {
|
|
519
|
+
settings.default_visibility_timeout_seconds =
|
|
520
|
+
params.settings.defaultVisibilityTimeoutSeconds;
|
|
521
|
+
}
|
|
522
|
+
if (params.settings.defaultMaxRetries !== undefined) {
|
|
523
|
+
settings.default_max_retries = params.settings.defaultMaxRetries;
|
|
524
|
+
}
|
|
525
|
+
if (params.settings.maxInFlightPerClient !== undefined) {
|
|
526
|
+
settings.max_in_flight_per_client = params.settings.maxInFlightPerClient;
|
|
527
|
+
}
|
|
528
|
+
if (params.settings.retentionSeconds !== undefined) {
|
|
529
|
+
settings.retention_seconds = params.settings.retentionSeconds;
|
|
530
|
+
}
|
|
531
|
+
if (Object.keys(settings).length > 0) {
|
|
532
|
+
requestBody.settings = settings;
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
const signal = AbortSignal.timeout(30_000);
|
|
537
|
+
const res = await this.#adapter.invoke<QueueCreateResult>(url, {
|
|
538
|
+
method: 'POST',
|
|
539
|
+
signal,
|
|
540
|
+
body: JSON.stringify(requestBody),
|
|
541
|
+
contentType: 'application/json',
|
|
542
|
+
telemetry: {
|
|
543
|
+
name: 'agentuity.queue.create',
|
|
544
|
+
attributes: {
|
|
545
|
+
queueName,
|
|
546
|
+
},
|
|
547
|
+
},
|
|
548
|
+
});
|
|
549
|
+
|
|
550
|
+
if (res.ok) {
|
|
551
|
+
const data = res.data as unknown as Record<string, unknown>;
|
|
552
|
+
this.#knownQueues.add(queueName);
|
|
553
|
+
return {
|
|
554
|
+
name: (data.name as string) ?? queueName,
|
|
555
|
+
queueType: (data.queue_type as string) ?? params?.queueType ?? 'worker',
|
|
556
|
+
};
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
if (res.response.status === 409) {
|
|
560
|
+
this.#knownQueues.add(queueName);
|
|
561
|
+
return {
|
|
562
|
+
name: queueName,
|
|
563
|
+
queueType: params?.queueType ?? 'worker',
|
|
564
|
+
};
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
throw await toServiceException('POST', url, res.response);
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
/**
|
|
571
|
+
* @inheritdoc
|
|
572
|
+
*/
|
|
573
|
+
async deleteQueue(queueName: string): Promise<void> {
|
|
574
|
+
validateQueueNameInternal(queueName);
|
|
575
|
+
|
|
576
|
+
const url = buildUrl(
|
|
577
|
+
this.#baseUrl,
|
|
578
|
+
`/queue/delete/2026-01-15/${encodeURIComponent(queueName)}`
|
|
579
|
+
);
|
|
580
|
+
|
|
581
|
+
const signal = AbortSignal.timeout(30_000);
|
|
582
|
+
const res = await this.#adapter.invoke<void>(url, {
|
|
583
|
+
method: 'DELETE',
|
|
584
|
+
signal,
|
|
585
|
+
telemetry: {
|
|
586
|
+
name: 'agentuity.queue.delete',
|
|
587
|
+
attributes: {
|
|
588
|
+
queueName,
|
|
589
|
+
},
|
|
590
|
+
},
|
|
591
|
+
});
|
|
592
|
+
|
|
593
|
+
if (res.ok) {
|
|
594
|
+
this.#knownQueues.delete(queueName);
|
|
595
|
+
return;
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
if (res.response.status === 404) {
|
|
599
|
+
throw new QueueNotFoundError({
|
|
600
|
+
message: `Queue not found: ${queueName}`,
|
|
601
|
+
});
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
throw await toServiceException('DELETE', url, res.response);
|
|
605
|
+
}
|
|
391
606
|
}
|
package/src/services/stream.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import { StructuredError } from '../error.ts';
|
|
1
2
|
import { safeStringify } from '../json.ts';
|
|
2
|
-
import { FetchAdapter } from './adapter.ts';
|
|
3
3
|
import { buildUrl, toServiceException } from './_util.ts';
|
|
4
|
-
import {
|
|
4
|
+
import type { FetchAdapter } from './adapter.ts';
|
|
5
5
|
import type { ListParams } from './pagination.ts';
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -19,17 +19,11 @@ export const STREAM_MAX_TTL_SECONDS = 7776000;
|
|
|
19
19
|
*/
|
|
20
20
|
export const STREAM_DEFAULT_TTL_SECONDS = 2592000;
|
|
21
21
|
|
|
22
|
-
//
|
|
23
|
-
//
|
|
24
|
-
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
28
|
-
const streamWeb = isNode ? require('stream/web') : globalThis;
|
|
29
|
-
const NativeWritableStream = streamWeb.WritableStream as typeof WritableStream;
|
|
30
|
-
const NativeReadableStream = streamWeb.ReadableStream as typeof ReadableStream;
|
|
31
|
-
const NativeCompressionStream = (streamWeb.CompressionStream ??
|
|
32
|
-
globalThis.CompressionStream) as typeof CompressionStream;
|
|
22
|
+
// Web Streams API (ReadableStream, WritableStream, CompressionStream) are globally
|
|
23
|
+
// available in all modern runtimes: Node.js 18+, Bun, Deno, and browsers.
|
|
24
|
+
const NativeWritableStream = globalThis.WritableStream;
|
|
25
|
+
const NativeReadableStream = globalThis.ReadableStream;
|
|
26
|
+
const NativeCompressionStream = globalThis.CompressionStream;
|
|
33
27
|
|
|
34
28
|
/**
|
|
35
29
|
* Properties for creating a stream
|
package/src/services/task.ts
CHANGED
|
@@ -42,6 +42,28 @@ export interface EntityRef {
|
|
|
42
42
|
name: string;
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
+
/**
|
|
46
|
+
* The type of user entity.
|
|
47
|
+
*
|
|
48
|
+
* - `'human'` — A human user.
|
|
49
|
+
* - `'agent'` — An AI agent.
|
|
50
|
+
*/
|
|
51
|
+
export type UserType = 'human' | 'agent';
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* A reference to a user entity with type discrimination.
|
|
55
|
+
* Extends {@link EntityRef} with a {@link UserEntityRef.type | type} field
|
|
56
|
+
* to distinguish between human users and AI agents.
|
|
57
|
+
*/
|
|
58
|
+
export interface UserEntityRef extends EntityRef {
|
|
59
|
+
/**
|
|
60
|
+
* The type of user. Defaults to `'human'` if not specified.
|
|
61
|
+
*
|
|
62
|
+
* @default 'human'
|
|
63
|
+
*/
|
|
64
|
+
type?: UserType;
|
|
65
|
+
}
|
|
66
|
+
|
|
45
67
|
/**
|
|
46
68
|
* A work item in the task management system.
|
|
47
69
|
*
|
|
@@ -130,13 +152,13 @@ export interface Task {
|
|
|
130
152
|
closed_id?: string;
|
|
131
153
|
|
|
132
154
|
/** Reference to the user who created the task. */
|
|
133
|
-
creator?:
|
|
155
|
+
creator?: UserEntityRef;
|
|
134
156
|
|
|
135
157
|
/** Reference to the user the task is assigned to. */
|
|
136
|
-
assignee?:
|
|
158
|
+
assignee?: UserEntityRef;
|
|
137
159
|
|
|
138
160
|
/** Reference to the user who closed the task. */
|
|
139
|
-
closer?:
|
|
161
|
+
closer?: UserEntityRef;
|
|
140
162
|
|
|
141
163
|
/** Reference to the project this task belongs to. */
|
|
142
164
|
project?: EntityRef;
|
|
@@ -171,7 +193,7 @@ export interface Comment {
|
|
|
171
193
|
user_id: string;
|
|
172
194
|
|
|
173
195
|
/** Reference to the comment author with display name. */
|
|
174
|
-
author?:
|
|
196
|
+
author?: UserEntityRef;
|
|
175
197
|
|
|
176
198
|
/**
|
|
177
199
|
* The comment text content.
|
|
@@ -286,11 +308,11 @@ export interface CreateTaskParams {
|
|
|
286
308
|
*/
|
|
287
309
|
assigned_id?: string;
|
|
288
310
|
|
|
289
|
-
/** Reference to the user creating the task (id and
|
|
290
|
-
creator?:
|
|
311
|
+
/** Reference to the user creating the task (id, name, and optional type). */
|
|
312
|
+
creator?: UserEntityRef;
|
|
291
313
|
|
|
292
314
|
/** Reference to the user being assigned the task. */
|
|
293
|
-
assignee?:
|
|
315
|
+
assignee?: UserEntityRef;
|
|
294
316
|
|
|
295
317
|
/** Reference to the project this task belongs to. */
|
|
296
318
|
project?: EntityRef;
|
|
@@ -349,10 +371,10 @@ export interface UpdateTaskParams {
|
|
|
349
371
|
closed_id?: string;
|
|
350
372
|
|
|
351
373
|
/** Reference to the user being assigned the task. */
|
|
352
|
-
assignee?:
|
|
374
|
+
assignee?: UserEntityRef;
|
|
353
375
|
|
|
354
376
|
/** Reference to the user closing the task. */
|
|
355
|
-
closer?:
|
|
377
|
+
closer?: UserEntityRef;
|
|
356
378
|
|
|
357
379
|
/** Reference to the project this task belongs to. */
|
|
358
380
|
project?: EntityRef;
|
|
@@ -425,6 +447,62 @@ export interface ListTasksResult {
|
|
|
425
447
|
offset: number;
|
|
426
448
|
}
|
|
427
449
|
|
|
450
|
+
/**
|
|
451
|
+
* Parameters for batch-deleting tasks by filter.
|
|
452
|
+
* At least one filter must be provided.
|
|
453
|
+
*/
|
|
454
|
+
export interface BatchDeleteTasksParams {
|
|
455
|
+
/** Filter by task status. */
|
|
456
|
+
status?: TaskStatus;
|
|
457
|
+
|
|
458
|
+
/** Filter by task type. */
|
|
459
|
+
type?: TaskType;
|
|
460
|
+
|
|
461
|
+
/** Filter by priority level. */
|
|
462
|
+
priority?: TaskPriority;
|
|
463
|
+
|
|
464
|
+
/** Filter by parent task ID (delete subtasks). */
|
|
465
|
+
parent_id?: string;
|
|
466
|
+
|
|
467
|
+
/** Filter by creator ID. */
|
|
468
|
+
created_id?: string;
|
|
469
|
+
|
|
470
|
+
/**
|
|
471
|
+
* Delete tasks older than this duration.
|
|
472
|
+
* Accepts Go-style duration strings: `'30m'`, `'24h'`, `'7d'`, `'2w'`.
|
|
473
|
+
*/
|
|
474
|
+
older_than?: string;
|
|
475
|
+
|
|
476
|
+
/**
|
|
477
|
+
* Maximum number of tasks to delete.
|
|
478
|
+
* @default 50
|
|
479
|
+
* @maximum 200
|
|
480
|
+
*/
|
|
481
|
+
limit?: number;
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
/**
|
|
485
|
+
* A single task that was deleted in a batch operation.
|
|
486
|
+
*/
|
|
487
|
+
export interface BatchDeletedTask {
|
|
488
|
+
/** The ID of the deleted task. */
|
|
489
|
+
id: string;
|
|
490
|
+
|
|
491
|
+
/** The title of the deleted task. */
|
|
492
|
+
title: string;
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
/**
|
|
496
|
+
* Result of a batch delete operation.
|
|
497
|
+
*/
|
|
498
|
+
export interface BatchDeleteTasksResult {
|
|
499
|
+
/** Array of tasks that were deleted. */
|
|
500
|
+
deleted: BatchDeletedTask[];
|
|
501
|
+
|
|
502
|
+
/** Total number of tasks deleted. */
|
|
503
|
+
count: number;
|
|
504
|
+
}
|
|
505
|
+
|
|
428
506
|
/**
|
|
429
507
|
* Paginated list of changelog entries for a task.
|
|
430
508
|
*/
|
|
@@ -484,7 +562,7 @@ export interface Attachment {
|
|
|
484
562
|
user_id: string;
|
|
485
563
|
|
|
486
564
|
/** Reference to the uploader with display name. */
|
|
487
|
-
author?:
|
|
565
|
+
author?: UserEntityRef;
|
|
488
566
|
|
|
489
567
|
/** Original filename of the uploaded file. */
|
|
490
568
|
filename: string;
|
|
@@ -554,8 +632,8 @@ export interface ListAttachmentsResult {
|
|
|
554
632
|
* List of all users who have been referenced in tasks (as creators, assignees, or closers).
|
|
555
633
|
*/
|
|
556
634
|
export interface ListUsersResult {
|
|
557
|
-
/** Array of user entity references. */
|
|
558
|
-
users:
|
|
635
|
+
/** Array of user entity references with type information. */
|
|
636
|
+
users: UserEntityRef[];
|
|
559
637
|
}
|
|
560
638
|
|
|
561
639
|
/**
|
|
@@ -672,6 +750,15 @@ export interface TaskStorage {
|
|
|
672
750
|
*/
|
|
673
751
|
softDelete(id: string): Promise<Task>;
|
|
674
752
|
|
|
753
|
+
/**
|
|
754
|
+
* Batch soft-delete tasks matching the given filters.
|
|
755
|
+
* At least one filter must be provided.
|
|
756
|
+
*
|
|
757
|
+
* @param params - Filters to select which tasks to delete
|
|
758
|
+
* @returns The list of deleted tasks and count
|
|
759
|
+
*/
|
|
760
|
+
batchDelete(params: BatchDeleteTasksParams): Promise<BatchDeleteTasksResult>;
|
|
761
|
+
|
|
675
762
|
/**
|
|
676
763
|
* Get the changelog (audit trail) for a task.
|
|
677
764
|
*
|
|
@@ -867,6 +954,9 @@ export interface TaskStorage {
|
|
|
867
954
|
/** API version string used for task CRUD, comment, tag, and attachment endpoints. */
|
|
868
955
|
const TASK_API_VERSION = '2026-02-24';
|
|
869
956
|
|
|
957
|
+
/** Maximum number of tasks that can be deleted in a single batch request. */
|
|
958
|
+
const MAX_BATCH_DELETE_LIMIT = 200;
|
|
959
|
+
|
|
870
960
|
/** API version string used for the task activity analytics endpoint. */
|
|
871
961
|
const TASK_ACTIVITY_API_VERSION = '2026-02-28';
|
|
872
962
|
|
|
@@ -1383,6 +1473,77 @@ export class TaskStorageService implements TaskStorage {
|
|
|
1383
1473
|
throw await toServiceException('POST', url, res.response);
|
|
1384
1474
|
}
|
|
1385
1475
|
|
|
1476
|
+
/**
|
|
1477
|
+
* Batch soft-delete tasks matching the given filters.
|
|
1478
|
+
* At least one filter must be provided. The server caps the limit at 200.
|
|
1479
|
+
*
|
|
1480
|
+
* @param params - Filters to select which tasks to delete
|
|
1481
|
+
* @returns The list of deleted tasks and count
|
|
1482
|
+
* @throws {@link ServiceException} if the API request fails
|
|
1483
|
+
*
|
|
1484
|
+
* @example
|
|
1485
|
+
* ```typescript
|
|
1486
|
+
* const result = await tasks.batchDelete({ status: 'closed', older_than: '7d', limit: 50 });
|
|
1487
|
+
* console.log(`Deleted ${result.count} tasks`);
|
|
1488
|
+
* ```
|
|
1489
|
+
*/
|
|
1490
|
+
async batchDelete(params: BatchDeleteTasksParams): Promise<BatchDeleteTasksResult> {
|
|
1491
|
+
const hasFilter =
|
|
1492
|
+
params.status ||
|
|
1493
|
+
params.type ||
|
|
1494
|
+
params.priority ||
|
|
1495
|
+
params.parent_id ||
|
|
1496
|
+
params.created_id ||
|
|
1497
|
+
params.older_than;
|
|
1498
|
+
if (!hasFilter) {
|
|
1499
|
+
throw new Error('At least one filter is required for batch delete');
|
|
1500
|
+
}
|
|
1501
|
+
if (params.limit !== undefined && params.limit > MAX_BATCH_DELETE_LIMIT) {
|
|
1502
|
+
throw new Error(
|
|
1503
|
+
`Batch delete limit must not exceed ${MAX_BATCH_DELETE_LIMIT} (got ${params.limit})`
|
|
1504
|
+
);
|
|
1505
|
+
}
|
|
1506
|
+
|
|
1507
|
+
const url = buildUrl(this.#baseUrl, `/task/delete/batch/${TASK_API_VERSION}`);
|
|
1508
|
+
const signal = AbortSignal.timeout(60_000);
|
|
1509
|
+
|
|
1510
|
+
const body: Record<string, unknown> = {};
|
|
1511
|
+
if (params.status) body.status = params.status;
|
|
1512
|
+
if (params.type) body.type = params.type;
|
|
1513
|
+
if (params.priority) body.priority = params.priority;
|
|
1514
|
+
if (params.parent_id) body.parent_id = params.parent_id;
|
|
1515
|
+
if (params.created_id) body.created_id = params.created_id;
|
|
1516
|
+
if (params.older_than) body.older_than = params.older_than;
|
|
1517
|
+
if (params.limit !== undefined) body.limit = params.limit;
|
|
1518
|
+
|
|
1519
|
+
const res = await this.#adapter.invoke<TaskResponse<BatchDeleteTasksResult>>(url, {
|
|
1520
|
+
method: 'POST',
|
|
1521
|
+
body: safeStringify(body),
|
|
1522
|
+
headers: { 'Content-Type': 'application/json' },
|
|
1523
|
+
signal,
|
|
1524
|
+
telemetry: {
|
|
1525
|
+
name: 'agentuity.task.batchDelete',
|
|
1526
|
+
attributes: {
|
|
1527
|
+
...(params.status ? { status: params.status } : {}),
|
|
1528
|
+
...(params.type ? { type: params.type } : {}),
|
|
1529
|
+
...(params.older_than ? { older_than: params.older_than } : {}),
|
|
1530
|
+
},
|
|
1531
|
+
},
|
|
1532
|
+
});
|
|
1533
|
+
|
|
1534
|
+
if (res.ok) {
|
|
1535
|
+
if (res.data.success) {
|
|
1536
|
+
return res.data.data;
|
|
1537
|
+
}
|
|
1538
|
+
throw new TaskStorageResponseError({
|
|
1539
|
+
status: res.response.status,
|
|
1540
|
+
message: res.data.message,
|
|
1541
|
+
});
|
|
1542
|
+
}
|
|
1543
|
+
|
|
1544
|
+
throw await toServiceException('POST', url, res.response);
|
|
1545
|
+
}
|
|
1546
|
+
|
|
1386
1547
|
/**
|
|
1387
1548
|
* Create a comment on a task.
|
|
1388
1549
|
*
|