@indexnetwork/protocol 4.3.4-rc.310.1 → 4.3.4-rc.311.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.graph.d.ts +8 -8
- package/dist/chat/chat.state.d.ts +4 -3
- package/dist/chat/chat.state.d.ts.map +1 -1
- package/dist/chat/chat.state.js +2 -2
- package/dist/chat/chat.state.js.map +1 -1
- package/dist/chat/chat.streamer.d.ts +3 -2
- package/dist/chat/chat.streamer.d.ts.map +1 -1
- package/dist/chat/chat.streamer.js +2 -2
- package/dist/chat/chat.streamer.js.map +1 -1
- package/dist/intent/intent.graph.d.ts +5 -5
- package/dist/intent/intent.state.d.ts +2 -1
- package/dist/intent/intent.state.d.ts.map +1 -1
- package/dist/opportunity/feed/feed.graph.d.ts +10 -0
- package/dist/opportunity/feed/feed.graph.d.ts.map +1 -1
- package/dist/opportunity/feed/feed.graph.js +4 -0
- package/dist/opportunity/feed/feed.graph.js.map +1 -1
- package/dist/opportunity/feed/feed.state.d.ts +2 -0
- package/dist/opportunity/feed/feed.state.d.ts.map +1 -1
- package/dist/opportunity/feed/feed.state.js +8 -0
- package/dist/opportunity/feed/feed.state.js.map +1 -1
- package/dist/opportunity/opportunity.graph.d.ts +6 -6
- 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 +71 -4
- package/dist/opportunity/opportunity.tools.js.map +1 -1
- package/dist/premise/premise.graph.d.ts +4 -4
- package/dist/premise/premise.state.d.ts +2 -1
- package/dist/premise/premise.state.d.ts.map +1 -1
- package/dist/questioner/questioner.tools.d.ts.map +1 -1
- package/dist/questioner/questioner.tools.js +21 -8
- package/dist/questioner/questioner.tools.js.map +1 -1
- package/dist/shared/agent/tool.helpers.d.ts +9 -6
- package/dist/shared/agent/tool.helpers.d.ts.map +1 -1
- package/dist/shared/agent/tool.helpers.js.map +1 -1
- package/dist/shared/agent/tool.scope.d.ts +7 -1
- package/dist/shared/agent/tool.scope.d.ts.map +1 -1
- package/dist/shared/agent/tool.scope.js +10 -0
- package/dist/shared/agent/tool.scope.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/database.interface.d.ts +3 -0
- 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/questioner.interface.d.ts +3 -0
- package/dist/shared/interfaces/questioner.interface.d.ts.map +1 -1
- package/dist/shared/interfaces/questioner.interface.js.map +1 -1
- package/dist/shared/schemas/network-assignment.schema.d.ts +2 -2
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { requestContext } from "../shared/observability/request-context.js";
|
|
3
3
|
import { success, error, UUID_REGEX } from "../shared/agent/tool.helpers.js";
|
|
4
|
-
import { deriveDiscoveryNetworkIds, focusedNetworkId, focusedNetworkLabel } from "../shared/agent/tool.scope.js";
|
|
4
|
+
import { deriveDiscoveryNetworkIds, focusedIntentId, focusedNetworkId, focusedNetworkLabel } from "../shared/agent/tool.scope.js";
|
|
5
5
|
import { MINIMAL_MAIN_TEXT_MAX_CHARS, getPrimaryActionLabel, SECONDARY_ACTION_LABEL } from "./opportunity.labels.js";
|
|
6
6
|
import { viewerCentricCardSummary, narratorRemarkFromReasoning, stripUuids } from "./opportunity.presentation.js";
|
|
7
7
|
import { runDiscoverFromQuery, continueDiscovery } from "./opportunity.discover.js";
|
|
@@ -177,6 +177,13 @@ const UPDATE_OPPORTUNITY_BLOCKED_STATUSES = new Set([
|
|
|
177
177
|
"expired",
|
|
178
178
|
"negotiating",
|
|
179
179
|
]);
|
|
180
|
+
function matchesSelectedIntentScope(opportunity, viewerId, scope) {
|
|
181
|
+
if (scope?.scopeType !== 'intent' || !scope.scopeId)
|
|
182
|
+
return true;
|
|
183
|
+
if (opportunity.detection?.triggeredBy === scope.scopeId)
|
|
184
|
+
return true;
|
|
185
|
+
return opportunity.actors.some((actor) => actor.userId === viewerId && actor.intent === scope.scopeId);
|
|
186
|
+
}
|
|
180
187
|
/**
|
|
181
188
|
* Maximum number of opportunity cards to show per chat response.
|
|
182
189
|
* Sized for `selectByComposition` to fill both feed buckets — up to 3
|
|
@@ -515,7 +522,7 @@ export function createOpportunityTools(defineTool, deps) {
|
|
|
515
522
|
"'complementary skills for a startup'). Helps the evaluator produce better match reasoning."),
|
|
516
523
|
}),
|
|
517
524
|
handler: async ({ context, query }) => {
|
|
518
|
-
const scopedNetworkId = focusedNetworkId(context);
|
|
525
|
+
const scopedNetworkId = focusedNetworkId(context) ?? context.networkId?.trim();
|
|
519
526
|
const scopedIndexLabel = focusedNetworkLabel(context);
|
|
520
527
|
// Strict scope enforcement: when chat is network-scoped, only allow that index
|
|
521
528
|
if (scopedNetworkId &&
|
|
@@ -1301,13 +1308,21 @@ export function createOpportunityTools(defineTool, deps) {
|
|
|
1301
1308
|
.string()
|
|
1302
1309
|
.optional()
|
|
1303
1310
|
.describe("Network UUID to filter opportunities to a specific community. Get from read_networks. Defaults to the scoped network in network-scoped chats. Omit to see opportunities across all networks."),
|
|
1311
|
+
scopeType: z
|
|
1312
|
+
.enum(['intent'])
|
|
1313
|
+
.optional()
|
|
1314
|
+
.describe("Optional selected scope type. Use 'intent' to narrow listed opportunities to a selected intent."),
|
|
1315
|
+
scopeId: z
|
|
1316
|
+
.string()
|
|
1317
|
+
.optional()
|
|
1318
|
+
.describe("Selected intent UUID when scopeType is 'intent'. Ignored only when absent."),
|
|
1304
1319
|
includeDigestMarkers: z
|
|
1305
1320
|
.boolean()
|
|
1306
1321
|
.optional()
|
|
1307
1322
|
.describe("Internal scheduled-digest mode only. When true, includes hidden delivery markers so the digest send pass can confirm only edited-in opportunities."),
|
|
1308
1323
|
}),
|
|
1309
1324
|
handler: async ({ context, query }) => {
|
|
1310
|
-
const scopedNetworkId = focusedNetworkId(context);
|
|
1325
|
+
const scopedNetworkId = focusedNetworkId(context) ?? context.networkId?.trim();
|
|
1311
1326
|
const scopedIndexLabel = focusedNetworkLabel(context);
|
|
1312
1327
|
// Strict scope enforcement: when chat is network-scoped, only allow that index
|
|
1313
1328
|
if (scopedNetworkId &&
|
|
@@ -1319,6 +1334,25 @@ export function createOpportunityTools(defineTool, deps) {
|
|
|
1319
1334
|
if (effectiveIndexId && !UUID_REGEX.test(effectiveIndexId)) {
|
|
1320
1335
|
return error("Invalid network ID format.");
|
|
1321
1336
|
}
|
|
1337
|
+
const contextIntentId = focusedIntentId(context);
|
|
1338
|
+
const rawScopeId = query.scopeId?.trim() || undefined;
|
|
1339
|
+
if (query.scopeType === 'intent' && !rawScopeId) {
|
|
1340
|
+
return error("scopeId required when scopeType is intent.");
|
|
1341
|
+
}
|
|
1342
|
+
if (!query.scopeType && rawScopeId) {
|
|
1343
|
+
return error("scopeType=intent required when scopeId is provided.");
|
|
1344
|
+
}
|
|
1345
|
+
if (rawScopeId && !UUID_REGEX.test(rawScopeId)) {
|
|
1346
|
+
return error("Invalid scope ID format.");
|
|
1347
|
+
}
|
|
1348
|
+
if (contextIntentId && rawScopeId && contextIntentId !== rawScopeId) {
|
|
1349
|
+
return error("This chat is scoped to a different intent.");
|
|
1350
|
+
}
|
|
1351
|
+
const effectiveIntentScope = contextIntentId
|
|
1352
|
+
? { scopeType: 'intent', scopeId: contextIntentId }
|
|
1353
|
+
: query.scopeType === 'intent' && rawScopeId
|
|
1354
|
+
? { scopeType: 'intent', scopeId: rawScopeId }
|
|
1355
|
+
: {};
|
|
1322
1356
|
// The MCP/chat surface exposes actionable opportunities.
|
|
1323
1357
|
// `latent` is included so the introducer-as-viewer can see their unapproved
|
|
1324
1358
|
// connector-flow cards ("do you know someone for X?"). Other latent visibility
|
|
@@ -1331,6 +1365,7 @@ export function createOpportunityTools(defineTool, deps) {
|
|
|
1331
1365
|
// sort order can fill the whole window and starve the other section.
|
|
1332
1366
|
const fetched = await database.getOpportunitiesForUser(context.userId, {
|
|
1333
1367
|
networkId: effectiveIndexId,
|
|
1368
|
+
...effectiveIntentScope,
|
|
1334
1369
|
statuses,
|
|
1335
1370
|
limit: CHAT_FETCH_LIMIT,
|
|
1336
1371
|
});
|
|
@@ -1399,8 +1434,10 @@ export function createOpportunityTools(defineTool, deps) {
|
|
|
1399
1434
|
if (isDigestMode && deduped.length > 0) {
|
|
1400
1435
|
const acceptedCounterpartIds = new Set();
|
|
1401
1436
|
try {
|
|
1437
|
+
// effectiveIntentScope scopes the statuses: ["accepted"] suppression fetch.
|
|
1402
1438
|
const acceptedOpps = await database.getOpportunitiesForUser(context.userId, {
|
|
1403
1439
|
...(effectiveIndexId ? { networkId: effectiveIndexId } : {}),
|
|
1440
|
+
...effectiveIntentScope,
|
|
1404
1441
|
statuses: ["accepted"],
|
|
1405
1442
|
limit: ACCEPTED_SUPPRESSION_FETCH_LIMIT,
|
|
1406
1443
|
});
|
|
@@ -1789,12 +1826,39 @@ export function createOpportunityTools(defineTool, deps) {
|
|
|
1789
1826
|
.enum(["pending", "accepted", "rejected", "expired"])
|
|
1790
1827
|
.describe("New status: 'pending' = send the draft to the other party, 'accepted' = accept the connection, " +
|
|
1791
1828
|
"'rejected' = decline, 'expired' = mark as timed out."),
|
|
1829
|
+
scopeType: z
|
|
1830
|
+
.enum(['intent'])
|
|
1831
|
+
.optional()
|
|
1832
|
+
.describe("Optional selected scope type. Use 'intent' to require this opportunity to belong to a selected intent."),
|
|
1833
|
+
scopeId: z
|
|
1834
|
+
.string()
|
|
1835
|
+
.optional()
|
|
1836
|
+
.describe("Selected intent UUID when scopeType is 'intent'. Must match the chat's focused intent when one exists."),
|
|
1792
1837
|
}),
|
|
1793
1838
|
handler: async ({ context, query }) => {
|
|
1794
1839
|
const opportunityId = query.opportunityId?.trim();
|
|
1795
1840
|
if (!opportunityId || !UUID_REGEX.test(opportunityId)) {
|
|
1796
1841
|
return error("Valid opportunityId required.");
|
|
1797
1842
|
}
|
|
1843
|
+
const contextIntentId = focusedIntentId(context);
|
|
1844
|
+
const rawScopeId = query.scopeId?.trim() || undefined;
|
|
1845
|
+
if (query.scopeType === 'intent' && !rawScopeId) {
|
|
1846
|
+
return error("scopeId required when scopeType is intent.");
|
|
1847
|
+
}
|
|
1848
|
+
if (!query.scopeType && rawScopeId) {
|
|
1849
|
+
return error("scopeType=intent required when scopeId is provided.");
|
|
1850
|
+
}
|
|
1851
|
+
if (rawScopeId && !UUID_REGEX.test(rawScopeId)) {
|
|
1852
|
+
return error("Invalid scope ID format.");
|
|
1853
|
+
}
|
|
1854
|
+
if (contextIntentId && rawScopeId && contextIntentId !== rawScopeId) {
|
|
1855
|
+
return error("This chat is scoped to a different intent.");
|
|
1856
|
+
}
|
|
1857
|
+
const effectiveIntentScope = contextIntentId
|
|
1858
|
+
? { scopeType: 'intent', scopeId: contextIntentId }
|
|
1859
|
+
: query.scopeType === 'intent' && rawScopeId
|
|
1860
|
+
? { scopeType: 'intent', scopeId: rawScopeId }
|
|
1861
|
+
: {};
|
|
1798
1862
|
// Always fetch the opportunity — needed for actor guard and state machine
|
|
1799
1863
|
const opportunity = await systemDb.getOpportunity(opportunityId);
|
|
1800
1864
|
if (!opportunity) {
|
|
@@ -1816,13 +1880,16 @@ export function createOpportunityTools(defineTool, deps) {
|
|
|
1816
1880
|
// Mirrors the per-actor filter in getOpportunitiesForUser — relying on
|
|
1817
1881
|
// a focus-scope id or any-actor matches would let a counterpart's network
|
|
1818
1882
|
// presence shadow a viewer whose own actor is elsewhere.
|
|
1819
|
-
const scopedNetworkId = focusedNetworkId(context);
|
|
1883
|
+
const scopedNetworkId = focusedNetworkId(context) ?? context.networkId?.trim();
|
|
1820
1884
|
if (scopedNetworkId) {
|
|
1821
1885
|
const callerOnBoundNetwork = opportunity.actors?.some((a) => a.userId === context.userId && a.networkId === scopedNetworkId);
|
|
1822
1886
|
if (!callerOnBoundNetwork) {
|
|
1823
1887
|
return error("Opportunity not found.");
|
|
1824
1888
|
}
|
|
1825
1889
|
}
|
|
1890
|
+
if (!matchesSelectedIntentScope(opportunity, context.userId, effectiveIntentScope)) {
|
|
1891
|
+
return error("Opportunity not found.");
|
|
1892
|
+
}
|
|
1826
1893
|
const isSend = query.status === "pending";
|
|
1827
1894
|
const _updateGraphStart = Date.now();
|
|
1828
1895
|
const _updateTraceEmitter = requestContext.getStore()?.traceEmitter;
|