dsh-reference-anything 0.3.1 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. package/LICENSE +22 -22
  2. package/NOTICE.md +52 -25
  3. package/README.md +334 -285
  4. package/cordis.patch.yml +89 -18
  5. package/lib/client.js +13530 -517
  6. package/lib/contract.d.ts +155 -3
  7. package/lib/contract.js +68 -4
  8. package/lib/download-directory.d.ts +18 -0
  9. package/lib/download-directory.js +55 -0
  10. package/lib/errors.d.ts +4 -0
  11. package/lib/host.d.ts +96 -3
  12. package/lib/host.js +88 -5
  13. package/lib/index.d.ts +22 -2
  14. package/lib/index.js +57 -7
  15. package/lib/opencli.d.ts +5 -3
  16. package/lib/opencli.js +13 -6
  17. package/lib/openlist/host.d.ts +157 -0
  18. package/lib/openlist/host.js +873 -0
  19. package/lib/openlist/index.d.ts +84 -0
  20. package/lib/openlist/index.js +507 -0
  21. package/lib/render.d.ts +12 -7
  22. package/lib/render.js +27 -21
  23. package/lib/sources/cloud-drive/cache.d.ts +60 -0
  24. package/lib/sources/cloud-drive/cache.js +107 -0
  25. package/lib/sources/cloud-drive/index.d.ts +190 -0
  26. package/lib/sources/cloud-drive/index.js +526 -0
  27. package/lib/sources/cloud-drive/providers/http.d.ts +27 -0
  28. package/lib/sources/cloud-drive/providers/http.js +73 -0
  29. package/lib/sources/cloud-drive/providers/openlist.d.ts +59 -0
  30. package/lib/sources/cloud-drive/providers/openlist.js +535 -0
  31. package/lib/sources/cloud-drive/registry.d.ts +53 -0
  32. package/lib/sources/cloud-drive/registry.js +101 -0
  33. package/lib/sources/cloud-drive/types.d.ts +169 -0
  34. package/lib/sources/cloud-drive/types.js +17 -0
  35. package/lib/sources/file.d.ts +2 -0
  36. package/lib/sources/file.js +2 -0
  37. package/lib/sources/local-agent/adapters/claude-code.d.ts +16 -0
  38. package/lib/sources/local-agent/adapters/claude-code.js +171 -0
  39. package/lib/sources/local-agent/adapters/codex.d.ts +20 -0
  40. package/lib/sources/local-agent/adapters/codex.js +204 -0
  41. package/lib/sources/local-agent/adapters/cursor.d.ts +23 -0
  42. package/lib/sources/local-agent/adapters/cursor.js +121 -0
  43. package/lib/sources/local-agent/adapters/gemini-cli.d.ts +20 -0
  44. package/lib/sources/local-agent/adapters/gemini-cli.js +141 -0
  45. package/lib/sources/local-agent/adapters/grokbuild.d.ts +22 -0
  46. package/lib/sources/local-agent/adapters/grokbuild.js +76 -0
  47. package/lib/sources/local-agent/adapters/hermes.d.ts +19 -0
  48. package/lib/sources/local-agent/adapters/hermes.js +85 -0
  49. package/lib/sources/local-agent/adapters/kimi.d.ts +28 -0
  50. package/lib/sources/local-agent/adapters/kimi.js +261 -0
  51. package/lib/sources/local-agent/adapters/openclaw.d.ts +21 -0
  52. package/lib/sources/local-agent/adapters/openclaw.js +120 -0
  53. package/lib/sources/local-agent/adapters/opencode.d.ts +44 -0
  54. package/lib/sources/local-agent/adapters/opencode.js +236 -0
  55. package/lib/sources/local-agent/adapters/pi.d.ts +26 -0
  56. package/lib/sources/local-agent/adapters/pi.js +242 -0
  57. package/lib/sources/local-agent/adapters/qoder.d.ts +19 -0
  58. package/lib/sources/local-agent/adapters/qoder.js +93 -0
  59. package/lib/sources/local-agent/adapters/reasonix.d.ts +23 -0
  60. package/lib/sources/local-agent/adapters/reasonix.js +90 -0
  61. package/lib/sources/local-agent/adapters/shared.d.ts +163 -0
  62. package/lib/sources/local-agent/adapters/shared.js +415 -0
  63. package/lib/sources/local-agent/adapters/sqlite-shared.d.ts +92 -0
  64. package/lib/sources/local-agent/adapters/sqlite-shared.js +215 -0
  65. package/lib/sources/local-agent/adapters/zcode.d.ts +41 -0
  66. package/lib/sources/local-agent/adapters/zcode.js +159 -0
  67. package/lib/sources/local-agent/index.d.ts +222 -0
  68. package/lib/sources/local-agent/index.js +656 -0
  69. package/lib/sources/local-agent/page.d.ts +55 -0
  70. package/lib/sources/local-agent/page.js +83 -0
  71. package/lib/sources/local-agent/path.d.ts +8 -0
  72. package/lib/sources/local-agent/path.js +43 -0
  73. package/lib/sources/local-agent/registry.d.ts +68 -0
  74. package/lib/sources/local-agent/registry.js +116 -0
  75. package/lib/sources/local-agent/scan.d.ts +175 -0
  76. package/lib/sources/local-agent/scan.js +472 -0
  77. package/lib/sources/local-agent/sqlite.d.ts +45 -0
  78. package/lib/sources/local-agent/sqlite.js +113 -0
  79. package/lib/sources/local-agent/store.d.ts +93 -0
  80. package/lib/sources/local-agent/store.js +113 -0
  81. package/lib/sources/local-agent/types.d.ts +338 -0
  82. package/lib/sources/local-agent/types.js +20 -0
  83. package/lib/sources/web-chat/index.d.ts +5 -1
  84. package/lib/sources/web-chat/index.js +47 -8
  85. package/lib/store/spec.d.ts +50 -0
  86. package/lib/store/spec.js +2 -2
  87. package/lib/sync/index.d.ts +1 -0
  88. package/lib/sync/index.js +28 -8
  89. package/lib/tool.d.ts +5 -0
  90. package/lib/tool.js +418 -45
  91. package/lib/typert.js +13 -1
  92. package/lib/types.d.ts +28 -2
  93. package/lib/update.d.ts +6 -0
  94. package/lib/update.js +29 -1
  95. package/lib/web.js +5 -1
  96. package/lib/wire.d.ts +80 -0
  97. package/lib/wire.js +30 -1
  98. package/opencli-plugin/chatgpt.js +30 -27
  99. package/opencli-plugin/claude.js +12 -8
  100. package/opencli-plugin/common.js +266 -187
  101. package/opencli-plugin/deepseek.js +8 -5
  102. package/opencli-plugin/gemini.js +42 -38
  103. package/opencli-plugin/grok.js +22 -21
  104. package/opencli-plugin/kimi.js +34 -31
  105. package/opencli-plugin/opencli-plugin.json +6 -6
  106. package/opencli-plugin/package.json +8 -8
  107. package/package.json +200 -185
