@ganju/utils 0.0.14 → 0.0.16

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 (111) hide show
  1. package/dist/channelCustomer.d.ts +99 -0
  2. package/dist/channelCustomer.d.ts.map +1 -0
  3. package/dist/channelCustomer.js +533 -0
  4. package/dist/channelDebounce.d.ts +7 -0
  5. package/dist/channelDebounce.d.ts.map +1 -1
  6. package/dist/chunkOverlap.d.ts +2 -0
  7. package/dist/chunkOverlap.d.ts.map +1 -0
  8. package/dist/chunkOverlap.js +9 -0
  9. package/dist/chunking.d.ts.map +1 -1
  10. package/dist/chunking.js +24 -4
  11. package/dist/citations.d.ts +28 -0
  12. package/dist/citations.d.ts.map +1 -0
  13. package/dist/citations.js +111 -0
  14. package/dist/constants.d.ts +49 -0
  15. package/dist/constants.d.ts.map +1 -1
  16. package/dist/constants.js +202 -17
  17. package/dist/data.d.ts +9 -0
  18. package/dist/data.d.ts.map +1 -0
  19. package/dist/data.js +78 -0
  20. package/dist/dataApi.d.ts +511 -0
  21. package/dist/dataApi.d.ts.map +1 -0
  22. package/dist/dataApi.js +355 -0
  23. package/dist/dataCompiler.d.ts +68 -0
  24. package/dist/dataCompiler.d.ts.map +1 -0
  25. package/dist/dataCompiler.js +726 -0
  26. package/dist/dataDdl.d.ts +29 -0
  27. package/dist/dataDdl.d.ts.map +1 -0
  28. package/dist/dataDdl.js +354 -0
  29. package/dist/dataEngine.d.ts +143 -0
  30. package/dist/dataEngine.d.ts.map +1 -0
  31. package/dist/dataEngine.js +2022 -0
  32. package/dist/dataIdentifiers.d.ts +8 -0
  33. package/dist/dataIdentifiers.d.ts.map +1 -0
  34. package/dist/dataIdentifiers.js +55 -0
  35. package/dist/dataImport.d.ts +77 -0
  36. package/dist/dataImport.d.ts.map +1 -0
  37. package/dist/dataImport.js +450 -0
  38. package/dist/dataRpc.d.ts +131 -0
  39. package/dist/dataRpc.d.ts.map +1 -0
  40. package/dist/dataRpc.js +2 -0
  41. package/dist/dataTypes.d.ts +157 -0
  42. package/dist/dataTypes.d.ts.map +1 -0
  43. package/dist/dataTypes.js +160 -0
  44. package/dist/index.d.ts +570 -36
  45. package/dist/index.d.ts.map +1 -1
  46. package/dist/index.js +72 -0
  47. package/dist/jsonSchemaToZodShape.d.ts +5 -1
  48. package/dist/jsonSchemaToZodShape.d.ts.map +1 -1
  49. package/dist/jsonSchemaToZodShape.js +21 -9
  50. package/dist/oauth.d.ts +14 -0
  51. package/dist/oauth.d.ts.map +1 -1
  52. package/dist/oauth.js +42 -2
  53. package/dist/pagination.d.ts +47 -0
  54. package/dist/pagination.d.ts.map +1 -0
  55. package/dist/pagination.js +160 -0
  56. package/dist/processQueueBatch.d.ts +6 -1
  57. package/dist/processQueueBatch.d.ts.map +1 -1
  58. package/dist/processQueueBatch.js +23 -10
  59. package/dist/queueFailure.d.ts +14 -0
  60. package/dist/queueFailure.d.ts.map +1 -0
  61. package/dist/queueFailure.js +43 -0
  62. package/dist/resourceRerank.d.ts +3 -2
  63. package/dist/resourceRerank.d.ts.map +1 -1
  64. package/dist/resourceRerank.js +8 -3
  65. package/dist/schema.d.ts +374 -29
  66. package/dist/schema.d.ts.map +1 -1
  67. package/dist/schema.js +290 -6
  68. package/dist/ssrf.d.ts +1 -0
  69. package/dist/ssrf.d.ts.map +1 -1
  70. package/dist/ssrf.js +48 -12
  71. package/dist/toolConfirmation.d.ts +48 -0
  72. package/dist/toolConfirmation.d.ts.map +1 -1
  73. package/dist/toolConfirmation.js +75 -1
  74. package/dist/toolCount.d.ts +13 -0
  75. package/dist/toolCount.d.ts.map +1 -0
  76. package/dist/toolCount.js +45 -0
  77. package/dist/toolLint.d.ts +1 -1
  78. package/dist/toolLint.d.ts.map +1 -1
  79. package/dist/toolLint.js +20 -0
  80. package/dist/untrustedContent.d.ts +135 -0
  81. package/dist/untrustedContent.d.ts.map +1 -0
  82. package/dist/untrustedContent.js +402 -0
  83. package/package.json +17 -1
  84. package/src/channelCustomer.ts +604 -0
  85. package/src/channelDebounce.ts +17 -0
  86. package/src/chunkOverlap.ts +6 -0
  87. package/src/chunking.ts +25 -4
  88. package/src/citations.ts +127 -0
  89. package/src/constants.ts +219 -17
  90. package/src/data.ts +74 -0
  91. package/src/dataApi.ts +428 -0
  92. package/src/dataCompiler.ts +948 -0
  93. package/src/dataDdl.ts +419 -0
  94. package/src/dataEngine.ts +2753 -0
  95. package/src/dataIdentifiers.ts +63 -0
  96. package/src/dataImport.ts +554 -0
  97. package/src/dataRpc.ts +121 -0
  98. package/src/dataTypes.ts +312 -0
  99. package/src/index.ts +156 -2
  100. package/src/jsonSchemaToZodShape.ts +31 -13
  101. package/src/oauth.ts +42 -1
  102. package/src/pagination.ts +193 -0
  103. package/src/processQueueBatch.ts +42 -12
  104. package/src/queueFailure.ts +63 -0
  105. package/src/resourceRerank.ts +10 -3
  106. package/src/schema.ts +346 -4
  107. package/src/ssrf.ts +40 -11
  108. package/src/toolConfirmation.ts +123 -0
  109. package/src/toolCount.ts +53 -0
  110. package/src/toolLint.ts +27 -0
  111. package/src/untrustedContent.ts +476 -0
