@indexnetwork/protocol 4.3.2 → 4.3.4-rc.309.1
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/chat/chat.agent.d.ts.map +1 -1
- package/dist/chat/chat.agent.js +11 -1
- package/dist/chat/chat.agent.js.map +1 -1
- package/dist/chat/chat.graph.d.ts +16 -0
- package/dist/chat/chat.graph.d.ts.map +1 -1
- package/dist/chat/chat.graph.js +5 -2
- package/dist/chat/chat.graph.js.map +1 -1
- package/dist/chat/chat.prompt.d.ts.map +1 -1
- package/dist/chat/chat.prompt.js +20 -13
- package/dist/chat/chat.prompt.js.map +1 -1
- package/dist/chat/chat.state.d.ts +6 -3
- package/dist/chat/chat.state.d.ts.map +1 -1
- package/dist/chat/chat.state.js +12 -3
- package/dist/chat/chat.state.js.map +1 -1
- package/dist/chat/chat.streamer.d.ts +5 -0
- package/dist/chat/chat.streamer.d.ts.map +1 -1
- package/dist/chat/chat.streamer.js +13 -4
- package/dist/chat/chat.streamer.js.map +1 -1
- package/dist/enrichment/enrichment.tools.d.ts.map +1 -1
- package/dist/enrichment/enrichment.tools.js +16 -19
- package/dist/enrichment/enrichment.tools.js.map +1 -1
- package/dist/index.d.ts +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/intent/intent.graph.d.ts +10 -0
- package/dist/intent/intent.graph.d.ts.map +1 -1
- package/dist/intent/intent.graph.js +6 -2
- package/dist/intent/intent.graph.js.map +1 -1
- package/dist/intent/intent.state.d.ts +5 -1
- package/dist/intent/intent.state.d.ts.map +1 -1
- package/dist/intent/intent.state.js +11 -1
- package/dist/intent/intent.state.js.map +1 -1
- package/dist/intent/intent.tools.d.ts.map +1 -1
- package/dist/intent/intent.tools.js +63 -39
- package/dist/intent/intent.tools.js.map +1 -1
- package/dist/mcp/mcp.server.d.ts +45 -18
- package/dist/mcp/mcp.server.d.ts.map +1 -1
- package/dist/mcp/mcp.server.js +86 -45
- package/dist/mcp/mcp.server.js.map +1 -1
- package/dist/negotiation/negotiation.tools.d.ts.map +1 -1
- package/dist/negotiation/negotiation.tools.js +11 -7
- package/dist/negotiation/negotiation.tools.js.map +1 -1
- package/dist/network/network.graph.js +2 -2
- package/dist/network/network.graph.js.map +1 -1
- package/dist/network/network.tools.d.ts.map +1 -1
- package/dist/network/network.tools.js +50 -38
- package/dist/network/network.tools.js.map +1 -1
- package/dist/opportunity/opportunity.discover.d.ts +5 -0
- package/dist/opportunity/opportunity.discover.d.ts.map +1 -1
- package/dist/opportunity/opportunity.discover.js +3 -0
- package/dist/opportunity/opportunity.discover.js.map +1 -1
- package/dist/opportunity/opportunity.graph.d.ts +6 -6
- package/dist/opportunity/opportunity.graph.js +1 -1
- package/dist/opportunity/opportunity.graph.js.map +1 -1
- package/dist/opportunity/opportunity.pending-questions.d.ts +3 -0
- package/dist/opportunity/opportunity.pending-questions.d.ts.map +1 -1
- package/dist/opportunity/opportunity.pending-questions.js +7 -2
- package/dist/opportunity/opportunity.pending-questions.js.map +1 -1
- package/dist/opportunity/opportunity.state.d.ts +1 -1
- package/dist/opportunity/opportunity.tools.d.ts.map +1 -1
- package/dist/opportunity/opportunity.tools.js +46 -36
- package/dist/opportunity/opportunity.tools.js.map +1 -1
- package/dist/premise/premise.graph.d.ts +13 -1
- package/dist/premise/premise.graph.d.ts.map +1 -1
- package/dist/premise/premise.graph.js +11 -6
- package/dist/premise/premise.graph.js.map +1 -1
- package/dist/premise/premise.state.d.ts +5 -0
- package/dist/premise/premise.state.d.ts.map +1 -1
- package/dist/premise/premise.state.js +11 -0
- package/dist/premise/premise.state.js.map +1 -1
- package/dist/premise/premise.tools.d.ts.map +1 -1
- package/dist/premise/premise.tools.js +5 -0
- package/dist/premise/premise.tools.js.map +1 -1
- package/dist/questioner/questioner.tools.d.ts +1 -1
- package/dist/questioner/questioner.tools.d.ts.map +1 -1
- package/dist/questioner/questioner.tools.js +24 -13
- package/dist/questioner/questioner.tools.js.map +1 -1
- package/dist/questioner/questioner.types.d.ts +5 -0
- package/dist/questioner/questioner.types.d.ts.map +1 -1
- package/dist/questioner/questioner.types.js.map +1 -1
- package/dist/shared/agent/tool.factory.d.ts.map +1 -1
- package/dist/shared/agent/tool.factory.js +25 -16
- package/dist/shared/agent/tool.factory.js.map +1 -1
- package/dist/shared/agent/tool.helpers.d.ts +17 -18
- package/dist/shared/agent/tool.helpers.d.ts.map +1 -1
- package/dist/shared/agent/tool.helpers.js +10 -11
- package/dist/shared/agent/tool.helpers.js.map +1 -1
- package/dist/shared/agent/tool.registry.js +1 -1
- package/dist/shared/agent/tool.registry.js.map +1 -1
- package/dist/shared/agent/tool.scope.d.ts +39 -0
- package/dist/shared/agent/tool.scope.d.ts.map +1 -0
- package/dist/shared/agent/tool.scope.js +41 -0
- package/dist/shared/agent/tool.scope.js.map +1 -0
- package/dist/shared/assignment/network-assignment.policy.d.ts +8 -5
- package/dist/shared/assignment/network-assignment.policy.d.ts.map +1 -1
- package/dist/shared/assignment/network-assignment.policy.js +11 -6
- package/dist/shared/assignment/network-assignment.policy.js.map +1 -1
- package/dist/shared/hyde/hyde.graph.d.ts +6 -6
- package/dist/shared/hyde/hyde.state.d.ts +2 -2
- package/dist/shared/interfaces/auth.interface.d.ts +3 -3
- package/dist/shared/interfaces/auth.interface.js.map +1 -1
- package/dist/shared/interfaces/database.interface.d.ts +15 -3
- package/dist/shared/interfaces/database.interface.d.ts.map +1 -1
- package/dist/shared/interfaces/database.interface.js.map +1 -1
- package/dist/shared/interfaces/discovery-run.interface.d.ts +1 -1
- package/dist/shared/interfaces/discovery-run.interface.d.ts.map +1 -1
- package/dist/shared/interfaces/discovery-run.interface.js.map +1 -1
- package/dist/shared/interfaces/enrichment-run.interface.d.ts +1 -1
- package/dist/shared/interfaces/enrichment-run.interface.d.ts.map +1 -1
- package/dist/shared/interfaces/enrichment-run.interface.js.map +1 -1
- package/dist/shared/interfaces/queue.interface.d.ts +8 -2
- package/dist/shared/interfaces/queue.interface.d.ts.map +1 -1
- package/dist/shared/interfaces/queue.interface.js.map +1 -1
- package/dist/shared/schemas/network-assignment.schema.d.ts +2 -2
- package/dist/shared/schemas/pending-question.schema.d.ts +5 -0
- package/dist/shared/schemas/pending-question.schema.d.ts.map +1 -1
- package/dist/shared/schemas/pending-question.schema.js.map +1 -1
- package/package.json +1 -1
|
@@ -4,6 +4,7 @@ import { protocolLogger } from "../shared/observability/protocol.logger.js";
|
|
|
4
4
|
import { traceGraph } from "../shared/observability/trace.js";
|
|
5
5
|
import { success, error, UUID_REGEX } from "../shared/agent/tool.helpers.js";
|
|
6
6
|
import { invokeWithAbortSignal } from "../shared/agent/model-signal.js";
|
|
7
|
+
import { deriveAllowedNetworkIds, focusedNetworkId, focusedNetworkLabel } from "../shared/agent/tool.scope.js";
|
|
7
8
|
const logger = protocolLogger("ChatTools:Intent");
|
|
8
9
|
/**
|
|
9
10
|
* Sanitize JSON string for use inside a markdown code fence (```). Escapes backticks
|
|
@@ -14,11 +15,12 @@ function sanitizeJsonForCodeFence(json) {
|
|
|
14
15
|
}
|
|
15
16
|
/** When context is index-scoped, verifies the caller is still a member of that index. Returns error message or null. */
|
|
16
17
|
async function ensureScopedMembership(context, systemDb) {
|
|
17
|
-
|
|
18
|
+
const scopedNetworkId = focusedNetworkId(context);
|
|
19
|
+
if (!scopedNetworkId)
|
|
18
20
|
return null;
|
|
19
|
-
const isMember = await systemDb.isNetworkMember(
|
|
21
|
+
const isMember = await systemDb.isNetworkMember(scopedNetworkId, context.userId);
|
|
20
22
|
if (!isMember) {
|
|
21
|
-
return `This chat is scoped to ${context
|
|
23
|
+
return `This chat is scoped to ${focusedNetworkLabel(context)}. You are no longer a member of this community.`;
|
|
22
24
|
}
|
|
23
25
|
return null;
|
|
24
26
|
}
|
|
@@ -79,6 +81,8 @@ export function createIntentTools(defineTool, deps) {
|
|
|
79
81
|
if (scopeErr)
|
|
80
82
|
return error(scopeErr);
|
|
81
83
|
// Distinguish "explicit network browse" from "implicit scope-aware read"
|
|
84
|
+
const scopedNetworkId = focusedNetworkId(context);
|
|
85
|
+
const scopedIndexLabel = focusedNetworkLabel(context);
|
|
82
86
|
const explicitNetworkId = query.networkId?.trim();
|
|
83
87
|
const explicitUserId = query.userId?.trim();
|
|
84
88
|
// Validate explicit networkId format
|
|
@@ -86,25 +90,24 @@ export function createIntentTools(defineTool, deps) {
|
|
|
86
90
|
return error("Invalid network ID format.");
|
|
87
91
|
}
|
|
88
92
|
// Strict scope enforcement: in a scoped chat, the only allowed explicit
|
|
89
|
-
// networkId is
|
|
90
|
-
//
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
return error(`This chat is scoped to ${context.indexName ?? 'this index'}. You can only read intents from this community.`);
|
|
93
|
+
// networkId is the envelope's scoped network. Cross-network browse must
|
|
94
|
+
// happen in a separate unscoped chat or a chat scoped to that network.
|
|
95
|
+
if (scopedNetworkId && explicitNetworkId && explicitNetworkId !== scopedNetworkId) {
|
|
96
|
+
return error(`This chat is scoped to ${scopedIndexLabel}. You can only read intents from this community.`);
|
|
94
97
|
}
|
|
95
98
|
// Cross-user read in scoped chat: target user must be a member of the scoped index
|
|
96
|
-
if (
|
|
97
|
-
const isInScopedIndex = await deps.systemDb.isNetworkMember(
|
|
99
|
+
if (scopedNetworkId && explicitUserId && explicitUserId !== context.userId) {
|
|
100
|
+
const isInScopedIndex = await deps.systemDb.isNetworkMember(scopedNetworkId, explicitUserId);
|
|
98
101
|
if (!isInScopedIndex) {
|
|
99
|
-
return error(`This chat is scoped to ${
|
|
102
|
+
return error(`This chat is scoped to ${scopedIndexLabel}. You can only read intents from members of this community.`);
|
|
100
103
|
}
|
|
101
104
|
}
|
|
102
105
|
// Cross-user global read is disallowed without an index scope
|
|
103
|
-
if (!explicitNetworkId && !
|
|
106
|
+
if (!explicitNetworkId && !scopedNetworkId && explicitUserId && explicitUserId !== context.userId) {
|
|
104
107
|
return error("Cannot read another user's global intents. Use networkId to scope to a shared network.");
|
|
105
108
|
}
|
|
106
109
|
// Membership check for explicit cross-network reads in unscoped chats
|
|
107
|
-
if (!
|
|
110
|
+
if (!scopedNetworkId && explicitNetworkId) {
|
|
108
111
|
const callerIsMember = await deps.systemDb.isNetworkMember(explicitNetworkId, context.userId);
|
|
109
112
|
if (!callerIsMember) {
|
|
110
113
|
return error("You can only read intents from indexes you are a member of.");
|
|
@@ -126,10 +129,10 @@ export function createIntentTools(defineTool, deps) {
|
|
|
126
129
|
if (explicitUserId)
|
|
127
130
|
graphInput.queryUserId = explicitUserId;
|
|
128
131
|
}
|
|
129
|
-
else if (explicitUserId &&
|
|
132
|
+
else if (explicitUserId && scopedNetworkId) {
|
|
130
133
|
// Scoped chat + userId: implicit network is the chat's bound network.
|
|
131
134
|
// Membership of the target user was verified above.
|
|
132
|
-
graphInput.networkId =
|
|
135
|
+
graphInput.networkId = scopedNetworkId;
|
|
133
136
|
graphInput.queryUserId = explicitUserId;
|
|
134
137
|
}
|
|
135
138
|
else if (explicitUserId) {
|
|
@@ -137,9 +140,13 @@ export function createIntentTools(defineTool, deps) {
|
|
|
137
140
|
graphInput.queryUserId = explicitUserId;
|
|
138
141
|
graphInput.allUserIntents = true;
|
|
139
142
|
}
|
|
140
|
-
else if (
|
|
143
|
+
else if (scopedNetworkId) {
|
|
141
144
|
// Scoped chat, implicit read: caller-only across reachable indexes.
|
|
142
|
-
graphInput.indexScope =
|
|
145
|
+
graphInput.indexScope = deriveAllowedNetworkIds({
|
|
146
|
+
memberships: context.userNetworks,
|
|
147
|
+
scopeType: 'network',
|
|
148
|
+
scopeId: scopedNetworkId,
|
|
149
|
+
});
|
|
143
150
|
}
|
|
144
151
|
else {
|
|
145
152
|
// Unscoped, implicit read: caller's global intents.
|
|
@@ -209,11 +216,16 @@ export function createIntentTools(defineTool, deps) {
|
|
|
209
216
|
if (!query.description?.trim()) {
|
|
210
217
|
return error("Description is required.");
|
|
211
218
|
}
|
|
219
|
+
const scopedNetworkId = focusedNetworkId(context);
|
|
220
|
+
const scopedIndexLabel = focusedNetworkLabel(context);
|
|
212
221
|
// Strict scope enforcement
|
|
213
|
-
if (
|
|
214
|
-
return error(`This chat is scoped to ${
|
|
222
|
+
if (scopedNetworkId && query.networkId?.trim() && query.networkId.trim() !== scopedNetworkId) {
|
|
223
|
+
return error(`This chat is scoped to ${scopedIndexLabel}. You can only create intents in this community.`);
|
|
215
224
|
}
|
|
216
|
-
const effectiveIndexId =
|
|
225
|
+
const effectiveIndexId = scopedNetworkId || query.networkId?.trim() || undefined;
|
|
226
|
+
const scopeEnvelope = scopedNetworkId
|
|
227
|
+
? { scopeType: 'network', scopeId: scopedNetworkId }
|
|
228
|
+
: {};
|
|
217
229
|
// Fetch profile (the intent graph needs it for inference)
|
|
218
230
|
const _profileGraphStart1 = Date.now();
|
|
219
231
|
const profileResult = await traceGraph("profile", () => invokeWithAbortSignal(graphs.profile, { userId: context.userId, operationMode: 'query' }));
|
|
@@ -229,6 +241,7 @@ export function createIntentTools(defineTool, deps) {
|
|
|
229
241
|
inputContent: query.description,
|
|
230
242
|
operationMode: 'propose',
|
|
231
243
|
...(effectiveIndexId ? { networkId: effectiveIndexId } : {}),
|
|
244
|
+
...scopeEnvelope,
|
|
232
245
|
}));
|
|
233
246
|
const _intentGraphMs1 = Date.now() - _intentGraphStart1;
|
|
234
247
|
logger.debug("Intent graph propose response", { result });
|
|
@@ -283,6 +296,7 @@ export function createIntentTools(defineTool, deps) {
|
|
|
283
296
|
inputContent: v.description,
|
|
284
297
|
operationMode: 'create',
|
|
285
298
|
...(effectiveIndexId ? { networkId: effectiveIndexId } : {}),
|
|
299
|
+
...scopeEnvelope,
|
|
286
300
|
}));
|
|
287
301
|
const _createGraphMs = Date.now() - _createGraphStart;
|
|
288
302
|
createTimings.push({ name: 'intent-create', durationMs: _createGraphMs, agents: createResult.agentTimings ?? [] });
|
|
@@ -370,12 +384,14 @@ export function createIntentTools(defineTool, deps) {
|
|
|
370
384
|
if (intent.archivedAt) {
|
|
371
385
|
return error("This intent is archived and cannot be updated. Create a new intent instead.");
|
|
372
386
|
}
|
|
387
|
+
const scopedNetworkId = focusedNetworkId(context);
|
|
388
|
+
const scopedIndexLabel = focusedNetworkLabel(context);
|
|
373
389
|
// Strict scope enforcement: when chat is index-scoped, verify intent is linked to that index
|
|
374
|
-
if (
|
|
390
|
+
if (scopedNetworkId) {
|
|
375
391
|
const db = deps.userDb;
|
|
376
392
|
const intentNetworks = await db.getNetworkIdsForIntent(intentId);
|
|
377
|
-
if (!intentNetworks.includes(
|
|
378
|
-
return error(`This chat is scoped to ${
|
|
393
|
+
if (!intentNetworks.includes(scopedNetworkId)) {
|
|
394
|
+
return error(`This chat is scoped to ${scopedIndexLabel}. You can only update intents linked to this community.`);
|
|
379
395
|
}
|
|
380
396
|
}
|
|
381
397
|
const _profileGraphStart2 = Date.now();
|
|
@@ -391,7 +407,7 @@ export function createIntentTools(defineTool, deps) {
|
|
|
391
407
|
operationMode: 'update',
|
|
392
408
|
inputContent: query.description,
|
|
393
409
|
targetIntentIds: [intentId],
|
|
394
|
-
...(
|
|
410
|
+
...(scopedNetworkId && { networkId: scopedNetworkId, scopeType: 'network', scopeId: scopedNetworkId }),
|
|
395
411
|
}));
|
|
396
412
|
const _intentGraphMs2 = Date.now() - _intentGraphStart2;
|
|
397
413
|
if (result.executionResults?.some((r) => !r.success)) {
|
|
@@ -434,12 +450,14 @@ export function createIntentTools(defineTool, deps) {
|
|
|
434
450
|
if (!intent || intent.userId !== context.userId) {
|
|
435
451
|
return error("Intent not found or you can only delete your own intents.");
|
|
436
452
|
}
|
|
453
|
+
const scopedNetworkId = focusedNetworkId(context);
|
|
454
|
+
const scopedIndexLabel = focusedNetworkLabel(context);
|
|
437
455
|
// Strict scope enforcement: when chat is index-scoped, verify intent is linked to that index
|
|
438
|
-
if (
|
|
456
|
+
if (scopedNetworkId) {
|
|
439
457
|
const db = deps.userDb;
|
|
440
458
|
const intentNetworks = await db.getNetworkIdsForIntent(intentId);
|
|
441
|
-
if (!intentNetworks.includes(
|
|
442
|
-
return error(`This chat is scoped to ${
|
|
459
|
+
if (!intentNetworks.includes(scopedNetworkId)) {
|
|
460
|
+
return error(`This chat is scoped to ${scopedIndexLabel}. You can only delete intents linked to this community.`);
|
|
443
461
|
}
|
|
444
462
|
}
|
|
445
463
|
const _deleteIntentGraphStart = Date.now();
|
|
@@ -448,7 +466,7 @@ export function createIntentTools(defineTool, deps) {
|
|
|
448
466
|
userProfile: "",
|
|
449
467
|
operationMode: 'delete',
|
|
450
468
|
targetIntentIds: [intentId],
|
|
451
|
-
...(
|
|
469
|
+
...(scopedNetworkId && { networkId: scopedNetworkId, scopeType: 'network', scopeId: scopedNetworkId }),
|
|
452
470
|
}));
|
|
453
471
|
const _deleteIntentGraphMs = Date.now() - _deleteIntentGraphStart;
|
|
454
472
|
if (result.executionResults?.some((r) => !r.success)) {
|
|
@@ -478,14 +496,16 @@ export function createIntentTools(defineTool, deps) {
|
|
|
478
496
|
const scopeErr = await ensureScopedMembership(context, deps.systemDb);
|
|
479
497
|
if (scopeErr)
|
|
480
498
|
return error(scopeErr);
|
|
499
|
+
const scopedNetworkId = focusedNetworkId(context);
|
|
500
|
+
const scopedIndexLabel = focusedNetworkLabel(context);
|
|
481
501
|
const intentId = query.intentId?.trim() ?? "";
|
|
482
|
-
const networkId = query.networkId?.trim() ||
|
|
502
|
+
const networkId = query.networkId?.trim() || scopedNetworkId || "";
|
|
483
503
|
if (!UUID_REGEX.test(intentId) || !UUID_REGEX.test(networkId)) {
|
|
484
504
|
return error("Invalid ID format. Both must be UUIDs.");
|
|
485
505
|
}
|
|
486
506
|
// Strict scope enforcement: when chat is index-scoped, only allow linking to that index
|
|
487
|
-
if (
|
|
488
|
-
return error(`This chat is scoped to ${
|
|
507
|
+
if (scopedNetworkId && networkId !== scopedNetworkId) {
|
|
508
|
+
return error(`This chat is scoped to ${scopedIndexLabel}. You can only link intents to this community.`);
|
|
489
509
|
}
|
|
490
510
|
const _createIntentIndexGraphStart = Date.now();
|
|
491
511
|
const result = await traceGraph("intent_network", () => invokeWithAbortSignal(graphs.intentIndex, {
|
|
@@ -530,8 +550,10 @@ export function createIntentTools(defineTool, deps) {
|
|
|
530
550
|
const scopeErr = await ensureScopedMembership(context, deps.systemDb);
|
|
531
551
|
if (scopeErr)
|
|
532
552
|
return error(scopeErr);
|
|
553
|
+
const scopedNetworkId = focusedNetworkId(context);
|
|
554
|
+
const scopedIndexLabel = focusedNetworkLabel(context);
|
|
533
555
|
const intentId = query.intentId?.trim() || undefined;
|
|
534
|
-
let networkId = query.networkId?.trim() ||
|
|
556
|
+
let networkId = query.networkId?.trim() || scopedNetworkId || undefined;
|
|
535
557
|
const queryUserId = query.userId?.trim() || undefined;
|
|
536
558
|
if (intentId && !UUID_REGEX.test(intentId)) {
|
|
537
559
|
return error("Invalid intent ID format.");
|
|
@@ -543,14 +565,14 @@ export function createIntentTools(defineTool, deps) {
|
|
|
543
565
|
return error("Provide networkId or intentId.");
|
|
544
566
|
}
|
|
545
567
|
// Strict scope enforcement: when chat is index-scoped, only allow querying that index
|
|
546
|
-
if (
|
|
547
|
-
return error(`This chat is scoped to ${
|
|
568
|
+
if (scopedNetworkId && networkId && networkId !== scopedNetworkId) {
|
|
569
|
+
return error(`This chat is scoped to ${scopedIndexLabel}. You can only read intent links from this community.`);
|
|
548
570
|
}
|
|
549
571
|
// When only intentId is provided, enforce scope - don't reveal all linked indexes
|
|
550
572
|
if (intentId && !networkId) {
|
|
551
|
-
if (
|
|
573
|
+
if (scopedNetworkId) {
|
|
552
574
|
// When scoped, only check if intent is linked to the scoped index
|
|
553
|
-
networkId =
|
|
575
|
+
networkId = scopedNetworkId;
|
|
554
576
|
}
|
|
555
577
|
else {
|
|
556
578
|
// When unscoped, still don't reveal all indexes - require explicit networkId
|
|
@@ -590,14 +612,16 @@ export function createIntentTools(defineTool, deps) {
|
|
|
590
612
|
const scopeErr = await ensureScopedMembership(context, deps.systemDb);
|
|
591
613
|
if (scopeErr)
|
|
592
614
|
return error(scopeErr);
|
|
615
|
+
const scopedNetworkId = focusedNetworkId(context);
|
|
616
|
+
const scopedIndexLabel = focusedNetworkLabel(context);
|
|
593
617
|
const intentId = query.intentId?.trim() ?? "";
|
|
594
|
-
const networkId = query.networkId?.trim() ||
|
|
618
|
+
const networkId = query.networkId?.trim() || scopedNetworkId || "";
|
|
595
619
|
if (!UUID_REGEX.test(intentId) || !UUID_REGEX.test(networkId)) {
|
|
596
620
|
return error("Invalid ID format. Both must be UUIDs.");
|
|
597
621
|
}
|
|
598
622
|
// Strict scope enforcement: when chat is index-scoped, only allow unlinking from that index
|
|
599
|
-
if (
|
|
600
|
-
return error(`This chat is scoped to ${
|
|
623
|
+
if (scopedNetworkId && networkId !== scopedNetworkId) {
|
|
624
|
+
return error(`This chat is scoped to ${scopedIndexLabel}. You can only unlink intents from this community.`);
|
|
601
625
|
}
|
|
602
626
|
const _deleteIntentIndexGraphStart = Date.now();
|
|
603
627
|
const result = await traceGraph("intent_network", () => invokeWithAbortSignal(graphs.intentIndex, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"intent.tools.js","sourceRoot":"/","sources":["intent/intent.tools.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from \"zod\";\n\nimport type { ExecutionResult, VerifiedIntent } from \"./intent.state.js\";\nimport { DEFAULT_SPECIFICITY_WARNING } from \"./intent.specificity.js\";\nimport { protocolLogger } from \"../shared/observability/protocol.logger.js\";\nimport { traceGraph } from \"../shared/observability/trace.js\";\n\nimport type { DefineTool, ToolDeps } from \"../shared/agent/tool.helpers.js\";\nimport { success, error, UUID_REGEX } from \"../shared/agent/tool.helpers.js\";\nimport type { UserRecord } from \"../shared/interfaces/database.interface.js\";\nimport { invokeWithAbortSignal } from \"../shared/agent/model-signal.js\";\n\nconst logger = protocolLogger(\"ChatTools:Intent\");\n\n/**\n * Sanitize JSON string for use inside a markdown code fence (```). Escapes backticks\n * so embedded ``` cannot close the fence prematurely.\n */\nfunction sanitizeJsonForCodeFence(json: string): string {\n return json.replace(/`/g, \"\\\\u0060\");\n}\n\n/** When context is index-scoped, verifies the caller is still a member of that index. Returns error message or null. */\nasync function ensureScopedMembership(\n context: { networkId?: string; indexName?: string; userId: string },\n systemDb: ToolDeps['systemDb']\n): Promise<string | null> {\n if (!context.networkId) return null;\n const isMember = await systemDb.isNetworkMember(context.networkId, context.userId);\n if (!isMember) {\n return `This chat is scoped to ${context.indexName ?? 'this index'}. You are no longer a member of this community.`;\n }\n return null;\n}\n\nfunction buildApprovedProfileFallback(user: UserRecord | null | undefined): string {\n const bio = user?.intro?.trim();\n if (!user || !bio) return \"\";\n\n return JSON.stringify({\n userId: user.id,\n identity: {\n name: user.name ?? \"\",\n bio,\n location: user.location?.trim() ?? \"\",\n },\n narrative: { context: bio },\n attributes: { skills: [], interests: [] },\n });\n}\n\nfunction isBroadAttributiveIntent(intent: VerifiedIntent): boolean {\n return intent.verification?.referential_breadth === \"broad\";\n}\n\nconst NULL_LIKE_SPECIFICITY_WARNING_VALUES = new Set([\"null\", \"undefined\"]);\n\nfunction normalizeSpecificityWarning(value: string | null | undefined): string | null {\n const warning = value?.trim();\n if (!warning) return null;\n return NULL_LIKE_SPECIFICITY_WARNING_VALUES.has(warning.toLowerCase()) ? null : warning;\n}\n\nfunction specificityWarningFor(intent: VerifiedIntent): string {\n return normalizeSpecificityWarning(intent.verification?.specificity_warning) ?? DEFAULT_SPECIFICITY_WARNING;\n}\n\nexport function createIntentTools(defineTool: DefineTool, deps: ToolDeps) {\n const { graphs, userDb } = deps;\n\n // ─────────────────────────────────────────────────────────────────────────────\n // INTENT CRUD\n // ─────────────────────────────────────────────────────────────────────────────\n\n const readIntents = defineTool({\n name: \"read_intents\",\n description:\n \"Retrieves intents (signals of interest/need, e.g. 'Looking for a React developer in Berlin'). \" +\n \"Intents are the core unit of discovery — they represent what users are seeking and drive semantic matching for opportunities.\\n\\n\" +\n \"**Usage modes:**\\n\" +\n \"- No parameters: returns the **caller's own** active intents. In an index-scoped chat the result is clamped to the reachable indexes (the bound index plus the user's personal index). In an unscoped chat the result spans all of the user's active intents. There is no implicit default to the scoped index — to browse the bound community's intents, pass `networkId` explicitly.\\n\" +\n \"- With networkId: returns **all members'** intents in that index (community browse path). Add userId to filter to one member.\\n\" +\n \"- With userId in an index-scoped chat: reads that member's intents in the bound index. The target user must be a member of that index.\\n\" +\n \"- With userId in an unscoped chat: only works for the current user (cannot read another user's global intents without an index scope).\\n\\n\" +\n \"**Workflow:** To explore what members of an index are looking for, first call read_network_memberships(networkId) to list members, \" +\n \"then read_intents(networkId) to see all intents in that community. \" +\n \"Each intent includes: id, description (payload), summary, confidence (0-1), inferenceType (explicit/implicit), status, and linked indexes.\\n\\n\" +\n \"**Returns:** Paginated list of intents with count. Use the intent IDs in subsequent calls to update_intent, delete_intent, or create_intent_index.\",\n querySchema: z.object({\n networkId: z.string().optional().describe(\"Index UUID — filters intents to this index (community browse path: returns all members' intents). There is no implicit default in index-scoped chats; omit to get caller-owned intents across the reachable indexes, or pass the scoped index UUID to browse community members. Get index IDs from read_networks.\"),\n userId: z.string().optional().describe(\"User ID — filters to this user's intents. In an index-scoped chat, this reads that member's intents in the bound index (no networkId required). In an unscoped chat, only the current user is allowed without networkId; cross-user reads require an index scope. Omit for caller-owned intents.\"),\n limit: z.number().int().min(1).max(100).optional().describe(\"Page size (1-100). Defaults to returning all results if omitted.\"),\n page: z.number().int().min(1).optional().describe(\"Page number (1-based). Only used when limit is also provided.\"),\n }),\n handler: async ({ context, query }) => {\n const scopeErr = await ensureScopedMembership(context, deps.systemDb);\n if (scopeErr) return error(scopeErr);\n\n // Distinguish \"explicit network browse\" from \"implicit scope-aware read\"\n const explicitNetworkId = query.networkId?.trim();\n const explicitUserId = query.userId?.trim();\n\n // Validate explicit networkId format\n if (explicitNetworkId && !UUID_REGEX.test(explicitNetworkId)) {\n return error(\"Invalid network ID format.\");\n }\n\n // Strict scope enforcement: in a scoped chat, the only allowed explicit\n // networkId is context.networkId itself. The chat's focus is the bound\n // network; cross-network browse must happen in a separate (unscoped)\n // chat or a chat scoped to that other network.\n if (context.networkId && explicitNetworkId && explicitNetworkId !== context.networkId) {\n return error(\n `This chat is scoped to ${context.indexName ?? 'this index'}. You can only read intents from this community.`\n );\n }\n\n // Cross-user read in scoped chat: target user must be a member of the scoped index\n if (context.networkId && explicitUserId && explicitUserId !== context.userId) {\n const isInScopedIndex = await deps.systemDb.isNetworkMember(context.networkId, explicitUserId);\n if (!isInScopedIndex) {\n return error(\n `This chat is scoped to ${context.indexName ?? 'this index'}. You can only read intents from members of this community.`\n );\n }\n }\n\n // Cross-user global read is disallowed without an index scope\n if (!explicitNetworkId && !context.networkId && explicitUserId && explicitUserId !== context.userId) {\n return error(\"Cannot read another user's global intents. Use networkId to scope to a shared network.\");\n }\n\n // Membership check for explicit cross-network reads in unscoped chats\n if (!context.networkId && explicitNetworkId) {\n const callerIsMember = await deps.systemDb.isNetworkMember(explicitNetworkId, context.userId);\n if (!callerIsMember) {\n return error(\"You can only read intents from indexes you are a member of.\");\n }\n }\n\n // ── Choose the read mode ──\n // 1. Explicit networkId (browse all members in that index) — pass networkId, optionally + queryUserId.\n // 2. Explicit userId in a scoped chat — read that user's intents in the bound network.\n // 3. Explicit userId in an unscoped chat — only self (cross-user rejected above); global \"my intents\".\n // 4. Implicit (no explicit network/user) in scoped chat — pass indexScope, no networkId.\n // 5. Implicit in unscoped chat — global getActiveIntents (caller's own).\n const graphInput: Record<string, unknown> = {\n userId: context.userId,\n userProfile: \"\",\n operationMode: 'read' as const,\n };\n\n if (explicitNetworkId) {\n graphInput.networkId = explicitNetworkId;\n if (explicitUserId) graphInput.queryUserId = explicitUserId;\n } else if (explicitUserId && context.networkId) {\n // Scoped chat + userId: implicit network is the chat's bound network.\n // Membership of the target user was verified above.\n graphInput.networkId = context.networkId;\n graphInput.queryUserId = explicitUserId;\n } else if (explicitUserId) {\n // Unscoped chat + userId: only allowed for self (others rejected above).\n graphInput.queryUserId = explicitUserId;\n graphInput.allUserIntents = true;\n } else if (context.indexScope && context.indexScope.length > 0 && context.networkId) {\n // Scoped chat, implicit read: caller-only across reachable indexes.\n graphInput.indexScope = context.indexScope;\n } else {\n // Unscoped, implicit read: caller's global intents.\n graphInput.allUserIntents = true;\n }\n\n const _readIntentGraphStart = Date.now();\n const result = await traceGraph(\"intent\", () => invokeWithAbortSignal(graphs.intent, graphInput));\n const _readIntentGraphMs = Date.now() - _readIntentGraphStart;\n\n if (result.readResult) {\n if (result.readResult.count === 0 && result.readResult.message && /not a member|Network not found/i.test(result.readResult.message)) {\n return error(result.readResult.message);\n }\n\n const shouldPaginate = query.limit !== undefined || query.page !== undefined;\n if (shouldPaginate && Array.isArray(result.readResult.intents)) {\n const limit = query.limit ?? 20;\n const page = query.page ?? 1;\n const offset = (page - 1) * limit;\n const pagedIntents = result.readResult.intents.slice(offset, offset + limit);\n return success({\n ...result.readResult,\n count: pagedIntents.length,\n totalCount: result.readResult.intents.length,\n limit,\n page,\n totalPages: Math.ceil(result.readResult.intents.length / limit),\n intents: pagedIntents,\n _graphTimings: [{ name: 'intent', durationMs: _readIntentGraphMs, agents: result.agentTimings ?? [] }],\n });\n }\n\n return success({ ...result.readResult, _graphTimings: [{ name: 'intent', durationMs: _readIntentGraphMs, agents: result.agentTimings ?? [] }] });\n }\n return error(\"Failed to fetch intents.\");\n },\n });\n\n const createIntent = defineTool({\n name: \"create_intent\",\n description:\n \"Creates a new intent (signal of interest/need) for the authenticated user. Intents drive the discovery engine — once created, \" +\n \"the system automatically evaluates them against indexes the user belongs to, links them to relevant communities, and begins \" +\n \"searching for matching opportunities (complementary intents from other users).\\n\\n\" +\n \"**What to pass:** A clear, concept-based description of what the user is looking for (e.g. 'Looking for an AI/ML co-founder in Berlin', \" +\n \"'Need a designer for a mobile app project'). If the user provided a URL, scrape it with scrape_url first and synthesize the content into a description.\\n\\n\" +\n \"**What happens:** The system runs inference (extracting structured intents), verification (checking specificity and speech-act type), \" +\n \"and returns a proposal widget. The proposal is NOT yet persisted — the user must approve it first.\\n\\n\" +\n \"**Returns:** An intent_proposal code block that MUST be included verbatim in the response. The frontend renders it as an interactive \" +\n \"card the user can approve or skip. On approval, the intent is persisted, indexed, and discovery begins.\\n\\n\" +\n \"**Next steps after approval:** The intent is automatically linked to relevant indexes. Call discover_opportunities(searchQuery) to explicitly trigger discovery, \" +\n \"or wait for background processing to find matches.\\n\\n\" +\n \"**Specificity gate.** Before calling this tool, judge whether the description is concrete enough to be \" +\n \"useful for matching. If the user says \\\"find a job\\\", \\\"meet people\\\", or \\\"learn something\\\", that's too \" +\n \"vague — FIRST call read_user_contexts() + read_intents() to understand their context, THEN propose a \" +\n \"refined version (\\\"Based on your background in X, did you mean 'Y'?\\\") and wait for confirmation before \" +\n \"calling create_intent. Specific asks (\\\"senior UX design role at a tech company in Berlin\\\") can go \" +\n \"directly to create_intent.\\n\\n\" +\n \"**URL handling.** If the user pastes a URL describing the intent (e.g. a job posting), call scrape_url \" +\n \"first with objective=\\\"Extract key details for an intent\\\", synthesize a conceptual description from the \" +\n \"content, then call create_intent with the synthesis. Exception: profile URLs (LinkedIn, GitHub, X) passed \" +\n \"to create_user_context are handled by that tool directly — do not scrape first.\",\n querySchema: z.object({\n description: z.string().describe(\"A clear, specific description of what the user is looking for. Should be concept-based, not a raw URL. If the user shared a URL, scrape it first with scrape_url and pass the synthesized content here. Vague descriptions will be rejected — include what kind, what for, and/or timeframe.\"),\n networkId: z.string().optional().describe(\"Index UUID to link the intent to upon creation. Defaults to the scoped index in index-scoped chats. Get index IDs from read_networks. If omitted, the system auto-assigns to relevant indexes based on their prompts.\"),\n autoApprove: z.boolean().optional().describe(\"When true, automatically persists all verified intents without returning proposal cards for manual approval. MCP agents SHOULD set this to true since there is no UI for card-based approval. Web chat agents should omit or set to false to get interactive proposal cards.\"),\n }),\n handler: async ({ context, query }) => {\n const scopeErr = await ensureScopedMembership(context, deps.systemDb);\n if (scopeErr) return error(scopeErr);\n if (!query.description?.trim()) {\n return error(\"Description is required.\");\n }\n\n // Strict scope enforcement\n if (context.networkId && query.networkId?.trim() && query.networkId.trim() !== context.networkId) {\n return error(\n `This chat is scoped to ${context.indexName ?? 'this index'}. You can only create intents in this community.`\n );\n }\n\n const effectiveIndexId = context.networkId || query.networkId?.trim() || undefined;\n\n // Fetch profile (the intent graph needs it for inference)\n const _profileGraphStart1 = Date.now();\n const profileResult = await traceGraph(\"profile\", () => invokeWithAbortSignal(graphs.profile, { userId: context.userId, operationMode: 'query' as const }));\n const _profileGraphMs1 = Date.now() - _profileGraphStart1;\n const latestUser = profileResult.profile ? undefined : typeof userDb.getUser === \"function\" ? await userDb.getUser() : context.user;\n const approvedProfileFallback = profileResult.profile ? \"\" : buildApprovedProfileFallback(latestUser);\n const userProfile = profileResult.profile ? JSON.stringify(profileResult.profile) : approvedProfileFallback;\n\n // Run inference + verification only (propose mode — no DB persistence)\n const _intentGraphStart1 = Date.now();\n const result = await traceGraph(\"intent\", () => invokeWithAbortSignal(graphs.intent, {\n userId: context.userId,\n userProfile,\n inputContent: query.description,\n operationMode: 'propose' as const,\n ...(effectiveIndexId ? { networkId: effectiveIndexId } : {}),\n }));\n const _intentGraphMs1 = Date.now() - _intentGraphStart1;\n logger.debug(\"Intent graph propose response\", { result });\n\n const verified = result.verifiedIntents || [];\n\n // MCP contexts have no interactive UI for proposal cards — default to auto-approve\n const shouldAutoApprove = query.autoApprove ?? context.isMcp ?? false;\n \n // Extract trace from graph and convert to debugSteps\n const trace = Array.isArray(result.trace) ? result.trace : [];\n const debugSteps = trace.map((t: { node: string; detail?: string; data?: Record<string, unknown> }) => ({\n step: t.node,\n detail: t.detail,\n ...(t.data ? { data: t.data } : {}),\n }));\n \n if (verified.length === 0) {\n // Build a descriptive rejection reason from the trace so the ReACT agent\n // can retry with a better description or ask the user for clarification.\n // When inference produces 0 intents, propose mode exits before verification\n // runs — so we check inference trace first.\n const verificationTrace = debugSteps.find((s: { step: string; detail?: string }) => s.step === \"verification\");\n\n if (!verificationTrace) {\n const inferenceHint =\n debugSteps.find((s: { step: string; detail?: string }) => s.step === \"inference\")?.detail\n ?? \"no intents extracted\";\n return error(\n `No actionable intent was extracted (${inferenceHint}). ` +\n `Please retry with a more specific goal (what kind, what for, and/or timeframe), ` +\n `or ask the user to clarify.`,\n debugSteps,\n );\n }\n\n const rejectionHint =\n verificationTrace.detail ?? \"all candidate intents were filtered as invalid or too vague\";\n return error(\n `Intent verification failed (${rejectionHint}). ` +\n `The description may be too vague or was classified as a statement rather than a goal. ` +\n `Either retry with a more specific description (e.g. include what kind, what for, or a timeframe) ` +\n `or ask the user to clarify what exactly they are looking for.`,\n debugSteps,\n );\n }\n\n // ── Auto-approve path (for MCP agents or explicit opt-in) ──\n if (shouldAutoApprove) {\n const broadIntents = (verified as VerifiedIntent[]).filter(isBroadAttributiveIntent);\n if (broadIntents.length > 0) {\n const first = broadIntents[0];\n const missing = first.verification?.missing_selectional_constraints ?? [];\n const missingHint = missing.length > 0\n ? ` Missing specifics: ${missing.map((m) => m.replace(/_/g, \" \")).join(\", \")}.`\n : \"\";\n return error(\n `${specificityWarningFor(first)}${missingHint} ` +\n `Please ask the user to clarify before creating this signal, or retry with a narrower description.`,\n debugSteps,\n );\n }\n\n const createdIntents: Array<{ description: string; confidence: number | null; speechActType: string | null }> = [];\n const createTimings: Array<{ name: string; durationMs: number; agents: unknown[] }> = [];\n\n for (const v of verified as VerifiedIntent[]) {\n const _createGraphStart = Date.now();\n const createResult = await traceGraph(\"intent\", () => invokeWithAbortSignal(graphs.intent, {\n userId: context.userId,\n userProfile,\n inputContent: v.description,\n operationMode: 'create' as const,\n ...(effectiveIndexId ? { networkId: effectiveIndexId } : {}),\n }));\n const _createGraphMs = Date.now() - _createGraphStart;\n\n createTimings.push({ name: 'intent-create', durationMs: _createGraphMs, agents: createResult.agentTimings ?? [] });\n\n const succeeded = createResult.executionResults?.some((r: ExecutionResult) => r.success);\n if (succeeded) {\n createdIntents.push({\n description: v.description,\n confidence: v.score != null ? Math.round(v.score * 100) / 100 : null,\n speechActType: v.verification?.classification ?? null,\n });\n }\n }\n\n return success({\n created: createdIntents.length > 0,\n count: createdIntents.length,\n intents: createdIntents,\n message: createdIntents.length > 0\n ? `Created ${createdIntents.length} intent${createdIntents.length > 1 ? 's' : ''} successfully. The system will automatically index them and begin searching for matching opportunities.`\n : 'Intent creation failed — the intents could not be persisted.',\n debugSteps,\n _graphTimings: [\n { name: 'enrichment', durationMs: _profileGraphMs1, agents: profileResult.agentTimings ?? [] },\n { name: 'intent-propose', durationMs: _intentGraphMs1, agents: result.agentTimings ?? [] },\n ...createTimings,\n ],\n });\n }\n\n // ── Proposal path (for web chat with interactive cards) ──\n // Build intent_proposal code fences for each verified intent\n const proposalBlocks = verified.map((v: VerifiedIntent) => {\n const proposalId = crypto.randomUUID();\n const isBroad = isBroadAttributiveIntent(v);\n const data = {\n proposalId,\n description: v.description,\n ...(effectiveIndexId ? { networkId: effectiveIndexId } : {}),\n confidence: v.score != null ? Math.round(v.score * 100) / 100 : null,\n speechActType: v.verification?.classification ?? null,\n semanticEntropy: v.verification?.semantic_entropy ?? null,\n referentialBreadth: v.verification?.referential_breadth ?? null,\n missingSelectionalConstraints: v.verification?.missing_selectional_constraints ?? [],\n specificityWarning: isBroad ? specificityWarningFor(v) : normalizeSpecificityWarning(v.verification?.specificity_warning),\n };\n return (\n \"```intent_proposal\\n\" +\n sanitizeJsonForCodeFence(JSON.stringify(data)) +\n \"\\n```\"\n );\n });\n\n const blocksText = proposalBlocks.join(\"\\n\\n\");\n\n return success({\n proposed: true,\n count: verified.length,\n message: `IMPORTANT: Include the following \\`\\`\\`intent_proposal code blocks EXACTLY as-is in your response (they render as interactive cards for the user to approve or skip):\\n\\n${blocksText}`,\n debugSteps,\n _graphTimings: [\n { name: 'enrichment', durationMs: _profileGraphMs1, agents: profileResult.agentTimings ?? [] },\n { name: 'intent', durationMs: _intentGraphMs1, agents: result.agentTimings ?? [] },\n ],\n });\n },\n });\n\n const updateIntent = defineTool({\n name: \"update_intent\",\n description:\n \"Updates an existing intent's description. After updating, the system re-processes the intent through inference and verification, \" +\n \"re-evaluates its index assignments, and triggers fresh opportunity discovery with the new description.\\n\\n\" +\n \"**When to use:** When the user wants to refine or change what they're looking for — e.g. narrowing scope, adding specificity, \" +\n \"or pivoting to a different need. Prefer updating over delete+create to preserve the intent's history and existing index links.\\n\\n\" +\n \"**Returns:** Updated `intentId` and `description`, plus a confirmation message. The intent's embeddings and index relevancy scores are recalculated automatically.\",\n querySchema: z.object({\n intentId: z.string().describe(\"The UUID of the intent to update. Get this from read_intents results.\"),\n description: z.string().describe(\"The updated description of what the user is looking for. Same guidelines as create_intent — should be clear and specific.\"),\n }),\n handler: async ({ context, query }) => {\n const scopeErr = await ensureScopedMembership(context, deps.systemDb);\n if (scopeErr) return error(scopeErr);\n const intentId = query.intentId?.trim() ?? \"\";\n if (!UUID_REGEX.test(intentId)) {\n return error(\"Invalid intent ID format.\");\n }\n\n // Ownership guard: caller must own the intent\n const intent = await deps.systemDb.getIntent(intentId);\n if (!intent || intent.userId !== context.userId) {\n return error(\"Intent not found or you can only update your own intents.\");\n }\n if (intent.archivedAt) {\n return error(\"This intent is archived and cannot be updated. Create a new intent instead.\");\n }\n\n // Strict scope enforcement: when chat is index-scoped, verify intent is linked to that index\n if (context.networkId) {\n const db = deps.userDb;\n const intentNetworks = await db.getNetworkIdsForIntent(intentId);\n if (!intentNetworks.includes(context.networkId)) {\n return error(\n `This chat is scoped to ${context.indexName ?? 'this index'}. You can only update intents linked to this community.`\n );\n }\n }\n\n const _profileGraphStart2 = Date.now();\n const profileResult = await traceGraph(\"profile\", () => invokeWithAbortSignal(graphs.profile, { userId: context.userId, operationMode: 'query' as const }));\n const _profileGraphMs2 = Date.now() - _profileGraphStart2;\n const latestUser = profileResult.profile ? undefined : typeof userDb.getUser === \"function\" ? await userDb.getUser() : context.user;\n const approvedProfileFallback = profileResult.profile ? \"\" : buildApprovedProfileFallback(latestUser);\n const userProfile = profileResult.profile ? JSON.stringify(profileResult.profile) : approvedProfileFallback;\n\n const _intentGraphStart2 = Date.now();\n const result = await traceGraph(\"intent\", () => invokeWithAbortSignal(graphs.intent, {\n userId: context.userId,\n userProfile,\n operationMode: 'update' as const,\n inputContent: query.description,\n targetIntentIds: [intentId],\n ...(context.networkId && { networkId: context.networkId }),\n }));\n const _intentGraphMs2 = Date.now() - _intentGraphStart2;\n\n if (result.executionResults?.some((r: ExecutionResult) => !r.success)) {\n return error(\"Failed to update intent.\");\n }\n if (!result.executionResults?.some((r: ExecutionResult) => r.success)) {\n return error(\n \"Intent update was not applied. The new description may be too broad, too vague, or failed semantic verification. Please ask the user to clarify with a more concrete role, outcome, location, timeframe, domain, or specific need.\",\n );\n }\n return success({\n message: \"Intent updated.\",\n intentId,\n description: query.description,\n _graphTimings: [\n { name: 'enrichment', durationMs: _profileGraphMs2, agents: profileResult.agentTimings ?? [] },\n { name: 'intent', durationMs: _intentGraphMs2, agents: result.agentTimings ?? [] },\n ],\n });\n },\n });\n\n const deleteIntent = defineTool({\n name: \"delete_intent\",\n description:\n \"Archives (soft-deletes) an intent, removing it from active discovery. The intent is not permanently deleted — it is marked as archived \" +\n \"and no longer participates in opportunity matching or index evaluation.\\n\\n\" +\n \"**When to use:** When the user's need has been fulfilled, is no longer relevant, or was created by mistake. \" +\n \"If the user wants to change the description instead, use update_intent to preserve history.\\n\\n\" +\n \"**Returns:** Confirmation that the intent was archived. Previously created opportunities from this intent remain but won't generate new ones.\",\n querySchema: z.object({\n intentId: z.string().describe(\"The UUID of the intent to archive. Get this from read_intents results.\"),\n }),\n handler: async ({ context, query }) => {\n const scopeErr = await ensureScopedMembership(context, deps.systemDb);\n if (scopeErr) return error(scopeErr);\n const intentId = query.intentId?.trim() ?? \"\";\n if (!UUID_REGEX.test(intentId)) {\n return error(\"Invalid intent ID format.\");\n }\n\n // Ownership guard: caller must own the intent\n const intent = await deps.systemDb.getIntent(intentId);\n if (!intent || intent.userId !== context.userId) {\n return error(\"Intent not found or you can only delete your own intents.\");\n }\n\n // Strict scope enforcement: when chat is index-scoped, verify intent is linked to that index\n if (context.networkId) {\n const db = deps.userDb;\n const intentNetworks = await db.getNetworkIdsForIntent(intentId);\n if (!intentNetworks.includes(context.networkId)) {\n return error(\n `This chat is scoped to ${context.indexName ?? 'this index'}. You can only delete intents linked to this community.`\n );\n }\n }\n\n const _deleteIntentGraphStart = Date.now();\n const result = await traceGraph(\"intent\", () => invokeWithAbortSignal(graphs.intent, {\n userId: context.userId,\n userProfile: \"\",\n operationMode: 'delete' as const,\n targetIntentIds: [intentId],\n ...(context.networkId && { networkId: context.networkId }),\n }));\n const _deleteIntentGraphMs = Date.now() - _deleteIntentGraphStart;\n\n if (result.executionResults?.some((r: ExecutionResult) => !r.success)) {\n return error(\"Failed to delete intent.\");\n }\n return success({\n message: \"Intent archived successfully.\",\n _graphTimings: [{ name: 'intent', durationMs: _deleteIntentGraphMs, agents: result.agentTimings ?? [] }],\n });\n },\n });\n\n // ─────────────────────────────────────────────────────────────────────────────\n // INTENT–INDEX JUNCTION (link / list / unlink)\n // ─────────────────────────────────────────────────────────────────────────────\n\n const createIntentIndex = defineTool({\n name: \"create_intent_index\",\n description:\n \"Manually links an intent to an index (community), making it visible to other members and eligible for opportunity discovery within that index. \" +\n \"Normally intents are auto-assigned to relevant indexes on creation, but use this to explicitly add an intent to an additional index.\\n\\n\" +\n \"**When to use:** When the user wants to share an existing intent with a specific community they belong to, \" +\n \"or when auto-assignment missed an index the user considers relevant.\\n\\n\" +\n \"**Returns:** Confirmation that the link was created. The intent will now appear in that index's intent list and participate in discovery within that community.\",\n querySchema: z.object({\n intentId: z.string().describe(\"The UUID of the intent to link. Get this from read_intents results.\"),\n networkId: z.string().optional().describe(\"The UUID of the index to link the intent to. Get this from read_networks. Defaults to the scoped index in index-scoped chats.\"),\n }),\n handler: async ({ context, query }) => {\n const scopeErr = await ensureScopedMembership(context, deps.systemDb);\n if (scopeErr) return error(scopeErr);\n const intentId = query.intentId?.trim() ?? \"\";\n const networkId = query.networkId?.trim() || context.networkId || \"\";\n if (!UUID_REGEX.test(intentId) || !UUID_REGEX.test(networkId)) {\n return error(\"Invalid ID format. Both must be UUIDs.\");\n }\n\n // Strict scope enforcement: when chat is index-scoped, only allow linking to that index\n if (context.networkId && networkId !== context.networkId) {\n return error(\n `This chat is scoped to ${context.indexName ?? 'this index'}. You can only link intents to this community.`\n );\n }\n\n const _createIntentIndexGraphStart = Date.now();\n const result = await traceGraph(\"intent_network\", () => invokeWithAbortSignal(graphs.intentIndex, {\n userId: context.userId,\n networkId,\n intentId,\n operationMode: 'create' as const,\n skipEvaluation: true,\n }));\n const _createIntentIndexGraphMs = Date.now() - _createIntentIndexGraphStart;\n\n if (result.mutationResult) {\n if (result.mutationResult.success) {\n const alreadyExisted = result.mutationResult.message?.includes('already in this network') ?? false;\n return success({\n created: !alreadyExisted,\n message: result.mutationResult.message,\n _graphTimings: [{ name: 'intent_network', durationMs: _createIntentIndexGraphMs, agents: result.agentTimings ?? [] }],\n });\n }\n return error(result.mutationResult.error || \"Failed to link intent to network.\");\n }\n return error(\"Failed to link intent to network.\");\n },\n });\n\n const readIntentIndexes = defineTool({\n name: \"read_intent_indexes\",\n description:\n \"Reads the many-to-many links between intents and indexes. Use this to understand which intents are shared in which communities, \" +\n \"and which indexes a specific intent belongs to.\\n\\n\" +\n \"**Usage modes:**\\n\" +\n \"- With networkId: lists all intents linked to that index. Add userId to filter to one member's intents in that index.\\n\" +\n \"- With intentId + networkId: checks whether a specific intent is linked to a specific index.\\n\" +\n \"- intentId alone requires a networkId (the system won't reveal all indexes an intent is in).\\n\\n\" +\n \"**When to use:** To audit which intents are active in a community, verify an intent's index assignment before unlinking, \" +\n \"or check if a newly created intent was auto-assigned to the expected index.\\n\\n\" +\n \"**Returns:** List of intent-index links with relevancy scores (0-1, how well the intent fits the index's purpose).\",\n querySchema: z.object({\n intentId: z.string().optional().describe(\"Intent UUID — check if this specific intent is linked to the specified index. Must be combined with networkId.\"),\n networkId: z.string().optional().describe(\"Index UUID — list all intents linked to this index. Get this from read_networks. Defaults to scoped index in index-scoped chats.\"),\n userId: z.string().optional().describe(\"Filter results to this user's intents within the specified index. Omit to see all members' intents.\"),\n }),\n handler: async ({ context, query }) => {\n const scopeErr = await ensureScopedMembership(context, deps.systemDb);\n if (scopeErr) return error(scopeErr);\n const intentId = query.intentId?.trim() || undefined;\n let networkId = query.networkId?.trim() || context.networkId || undefined;\n const queryUserId = query.userId?.trim() || undefined;\n\n if (intentId && !UUID_REGEX.test(intentId)) {\n return error(\"Invalid intent ID format.\");\n }\n if (networkId && !UUID_REGEX.test(networkId)) {\n return error(\"Invalid network ID format.\");\n }\n if (!intentId && !networkId) {\n return error(\"Provide networkId or intentId.\");\n }\n\n // Strict scope enforcement: when chat is index-scoped, only allow querying that index\n if (context.networkId && networkId && networkId !== context.networkId) {\n return error(\n `This chat is scoped to ${context.indexName ?? 'this index'}. You can only read intent links from this community.`\n );\n }\n\n // When only intentId is provided, enforce scope - don't reveal all linked indexes\n if (intentId && !networkId) {\n if (context.networkId) {\n // When scoped, only check if intent is linked to the scoped index\n networkId = context.networkId;\n } else {\n // When unscoped, still don't reveal all indexes - require explicit networkId\n return error(\n \"Please provide a networkId to check if the intent is linked to a specific network. Listing all linked networks is not supported.\"\n );\n }\n }\n\n const _readIntentIndexGraphStart = Date.now();\n const result = await traceGraph(\"intent_network\", () => invokeWithAbortSignal(graphs.intentIndex, {\n userId: context.userId,\n networkId,\n intentId,\n operationMode: 'read' as const,\n queryUserId,\n }));\n const _readIntentIndexGraphMs = Date.now() - _readIntentIndexGraphStart;\n\n if (result.error) {\n return error(result.error);\n }\n if (result.readResult) {\n return success({ ...result.readResult, _graphTimings: [{ name: 'intent_network', durationMs: _readIntentIndexGraphMs, agents: result.agentTimings ?? [] }] });\n }\n return error(\"Failed to fetch intent-network links.\");\n },\n });\n\n const deleteIntentIndex = defineTool({\n name: \"delete_intent_index\",\n description:\n \"Removes the link between an intent and an index. The intent itself is NOT deleted — it just stops being visible in that community \" +\n \"and no longer participates in opportunity discovery within that index. The intent may still be linked to other indexes.\\n\\n\" +\n \"**When to use:** When the user wants to withdraw an intent from a specific community without archiving it entirely. \" +\n \"Use read_intent_indexes first to verify the link exists.\\n\\n\" +\n \"**Returns:** Confirmation that the link was removed. To fully remove an intent, use delete_intent instead.\",\n querySchema: z.object({\n intentId: z.string().describe(\"The UUID of the intent to unlink. Get this from read_intents or read_intent_indexes.\"),\n networkId: z.string().optional().describe(\"The UUID of the index to unlink from. Get this from read_networks. Defaults to the scoped index in index-scoped chats.\"),\n }),\n handler: async ({ context, query }) => {\n const scopeErr = await ensureScopedMembership(context, deps.systemDb);\n if (scopeErr) return error(scopeErr);\n const intentId = query.intentId?.trim() ?? \"\";\n const networkId = query.networkId?.trim() || context.networkId || \"\";\n if (!UUID_REGEX.test(intentId) || !UUID_REGEX.test(networkId)) {\n return error(\"Invalid ID format. Both must be UUIDs.\");\n }\n\n // Strict scope enforcement: when chat is index-scoped, only allow unlinking from that index\n if (context.networkId && networkId !== context.networkId) {\n return error(\n `This chat is scoped to ${context.indexName ?? 'this index'}. You can only unlink intents from this community.`\n );\n }\n\n const _deleteIntentIndexGraphStart = Date.now();\n const result = await traceGraph(\"intent_network\", () => invokeWithAbortSignal(graphs.intentIndex, {\n userId: context.userId,\n networkId,\n intentId,\n operationMode: 'delete' as const,\n }));\n const _deleteIntentIndexGraphMs = Date.now() - _deleteIntentIndexGraphStart;\n\n if (result.mutationResult) {\n if (result.mutationResult.success) {\n return success({\n deleted: true,\n message: result.mutationResult.message,\n _graphTimings: [{ name: 'intent_network', durationMs: _deleteIntentIndexGraphMs, agents: result.agentTimings ?? [] }],\n });\n }\n return error(result.mutationResult.error || \"Failed to unlink.\");\n }\n return error(\"Failed to unlink intent from network.\");\n },\n });\n\n const searchIntents = defineTool({\n name: \"search_intents\",\n description:\n \"Text-searches the authenticated user's own active signals by description. Case-insensitive substring \" +\n \"match over the signal's payload and summary. Use when the user references a past signal they wrote \" +\n '(\"find my signal about React mentorship\") or wants to audit what they\\'ve posted.\\n\\n' +\n \"For discovery of OTHER users' signals that match a query, use discover_opportunities(searchQuery=...) \" +\n \"instead — that runs semantic matching across the user's networks.\\n\\n\" +\n \"**Returns:** `intents: [{ id, payload, summary, createdAt }]`, most recent first, up to `limit` (default 25).\",\n querySchema: z.object({\n query: z.string().min(1).describe(\"Text to match against payload and summary (case-insensitive).\"),\n limit: z\n .number()\n .int()\n .positive()\n .max(100)\n .optional()\n .describe(\"Maximum intents to return (default 25, max 100).\"),\n }),\n handler: async ({ context, query }) => {\n const rows = await userDb.searchOwnIntents(query.query, query.limit ?? 25);\n logger.verbose(\"search_intents\", { userId: context.userId, query: query.query, matched: rows.length });\n return success({ intents: rows });\n },\n });\n\n return [readIntents, createIntent, updateIntent, deleteIntent, createIntentIndex, readIntentIndexes, deleteIntentIndex, searchIntents] as const;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"intent.tools.js","sourceRoot":"/","sources":["intent/intent.tools.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from \"zod\";\n\nimport type { ExecutionResult, VerifiedIntent } from \"./intent.state.js\";\nimport { DEFAULT_SPECIFICITY_WARNING } from \"./intent.specificity.js\";\nimport { protocolLogger } from \"../shared/observability/protocol.logger.js\";\nimport { traceGraph } from \"../shared/observability/trace.js\";\n\nimport type { DefineTool, ToolDeps } from \"../shared/agent/tool.helpers.js\";\nimport { success, error, UUID_REGEX } from \"../shared/agent/tool.helpers.js\";\nimport type { UserRecord } from \"../shared/interfaces/database.interface.js\";\nimport { invokeWithAbortSignal } from \"../shared/agent/model-signal.js\";\nimport { deriveAllowedNetworkIds, focusedNetworkId, focusedNetworkLabel, type ToolScopeEnvelope } from \"../shared/agent/tool.scope.js\";\n\nconst logger = protocolLogger(\"ChatTools:Intent\");\n\n/**\n * Sanitize JSON string for use inside a markdown code fence (```). Escapes backticks\n * so embedded ``` cannot close the fence prematurely.\n */\nfunction sanitizeJsonForCodeFence(json: string): string {\n return json.replace(/`/g, \"\\\\u0060\");\n}\n\n/** When context is index-scoped, verifies the caller is still a member of that index. Returns error message or null. */\nasync function ensureScopedMembership(\n context: ToolScopeEnvelope & { indexName?: string; userId: string },\n systemDb: ToolDeps['systemDb']\n): Promise<string | null> {\n const scopedNetworkId = focusedNetworkId(context);\n if (!scopedNetworkId) return null;\n const isMember = await systemDb.isNetworkMember(scopedNetworkId, context.userId);\n if (!isMember) {\n return `This chat is scoped to ${focusedNetworkLabel(context)}. You are no longer a member of this community.`;\n }\n return null;\n}\n\nfunction buildApprovedProfileFallback(user: UserRecord | null | undefined): string {\n const bio = user?.intro?.trim();\n if (!user || !bio) return \"\";\n\n return JSON.stringify({\n userId: user.id,\n identity: {\n name: user.name ?? \"\",\n bio,\n location: user.location?.trim() ?? \"\",\n },\n narrative: { context: bio },\n attributes: { skills: [], interests: [] },\n });\n}\n\nfunction isBroadAttributiveIntent(intent: VerifiedIntent): boolean {\n return intent.verification?.referential_breadth === \"broad\";\n}\n\nconst NULL_LIKE_SPECIFICITY_WARNING_VALUES = new Set([\"null\", \"undefined\"]);\n\nfunction normalizeSpecificityWarning(value: string | null | undefined): string | null {\n const warning = value?.trim();\n if (!warning) return null;\n return NULL_LIKE_SPECIFICITY_WARNING_VALUES.has(warning.toLowerCase()) ? null : warning;\n}\n\nfunction specificityWarningFor(intent: VerifiedIntent): string {\n return normalizeSpecificityWarning(intent.verification?.specificity_warning) ?? DEFAULT_SPECIFICITY_WARNING;\n}\n\nexport function createIntentTools(defineTool: DefineTool, deps: ToolDeps) {\n const { graphs, userDb } = deps;\n\n // ─────────────────────────────────────────────────────────────────────────────\n // INTENT CRUD\n // ─────────────────────────────────────────────────────────────────────────────\n\n const readIntents = defineTool({\n name: \"read_intents\",\n description:\n \"Retrieves intents (signals of interest/need, e.g. 'Looking for a React developer in Berlin'). \" +\n \"Intents are the core unit of discovery — they represent what users are seeking and drive semantic matching for opportunities.\\n\\n\" +\n \"**Usage modes:**\\n\" +\n \"- No parameters: returns the **caller's own** active intents. In an index-scoped chat the result is clamped to the reachable indexes (the bound index plus the user's personal index). In an unscoped chat the result spans all of the user's active intents. There is no implicit default to the scoped index — to browse the bound community's intents, pass `networkId` explicitly.\\n\" +\n \"- With networkId: returns **all members'** intents in that index (community browse path). Add userId to filter to one member.\\n\" +\n \"- With userId in an index-scoped chat: reads that member's intents in the bound index. The target user must be a member of that index.\\n\" +\n \"- With userId in an unscoped chat: only works for the current user (cannot read another user's global intents without an index scope).\\n\\n\" +\n \"**Workflow:** To explore what members of an index are looking for, first call read_network_memberships(networkId) to list members, \" +\n \"then read_intents(networkId) to see all intents in that community. \" +\n \"Each intent includes: id, description (payload), summary, confidence (0-1), inferenceType (explicit/implicit), status, and linked indexes.\\n\\n\" +\n \"**Returns:** Paginated list of intents with count. Use the intent IDs in subsequent calls to update_intent, delete_intent, or create_intent_index.\",\n querySchema: z.object({\n networkId: z.string().optional().describe(\"Index UUID — filters intents to this index (community browse path: returns all members' intents). There is no implicit default in index-scoped chats; omit to get caller-owned intents across the reachable indexes, or pass the scoped index UUID to browse community members. Get index IDs from read_networks.\"),\n userId: z.string().optional().describe(\"User ID — filters to this user's intents. In an index-scoped chat, this reads that member's intents in the bound index (no networkId required). In an unscoped chat, only the current user is allowed without networkId; cross-user reads require an index scope. Omit for caller-owned intents.\"),\n limit: z.number().int().min(1).max(100).optional().describe(\"Page size (1-100). Defaults to returning all results if omitted.\"),\n page: z.number().int().min(1).optional().describe(\"Page number (1-based). Only used when limit is also provided.\"),\n }),\n handler: async ({ context, query }) => {\n const scopeErr = await ensureScopedMembership(context, deps.systemDb);\n if (scopeErr) return error(scopeErr);\n\n // Distinguish \"explicit network browse\" from \"implicit scope-aware read\"\n const scopedNetworkId = focusedNetworkId(context);\n const scopedIndexLabel = focusedNetworkLabel(context);\n const explicitNetworkId = query.networkId?.trim();\n const explicitUserId = query.userId?.trim();\n\n // Validate explicit networkId format\n if (explicitNetworkId && !UUID_REGEX.test(explicitNetworkId)) {\n return error(\"Invalid network ID format.\");\n }\n\n // Strict scope enforcement: in a scoped chat, the only allowed explicit\n // networkId is the envelope's scoped network. Cross-network browse must\n // happen in a separate unscoped chat or a chat scoped to that network.\n if (scopedNetworkId && explicitNetworkId && explicitNetworkId !== scopedNetworkId) {\n return error(\n `This chat is scoped to ${scopedIndexLabel}. You can only read intents from this community.`\n );\n }\n\n // Cross-user read in scoped chat: target user must be a member of the scoped index\n if (scopedNetworkId && explicitUserId && explicitUserId !== context.userId) {\n const isInScopedIndex = await deps.systemDb.isNetworkMember(scopedNetworkId, explicitUserId);\n if (!isInScopedIndex) {\n return error(\n `This chat is scoped to ${scopedIndexLabel}. You can only read intents from members of this community.`\n );\n }\n }\n\n // Cross-user global read is disallowed without an index scope\n if (!explicitNetworkId && !scopedNetworkId && explicitUserId && explicitUserId !== context.userId) {\n return error(\"Cannot read another user's global intents. Use networkId to scope to a shared network.\");\n }\n\n // Membership check for explicit cross-network reads in unscoped chats\n if (!scopedNetworkId && explicitNetworkId) {\n const callerIsMember = await deps.systemDb.isNetworkMember(explicitNetworkId, context.userId);\n if (!callerIsMember) {\n return error(\"You can only read intents from indexes you are a member of.\");\n }\n }\n\n // ── Choose the read mode ──\n // 1. Explicit networkId (browse all members in that index) — pass networkId, optionally + queryUserId.\n // 2. Explicit userId in a scoped chat — read that user's intents in the bound network.\n // 3. Explicit userId in an unscoped chat — only self (cross-user rejected above); global \"my intents\".\n // 4. Implicit (no explicit network/user) in scoped chat — pass indexScope, no networkId.\n // 5. Implicit in unscoped chat — global getActiveIntents (caller's own).\n const graphInput: Record<string, unknown> = {\n userId: context.userId,\n userProfile: \"\",\n operationMode: 'read' as const,\n };\n\n if (explicitNetworkId) {\n graphInput.networkId = explicitNetworkId;\n if (explicitUserId) graphInput.queryUserId = explicitUserId;\n } else if (explicitUserId && scopedNetworkId) {\n // Scoped chat + userId: implicit network is the chat's bound network.\n // Membership of the target user was verified above.\n graphInput.networkId = scopedNetworkId;\n graphInput.queryUserId = explicitUserId;\n } else if (explicitUserId) {\n // Unscoped chat + userId: only allowed for self (others rejected above).\n graphInput.queryUserId = explicitUserId;\n graphInput.allUserIntents = true;\n } else if (scopedNetworkId) {\n // Scoped chat, implicit read: caller-only across reachable indexes.\n graphInput.indexScope = deriveAllowedNetworkIds({\n memberships: context.userNetworks,\n scopeType: 'network',\n scopeId: scopedNetworkId,\n });\n } else {\n // Unscoped, implicit read: caller's global intents.\n graphInput.allUserIntents = true;\n }\n\n const _readIntentGraphStart = Date.now();\n const result = await traceGraph(\"intent\", () => invokeWithAbortSignal(graphs.intent, graphInput));\n const _readIntentGraphMs = Date.now() - _readIntentGraphStart;\n\n if (result.readResult) {\n if (result.readResult.count === 0 && result.readResult.message && /not a member|Network not found/i.test(result.readResult.message)) {\n return error(result.readResult.message);\n }\n\n const shouldPaginate = query.limit !== undefined || query.page !== undefined;\n if (shouldPaginate && Array.isArray(result.readResult.intents)) {\n const limit = query.limit ?? 20;\n const page = query.page ?? 1;\n const offset = (page - 1) * limit;\n const pagedIntents = result.readResult.intents.slice(offset, offset + limit);\n return success({\n ...result.readResult,\n count: pagedIntents.length,\n totalCount: result.readResult.intents.length,\n limit,\n page,\n totalPages: Math.ceil(result.readResult.intents.length / limit),\n intents: pagedIntents,\n _graphTimings: [{ name: 'intent', durationMs: _readIntentGraphMs, agents: result.agentTimings ?? [] }],\n });\n }\n\n return success({ ...result.readResult, _graphTimings: [{ name: 'intent', durationMs: _readIntentGraphMs, agents: result.agentTimings ?? [] }] });\n }\n return error(\"Failed to fetch intents.\");\n },\n });\n\n const createIntent = defineTool({\n name: \"create_intent\",\n description:\n \"Creates a new intent (signal of interest/need) for the authenticated user. Intents drive the discovery engine — once created, \" +\n \"the system automatically evaluates them against indexes the user belongs to, links them to relevant communities, and begins \" +\n \"searching for matching opportunities (complementary intents from other users).\\n\\n\" +\n \"**What to pass:** A clear, concept-based description of what the user is looking for (e.g. 'Looking for an AI/ML co-founder in Berlin', \" +\n \"'Need a designer for a mobile app project'). If the user provided a URL, scrape it with scrape_url first and synthesize the content into a description.\\n\\n\" +\n \"**What happens:** The system runs inference (extracting structured intents), verification (checking specificity and speech-act type), \" +\n \"and returns a proposal widget. The proposal is NOT yet persisted — the user must approve it first.\\n\\n\" +\n \"**Returns:** An intent_proposal code block that MUST be included verbatim in the response. The frontend renders it as an interactive \" +\n \"card the user can approve or skip. On approval, the intent is persisted, indexed, and discovery begins.\\n\\n\" +\n \"**Next steps after approval:** The intent is automatically linked to relevant indexes. Call discover_opportunities(searchQuery) to explicitly trigger discovery, \" +\n \"or wait for background processing to find matches.\\n\\n\" +\n \"**Specificity gate.** Before calling this tool, judge whether the description is concrete enough to be \" +\n \"useful for matching. If the user says \\\"find a job\\\", \\\"meet people\\\", or \\\"learn something\\\", that's too \" +\n \"vague — FIRST call read_user_contexts() + read_intents() to understand their context, THEN propose a \" +\n \"refined version (\\\"Based on your background in X, did you mean 'Y'?\\\") and wait for confirmation before \" +\n \"calling create_intent. Specific asks (\\\"senior UX design role at a tech company in Berlin\\\") can go \" +\n \"directly to create_intent.\\n\\n\" +\n \"**URL handling.** If the user pastes a URL describing the intent (e.g. a job posting), call scrape_url \" +\n \"first with objective=\\\"Extract key details for an intent\\\", synthesize a conceptual description from the \" +\n \"content, then call create_intent with the synthesis. Exception: profile URLs (LinkedIn, GitHub, X) passed \" +\n \"to create_user_context are handled by that tool directly — do not scrape first.\",\n querySchema: z.object({\n description: z.string().describe(\"A clear, specific description of what the user is looking for. Should be concept-based, not a raw URL. If the user shared a URL, scrape it first with scrape_url and pass the synthesized content here. Vague descriptions will be rejected — include what kind, what for, and/or timeframe.\"),\n networkId: z.string().optional().describe(\"Index UUID to link the intent to upon creation. Defaults to the scoped index in index-scoped chats. Get index IDs from read_networks. If omitted, the system auto-assigns to relevant indexes based on their prompts.\"),\n autoApprove: z.boolean().optional().describe(\"When true, automatically persists all verified intents without returning proposal cards for manual approval. MCP agents SHOULD set this to true since there is no UI for card-based approval. Web chat agents should omit or set to false to get interactive proposal cards.\"),\n }),\n handler: async ({ context, query }) => {\n const scopeErr = await ensureScopedMembership(context, deps.systemDb);\n if (scopeErr) return error(scopeErr);\n if (!query.description?.trim()) {\n return error(\"Description is required.\");\n }\n\n const scopedNetworkId = focusedNetworkId(context);\n const scopedIndexLabel = focusedNetworkLabel(context);\n\n // Strict scope enforcement\n if (scopedNetworkId && query.networkId?.trim() && query.networkId.trim() !== scopedNetworkId) {\n return error(\n `This chat is scoped to ${scopedIndexLabel}. You can only create intents in this community.`\n );\n }\n\n const effectiveIndexId = scopedNetworkId || query.networkId?.trim() || undefined;\n const scopeEnvelope = scopedNetworkId\n ? { scopeType: 'network' as const, scopeId: scopedNetworkId }\n : {};\n\n // Fetch profile (the intent graph needs it for inference)\n const _profileGraphStart1 = Date.now();\n const profileResult = await traceGraph(\"profile\", () => invokeWithAbortSignal(graphs.profile, { userId: context.userId, operationMode: 'query' as const }));\n const _profileGraphMs1 = Date.now() - _profileGraphStart1;\n const latestUser = profileResult.profile ? undefined : typeof userDb.getUser === \"function\" ? await userDb.getUser() : context.user;\n const approvedProfileFallback = profileResult.profile ? \"\" : buildApprovedProfileFallback(latestUser);\n const userProfile = profileResult.profile ? JSON.stringify(profileResult.profile) : approvedProfileFallback;\n\n // Run inference + verification only (propose mode — no DB persistence)\n const _intentGraphStart1 = Date.now();\n const result = await traceGraph(\"intent\", () => invokeWithAbortSignal(graphs.intent, {\n userId: context.userId,\n userProfile,\n inputContent: query.description,\n operationMode: 'propose' as const,\n ...(effectiveIndexId ? { networkId: effectiveIndexId } : {}),\n ...scopeEnvelope,\n }));\n const _intentGraphMs1 = Date.now() - _intentGraphStart1;\n logger.debug(\"Intent graph propose response\", { result });\n\n const verified = result.verifiedIntents || [];\n\n // MCP contexts have no interactive UI for proposal cards — default to auto-approve\n const shouldAutoApprove = query.autoApprove ?? context.isMcp ?? false;\n \n // Extract trace from graph and convert to debugSteps\n const trace = Array.isArray(result.trace) ? result.trace : [];\n const debugSteps = trace.map((t: { node: string; detail?: string; data?: Record<string, unknown> }) => ({\n step: t.node,\n detail: t.detail,\n ...(t.data ? { data: t.data } : {}),\n }));\n \n if (verified.length === 0) {\n // Build a descriptive rejection reason from the trace so the ReACT agent\n // can retry with a better description or ask the user for clarification.\n // When inference produces 0 intents, propose mode exits before verification\n // runs — so we check inference trace first.\n const verificationTrace = debugSteps.find((s: { step: string; detail?: string }) => s.step === \"verification\");\n\n if (!verificationTrace) {\n const inferenceHint =\n debugSteps.find((s: { step: string; detail?: string }) => s.step === \"inference\")?.detail\n ?? \"no intents extracted\";\n return error(\n `No actionable intent was extracted (${inferenceHint}). ` +\n `Please retry with a more specific goal (what kind, what for, and/or timeframe), ` +\n `or ask the user to clarify.`,\n debugSteps,\n );\n }\n\n const rejectionHint =\n verificationTrace.detail ?? \"all candidate intents were filtered as invalid or too vague\";\n return error(\n `Intent verification failed (${rejectionHint}). ` +\n `The description may be too vague or was classified as a statement rather than a goal. ` +\n `Either retry with a more specific description (e.g. include what kind, what for, or a timeframe) ` +\n `or ask the user to clarify what exactly they are looking for.`,\n debugSteps,\n );\n }\n\n // ── Auto-approve path (for MCP agents or explicit opt-in) ──\n if (shouldAutoApprove) {\n const broadIntents = (verified as VerifiedIntent[]).filter(isBroadAttributiveIntent);\n if (broadIntents.length > 0) {\n const first = broadIntents[0];\n const missing = first.verification?.missing_selectional_constraints ?? [];\n const missingHint = missing.length > 0\n ? ` Missing specifics: ${missing.map((m) => m.replace(/_/g, \" \")).join(\", \")}.`\n : \"\";\n return error(\n `${specificityWarningFor(first)}${missingHint} ` +\n `Please ask the user to clarify before creating this signal, or retry with a narrower description.`,\n debugSteps,\n );\n }\n\n const createdIntents: Array<{ description: string; confidence: number | null; speechActType: string | null }> = [];\n const createTimings: Array<{ name: string; durationMs: number; agents: unknown[] }> = [];\n\n for (const v of verified as VerifiedIntent[]) {\n const _createGraphStart = Date.now();\n const createResult = await traceGraph(\"intent\", () => invokeWithAbortSignal(graphs.intent, {\n userId: context.userId,\n userProfile,\n inputContent: v.description,\n operationMode: 'create' as const,\n ...(effectiveIndexId ? { networkId: effectiveIndexId } : {}),\n ...scopeEnvelope,\n }));\n const _createGraphMs = Date.now() - _createGraphStart;\n\n createTimings.push({ name: 'intent-create', durationMs: _createGraphMs, agents: createResult.agentTimings ?? [] });\n\n const succeeded = createResult.executionResults?.some((r: ExecutionResult) => r.success);\n if (succeeded) {\n createdIntents.push({\n description: v.description,\n confidence: v.score != null ? Math.round(v.score * 100) / 100 : null,\n speechActType: v.verification?.classification ?? null,\n });\n }\n }\n\n return success({\n created: createdIntents.length > 0,\n count: createdIntents.length,\n intents: createdIntents,\n message: createdIntents.length > 0\n ? `Created ${createdIntents.length} intent${createdIntents.length > 1 ? 's' : ''} successfully. The system will automatically index them and begin searching for matching opportunities.`\n : 'Intent creation failed — the intents could not be persisted.',\n debugSteps,\n _graphTimings: [\n { name: 'enrichment', durationMs: _profileGraphMs1, agents: profileResult.agentTimings ?? [] },\n { name: 'intent-propose', durationMs: _intentGraphMs1, agents: result.agentTimings ?? [] },\n ...createTimings,\n ],\n });\n }\n\n // ── Proposal path (for web chat with interactive cards) ──\n // Build intent_proposal code fences for each verified intent\n const proposalBlocks = verified.map((v: VerifiedIntent) => {\n const proposalId = crypto.randomUUID();\n const isBroad = isBroadAttributiveIntent(v);\n const data = {\n proposalId,\n description: v.description,\n ...(effectiveIndexId ? { networkId: effectiveIndexId } : {}),\n confidence: v.score != null ? Math.round(v.score * 100) / 100 : null,\n speechActType: v.verification?.classification ?? null,\n semanticEntropy: v.verification?.semantic_entropy ?? null,\n referentialBreadth: v.verification?.referential_breadth ?? null,\n missingSelectionalConstraints: v.verification?.missing_selectional_constraints ?? [],\n specificityWarning: isBroad ? specificityWarningFor(v) : normalizeSpecificityWarning(v.verification?.specificity_warning),\n };\n return (\n \"```intent_proposal\\n\" +\n sanitizeJsonForCodeFence(JSON.stringify(data)) +\n \"\\n```\"\n );\n });\n\n const blocksText = proposalBlocks.join(\"\\n\\n\");\n\n return success({\n proposed: true,\n count: verified.length,\n message: `IMPORTANT: Include the following \\`\\`\\`intent_proposal code blocks EXACTLY as-is in your response (they render as interactive cards for the user to approve or skip):\\n\\n${blocksText}`,\n debugSteps,\n _graphTimings: [\n { name: 'enrichment', durationMs: _profileGraphMs1, agents: profileResult.agentTimings ?? [] },\n { name: 'intent', durationMs: _intentGraphMs1, agents: result.agentTimings ?? [] },\n ],\n });\n },\n });\n\n const updateIntent = defineTool({\n name: \"update_intent\",\n description:\n \"Updates an existing intent's description. After updating, the system re-processes the intent through inference and verification, \" +\n \"re-evaluates its index assignments, and triggers fresh opportunity discovery with the new description.\\n\\n\" +\n \"**When to use:** When the user wants to refine or change what they're looking for — e.g. narrowing scope, adding specificity, \" +\n \"or pivoting to a different need. Prefer updating over delete+create to preserve the intent's history and existing index links.\\n\\n\" +\n \"**Returns:** Updated `intentId` and `description`, plus a confirmation message. The intent's embeddings and index relevancy scores are recalculated automatically.\",\n querySchema: z.object({\n intentId: z.string().describe(\"The UUID of the intent to update. Get this from read_intents results.\"),\n description: z.string().describe(\"The updated description of what the user is looking for. Same guidelines as create_intent — should be clear and specific.\"),\n }),\n handler: async ({ context, query }) => {\n const scopeErr = await ensureScopedMembership(context, deps.systemDb);\n if (scopeErr) return error(scopeErr);\n const intentId = query.intentId?.trim() ?? \"\";\n if (!UUID_REGEX.test(intentId)) {\n return error(\"Invalid intent ID format.\");\n }\n\n // Ownership guard: caller must own the intent\n const intent = await deps.systemDb.getIntent(intentId);\n if (!intent || intent.userId !== context.userId) {\n return error(\"Intent not found or you can only update your own intents.\");\n }\n if (intent.archivedAt) {\n return error(\"This intent is archived and cannot be updated. Create a new intent instead.\");\n }\n\n const scopedNetworkId = focusedNetworkId(context);\n const scopedIndexLabel = focusedNetworkLabel(context);\n\n // Strict scope enforcement: when chat is index-scoped, verify intent is linked to that index\n if (scopedNetworkId) {\n const db = deps.userDb;\n const intentNetworks = await db.getNetworkIdsForIntent(intentId);\n if (!intentNetworks.includes(scopedNetworkId)) {\n return error(\n `This chat is scoped to ${scopedIndexLabel}. You can only update intents linked to this community.`\n );\n }\n }\n\n const _profileGraphStart2 = Date.now();\n const profileResult = await traceGraph(\"profile\", () => invokeWithAbortSignal(graphs.profile, { userId: context.userId, operationMode: 'query' as const }));\n const _profileGraphMs2 = Date.now() - _profileGraphStart2;\n const latestUser = profileResult.profile ? undefined : typeof userDb.getUser === \"function\" ? await userDb.getUser() : context.user;\n const approvedProfileFallback = profileResult.profile ? \"\" : buildApprovedProfileFallback(latestUser);\n const userProfile = profileResult.profile ? JSON.stringify(profileResult.profile) : approvedProfileFallback;\n\n const _intentGraphStart2 = Date.now();\n const result = await traceGraph(\"intent\", () => invokeWithAbortSignal(graphs.intent, {\n userId: context.userId,\n userProfile,\n operationMode: 'update' as const,\n inputContent: query.description,\n targetIntentIds: [intentId],\n ...(scopedNetworkId && { networkId: scopedNetworkId, scopeType: 'network' as const, scopeId: scopedNetworkId }),\n }));\n const _intentGraphMs2 = Date.now() - _intentGraphStart2;\n\n if (result.executionResults?.some((r: ExecutionResult) => !r.success)) {\n return error(\"Failed to update intent.\");\n }\n if (!result.executionResults?.some((r: ExecutionResult) => r.success)) {\n return error(\n \"Intent update was not applied. The new description may be too broad, too vague, or failed semantic verification. Please ask the user to clarify with a more concrete role, outcome, location, timeframe, domain, or specific need.\",\n );\n }\n return success({\n message: \"Intent updated.\",\n intentId,\n description: query.description,\n _graphTimings: [\n { name: 'enrichment', durationMs: _profileGraphMs2, agents: profileResult.agentTimings ?? [] },\n { name: 'intent', durationMs: _intentGraphMs2, agents: result.agentTimings ?? [] },\n ],\n });\n },\n });\n\n const deleteIntent = defineTool({\n name: \"delete_intent\",\n description:\n \"Archives (soft-deletes) an intent, removing it from active discovery. The intent is not permanently deleted — it is marked as archived \" +\n \"and no longer participates in opportunity matching or index evaluation.\\n\\n\" +\n \"**When to use:** When the user's need has been fulfilled, is no longer relevant, or was created by mistake. \" +\n \"If the user wants to change the description instead, use update_intent to preserve history.\\n\\n\" +\n \"**Returns:** Confirmation that the intent was archived. Previously created opportunities from this intent remain but won't generate new ones.\",\n querySchema: z.object({\n intentId: z.string().describe(\"The UUID of the intent to archive. Get this from read_intents results.\"),\n }),\n handler: async ({ context, query }) => {\n const scopeErr = await ensureScopedMembership(context, deps.systemDb);\n if (scopeErr) return error(scopeErr);\n const intentId = query.intentId?.trim() ?? \"\";\n if (!UUID_REGEX.test(intentId)) {\n return error(\"Invalid intent ID format.\");\n }\n\n // Ownership guard: caller must own the intent\n const intent = await deps.systemDb.getIntent(intentId);\n if (!intent || intent.userId !== context.userId) {\n return error(\"Intent not found or you can only delete your own intents.\");\n }\n\n const scopedNetworkId = focusedNetworkId(context);\n const scopedIndexLabel = focusedNetworkLabel(context);\n\n // Strict scope enforcement: when chat is index-scoped, verify intent is linked to that index\n if (scopedNetworkId) {\n const db = deps.userDb;\n const intentNetworks = await db.getNetworkIdsForIntent(intentId);\n if (!intentNetworks.includes(scopedNetworkId)) {\n return error(\n `This chat is scoped to ${scopedIndexLabel}. You can only delete intents linked to this community.`\n );\n }\n }\n\n const _deleteIntentGraphStart = Date.now();\n const result = await traceGraph(\"intent\", () => invokeWithAbortSignal(graphs.intent, {\n userId: context.userId,\n userProfile: \"\",\n operationMode: 'delete' as const,\n targetIntentIds: [intentId],\n ...(scopedNetworkId && { networkId: scopedNetworkId, scopeType: 'network' as const, scopeId: scopedNetworkId }),\n }));\n const _deleteIntentGraphMs = Date.now() - _deleteIntentGraphStart;\n\n if (result.executionResults?.some((r: ExecutionResult) => !r.success)) {\n return error(\"Failed to delete intent.\");\n }\n return success({\n message: \"Intent archived successfully.\",\n _graphTimings: [{ name: 'intent', durationMs: _deleteIntentGraphMs, agents: result.agentTimings ?? [] }],\n });\n },\n });\n\n // ─────────────────────────────────────────────────────────────────────────────\n // INTENT–INDEX JUNCTION (link / list / unlink)\n // ─────────────────────────────────────────────────────────────────────────────\n\n const createIntentIndex = defineTool({\n name: \"create_intent_index\",\n description:\n \"Manually links an intent to an index (community), making it visible to other members and eligible for opportunity discovery within that index. \" +\n \"Normally intents are auto-assigned to relevant indexes on creation, but use this to explicitly add an intent to an additional index.\\n\\n\" +\n \"**When to use:** When the user wants to share an existing intent with a specific community they belong to, \" +\n \"or when auto-assignment missed an index the user considers relevant.\\n\\n\" +\n \"**Returns:** Confirmation that the link was created. The intent will now appear in that index's intent list and participate in discovery within that community.\",\n querySchema: z.object({\n intentId: z.string().describe(\"The UUID of the intent to link. Get this from read_intents results.\"),\n networkId: z.string().optional().describe(\"The UUID of the index to link the intent to. Get this from read_networks. Defaults to the scoped index in index-scoped chats.\"),\n }),\n handler: async ({ context, query }) => {\n const scopeErr = await ensureScopedMembership(context, deps.systemDb);\n if (scopeErr) return error(scopeErr);\n const scopedNetworkId = focusedNetworkId(context);\n const scopedIndexLabel = focusedNetworkLabel(context);\n const intentId = query.intentId?.trim() ?? \"\";\n const networkId = query.networkId?.trim() || scopedNetworkId || \"\";\n if (!UUID_REGEX.test(intentId) || !UUID_REGEX.test(networkId)) {\n return error(\"Invalid ID format. Both must be UUIDs.\");\n }\n\n // Strict scope enforcement: when chat is index-scoped, only allow linking to that index\n if (scopedNetworkId && networkId !== scopedNetworkId) {\n return error(\n `This chat is scoped to ${scopedIndexLabel}. You can only link intents to this community.`\n );\n }\n\n const _createIntentIndexGraphStart = Date.now();\n const result = await traceGraph(\"intent_network\", () => invokeWithAbortSignal(graphs.intentIndex, {\n userId: context.userId,\n networkId,\n intentId,\n operationMode: 'create' as const,\n skipEvaluation: true,\n }));\n const _createIntentIndexGraphMs = Date.now() - _createIntentIndexGraphStart;\n\n if (result.mutationResult) {\n if (result.mutationResult.success) {\n const alreadyExisted = result.mutationResult.message?.includes('already in this network') ?? false;\n return success({\n created: !alreadyExisted,\n message: result.mutationResult.message,\n _graphTimings: [{ name: 'intent_network', durationMs: _createIntentIndexGraphMs, agents: result.agentTimings ?? [] }],\n });\n }\n return error(result.mutationResult.error || \"Failed to link intent to network.\");\n }\n return error(\"Failed to link intent to network.\");\n },\n });\n\n const readIntentIndexes = defineTool({\n name: \"read_intent_indexes\",\n description:\n \"Reads the many-to-many links between intents and indexes. Use this to understand which intents are shared in which communities, \" +\n \"and which indexes a specific intent belongs to.\\n\\n\" +\n \"**Usage modes:**\\n\" +\n \"- With networkId: lists all intents linked to that index. Add userId to filter to one member's intents in that index.\\n\" +\n \"- With intentId + networkId: checks whether a specific intent is linked to a specific index.\\n\" +\n \"- intentId alone requires a networkId (the system won't reveal all indexes an intent is in).\\n\\n\" +\n \"**When to use:** To audit which intents are active in a community, verify an intent's index assignment before unlinking, \" +\n \"or check if a newly created intent was auto-assigned to the expected index.\\n\\n\" +\n \"**Returns:** List of intent-index links with relevancy scores (0-1, how well the intent fits the index's purpose).\",\n querySchema: z.object({\n intentId: z.string().optional().describe(\"Intent UUID — check if this specific intent is linked to the specified index. Must be combined with networkId.\"),\n networkId: z.string().optional().describe(\"Index UUID — list all intents linked to this index. Get this from read_networks. Defaults to scoped index in index-scoped chats.\"),\n userId: z.string().optional().describe(\"Filter results to this user's intents within the specified index. Omit to see all members' intents.\"),\n }),\n handler: async ({ context, query }) => {\n const scopeErr = await ensureScopedMembership(context, deps.systemDb);\n if (scopeErr) return error(scopeErr);\n const scopedNetworkId = focusedNetworkId(context);\n const scopedIndexLabel = focusedNetworkLabel(context);\n const intentId = query.intentId?.trim() || undefined;\n let networkId = query.networkId?.trim() || scopedNetworkId || undefined;\n const queryUserId = query.userId?.trim() || undefined;\n\n if (intentId && !UUID_REGEX.test(intentId)) {\n return error(\"Invalid intent ID format.\");\n }\n if (networkId && !UUID_REGEX.test(networkId)) {\n return error(\"Invalid network ID format.\");\n }\n if (!intentId && !networkId) {\n return error(\"Provide networkId or intentId.\");\n }\n\n // Strict scope enforcement: when chat is index-scoped, only allow querying that index\n if (scopedNetworkId && networkId && networkId !== scopedNetworkId) {\n return error(\n `This chat is scoped to ${scopedIndexLabel}. You can only read intent links from this community.`\n );\n }\n\n // When only intentId is provided, enforce scope - don't reveal all linked indexes\n if (intentId && !networkId) {\n if (scopedNetworkId) {\n // When scoped, only check if intent is linked to the scoped index\n networkId = scopedNetworkId;\n } else {\n // When unscoped, still don't reveal all indexes - require explicit networkId\n return error(\n \"Please provide a networkId to check if the intent is linked to a specific network. Listing all linked networks is not supported.\"\n );\n }\n }\n\n const _readIntentIndexGraphStart = Date.now();\n const result = await traceGraph(\"intent_network\", () => invokeWithAbortSignal(graphs.intentIndex, {\n userId: context.userId,\n networkId,\n intentId,\n operationMode: 'read' as const,\n queryUserId,\n }));\n const _readIntentIndexGraphMs = Date.now() - _readIntentIndexGraphStart;\n\n if (result.error) {\n return error(result.error);\n }\n if (result.readResult) {\n return success({ ...result.readResult, _graphTimings: [{ name: 'intent_network', durationMs: _readIntentIndexGraphMs, agents: result.agentTimings ?? [] }] });\n }\n return error(\"Failed to fetch intent-network links.\");\n },\n });\n\n const deleteIntentIndex = defineTool({\n name: \"delete_intent_index\",\n description:\n \"Removes the link between an intent and an index. The intent itself is NOT deleted — it just stops being visible in that community \" +\n \"and no longer participates in opportunity discovery within that index. The intent may still be linked to other indexes.\\n\\n\" +\n \"**When to use:** When the user wants to withdraw an intent from a specific community without archiving it entirely. \" +\n \"Use read_intent_indexes first to verify the link exists.\\n\\n\" +\n \"**Returns:** Confirmation that the link was removed. To fully remove an intent, use delete_intent instead.\",\n querySchema: z.object({\n intentId: z.string().describe(\"The UUID of the intent to unlink. Get this from read_intents or read_intent_indexes.\"),\n networkId: z.string().optional().describe(\"The UUID of the index to unlink from. Get this from read_networks. Defaults to the scoped index in index-scoped chats.\"),\n }),\n handler: async ({ context, query }) => {\n const scopeErr = await ensureScopedMembership(context, deps.systemDb);\n if (scopeErr) return error(scopeErr);\n const scopedNetworkId = focusedNetworkId(context);\n const scopedIndexLabel = focusedNetworkLabel(context);\n const intentId = query.intentId?.trim() ?? \"\";\n const networkId = query.networkId?.trim() || scopedNetworkId || \"\";\n if (!UUID_REGEX.test(intentId) || !UUID_REGEX.test(networkId)) {\n return error(\"Invalid ID format. Both must be UUIDs.\");\n }\n\n // Strict scope enforcement: when chat is index-scoped, only allow unlinking from that index\n if (scopedNetworkId && networkId !== scopedNetworkId) {\n return error(\n `This chat is scoped to ${scopedIndexLabel}. You can only unlink intents from this community.`\n );\n }\n\n const _deleteIntentIndexGraphStart = Date.now();\n const result = await traceGraph(\"intent_network\", () => invokeWithAbortSignal(graphs.intentIndex, {\n userId: context.userId,\n networkId,\n intentId,\n operationMode: 'delete' as const,\n }));\n const _deleteIntentIndexGraphMs = Date.now() - _deleteIntentIndexGraphStart;\n\n if (result.mutationResult) {\n if (result.mutationResult.success) {\n return success({\n deleted: true,\n message: result.mutationResult.message,\n _graphTimings: [{ name: 'intent_network', durationMs: _deleteIntentIndexGraphMs, agents: result.agentTimings ?? [] }],\n });\n }\n return error(result.mutationResult.error || \"Failed to unlink.\");\n }\n return error(\"Failed to unlink intent from network.\");\n },\n });\n\n const searchIntents = defineTool({\n name: \"search_intents\",\n description:\n \"Text-searches the authenticated user's own active signals by description. Case-insensitive substring \" +\n \"match over the signal's payload and summary. Use when the user references a past signal they wrote \" +\n '(\"find my signal about React mentorship\") or wants to audit what they\\'ve posted.\\n\\n' +\n \"For discovery of OTHER users' signals that match a query, use discover_opportunities(searchQuery=...) \" +\n \"instead — that runs semantic matching across the user's networks.\\n\\n\" +\n \"**Returns:** `intents: [{ id, payload, summary, createdAt }]`, most recent first, up to `limit` (default 25).\",\n querySchema: z.object({\n query: z.string().min(1).describe(\"Text to match against payload and summary (case-insensitive).\"),\n limit: z\n .number()\n .int()\n .positive()\n .max(100)\n .optional()\n .describe(\"Maximum intents to return (default 25, max 100).\"),\n }),\n handler: async ({ context, query }) => {\n const rows = await userDb.searchOwnIntents(query.query, query.limit ?? 25);\n logger.verbose(\"search_intents\", { userId: context.userId, query: query.query, matched: rows.length });\n return success({ intents: rows });\n },\n });\n\n return [readIntents, createIntent, updateIntent, deleteIntent, createIntentIndex, readIntentIndexes, deleteIntentIndex, searchIntents] as const;\n}\n"]}
|