dsh-reference-anything 0.3.0 → 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.
- package/LICENSE +22 -22
- package/NOTICE.md +52 -25
- package/README.md +339 -286
- package/cordis.patch.yml +89 -18
- package/lib/client.js +13538 -591
- package/lib/contract.d.ts +155 -16
- package/lib/contract.js +68 -7
- package/lib/download-directory.d.ts +18 -0
- package/lib/download-directory.js +55 -0
- package/lib/errors.d.ts +4 -0
- package/lib/host.d.ts +96 -8
- package/lib/host.js +88 -19
- package/lib/index.d.ts +22 -2
- package/lib/index.js +57 -7
- package/lib/opencli.d.ts +5 -3
- package/lib/opencli.js +13 -6
- package/lib/openlist/host.d.ts +157 -0
- package/lib/openlist/host.js +873 -0
- package/lib/openlist/index.d.ts +84 -0
- package/lib/openlist/index.js +507 -0
- package/lib/render.d.ts +12 -7
- package/lib/render.js +27 -21
- package/lib/sources/cloud-drive/cache.d.ts +60 -0
- package/lib/sources/cloud-drive/cache.js +107 -0
- package/lib/sources/cloud-drive/index.d.ts +190 -0
- package/lib/sources/cloud-drive/index.js +526 -0
- package/lib/sources/cloud-drive/providers/http.d.ts +27 -0
- package/lib/sources/cloud-drive/providers/http.js +73 -0
- package/lib/sources/cloud-drive/providers/openlist.d.ts +59 -0
- package/lib/sources/cloud-drive/providers/openlist.js +535 -0
- package/lib/sources/cloud-drive/registry.d.ts +53 -0
- package/lib/sources/cloud-drive/registry.js +101 -0
- package/lib/sources/cloud-drive/types.d.ts +169 -0
- package/lib/sources/cloud-drive/types.js +17 -0
- package/lib/sources/file.d.ts +2 -0
- package/lib/sources/file.js +2 -0
- package/lib/sources/local-agent/adapters/claude-code.d.ts +16 -0
- package/lib/sources/local-agent/adapters/claude-code.js +171 -0
- package/lib/sources/local-agent/adapters/codex.d.ts +20 -0
- package/lib/sources/local-agent/adapters/codex.js +204 -0
- package/lib/sources/local-agent/adapters/cursor.d.ts +23 -0
- package/lib/sources/local-agent/adapters/cursor.js +121 -0
- package/lib/sources/local-agent/adapters/gemini-cli.d.ts +20 -0
- package/lib/sources/local-agent/adapters/gemini-cli.js +141 -0
- package/lib/sources/local-agent/adapters/grokbuild.d.ts +22 -0
- package/lib/sources/local-agent/adapters/grokbuild.js +76 -0
- package/lib/sources/local-agent/adapters/hermes.d.ts +19 -0
- package/lib/sources/local-agent/adapters/hermes.js +85 -0
- package/lib/sources/local-agent/adapters/kimi.d.ts +28 -0
- package/lib/sources/local-agent/adapters/kimi.js +261 -0
- package/lib/sources/local-agent/adapters/openclaw.d.ts +21 -0
- package/lib/sources/local-agent/adapters/openclaw.js +120 -0
- package/lib/sources/local-agent/adapters/opencode.d.ts +44 -0
- package/lib/sources/local-agent/adapters/opencode.js +236 -0
- package/lib/sources/local-agent/adapters/pi.d.ts +26 -0
- package/lib/sources/local-agent/adapters/pi.js +242 -0
- package/lib/sources/local-agent/adapters/qoder.d.ts +19 -0
- package/lib/sources/local-agent/adapters/qoder.js +93 -0
- package/lib/sources/local-agent/adapters/reasonix.d.ts +23 -0
- package/lib/sources/local-agent/adapters/reasonix.js +90 -0
- package/lib/sources/local-agent/adapters/shared.d.ts +163 -0
- package/lib/sources/local-agent/adapters/shared.js +415 -0
- package/lib/sources/local-agent/adapters/sqlite-shared.d.ts +92 -0
- package/lib/sources/local-agent/adapters/sqlite-shared.js +215 -0
- package/lib/sources/local-agent/adapters/zcode.d.ts +41 -0
- package/lib/sources/local-agent/adapters/zcode.js +159 -0
- package/lib/sources/local-agent/index.d.ts +222 -0
- package/lib/sources/local-agent/index.js +656 -0
- package/lib/sources/local-agent/page.d.ts +55 -0
- package/lib/sources/local-agent/page.js +83 -0
- package/lib/sources/local-agent/path.d.ts +8 -0
- package/lib/sources/local-agent/path.js +43 -0
- package/lib/sources/local-agent/registry.d.ts +68 -0
- package/lib/sources/local-agent/registry.js +116 -0
- package/lib/sources/local-agent/scan.d.ts +175 -0
- package/lib/sources/local-agent/scan.js +472 -0
- package/lib/sources/local-agent/sqlite.d.ts +45 -0
- package/lib/sources/local-agent/sqlite.js +113 -0
- package/lib/sources/local-agent/store.d.ts +93 -0
- package/lib/sources/local-agent/store.js +113 -0
- package/lib/sources/local-agent/types.d.ts +338 -0
- package/lib/sources/local-agent/types.js +20 -0
- package/lib/sources/web-chat/index.d.ts +5 -1
- package/lib/sources/web-chat/index.js +47 -8
- package/lib/store/spec.d.ts +50 -4
- package/lib/store/spec.js +2 -2
- package/lib/sync/index.d.ts +1 -0
- package/lib/sync/index.js +28 -8
- package/lib/tool.d.ts +5 -0
- package/lib/tool.js +418 -45
- package/lib/typert.js +13 -2
- package/lib/types.d.ts +28 -2
- package/lib/update.d.ts +6 -0
- package/lib/update.js +29 -1
- package/lib/web.js +5 -1
- package/lib/wire.d.ts +80 -9
- package/lib/wire.js +30 -4
- package/opencli-plugin/chatgpt.js +30 -27
- package/opencli-plugin/claude.js +12 -8
- package/opencli-plugin/common.js +266 -187
- package/opencli-plugin/deepseek.js +8 -5
- package/opencli-plugin/gemini.js +42 -38
- package/opencli-plugin/grok.js +22 -21
- package/opencli-plugin/kimi.js +34 -31
- package/opencli-plugin/opencli-plugin.json +6 -6
- package/opencli-plugin/package.json +8 -8
- package/package.json +182 -167
- package/lib/profile-mode.d.ts +0 -30
- package/lib/profile-mode.js +0 -90
|
@@ -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
|
-
|
|
219
|
-
const
|
|
220
|
-
const
|
|
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));
|
package/lib/store/spec.d.ts
CHANGED
|
@@ -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,15 +189,44 @@ 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";
|
|
193
228
|
"raw-text": "raw-text";
|
|
194
229
|
}>>;
|
|
195
|
-
referenceUiMode: z.ZodOptional<z.ZodEnum<{
|
|
196
|
-
plugin: "plugin";
|
|
197
|
-
official: "official";
|
|
198
|
-
}>>;
|
|
199
230
|
picker: z.ZodOptional<z.ZodObject<{
|
|
200
231
|
displayMode: z.ZodDefault<z.ZodEnum<{
|
|
201
232
|
collapse: "collapse";
|
|
@@ -225,23 +256,38 @@ export declare const referenceAnythingDomainSpec: {
|
|
|
225
256
|
limit: z.ZodNumber;
|
|
226
257
|
maxCandidates: z.ZodDefault<z.ZodNumber>;
|
|
227
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>>;
|
|
228
265
|
conversations: z.ZodObject<{
|
|
229
266
|
enabled: z.ZodBoolean;
|
|
230
267
|
order: z.ZodNumber;
|
|
231
268
|
limit: z.ZodNumber;
|
|
232
269
|
maxCandidates: z.ZodDefault<z.ZodNumber>;
|
|
233
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>>;
|
|
234
277
|
}, z.core.$strip>>;
|
|
235
278
|
}, z.core.$strip>;
|
|
236
279
|
initial: {
|
|
237
280
|
opencliPath: string;
|
|
238
281
|
profile: string;
|
|
282
|
+
cloudDriveDownloadDirectory: string;
|
|
239
283
|
detailConcurrency: number;
|
|
240
284
|
autoSync: boolean;
|
|
241
285
|
syncOnStartup: boolean;
|
|
242
286
|
autoSyncMinutes: number;
|
|
243
287
|
historyMode: "metadata-only";
|
|
288
|
+
syncHistoryDays: null;
|
|
244
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")[];
|
|
245
291
|
maxReadTurns: number;
|
|
246
292
|
inputRenderMode: "pill";
|
|
247
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),
|
package/lib/sync/index.d.ts
CHANGED
|
@@ -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) =>
|
|
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
|
|
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:
|
|
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
|
-
|
|
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;
|