package/src/dataRpc.ts ADDED
@@ -0,0 +1,121 @@
1
+ // The methods a project's database object answers over RPC. apps/data's
2
+ // ProjectDatabase implements it; apps/api, apps/mcp and apps/tool-broker call
3
+ // it through databaseStub. Every method resolves to a DataResult.
4
+ import type {
5
+ DataCaller,
6
+ DataDeleteImpact,
7
+ DataResult,
8
+ DataSchema,
9
+ DataTable,
10
+ DataTableCopy
11
+ } from './dataTypes';
12
+
13
+ export type ExportFormat = 'jsonl' | 'csv';
14
+
15
+ export interface ExportFile {
16
+ // null for schema.json
17
+ table: string | null;
18
+ key: string;
19
+ rows: number;
20
+ bytes: number;
21
+ }
22
+
23
+ export interface ExportState {
24
+ id: string;
25
+ format: ExportFormat;
26
+ status: 'running' | 'done' | 'failed';
27
+ startedAt: string;
28
+ finishedAt: string | null;
29
+ actor: string;
30
+ tables: string[];
31
+ tableIndex: number;
32
+ afterId: number;
33
+ upload: {
34
+ key: string;
35
+ uploadId: string;
36
+ parts: { partNumber: number; etag: string }[];
37
+ rows: number;
38
+ bytes: number;
39
+ // Bytes read but not yet uploaded, kept in R2 between steps: every part
40
+ // but the last must be exactly the same size.
41
+ carryKey: string | null;
42
+ } | null;
43
+ files: ExportFile[];
44
+ error: string | null;
45
+ }
46
+
47
+ export interface DatabaseInfo {
48
+ artifactId: string | null;
49
+ name: string | null;
50
+ initializedAt: string | null;
51
+ deletedAt: string | null;
52
+ firstWriteAt: string | null;
53
+ schemaVersion: number;
54
+ size: number;
55
+ tables: { name: string; label: string | null; columns: number }[];
56
+ // A column change copying a large table in the background: table changes,
57
+ // and writes that would change its rows, wait while it runs.
58
+ copy: DataTableCopy | null;
59
+ }
60
+
61
+ export interface RestoreResult {
62
+ bookmark: string;
63
+ undoBookmark: string;
64
+ }
65
+
66
+ type R<T> = Promise<DataResult<T>>;
67
+
68
+ export interface ProjectDatabaseRpc {
69
+ init(args: { artifactId: string; name: string }): R<DatabaseInfo>;
70
+ info(): R<DatabaseInfo>;
71
+ rename(args: { name: string }): R<DatabaseInfo>;
72
+ size(): R<{ bytes: number }>;
73
+ markDeleted(
74
+ caller: DataCaller
75
+ ): R<{ deletedAt: string | null; bookmark: string }>;
76
+ undelete(caller: DataCaller): R<DatabaseInfo>;
77
+ purge(): R<{ purged: true; bookmark: string }>;
78
+ currentBookmark(): R<{ bookmark: string }>;
79
+ restoreTo(caller: DataCaller, args: { timestamp: number }): R<RestoreResult>;
80
+ restoreToBookmark(args: { bookmark: string }): R<RestoreResult>;
81
+ schemaRead(): R<DataSchema>;
82
+ createTable(caller: DataCaller, input: unknown): R<DataTable>;
83
+ updateTable(caller: DataCaller, table: string, patch: unknown): R<DataTable>;
84
+ dropTable(
85
+ caller: DataCaller,
86
+ table: string
87
+ ): R<{ dropped: string; bookmark: string }>;
88
+ addColumn(caller: DataCaller, table: string, input: unknown): R<DataTable>;
89
+ updateColumn(
90
+ caller: DataCaller,
91
+ table: string,
92
+ column: string,
93
+ patch: unknown
94
+ ): R<{ table: DataTable; bookmark: string | null; copy: DataTableCopy | null }>;
95
+ dropColumn(
96
+ caller: DataCaller,
97
+ table: string,
98
+ column: string
99
+ ): R<{ table: DataTable; bookmark: string; copy: DataTableCopy | null }>;
100
+ // Forgets a failed background copy once the owner has seen why.
101
+ dismissCopy(caller: DataCaller): R<{ copy: null }>;
102
+ describe(caller: DataCaller, args?: unknown): R<unknown>;
103
+ query(caller: DataCaller, args: unknown): R<unknown>;
104
+ write(
105
+ caller: DataCaller,
106
+ args: unknown
107
+ ): R<{ ok: true; results: unknown[] }>;
108
+ deleteImpact(
109
+ caller: DataCaller,
110
+ args: { table: string; ids?: number[] }
111
+ ): R<DataDeleteImpact>;
112
+ history(
113
+ caller: DataCaller,
114
+ args: { table: string; id: number; limit?: number; cursor?: number }
115
+ ): R<unknown>;
116
+ exportStart(
117
+ caller: DataCaller,
118
+ args?: { format?: ExportFormat }
119
+ ): R<{ exportId: string; status: ExportState['status'] }>;
120
+ exportStatus(args?: { exportId?: string }): R<ExportState>;
121
+ }
@@ -0,0 +1,312 @@
1
+ // The shapes and limits shared by a project's database object (apps/data),
2
+ // the workers that call it, and the tests. Pure: nothing here touches SQLite.
3
+
4
+ export const DATA_COLUMN_TYPES = [
5
+ 'text',
6
+ 'long_text',
7
+ 'integer',
8
+ 'decimal',
9
+ 'boolean',
10
+ 'date',
11
+ 'datetime',
12
+ 'enum',
13
+ 'json',
14
+ 'email',
15
+ 'url',
16
+ 'phone',
17
+ 'relation',
18
+ 'file'
19
+ ] as const;
20
+ export type DataColumnType = (typeof DATA_COLUMN_TYPES)[number];
21
+
22
+ // What the assistant may do with a table when the caller is restricted (a
23
+ // channel bot). Owners, the dashboard, the CLI and functions see every table.
24
+ export const DATA_ACCESS_LEVELS = ['none', 'read', 'add', 'full'] as const;
25
+ export type DataAccess = (typeof DATA_ACCESS_LEVELS)[number];
26
+ export const DATA_ACCESS_RANK: Record<DataAccess, number> = {
27
+ none: 0,
28
+ read: 1,
29
+ add: 2,
30
+ full: 3
31
+ };
32
+
33
+ export const DATA_ON_DELETE = ['restrict', 'cascade', 'set_null'] as const;
34
+ export type DataOnDelete = (typeof DATA_ON_DELETE)[number];
35
+
36
+ export type DataDefaultValue = string | number | boolean | null;
37
+
38
+ // A column as the owner defines it: the dashboard's form, `ganju.data.json`
39
+ // and the table-create body all use this shape.
40
+ export interface DataColumnInput {
41
+ name: string;
42
+ type: DataColumnType;
43
+ label?: string | null;
44
+ description?: string | null;
45
+ required?: boolean;
46
+ unique?: boolean;
47
+ filterable?: boolean;
48
+ searchable?: boolean;
49
+ personal?: boolean;
50
+ // enum
51
+ values?: string[];
52
+ // relation: the table it points at, and what deleting that row does
53
+ table?: string;
54
+ onDelete?: DataOnDelete;
55
+ // integer / decimal: the lowest value the column may hold
56
+ min?: number | null;
57
+ default?: DataDefaultValue;
58
+ }
59
+
60
+ export interface DataTableInput {
61
+ name: string;
62
+ label?: string | null;
63
+ description?: string | null;
64
+ displayColumn?: string | null;
65
+ access?: DataAccess;
66
+ customerScoped?: boolean;
67
+ history?: boolean;
68
+ columns: DataColumnInput[];
69
+ }
70
+
71
+ // A column as the database object stores it: the input plus its stable id,
72
+ // which names its indexes and constraints so a rename never orphans them.
73
+ export interface DataColumn {
74
+ id: number;
75
+ name: string;
76
+ type: DataColumnType;
77
+ label: string | null;
78
+ description: string | null;
79
+ required: boolean;
80
+ unique: boolean;
81
+ filterable: boolean;
82
+ searchable: boolean;
83
+ personal: boolean;
84
+ values: string[] | null;
85
+ table: string | null;
86
+ onDelete: DataOnDelete | null;
87
+ min: number | null;
88
+ default: DataDefaultValue | undefined;
89
+ position: number;
90
+ }
91
+
92
+ export interface DataTable {
93
+ id: number;
94
+ name: string;
95
+ label: string | null;
96
+ description: string | null;
97
+ displayColumn: string | null;
98
+ access: DataAccess;
99
+ customerScoped: boolean;
100
+ history: boolean;
101
+ position: number;
102
+ columns: DataColumn[];
103
+ }
104
+
105
+ export interface DataSchema {
106
+ tables: DataTable[];
107
+ }
108
+
109
+ // Who is calling and under which rules. `actor` is recorded on every row a
110
+ // call writes; the storage layer refuses a write without one.
111
+ export interface DataCaller {
112
+ // user:<id> · cli:<tokenId> · mcp:<userId> · channel:<participantId> ·
113
+ // function:<toolName> · trigger:<id> · system:<job>
114
+ actor: string;
115
+ // Apply each table's assistant access. Set for channel bots only.
116
+ restricted?: boolean;
117
+ // Customer-scoped tables: fill and filter `participant_id` with this.
118
+ participantId?: string;
119
+ // Datetimes come back in this zone, with the offset.
120
+ timeZone?: string;
121
+ limits?: DataCallerLimits;
122
+ }
123
+
124
+ export interface DataCallerLimits {
125
+ // Writes that add data stop at this size (the plan's ceiling).
126
+ maxBytes?: number | null;
127
+ maxTables?: number | null;
128
+ // The organization left the paid plan: reads and exports only.
129
+ readOnly?: boolean;
130
+ }
131
+
132
+ export interface DataUsage {
133
+ rowsRead: number;
134
+ rowsWritten: number;
135
+ }
136
+
137
+ export const DATA_ERROR_CODES = [
138
+ 'invalid',
139
+ 'not_found',
140
+ 'forbidden',
141
+ 'conflict',
142
+ 'constraint',
143
+ 'guard',
144
+ 'too_large',
145
+ 'full',
146
+ 'read_only',
147
+ 'deleted',
148
+ 'not_initialised',
149
+ 'restore',
150
+ 'internal'
151
+ ] as const;
152
+ export type DataErrorCode = (typeof DATA_ERROR_CODES)[number];
153
+
154
+ // The one error the database object returns. Its message is written for the
155
+ // person or model that made the call, never raw SQLite text.
156
+ export class DataError extends Error {
157
+ readonly code: DataErrorCode;
158
+ readonly details: Record<string, unknown> | undefined;
159
+
160
+ constructor(
161
+ message: string,
162
+ code: DataErrorCode = 'invalid',
163
+ details?: Record<string, unknown>
164
+ ) {
165
+ super(message);
166
+ this.name = 'DataError';
167
+ this.code = code;
168
+ this.details = details;
169
+ }
170
+
171
+ // What the API answers with; its error handler reads both.
172
+ get status(): 400 | 403 | 404 | 409 | 500 {
173
+ return DATA_ERROR_STATUS[this.code];
174
+ }
175
+
176
+ toBody(): Record<string, unknown> {
177
+ return { code: this.code, ...(this.details ? { details: this.details } : {}) };
178
+ }
179
+ }
180
+
181
+ const DATA_ERROR_STATUS: Record<DataErrorCode, 400 | 403 | 404 | 409 | 500> = {
182
+ invalid: 400,
183
+ not_found: 404,
184
+ forbidden: 403,
185
+ conflict: 409,
186
+ constraint: 409,
187
+ guard: 409,
188
+ too_large: 400,
189
+ full: 409,
190
+ read_only: 403,
191
+ deleted: 409,
192
+ not_initialised: 404,
193
+ restore: 400,
194
+ internal: 500
195
+ };
196
+
197
+ export const isDataError = (error: unknown): error is DataError =>
198
+ error instanceof DataError;
199
+
200
+ // What every database object method returns. Errors travel as values, not
201
+ // throws: an RPC exception keeps only its message, and the caller needs the
202
+ // code and the rows read before it.
203
+ export type DataResult<T> =
204
+ | { ok: true; value: T; usage: DataUsage }
205
+ | {
206
+ ok: false;
207
+ error: {
208
+ code: DataErrorCode;
209
+ message: string;
210
+ details?: Record<string, unknown>;
211
+ };
212
+ usage: DataUsage;
213
+ };
214
+
215
+ // Limits. SQLite in a Durable Object allows 100 columns per table, 100 bound
216
+ // parameters per statement and 100 KB per statement; the rest are ours.
217
+ export const DATA_MAX_PARAMS = 100;
218
+ export const DATA_MAX_STATEMENT_BYTES = 90_000;
219
+ // 100 minus id, created_at, updated_at, version, created_by, updated_by and
220
+ // participant_id.
221
+ export const DATA_MAX_COLUMNS = 93;
222
+ export const DATA_MAX_TABLES = 50;
223
+ export const DATA_DEFAULT_PAGE = 20;
224
+ export const DATA_MAX_PAGE = 500;
225
+ export const DATA_MAX_RESULT_BYTES = 1024 * 1024;
226
+ // Past this many rows, an aggregate or a sort on an unindexed column needs a
227
+ // filter on an indexed one: the object serves one request at a time.
228
+ export const DATA_LARGE_TABLE_ROWS = 200_000;
229
+ export const DATA_MAX_WRITE_OPERATIONS = 50;
230
+ export const DATA_MAX_INSERT_ROWS = 500;
231
+ export const DATA_MAX_ROWS_PER_WRITE = 5_000;
232
+ export const DATA_MAX_VALUE_BYTES = 1_000_000;
233
+ export const DATA_MAX_DESCRIPTION = 300;
234
+ export const DATA_MAX_LABEL = 100;
235
+ export const DATA_MAX_ENUM_VALUES = 100;
236
+ export const DATA_MAX_IN_VALUES = 50;
237
+ export const DATA_MAX_SORT_KEYS = 3;
238
+ export const DATA_MAX_AGGREGATES = 5;
239
+ export const DATA_MAX_GROUP_BY = 3;
240
+ export const DATA_MAX_GROUPS = 100;
241
+ // A type change copies the table in one request up to this size. A larger
242
+ // table is copied in the background, this many rows a step (tens of
243
+ // milliseconds, so other requests are served in between), and writes that
244
+ // would change its rows wait until it is done.
245
+ export const DATA_REBUILD_MAX_ROWS = 100_000;
246
+ export const DATA_COPY_STEP_ROWS = 5_000;
247
+ // A delete preview follows cascades through up to this many rows; past it,
248
+ // its counts are lower bounds.
249
+ export const DATA_IMPACT_MAX_ROWS = 200_000;
250
+ export const DATA_IMPACT_MAX_IDS = DATA_MAX_ROWS_PER_WRITE;
251
+ export const DATA_HISTORY_DAYS = 90;
252
+
253
+ // What deleting rows does elsewhere: one entry per relation column that points
254
+ // at a row the delete removes, cascades followed all the way down. `depth` is
255
+ // how many cascades away from the deleted rows the pointed-at table is.
256
+ export interface DataDeleteImpact {
257
+ table: string;
258
+ rows: number;
259
+ effects: {
260
+ table: string;
261
+ column: string;
262
+ onDelete: DataOnDelete;
263
+ rows: number;
264
+ depth: number;
265
+ }[];
266
+ // A restrict would refuse the delete.
267
+ blocked: boolean;
268
+ // Past DATA_IMPACT_MAX_ROWS: every count is at least what it says.
269
+ truncated: boolean;
270
+ }
271
+
272
+ // A table copy running in the background, as callers see it.
273
+ export interface DataTableCopy {
274
+ table: string;
275
+ // The column whose change or drop started it.
276
+ column: string;
277
+ kind: 'change' | 'drop';
278
+ rows: number;
279
+ copied: number;
280
+ startedAt: string;
281
+ actor: string;
282
+ status: 'running' | 'failed';
283
+ error: string | null;
284
+ }
285
+
286
+ // The table as the owner would write it again: what `ganju.data.json` and an
287
+ // export's schema.json hold.
288
+ export const toTableInput = (table: DataTable): DataTableInput => ({
289
+ name: table.name,
290
+ label: table.label,
291
+ description: table.description,
292
+ displayColumn: table.displayColumn,
293
+ access: table.access,
294
+ customerScoped: table.customerScoped,
295
+ history: table.history,
296
+ columns: table.columns.map(column => {
297
+ const out: DataColumnInput = { name: column.name, type: column.type };
298
+ if (column.label) out.label = column.label;
299
+ if (column.description) out.description = column.description;
300
+ if (column.required) out.required = true;
301
+ if (column.unique) out.unique = true;
302
+ if (column.filterable) out.filterable = true;
303
+ if (column.searchable) out.searchable = true;
304
+ if (column.personal) out.personal = true;
305
+ if (column.values) out.values = column.values;
306
+ if (column.table) out.table = column.table;
307
+ if (column.onDelete) out.onDelete = column.onDelete;
308
+ if (column.min !== null) out.min = column.min;
309
+ if (column.default !== undefined) out.default = column.default;
310
+ return out;
311
+ })
312
+ });
package/src/index.ts CHANGED
@@ -98,6 +98,14 @@ import {
98
98
  } from './jsonSchemaToZodShape';
