@usewhisper/mcp-server 2.15.0 → 2.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/server.js +797 -448
- package/package.json +1 -1
package/dist/server.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// ../src/mcp/server.ts
|
|
4
4
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
5
5
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
6
|
-
import { z } from "zod";
|
|
6
|
+
import { z as z2 } from "zod";
|
|
7
7
|
import { execSync, spawnSync } from "child_process";
|
|
8
8
|
import { existsSync, mkdirSync, readdirSync, readFileSync, statSync, writeFileSync, appendFileSync } from "fs";
|
|
9
9
|
import { join, relative, extname, normalize as normalizePath, resolve as resolvePath } from "path";
|
|
@@ -127,6 +127,8 @@ var RuntimeClientError = class extends Error {
|
|
|
127
127
|
code;
|
|
128
128
|
details;
|
|
129
129
|
traceId;
|
|
130
|
+
hint;
|
|
131
|
+
requestId;
|
|
130
132
|
constructor(args) {
|
|
131
133
|
super(args.message);
|
|
132
134
|
this.name = "RuntimeClientError";
|
|
@@ -135,6 +137,8 @@ var RuntimeClientError = class extends Error {
|
|
|
135
137
|
this.code = args.code;
|
|
136
138
|
this.details = args.details;
|
|
137
139
|
this.traceId = args.traceId;
|
|
140
|
+
this.hint = args.hint;
|
|
141
|
+
this.requestId = args.requestId;
|
|
138
142
|
}
|
|
139
143
|
};
|
|
140
144
|
var RuntimeClient = class {
|
|
@@ -339,14 +343,22 @@ var RuntimeClient = class {
|
|
|
339
343
|
};
|
|
340
344
|
}
|
|
341
345
|
const message = toMessage(payload, response.status, response.statusText);
|
|
342
|
-
const
|
|
346
|
+
const payloadObject = isObject(payload) ? payload : {};
|
|
347
|
+
const payloadCode = typeof payloadObject.code === "string" ? payloadObject.code : void 0;
|
|
348
|
+
const payloadHint = typeof payloadObject.hint === "string" ? payloadObject.hint : void 0;
|
|
349
|
+
const payloadRequestId = typeof payloadObject.requestId === "string" ? payloadObject.requestId : typeof payloadObject.request_id === "string" ? payloadObject.request_id : void 0;
|
|
350
|
+
const payloadRetryable = typeof payloadObject.retryable === "boolean" ? payloadObject.retryable : void 0;
|
|
351
|
+
const statusRetryable = this.shouldRetryStatus(response.status);
|
|
352
|
+
const retryable = payloadRetryable ?? statusRetryable;
|
|
343
353
|
const error = new RuntimeClientError({
|
|
344
354
|
message,
|
|
345
355
|
status: response.status,
|
|
346
356
|
retryable,
|
|
347
|
-
code: response.status === 404 ? "NOT_FOUND" : "REQUEST_FAILED",
|
|
357
|
+
code: payloadCode || (response.status === 404 ? "NOT_FOUND" : "REQUEST_FAILED"),
|
|
348
358
|
details: payload,
|
|
349
|
-
traceId
|
|
359
|
+
traceId: payloadRequestId || traceId,
|
|
360
|
+
requestId: payloadRequestId || traceId,
|
|
361
|
+
hint: payloadHint
|
|
350
362
|
});
|
|
351
363
|
lastError = error;
|
|
352
364
|
if (!retryable || attempt === maxAttempts - 1) {
|
|
@@ -360,7 +372,8 @@ var RuntimeClient = class {
|
|
|
360
372
|
message: isAbort ? "Request timed out" : error instanceof Error ? error.message : "Network error",
|
|
361
373
|
retryable: this.retryPolicy.retryOnNetworkError ?? true,
|
|
362
374
|
code: isAbort ? "TIMEOUT" : "NETWORK_ERROR",
|
|
363
|
-
traceId
|
|
375
|
+
traceId,
|
|
376
|
+
requestId: traceId
|
|
364
377
|
});
|
|
365
378
|
lastError = mapped;
|
|
366
379
|
this.diagnostics.add({
|
|
@@ -391,6 +404,26 @@ var RuntimeClient = class {
|
|
|
391
404
|
}
|
|
392
405
|
};
|
|
393
406
|
|
|
407
|
+
// ../src/sdk/errors.ts
|
|
408
|
+
var WhisperError = class extends Error {
|
|
409
|
+
code;
|
|
410
|
+
status;
|
|
411
|
+
retryable;
|
|
412
|
+
hint;
|
|
413
|
+
requestId;
|
|
414
|
+
details;
|
|
415
|
+
constructor(args) {
|
|
416
|
+
super(args.message, args.cause ? { cause: args.cause } : void 0);
|
|
417
|
+
this.name = "WhisperError";
|
|
418
|
+
this.code = args.code;
|
|
419
|
+
this.status = args.status;
|
|
420
|
+
this.retryable = args.retryable ?? false;
|
|
421
|
+
this.hint = args.hint;
|
|
422
|
+
this.requestId = args.requestId;
|
|
423
|
+
this.details = args.details;
|
|
424
|
+
}
|
|
425
|
+
};
|
|
426
|
+
|
|
394
427
|
// ../src/sdk/core/cache.ts
|
|
395
428
|
var SearchResponseCache = class {
|
|
396
429
|
ttlMs;
|
|
@@ -2186,12 +2219,44 @@ ${lines.join("\n")}`;
|
|
|
2186
2219
|
|
|
2187
2220
|
// ../src/sdk/whisper.ts
|
|
2188
2221
|
var PROJECT_CACHE_TTL_MS = 3e4;
|
|
2222
|
+
var IDENTITY_WARNINGS = /* @__PURE__ */ new Set();
|
|
2189
2223
|
function isLikelyProjectId(projectRef) {
|
|
2190
2224
|
return /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(projectRef);
|
|
2191
2225
|
}
|
|
2226
|
+
function randomRequestId() {
|
|
2227
|
+
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
|
|
2228
|
+
return crypto.randomUUID();
|
|
2229
|
+
}
|
|
2230
|
+
return `req_${Math.random().toString(36).slice(2, 11)}`;
|
|
2231
|
+
}
|
|
2232
|
+
function parseIdentityMode(value) {
|
|
2233
|
+
return value === "app-identity" ? "app-identity" : "demo-local";
|
|
2234
|
+
}
|
|
2235
|
+
function parseEnvironment(value) {
|
|
2236
|
+
if (value === "staging" || value === "production") return value;
|
|
2237
|
+
return "local";
|
|
2238
|
+
}
|
|
2239
|
+
function classifyRuntimeErrorCode(error) {
|
|
2240
|
+
if (error.code === "MISSING_PROJECT") return "MISSING_PROJECT";
|
|
2241
|
+
if (error.code === "TIMEOUT") return "TIMEOUT";
|
|
2242
|
+
if (error.code === "NETWORK_ERROR") return "NETWORK_ERROR";
|
|
2243
|
+
if (error.code === "VALIDATION_ERROR") return "VALIDATION_ERROR";
|
|
2244
|
+
if (error.status === 401 || error.status === 403) return "INVALID_API_KEY";
|
|
2245
|
+
if (error.status === 408) return "TIMEOUT";
|
|
2246
|
+
if (error.status === 429) return "RATE_LIMITED";
|
|
2247
|
+
if (error.status && error.status >= 500) return "TEMPORARY_UNAVAILABLE";
|
|
2248
|
+
if (error.code === "PROJECT_NOT_FOUND" || error.code === "NOT_FOUND") return "PROJECT_NOT_FOUND";
|
|
2249
|
+
return "REQUEST_FAILED";
|
|
2250
|
+
}
|
|
2192
2251
|
var WhisperClient = class _WhisperClient {
|
|
2193
2252
|
constructor(config) {
|
|
2194
2253
|
this.config = config;
|
|
2254
|
+
const env = typeof process !== "undefined" ? process.env : {};
|
|
2255
|
+
this.identityMode = parseIdentityMode(config.identityMode || env.WHISPER_IDENTITY_MODE);
|
|
2256
|
+
this.environment = parseEnvironment(config.environment || env.WHISPER_ENV || (env.NODE_ENV === "production" ? "production" : "local"));
|
|
2257
|
+
this.strictIdentityMode = config.strictIdentityMode ?? env.WHISPER_DEMO_LOCAL_STRICT === "true";
|
|
2258
|
+
this.getIdentity = config.getIdentity;
|
|
2259
|
+
this.enforceIdentityModeGuardrail();
|
|
2195
2260
|
this.diagnosticsStore = new DiagnosticsStore(config.telemetry?.maxEntries || 1e3);
|
|
2196
2261
|
this.runtimeClient = new RuntimeClient(
|
|
2197
2262
|
{
|
|
@@ -2301,26 +2366,29 @@ var WhisperClient = class _WhisperClient {
|
|
|
2301
2366
|
status: () => this.writeQueue.status()
|
|
2302
2367
|
};
|
|
2303
2368
|
this.memory = {
|
|
2304
|
-
add: (params) => this.memoryModule.add(params),
|
|
2305
|
-
addBulk: (params) => this.memoryModule.addBulk(
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2369
|
+
add: (params) => this.runOrThrow(async () => this.memoryModule.add(await this.withIdentity(params))),
|
|
2370
|
+
addBulk: (params) => this.runOrThrow(async () => this.memoryModule.addBulk({
|
|
2371
|
+
...params,
|
|
2372
|
+
memories: await Promise.all(params.memories.map((memory) => this.withIdentity(memory)))
|
|
2373
|
+
})),
|
|
2374
|
+
search: (params) => this.runOrThrow(async () => this.memoryModule.search(await this.withIdentity(params))),
|
|
2375
|
+
get: (memoryId) => this.runOrThrow(async () => this.memoryModule.get(memoryId)),
|
|
2376
|
+
getUserProfile: (params) => this.runOrThrow(async () => this.profileModule.getUserProfile(await this.withIdentity(params, true))),
|
|
2377
|
+
getSessionMemories: (params) => this.runOrThrow(async () => this.profileModule.getSessionMemories(await this.withIdentity(params))),
|
|
2378
|
+
update: (memoryId, params) => this.runOrThrow(async () => this.memoryModule.update(memoryId, params)),
|
|
2379
|
+
delete: (memoryId) => this.runOrThrow(async () => this.memoryModule.delete(memoryId)),
|
|
2380
|
+
flag: (params) => this.runOrThrow(async () => this.memoryModule.flag(params))
|
|
2313
2381
|
};
|
|
2314
2382
|
this.session = {
|
|
2315
|
-
start: (params) => this.sessionModule.start(params),
|
|
2316
|
-
event: (params) => this.sessionModule.event(params),
|
|
2317
|
-
suspend: (params) => this.sessionModule.suspend(params),
|
|
2318
|
-
resume: (params) => this.sessionModule.resume(params),
|
|
2319
|
-
end: (params) => this.sessionModule.end(params)
|
|
2383
|
+
start: (params) => this.runOrThrow(async () => this.sessionModule.start(await this.withSessionIdentity(params))),
|
|
2384
|
+
event: (params) => this.runOrThrow(async () => this.sessionModule.event(params)),
|
|
2385
|
+
suspend: (params) => this.runOrThrow(async () => this.sessionModule.suspend(params)),
|
|
2386
|
+
resume: (params) => this.runOrThrow(async () => this.sessionModule.resume(params)),
|
|
2387
|
+
end: (params) => this.runOrThrow(async () => this.sessionModule.end(params))
|
|
2320
2388
|
};
|
|
2321
2389
|
this.profile = {
|
|
2322
|
-
getUserProfile: (params) => this.profileModule.getUserProfile(params),
|
|
2323
|
-
getSessionMemories: (params) => this.profileModule.getSessionMemories(params)
|
|
2390
|
+
getUserProfile: (params) => this.runOrThrow(async () => this.profileModule.getUserProfile(await this.withIdentity(params, true))),
|
|
2391
|
+
getSessionMemories: (params) => this.runOrThrow(async () => this.profileModule.getSessionMemories(await this.withIdentity(params)))
|
|
2324
2392
|
};
|
|
2325
2393
|
this.analytics = {
|
|
2326
2394
|
diagnosticsSnapshot: () => this.analyticsModule.diagnosticsSnapshot(),
|
|
@@ -2342,18 +2410,158 @@ var WhisperClient = class _WhisperClient {
|
|
|
2342
2410
|
profileModule;
|
|
2343
2411
|
analyticsModule;
|
|
2344
2412
|
projectRefToId = /* @__PURE__ */ new Map();
|
|
2413
|
+
identityMode;
|
|
2414
|
+
environment;
|
|
2415
|
+
strictIdentityMode;
|
|
2416
|
+
getIdentity;
|
|
2345
2417
|
projectCache = [];
|
|
2346
2418
|
projectCacheExpiresAt = 0;
|
|
2419
|
+
enforceIdentityModeGuardrail(requestId = randomRequestId()) {
|
|
2420
|
+
if (this.identityMode !== "demo-local") return;
|
|
2421
|
+
if (this.environment === "local") return;
|
|
2422
|
+
const message = "[Whisper SDK] WHISPER_IDENTITY_MODE=demo-local is intended only for local development. Switch to app-identity and provide getIdentity() or per-call user_id/session_id.";
|
|
2423
|
+
if (this.strictIdentityMode || this.environment === "production") {
|
|
2424
|
+
throw new WhisperError({
|
|
2425
|
+
code: "MISCONFIGURED_IDENTITY_MODE",
|
|
2426
|
+
message,
|
|
2427
|
+
retryable: false,
|
|
2428
|
+
hint: "Set identityMode: 'app-identity' and provide a getIdentity() function that returns { userId, sessionId? }. To override for testing, set environment: 'local' explicitly."
|
|
2429
|
+
});
|
|
2430
|
+
}
|
|
2431
|
+
const warningKey = `${this.environment}:${this.identityMode}`;
|
|
2432
|
+
if (!IDENTITY_WARNINGS.has(warningKey)) {
|
|
2433
|
+
IDENTITY_WARNINGS.add(warningKey);
|
|
2434
|
+
if (typeof console !== "undefined" && typeof console.warn === "function") {
|
|
2435
|
+
console.warn(`${message} requestId=${requestId}`);
|
|
2436
|
+
}
|
|
2437
|
+
}
|
|
2438
|
+
}
|
|
2439
|
+
toWhisperError(error, hint) {
|
|
2440
|
+
if (error instanceof WhisperError) return error;
|
|
2441
|
+
if (error instanceof RuntimeClientError) {
|
|
2442
|
+
return new WhisperError({
|
|
2443
|
+
code: classifyRuntimeErrorCode(error),
|
|
2444
|
+
message: error.message,
|
|
2445
|
+
status: error.status,
|
|
2446
|
+
retryable: error.retryable,
|
|
2447
|
+
hint: error.hint || hint,
|
|
2448
|
+
requestId: error.requestId || error.traceId,
|
|
2449
|
+
details: error.details,
|
|
2450
|
+
cause: error
|
|
2451
|
+
});
|
|
2452
|
+
}
|
|
2453
|
+
if (error instanceof Error) {
|
|
2454
|
+
return new WhisperError({
|
|
2455
|
+
code: "REQUEST_FAILED",
|
|
2456
|
+
message: error.message,
|
|
2457
|
+
retryable: false,
|
|
2458
|
+
hint,
|
|
2459
|
+
cause: error
|
|
2460
|
+
});
|
|
2461
|
+
}
|
|
2462
|
+
return new WhisperError({
|
|
2463
|
+
code: "REQUEST_FAILED",
|
|
2464
|
+
message: "Unknown SDK error",
|
|
2465
|
+
retryable: false,
|
|
2466
|
+
hint,
|
|
2467
|
+
details: error
|
|
2468
|
+
});
|
|
2469
|
+
}
|
|
2470
|
+
async runOrThrow(work, hint) {
|
|
2471
|
+
try {
|
|
2472
|
+
return await work();
|
|
2473
|
+
} catch (error) {
|
|
2474
|
+
throw this.toWhisperError(error, hint);
|
|
2475
|
+
}
|
|
2476
|
+
}
|
|
2477
|
+
async resolveIdentityOverride() {
|
|
2478
|
+
if (!this.getIdentity) return null;
|
|
2479
|
+
const resolved = await this.getIdentity();
|
|
2480
|
+
const userId = String(resolved?.userId || "").trim();
|
|
2481
|
+
const sessionId = resolved?.sessionId ? String(resolved.sessionId).trim() : void 0;
|
|
2482
|
+
if (!userId) {
|
|
2483
|
+
throw new WhisperError({
|
|
2484
|
+
code: "AUTH_IDENTITY_INVALID",
|
|
2485
|
+
message: "getIdentity() returned an invalid identity payload.",
|
|
2486
|
+
retryable: false,
|
|
2487
|
+
hint: "Return { userId, sessionId? } from getIdentity()."
|
|
2488
|
+
});
|
|
2489
|
+
}
|
|
2490
|
+
return {
|
|
2491
|
+
userId,
|
|
2492
|
+
sessionId: sessionId || void 0
|
|
2493
|
+
};
|
|
2494
|
+
}
|
|
2495
|
+
async withIdentity(params, requireUser = false) {
|
|
2496
|
+
const currentUser = params.user_id ? String(params.user_id).trim() : "";
|
|
2497
|
+
const currentSession = params.session_id ? String(params.session_id).trim() : "";
|
|
2498
|
+
if (currentUser) {
|
|
2499
|
+
return {
|
|
2500
|
+
...params,
|
|
2501
|
+
user_id: currentUser,
|
|
2502
|
+
session_id: currentSession || params.session_id
|
|
2503
|
+
};
|
|
2504
|
+
}
|
|
2505
|
+
const resolved = await this.resolveIdentityOverride();
|
|
2506
|
+
if (resolved) {
|
|
2507
|
+
return {
|
|
2508
|
+
...params,
|
|
2509
|
+
user_id: resolved.userId,
|
|
2510
|
+
session_id: currentSession || resolved.sessionId
|
|
2511
|
+
};
|
|
2512
|
+
}
|
|
2513
|
+
if (requireUser || this.identityMode === "app-identity") {
|
|
2514
|
+
throw new WhisperError({
|
|
2515
|
+
code: "AUTH_IDENTITY_REQUIRED",
|
|
2516
|
+
message: "A user identity is required in app-identity mode.",
|
|
2517
|
+
retryable: false,
|
|
2518
|
+
hint: "Provide user_id/session_id per call or configure getIdentity() in WhisperClient."
|
|
2519
|
+
});
|
|
2520
|
+
}
|
|
2521
|
+
return params;
|
|
2522
|
+
}
|
|
2523
|
+
async withSessionIdentity(params) {
|
|
2524
|
+
const userId = params.userId ? String(params.userId).trim() : "";
|
|
2525
|
+
const sessionId = params.sessionId ? String(params.sessionId).trim() : "";
|
|
2526
|
+
if (userId) {
|
|
2527
|
+
return {
|
|
2528
|
+
...params,
|
|
2529
|
+
userId,
|
|
2530
|
+
sessionId: sessionId || params.sessionId
|
|
2531
|
+
};
|
|
2532
|
+
}
|
|
2533
|
+
const resolved = await this.resolveIdentityOverride();
|
|
2534
|
+
if (resolved?.userId) {
|
|
2535
|
+
return {
|
|
2536
|
+
...params,
|
|
2537
|
+
userId: resolved.userId,
|
|
2538
|
+
sessionId: sessionId || resolved.sessionId
|
|
2539
|
+
};
|
|
2540
|
+
}
|
|
2541
|
+
throw new WhisperError({
|
|
2542
|
+
code: "AUTH_IDENTITY_REQUIRED",
|
|
2543
|
+
message: "Session operations require a user identity.",
|
|
2544
|
+
retryable: false,
|
|
2545
|
+
hint: "Pass userId explicitly or configure getIdentity() in WhisperClient."
|
|
2546
|
+
});
|
|
2547
|
+
}
|
|
2347
2548
|
static fromEnv(overrides = {}) {
|
|
2348
2549
|
const env = typeof process !== "undefined" ? process.env : {};
|
|
2349
2550
|
const apiKey = overrides.apiKey || env.WHISPER_API_KEY || env.USEWHISPER_API_KEY || env.API_KEY;
|
|
2350
2551
|
if (!apiKey) {
|
|
2351
|
-
throw new
|
|
2552
|
+
throw new WhisperError({
|
|
2553
|
+
code: "INVALID_API_KEY",
|
|
2554
|
+
message: "Missing API key. Set WHISPER_API_KEY / USEWHISPER_API_KEY / API_KEY.",
|
|
2555
|
+
retryable: false
|
|
2556
|
+
});
|
|
2352
2557
|
}
|
|
2353
2558
|
return new _WhisperClient({
|
|
2354
2559
|
apiKey,
|
|
2355
2560
|
baseUrl: overrides.baseUrl || env.WHISPER_BASE_URL || env.API_BASE_URL || "https://context.usewhisper.dev",
|
|
2356
2561
|
project: overrides.project || env.WHISPER_PROJECT || env.PROJECT,
|
|
2562
|
+
identityMode: overrides.identityMode || parseIdentityMode(env.WHISPER_IDENTITY_MODE),
|
|
2563
|
+
environment: overrides.environment || parseEnvironment(env.WHISPER_ENV || (env.NODE_ENV === "production" ? "production" : "local")),
|
|
2564
|
+
strictIdentityMode: overrides.strictIdentityMode ?? env.WHISPER_DEMO_LOCAL_STRICT === "true",
|
|
2357
2565
|
...overrides
|
|
2358
2566
|
});
|
|
2359
2567
|
}
|
|
@@ -2390,10 +2598,11 @@ var WhisperClient = class _WhisperClient {
|
|
|
2390
2598
|
getRequiredProject(project) {
|
|
2391
2599
|
const resolved = project || this.config.project;
|
|
2392
2600
|
if (!resolved) {
|
|
2393
|
-
throw new
|
|
2601
|
+
throw new WhisperError({
|
|
2394
2602
|
code: "MISSING_PROJECT",
|
|
2395
2603
|
message: "Project is required",
|
|
2396
|
-
retryable: false
|
|
2604
|
+
retryable: false,
|
|
2605
|
+
hint: "Pass project in the call or configure a default project in WhisperClient."
|
|
2397
2606
|
});
|
|
2398
2607
|
}
|
|
2399
2608
|
return resolved;
|
|
@@ -2435,81 +2644,182 @@ var WhisperClient = class _WhisperClient {
|
|
|
2435
2644
|
}
|
|
2436
2645
|
}
|
|
2437
2646
|
async resolveProject(projectRef) {
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2647
|
+
return this.runOrThrow(async () => {
|
|
2648
|
+
const resolvedRef = this.getRequiredProject(projectRef);
|
|
2649
|
+
const cachedProjects = await this.refreshProjectCache(false);
|
|
2650
|
+
const cachedProject = cachedProjects.find(
|
|
2651
|
+
(project) => project.id === resolvedRef || project.slug === resolvedRef || project.name === resolvedRef
|
|
2652
|
+
);
|
|
2653
|
+
if (cachedProject) {
|
|
2654
|
+
return cachedProject;
|
|
2655
|
+
}
|
|
2656
|
+
const resolvedProject = await this.fetchResolvedProject(resolvedRef);
|
|
2657
|
+
if (resolvedProject) {
|
|
2658
|
+
this.projectRefToId.set(resolvedProject.id, resolvedProject.id);
|
|
2659
|
+
this.projectRefToId.set(resolvedProject.slug, resolvedProject.id);
|
|
2660
|
+
this.projectRefToId.set(resolvedProject.name, resolvedProject.id);
|
|
2661
|
+
this.projectCache = [
|
|
2662
|
+
...this.projectCache.filter((project) => project.id !== resolvedProject.id),
|
|
2663
|
+
resolvedProject
|
|
2664
|
+
];
|
|
2665
|
+
this.projectCacheExpiresAt = Date.now() + PROJECT_CACHE_TTL_MS;
|
|
2666
|
+
return resolvedProject;
|
|
2667
|
+
}
|
|
2668
|
+
if (isLikelyProjectId(resolvedRef)) {
|
|
2669
|
+
return {
|
|
2670
|
+
id: resolvedRef,
|
|
2671
|
+
orgId: "",
|
|
2672
|
+
name: resolvedRef,
|
|
2673
|
+
slug: resolvedRef,
|
|
2674
|
+
createdAt: (/* @__PURE__ */ new Date(0)).toISOString(),
|
|
2675
|
+
updatedAt: (/* @__PURE__ */ new Date(0)).toISOString()
|
|
2676
|
+
};
|
|
2677
|
+
}
|
|
2678
|
+
throw new WhisperError({
|
|
2679
|
+
code: "PROJECT_NOT_FOUND",
|
|
2680
|
+
message: `Project '${resolvedRef}' not found`,
|
|
2681
|
+
retryable: false
|
|
2682
|
+
});
|
|
2683
|
+
});
|
|
2684
|
+
}
|
|
2685
|
+
async preflight(options) {
|
|
2686
|
+
const requestId = randomRequestId();
|
|
2687
|
+
const checks = [];
|
|
2688
|
+
try {
|
|
2689
|
+
this.enforceIdentityModeGuardrail(requestId);
|
|
2690
|
+
} catch (error) {
|
|
2691
|
+
throw this.toWhisperError(error, "Update identity mode before running preflight.");
|
|
2692
|
+
}
|
|
2693
|
+
const apiKeyOk = typeof this.config.apiKey === "string" && this.config.apiKey.trim().length > 0;
|
|
2694
|
+
checks.push({
|
|
2695
|
+
check: "api_key",
|
|
2696
|
+
ok: apiKeyOk,
|
|
2697
|
+
message: apiKeyOk ? "API key is configured." : "Missing API key.",
|
|
2698
|
+
hint: apiKeyOk ? void 0 : "Set WHISPER_API_KEY or pass apiKey to WhisperClient."
|
|
2699
|
+
});
|
|
2700
|
+
try {
|
|
2701
|
+
await this.runtimeClient.request({
|
|
2702
|
+
endpoint: "/v1/projects",
|
|
2703
|
+
method: "GET",
|
|
2704
|
+
operation: "get",
|
|
2705
|
+
idempotent: true,
|
|
2706
|
+
traceId: requestId
|
|
2707
|
+
});
|
|
2708
|
+
checks.push({
|
|
2709
|
+
check: "api_connectivity",
|
|
2710
|
+
ok: true,
|
|
2711
|
+
message: "Connected to Whisper API."
|
|
2712
|
+
});
|
|
2713
|
+
} catch (error) {
|
|
2714
|
+
const mapped = this.toWhisperError(error, "Confirm WHISPER_BASE_URL and API key permissions.");
|
|
2715
|
+
checks.push({
|
|
2716
|
+
check: "api_connectivity",
|
|
2717
|
+
ok: false,
|
|
2718
|
+
message: mapped.message,
|
|
2719
|
+
hint: mapped.hint
|
|
2720
|
+
});
|
|
2445
2721
|
}
|
|
2446
|
-
const
|
|
2447
|
-
if (
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2722
|
+
const projectRef = options?.project || this.config.project;
|
|
2723
|
+
if (projectRef) {
|
|
2724
|
+
try {
|
|
2725
|
+
await this.resolveProject(projectRef);
|
|
2726
|
+
checks.push({
|
|
2727
|
+
check: "project_access",
|
|
2728
|
+
ok: true,
|
|
2729
|
+
message: `Project '${projectRef}' is reachable.`
|
|
2730
|
+
});
|
|
2731
|
+
} catch (error) {
|
|
2732
|
+
const mapped = this.toWhisperError(error, "Create or grant access to the configured project.");
|
|
2733
|
+
checks.push({
|
|
2734
|
+
check: "project_access",
|
|
2735
|
+
ok: false,
|
|
2736
|
+
message: mapped.message,
|
|
2737
|
+
hint: mapped.hint
|
|
2738
|
+
});
|
|
2739
|
+
}
|
|
2740
|
+
} else {
|
|
2741
|
+
checks.push({
|
|
2742
|
+
check: "project_access",
|
|
2743
|
+
ok: true,
|
|
2744
|
+
message: "No default project configured (project will be required per call)."
|
|
2745
|
+
});
|
|
2457
2746
|
}
|
|
2458
|
-
if (
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2747
|
+
if (options?.requireIdentity || this.identityMode === "app-identity") {
|
|
2748
|
+
try {
|
|
2749
|
+
const identity = await this.resolveIdentityOverride();
|
|
2750
|
+
const ok = Boolean(identity?.userId);
|
|
2751
|
+
checks.push({
|
|
2752
|
+
check: "identity_resolution",
|
|
2753
|
+
ok,
|
|
2754
|
+
message: ok ? "Identity resolver is configured." : "Identity resolver is missing.",
|
|
2755
|
+
hint: ok ? void 0 : "Provide getIdentity() or pass user_id/session_id per call."
|
|
2756
|
+
});
|
|
2757
|
+
} catch (error) {
|
|
2758
|
+
const mapped = this.toWhisperError(error, "Fix identity resolver output before production usage.");
|
|
2759
|
+
checks.push({
|
|
2760
|
+
check: "identity_resolution",
|
|
2761
|
+
ok: false,
|
|
2762
|
+
message: mapped.message,
|
|
2763
|
+
hint: mapped.hint
|
|
2764
|
+
});
|
|
2765
|
+
}
|
|
2467
2766
|
}
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2767
|
+
return {
|
|
2768
|
+
ok: checks.every((check) => check.ok),
|
|
2769
|
+
checks,
|
|
2770
|
+
requestId,
|
|
2771
|
+
identityMode: this.identityMode,
|
|
2772
|
+
environment: this.environment
|
|
2773
|
+
};
|
|
2473
2774
|
}
|
|
2474
2775
|
async query(params) {
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2776
|
+
return this.runOrThrow(async () => {
|
|
2777
|
+
const identityParams = await this.withIdentity(params);
|
|
2778
|
+
const project = (await this.resolveProject(identityParams.project)).id;
|
|
2779
|
+
const response = await this.runtimeClient.request({
|
|
2780
|
+
endpoint: "/v1/context/query",
|
|
2781
|
+
method: "POST",
|
|
2782
|
+
operation: "search",
|
|
2783
|
+
body: {
|
|
2784
|
+
...identityParams,
|
|
2785
|
+
project
|
|
2786
|
+
},
|
|
2787
|
+
idempotent: true
|
|
2788
|
+
});
|
|
2789
|
+
return response.data;
|
|
2485
2790
|
});
|
|
2486
|
-
return response.data;
|
|
2487
2791
|
}
|
|
2488
2792
|
async ingestSession(params) {
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2793
|
+
return this.runOrThrow(async () => {
|
|
2794
|
+
const identityParams = await this.withIdentity(params);
|
|
2795
|
+
const project = (await this.resolveProject(identityParams.project)).id;
|
|
2796
|
+
const response = await this.runtimeClient.request({
|
|
2797
|
+
endpoint: "/v1/memory/ingest/session",
|
|
2798
|
+
method: "POST",
|
|
2799
|
+
operation: "session",
|
|
2800
|
+
body: {
|
|
2801
|
+
...identityParams,
|
|
2802
|
+
project
|
|
2803
|
+
}
|
|
2804
|
+
});
|
|
2805
|
+
return response.data;
|
|
2498
2806
|
});
|
|
2499
|
-
return response.data;
|
|
2500
2807
|
}
|
|
2501
2808
|
async learn(params) {
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2809
|
+
return this.runOrThrow(async () => {
|
|
2810
|
+
const identityParams = params.mode === "conversation" ? await this.withIdentity(params) : params;
|
|
2811
|
+
const project = (await this.resolveProject(identityParams.project)).id;
|
|
2812
|
+
const response = await this.runtimeClient.request({
|
|
2813
|
+
endpoint: "/v1/learn",
|
|
2814
|
+
method: "POST",
|
|
2815
|
+
operation: params.mode === "conversation" ? "session" : "bulk",
|
|
2816
|
+
body: {
|
|
2817
|
+
...identityParams,
|
|
2818
|
+
project
|
|
2819
|
+
}
|
|
2820
|
+
});
|
|
2821
|
+
return response.data;
|
|
2511
2822
|
});
|
|
2512
|
-
return response.data;
|
|
2513
2823
|
}
|
|
2514
2824
|
createAgentRuntime(options = {}) {
|
|
2515
2825
|
const baseContext = {
|
|
@@ -2571,26 +2881,60 @@ var WhisperClient = class _WhisperClient {
|
|
|
2571
2881
|
diagnostics: base.diagnostics
|
|
2572
2882
|
};
|
|
2573
2883
|
}
|
|
2884
|
+
async deleteSource(sourceId) {
|
|
2885
|
+
return this.runOrThrow(async () => {
|
|
2886
|
+
const response = await this.runtimeClient.request({
|
|
2887
|
+
endpoint: `/v1/sources/${sourceId}`,
|
|
2888
|
+
method: "DELETE",
|
|
2889
|
+
operation: "writeAck"
|
|
2890
|
+
});
|
|
2891
|
+
return response.data;
|
|
2892
|
+
});
|
|
2893
|
+
}
|
|
2894
|
+
async extractMemories(params) {
|
|
2895
|
+
return this.runOrThrow(async () => {
|
|
2896
|
+
const project = (await this.resolveProject(params.project)).id;
|
|
2897
|
+
const response = await this.runtimeClient.request({
|
|
2898
|
+
endpoint: "/v1/memory/extract",
|
|
2899
|
+
method: "POST",
|
|
2900
|
+
operation: "writeAck",
|
|
2901
|
+
body: { project, message: params.message }
|
|
2902
|
+
});
|
|
2903
|
+
return response.data;
|
|
2904
|
+
});
|
|
2905
|
+
}
|
|
2574
2906
|
async shutdown() {
|
|
2575
2907
|
await this.writeQueue.stop();
|
|
2576
2908
|
}
|
|
2577
2909
|
};
|
|
2578
2910
|
|
|
2911
|
+
// ../src/sdk/adapters/tools.ts
|
|
2912
|
+
import { z } from "zod";
|
|
2913
|
+
var searchInputSchema = z.object({
|
|
2914
|
+
q: z.string().min(1),
|
|
2915
|
+
project: z.string().optional(),
|
|
2916
|
+
topK: z.number().int().positive().max(50).optional(),
|
|
2917
|
+
userId: z.string().optional(),
|
|
2918
|
+
sessionId: z.string().optional()
|
|
2919
|
+
});
|
|
2920
|
+
var rememberInputSchema = z.object({
|
|
2921
|
+
content: z.string().min(1),
|
|
2922
|
+
project: z.string().optional(),
|
|
2923
|
+
memoryType: z.enum([
|
|
2924
|
+
"factual",
|
|
2925
|
+
"preference",
|
|
2926
|
+
"event",
|
|
2927
|
+
"relationship",
|
|
2928
|
+
"opinion",
|
|
2929
|
+
"goal",
|
|
2930
|
+
"instruction"
|
|
2931
|
+
]).optional(),
|
|
2932
|
+
userId: z.string().optional(),
|
|
2933
|
+
sessionId: z.string().optional(),
|
|
2934
|
+
metadata: z.record(z.unknown()).optional()
|
|
2935
|
+
});
|
|
2936
|
+
|
|
2579
2937
|
// ../src/sdk/index.ts
|
|
2580
|
-
var WhisperError = class extends Error {
|
|
2581
|
-
code;
|
|
2582
|
-
status;
|
|
2583
|
-
retryable;
|
|
2584
|
-
details;
|
|
2585
|
-
constructor(args) {
|
|
2586
|
-
super(args.message);
|
|
2587
|
-
this.name = "WhisperError";
|
|
2588
|
-
this.code = args.code;
|
|
2589
|
-
this.status = args.status;
|
|
2590
|
-
this.retryable = args.retryable ?? false;
|
|
2591
|
-
this.details = args.details;
|
|
2592
|
-
}
|
|
2593
|
-
};
|
|
2594
2938
|
var DEFAULT_MAX_ATTEMPTS = 3;
|
|
2595
2939
|
var DEFAULT_BASE_DELAY_MS = 250;
|
|
2596
2940
|
var DEFAULT_MAX_DELAY_MS = 2e3;
|
|
@@ -2961,7 +3305,10 @@ var WhisperContext = class _WhisperContext {
|
|
|
2961
3305
|
message,
|
|
2962
3306
|
status: error.status,
|
|
2963
3307
|
retryable,
|
|
2964
|
-
|
|
3308
|
+
hint: error.hint,
|
|
3309
|
+
requestId: error.requestId || error.traceId,
|
|
3310
|
+
details: error.details,
|
|
3311
|
+
cause: error
|
|
2965
3312
|
});
|
|
2966
3313
|
}
|
|
2967
3314
|
}
|
|
@@ -6128,9 +6475,9 @@ server.tool(
|
|
|
6128
6475
|
"index.workspace_resolve",
|
|
6129
6476
|
"Resolve workspace identity from path + API key and map to a project without mandatory dashboard setup.",
|
|
6130
6477
|
{
|
|
6131
|
-
path:
|
|
6132
|
-
workspace_id:
|
|
6133
|
-
project:
|
|
6478
|
+
path: z2.string().optional().describe("Workspace path. Defaults to current working directory."),
|
|
6479
|
+
workspace_id: z2.string().optional(),
|
|
6480
|
+
project: z2.string().optional()
|
|
6134
6481
|
},
|
|
6135
6482
|
async ({ path, workspace_id, project }) => {
|
|
6136
6483
|
try {
|
|
@@ -6167,8 +6514,8 @@ server.tool(
|
|
|
6167
6514
|
"index.workspace_status",
|
|
6168
6515
|
"Check index freshness, coverage, commit, and pending changes before retrieval/edits.",
|
|
6169
6516
|
{
|
|
6170
|
-
workspace_id:
|
|
6171
|
-
path:
|
|
6517
|
+
workspace_id: z2.string().optional(),
|
|
6518
|
+
path: z2.string().optional()
|
|
6172
6519
|
},
|
|
6173
6520
|
async ({ workspace_id, path }) => {
|
|
6174
6521
|
try {
|
|
@@ -6205,10 +6552,10 @@ server.tool(
|
|
|
6205
6552
|
"index.workspace_run",
|
|
6206
6553
|
"Refresh local workspace index metadata (coverage, commit, freshness) for trust checks. This does not upload files or create backend embeddings.",
|
|
6207
6554
|
{
|
|
6208
|
-
workspace_id:
|
|
6209
|
-
path:
|
|
6210
|
-
mode:
|
|
6211
|
-
max_files:
|
|
6555
|
+
workspace_id: z2.string().optional(),
|
|
6556
|
+
path: z2.string().optional(),
|
|
6557
|
+
mode: z2.enum(["full", "incremental"]).optional().default("incremental"),
|
|
6558
|
+
max_files: z2.number().optional().default(1500)
|
|
6212
6559
|
},
|
|
6213
6560
|
async ({ workspace_id, path, mode, max_files }) => {
|
|
6214
6561
|
try {
|
|
@@ -6254,11 +6601,11 @@ server.tool(
|
|
|
6254
6601
|
"index.local_scan_ingest",
|
|
6255
6602
|
"Ingest local files into Whisper backend (chunk/embed/index) and persist incremental manifest. Requires WHISPER_MCP_MODE=auto or local.",
|
|
6256
6603
|
{
|
|
6257
|
-
project:
|
|
6258
|
-
path:
|
|
6259
|
-
glob:
|
|
6260
|
-
max_files:
|
|
6261
|
-
chunk_chars:
|
|
6604
|
+
project: z2.string().optional().describe("Project name or slug"),
|
|
6605
|
+
path: z2.string().optional().describe("Local path to ingest. Defaults to current working directory."),
|
|
6606
|
+
glob: z2.string().optional().describe("Optional include glob"),
|
|
6607
|
+
max_files: z2.number().optional().default(200),
|
|
6608
|
+
chunk_chars: z2.number().optional().default(2e4)
|
|
6262
6609
|
},
|
|
6263
6610
|
async ({ project, path, glob, max_files, chunk_chars }) => {
|
|
6264
6611
|
try {
|
|
@@ -6290,12 +6637,12 @@ server.tool(
|
|
|
6290
6637
|
"index.auto_repair",
|
|
6291
6638
|
"Diagnose and apply deterministic retrieval/setup repairs. This is the canonical zero-stress repair path.",
|
|
6292
6639
|
{
|
|
6293
|
-
path:
|
|
6294
|
-
workspace_id:
|
|
6295
|
-
project:
|
|
6296
|
-
apply:
|
|
6297
|
-
repair_scope:
|
|
6298
|
-
allow_restart_hint:
|
|
6640
|
+
path: z2.string().optional(),
|
|
6641
|
+
workspace_id: z2.string().optional(),
|
|
6642
|
+
project: z2.string().optional(),
|
|
6643
|
+
apply: z2.boolean().optional().default(true),
|
|
6644
|
+
repair_scope: z2.enum(["safe", "full"]).optional().default("safe"),
|
|
6645
|
+
allow_restart_hint: z2.boolean().optional().default(true)
|
|
6299
6646
|
},
|
|
6300
6647
|
async ({ path, workspace_id, project, apply, repair_scope, allow_restart_hint }) => {
|
|
6301
6648
|
try {
|
|
@@ -6317,12 +6664,12 @@ server.tool(
|
|
|
6317
6664
|
"fix",
|
|
6318
6665
|
"Primary alias for zero-stress setup/retrieval repair. Delegates to index.auto_repair.",
|
|
6319
6666
|
{
|
|
6320
|
-
path:
|
|
6321
|
-
workspace_id:
|
|
6322
|
-
project:
|
|
6323
|
-
apply:
|
|
6324
|
-
repair_scope:
|
|
6325
|
-
allow_restart_hint:
|
|
6667
|
+
path: z2.string().optional(),
|
|
6668
|
+
workspace_id: z2.string().optional(),
|
|
6669
|
+
project: z2.string().optional(),
|
|
6670
|
+
apply: z2.boolean().optional().default(true),
|
|
6671
|
+
repair_scope: z2.enum(["safe", "full"]).optional().default("safe"),
|
|
6672
|
+
allow_restart_hint: z2.boolean().optional().default(true)
|
|
6326
6673
|
},
|
|
6327
6674
|
async ({ path, workspace_id, project, apply, repair_scope, allow_restart_hint }) => {
|
|
6328
6675
|
try {
|
|
@@ -6591,17 +6938,17 @@ server.tool(
|
|
|
6591
6938
|
"context.get_relevant",
|
|
6592
6939
|
"Default grounded retrieval step for workspace/project questions. Returns ranked evidence with file:line citations and may abstain when workspace/repo trust is not ready.",
|
|
6593
6940
|
{
|
|
6594
|
-
question:
|
|
6595
|
-
path:
|
|
6596
|
-
workspace_id:
|
|
6597
|
-
project:
|
|
6598
|
-
top_k:
|
|
6599
|
-
include_memories:
|
|
6600
|
-
include_graph:
|
|
6601
|
-
session_id:
|
|
6602
|
-
user_id:
|
|
6603
|
-
include_parent_content:
|
|
6604
|
-
retrieval_profile:
|
|
6941
|
+
question: z2.string().describe("Task/question to retrieve context for"),
|
|
6942
|
+
path: z2.string().optional().describe("Workspace path. Defaults to current working directory."),
|
|
6943
|
+
workspace_id: z2.string().optional(),
|
|
6944
|
+
project: z2.string().optional(),
|
|
6945
|
+
top_k: z2.number().optional().default(12),
|
|
6946
|
+
include_memories: z2.boolean().optional().default(true),
|
|
6947
|
+
include_graph: z2.boolean().optional().default(true),
|
|
6948
|
+
session_id: z2.string().optional(),
|
|
6949
|
+
user_id: z2.string().optional(),
|
|
6950
|
+
include_parent_content: z2.boolean().optional().default(false),
|
|
6951
|
+
retrieval_profile: z2.enum(MCP_RETRIEVAL_PROFILE_VALUES).optional()
|
|
6605
6952
|
},
|
|
6606
6953
|
async ({ question, path, workspace_id, project, top_k, include_memories, include_graph, session_id, user_id, include_parent_content, retrieval_profile }) => {
|
|
6607
6954
|
try {
|
|
@@ -6629,12 +6976,12 @@ server.tool(
|
|
|
6629
6976
|
"context.claim_verify",
|
|
6630
6977
|
"Verify whether a claim is supported by retrieved context. Returns supported/partial/unsupported with evidence.",
|
|
6631
6978
|
{
|
|
6632
|
-
claim:
|
|
6633
|
-
path:
|
|
6634
|
-
workspace_id:
|
|
6635
|
-
project:
|
|
6636
|
-
context_ids:
|
|
6637
|
-
strict:
|
|
6979
|
+
claim: z2.string().describe("Claim to verify"),
|
|
6980
|
+
path: z2.string().optional().describe("Workspace path. Defaults to current working directory."),
|
|
6981
|
+
workspace_id: z2.string().optional(),
|
|
6982
|
+
project: z2.string().optional(),
|
|
6983
|
+
context_ids: z2.array(z2.string()).optional(),
|
|
6984
|
+
strict: z2.boolean().optional().default(true)
|
|
6638
6985
|
},
|
|
6639
6986
|
async ({ claim, path, workspace_id, project, context_ids, strict }) => {
|
|
6640
6987
|
try {
|
|
@@ -6704,20 +7051,20 @@ server.tool(
|
|
|
6704
7051
|
"context.evidence_answer",
|
|
6705
7052
|
"Answer a question only when evidence requirements are met. Fails closed with an abstain payload when not verifiable.",
|
|
6706
7053
|
{
|
|
6707
|
-
question:
|
|
6708
|
-
path:
|
|
6709
|
-
workspace_id:
|
|
6710
|
-
project:
|
|
6711
|
-
constraints:
|
|
6712
|
-
require_citations:
|
|
6713
|
-
min_evidence_items:
|
|
6714
|
-
min_confidence:
|
|
6715
|
-
max_staleness_hours:
|
|
7054
|
+
question: z2.string(),
|
|
7055
|
+
path: z2.string().optional().describe("Workspace path. Defaults to current working directory."),
|
|
7056
|
+
workspace_id: z2.string().optional(),
|
|
7057
|
+
project: z2.string().optional(),
|
|
7058
|
+
constraints: z2.object({
|
|
7059
|
+
require_citations: z2.boolean().optional().default(true),
|
|
7060
|
+
min_evidence_items: z2.number().optional().default(2),
|
|
7061
|
+
min_confidence: z2.number().optional().default(0.65),
|
|
7062
|
+
max_staleness_hours: z2.number().optional().default(168)
|
|
6716
7063
|
}).optional(),
|
|
6717
|
-
retrieval:
|
|
6718
|
-
top_k:
|
|
6719
|
-
include_symbols:
|
|
6720
|
-
include_recent_decisions:
|
|
7064
|
+
retrieval: z2.object({
|
|
7065
|
+
top_k: z2.number().optional().default(12),
|
|
7066
|
+
include_symbols: z2.boolean().optional().default(true),
|
|
7067
|
+
include_recent_decisions: z2.boolean().optional().default(true)
|
|
6721
7068
|
}).optional()
|
|
6722
7069
|
},
|
|
6723
7070
|
async ({ question, path, workspace_id, project, constraints, retrieval }) => {
|
|
@@ -6830,18 +7177,18 @@ server.tool(
|
|
|
6830
7177
|
"context.query",
|
|
6831
7178
|
"Use this when answering from project knowledge rather than general model memory. Retrieves packed context and auto-falls back between repo, local, and memory routes based on trust/readiness.",
|
|
6832
7179
|
{
|
|
6833
|
-
project:
|
|
6834
|
-
query:
|
|
6835
|
-
path:
|
|
6836
|
-
top_k:
|
|
6837
|
-
chunk_types:
|
|
6838
|
-
include_memories:
|
|
6839
|
-
include_graph:
|
|
6840
|
-
user_id:
|
|
6841
|
-
session_id:
|
|
6842
|
-
max_tokens:
|
|
6843
|
-
include_parent_content:
|
|
6844
|
-
retrieval_profile:
|
|
7180
|
+
project: z2.string().optional().describe("Project name or slug (optional if WHISPER_PROJECT is set)"),
|
|
7181
|
+
query: z2.string().describe("What are you looking for?"),
|
|
7182
|
+
path: z2.string().optional().describe("Workspace path. Defaults to current working directory."),
|
|
7183
|
+
top_k: z2.number().optional().default(10).describe("Number of results"),
|
|
7184
|
+
chunk_types: z2.array(z2.string()).optional().describe("Filter: code, function, class, documentation, api_spec, schema, config, text"),
|
|
7185
|
+
include_memories: z2.boolean().optional().describe("Include relevant memories. Omit to use automatic runtime defaults."),
|
|
7186
|
+
include_graph: z2.boolean().optional().default(false).describe("Include knowledge graph traversal"),
|
|
7187
|
+
user_id: z2.string().optional().describe("User ID for memory scoping"),
|
|
7188
|
+
session_id: z2.string().optional().describe("Session ID for memory scoping"),
|
|
7189
|
+
max_tokens: z2.number().optional().describe("Max tokens for packed context"),
|
|
7190
|
+
include_parent_content: z2.boolean().optional().default(false),
|
|
7191
|
+
retrieval_profile: z2.enum(MCP_RETRIEVAL_PROFILE_VALUES).optional()
|
|
6845
7192
|
},
|
|
6846
7193
|
async ({ project, query, path, top_k, chunk_types, include_memories, include_graph, user_id, session_id, max_tokens, include_parent_content, retrieval_profile }) => {
|
|
6847
7194
|
try {
|
|
@@ -6868,14 +7215,14 @@ server.tool(
|
|
|
6868
7215
|
"memory.add",
|
|
6869
7216
|
"Store a memory (fact, preference, decision) that persists across conversations. Memories can be scoped to a user, session, or agent.",
|
|
6870
7217
|
{
|
|
6871
|
-
project:
|
|
6872
|
-
content:
|
|
6873
|
-
memory_type:
|
|
6874
|
-
scope:
|
|
6875
|
-
user_id:
|
|
6876
|
-
session_id:
|
|
6877
|
-
agent_id:
|
|
6878
|
-
importance:
|
|
7218
|
+
project: z2.string().optional().describe("Project name or slug"),
|
|
7219
|
+
content: z2.string().describe("The memory content to store"),
|
|
7220
|
+
memory_type: z2.enum(["factual", "preference", "event", "relationship", "opinion", "goal", "instruction"]).optional().default("factual"),
|
|
7221
|
+
scope: z2.enum(["personal", "shared_project"]).optional().default("personal"),
|
|
7222
|
+
user_id: z2.string().optional().describe("User this memory belongs to"),
|
|
7223
|
+
session_id: z2.string().optional().describe("Session scope"),
|
|
7224
|
+
agent_id: z2.string().optional().describe("Agent scope"),
|
|
7225
|
+
importance: z2.number().optional().default(0.5).describe("Importance 0-1")
|
|
6879
7226
|
},
|
|
6880
7227
|
async ({ project, content, memory_type, scope, user_id, session_id, agent_id, importance }) => {
|
|
6881
7228
|
try {
|
|
@@ -6926,13 +7273,13 @@ server.tool(
|
|
|
6926
7273
|
"memory.search",
|
|
6927
7274
|
"Call this before answering questions about user history (preferences, prior decisions, past tasks, or 'what did we discuss/search'). Returns memory context you would not otherwise know.",
|
|
6928
7275
|
{
|
|
6929
|
-
project:
|
|
6930
|
-
query:
|
|
6931
|
-
scope:
|
|
6932
|
-
user_id:
|
|
6933
|
-
session_id:
|
|
6934
|
-
top_k:
|
|
6935
|
-
memory_types:
|
|
7276
|
+
project: z2.string().optional().describe("Project name or slug"),
|
|
7277
|
+
query: z2.string().describe("What to search for"),
|
|
7278
|
+
scope: z2.enum(["personal", "shared_project"]).optional().default("personal"),
|
|
7279
|
+
user_id: z2.string().optional().describe("Filter by user"),
|
|
7280
|
+
session_id: z2.string().optional().describe("Filter by session"),
|
|
7281
|
+
top_k: z2.number().optional().default(10).describe("Number of results"),
|
|
7282
|
+
memory_types: z2.array(z2.enum(["factual", "preference", "event", "relationship", "opinion", "goal", "instruction"])).optional()
|
|
6936
7283
|
},
|
|
6937
7284
|
async ({ project, query, scope, user_id, session_id, top_k, memory_types }) => {
|
|
6938
7285
|
try {
|
|
@@ -7006,7 +7353,7 @@ server.tool(
|
|
|
7006
7353
|
server.tool(
|
|
7007
7354
|
"context.list_sources",
|
|
7008
7355
|
"List all data sources connected to a project.",
|
|
7009
|
-
{ project:
|
|
7356
|
+
{ project: z2.string().optional().describe("Project name or slug") },
|
|
7010
7357
|
async ({ project }) => {
|
|
7011
7358
|
try {
|
|
7012
7359
|
const sourceData = await whisper.listSources(project || DEFAULT_PROJECT);
|
|
@@ -7022,38 +7369,38 @@ server.tool(
|
|
|
7022
7369
|
"context.add_source",
|
|
7023
7370
|
"Compatibility learning tool. Add a source to a project with normalized source contract and auto-index by default. Prefer `learn` for new integrations.",
|
|
7024
7371
|
{
|
|
7025
|
-
project:
|
|
7026
|
-
type:
|
|
7027
|
-
name:
|
|
7028
|
-
auto_index:
|
|
7029
|
-
metadata:
|
|
7030
|
-
ingestion_profile:
|
|
7031
|
-
strategy_override:
|
|
7032
|
-
profile_config:
|
|
7033
|
-
owner:
|
|
7034
|
-
repo:
|
|
7035
|
-
branch:
|
|
7036
|
-
paths:
|
|
7037
|
-
url:
|
|
7038
|
-
crawl_depth:
|
|
7039
|
-
include_paths:
|
|
7040
|
-
exclude_paths:
|
|
7041
|
-
file_path:
|
|
7042
|
-
path:
|
|
7043
|
-
glob:
|
|
7044
|
-
max_files:
|
|
7045
|
-
max_pages:
|
|
7046
|
-
extract_mode:
|
|
7047
|
-
workspace_id:
|
|
7048
|
-
channel_ids:
|
|
7049
|
-
since:
|
|
7050
|
-
token:
|
|
7051
|
-
auth_ref:
|
|
7052
|
-
platform:
|
|
7053
|
-
language:
|
|
7054
|
-
allow_stt_fallback:
|
|
7055
|
-
max_duration_minutes:
|
|
7056
|
-
max_chunks:
|
|
7372
|
+
project: z2.string().optional().describe("Project name or slug"),
|
|
7373
|
+
type: z2.enum(["github", "web", "playwright", "pdf", "local", "slack", "video"]).default("github"),
|
|
7374
|
+
name: z2.string().optional(),
|
|
7375
|
+
auto_index: z2.boolean().optional().default(true),
|
|
7376
|
+
metadata: z2.record(z2.string()).optional(),
|
|
7377
|
+
ingestion_profile: z2.enum(["auto", "repo", "web_docs", "pdf_layout", "video_transcript", "plain_text"]).optional(),
|
|
7378
|
+
strategy_override: z2.enum(["fixed", "recursive", "semantic", "hierarchical", "adaptive"]).optional(),
|
|
7379
|
+
profile_config: z2.record(z2.any()).optional(),
|
|
7380
|
+
owner: z2.string().optional(),
|
|
7381
|
+
repo: z2.string().optional(),
|
|
7382
|
+
branch: z2.string().optional(),
|
|
7383
|
+
paths: z2.array(z2.string()).optional(),
|
|
7384
|
+
url: z2.string().url().optional(),
|
|
7385
|
+
crawl_depth: z2.number().optional(),
|
|
7386
|
+
include_paths: z2.array(z2.string()).optional(),
|
|
7387
|
+
exclude_paths: z2.array(z2.string()).optional(),
|
|
7388
|
+
file_path: z2.string().optional(),
|
|
7389
|
+
path: z2.string().optional(),
|
|
7390
|
+
glob: z2.string().optional(),
|
|
7391
|
+
max_files: z2.number().optional(),
|
|
7392
|
+
max_pages: z2.number().optional(),
|
|
7393
|
+
extract_mode: z2.enum(["text", "structured", "markdown"]).optional(),
|
|
7394
|
+
workspace_id: z2.string().optional(),
|
|
7395
|
+
channel_ids: z2.array(z2.string()).optional(),
|
|
7396
|
+
since: z2.string().optional(),
|
|
7397
|
+
token: z2.string().optional(),
|
|
7398
|
+
auth_ref: z2.string().optional(),
|
|
7399
|
+
platform: z2.enum(["youtube", "loom", "generic"]).optional(),
|
|
7400
|
+
language: z2.string().optional(),
|
|
7401
|
+
allow_stt_fallback: z2.boolean().optional(),
|
|
7402
|
+
max_duration_minutes: z2.number().optional(),
|
|
7403
|
+
max_chunks: z2.number().optional()
|
|
7057
7404
|
},
|
|
7058
7405
|
async (input) => {
|
|
7059
7406
|
try {
|
|
@@ -7109,7 +7456,7 @@ server.tool(
|
|
|
7109
7456
|
"context.source_status",
|
|
7110
7457
|
"Get status and stage/progress details for a source sync job.",
|
|
7111
7458
|
{
|
|
7112
|
-
source_id:
|
|
7459
|
+
source_id: z2.string().describe("Source id")
|
|
7113
7460
|
},
|
|
7114
7461
|
async ({ source_id }) => {
|
|
7115
7462
|
try {
|
|
@@ -7124,12 +7471,12 @@ server.tool(
|
|
|
7124
7471
|
"context.add_text",
|
|
7125
7472
|
"Compatibility learning tool. Add text content to a project's knowledge base. Prefer `learn` for new integrations.",
|
|
7126
7473
|
{
|
|
7127
|
-
project:
|
|
7128
|
-
title:
|
|
7129
|
-
content:
|
|
7130
|
-
ingestion_profile:
|
|
7131
|
-
strategy_override:
|
|
7132
|
-
profile_config:
|
|
7474
|
+
project: z2.string().optional().describe("Project name or slug"),
|
|
7475
|
+
title: z2.string().describe("Title for this content"),
|
|
7476
|
+
content: z2.string().describe("The text content to index"),
|
|
7477
|
+
ingestion_profile: z2.enum(["auto", "repo", "web_docs", "pdf_layout", "video_transcript", "plain_text"]).optional(),
|
|
7478
|
+
strategy_override: z2.enum(["fixed", "recursive", "semantic", "hierarchical", "adaptive"]).optional(),
|
|
7479
|
+
profile_config: z2.record(z2.any()).optional()
|
|
7133
7480
|
},
|
|
7134
7481
|
async ({ project, title, content, ingestion_profile, strategy_override, profile_config }) => {
|
|
7135
7482
|
try {
|
|
@@ -7157,18 +7504,18 @@ server.tool(
|
|
|
7157
7504
|
"context.add_document",
|
|
7158
7505
|
"Compatibility learning tool. Ingest a document into project knowledge. Supports plain text and video URLs. Prefer `learn` for new integrations.",
|
|
7159
7506
|
{
|
|
7160
|
-
project:
|
|
7161
|
-
source_type:
|
|
7162
|
-
title:
|
|
7163
|
-
content:
|
|
7164
|
-
url:
|
|
7165
|
-
auto_sync:
|
|
7166
|
-
tags:
|
|
7167
|
-
platform:
|
|
7168
|
-
language:
|
|
7169
|
-
ingestion_profile:
|
|
7170
|
-
strategy_override:
|
|
7171
|
-
profile_config:
|
|
7507
|
+
project: z2.string().optional().describe("Project name or slug"),
|
|
7508
|
+
source_type: z2.enum(["text", "video"]).default("text"),
|
|
7509
|
+
title: z2.string().optional().describe("Title for text documents"),
|
|
7510
|
+
content: z2.string().optional().describe("Text document content"),
|
|
7511
|
+
url: z2.string().url().optional().describe("Video URL when source_type=video"),
|
|
7512
|
+
auto_sync: z2.boolean().optional().default(true),
|
|
7513
|
+
tags: z2.array(z2.string()).optional(),
|
|
7514
|
+
platform: z2.enum(["youtube", "loom", "generic"]).optional(),
|
|
7515
|
+
language: z2.string().optional(),
|
|
7516
|
+
ingestion_profile: z2.enum(["auto", "repo", "web_docs", "pdf_layout", "video_transcript", "plain_text"]).optional(),
|
|
7517
|
+
strategy_override: z2.enum(["fixed", "recursive", "semantic", "hierarchical", "adaptive"]).optional(),
|
|
7518
|
+
profile_config: z2.record(z2.any()).optional()
|
|
7172
7519
|
},
|
|
7173
7520
|
async ({ project, source_type, title, content, url, auto_sync, tags, platform, language, ingestion_profile, strategy_override, profile_config }) => {
|
|
7174
7521
|
try {
|
|
@@ -7223,15 +7570,15 @@ server.tool(
|
|
|
7223
7570
|
"memory.search_sota",
|
|
7224
7571
|
"SOTA memory search with temporal reasoning and relation graphs. Searches memories with support for temporal queries ('what did I say yesterday?'), type filtering, and knowledge graph traversal.",
|
|
7225
7572
|
{
|
|
7226
|
-
project:
|
|
7227
|
-
query:
|
|
7228
|
-
scope:
|
|
7229
|
-
user_id:
|
|
7230
|
-
session_id:
|
|
7231
|
-
question_date:
|
|
7232
|
-
memory_types:
|
|
7233
|
-
top_k:
|
|
7234
|
-
include_relations:
|
|
7573
|
+
project: z2.string().optional().describe("Project name or slug"),
|
|
7574
|
+
query: z2.string().describe("Search query (supports temporal: 'yesterday', 'last week')"),
|
|
7575
|
+
scope: z2.enum(["personal", "shared_project"]).optional().default("personal"),
|
|
7576
|
+
user_id: z2.string().optional().describe("Filter by user"),
|
|
7577
|
+
session_id: z2.string().optional().describe("Filter by session"),
|
|
7578
|
+
question_date: z2.string().optional().describe("ISO datetime for temporal grounding"),
|
|
7579
|
+
memory_types: z2.array(z2.enum(["factual", "preference", "event", "relationship", "opinion", "goal", "instruction"])).optional(),
|
|
7580
|
+
top_k: z2.number().optional().default(10),
|
|
7581
|
+
include_relations: z2.boolean().optional().default(true).describe("Include related memories via knowledge graph")
|
|
7235
7582
|
},
|
|
7236
7583
|
async ({ project, query, scope, user_id, session_id, question_date, memory_types, top_k, include_relations }) => {
|
|
7237
7584
|
try {
|
|
@@ -7275,13 +7622,13 @@ server.tool(
|
|
|
7275
7622
|
"memory.ingest_conversation",
|
|
7276
7623
|
"Compatibility learning tool. Extract memories from a conversation session. Prefer `learn` for new integrations.",
|
|
7277
7624
|
{
|
|
7278
|
-
project:
|
|
7279
|
-
session_id:
|
|
7280
|
-
user_id:
|
|
7281
|
-
messages:
|
|
7282
|
-
role:
|
|
7283
|
-
content:
|
|
7284
|
-
timestamp:
|
|
7625
|
+
project: z2.string().optional().describe("Project name or slug"),
|
|
7626
|
+
session_id: z2.string().describe("Session identifier"),
|
|
7627
|
+
user_id: z2.string().optional().describe("User identifier"),
|
|
7628
|
+
messages: z2.array(z2.object({
|
|
7629
|
+
role: z2.string(),
|
|
7630
|
+
content: z2.string(),
|
|
7631
|
+
timestamp: z2.string()
|
|
7285
7632
|
})).describe("Array of conversation messages with timestamps")
|
|
7286
7633
|
},
|
|
7287
7634
|
async ({ project, session_id, user_id, messages }) => {
|
|
@@ -7329,11 +7676,11 @@ server.tool(
|
|
|
7329
7676
|
"research.oracle",
|
|
7330
7677
|
"Oracle Research Mode - Tree-guided document navigation with multi-step reasoning. More precise than standard search, especially for bleeding-edge features.",
|
|
7331
7678
|
{
|
|
7332
|
-
project:
|
|
7333
|
-
query:
|
|
7334
|
-
mode:
|
|
7335
|
-
max_results:
|
|
7336
|
-
max_steps:
|
|
7679
|
+
project: z2.string().optional().describe("Project name or slug"),
|
|
7680
|
+
query: z2.string().describe("Research question"),
|
|
7681
|
+
mode: z2.enum(["search", "research"]).optional().default("search").describe("'search' for tree-guided, 'research' for multi-step reasoning"),
|
|
7682
|
+
max_results: z2.number().optional().default(5),
|
|
7683
|
+
max_steps: z2.number().optional().default(5).describe("For research mode: max reasoning steps")
|
|
7337
7684
|
},
|
|
7338
7685
|
async ({ project, query, mode, max_results, max_steps }) => {
|
|
7339
7686
|
try {
|
|
@@ -7377,13 +7724,13 @@ server.tool(
|
|
|
7377
7724
|
"index.autosubscribe_deps",
|
|
7378
7725
|
"Automatically index a project's dependencies (package.json, requirements.txt, etc.). Resolves docs URLs and indexes documentation.",
|
|
7379
7726
|
{
|
|
7380
|
-
project:
|
|
7381
|
-
source_type:
|
|
7382
|
-
github_owner:
|
|
7383
|
-
github_repo:
|
|
7384
|
-
local_path:
|
|
7385
|
-
dependency_file:
|
|
7386
|
-
index_limit:
|
|
7727
|
+
project: z2.string().optional().describe("Project name or slug"),
|
|
7728
|
+
source_type: z2.enum(["github", "local"]).describe("Source location"),
|
|
7729
|
+
github_owner: z2.string().optional().describe("For GitHub: owner/org name"),
|
|
7730
|
+
github_repo: z2.string().optional().describe("For GitHub: repository name"),
|
|
7731
|
+
local_path: z2.string().optional().describe("For local: path to dependency file"),
|
|
7732
|
+
dependency_file: z2.enum(["package.json", "requirements.txt", "Cargo.toml", "go.mod", "Gemfile"]).optional(),
|
|
7733
|
+
index_limit: z2.number().optional().default(20).describe("Max dependencies to index")
|
|
7387
7734
|
},
|
|
7388
7735
|
async ({ project, source_type, github_owner, github_repo, local_path, dependency_file, index_limit }) => {
|
|
7389
7736
|
try {
|
|
@@ -7410,10 +7757,10 @@ server.tool(
|
|
|
7410
7757
|
"context.share",
|
|
7411
7758
|
"Create a shareable snapshot of a conversation with memories. Returns a URL that can be shared or resumed later.",
|
|
7412
7759
|
{
|
|
7413
|
-
project:
|
|
7414
|
-
session_id:
|
|
7415
|
-
title:
|
|
7416
|
-
expiry_days:
|
|
7760
|
+
project: z2.string().optional().describe("Project name or slug"),
|
|
7761
|
+
session_id: z2.string().describe("Session to share"),
|
|
7762
|
+
title: z2.string().optional().describe("Title for the shared context"),
|
|
7763
|
+
expiry_days: z2.number().optional().default(30).describe("Days until expiry")
|
|
7417
7764
|
},
|
|
7418
7765
|
async ({ project, session_id, title, expiry_days }) => {
|
|
7419
7766
|
try {
|
|
@@ -7448,9 +7795,9 @@ server.tool(
|
|
|
7448
7795
|
"memory.consolidate",
|
|
7449
7796
|
"Find and merge duplicate memories to reduce bloat. Uses vector similarity + LLM merging.",
|
|
7450
7797
|
{
|
|
7451
|
-
project:
|
|
7452
|
-
similarity_threshold:
|
|
7453
|
-
dry_run:
|
|
7798
|
+
project: z2.string().optional().describe("Project name or slug"),
|
|
7799
|
+
similarity_threshold: z2.number().optional().default(0.95).describe("Similarity threshold (0-1)"),
|
|
7800
|
+
dry_run: z2.boolean().optional().default(false).describe("Preview without merging")
|
|
7454
7801
|
},
|
|
7455
7802
|
async ({ project, similarity_threshold, dry_run }) => {
|
|
7456
7803
|
try {
|
|
@@ -7491,8 +7838,8 @@ server.tool(
|
|
|
7491
7838
|
"context.cost_summary",
|
|
7492
7839
|
"Get cost tracking summary showing spending by model and task. Includes savings vs always-Opus.",
|
|
7493
7840
|
{
|
|
7494
|
-
project:
|
|
7495
|
-
days:
|
|
7841
|
+
project: z2.string().optional().describe("Project name or slug (optional for org-wide)"),
|
|
7842
|
+
days: z2.number().optional().default(30).describe("Time period in days")
|
|
7496
7843
|
},
|
|
7497
7844
|
async ({ project, days }) => {
|
|
7498
7845
|
try {
|
|
@@ -7534,17 +7881,17 @@ server.tool(
|
|
|
7534
7881
|
"memory.forget",
|
|
7535
7882
|
"Delete or invalidate memories with immutable audit logging.",
|
|
7536
7883
|
{
|
|
7537
|
-
workspace_id:
|
|
7538
|
-
project:
|
|
7539
|
-
scope:
|
|
7540
|
-
user_id:
|
|
7541
|
-
session_id:
|
|
7542
|
-
target:
|
|
7543
|
-
memory_id:
|
|
7544
|
-
query:
|
|
7884
|
+
workspace_id: z2.string().optional(),
|
|
7885
|
+
project: z2.string().optional(),
|
|
7886
|
+
scope: z2.enum(["personal", "shared_project"]).optional().default("personal"),
|
|
7887
|
+
user_id: z2.string().optional(),
|
|
7888
|
+
session_id: z2.string().optional(),
|
|
7889
|
+
target: z2.object({
|
|
7890
|
+
memory_id: z2.string().optional(),
|
|
7891
|
+
query: z2.string().optional()
|
|
7545
7892
|
}),
|
|
7546
|
-
mode:
|
|
7547
|
-
reason:
|
|
7893
|
+
mode: z2.enum(["delete", "invalidate"]).optional().default("invalidate"),
|
|
7894
|
+
reason: z2.string().optional()
|
|
7548
7895
|
},
|
|
7549
7896
|
async ({ workspace_id, project, scope, user_id, session_id, target, mode, reason }) => {
|
|
7550
7897
|
try {
|
|
@@ -7712,8 +8059,8 @@ server.tool(
|
|
|
7712
8059
|
"context.export_bundle",
|
|
7713
8060
|
"Export project/workspace memory and context to a portable bundle with checksum.",
|
|
7714
8061
|
{
|
|
7715
|
-
workspace_id:
|
|
7716
|
-
project:
|
|
8062
|
+
workspace_id: z2.string().optional(),
|
|
8063
|
+
project: z2.string().optional()
|
|
7717
8064
|
},
|
|
7718
8065
|
async ({ workspace_id, project }) => {
|
|
7719
8066
|
try {
|
|
@@ -7763,26 +8110,26 @@ server.tool(
|
|
|
7763
8110
|
"context.import_bundle",
|
|
7764
8111
|
"Import a portable context bundle with merge/replace modes and checksum verification.",
|
|
7765
8112
|
{
|
|
7766
|
-
workspace_id:
|
|
7767
|
-
bundle:
|
|
7768
|
-
bundle_version:
|
|
7769
|
-
workspace_id:
|
|
7770
|
-
project:
|
|
7771
|
-
exported_at:
|
|
7772
|
-
contents:
|
|
7773
|
-
memories:
|
|
7774
|
-
entities:
|
|
7775
|
-
decisions:
|
|
7776
|
-
failures:
|
|
7777
|
-
annotations:
|
|
7778
|
-
session_summaries:
|
|
7779
|
-
documents:
|
|
7780
|
-
index_metadata:
|
|
8113
|
+
workspace_id: z2.string().optional(),
|
|
8114
|
+
bundle: z2.object({
|
|
8115
|
+
bundle_version: z2.string(),
|
|
8116
|
+
workspace_id: z2.string(),
|
|
8117
|
+
project: z2.string().optional(),
|
|
8118
|
+
exported_at: z2.string(),
|
|
8119
|
+
contents: z2.object({
|
|
8120
|
+
memories: z2.array(z2.any()).default([]),
|
|
8121
|
+
entities: z2.array(z2.any()).default([]),
|
|
8122
|
+
decisions: z2.array(z2.any()).default([]),
|
|
8123
|
+
failures: z2.array(z2.any()).default([]),
|
|
8124
|
+
annotations: z2.array(z2.any()).default([]),
|
|
8125
|
+
session_summaries: z2.array(z2.any()).default([]),
|
|
8126
|
+
documents: z2.array(z2.any()).default([]),
|
|
8127
|
+
index_metadata: z2.record(z2.any()).default({})
|
|
7781
8128
|
}),
|
|
7782
|
-
checksum:
|
|
8129
|
+
checksum: z2.string()
|
|
7783
8130
|
}),
|
|
7784
|
-
mode:
|
|
7785
|
-
dedupe_strategy:
|
|
8131
|
+
mode: z2.enum(["merge", "replace"]).optional().default("merge"),
|
|
8132
|
+
dedupe_strategy: z2.enum(["semantic", "id", "none"]).optional().default("semantic")
|
|
7786
8133
|
},
|
|
7787
8134
|
async ({ workspace_id, bundle, mode, dedupe_strategy }) => {
|
|
7788
8135
|
try {
|
|
@@ -7926,13 +8273,13 @@ server.tool(
|
|
|
7926
8273
|
"context.diff",
|
|
7927
8274
|
"Return deterministic context changes from an explicit anchor (session_id, timestamp, or commit).",
|
|
7928
8275
|
{
|
|
7929
|
-
workspace_id:
|
|
7930
|
-
anchor:
|
|
7931
|
-
type:
|
|
7932
|
-
value:
|
|
8276
|
+
workspace_id: z2.string().optional(),
|
|
8277
|
+
anchor: z2.object({
|
|
8278
|
+
type: z2.enum(["session_id", "timestamp", "commit"]),
|
|
8279
|
+
value: z2.string()
|
|
7933
8280
|
}).optional(),
|
|
7934
|
-
scope:
|
|
7935
|
-
include:
|
|
8281
|
+
scope: z2.object({
|
|
8282
|
+
include: z2.array(z2.enum(["decisions", "failures", "entities", "documents", "summaries"])).optional().default(["decisions", "failures", "entities", "documents", "summaries"])
|
|
7936
8283
|
}).optional()
|
|
7937
8284
|
},
|
|
7938
8285
|
async ({ workspace_id, anchor, scope }) => {
|
|
@@ -8043,12 +8390,12 @@ server.tool(
|
|
|
8043
8390
|
"code.search_semantic",
|
|
8044
8391
|
"Semantically search a local codebase without pre-indexing. Unlike grep/ripgrep, this understands meaning \u2014 so 'find authentication logic' finds auth code even if it doesn't literally say 'auth'. Uses vector embeddings via the Whisper API. Perfect for exploring unfamiliar codebases.",
|
|
8045
8392
|
{
|
|
8046
|
-
query:
|
|
8047
|
-
path:
|
|
8048
|
-
file_types:
|
|
8049
|
-
top_k:
|
|
8050
|
-
threshold:
|
|
8051
|
-
max_files:
|
|
8393
|
+
query: z2.string().describe("Natural language description of what you're looking for. E.g. 'authentication and session management', 'database connection pooling', 'error handling middleware'"),
|
|
8394
|
+
path: z2.string().optional().describe("Absolute path to the codebase root. Defaults to current working directory."),
|
|
8395
|
+
file_types: z2.array(z2.string()).optional().describe("Limit to specific extensions e.g. ['ts', 'py']. Defaults to all common code files."),
|
|
8396
|
+
top_k: z2.number().optional().default(10).describe("Number of most relevant files to return"),
|
|
8397
|
+
threshold: z2.number().optional().default(0.2).describe("Minimum similarity score 0-1. Lower = more results but less precise."),
|
|
8398
|
+
max_files: z2.number().optional().default(150).describe("Max files to scan. For large codebases, narrow with file_types instead of raising this.")
|
|
8052
8399
|
},
|
|
8053
8400
|
async ({ query, path: searchPath, file_types, top_k, threshold, max_files }) => {
|
|
8054
8401
|
try {
|
|
@@ -8123,13 +8470,13 @@ server.tool(
|
|
|
8123
8470
|
"code.search_text",
|
|
8124
8471
|
"Search files and content in a local directory without requiring pre-indexing. Uses ripgrep when available, falls back to Node.js. Great for finding files, functions, patterns, or any text across a codebase instantly.",
|
|
8125
8472
|
{
|
|
8126
|
-
query:
|
|
8127
|
-
path:
|
|
8128
|
-
mode:
|
|
8129
|
-
file_types:
|
|
8130
|
-
max_results:
|
|
8131
|
-
context_lines:
|
|
8132
|
-
case_sensitive:
|
|
8473
|
+
query: z2.string().describe("What to search for \u2014 natural language keyword, function name, pattern, etc."),
|
|
8474
|
+
path: z2.string().optional().describe("Absolute path to search in. Defaults to current working directory."),
|
|
8475
|
+
mode: z2.enum(["content", "filename", "both"]).optional().default("both").describe("Search file contents, filenames, or both"),
|
|
8476
|
+
file_types: z2.array(z2.string()).optional().describe("Limit to these file extensions e.g. ['ts', 'js', 'py', 'go']"),
|
|
8477
|
+
max_results: z2.number().optional().default(20).describe("Max number of matching files to return"),
|
|
8478
|
+
context_lines: z2.number().optional().default(2).describe("Lines of context around each match"),
|
|
8479
|
+
case_sensitive: z2.boolean().optional().default(false)
|
|
8133
8480
|
},
|
|
8134
8481
|
async ({ query, path: searchPath, mode, file_types, max_results, context_lines, case_sensitive }) => {
|
|
8135
8482
|
const rootPath = searchPath || process.cwd();
|
|
@@ -8262,13 +8609,13 @@ server.tool(
|
|
|
8262
8609
|
"code.semantic_documents",
|
|
8263
8610
|
"Semantic vector search over provided documents. Uses embeddings to find semantically similar content. Perfect for AI code search, finding similar functions, or searching by meaning rather than keywords.",
|
|
8264
8611
|
{
|
|
8265
|
-
query:
|
|
8266
|
-
documents:
|
|
8267
|
-
id:
|
|
8268
|
-
content:
|
|
8612
|
+
query: z2.string().describe("What to search for semantically (e.g. 'authentication logic', 'database connection')"),
|
|
8613
|
+
documents: z2.array(z2.object({
|
|
8614
|
+
id: z2.string().describe("Unique identifier (file path, URL, or any ID)"),
|
|
8615
|
+
content: z2.string().describe("The text content to search in")
|
|
8269
8616
|
})).describe("Documents to search over"),
|
|
8270
|
-
top_k:
|
|
8271
|
-
threshold:
|
|
8617
|
+
top_k: z2.number().optional().default(5).describe("Number of results to return"),
|
|
8618
|
+
threshold: z2.number().optional().default(0.3).describe("Minimum similarity score 0-1")
|
|
8272
8619
|
},
|
|
8273
8620
|
async ({ query, documents, top_k, threshold }) => {
|
|
8274
8621
|
try {
|
|
@@ -8306,14 +8653,14 @@ server.tool(
|
|
|
8306
8653
|
"search",
|
|
8307
8654
|
"Primary retrieval alias. Call this whenever the user asks to find or recall context: use `query` for semantic retrieval, `id` for exact memory fetch, or both for hybrid recall.",
|
|
8308
8655
|
{
|
|
8309
|
-
project:
|
|
8310
|
-
query:
|
|
8311
|
-
id:
|
|
8312
|
-
top_k:
|
|
8313
|
-
include_memories:
|
|
8314
|
-
include_graph:
|
|
8315
|
-
user_id:
|
|
8316
|
-
session_id:
|
|
8656
|
+
project: z2.string().optional().describe("Project name or slug"),
|
|
8657
|
+
query: z2.string().optional().describe("Semantic retrieval query"),
|
|
8658
|
+
id: z2.string().optional().describe("Exact memory id to fetch"),
|
|
8659
|
+
top_k: z2.number().optional().default(10),
|
|
8660
|
+
include_memories: z2.boolean().optional().default(false),
|
|
8661
|
+
include_graph: z2.boolean().optional().default(false),
|
|
8662
|
+
user_id: z2.string().optional(),
|
|
8663
|
+
session_id: z2.string().optional()
|
|
8317
8664
|
},
|
|
8318
8665
|
async ({ project, query, id, top_k, include_memories, include_graph, user_id, session_id }) => {
|
|
8319
8666
|
try {
|
|
@@ -8377,12 +8724,12 @@ server.tool(
|
|
|
8377
8724
|
"search_code",
|
|
8378
8725
|
"Semantically search a local codebase by meaning. Use this for questions like 'where is auth handled?' or 'find retry logic'.",
|
|
8379
8726
|
{
|
|
8380
|
-
query:
|
|
8381
|
-
path:
|
|
8382
|
-
file_types:
|
|
8383
|
-
top_k:
|
|
8384
|
-
threshold:
|
|
8385
|
-
max_files:
|
|
8727
|
+
query: z2.string().describe("Natural-language code search query"),
|
|
8728
|
+
path: z2.string().optional().describe("Codebase root. Defaults to current working directory."),
|
|
8729
|
+
file_types: z2.array(z2.string()).optional(),
|
|
8730
|
+
top_k: z2.number().optional().default(10),
|
|
8731
|
+
threshold: z2.number().optional().default(0.2),
|
|
8732
|
+
max_files: z2.number().optional().default(150)
|
|
8386
8733
|
},
|
|
8387
8734
|
async ({ query, path, file_types, top_k, threshold, max_files }) => {
|
|
8388
8735
|
try {
|
|
@@ -8403,11 +8750,11 @@ server.tool(
|
|
|
8403
8750
|
"grep",
|
|
8404
8751
|
"Regex or text search across a local codebase. Use this when you know the symbol, string, or pattern you want.",
|
|
8405
8752
|
{
|
|
8406
|
-
query:
|
|
8407
|
-
path:
|
|
8408
|
-
file_types:
|
|
8409
|
-
max_results:
|
|
8410
|
-
case_sensitive:
|
|
8753
|
+
query: z2.string().describe("Text or regex-like pattern to search for"),
|
|
8754
|
+
path: z2.string().optional().describe("Search root. Defaults to current working directory."),
|
|
8755
|
+
file_types: z2.array(z2.string()).optional(),
|
|
8756
|
+
max_results: z2.number().optional().default(20),
|
|
8757
|
+
case_sensitive: z2.boolean().optional().default(false)
|
|
8411
8758
|
},
|
|
8412
8759
|
async ({ query, path, file_types, max_results, case_sensitive }) => {
|
|
8413
8760
|
const rootPath = path || process.cwd();
|
|
@@ -8455,9 +8802,9 @@ server.tool(
|
|
|
8455
8802
|
"read",
|
|
8456
8803
|
"Read a local file with optional line ranges. Use this after search or grep when you want the actual source.",
|
|
8457
8804
|
{
|
|
8458
|
-
path:
|
|
8459
|
-
start_line:
|
|
8460
|
-
end_line:
|
|
8805
|
+
path: z2.string().describe("Absolute or relative path to the file to read."),
|
|
8806
|
+
start_line: z2.number().optional().default(1),
|
|
8807
|
+
end_line: z2.number().optional().default(200)
|
|
8461
8808
|
},
|
|
8462
8809
|
async ({ path, start_line, end_line }) => {
|
|
8463
8810
|
try {
|
|
@@ -8482,9 +8829,9 @@ server.tool(
|
|
|
8482
8829
|
"explore",
|
|
8483
8830
|
"Browse a repository tree or directory structure. Use this to orient yourself before reading files.",
|
|
8484
8831
|
{
|
|
8485
|
-
path:
|
|
8486
|
-
max_depth:
|
|
8487
|
-
max_entries:
|
|
8832
|
+
path: z2.string().optional().describe("Root directory to inspect. Defaults to current working directory."),
|
|
8833
|
+
max_depth: z2.number().optional().default(3),
|
|
8834
|
+
max_entries: z2.number().optional().default(200)
|
|
8488
8835
|
},
|
|
8489
8836
|
async ({ path, max_depth, max_entries }) => {
|
|
8490
8837
|
try {
|
|
@@ -8513,11 +8860,11 @@ server.tool(
|
|
|
8513
8860
|
"research",
|
|
8514
8861
|
"Run deeper research over indexed sources. Use this when search is not enough and you want synthesis or multi-step investigation.",
|
|
8515
8862
|
{
|
|
8516
|
-
project:
|
|
8517
|
-
query:
|
|
8518
|
-
mode:
|
|
8519
|
-
max_results:
|
|
8520
|
-
max_steps:
|
|
8863
|
+
project: z2.string().optional(),
|
|
8864
|
+
query: z2.string().describe("Research question"),
|
|
8865
|
+
mode: z2.enum(["search", "research"]).optional().default("research"),
|
|
8866
|
+
max_results: z2.number().optional().default(5),
|
|
8867
|
+
max_steps: z2.number().optional().default(5)
|
|
8521
8868
|
},
|
|
8522
8869
|
async ({ project, query, mode, max_results, max_steps }) => {
|
|
8523
8870
|
try {
|
|
@@ -8539,27 +8886,27 @@ server.tool(
|
|
|
8539
8886
|
"index",
|
|
8540
8887
|
"Administrative indexing tool. Call this when retrieval is stale/missing or the user asks to connect new data. Use action='source' to add GitHub/web/pdf/local/slack/video, action='workspace' to refresh local workspace metadata.",
|
|
8541
8888
|
{
|
|
8542
|
-
action:
|
|
8543
|
-
project:
|
|
8544
|
-
type:
|
|
8545
|
-
name:
|
|
8546
|
-
owner:
|
|
8547
|
-
repo:
|
|
8548
|
-
branch:
|
|
8549
|
-
url:
|
|
8550
|
-
file_path:
|
|
8551
|
-
path:
|
|
8552
|
-
glob:
|
|
8553
|
-
max_files:
|
|
8554
|
-
channel_ids:
|
|
8555
|
-
token:
|
|
8556
|
-
workspace_id:
|
|
8557
|
-
mode:
|
|
8558
|
-
platform:
|
|
8559
|
-
language:
|
|
8560
|
-
allow_stt_fallback:
|
|
8561
|
-
max_duration_minutes:
|
|
8562
|
-
max_chunks:
|
|
8889
|
+
action: z2.enum(["source", "workspace"]).default("source"),
|
|
8890
|
+
project: z2.string().optional(),
|
|
8891
|
+
type: z2.enum(["github", "web", "playwright", "pdf", "local", "slack", "video"]).optional(),
|
|
8892
|
+
name: z2.string().optional(),
|
|
8893
|
+
owner: z2.string().optional(),
|
|
8894
|
+
repo: z2.string().optional(),
|
|
8895
|
+
branch: z2.string().optional(),
|
|
8896
|
+
url: z2.string().optional(),
|
|
8897
|
+
file_path: z2.string().optional(),
|
|
8898
|
+
path: z2.string().optional(),
|
|
8899
|
+
glob: z2.string().optional(),
|
|
8900
|
+
max_files: z2.number().optional(),
|
|
8901
|
+
channel_ids: z2.array(z2.string()).optional(),
|
|
8902
|
+
token: z2.string().optional(),
|
|
8903
|
+
workspace_id: z2.string().optional(),
|
|
8904
|
+
mode: z2.enum(["full", "incremental"]).optional().default("incremental"),
|
|
8905
|
+
platform: z2.enum(["youtube", "loom", "generic"]).optional(),
|
|
8906
|
+
language: z2.string().optional(),
|
|
8907
|
+
allow_stt_fallback: z2.boolean().optional(),
|
|
8908
|
+
max_duration_minutes: z2.number().optional(),
|
|
8909
|
+
max_chunks: z2.number().optional()
|
|
8563
8910
|
},
|
|
8564
8911
|
async (input) => {
|
|
8565
8912
|
try {
|
|
@@ -8620,14 +8967,14 @@ server.tool(
|
|
|
8620
8967
|
"remember",
|
|
8621
8968
|
"Call this whenever the user states a durable preference, decision, instruction, or personal/project fact that should persist across sessions. Save proactively without waiting for an explicit 'remember this'.",
|
|
8622
8969
|
{
|
|
8623
|
-
project:
|
|
8624
|
-
content:
|
|
8625
|
-
memory_type:
|
|
8626
|
-
scope:
|
|
8627
|
-
user_id:
|
|
8628
|
-
session_id:
|
|
8629
|
-
agent_id:
|
|
8630
|
-
importance:
|
|
8970
|
+
project: z2.string().optional(),
|
|
8971
|
+
content: z2.string().describe("Memory content"),
|
|
8972
|
+
memory_type: z2.enum(["factual", "preference", "event", "relationship", "opinion", "goal", "instruction"]).optional().default("factual"),
|
|
8973
|
+
scope: z2.enum(["personal", "shared_project"]).optional().default("personal"),
|
|
8974
|
+
user_id: z2.string().optional(),
|
|
8975
|
+
session_id: z2.string().optional(),
|
|
8976
|
+
agent_id: z2.string().optional(),
|
|
8977
|
+
importance: z2.number().optional().default(0.5)
|
|
8631
8978
|
},
|
|
8632
8979
|
async ({ project, content, memory_type, scope, user_id, session_id, agent_id, importance }) => {
|
|
8633
8980
|
try {
|
|
@@ -8677,17 +9024,17 @@ server.tool(
|
|
|
8677
9024
|
"record",
|
|
8678
9025
|
"Record what just happened in a session or conversation. Use this for temporal capture, not durable preference storage.",
|
|
8679
9026
|
{
|
|
8680
|
-
project:
|
|
8681
|
-
session_id:
|
|
8682
|
-
user_id:
|
|
8683
|
-
messages:
|
|
8684
|
-
role:
|
|
8685
|
-
content:
|
|
8686
|
-
timestamp:
|
|
9027
|
+
project: z2.string().optional(),
|
|
9028
|
+
session_id: z2.string().describe("Session to record into"),
|
|
9029
|
+
user_id: z2.string().optional(),
|
|
9030
|
+
messages: z2.array(z2.object({
|
|
9031
|
+
role: z2.string().optional(),
|
|
9032
|
+
content: z2.string(),
|
|
9033
|
+
timestamp: z2.string().optional()
|
|
8687
9034
|
})).optional(),
|
|
8688
|
-
role:
|
|
8689
|
-
content:
|
|
8690
|
-
timestamp:
|
|
9035
|
+
role: z2.string().optional(),
|
|
9036
|
+
content: z2.string().optional(),
|
|
9037
|
+
timestamp: z2.string().optional()
|
|
8691
9038
|
},
|
|
8692
9039
|
async ({ project, session_id, user_id, messages, role, content, timestamp }) => {
|
|
8693
9040
|
try {
|
|
@@ -8739,60 +9086,62 @@ server.tool(
|
|
|
8739
9086
|
"learn",
|
|
8740
9087
|
"Unified ingestion entrypoint. Call this when the user asks to import knowledge: mode='conversation' for chat logs, mode='text' for raw text, mode='source' for external sources to index. Prefer this over legacy compatibility tools.",
|
|
8741
9088
|
{
|
|
8742
|
-
mode:
|
|
8743
|
-
project:
|
|
8744
|
-
user_id:
|
|
8745
|
-
session_id:
|
|
8746
|
-
messages:
|
|
8747
|
-
role:
|
|
8748
|
-
content:
|
|
8749
|
-
timestamp:
|
|
9089
|
+
mode: z2.enum(["conversation", "text", "source"]).describe("What kind of learning to perform"),
|
|
9090
|
+
project: z2.string().optional(),
|
|
9091
|
+
user_id: z2.string().optional().describe("Optional end-user identity for conversation learning"),
|
|
9092
|
+
session_id: z2.string().optional().describe("Session identifier for conversation learning"),
|
|
9093
|
+
messages: z2.array(z2.object({
|
|
9094
|
+
role: z2.string(),
|
|
9095
|
+
content: z2.string(),
|
|
9096
|
+
timestamp: z2.string().optional()
|
|
8750
9097
|
})).optional().describe("Conversation messages to learn from"),
|
|
8751
|
-
title:
|
|
8752
|
-
content:
|
|
8753
|
-
metadata:
|
|
8754
|
-
tags:
|
|
8755
|
-
namespace:
|
|
8756
|
-
type:
|
|
8757
|
-
url:
|
|
8758
|
-
owner:
|
|
8759
|
-
repo:
|
|
8760
|
-
branch:
|
|
8761
|
-
paths:
|
|
8762
|
-
path:
|
|
8763
|
-
file_path:
|
|
8764
|
-
name:
|
|
8765
|
-
channel_ids:
|
|
8766
|
-
since:
|
|
8767
|
-
token:
|
|
8768
|
-
auth_ref:
|
|
8769
|
-
platform:
|
|
8770
|
-
language:
|
|
8771
|
-
options:
|
|
8772
|
-
async:
|
|
8773
|
-
auto_index:
|
|
8774
|
-
ingestion_profile:
|
|
8775
|
-
strategy_override:
|
|
8776
|
-
profile_config:
|
|
8777
|
-
crawl_depth:
|
|
8778
|
-
include_paths:
|
|
8779
|
-
exclude_paths:
|
|
8780
|
-
glob:
|
|
8781
|
-
max_files:
|
|
8782
|
-
max_pages:
|
|
8783
|
-
extract_mode:
|
|
8784
|
-
workspace_id:
|
|
8785
|
-
allow_stt_fallback:
|
|
8786
|
-
max_duration_minutes:
|
|
8787
|
-
max_chunks:
|
|
9098
|
+
title: z2.string().optional().describe("Title for text learning"),
|
|
9099
|
+
content: z2.string().optional().describe("Inline text content to ingest"),
|
|
9100
|
+
metadata: z2.record(z2.any()).optional(),
|
|
9101
|
+
tags: z2.array(z2.string()).optional(),
|
|
9102
|
+
namespace: z2.string().optional(),
|
|
9103
|
+
type: z2.enum(["github", "web", "playwright", "pdf", "local", "slack", "video"]).optional().describe("Source type when mode=source"),
|
|
9104
|
+
url: z2.string().optional().describe("URL to learn from"),
|
|
9105
|
+
owner: z2.string().optional().describe("GitHub owner"),
|
|
9106
|
+
repo: z2.string().optional().describe("GitHub repository"),
|
|
9107
|
+
branch: z2.string().optional(),
|
|
9108
|
+
paths: z2.array(z2.string()).optional(),
|
|
9109
|
+
path: z2.string().optional().describe("Local path to learn from"),
|
|
9110
|
+
file_path: z2.string().optional().describe("Single file path to learn from"),
|
|
9111
|
+
name: z2.string().optional().describe("Optional source name"),
|
|
9112
|
+
channel_ids: z2.array(z2.string()).optional(),
|
|
9113
|
+
since: z2.string().optional(),
|
|
9114
|
+
token: z2.string().optional(),
|
|
9115
|
+
auth_ref: z2.string().optional(),
|
|
9116
|
+
platform: z2.enum(["youtube", "loom", "generic"]).optional(),
|
|
9117
|
+
language: z2.string().optional(),
|
|
9118
|
+
options: z2.object({
|
|
9119
|
+
async: z2.boolean().optional(),
|
|
9120
|
+
auto_index: z2.boolean().optional(),
|
|
9121
|
+
ingestion_profile: z2.enum(["auto", "repo", "web_docs", "pdf_layout", "video_transcript", "plain_text"]).optional(),
|
|
9122
|
+
strategy_override: z2.enum(["fixed", "recursive", "semantic", "hierarchical", "adaptive"]).optional(),
|
|
9123
|
+
profile_config: z2.record(z2.any()).optional(),
|
|
9124
|
+
crawl_depth: z2.number().optional(),
|
|
9125
|
+
include_paths: z2.array(z2.string()).optional(),
|
|
9126
|
+
exclude_paths: z2.array(z2.string()).optional(),
|
|
9127
|
+
glob: z2.string().optional(),
|
|
9128
|
+
max_files: z2.number().optional(),
|
|
9129
|
+
max_pages: z2.number().optional(),
|
|
9130
|
+
extract_mode: z2.enum(["text", "structured", "markdown"]).optional(),
|
|
9131
|
+
workspace_id: z2.string().optional(),
|
|
9132
|
+
allow_stt_fallback: z2.boolean().optional(),
|
|
9133
|
+
max_duration_minutes: z2.number().optional(),
|
|
9134
|
+
max_chunks: z2.number().optional()
|
|
8788
9135
|
}).optional()
|
|
8789
9136
|
},
|
|
8790
9137
|
async (input) => {
|
|
8791
9138
|
try {
|
|
8792
9139
|
const result = await learnFromInput(input);
|
|
9140
|
+
const indexingNote = result.mode === "source" && result.index_started ? "Indexing has started in the background and usually completes in 1\u20132 minutes. Queries may return limited results until then. Run `index.workspace_status` or `context.source_status` to check progress." : void 0;
|
|
8793
9141
|
return primaryToolSuccess({
|
|
8794
9142
|
tool: "learn",
|
|
8795
|
-
...result
|
|
9143
|
+
...result,
|
|
9144
|
+
...indexingNote ? { _note: indexingNote } : {}
|
|
8796
9145
|
});
|
|
8797
9146
|
} catch (error) {
|
|
8798
9147
|
return primaryToolError(error.message);
|
|
@@ -8803,10 +9152,10 @@ server.tool(
|
|
|
8803
9152
|
"share_context",
|
|
8804
9153
|
"Create a shareable snapshot of a session so another agent or teammate can continue with the same context.",
|
|
8805
9154
|
{
|
|
8806
|
-
project:
|
|
8807
|
-
session_id:
|
|
8808
|
-
title:
|
|
8809
|
-
expiry_days:
|
|
9155
|
+
project: z2.string().optional(),
|
|
9156
|
+
session_id: z2.string().describe("Session to share"),
|
|
9157
|
+
title: z2.string().optional(),
|
|
9158
|
+
expiry_days: z2.number().optional().default(30)
|
|
8810
9159
|
},
|
|
8811
9160
|
async ({ project, session_id, title, expiry_days }) => {
|
|
8812
9161
|
try {
|