@@ -7,8 +7,10 @@ import { OpenCliError, OpenCliRunner, discoverOpenCli, installOpenCli as install
7
7
  import { PACKAGE_NAME, PackageUpdateManager } from "../../update.js";
8
8
  import { join } from 'node:path';
9
9
  import { pathToFileURL } from 'node:url';
10
+ import { isDeepStrictEqual } from 'node:util';
10
11
  import { ReferenceAnythingError } from "../../errors.js";
11
12
  import { parseProviderQuery } from "../../search.js";
13
+ import { validateDownloadDirectory } from "../../download-directory.js";
12
14
  export { parseProviderQuery };
13
15
  export const name = 'reference-web-chat';
14
16
  export const inject = ['references', 'storageDomain'];
@@ -25,10 +27,14 @@ export default class WebChatHistoryService extends Service {
25
27
  static inject = inject;
26
28
  static Config = Config;
27
29
  id = 'web-chat';
30
+ /** Mirrored browser chats are outside the task's workspace: read only what the user named. */
31
+ requiresGrant = true;
28
32
  storeValue;
29
33
  syncValue;
30
34
  autoSyncInterval;
31
35
  autoSyncCatchUp;
36
+ settingsUpdateQueue = Promise.resolve();
37
+ validateDownloadDirectoryValue = validateDownloadDirectory;
32
38
  packageUpdates = new PackageUpdateManager({
33
39
  afterInstall: async (profileDir, _version, signal) => {
34
40
  await this.installAdapterFrom(pathToFileURL(join(profileDir, 'node_modules', PACKAGE_NAME, 'opencli-plugin')).href, signal);
@@ -50,6 +56,9 @@ export default class WebChatHistoryService extends Service {
50
56
  await this.store.setSettings(this.store.settings);
51
57
  await this.store.clearMirrorContent();
52
58
  }
59
+ if (this.store.settings.syncHistoryDays !== null) {
60
+ await this.store.removeOlderThan(this.store.settings.syncHistoryDays);
61
+ }
53
62
  this.syncValue = new ConversationSyncManager(this.storeValue, () => new OpenCliRunner({
54
63
  executable: this.store.settings.opencliPath, profile: this.store.settings.profile,
55
64
  timeoutMs: this.config.timeoutMs, maxStdoutBytes: this.config.maxStdoutBytes,
@@ -179,11 +188,6 @@ export default class WebChatHistoryService extends Service {
179
188
  throw new ReferenceAnythingError('cannot clear provider data while a sync is in progress', 'REFERENCE_SYNC_IN_PROGRESS');
180
189
  return this.store.removeProvider(provider);
181
190
  }
182
- async removeOlderThan(days) {
183
- if (this.sync.isRunning())
184
- throw new ReferenceAnythingError('cannot clear old data while a sync is in progress', 'REFERENCE_SYNC_IN_PROGRESS');
185
- return this.store.removeOlderThan(days);
186
- }
187
191
  async removeRemoteMissing() {
188
192
  if (this.sync.isRunning())
189
193
  throw new ReferenceAnythingError('cannot clear remote-missing data while a sync is in progress', 'REFERENCE_SYNC_IN_PROGRESS');
@@ -215,12 +219,36 @@ export default class WebChatHistoryService extends Service {
215
219
  }
216
220
  return discovery;
217
221
  }
218
- async updateSettings(value) {
219
- const settings = settingsRecordSchema.parse(value);
220
- const enteringMetadataOnly = settings.historyMode === 'metadata-only' && this.store.settings.historyMode !== 'metadata-only';
222
+ updateSettings(value) {
223
+ const submittedAgainst = this.store.settings;
224
+ const pending = (this.settingsUpdateQueue ?? Promise.resolve()).then(() => this.applySettings(value, submittedAgainst));
225
+ // Keep the serialization tail fulfilled so one rejected mutation does not
226
+ // prevent a later, valid settings request from running.
227
+ this.settingsUpdateQueue = pending.then(() => undefined, () => undefined);
228
+ return pending;
229
+ }
230
+ async applySettings(value, submittedAgainst) {
231
+ const submitted = settingsRecordSchema.parse(value);
232
+ const directoryChanged = !isDeepStrictEqual(submitted.cloudDriveDownloadDirectory, submittedAgainst.cloudDriveDownloadDirectory);
233
+ let validatedDirectory = submitted.cloudDriveDownloadDirectory;
234
+ if (directoryChanged) {
235
+ const validateDirectory = this.validateDownloadDirectoryValue ?? validateDownloadDirectory;
236
+ validatedDirectory = await validateDirectory(validatedDirectory);
237
+ }
238
+ // Validation can be slow (especially for a network drive). Merge against a
239
+ // fresh value so direct writers such as installOpenCli are not overwritten
240
+ // by the snapshot captured before that await.
241
+ const current = this.store.settings;
242
+ let settings = mergeSettingsUpdate(submittedAgainst, current, submitted);
243
+ if (directoryChanged)
244
+ settings = { ...settings, cloudDriveDownloadDirectory: validatedDirectory };
245
+ const enteringMetadataOnly = settings.historyMode === 'metadata-only' && current.historyMode !== 'metadata-only';
246
+ const historyRangeChanged = settings.syncHistoryDays !== current.syncHistoryDays;
221
247
  await this.store.setSettings(settings);
222
248
  if (enteringMetadataOnly)
223
249
  await this.store.clearMirrorContent();
250
+ if (historyRangeChanged && settings.syncHistoryDays !== null)
251
+ await this.store.removeOlderThan(settings.syncHistoryDays);
224
252
  this.armAutoSync();
225
253
  return settings;
226
254
  }
@@ -330,6 +358,17 @@ export default class WebChatHistoryService extends Service {
330
358
  }
331
359
  }
332
360
  }
361
+ /** Apply only fields changed by this full-record request since its submission snapshot. */
362
+ function mergeSettingsUpdate(submittedAgainst, current, submitted) {
363
+ const merged = { ...current };
364
+ const keys = new Set([...Object.keys(submittedAgainst), ...Object.keys(submitted)]);
365
+ for (const key of keys) {
366
+ if (!isDeepStrictEqual(submitted[key], submittedAgainst[key])) {
367
+ Object.assign(merged, { [key]: submitted[key] });
368
+ }
369
+ }
370
+ return settingsRecordSchema.parse(merged);
371
+ }
333
372
  /** Spread a period by ±10% so providers and instances do not all fire together. */
334
373
  function jitter(period) {
335
374
  return Math.round(period * (0.9 + Math.random() * 0.2));
@@ -171,6 +171,7 @@ export declare const referenceAnythingDomainSpec: {
171
171
  schema: z.ZodObject<{
172
172
  opencliPath: z.ZodString;
173
173
  profile: z.ZodString;
174
+ cloudDriveDownloadDirectory: z.ZodDefault<z.ZodString>;
174
175
  detailConcurrency: z.ZodNumber;
175
176
  autoSync: z.ZodDefault<z.ZodBoolean>;
176
177
  syncOnStartup: z.ZodDefault<z.ZodBoolean>;
@@ -179,6 +180,7 @@ export declare const referenceAnythingDomainSpec: {
179
180
  "metadata-only": "metadata-only";
180
181
  "offline-mirror": "offline-mirror";
181
182
  }>>;
183
+ syncHistoryDays: z.ZodDefault<z.ZodNullable<z.ZodNumber>>;
182
184
  enabledProviders: z.ZodDefault<z.ZodArray<z.ZodEnum<{
183
185
  chatgpt: "chatgpt";
184
186
  claude: "claude";
@@ -187,6 +189,39 @@ export declare const referenceAnythingDomainSpec: {
187
189
  grok: "grok";
188
190
  kimi: "kimi";
189
191
  }>>>;
192
+ enabledAgents: z.ZodDefault<z.ZodArray<z.ZodEnum<{
193
+ kimi: "kimi";
194
+ "claude-code": "claude-code";
195
+ codex: "codex";
196
+ cursor: "cursor";
197
+ qoder: "qoder";
198
+ reasonix: "reasonix";
199
+ openclaw: "openclaw";
200
+ grokbuild: "grokbuild";
201
+ hermes: "hermes";
202
+ "gemini-cli": "gemini-cli";
203
+ pi: "pi";
204
+ opencode: "opencode";
205
+ mimocode: "mimocode";
206
+ zcode: "zcode";
207
+ }>>>;
208
+ agentDirectories: z.ZodOptional<z.ZodRecord<z.ZodEnum<{
209
+ kimi: "kimi";
210
+ "claude-code": "claude-code";
211
+ codex: "codex";
212
+ cursor: "cursor";
213
+ qoder: "qoder";
214
+ reasonix: "reasonix";
215
+ openclaw: "openclaw";
216
+ grokbuild: "grokbuild";
217
+ hermes: "hermes";
218
+ "gemini-cli": "gemini-cli";
219
+ pi: "pi";
220
+ opencode: "opencode";
221
+ mimocode: "mimocode";
222
+ zcode: "zcode";
223
+ }> & z.core.$partial, z.ZodString>>;
224
+ enabledDriveMounts: z.ZodOptional<z.ZodArray<z.ZodString>>;
190
225
  maxReadTurns: z.ZodDefault<z.ZodNumber>;
191
226
  inputRenderMode: z.ZodDefault<z.ZodEnum<{
192
227
  pill: "pill";
@@ -221,23 +256,38 @@ export declare const referenceAnythingDomainSpec: {
221
256
  limit: z.ZodNumber;
222
257
  maxCandidates: z.ZodDefault<z.ZodNumber>;
223
258
  }, z.core.$strip>;
259
+ agents: z.ZodDefault<z.ZodObject<{
260
+ enabled: z.ZodBoolean;
261
+ order: z.ZodNumber;
262
+ limit: z.ZodNumber;
263
+ maxCandidates: z.ZodDefault<z.ZodNumber>;
264
+ }, z.core.$strip>>;
224
265
  conversations: z.ZodObject<{
225
266
  enabled: z.ZodBoolean;
226
267
  order: z.ZodNumber;
227
268
  limit: z.ZodNumber;
228
269
  maxCandidates: z.ZodDefault<z.ZodNumber>;
229
270
  }, z.core.$strip>;
271
+ drives: z.ZodDefault<z.ZodObject<{
272
+ enabled: z.ZodBoolean;
273
+ order: z.ZodNumber;
274
+ limit: z.ZodNumber;
275
+ maxCandidates: z.ZodDefault<z.ZodNumber>;
276
+ }, z.core.$strip>>;
230
277
  }, z.core.$strip>>;
231
278
  }, z.core.$strip>;
232
279
  initial: {
233
280
  opencliPath: string;
234
281
  profile: string;
282
+ cloudDriveDownloadDirectory: string;
235
283
  detailConcurrency: number;
236
284
  autoSync: boolean;
237
285
  syncOnStartup: boolean;
238
286
  autoSyncMinutes: number;
239
287
  historyMode: "metadata-only";
288
+ syncHistoryDays: null;
240
289
  enabledProviders: ("chatgpt" | "claude" | "gemini" | "deepseek" | "grok" | "kimi")[];
290
+ enabledAgents: ("kimi" | "claude-code" | "codex" | "cursor" | "qoder" | "reasonix" | "openclaw" | "grokbuild" | "hermes" | "gemini-cli" | "pi" | "opencode" | "mimocode" | "zcode")[];
241
291
  maxReadTurns: number;
242
292
  inputRenderMode: "pill";
243
293
  };
package/lib/store/spec.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { z } from 'zod';
2
2
  import { defineDomain, domainTable } from '@deepseek-ai/dsh-storage-domain';
3
- import { providerSchema, settingsRecordSchema } from "../wire.js";
3
+ import { ALL_LOCAL_AGENTS, providerSchema, settingsRecordSchema } from "../wire.js";
4
4
  export { providerSchema, settingsRecordSchema };
5
5
  export const storedAttachmentSchema = z.object({
6
6
  attachmentId: z.string(),
@@ -82,7 +82,7 @@ export const referenceAnythingDomainSpec = defineDomain({
82
82
  version: 1,
83
83
  global: {
84
84
  schema: settingsRecordSchema,
85
- initial: { opencliPath: 'opencli', profile: '', detailConcurrency: 8, autoSync: false, syncOnStartup: false, autoSyncMinutes: 60, historyMode: 'metadata-only', enabledProviders: [...providerSchema.options], maxReadTurns: 10, inputRenderMode: 'pill' },
85
+ initial: { opencliPath: 'opencli', profile: '', cloudDriveDownloadDirectory: '', detailConcurrency: 8, autoSync: false, syncOnStartup: false, autoSyncMinutes: 60, historyMode: 'metadata-only', syncHistoryDays: null, enabledProviders: [...providerSchema.options], enabledAgents: [...ALL_LOCAL_AGENTS], maxReadTurns: 10, inputRenderMode: 'pill' },
86
86
  },
87
87
  tables: {
88
88
  conversations: domainTable(conversationRecordSchema),
@@ -79,6 +79,7 @@ export declare class ConversationSyncManager {
79
79
  * @returns an ISO instant the adapter may page back to, exclusive of slack.
80
80
  */
81
81
  private listingSince;
82
+ private historySince;
82
83
  private progressWriter;
83
84
  /** Newest durable account scope for a provider, used only as an incremental listing hint. */
84
85
  private latestAccountScope;
package/lib/sync/index.js CHANGED
@@ -109,6 +109,9 @@ export class ConversationSyncManager {
109
109
  const failures = new Map();
110
110
  let succeeded = 0;
111
111
  try {
112
+ const historyDays = this.store.settings.syncHistoryDays;
113
+ if (historyDays !== null)
114
+ await this.store.removeOlderThan(historyDays);
112
115
  for (const provider of job.providers) {
113
116
  if (job.controller.signal.aborted)
114
117
  break;
@@ -128,6 +131,9 @@ export class ConversationSyncManager {
128
131
  this.logger?.warn(`reference sync: ${provider} failed: ${describe(error)}`);
129
132
  }
130
133
  }
134
+ const currentHistoryDays = this.store.settings.syncHistoryDays;
135
+ if (currentHistoryDays !== null)
136
+ await this.store.removeOlderThan(currentHistoryDays);
131
137
  job.status = job.controller.signal.aborted ? 'cancelled'
132
138
  : failures.size === 0 ? 'complete'
133
139
  : succeeded === 0 ? 'failed' : 'partial';
@@ -175,7 +181,7 @@ export class ConversationSyncManager {
175
181
  let accountScope = '';
176
182
  let progress;
177
183
  try {
178
- const sinceFor = (scope) => mode === 'incremental' ? this.listingSince(provider, scope) : '';
184
+ const sinceFor = (scope) => this.listingSince(provider, scope, mode);
179
185
  let rows;
180
186
  let since = '';
181
187
  if (typeof runner.syncIndex === 'function') {
@@ -202,7 +208,13 @@ export class ConversationSyncManager {
202
208
  // changed rows when a trustworthy watermark exists, then fetch detail
203
209
  // only for rows whose provider timestamp changed. Full always enumerates
204
210
  // and re-fetches everything, replacing each current local revision.
205
- const seen = new Set(rows.map(row => row.id));
211
+ const listedRows = rows;
212
+ const historySince = this.historySince();
213
+ if (historySince) {
214
+ const cutoff = Date.parse(historySince);
215
+ rows = rows.filter(row => { const updatedAt = Date.parse(row.updatedAt); return Number.isNaN(updatedAt) || updatedAt >= cutoff; });
216
+ }
217
+ const seen = new Set(listedRows.map(row => row.id));
206
218
  job.total += rows.length;
207
219
  const providerProgress = this.providerProgress(job, provider);
208
220
  providerProgress.phase = 'syncing';
@@ -251,7 +263,7 @@ export class ConversationSyncManager {
251
263
  if (enumerated)
252
264
  await this.store.markRemoteMissing(provider, accountScope, seen);
253
265
  await progress.save('idle', {
254
- cursor: rows.at(-1)?.cursor ?? '',
266
+ cursor: listedRows.at(-1)?.cursor ?? '',
255
267
  complete: enumerated,
256
268
  ...(failures.length > 0 ? { error: `${String(failures.length)} conversations failed; ${summarize(failures)}` } : {}),
257
269
  });
@@ -300,15 +312,23 @@ export class ConversationSyncManager {
300
312
  * Watermark for an incremental listing, or `''` to demand a full one.
301
313
  * @returns an ISO instant the adapter may page back to, exclusive of slack.
302
314
  */
303
- listingSince(provider, accountScope) {
315
+ listingSince(provider, accountScope, mode) {
316
+ const historySince = this.historySince();
317
+ if (mode === 'full')
318
+ return historySince;
304
319
  const state = this.store.syncStates.get(`${provider}:${accountScope}`);
305
320
  const lastComplete = Date.parse(state?.lastCompleteScanAt ?? '');
306
321
  const lastSync = Date.parse(state?.lastSyncAt ?? '');
307
322
  if (Number.isNaN(lastComplete) || Number.isNaN(lastSync))
308
- return '';
323
+ return historySince;
309
324
  if (Date.now() - lastComplete >= FULL_SCAN_INTERVAL_MS)
310
- return '';
311
- return new Date(lastSync - LISTING_OVERLAP_MS).toISOString();
325
+ return historySince;
326
+ const incrementalSince = new Date(lastSync - LISTING_OVERLAP_MS).toISOString();
327
+ return historySince > incrementalSince ? historySince : incrementalSince;
328
+ }
329
+ historySince() {
330
+ const days = this.store.settings.syncHistoryDays;
331
+ return days === null ? '' : new Date(Date.now() - days * 24 * 60 * 60_000).toISOString();
312
332
  }
313
333
  progressWriter(provider, accountScope, job, total) {
314
334
  let completed = 0;
@@ -413,7 +433,7 @@ function isRetryable(error) {
413
433
  function isFatal(error) {
414
434
  return error instanceof OpenCliError && (error.code === 'OPENCLI_CONFIGURATION'
415
435
  || error.code === 'PROVIDER_NOT_LOGGED_IN' || error.code === 'PROVIDER_ACCOUNT_MISMATCH'
416
- || error.code === 'EXTENSION_NOT_CONNECTED');
436
+ || error.code === 'PROVIDER_RATE_LIMIT' || error.code === 'EXTENSION_NOT_CONNECTED');
417
437
  }
418
438
  function summarize(failures) {
419
439
  const head = failures.slice(0, 3).join('; ');
package/lib/tool.d.ts CHANGED
@@ -23,6 +23,10 @@ export declare const DEFAULT_TIMEOUT_MS = 30000;
23
23
  export declare const DEFAULT_READ_TURNS = 10;
24
24
  /** Ceiling on the model-supplied turn limit when none is configured. */
25
25
  export declare const DEFAULT_MAX_READ_TURNS = 100;
26
+ /** Hard attachment cap shared by drive and Web materialization. */
27
+ export declare const MAX_ATTACHMENT_BYTES: number;
28
+ /** Successful materializations remain usable for one hour. */
29
+ export declare const ATTACHMENT_LIFETIME_MS: number;
26
30
  /** Deployment settings for the model-facing tools. */
27
31
  export interface Config {
28
32
  /** Items `reference_list` may return; also the cap the model cannot raise. */
@@ -59,4 +63,5 @@ export declare function parseWindow(args: {
59
63
  limit?: number;
60
64
  before?: number;
61
65
  cursor?: string;
66
+ detail?: 'summary' | 'full';
62
67
  }, fallback: number, ceiling: number): ReferenceWindow;