99
99
  import type { SchemaViolation } from './jsonSchemaToZodShape';
100
100
  import { buildProxyToolName } from './mcpProxy';
101
+ import { countInstallTools } from './toolCount';
102
+ import {
103
+ capText,
104
+ findNextCursor,
105
+ paginate,
106
+ InvalidCursorError,
107
+ listResourcesPage
108
+ } from './pagination';
101
109
  import {
102
110
  mintCustomCodeToken,
103
111
  verifyCustomCodeToken,
@@ -142,7 +150,7 @@ import type {
142
150
  ResolvedAttachment,
143
151
  ResolveAttachmentResult
144
152
  } from './attachment';
145
- import { ipv4InPrivateRange, isBlockedHost } from './ssrf';
153
+ import { ipv4InPrivateRange, isBlockedHost, isBlockedUrl } from './ssrf';
146
154
  import {
147
155
  requiresLlmBaseUrl,
148
156
  isAllowedLlmBaseUrl,
@@ -201,8 +209,10 @@ import type { RerankAiBinding } from './resourceRerank';
201
209
  import { sleep, isRateLimitError, withRateLimitRetry } from './retry';
202
210
  import type { RateLimitRetryOptions } from './retry';
203
211
  import { processQueueBatch } from './processQueueBatch';
212
+ import { PermanentJobError, isPermanentJobError } from './queueFailure';
204
213
  import type {
205
214
  QueueBatchLike,
215
+ QueueFailureContext,
206
216
  QueueMessageLike,
207
217
  ProcessQueueBatchHandlers
208
218
  } from './processQueueBatch';
@@ -222,6 +232,7 @@ import {
222
232
  import type {
223
233
  BufferedChannelMessage,
224
234
  BufferedChannelCommand,
235
+ BufferedVoiceNote,
225
236
  ChannelBufferEnvelope,
226
237
  ChannelBufferFlush
227
238
  } from './channelDebounce';
@@ -235,13 +246,79 @@ import {
235
246
  annotationsForEffect,
236
247
  TOOL_EFFECTS,
237
248
  isSensitiveTool,
249
+ proxiedToolAnnotations,
250
+ proxiedToolTrust,
251
+ isSensitiveProxiedTool,
252
+ keepProxiedToolMarks,
253
+ toolApprovalStatus,
254
+ toolApprovalUrl,
238
255
  stableJson
239
256
  } from './toolConfirmation';
240
257
  import type {
241
258
  PendingToolConfirmation,
242
259
  PendingToolConfirmations,
243
- ToolEffect
260
+ ToolEffect,
261
+ ToolApprovalStatus,
262
+ ProxiedToolTrust
244
263
  } from './toolConfirmation';
264
+ import {
265
+ wrapUntrustedContent,
266
+ unwrapUntrustedContent,
267
+ isUntrustedToolResult,
268
+ findInstructionLikeText,
269
+ UNTRUSTED_CONTENT_TAG,
270
+ UNTRUSTED_CONTENT_META_KEY,
271
+ UNTRUSTED_CONTENT_NOTE,
272
+ INSTRUCTION_WARNING_METADATA_KEY,
273
+ untrustedToolResult,
274
+ ownWritingToolResult,
275
+ labelOwnToolResult,
276
+ labelProxiedToolResult,
277
+ untrustedErrorResult,
278
+ readsLikeInstructions,
279
+ labelResourceContents
280
+ } from './untrustedContent';
281
+ import type {
282
+ InstructionWarning,
283
+ LabelledToolResult
284
+ } from './untrustedContent';
285
+ import {
286
+ PARTICIPANT_DAILY_LIMIT_DEFAULT,
287
+ PARTICIPANT_DAILY_LIMIT_MAX,
288
+ PARTICIPANT_DAILY_LIMIT_OFF,
289
+ PARTICIPANT_DAILY_LIMIT_WINDOW_MS,
290
+ PARTICIPANT_LIMIT_METADATA_KEY,
291
+ resolveParticipantDailyLimit,
292
+ resolveParticipantMemoryEnabled,
293
+ VOICE_NOTE_MAX_BYTES,
294
+ VOICE_NOTE_MAX_SECONDS,
295
+ audioDurationSeconds,
296
+ oggDurationSeconds,
297
+ VOICE_NOTE_TRANSCRIPTION_PROMPT,
298
+ VOICE_NOTE_METADATA_KEY,
299
+ VOICE_NOTE_UNREADABLE_METADATA_KEY,
300
+ PARTICIPANT_MEMORY_TOOL_NAME,
301
+ PARTICIPANT_MEMORY_MAX_FACTS,
302
+ PARTICIPANT_MEMORY_TOOL_DESCRIPTION,
303
+ PARTICIPANT_MEMORY_TOOL_SCHEMA,
304
+ PARTICIPANT_MEMORY_GROUP_NOTE,
305
+ readParticipantMemory,
306
+ applyParticipantMemoryUpdate,
307
+ redactParticipantMemoryArgs,
308
+ redactParticipantMemoryConfirmation,
309
+ participantMemoryUpdateReadsLikeInstructions,
310
+ CONVERSATION_UNTRUSTED_WINDOW_MS,
311
+ CONVERSATION_UNTRUSTED_READ_AT_KEY,
312
+ conversationReadUntrustedRecently,
313
+ formatParticipantMemoryPrompt,
314
+ participantLimitNotice,
315
+ voiceNoteUnreadableNotice,
316
+ voiceNoteTooLongNotice
317
+ } from './channelCustomer';
318
+ import type {
319
+ ParticipantMemory,
320
+ ParticipantMemoryUpdate
321
+ } from './channelCustomer';
245
322
  import {
246
323
  lintTools,
247
324
  TOOL_LINT_RULES,
@@ -263,9 +340,12 @@ import {
263
340
  formatSourcesAsButtons
264
341
  } from './sources';
265
342
  import type { Source, ResourceUrlContext, SourceButton } from './sources';
343
+ import { citesUrl, citedPages, selectCitedSources } from './citations';
266
344
  import {
267
345
  refreshOAuthToken,
268
346
  OAuthReauthRequiredError,
347
+ OAuthRefreshError,
348
+ refreshFailureReauthReason,
269
349
  buildReauthMetadata,
270
350
  clearReauthMetadata,
271
351
  isCredentialNeedingReauth
@@ -323,6 +403,12 @@ export const utils = {
323
403
  jsonSchemaToZodShape,
324
404
  validateAgainstJsonSchema,
325
405
  buildProxyToolName,
406
+ countInstallTools,
407
+ capText,
408
+ findNextCursor,
409
+ paginate,
410
+ InvalidCursorError,
411
+ listResourcesPage,
326
412
  mintCustomCodeToken,
327
413
  verifyCustomCodeToken,
328
414
  customCodeScriptName,
@@ -347,6 +433,7 @@ export const utils = {
347
433
  validateProjectPath,
348
434
  projectPathIssue,
349
435
  ipv4InPrivateRange,
436
+ isBlockedUrl,
350
437
  isBlockedHost,
351
438
  requiresLlmBaseUrl,
352
439
  isAllowedLlmBaseUrl,
@@ -388,6 +475,8 @@ export const utils = {
388
475
  isRateLimitError,
389
476
  withRateLimitRetry,
390
477
  processQueueBatch,
478
+ PermanentJobError,
479
+ isPermanentJobError,
391
480
  getToolStatusMessage,
392
481
  resolveDebounceMs,
393
482
  channelBufferKey,
@@ -402,7 +491,59 @@ export const utils = {
402
491
  annotationsForEffect,
403
492
  TOOL_EFFECTS,
404
493
  isSensitiveTool,
494
+ proxiedToolAnnotations,
495
+ proxiedToolTrust,
496
+ isSensitiveProxiedTool,
497
+ keepProxiedToolMarks,
498
+ toolApprovalStatus,
499
+ toolApprovalUrl,
405
500
  stableJson,
501
+ wrapUntrustedContent,
502
+ unwrapUntrustedContent,
503
+ isUntrustedToolResult,
504
+ findInstructionLikeText,
505
+ UNTRUSTED_CONTENT_TAG,
506
+ UNTRUSTED_CONTENT_META_KEY,
507
+ UNTRUSTED_CONTENT_NOTE,
508
+ INSTRUCTION_WARNING_METADATA_KEY,
509
+ untrustedToolResult,
510
+ ownWritingToolResult,
511
+ labelOwnToolResult,
512
+ labelProxiedToolResult,
513
+ untrustedErrorResult,
514
+ readsLikeInstructions,
515
+ labelResourceContents,
516
+ PARTICIPANT_DAILY_LIMIT_DEFAULT,
517
+ PARTICIPANT_DAILY_LIMIT_MAX,
518
+ PARTICIPANT_DAILY_LIMIT_OFF,
519
+ PARTICIPANT_DAILY_LIMIT_WINDOW_MS,
520
+ PARTICIPANT_LIMIT_METADATA_KEY,
521
+ resolveParticipantDailyLimit,
522
+ resolveParticipantMemoryEnabled,
523
+ VOICE_NOTE_MAX_BYTES,
524
+ VOICE_NOTE_MAX_SECONDS,
525
+ audioDurationSeconds,
526
+ oggDurationSeconds,
527
+ VOICE_NOTE_TRANSCRIPTION_PROMPT,
528
+ VOICE_NOTE_METADATA_KEY,
529
+ VOICE_NOTE_UNREADABLE_METADATA_KEY,
530
+ PARTICIPANT_MEMORY_TOOL_NAME,
531
+ PARTICIPANT_MEMORY_MAX_FACTS,
532
+ PARTICIPANT_MEMORY_TOOL_DESCRIPTION,
533
+ PARTICIPANT_MEMORY_TOOL_SCHEMA,
534
+ PARTICIPANT_MEMORY_GROUP_NOTE,
535
+ readParticipantMemory,
536
+ applyParticipantMemoryUpdate,
537
+ redactParticipantMemoryArgs,
538
+ redactParticipantMemoryConfirmation,
539
+ participantMemoryUpdateReadsLikeInstructions,
540
+ CONVERSATION_UNTRUSTED_WINDOW_MS,
541
+ CONVERSATION_UNTRUSTED_READ_AT_KEY,
542
+ conversationReadUntrustedRecently,
543
+ formatParticipantMemoryPrompt,
544
+ participantLimitNotice,
545
+ voiceNoteUnreadableNotice,
546
+ voiceNoteTooLongNotice,
406
547
  lintTools,
407
548
  TOOL_LINT_RULES,
408
549
  TOOL_LINT_MAX_TOOLS,
@@ -413,8 +554,13 @@ export const utils = {
413
554
  buildResourceDownloadUrl,
414
555
  formatSourcesAsMarkdown,
415
556
  formatSourcesAsButtons,
557
+ citesUrl,
558
+ citedPages,
559
+ selectCitedSources,
416
560
  refreshOAuthToken,
417
561
  OAuthReauthRequiredError,
562
+ OAuthRefreshError,
563
+ refreshFailureReauthReason,
418
564
  buildReauthMetadata,
419
565
  clearReauthMetadata,
420
566
  isCredentialNeedingReauth,
@@ -429,6 +575,10 @@ export const utils = {
429
575
  };
430
576
 
431
577
  export type {
578
+ ParticipantMemory,
579
+ ParticipantMemoryUpdate,
580
+ InstructionWarning,
581
+ LabelledToolResult,
432
582
  MintedAccessToken,
433
583
  CustomCodeProject,
434
584
  ProjectPathIssue,
@@ -439,6 +589,8 @@ export type {
439
589
  PendingToolConfirmation,
440
590
  PendingToolConfirmations,
441
591
  ToolEffect,
592
+ ToolApprovalStatus,
593
+ ProxiedToolTrust,
442
594
  LintableTool,
443
595
  ToolLintFinding,
444
596
  ToolLintOptions,
@@ -479,12 +631,14 @@ export type {
479
631
  RateLimitRetryOptions,
480
632
  RerankAiBinding,
481
633
  QueueBatchLike,
634
+ QueueFailureContext,
482
635
  QueueMessageLike,
483
636
  ProcessQueueBatchHandlers,
484
637
  ChannelNotifier,
485
638
  ToolStatusEvent,
486
639
  BufferedChannelMessage,
487
640
  BufferedChannelCommand,
641
+ BufferedVoiceNote,
488
642
  ChannelBufferEnvelope,
489
643
  ChannelBufferFlush,
490
644
  Source,