@indexnetwork/protocol 3.6.0-rc.256.1 → 3.6.0-rc.260.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.
@@ -1 +1 @@
1
- {"version":3,"file":"opportunity.tools.js","sourceRoot":"/","sources":["opportunity/opportunity.tools.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from \"zod\";\n\nimport { requestContext } from \"../shared/observability/request-context.js\";\n\nimport type { DefineTool, ToolDeps } from \"../shared/agent/tool.helpers.js\";\nimport { success, error, UUID_REGEX } from \"../shared/agent/tool.helpers.js\";\nimport { MINIMAL_MAIN_TEXT_MAX_CHARS, getPrimaryActionLabel, SECONDARY_ACTION_LABEL } from \"./opportunity.labels.js\";\nimport { viewerCentricCardSummary, narratorRemarkFromReasoning, stripUuids } from \"./opportunity.presentation.js\";\nimport { runDiscoverFromQuery, continueDiscovery } from \"./opportunity.discover.js\";\nimport { OpportunityPresenter, gatherPresenterContext, type PresenterDatabase } from \"./opportunity.presenter.js\";\n\nfunction stripLeadingNarratorName(remark: string, narratorName: string): string {\n let t = remark.trim();\n if (!t || !narratorName.trim()) return remark;\n const name = narratorName.trim();\n const nameLower = name.toLowerCase();\n for (;;) {\n const lower = t.toLowerCase();\n if (!lower.startsWith(nameLower)) break;\n // Require a word boundary after the name so a short name like \"Al\" does not\n // mangle a longer word (\"Always …\" → \"ways …\"). The char after the name must\n // be a separator (sentence/clause punctuation or whitespace) or end of string.\n // Keep this set in sync with the separator stripped from `rest` below.\n const boundary = t.charAt(name.length);\n if (boundary && !/[\\s.:,\\-–—]/.test(boundary)) break;\n const rest = t.slice(name.length).replace(/^\\s*[.:,\\-–—]\\s*/i, '').trim();\n if (rest.length === 0 || rest === t) break;\n t = rest;\n }\n return t;\n}\nimport type { EvaluatorEntity } from \"./opportunity.evaluator.js\";\nimport { protocolLogger } from \"../shared/observability/protocol.logger.js\";\nimport type { Opportunity, OpportunityStatus } from \"../shared/interfaces/database.interface.js\";\nimport type { DiscoveryRunInput } from \"../shared/interfaces/discovery-run.interface.js\";\nimport type { ConnectLinkKind } from \"../shared/interfaces/connect-link.interface.js\";\nimport { selectByComposition, deduplicateByPerson } from \"./opportunity.utils.js\";\nimport { mergePendingQuestions } from \"./opportunity.pending-questions.js\";\nimport { invokeWithAbortSignal } from \"../shared/agent/model-signal.js\";\n\nconst logger = protocolLogger(\"ChatTools:Opportunity\");\n\n/**\n * Pure status × role → ConnectLinkKind matrix.\n *\n * Returns the kind of short-link the viewer can act on directly, or `null` if\n * no direct link makes sense for this combination. Non-null kinds map to:\n *\n * - `connect` — pending opp where viewer is a non-introducer party. Clicking\n * flips the opp to accepted and opens the chat with the counterpart.\n * - `approve_introduction` — draft or latent opp where viewer is an unapproved\n * introducer. Clicking flips approved=true and triggers negotiation. The\n * `draft` case comes from `discover_opportunities` intro mode; the `latent`\n * case comes from background-discovered connector-flow cards surfaced in\n * `list_opportunities`. In both, status remains pre-send and the `/c/<code>`\n * link is the only MCP path to approve.\n * - `outreach` — accepted opp where viewer is a non-introducer party.\n * Clicking opens the existing chat (no state change).\n * - `send_direct` — draft or latent opp where viewer is a non-introducer\n * party. Issued by `discover_opportunities` in direct (no-introducer)\n * mode: the match has already passed evaluation, the row exists in\n * draft state, and the sender just needs to release it. Clicking flips\n * the opp straight to accepted and opens the chat with a greeting —\n * same handler path as `connect`. The counterpart's side sees the new\n * accepted opp and can engage or ignore.\n */\nexport function resolveActionableLinkKind(input: {\n status: string;\n viewerRole: string;\n viewerApproved?: boolean;\n}): ConnectLinkKind | null {\n const { status, viewerRole, viewerApproved } = input;\n const isIntroducer = viewerRole === \"introducer\";\n if (status === \"accepted\") {\n return isIntroducer ? null : \"outreach\";\n }\n if (status === \"pending\") {\n return isIntroducer ? null : \"connect\";\n }\n if (status === \"draft\" || status === \"latent\") {\n if (!isIntroducer) return \"send_direct\";\n return viewerApproved === true ? null : \"approve_introduction\";\n }\n return null;\n}\n\n/**\n * Build the agent-facing profile link for a counterpart — always the Index web\n * profile URL with `?link_preview=false`. Returns `undefined` only if\n * `frontendUrl` is not configured.\n *\n * The `?link_preview=false` hint is honored by chat-gateway runtimes (e.g.\n * OpenClaw's Telegram delivery) that strip link previews when present in the\n * URL; consistent placement matters more than Telegram's own handling.\n *\n * Trailing slashes on frontendUrl are stripped before concatenation.\n */\nexport function buildProfileUrl(\n counterpartUserId: string,\n frontendUrl: string | undefined,\n): string | undefined {\n // The profile link is always the Index web profile, regardless of the\n // counterpart's socials or the viewer's surface. Surface-aware Telegram\n // deep-linking lives on the connect URL (`/c/:code`) — the connect-link\n // controller resolves that to a pre-messaged t.me link — never here.\n if (!frontendUrl) return undefined;\n const base = frontendUrl.replace(/\\/+$/, \"\");\n return `${base}/u/${counterpartUserId}?link_preview=false`;\n}\n\n/**\n * Mint a short-link for `card` if the (status, viewerRole, viewerApproved)\n * combination is actionable; mutate the card in place with `acceptUrl`,\n * `profileUrl`, and `feedCategory`. No-op (and no DB call) if not actionable.\n *\n * Swallows mint errors after logging — the card is still returned without an\n * `acceptUrl`, matching the prior `list_opportunities` resilience behavior.\n */\nexport async function attachActionableLinks(\n card: Record<string, unknown> & {\n opportunityId: string;\n viewerRole: string;\n status: string;\n },\n opts: {\n viewerId: string;\n viewerApproved?: boolean;\n counterpartUserId: string;\n mintConnectLink: NonNullable<ToolDeps[\"mintConnectLink\"]>;\n frontendUrl: string | undefined;\n preferredSurface?: 'telegram' | 'web';\n },\n): Promise<void> {\n // profileUrl is independent of whether the (status, viewerRole) combination\n // is actionable — every counterpart has a profile page worth linking to,\n // even on a fresh draft where there is no acceptUrl yet. Setting it before\n // the early-return below means cards from non-actionable combinations\n // (e.g. draft + party in `discover_opportunities` direct mode) still carry\n // the profile link the agent needs to render. Without this, the agent gets\n // a name with no URL attached and tends to fabricate one.\n const profileUrl = buildProfileUrl(opts.counterpartUserId, opts.frontendUrl);\n if (profileUrl) card.profileUrl = profileUrl;\n\n const kind = resolveActionableLinkKind({\n status: card.status,\n viewerRole: card.viewerRole,\n viewerApproved: opts.viewerApproved,\n });\n logger.info(\"Opportunity actionability decision\", {\n opportunityId: card.opportunityId,\n status: card.status,\n viewerRole: card.viewerRole,\n viewerApproved: opts.viewerApproved,\n kind: kind ?? \"none\",\n });\n if (kind === null) return;\n\n try {\n const { url } = await opts.mintConnectLink({\n userId: opts.viewerId,\n opportunityId: card.opportunityId,\n kind,\n greeting: null,\n preferredSurface: opts.preferredSurface,\n });\n card.acceptUrl = url;\n card.feedCategory = card.viewerRole === \"introducer\" ? \"connector-flow\" : \"connection\";\n } catch (err) {\n logger.warn(\n \"Failed to mint MCP opportunity link — surfacing card without acceptUrl/feedCategory; profileUrl is still attached\",\n {\n opportunityId: card.opportunityId,\n kind,\n error: err instanceof Error ? err.message : String(err),\n },\n );\n }\n}\n\n/**\n * Statuses for which `update_opportunity` must refuse mutations.\n * - `accepted` / `rejected` / `expired`: terminal outcomes.\n * - `negotiating`: in-flight system-driven turn; user-driven mutations would\n * race the negotiation graph. The graph itself transitions out of this state.\n */\nconst UPDATE_OPPORTUNITY_BLOCKED_STATUSES = new Set<OpportunityStatus>([\n \"accepted\",\n \"rejected\",\n \"expired\",\n \"negotiating\",\n]);\n\n/**\n * Maximum number of opportunity cards to show per chat response.\n * Sized for `selectByComposition` to fill both feed buckets — up to 3\n * connection + 3 connector-flow per the digest/ambient prompt rules.\n */\nconst CHAT_DISPLAY_LIMIT = 6;\n\n/**\n * Wider fetch budget so `selectByComposition` has both buckets to balance\n * across, even when one category dominates the natural sort order.\n */\nconst CHAT_FETCH_LIMIT = 30;\n\n/** Markdown code fence (three backticks). Avoids embedding ``` in string literals so TS parser stays in sync. */\nconst CODE_FENCE = String.fromCharCode(96, 96, 96);\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/**\n * Build minimal opportunity card data for chat without calling the LLM presenter.\n * Uses only required fields from the opportunity record and counterpart name/avatar\n * so list_opportunities and discovery return quickly.\n *\n * Note: narratorChip.text is generated via regex heuristics (narratorRemarkFromReasoning)\n * rather than the OpportunityPresenter LLM. If narrator quality becomes an issue again,\n * consider making this function async and delegating to OpportunityPresenter.presentHomeCard()\n * which already produces a high-quality narratorRemark via LLM (used by the home graph\n * and discovery pipeline). The trade-off is 5-20s latency per card.\n *\n * Exported for use in tests (opportunity.tools.spec.ts).\n */\nexport function buildMinimalOpportunityCard(\n opp: Opportunity,\n viewerId: string,\n counterpartUserId: string,\n counterpartName: string,\n counterpartAvatar: string | null,\n introducerName?: string | null,\n introducerAvatar?: string | null,\n viewerName?: string,\n secondPartyName?: string,\n secondPartyAvatar?: string | null,\n secondPartyUserId?: string,\n isCounterpartGhost?: boolean,\n): {\n opportunityId: string;\n userId: string;\n name: string;\n avatar: string | null;\n mainText: string;\n cta: string;\n headline: string;\n primaryActionLabel: string;\n secondaryActionLabel: string;\n mutualIntentsLabel: string;\n narratorChip: { name: string; text: string; avatar?: string | null; userId?: string };\n viewerRole: string;\n score: number | undefined;\n status: string;\n isGhost: boolean;\n secondParty?: { name: string; avatar?: string | null; userId?: string };\n} {\n const viewerActor = opp.actors.find((a) => a.userId === viewerId);\n const viewerRole = viewerActor?.role ?? \"party\";\n const introducerActor = opp.actors.find(\n (a) => a.role === \"introducer\" && a.userId !== viewerId,\n );\n const viewerIsIntroducer = opp.actors.some(\n (a) => a.role === \"introducer\" && a.userId === viewerId,\n );\n const reasoning = opp.interpretation?.reasoning ?? \"\";\n const mainText = viewerCentricCardSummary(\n reasoning,\n counterpartName,\n MINIMAL_MAIN_TEXT_MAX_CHARS,\n viewerName,\n introducerName ?? undefined,\n );\n const score =\n typeof opp.interpretation?.confidence === \"number\"\n ? opp.interpretation.confidence\n : undefined;\n const narratorName = viewerIsIntroducer\n ? \"You\"\n : introducerName?.trim() || (introducerActor ? \"Someone\" : \"Index\");\n const primaryActionLabel = getPrimaryActionLabel(viewerRole);\n return {\n opportunityId: opp.id,\n userId: counterpartUserId,\n name: counterpartName,\n avatar: counterpartAvatar,\n mainText,\n cta: \"Start a conversation to connect.\",\n headline: viewerIsIntroducer && secondPartyName\n ? `${counterpartName} → ${secondPartyName}`\n : `Connection with ${counterpartName}`,\n primaryActionLabel,\n secondaryActionLabel: SECONDARY_ACTION_LABEL,\n mutualIntentsLabel: \"Suggested connection\",\n narratorChip: {\n name: narratorName,\n text: narratorRemarkFromReasoning(reasoning, counterpartName, viewerName),\n ...(viewerIsIntroducer\n ? { userId: viewerId, avatar: null }\n : introducerActor\n ? { userId: introducerActor.userId, avatar: introducerAvatar ?? null }\n : {}),\n },\n viewerRole,\n score,\n status: opp.status ?? \"latent\",\n isGhost: isCounterpartGhost ?? false,\n ...(viewerIsIntroducer && secondPartyName\n ? {\n secondParty: {\n name: secondPartyName,\n ...(secondPartyAvatar != null ? { avatar: secondPartyAvatar } : {}),\n ...(secondPartyUserId ? { userId: secondPartyUserId } : {}),\n },\n }\n : {}),\n };\n}\n\n/**\n * Minimal shape consumed by buildOpportunityPresentation for prose rendering.\n * Card data objects in the codebase carry additional frontend-only fields;\n * only these are surfaced to MCP agents.\n */\ntype OpportunityCardLike = Record<string, unknown> & {\n opportunityId: string;\n userId?: string | undefined;\n name?: string | undefined;\n mainText?: string | undefined;\n digestSummary?: string | undefined;\n status?: string | undefined;\n feedCategory?: string | undefined;\n acceptUrl?: string | undefined;\n profileUrl?: string | undefined;\n score?: number | undefined;\n};\n\n/**\n * Format opportunity cards into the \"opportunities\" portion of a tool response.\n *\n * Web chat (`isMcp=false`): emits ```opportunity``` code fences with an\n * \"include EXACTLY as-is\" directive so the frontend card renderer can parse\n * and render interactive cards.\n *\n * MCP (`isMcp=true`): emits prose (name, reason, status, profileUrl when\n * present, acceptUrl when present, feedCategory when present) and includes\n * `opportunityId` ONLY for cards without an `acceptUrl` — exposing the UUID\n * alongside an actionable link gave LLMs a foothold to hallucinate bare\n * `/api/opportunities/<id>/connect` URLs (see IND-271). The trailing\n * instruction reminds the agent to synthesize in natural language and never\n * fabricate URLs for cards that don't have them. MCP clients have no card\n * renderer, so code fences would surface as raw JSON to end users.\n */\nexport function buildOpportunityPresentation(\n cards: OpportunityCardLike[],\n opts: {\n isMcp: boolean;\n leadIn: string;\n label?: \"opportunity\" | \"opportunities\";\n /** Include hidden digest metadata markers so scheduled brief tooling can confirm delivery. */\n includeDigestMarkers?: boolean;\n },\n): string {\n if (cards.length === 0) return opts.leadIn;\n\n if (opts.isMcp) {\n const prose = cards\n .map((card, i) => {\n const lines: string[] = [`${i + 1}. ${card.name ?? \"Unknown\"}`];\n if (opts.includeDigestMarkers) {\n const markerId = String(card.opportunityId).replace(/[\\s>]/g, \"\");\n if (markerId) lines.push(` <!-- digest-opportunity:id=${markerId} -->`);\n }\n if (opts.includeDigestMarkers && card.digestSummary) {\n lines.push(` ${card.digestSummary}`);\n } else if (card.mainText) {\n lines.push(` ${card.mainText}`);\n }\n if (card.status) lines.push(` status: ${card.status}`);\n if (card.profileUrl) lines.push(` profileUrl: ${card.profileUrl}`);\n if (card.acceptUrl) lines.push(` acceptUrl: ${card.acceptUrl}`);\n if (card.feedCategory) lines.push(` feedCategory: ${card.feedCategory}`);\n if (opts.includeDigestMarkers && card.score != null) lines.push(` confidence: ${Math.round(card.score * 100)}`);\n // Only surface opportunityId when there's no acceptUrl. Exposing the\n // UUID alongside an actionable link gives the LLM a foothold to\n // hallucinate bare `/api/opportunities/<id>/connect` URLs.\n if (!card.acceptUrl) {\n lines.push(` opportunityId: ${card.opportunityId}`);\n }\n return lines.join(\"\\n\");\n })\n .join(\"\\n\\n\");\n const hasLinks = cards.some((c) => c.acceptUrl);\n const hasOpportunityIds = cards.some((c) => !c.acceptUrl);\n const linkInstructions = hasLinks\n ? `For each card that has an acceptUrl, embed it on a short verb phrase (e.g. \"message [Name]\" for connection, \"make intro\" for connector-flow). For each card that has a profileUrl, link the person's name to it. Some cards may have neither — render those as plain text and never fabricate URLs for them. The acceptUrl is opaque and self-contained — embed it verbatim. Do NOT append, encode, or modify any part of any URL. Never render link strips or tables — weave URLs into prose. `\n : \"\";\n const idInstructions = hasOpportunityIds\n ? `Use opportunityId values only when calling update_opportunity (send/accept/reject) or confirm_opportunity_delivery.`\n : \"\";\n return (\n `${opts.leadIn}\\n\\n${prose}\\n\\n` +\n `Summarize these for the user in natural prose — mention first names and a brief match reason per connection. ` +\n `${linkInstructions}` +\n `Do NOT print raw JSON, field labels, or opportunityIds. ` +\n `${idInstructions}`\n );\n }\n\n const label = opts.label ?? (cards.length === 1 ? \"opportunity\" : \"opportunities\");\n const blocks = cards\n .map(\n (card) =>\n CODE_FENCE + \"opportunity\\n\" + sanitizeJsonForCodeFence(JSON.stringify(card)) + \"\\n\" + CODE_FENCE,\n )\n .join(\"\\n\\n\");\n return (\n `${opts.leadIn} IMPORTANT: Include the following ${CODE_FENCE}${label} code blocks EXACTLY as-is in your response (they render as interactive cards):\\n\\n${blocks}`\n );\n}\n\n/**\n * Stable signature of a discovery request, used to coalesce duplicate MCP runs.\n * Two requests with the same signature describe the same discovery and should\n * share a single in-flight run rather than each spawning a fresh (expensive)\n * opportunity-graph execution. Text fields are normalized (trim + lowercase);\n * id lists are sorted so ordering does not matter.\n *\n * Encoded as JSON of a normalized object — NOT a delimiter join — so a\n * user-supplied string containing the delimiter can never make two distinct\n * requests collide. `hint` and each entity's `networkId` are included because\n * they change the discovery result (different reason / different shared index),\n * so requests that differ only in those must NOT coalesce. Natural-language\n * fields (`searchQuery`, `hint`) are lowercased; identifiers and the opaque\n * `continueFrom` pagination token are only trimmed (case-sensitive) so distinct\n * tokens never collapse together.\n */\nfunction discoveryRunSignature(input: DiscoveryRunInput, scopeKey: string): string {\n const text = (s?: string) => (s ?? \"\").trim().toLowerCase();\n const id = (s?: string) => (s ?? \"\").trim();\n // Encode each entity as a JSON tuple string, then sort the strings — a stable\n // total order with a correct comparator (default Array#sort on strings).\n const entities = [...(input.entities ?? [])]\n .map((e) => JSON.stringify([id(e.networkId), id(e.userId)]))\n .sort();\n return JSON.stringify({\n searchQuery: text(input.searchQuery),\n networkId: id(input.networkId),\n intentId: id(input.intentId),\n targetUserId: id(input.targetUserId),\n introTargetUserId: id(input.introTargetUserId),\n continueFrom: id(input.continueFrom),\n hint: text(input.hint),\n partyUserIds: [...(input.partyUserIds ?? [])].map((x) => x.trim()).sort(),\n entities,\n scope: scopeKey,\n });\n}\n\n/**\n * Stable key for the resolved discovery scope of a request. Two requests\n * coalesce only when they resolve to the same reach — the focus index\n * (`networkId`) and the full reachable `indexScope` set. When `query.networkId`\n * is omitted, scope comes from context (network-scoped agent vs unscoped\n * session), so folding it into the signature prevents a scoped caller from\n * coalescing onto an unscoped run and receiving out-of-scope opportunities.\n */\nfunction discoveryScopeKey(ctx: { networkId?: string; indexScope?: string[] }): string {\n return JSON.stringify({\n networkId: (ctx.networkId ?? \"\").trim(),\n indexScope: [...(ctx.indexScope ?? [])].map((s) => s.trim()).sort(),\n });\n}\n\nexport function createOpportunityTools(defineTool: DefineTool, deps: ToolDeps) {\n const { database, userDb, systemDb, graphs, cache } = deps;\n\n const discoverOpportunities = defineTool({\n name: \"discover_opportunities\",\n description:\n \"Discovers opportunities — connections between users based on complementary intents — and persists them as drafts. \" +\n \"Opportunities are the core output of the discovery engine, representing potential valuable connections between people.\\n\\n\" +\n \"**NOT for person lookup** — use read_user_profiles(query=name) to find people by name.\\n\\n\" +\n \"**Four modes:**\\n\" +\n \"1. **Discovery** (most common): pass `searchQuery` and/or `networkId`. The system finds other users in shared indexes \" +\n \"whose intents semantically complement the query. Uses HyDE embeddings and LLM evaluation for scoring.\\n\" +\n \"2. **Introduction**: pass `partyUserIds` (2+ user IDs) + `entities` (pre-gathered profiles and intents from shared indexes). \" +\n \"You MUST call read_user_profiles and read_intents for each party BEFORE calling this. \" +\n \"Optionally pass `hint` with the user's reason for the introduction.\\n\" +\n \"3. **Direct connection**: pass `targetUserId` + `searchQuery`. Creates an opportunity between the current user and one specific person.\\n\" +\n \"4. **Introducer discovery**: pass `introTargetUserId` (find matches FOR that person; current user becomes the introducer). \" +\n \"Use when user asks 'who should I introduce to [person]?'\\n\\n\" +\n \"**Returns:** In regular chat, opportunity code blocks (render as interactive cards) with opportunityId, match reasoning, confidence score, and status. \" +\n \"In MCP contexts, starts an async discovery run and returns `discoveryRunId` with status `queued`. \" +\n \"Then poll get_discovery_run with that id roughly every 5 seconds until status is `succeeded`, `failed`, or `cancelled`, and present its `result`. \" +\n \"Do NOT call discover_opportunities again for the same request while a run is in progress — a repeat call with the same parameters \" +\n \"returns the SAME in-progress run (with `coalesced: true`), not a new one. Keep polling the run id instead of starting new runs. \" +\n \"All results start as drafts. Supports pagination via `continueFrom` for large result sets.\\n\\n\" +\n \"**Next steps:** Use update_opportunity(opportunityId, status='pending') to send a draft to the other party.\\n\\n\" +\n \"**Discovery-first rule.** For open-ended connection-seeking requests (\\\"find me a mentor\\\", \" +\n \"\\\"who needs a React dev\\\", \\\"looking for investors\\\"), call this tool with `searchQuery` FIRST. \" +\n \"Do NOT call create_intent for these phrasings — create_intent is only for when the user explicitly \" +\n \"asks to \\\"create\\\", \\\"save\\\", \\\"add\\\", or \\\"remember\\\" a signal.\\n\\n\" +\n \"**Personal-index scoping.** When the user says \\\"in my network\\\", \\\"from my contacts\\\", \\\"people I know\\\", \" +\n \"or similar scoping language, pass the user's personal index ID (from memberships where `isPersonal: true`) \" +\n \"as `networkId`. The personal index contains the user's contacts — scoping discovery to it restricts \" +\n \"results to people the user already knows. Without this scoping language, omit networkId to let discovery \" +\n \"run across all indexes.\\n\\n\" +\n \"**Introduction mode prerequisites.** When using `partyUserIds` + `entities`, YOU must pre-fetch each party's \" +\n \"profile and intents before calling this tool. The entities array must include each party's userId, profile, \" +\n \"intents from shared indexes, and the shared networkId. Call read_user_profiles, read_network_memberships, \" +\n \"and read_intents for both parties first. The introducer (current user) must NOT appear in entities.\\n\\n\" +\n \"**Signal-visibility follow-up.** If the response includes `suggestIntentCreationForVisibility: true` and \" +\n \"`suggestedIntentDescription`, after presenting opportunity cards ask the user ONCE whether they'd also like \" +\n \"to create a signal so others can find them. On yes, call create_intent with the suggested description. \" +\n \"Never suggest this after introducer-mode (`introTargetUserId`) calls — the query describes the other person's \" +\n \"needs, not the signed-in user's.\",\n querySchema: z.object({\n continueFrom: z\n .string()\n .optional()\n .describe(\"Pagination token: pass the discoveryId from a previous discover_opportunities result to evaluate the next batch of candidates. Do not combine with searchQuery or other mode parameters — when a fresh searchQuery is also present, the server ignores continueFrom and runs a fresh discovery.\"),\n searchQuery: z\n .string()\n .optional()\n .describe(\"Discovery mode: natural language description of what to look for (e.g. 'AI/ML engineers', 'startup advisors in fintech'). Drives semantic matching against other users' intents and profiles.\"),\n networkId: z\n .string()\n .optional()\n .describe(\"Index UUID to scope discovery to a specific community. Get from read_networks. In an index-scoped chat, omitting this runs discovery across the full reachable scope (the bound community plus the user's personal index); pass an explicit networkId to force single-index discovery. Pass the personal index ID (from read_networks, isPersonal=true) to scope to the user's contacts only.\"),\n intentId: z\n .string()\n .optional()\n .describe(\"Optional intent UUID to use as the discovery source. The intent's description drives matching instead of searchQuery. Get from read_intents. Typically used by background processing, not direct agent calls.\"),\n targetUserId: z\n .string()\n .optional()\n .describe(\"Direct connection mode: create an opportunity with this specific user. Get the userId from read_user_profiles(query=name). Combine with searchQuery to explain the connection reason.\"),\n introTargetUserId: z\n .string()\n .optional()\n .describe(\n \"Introducer discovery mode: find matches FOR this user ID (the current user becomes the introducer). \" +\n \"Get the userId from read_user_profiles(query=name). \" +\n \"Use when the user asks 'who should I introduce to [person]?'. \" +\n \"Do NOT combine with partyUserIds (that's full introduction mode).\"\n ),\n partyUserIds: z\n .array(z.string())\n .optional()\n .describe(\"Introduction mode: array of 2+ user IDs to introduce to each other. Get user IDs from read_user_profiles or read_network_memberships. Must also provide entities with pre-gathered profile/intent data.\"),\n entities: z\n .array(\n z.object({\n userId: z.string(),\n profile: z\n .object({\n name: z.string().optional(),\n bio: z.string().optional(),\n location: z.string().optional(),\n interests: z.array(z.string()).optional(),\n skills: z.array(z.string()).optional(),\n context: z.string().optional(),\n })\n .optional(),\n intents: z\n .array(\n z.object({\n intentId: z.string(),\n payload: z.string(),\n summary: z.string().optional(),\n }),\n )\n .optional(),\n networkId: z\n .string()\n .describe(\"Shared index this entity's data comes from (required for intro mode)\"),\n }),\n )\n .optional()\n .describe(\n \"Introduction mode: pre-gathered profile and intent data for each party being introduced. \" +\n \"Each entry needs userId, networkId (the shared index), and optionally profile (name, bio, skills, interests) and intents (intentId, payload). \" +\n \"Gather this data by calling read_user_profiles and read_intents for each party BEFORE calling discover_opportunities. \" +\n \"All entities must share the same networkId (the shared index where both parties are members).\",\n ),\n hint: z\n .string()\n .optional()\n .describe(\n \"Introduction mode: the user's reason for making this introduction (e.g. 'both working on AI in healthcare', \" +\n \"'complementary skills for a startup'). Helps the evaluator produce better match reasoning.\",\n ),\n }),\n handler: async ({ context, query }) => {\n // Strict scope enforcement: when chat is index-scoped, only allow that index\n if (\n context.networkId &&\n query.networkId?.trim() &&\n query.networkId.trim() !== context.networkId\n ) {\n return error(\n `This chat is scoped to ${context.indexName ?? \"this index\"}. You can only create opportunities in this community.`,\n );\n }\n\n // Distinguish an explicit `query.networkId` override (caller wants discovery\n // scoped to one specific index) from an implicit scoped-chat context\n // (caller is in a scoped chat with no explicit override — discovery should\n // span the chat's reach, i.e. context.indexScope = [bound, personal]).\n // Conflating them via `context.networkId || query.networkId` made the\n // implicit branch unreachable.\n const explicitIndexId = query.networkId?.trim() || undefined;\n const effectiveIndexId = explicitIndexId;\n if (effectiveIndexId && !UUID_REGEX.test(effectiveIndexId)) {\n return error(\"Invalid network ID format.\");\n }\n\n if (context.isMcp && deps.discoveryRuns && deps.discoveryRunQueue) {\n // Coalesce: if an equivalent discovery is already queued/running for this\n // user, return that run instead of spawning a duplicate. An over-eager\n // MCP client that re-fires discover_opportunities (instead of polling\n // get_discovery_run) would otherwise kick off a fresh, expensive\n // opportunity-graph run on every call — the loop that drives the agent\n // into provider rate limits.\n const signature = discoveryRunSignature(\n query as DiscoveryRunInput,\n discoveryScopeKey(context),\n );\n try {\n const active = await deps.discoveryRuns.listActive(context.userId);\n const existing = active.find(\n (r) => discoveryRunSignature(r.input, discoveryScopeKey(r.context)) === signature,\n );\n if (existing) {\n return success({\n status: existing.status === \"running\" ? (\"running\" as const) : (\"queued\" as const),\n discoveryRunId: existing.id,\n coalesced: true,\n message:\n `A discovery run for this exact request is already ${existing.status}. ` +\n `Do NOT call discover_opportunities again — keep calling get_discovery_run with ` +\n `discoveryRunId=\"${existing.id}\" (about every 5 seconds) until it succeeds, fails, ` +\n `or is cancelled, then present its result.`,\n });\n }\n } catch {\n // listActive is a best-effort optimization; fall through to create on error.\n }\n\n const run = await deps.discoveryRuns.create({\n userId: context.userId,\n agentId: context.agentId ?? null,\n input: query as DiscoveryRunInput,\n context: {\n userId: context.userId,\n userName: context.userName,\n userEmail: context.userEmail,\n ...(context.networkId ? { networkId: context.networkId } : {}),\n ...(context.indexName ? { indexName: context.indexName } : {}),\n indexScope: context.indexScope,\n ...(context.sessionId ? { sessionId: context.sessionId } : {}),\n ...(context.agentId ? { agentId: context.agentId } : {}),\n ...(context.clientSurface ? { clientSurface: context.clientSurface } : {}),\n },\n });\n try {\n await deps.discoveryRunQueue.enqueue(run.id);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n await deps.discoveryRuns.markFailed(run.id, message);\n return error(`Failed to enqueue discovery run: ${message}`);\n }\n return success({\n status: \"queued\" as const,\n discoveryRunId: run.id,\n message:\n `Discovery started. Poll get_discovery_run with discoveryRunId=\"${run.id}\" about every 5 seconds ` +\n `until status is succeeded, failed, or cancelled, then present its result. ` +\n `Do NOT call discover_opportunities again for this request while the run is in progress — ` +\n `a repeat call returns this same run, not a new one.`,\n });\n }\n\n // ── Continuation mode ──\n // `continueFrom` is a pagination token for resuming a prior discovery's\n // cached candidates. When a caller (typically an MCP client's LLM) sends\n // a fresh `searchQuery` alongside a stale `continueFrom`, treat it as a\n // fresh search — the explicit search intent wins. Resuming against the\n // stale session's exhausted cache silently produced the \"No more\n // matching opportunities found in the remaining candidates\" response\n // for users who expected fresh results (IND-305).\n if (query.continueFrom && query.searchQuery?.trim()) {\n logger.warn(\"discover_opportunities: dropping stale continueFrom in favor of fresh searchQuery\", {\n userId: context.userId,\n continueFrom: query.continueFrom,\n });\n }\n if (query.continueFrom && !query.searchQuery?.trim()) {\n const _continueTraceEmitter = requestContext.getStore()?.traceEmitter;\n const _graphStart = Date.now();\n _continueTraceEmitter?.({ type: \"graph_start\", name: \"opportunity\" });\n const result = await continueDiscovery({\n opportunityGraph: graphs.opportunity,\n database,\n cache,\n userId: context.userId,\n discoveryId: query.continueFrom,\n expectedIndexId: context.networkId,\n limit: 20,\n presenter: new OpportunityPresenter(),\n useHomeCardFormat: true,\n ...(context.sessionId ? { chatSessionId: context.sessionId } : {}),\n });\n const _graphMs = Date.now() - _graphStart;\n _continueTraceEmitter?.({ type: \"graph_end\", name: \"opportunity\", durationMs: _graphMs });\n\n const allDebugSteps = [...(result.debugSteps ?? [])];\n\n if (!result.found) {\n return success({\n found: false,\n count: 0,\n message: result.message ?? \"No more matching opportunities found in the remaining candidates.\",\n summary: \"No more matches found\",\n ...(result.pagination ? { pagination: result.pagination } : {}),\n debugSteps: allDebugSteps,\n _graphTimings: [{ name: 'opportunity', durationMs: _graphMs, agents: [] }],\n });\n }\n\n // Build card data; cap at CHAT_DISPLAY_LIMIT (remaining feeds into pagination)\n const allCardData = (result.opportunities ?? []).map((opp) => ({\n opportunityId: opp.opportunityId,\n userId: opp.userId,\n name: opp.name,\n avatar: opp.avatar,\n mainText: opp.homeCardPresentation?.personalizedSummary ?? opp.matchReason ?? \"\",\n cta: opp.homeCardPresentation?.suggestedAction,\n headline: opp.homeCardPresentation?.headline,\n primaryActionLabel: opp.homeCardPresentation?.primaryActionLabel,\n secondaryActionLabel: opp.homeCardPresentation?.secondaryActionLabel,\n mutualIntentsLabel: opp.homeCardPresentation?.mutualIntentsLabel,\n narratorChip: opp.narratorChip,\n viewerRole: opp.viewerRole,\n isGhost: opp.isGhost ?? false,\n score: opp.score,\n status: opp.status,\n }));\n const displayedCards = allCardData.slice(0, CHAT_DISPLAY_LIMIT);\n const extraFromCap = allCardData.length - displayedCards.length;\n\n let message = buildOpportunityPresentation(displayedCards, {\n isMcp: context.isMcp ?? false,\n leadIn: `Found ${displayedCards.length} more potential connection(s).`,\n });\n\n const isIntroducerContinuation = !!query.introTargetUserId?.trim();\n const totalRemaining = (result.pagination?.remaining ?? 0) + extraFromCap;\n if (totalRemaining > 0 && result.pagination?.discoveryId) {\n message += `\\n\\nThere are ${totalRemaining} more candidates. Ask if the user wants to see more — they can say \"show me more\" and you should call discover_opportunities with continueFrom=\"${result.pagination.discoveryId}\".`;\n } else if (isIntroducerContinuation) {\n message += `\\n\\nThese are all the introduction candidates I found for this person.`;\n } else {\n message += `\\n\\nThese are all the connections I found. If the user wants to attract more connections, suggest they create a signal — e.g. \"Would you like to create a signal so others looking for someone like you can find you?\" If they agree, call create_intent with a description based on what they were searching for.`;\n }\n\n return success({\n found: true,\n count: displayedCards.length,\n message,\n summary: `Found ${displayedCards.length} more match(es)`,\n ...(result.pagination ? { pagination: result.pagination } : {}),\n debugSteps: allDebugSteps,\n _graphTimings: [{ name: 'opportunity', durationMs: _graphMs, agents: [] }],\n });\n }\n\n // Normalize entity networkIds before any checks to avoid raw-vs-trimmed mismatches.\n const normalizedEntities = query.entities?.map((e) => ({ ...e, networkId: e.networkId?.trim() }));\n\n // Derive partyUserIds from entities when agent passes entities but omits partyUserIds (intro mode).\n // Only derive when all entities share the same networkId to prevent cross-network introductions.\n const partyUserIdsFromEntities =\n normalizedEntities &&\n normalizedEntities.length >= 2 &&\n normalizedEntities.every((e) => e.userId && e.networkId) &&\n new Set(normalizedEntities.map((e) => e.networkId)).size === 1\n ? [...new Set(normalizedEntities.map((e) => e.userId))]\n : undefined;\n const effectivePartyUserIds =\n query.partyUserIds && query.partyUserIds.length >= 2\n ? query.partyUserIds\n : (partyUserIdsFromEntities?.length ?? 0) >= 2\n ? partyUserIdsFromEntities\n : undefined;\n\n // ── Introduction mode ── (validation and persistence via opportunity graph)\n if (effectivePartyUserIds && effectivePartyUserIds.length >= 2) {\n if (!normalizedEntities || normalizedEntities.length === 0) {\n return error(\n \"Introduction requires pre-gathered entity data. \" +\n \"First use read_network_memberships to find shared networks, \" +\n \"then read_user_profiles and read_intents for each party, \" +\n \"then pass the results as entities.\",\n );\n }\n\n const normalizedEntityNetworkIds = normalizedEntities\n .map((e) => e.networkId)\n .filter((id): id is string => Boolean(id));\n\n if (\n normalizedEntityNetworkIds.length !== normalizedEntities.length ||\n new Set(normalizedEntityNetworkIds).size !== 1\n ) {\n return error(\"All entities must include the same shared networkId.\");\n }\n\n const [primaryNetworkId] = normalizedEntityNetworkIds;\n\n const introducedPartyUserIds = effectivePartyUserIds.filter(\n (uid) => uid !== context.userId,\n );\n if (introducedPartyUserIds.length === 0) {\n return error(\n \"No counterpart to introduce. Provide at least one other user ID in partyUserIds (besides yourself).\",\n );\n }\n\n const evaluatorEntities: EvaluatorEntity[] = normalizedEntities.map(\n (e) => ({\n userId: e.userId,\n profile: e.profile ?? {},\n intents: e.intents,\n networkId: e.networkId,\n }),\n );\n\n const _introGraphStart = Date.now();\n const _introTraceEmitter = requestContext.getStore()?.traceEmitter;\n _introTraceEmitter?.({ type: \"graph_start\", name: \"opportunity\" });\n const result = await invokeWithAbortSignal(graphs.opportunity, {\n operationMode: \"create_introduction\",\n userId: context.userId,\n networkId: primaryNetworkId,\n introductionEntities: evaluatorEntities,\n introductionHint: query.hint,\n requiredNetworkId: context.networkId ?? undefined,\n options: {\n initialStatus: \"draft\" as const,\n ...(context.sessionId ? { conversationId: context.sessionId } : {}),\n },\n });\n const _introGraphMs = Date.now() - _introGraphStart;\n _introTraceEmitter?.({ type: \"graph_end\", name: \"opportunity\", durationMs: _introGraphMs });\n\n if (result.error || !result.opportunities?.length) {\n return error(\n result.error ?? \"Failed to create introduction.\",\n );\n }\n\n const created = result.opportunities[0];\n const reasoning =\n created.interpretation?.reasoning ?? \"A suggested connection.\";\n const confidence =\n typeof created.interpretation?.confidence === \"number\"\n ? created.interpretation.confidence\n : parseFloat(String(created.confidence ?? 0)) || 0;\n const introducerUser = await userDb.getUser();\n const firstPartyId = introducedPartyUserIds[0];\n const firstEntity = query.entities?.find((e) => e.userId === firstPartyId);\n const counterpartUser = firstPartyId\n ? await database.getUser(firstPartyId)\n : null;\n const counterpartName =\n firstEntity?.profile?.name ?? firstPartyId ?? \"Someone\";\n\n // Second party — used in the headline and arrow layout for the introducer view (\"A → B\")\n const secondPartyId = introducedPartyUserIds[1];\n const secondEntity = query.entities?.find((e) => e.userId === secondPartyId);\n const secondPartyName = (secondEntity?.profile as { name?: string } | undefined)?.name;\n const secondPartyAvatar = (secondEntity?.profile as { avatar?: string | null } | undefined)?.avatar ?? null;\n const secondPartyUser = secondPartyId ? await database.getUser(secondPartyId) : null;\n\n const viewerIsParty = effectivePartyUserIds.includes(context.userId);\n const viewerRole = viewerIsParty ? \"party\" : \"introducer\";\n const isCounterpartGhost = counterpartUser?.isGhost ?? false;\n const primaryActionLabel = getPrimaryActionLabel(viewerRole);\n const narratorChip = viewerIsParty\n ? {\n name: \"Index\",\n text: narratorRemarkFromReasoning(reasoning, counterpartName, introducerUser?.name ?? undefined),\n }\n : {\n name: \"You\",\n text: narratorRemarkFromReasoning(reasoning, counterpartName, introducerUser?.name ?? undefined),\n userId: context.userId,\n };\n\n const headline =\n !viewerIsParty && secondPartyName\n ? `${counterpartName} → ${secondPartyName}`\n : `Connection with ${counterpartName}`;\n\n const cardData = {\n opportunityId: created.id,\n userId: firstPartyId,\n name: counterpartName,\n avatar:\n counterpartUser?.avatar ??\n (firstEntity?.profile as { avatar?: string | null } | undefined)\n ?.avatar ??\n null,\n mainText: viewerCentricCardSummary(\n reasoning,\n counterpartName,\n MINIMAL_MAIN_TEXT_MAX_CHARS,\n undefined, // viewerName not available in this context; introducer name passed separately\n introducerUser?.name ?? undefined,\n ),\n cta: \"Start a conversation to connect.\",\n headline,\n primaryActionLabel,\n secondaryActionLabel: SECONDARY_ACTION_LABEL,\n mutualIntentsLabel: \"Suggested connection\",\n narratorChip,\n viewerRole,\n isGhost: isCounterpartGhost,\n score: confidence,\n status: created.status ?? \"draft\",\n ...(!viewerIsParty && secondPartyName\n ? {\n secondParty: {\n name: secondPartyName,\n avatar: secondPartyUser?.avatar ?? secondPartyAvatar,\n ...(secondPartyId ? { userId: secondPartyId } : {}),\n },\n }\n : {}),\n };\n\n if (context.isMcp && deps.mintConnectLink) {\n await attachActionableLinks(cardData as Record<string, unknown> & {\n opportunityId: string;\n viewerRole: string;\n status: string;\n }, {\n viewerId: context.userId,\n viewerApproved: false,\n counterpartUserId: firstPartyId,\n mintConnectLink: deps.mintConnectLink,\n frontendUrl: deps.frontendUrl,\n preferredSurface: context.clientSurface,\n });\n }\n\n return success({\n found: true,\n count: 1,\n summary: \"Draft introduction created\",\n message: buildOpportunityPresentation([cardData], {\n isMcp: context.isMcp ?? false,\n leadIn: \"Draft introduction created.\",\n label: \"opportunity\",\n }),\n opportunities: [\n {\n opportunityId: created.id,\n matchReason: reasoning,\n score: confidence,\n status: created.status ?? \"draft\",\n },\n ],\n _graphTimings: [{ name: 'opportunity', durationMs: _introGraphMs, agents: result.agentTimings ?? [] }],\n });\n }\n\n // ── Discovery mode ──\n const searchQuery = query.searchQuery?.trim() ?? \"\";\n\n if (query.intentId != null && query.intentId !== \"\" && !UUID_REGEX.test(query.intentId.trim())) {\n return error(\"Invalid intent ID format.\");\n }\n\n let indexScope: string[];\n const _scopeGraphTimings: Array<{ name: string; durationMs: number; agents: Array<{ name: string; durationMs: number }> }> = [];\n if (effectiveIndexId) {\n if (!UUID_REGEX.test(effectiveIndexId)) {\n return error(\"Invalid network ID format.\");\n }\n const _scopeGraphStart = Date.now();\n const _scopeIndexMembershipTraceEmitter = requestContext.getStore()?.traceEmitter;\n _scopeIndexMembershipTraceEmitter?.({ type: \"graph_start\", name: \"network_membership\" });\n const memberResult = await invokeWithAbortSignal(graphs.networkMembership, {\n userId: context.userId,\n networkId: effectiveIndexId,\n operationMode: \"read\" as const,\n });\n const _scopeIndexMembershipMs = Date.now() - _scopeGraphStart;\n _scopeIndexMembershipTraceEmitter?.({ type: \"graph_end\", name: \"network_membership\", durationMs: _scopeIndexMembershipMs });\n _scopeGraphTimings.push({ name: 'network_membership', durationMs: _scopeIndexMembershipMs, agents: [] });\n if (memberResult.error) {\n return error(\"Network not found or you are not a member.\");\n }\n indexScope = [effectiveIndexId];\n } else if (context.networkId) {\n // Scoped chat: use the agent's full reach so personal-index\n // signals participate in opportunity discovery. See IND-306.\n indexScope = context.indexScope.length > 0\n ? [...context.indexScope]\n : [context.networkId];\n } else {\n // No scope - use all indexes (only in unscoped chat)\n const _scopeGraphStart = Date.now();\n const _scopeIndexTraceEmitter = requestContext.getStore()?.traceEmitter;\n _scopeIndexTraceEmitter?.({ type: \"graph_start\", name: \"index\" });\n const indexResult = await invokeWithAbortSignal(graphs.index, {\n userId: context.userId,\n operationMode: \"read\" as const,\n showAll: true,\n });\n const _scopeIndexMs = Date.now() - _scopeGraphStart;\n _scopeIndexTraceEmitter?.({ type: \"graph_end\", name: \"index\", durationMs: _scopeIndexMs });\n _scopeGraphTimings.push({ name: 'index', durationMs: _scopeIndexMs, agents: [] });\n indexScope = (indexResult.readResult?.memberOf || []).map(\n (m: { networkId: string }) => m.networkId,\n );\n }\n\n const toolDebugSteps: Array<{ step: string; detail?: string }> = [\n { step: \"resolve_index_scope\", detail: `${indexScope.length} index(es)` },\n ];\n\n const triggerIntentId = query.intentId?.trim() || undefined;\n if (triggerIntentId != null && !UUID_REGEX.test(triggerIntentId)) {\n return error(\"Invalid intent ID format.\");\n }\n\n if (query.introTargetUserId?.trim() && query.introTargetUserId.trim() === context.userId) {\n return error(\"You cannot discover introductions for yourself. Try regular discovery instead.\");\n }\n\n const _discoverTraceEmitter = requestContext.getStore()?.traceEmitter;\n const _discoverGraphStart = Date.now();\n _discoverTraceEmitter?.({ type: \"graph_start\", name: \"opportunity\" });\n // Chat-driven invocations run under the orchestrator trigger: persist\n // opens at 'negotiating', negotiate fans out with a 60s park window,\n // each accepted draft streams via traceEmitter, and the persist step\n // surfaces already-accepted pairs. Other callers (maintenance, queue\n // workers) still get the 'ambient' default.\n // Orchestrator trigger fires for both web chat (has sessionId) and MCP\n // (isMcp=true, no sessionId). Both are user-initiated discovery that\n // should persist as `negotiating` and flip to `draft` post-finalize via\n // onCandidateResolved. Ambient/cron paths leave both falsy and use the\n // `pending` default.\n const runDiscoveryOrchestrator = !!context.sessionId || !!context.isMcp;\n const result = await runDiscoverFromQuery({\n opportunityGraph: graphs.opportunity,\n database,\n userId: context.userId,\n query: searchQuery,\n indexScope,\n limit: 20,\n presenter: new OpportunityPresenter(),\n useHomeCardFormat: true,\n triggerIntentId,\n targetUserId: query.targetUserId?.trim() || undefined,\n onBehalfOfUserId: query.introTargetUserId?.trim() || undefined,\n cache,\n // MCP-only: cap the negotiate phase at 20 s so Railway's edge proxy\n // (which 502s the client at ~57 s) never beats the response. The\n // remainder finalizes in the background and is fetched on the\n // user's next list_opportunities call. Removable when IND-274\n // (negotiation conversation continuation) lands.\n ...(context.isMcp ? { negotiateTimeoutMs: 20_000 } : {}),\n ...(context.sessionId ? { chatSessionId: context.sessionId } : {}),\n ...(runDiscoveryOrchestrator && { trigger: 'orchestrator' as const }),\n ...(deps.chatSummary && { chatSummary: deps.chatSummary }),\n ...(deps.questionGenerator && { questionGenerator: deps.questionGenerator }),\n ...(deps.questionerEnqueue && { questionerEnqueue: deps.questionerEnqueue }),\n ...(deps.negotiationSummary && { negotiationSummary: deps.negotiationSummary }),\n // Decision questions add an LLM call after the negotiation phase.\n // Capped at DISCOVERY_QUESTIONS_TIMEOUT_MS (12 s default,\n // env-overridable; see opportunity.discover.ts). Aborted calls return\n // no questions but the rest of the discovery payload still ships.\n // For chat sessions, questions are rendered by the frontend via\n // streamed events (Slice 4). For MCP, they drive a sequential\n // elicitation/create flow (Slice 5) — the MCP tool handler awaits the\n // elicitations before returning the tool result. The per-negotiation\n // summarizer is similarly capped at NEGOTIATION_SUMMARY_TIMEOUT_MS\n // (5 s default per negotiation). Master switch remains\n // ENABLE_DISCOVERY_QUESTIONS.\n enableQuestions:\n process.env.ENABLE_DISCOVERY_QUESTIONS === \"true\" &&\n (!!context.sessionId || !!context.isMcp),\n });\n\n // ── Pending question injection ────────────────────────────────────\n // Look up previously-generated questions relevant to this user's\n // discovery context and merge them into the result alongside any\n // inline-generated questions from the current run.\n const pendingQuestionResult = await mergePendingQuestions({\n findPendingQuestions: deps.findPendingQuestions,\n userId: context.userId,\n sourceType: 'discovery',\n surfacedQuestionIds: new Set(), // Dedup handled at chat.agent level\n });\n const pendingQuestions = pendingQuestionResult.questions;\n\n const _discoverGraphMs = Date.now() - _discoverGraphStart;\n _discoverTraceEmitter?.({ type: \"graph_end\", name: \"opportunity\", durationMs: _discoverGraphMs });\n const _discoverGraphTimings = [\n ..._scopeGraphTimings,\n { name: 'opportunity', durationMs: _discoverGraphMs, agents: [] },\n ];\n\n const allDebugSteps = [\n ...toolDebugSteps,\n ...(result.debugSteps ?? []),\n ];\n\n // Extract negotiation timing from trace (if negotiation ran)\n const negotiateStep = (result.debugSteps ?? []).find(\n s => s.step === 'negotiate' && s.data?.durationMs != null\n );\n const _allGraphTimings = [\n ..._discoverGraphTimings,\n ...(negotiateStep?.data?.durationMs != null\n ? [{ name: 'negotiation', durationMs: negotiateStep.data.durationMs as number, agents: [] }]\n : []),\n ];\n\n const isIntroducerFlow = !!query.introTargetUserId?.trim();\n\n if (result.createIntentSuggested && result.suggestedIntentDescription && !isIntroducerFlow) {\n return success({\n found: false,\n count: 0,\n createIntentSuggested: true,\n suggestedIntentDescription: result.suggestedIntentDescription,\n message:\n \"No matching opportunities found. Call create_intent with the suggested description, then discover_opportunities again.\",\n summary: \"No matches found\",\n ...(result.pagination ? { pagination: result.pagination } : {}),\n debugSteps: allDebugSteps,\n _graphTimings: _allGraphTimings,\n ...(() => {\n const allQ = [...(result.questions ?? []), ...pendingQuestions];\n return allQ.length > 0 ? { questions: allQ } : {};\n })(),\n ...(result.discoveryQuestionsDebug ? { _discoveryQuestionsDebug: result.discoveryQuestionsDebug } : {}),\n });\n }\n\n if (!result.found) {\n return success({\n found: false,\n count: 0,\n message: result.message ?? \"No matching opportunities found.\",\n summary: \"No matches found\",\n ...(result.pagination ? { pagination: result.pagination } : {}),\n debugSteps: allDebugSteps,\n _graphTimings: _allGraphTimings,\n ...(() => {\n const allQ = [...(result.questions ?? []), ...pendingQuestions];\n return allQ.length > 0 ? { questions: allQ } : {};\n })(),\n ...(result.discoveryQuestionsDebug ? { _discoveryQuestionsDebug: result.discoveryQuestionsDebug } : {}),\n });\n }\n\n // Found but only existing connections (no new opportunities created)\n const forMention = result.existingConnectionsForMention ?? result.existingConnections ?? [];\n if ((result.opportunities?.length ?? 0) === 0 && forMention.length > 0) {\n return success({\n found: true,\n count: 0,\n message:\n result.message ??\n \"No new opportunities created; you already have a connection with: \" +\n forMention.map((c) => c.name + (c.status ? \" (\" + c.status + \")\" : \"\")).join(\", \") +\n \". View on your home page.\",\n existingConnections: result.existingConnections,\n summary: \"No new matches (existing connections only)\",\n debugSteps: allDebugSteps,\n _graphTimings: _allGraphTimings,\n ...(() => {\n const allQ = [...(result.questions ?? []), ...pendingQuestions];\n return allQ.length > 0 ? { questions: allQ } : {};\n })(),\n ...(result.discoveryQuestionsDebug ? { _discoveryQuestionsDebug: result.discoveryQuestionsDebug } : {}),\n });\n }\n\n // MCP-only: refresh persisted opp statuses from the DB. The graph captures\n // state.opportunities at persist time, but the negotiate phase mutates each\n // opp's DB row independently. Without this refresh we'd render persist-time\n // 'negotiating' as if it were 'draft'. Also drops rejected/stalled — they\n // are not actionable post-negotiation. Existing-connection cards (cards\n // whose opportunityId is in result.existingConnections) are preserved as-is\n // per opportunity.discover.ts's EXISTING_CONNECTION_CARD_STATUSES contract.\n const existingConnectionIds = new Set(\n (result.existingConnections ?? [])\n .map((c) => c.opportunityId)\n .filter((id): id is string => typeof id === 'string'),\n );\n const candidatesArr = result.opportunities ?? [];\n let negotiatingCount = 0;\n let cards = candidatesArr;\n if (context.isMcp && candidatesArr.length > 0) {\n const newlyCreatedIds = candidatesArr\n .filter((c) => !existingConnectionIds.has(c.opportunityId))\n .map((c) => c.opportunityId);\n const refreshed = newlyCreatedIds.length > 0\n ? await database.getOpportunitiesByIds(newlyCreatedIds)\n : [];\n const statusById = new Map<string, OpportunityStatus>(\n refreshed.map((o) => [o.id, o.status]),\n );\n\n const draftCards: typeof candidatesArr = [];\n for (const card of candidatesArr) {\n if (existingConnectionIds.has(card.opportunityId)) {\n // Re-surfaced opp from a prior run — keep with its discover-time status.\n draftCards.push(card);\n continue;\n }\n const refreshedStatus = statusById.get(card.opportunityId);\n if (refreshedStatus === 'draft') {\n draftCards.push({ ...card, status: refreshedStatus });\n continue;\n }\n if (refreshedStatus === 'negotiating') {\n negotiatingCount += 1;\n continue;\n }\n if (refreshedStatus === 'rejected' || refreshedStatus === 'stalled') {\n continue; // drop\n }\n // 'pending' / 'latent' / unknown — not expected post-IND-287. Treat as\n // negotiating (count only) and log so we can spot wiring regressions.\n logger.warn('[discover_opportunities] unexpected refreshed status — counting as negotiating', {\n opportunityId: card.opportunityId,\n refreshedStatus,\n });\n negotiatingCount += 1;\n }\n cards = draftCards;\n }\n\n // Build card data; cap at CHAT_DISPLAY_LIMIT (remaining feeds into pagination)\n const allCardData = cards.map((opp) => ({\n opportunityId: opp.opportunityId,\n userId: opp.userId,\n name: opp.name,\n avatar: opp.avatar,\n mainText:\n opp.homeCardPresentation?.personalizedSummary ??\n opp.matchReason ??\n \"\",\n cta: opp.homeCardPresentation?.suggestedAction,\n headline: opp.homeCardPresentation?.headline,\n primaryActionLabel: opp.homeCardPresentation?.primaryActionLabel,\n secondaryActionLabel: opp.homeCardPresentation?.secondaryActionLabel,\n mutualIntentsLabel: opp.homeCardPresentation?.mutualIntentsLabel,\n narratorChip: opp.narratorChip,\n viewerRole: opp.viewerRole,\n isGhost: opp.isGhost ?? false,\n score: opp.score,\n status: opp.status,\n ...(opp.secondParty && { secondParty: opp.secondParty }),\n }));\n const displayedCards = allCardData.slice(0, CHAT_DISPLAY_LIMIT);\n const extraFromCap = allCardData.length - displayedCards.length;\n\n if (context.isMcp && deps.mintConnectLink) {\n const mintConnectLink = deps.mintConnectLink;\n await Promise.all(\n displayedCards.map(async (card, idx) => {\n const source = cards[idx];\n await attachActionableLinks(card as Record<string, unknown> & {\n opportunityId: string;\n viewerRole: string;\n status: string;\n }, {\n viewerId: context.userId,\n viewerApproved: source?.viewerApproved,\n counterpartUserId: source?.userId ?? card.userId,\n mintConnectLink,\n frontendUrl: deps.frontendUrl,\n preferredSurface: context.clientSurface,\n });\n }),\n );\n }\n\n let message = buildOpportunityPresentation(displayedCards, {\n isMcp: context.isMcp ?? false,\n leadIn: `Found ${displayedCards.length} potential connection(s).`,\n });\n const existingForMention = result.existingConnectionsForMention ?? result.existingConnections ?? [];\n if (existingForMention.length > 0) {\n message +=\n \"\\n\\nYou already have a connection with: \" +\n existingForMention.map((c) => c.name + (c.status ? \" (\" + c.status + \")\" : \"\")).join(\", \") +\n \". View on your home page.\";\n }\n // Orchestrator-only: dedupAlreadyAccepted surfaces pairs that already\n // have an accepted opp between the users. Tell the LLM so it can guide\n // the user to the existing chat instead of treating this like a brand-\n // new connection.\n if (result.alreadyAcceptedPairs && result.alreadyAcceptedPairs.length > 0) {\n message +=\n `\\n\\nYou already have ${result.alreadyAcceptedPairs.length} accepted opportunity(ies) with some of these candidates — open the existing chat with them rather than creating a new draft.`;\n }\n\n const totalRemaining = (result.pagination?.remaining ?? 0) + extraFromCap;\n if (totalRemaining > 0 && result.pagination?.discoveryId) {\n message += `\\n\\nThere are ${totalRemaining} more candidates. Ask if the user wants to see more — they can say \"show me more\" and you should call discover_opportunities with continueFrom=\"${result.pagination.discoveryId}\".`;\n } else if (isIntroducerFlow) {\n message += `\\n\\nThese are all the introduction candidates I found for this person.`;\n } else {\n message += `\\n\\nThese are all the connections I found. If the user wants to attract more connections, suggest they create a signal — e.g. \"Would you like to create a signal so others looking for someone like you can find you?\" If they agree, call create_intent with a description based on what they were searching for.`;\n }\n\n // MCP-only: tell the LLM how many opps are still negotiating in the background\n // and how to fetch them. This is the deferred-surfacing handshake — the user's\n // next list_opportunities call will pick up the rest as they finalize.\n if (context.isMcp && negotiatingCount > 0) {\n if (displayedCards.length > 0) {\n message += `\\n\\n${negotiatingCount} more opportunit${negotiatingCount === 1 ? 'y is' : 'ies are'} still being evaluated — check back via \\`list_opportunities\\` shortly.`;\n } else {\n // No cards shown. Rebuild the message without the misleading\n // \"Found 0 potential connection(s)\" lead-in but preserve the\n // existing-connections mention and already-accepted-pairs note\n // appended earlier — those are standalone facts independent of\n // any draft cards. Pagination/intro/closing trailers are dropped\n // intentionally (they only make sense when cards are shown).\n let rebuilt = `Found candidates, but they're still being evaluated. Try \\`list_opportunities\\` in a minute — ${negotiatingCount} pending.`;\n if (existingForMention.length > 0) {\n rebuilt +=\n \"\\n\\nYou already have a connection with: \" +\n existingForMention.map((c) => c.name + (c.status ? \" (\" + c.status + \")\" : \"\")).join(\", \") +\n \". View on your home page.\";\n }\n if (result.alreadyAcceptedPairs && result.alreadyAcceptedPairs.length > 0) {\n rebuilt += `\\n\\nYou already have ${result.alreadyAcceptedPairs.length} accepted opportunity(ies) with some of these candidates — open the existing chat with them rather than creating a new draft.`;\n }\n message = rebuilt;\n }\n }\n\n return success({\n found: true,\n count: displayedCards.length,\n message,\n summary: `Found ${displayedCards.length} match(es)`,\n ...(result.existingConnections?.length ? { existingConnections: result.existingConnections } : {}),\n ...(result.pagination ? { pagination: result.pagination } : {}),\n debugSteps: allDebugSteps,\n // Distinct from `createIntentSuggested` (no-results path) intentionally:\n // `handleCreateIntentCallback` in chat.agent.ts auto-creates for that key.\n // This flag is for the results-found path where the agent must ask the user first.\n ...(searchQuery && !query.targetUserId && !isIntroducerFlow\n ? {\n suggestIntentCreationForVisibility: true,\n suggestedIntentDescription: searchQuery,\n }\n : {}),\n ...(() => {\n const allQ = [...(result.questions ?? []), ...pendingQuestions];\n return allQ.length > 0 ? { questions: allQ } : {};\n })(),\n ...(result.discoveryQuestionsDebug ? { _discoveryQuestionsDebug: result.discoveryQuestionsDebug } : {}),\n _graphTimings: _allGraphTimings,\n });\n },\n });\n\n const getDiscoveryRun = defineTool({\n name: \"get_discovery_run\",\n description:\n \"Checks the status of an async discovery run started by discover_opportunities in MCP contexts. \" +\n \"Poll this tool with the discoveryRunId roughly every 5 seconds until status is succeeded, failed, or cancelled. \" +\n \"While status is queued or running, keep polling THIS tool — do NOT call discover_opportunities again (that does not speed anything up and returns the same run). \" +\n \"When succeeded, the result field contains the same discovery payload that discover_opportunities would have returned synchronously.\",\n querySchema: z.object({\n discoveryRunId: z.string().describe(\"Discovery run ID returned by discover_opportunities.\"),\n }),\n handler: async ({ context, query }) => {\n if (!deps.discoveryRuns) {\n return error(\"Async discovery runs are not available in this context.\");\n }\n const run = await deps.discoveryRuns.get(query.discoveryRunId, context.userId);\n if (!run) return error(\"Discovery run not found.\");\n return success({\n discoveryRunId: run.id,\n status: run.status,\n progress: run.progress ?? null,\n result: run.result ?? null,\n error: run.error ?? null,\n cancelRequestedAt: run.cancelRequestedAt?.toISOString?.() ?? null,\n createdAt: run.createdAt.toISOString(),\n startedAt: run.startedAt?.toISOString?.() ?? null,\n completedAt: run.completedAt?.toISOString?.() ?? null,\n });\n },\n });\n\n const cancelDiscoveryRun = defineTool({\n name: \"cancel_discovery_run\",\n description:\n \"Requests cancellation for an async discovery run. If the queued job has not started, it is removed and marked cancelled. \" +\n \"If already running, the worker observes cancellation and stops at the next cancellation check.\",\n querySchema: z.object({\n discoveryRunId: z.string().describe(\"Discovery run ID returned by discover_opportunities.\"),\n }),\n handler: async ({ context, query }) => {\n if (!deps.discoveryRuns || !deps.discoveryRunQueue) {\n return error(\"Async discovery runs are not available in this context.\");\n }\n const existing = await deps.discoveryRuns.get(query.discoveryRunId, context.userId);\n if (!existing) return error(\"Discovery run not found.\");\n if (![\"queued\", \"running\"].includes(existing.status)) {\n return success({\n discoveryRunId: existing.id,\n status: existing.status,\n cancelled: existing.status === \"cancelled\",\n message: `Discovery run is already ${existing.status}.`,\n });\n }\n const run = await deps.discoveryRuns.requestCancel(query.discoveryRunId, context.userId);\n if (!run) return error(\"Discovery run is no longer cancellable.\");\n const removed = await deps.discoveryRunQueue.cancel(run.id);\n if (removed) {\n await deps.discoveryRuns.markCancelled(run.id, \"cancelled before worker start\");\n }\n const updated = await deps.discoveryRuns.get(run.id, context.userId);\n const status = updated?.status ?? (removed ? \"cancelled\" : run.status);\n const message = removed\n ? \"Discovery run cancelled.\"\n : status === \"queued\"\n ? \"Cancellation requested while the discovery run is still queued. It will be skipped or cancelled before work starts.\"\n : status === \"running\"\n ? \"Cancellation requested. The running worker will stop at the next cancellation check.\"\n : `Cancellation requested. Discovery run is now ${status}.`;\n return success({\n discoveryRunId: run.id,\n status,\n cancelled: removed || status === \"cancelled\",\n message,\n });\n },\n });\n\n const listOpportunities = defineTool({\n name: \"list_opportunities\",\n description:\n \"Lists the authenticated user's actionable opportunities (discovered connections). Returns opportunity cards ready for display.\\n\\n\" +\n \"**What are opportunities?** Matches between users whose intents complement each other within shared indexes. \" +\n \"Each opportunity has a status: draft (not yet sent), pending (sent, awaiting response), accepted, rejected, or expired.\\n\\n\" +\n \"**What this returns:** Only draft and pending opportunities — the ones the user can still act on. \" +\n \"Accepted, rejected, and expired ones are not surfaced through this tool.\\n\\n\" +\n \"**When to use:** When the user wants to see their current matches or review what's waiting for their response.\\n\\n\" +\n \"**Returns:** Up to 3 opportunity code blocks (interactive cards) with counterpart name, match reasoning, confidence score, \" +\n \"and current status. Use update_opportunity to act on them (send, accept, reject).\",\n querySchema: z.object({\n networkId: z\n .string()\n .optional()\n .describe(\"Index UUID to filter opportunities to a specific community. Get from read_networks. Defaults to the scoped index in index-scoped chats. Omit to see opportunities across all indexes.\"),\n includeDigestMarkers: z\n .boolean()\n .optional()\n .describe(\"Internal scheduled-digest mode only. When true, includes hidden delivery markers so the digest send pass can confirm only edited-in opportunities.\"),\n }),\n handler: async ({ context, query }) => {\n // Strict scope enforcement: when chat is index-scoped, only allow that index\n if (\n context.networkId &&\n query.networkId?.trim() &&\n query.networkId.trim() !== context.networkId\n ) {\n return error(\n \"This chat is scoped to \" +\n (context.indexName ?? \"this index\") +\n \". You can only list opportunities from this community.\",\n );\n }\n\n const effectiveIndexId =\n (context.networkId || query.networkId?.trim()) ?? undefined;\n if (effectiveIndexId && !UUID_REGEX.test(effectiveIndexId)) {\n return error(\"Invalid network ID format.\");\n }\n\n // The MCP/chat surface exposes actionable opportunities.\n // `latent` is included so the introducer-as-viewer can see their unapproved\n // connector-flow cards (\"do you know someone for X?\"). Other latent visibility\n // rules from isActionableForViewer (latent + no introducer; latent + approved=true\n // mid-negotiation) are correct at the ACL layer but should not flow through the\n // chat tool — patient/peer wait for the negotiation to land them in `pending`.\n const statuses: OpportunityStatus[] = [\"draft\", \"pending\", \"latent\"];\n\n // Fetch wider than CHAT_DISPLAY_LIMIT so selectByComposition has both\n // buckets to balance — otherwise a category that dominates the natural\n // sort order can fill the whole window and starve the other section.\n const fetched = await database.getOpportunitiesForUser(\n context.userId,\n {\n networkId: effectiveIndexId,\n statuses,\n limit: CHAT_FETCH_LIMIT,\n },\n );\n\n const skippedIds: string[] = [];\n const buildListDebugSteps = (): Array<{ step: string; detail?: string; data?: Record<string, unknown> }> => {\n const steps: Array<{ step: string; detail?: string; data?: Record<string, unknown> }> = [];\n if (skippedIds.length > 0) {\n steps.push({\n step: \"opportunity_display_skips\",\n detail: `${skippedIds.length} opportunity card(s) couldn't be displayed`,\n data: {\n skippedCount: skippedIds.length,\n totalOpportunities: fetched.length,\n skippedOpportunityIds: skippedIds,\n },\n });\n }\n return steps;\n };\n const recordCallerMismatch = (opp: Opportunity): void => {\n logger.warn(\"list_opportunities: skipping opportunity where caller is not an actor\", {\n opportunityId: opp.id,\n viewerId: context.userId,\n actorUserIds: opp.actors\n .map((a) => a.userId)\n .filter((userId): userId is string => typeof userId === \"string\"),\n });\n skippedIds.push(opp.id);\n };\n\n // Read invariant: only surface opportunities the caller actually\n // participates in. Apply before latent filtering, dedup/selection, and\n // profile/user batch fetches so a mismatched row cannot influence which\n // valid opportunities are selected or trigger cross-user reads.\n const callerScoped = fetched.filter((opp) => {\n if (opp.actors.some((a) => a.userId === context.userId)) return true;\n recordCallerMismatch(opp);\n return false;\n });\n\n // Latent rows in chat are introducer-as-viewer only. The ACL layer\n // (isActionableForViewer) returns true for several other latent cases —\n // those belong to the home feed, not the digest/ambient surface.\n const visible = callerScoped.filter((opp) => {\n if (opp.status !== \"latent\") return true;\n const me = opp.actors.find((a) => a.userId === context.userId);\n return me?.role === \"introducer\";\n });\n\n // Deduplicate so each counterpart appears at most once — keeps the\n // highest-confidence opportunity per person across discovery runs.\n const deduped = deduplicateByPerson(visible, context.userId);\n\n // Compose-balance across feed categories so the digest/ambient prompt\n // can fill both Section A (connection) and Section B (connector-flow).\n // Falls back to the unbalanced view when the helper has nothing to do.\n const selected = deduped.length > 0\n ? selectByComposition(deduped, context.userId)\n : deduped;\n const opportunities = selected.slice(0, CHAT_DISPLAY_LIMIT);\n\n if (!opportunities || opportunities.length === 0) {\n if (skippedIds.length > 0) {\n const listDebugSteps = buildListDebugSteps();\n return success({\n found: false,\n count: 0,\n summary: \"Some opportunities couldn't be displayed\",\n message:\n \"I found opportunities, but couldn't render them. Please try again.\",\n ...(listDebugSteps.length ? { debugSteps: listDebugSteps } : {}),\n });\n }\n return success({\n found: false,\n count: 0,\n summary: \"No opportunities yet\",\n message:\n \"You have no opportunities yet. Use discover_opportunities to find connections.\",\n });\n }\n\n // Batch-fetch profiles and users for all counterpart and introducer userIds to avoid N+1\n const counterpartUserIds = new Set<string>();\n const introducerUserIds = new Set<string>();\n for (const opp of opportunities) {\n const counterpartActor = opp.actors.find(\n (a) => a.userId !== context.userId && a.role !== \"introducer\",\n );\n if (counterpartActor?.userId) counterpartUserIds.add(counterpartActor.userId);\n const introducerActor = opp.actors.find(\n (a) => a.role === \"introducer\" && a.userId !== context.userId,\n );\n if (introducerActor?.userId) introducerUserIds.add(introducerActor.userId);\n }\n const allUserIds = [\n ...new Set([...counterpartUserIds, ...introducerUserIds]),\n ];\n const [viewerUser, profileResults, userResults] = await Promise.all([\n database.getUser(context.userId),\n Promise.all(allUserIds.map((id) => database.getProfile(id))),\n Promise.all(allUserIds.map((id) => database.getUser(id))),\n ]);\n const viewerName = viewerUser?.name ?? undefined;\n const profileMap = new Map<string, Awaited<ReturnType<typeof database.getProfile>>>();\n const userMap = new Map<string, Awaited<ReturnType<typeof database.getUser>>>();\n allUserIds.forEach((userId, i) => {\n const profile = profileResults[i] ?? null;\n const user = userResults[i] ?? null;\n if (profile) profileMap.set(userId, profile);\n if (user) userMap.set(userId, user);\n });\n\n const isDigestMode = context.isMcp === true && query.includeDigestMarkers === true;\n const cardDataList: Array<Record<string, unknown> & { opportunityId: string }> = [];\n const seenOpportunityIds = new Set<string>();\n\n if (isDigestMode) {\n // ── Digest mode: use LLM presenter for rich, second-person card text ──\n const presenter = new OpportunityPresenter();\n const presenterDb: PresenterDatabase = database;\n const PRESENTER_CONCURRENCY = 6;\n\n for (let i = 0; i < opportunities.length; i += PRESENTER_CONCURRENCY) {\n const chunk = opportunities.slice(i, i + PRESENTER_CONCURRENCY);\n const chunkCards = await Promise.all(\n chunk.map(async (opp) => {\n if (seenOpportunityIds.has(opp.id)) return null;\n seenOpportunityIds.add(opp.id);\n try {\n const counterpartActor = opp.actors.find(\n (a) => a.userId !== context.userId && a.role !== \"introducer\",\n );\n const counterpartUserId = counterpartActor?.userId;\n if (!counterpartUserId) return null;\n\n const viewerIsIntroducerHere = opp.actors.some(\n (a) => a.role === \"introducer\" && a.userId === context.userId,\n );\n const secondPartyActorForHeadline = viewerIsIntroducerHere\n ? opp.actors.find(\n (a) =>\n a.userId !== context.userId &&\n a.userId !== counterpartUserId &&\n a.role !== \"introducer\",\n )\n : undefined;\n\n const introducerActor = opp.actors.find(\n (a) => a.role === \"introducer\" && a.userId !== context.userId,\n );\n const createdByName = opp.detection.createdByName;\n\n const counterpartUser = userMap.get(counterpartUserId) ?? null;\n const counterpartName =\n profileMap.get(counterpartUserId)?.identity?.name ??\n counterpartUser?.name ??\n \"Someone\";\n const introducerName =\n createdByName ??\n (introducerActor\n ? (profileMap.get(introducerActor.userId)?.identity?.name ?? null)\n : null);\n const introducerUser = introducerActor\n ? userMap.get(introducerActor.userId) ?? null\n : null;\n\n const secondPartyUser = secondPartyActorForHeadline\n ? userMap.get(secondPartyActorForHeadline.userId) ?? null\n : null;\n const secondPartyNameForHeadline = secondPartyActorForHeadline\n ? (profileMap.get(secondPartyActorForHeadline.userId)?.identity?.name ??\n secondPartyUser?.name ??\n undefined)\n : undefined;\n\n const viewerActor = opp.actors.find((a) => a.userId === context.userId);\n const viewerRole = viewerActor?.role ?? \"party\";\n const isCounterpartGhost = counterpartUser?.isGhost ?? false;\n\n try {\n const ctx = await gatherPresenterContext(\n presenterDb,\n opp,\n context.userId,\n counterpartUserId,\n );\n\n const presentation = await presenter.presentHomeCard({\n ...ctx,\n opportunityStatus: opp.status,\n });\n\n // Build narrator chip from presenter output\n let narratorChip: { name: string; text: string; avatar?: string | null; userId?: string };\n const introducerIsCounterpart = introducerActor && counterpartActor && introducerActor.userId === counterpartActor.userId;\n if (introducerActor && introducerActor.userId !== context.userId && !introducerIsCounterpart) {\n const narratorName = introducerName?.trim() || \"Someone\";\n narratorChip = {\n name: narratorName,\n text: stripLeadingNarratorName(presentation.narratorRemark, narratorName),\n avatar: introducerUser?.avatar ?? null,\n userId: introducerActor.userId,\n };\n } else if (introducerActor?.userId === context.userId) {\n narratorChip = { name: \"You\", text: presentation.narratorRemark, userId: context.userId };\n } else {\n narratorChip = { name: \"Index\", text: presentation.narratorRemark };\n }\n\n const card: Record<string, unknown> = {\n opportunityId: opp.id,\n userId: counterpartUserId,\n name: counterpartName,\n avatar: counterpartUser?.avatar ?? null,\n mainText: stripUuids(presentation.personalizedSummary),\n digestSummary: stripUuids(presentation.digestSummary),\n cta: presentation.suggestedAction,\n headline: viewerIsIntroducerHere && secondPartyNameForHeadline\n ? `${counterpartName} → ${secondPartyNameForHeadline}`\n : presentation.headline,\n primaryActionLabel: getPrimaryActionLabel(viewerRole),\n secondaryActionLabel: SECONDARY_ACTION_LABEL,\n mutualIntentsLabel: presentation.mutualIntentsLabel,\n narratorChip,\n viewerRole,\n score: typeof opp.interpretation?.confidence === \"number\"\n ? opp.interpretation.confidence\n : undefined,\n status: opp.status,\n isGhost: isCounterpartGhost,\n ...(viewerIsIntroducerHere && secondPartyNameForHeadline\n ? {\n secondParty: {\n name: secondPartyNameForHeadline,\n ...(secondPartyUser?.avatar != null ? { avatar: secondPartyUser.avatar } : {}),\n ...(secondPartyActorForHeadline?.userId ? { userId: secondPartyActorForHeadline.userId } : {}),\n },\n }\n : {}),\n };\n\n // Attach actionable links for MCP callers\n if (context.isMcp && deps.mintConnectLink) {\n const viewerApproved =\n viewerActor?.role === \"introducer\" ? viewerActor.approved === true : undefined;\n await attachActionableLinks(card as Record<string, unknown> & {\n opportunityId: string;\n viewerRole: string;\n status: string;\n }, {\n viewerId: context.userId,\n viewerApproved,\n counterpartUserId,\n mintConnectLink: deps.mintConnectLink,\n frontendUrl: deps.frontendUrl,\n preferredSurface: context.clientSurface,\n });\n }\n\n return card as Record<string, unknown> & { opportunityId: string };\n } catch (presenterErr) {\n logger.warn(\"LLM presenter failed for list_opportunities digest card, skipping raw fallback\", {\n opportunityId: opp.id,\n err: presenterErr,\n });\n // Scheduled digests should only surface OpportunityPresenter-rendered\n // copy. The minimal fallback reuses evaluator reasoning, which can\n // contain raw narrator phrasing (for example \"The discoverer...\")\n // and is not suitable for AgentVillage morning briefs.\n skippedIds.push(opp.id);\n return null;\n }\n } catch (err) {\n logger.warn(\"Skipping opportunity that failed to build card\", {\n opportunityId: opp.id,\n err,\n });\n skippedIds.push(opp.id);\n return null;\n }\n }),\n );\n for (const card of chunkCards) {\n if (card) cardDataList.push(card);\n }\n }\n } else {\n // ── Chat mode: fast heuristic path (no LLM) ──\n for (const opp of opportunities) {\n if (seenOpportunityIds.has(opp.id)) continue;\n seenOpportunityIds.add(opp.id);\n try {\n const counterpartActor = opp.actors.find(\n (a) => a.userId !== context.userId && a.role !== \"introducer\",\n );\n const counterpartUserId = counterpartActor?.userId;\n if (!counterpartUserId) continue;\n\n const viewerIsIntroducerHere = opp.actors.some(\n (a) => a.role === \"introducer\" && a.userId === context.userId,\n );\n const secondPartyActorForHeadline = viewerIsIntroducerHere\n ? opp.actors.find(\n (a) =>\n a.userId !== context.userId &&\n a.userId !== counterpartUserId &&\n a.role !== \"introducer\",\n )\n : undefined;\n const secondPartyNameForHeadline = secondPartyActorForHeadline\n ? (profileMap.get(secondPartyActorForHeadline.userId)?.identity?.name ??\n userMap.get(secondPartyActorForHeadline.userId)?.name ??\n undefined)\n : undefined;\n\n const introducerActor = opp.actors.find(\n (a) => a.role === \"introducer\" && a.userId !== context.userId,\n );\n const createdByName = opp.detection.createdByName;\n\n const counterpartProfile = profileMap.get(counterpartUserId) ?? null;\n const counterpartUser = userMap.get(counterpartUserId) ?? null;\n const introducerProfile =\n introducerActor && !createdByName\n ? profileMap.get(introducerActor.userId) ?? null\n : null;\n\n const counterpartName =\n counterpartProfile?.identity?.name ??\n counterpartUser?.name ??\n \"Someone\";\n const introducerName =\n createdByName ??\n (introducerActor ? introducerProfile?.identity?.name ?? null : null);\n const introducerUser = introducerActor\n ? userMap.get(introducerActor.userId) ?? null\n : null;\n\n const secondPartyUser = secondPartyActorForHeadline\n ? userMap.get(secondPartyActorForHeadline.userId) ?? null\n : null;\n const cardData = buildMinimalOpportunityCard(\n opp,\n context.userId,\n counterpartUserId,\n counterpartName,\n counterpartUser?.avatar ?? null,\n introducerName,\n introducerUser?.avatar ?? null,\n viewerName,\n secondPartyNameForHeadline,\n secondPartyUser?.avatar ?? null,\n secondPartyActorForHeadline?.userId,\n );\n\n // For MCP callers (e.g. Edge Claw), mint a connect token and attach\n // acceptUrl + profileUrl when the (status, viewerRole) is actionable\n // for the viewer. Non-actionable combos (sender-on-draft,\n // pending-on-introducer-waiting, rejected, etc.) deliberately get\n // no link — the LLM would otherwise hallucinate `/api/.../connect`\n // URLs from the exposed opportunityId.\n if (context.isMcp && deps.mintConnectLink) {\n const viewerActor = opp.actors.find((a) => a.userId === context.userId);\n const viewerApproved =\n viewerActor?.role === \"introducer\" ? viewerActor.approved === true : undefined;\n await attachActionableLinks(cardData as Record<string, unknown> & {\n opportunityId: string;\n viewerRole: string;\n status: string;\n }, {\n viewerId: context.userId,\n viewerApproved,\n counterpartUserId,\n mintConnectLink: deps.mintConnectLink,\n frontendUrl: deps.frontendUrl,\n preferredSurface: context.clientSurface,\n });\n }\n\n cardDataList.push(cardData);\n } catch (err) {\n logger.warn(\"Skipping opportunity that failed to build minimal card\", {\n opportunityId: opp.id,\n err,\n });\n skippedIds.push(opp.id);\n continue;\n }\n }\n }\n\n const listDebugSteps = buildListDebugSteps();\n\n if (cardDataList.length === 0) {\n if (skippedIds.length > 0) {\n return success({\n found: false,\n count: 0,\n summary: \"Some opportunities couldn't be displayed\",\n message:\n \"I found opportunities, but couldn't render them. Please try again.\",\n ...(listDebugSteps.length ? { debugSteps: listDebugSteps } : {}),\n });\n }\n return success({\n found: false,\n count: 0,\n summary: \"No opportunities yet\",\n message:\n \"You have no opportunities yet. Use discover_opportunities to find connections.\",\n });\n }\n\n return success({\n found: true,\n count: cardDataList.length,\n summary: `You have ${cardDataList.length} opportunity(ies)`,\n message: buildOpportunityPresentation(cardDataList, {\n isMcp: context.isMcp ?? false,\n leadIn: `You have ${cardDataList.length} opportunity(ies).`,\n includeDigestMarkers: context.isMcp === true && query.includeDigestMarkers === true,\n }),\n ...(listDebugSteps.length ? { debugSteps: listDebugSteps } : {}),\n });\n },\n });\n\n const updateOpportunity = defineTool({\n name: \"update_opportunity\",\n description:\n \"Updates an opportunity's status, advancing it through the connection lifecycle.\\n\\n\" +\n \"**Status transitions:**\\n\" +\n \"- `pending`: Sends a draft opportunity to the other party. They'll be notified and can accept or reject. \" +\n \"This is the primary action after discover_opportunities returns a draft.\\n\" +\n \"- `accepted`: Accept a received opportunity — opens a direct conversation between both parties. Returns a conversationId to surface to the user.\\n\" +\n \"- `rejected`: Decline a received opportunity.\\n\" +\n \"- `expired`: Mark as expired (typically done by the system after timeout).\\n\\n\" +\n \"**When to use:** After discover_opportunities or list_opportunities returns opportunity cards. \" +\n \"The user clicks 'Send' (pending), 'Accept', or 'Reject' on the card, and the agent calls this tool.\\n\\n\" +\n \"**Returns:** Confirmation with the new status and notification details (who was notified).\",\n querySchema: z.object({\n opportunityId: z\n .string()\n .describe(\"The UUID of the opportunity to update. Get from discover_opportunities or list_opportunities results.\"),\n status: z\n .enum([\"pending\", \"accepted\", \"rejected\", \"expired\"])\n .describe(\n \"New status: 'pending' = send the draft to the other party, 'accepted' = accept the connection, \" +\n \"'rejected' = decline, 'expired' = mark as timed out.\",\n ),\n }),\n handler: async ({ context, query }) => {\n const opportunityId = query.opportunityId?.trim();\n if (!opportunityId || !UUID_REGEX.test(opportunityId)) {\n return error(\"Valid opportunityId required.\");\n }\n\n // Always fetch the opportunity — needed for actor guard and state machine\n const opportunity = await systemDb.getOpportunity(opportunityId);\n if (!opportunity) {\n return error(\"Opportunity not found.\");\n }\n\n // Actor guard: caller must be a party to the opportunity\n const isActor = opportunity.actors?.some((a) => a.userId === context.userId);\n if (!isActor) {\n return error(\"Opportunity not found.\");\n }\n\n // Terminal-state and in-flight-negotiation guard.\n // Not a full state-machine: the Zod enum already constrains the target status,\n // and source statuses like `draft` / `latent` remain permitted.\n if (UPDATE_OPPORTUNITY_BLOCKED_STATUSES.has(opportunity.status)) {\n return error(`This opportunity is already ${opportunity.status} and cannot be updated.`);\n }\n\n // Strict scope enforcement: when chat is index-scoped, the caller's own\n // actor entry on this opportunity must be anchored on the bound network.\n // Mirrors the per-actor filter in getOpportunitiesForUser — relying on\n // `context.networkId` or any-actor matches would let a counterpart's\n // network presence shadow a viewer whose own actor is elsewhere.\n if (context.networkId) {\n const callerOnBoundNetwork = opportunity.actors?.some(\n (a) => a.userId === context.userId && a.networkId === context.networkId,\n );\n if (!callerOnBoundNetwork) {\n return error(\"Opportunity not found.\");\n }\n }\n\n const isSend = query.status === \"pending\";\n const _updateGraphStart = Date.now();\n const _updateTraceEmitter = requestContext.getStore()?.traceEmitter;\n _updateTraceEmitter?.({ type: \"graph_start\", name: \"opportunity\" });\n const result = await invokeWithAbortSignal(graphs.opportunity, {\n userId: context.userId,\n operationMode: isSend ? (\"send\" as const) : (\"update\" as const),\n opportunityId: query.opportunityId,\n ...(isSend ? {} : { newStatus: query.status }),\n });\n const _updateGraphMs = Date.now() - _updateGraphStart;\n _updateTraceEmitter?.({ type: \"graph_end\", name: \"opportunity\", durationMs: _updateGraphMs });\n\n if (result.mutationResult) {\n if (result.mutationResult.success) {\n return success({\n opportunityId: result.mutationResult.opportunityId,\n status: query.status,\n message: result.mutationResult.message,\n ...(result.mutationResult.notified && { notified: result.mutationResult.notified }),\n ...(result.mutationResult.conversationId && {\n conversationId: result.mutationResult.conversationId,\n }),\n _graphTimings: [{ name: 'opportunity', durationMs: _updateGraphMs, agents: result.agentTimings ?? [] }],\n });\n }\n return error(result.mutationResult.error || \"Failed to update opportunity.\");\n }\n return error(\"Failed to update opportunity.\");\n },\n });\n\n const confirmOpportunityDelivery = defineTool({\n name: \"confirm_opportunity_delivery\",\n description:\n \"Marks an opportunity as delivered to the user via the OpenClaw channel. \" +\n \"Call this for each opportunity you decide to surface, BEFORE including it in your delivery message. \" +\n \"The 'trigger' argument records which dispatch path produced this delivery: \" +\n \"'ambient' for real-time critical alerts (target ≤3/day), 'digest' for the daily sweep, \" +\n \"'accepted' for accepted-opportunity notifications to the counterparty. \" +\n \"Idempotent — safe to call even if the opportunity was already confirmed.\",\n querySchema: z.object({\n opportunityId: z\n .string()\n .describe(\"The UUID of the opportunity to mark as delivered.\"),\n trigger: z\n .enum(['ambient', 'digest', 'accepted'])\n .describe(\n \"Which dispatch path produced this delivery. Use 'ambient' if the dispatch prompt says you are in the ambient pass; use 'digest' if it says you are in the daily digest; use 'accepted' for accepted-opportunity notifications to the counterparty.\",\n ),\n }),\n handler: async ({ context, query }) => {\n if (!context.isMcp || !context.agentId) {\n return error(\n \"confirm_opportunity_delivery is only available to authenticated agent MCP contexts.\",\n );\n }\n if (!deps.deliveryLedger) {\n return error(\"Delivery ledger not available in this context.\");\n }\n if (!UUID_REGEX.test(query.opportunityId)) {\n return error(\"Invalid opportunity ID format.\");\n }\n try {\n const result = await deps.deliveryLedger.confirmOpportunityDelivery({\n opportunityId: query.opportunityId,\n userId: context.userId,\n agentId: context.agentId,\n trigger: query.trigger,\n });\n return success({ status: result });\n } catch (err) {\n logger.error('Failed to confirm opportunity delivery', { err });\n return error('Failed to confirm opportunity delivery. Please try again.');\n }\n },\n });\n\n return [\n discoverOpportunities,\n getDiscoveryRun,\n cancelDiscoveryRun,\n listOpportunities,\n updateOpportunity,\n confirmOpportunityDelivery,\n ] as const;\n}\n"]}
1
+ {"version":3,"file":"opportunity.tools.js","sourceRoot":"/","sources":["opportunity/opportunity.tools.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from \"zod\";\n\nimport { requestContext } from \"../shared/observability/request-context.js\";\n\nimport type { DefineTool, ToolDeps } from \"../shared/agent/tool.helpers.js\";\nimport { success, error, UUID_REGEX } from \"../shared/agent/tool.helpers.js\";\nimport { MINIMAL_MAIN_TEXT_MAX_CHARS, getPrimaryActionLabel, SECONDARY_ACTION_LABEL } from \"./opportunity.labels.js\";\nimport { viewerCentricCardSummary, narratorRemarkFromReasoning, stripUuids } from \"./opportunity.presentation.js\";\nimport { runDiscoverFromQuery, continueDiscovery } from \"./opportunity.discover.js\";\nimport { OpportunityPresenter, gatherPresenterContext, type PresenterDatabase } from \"./opportunity.presenter.js\";\n\nfunction stripLeadingNarratorName(remark: string, narratorName: string): string {\n let t = remark.trim();\n if (!t || !narratorName.trim()) return remark;\n const name = narratorName.trim();\n const nameLower = name.toLowerCase();\n for (;;) {\n const lower = t.toLowerCase();\n if (!lower.startsWith(nameLower)) break;\n // Require a word boundary after the name so a short name like \"Al\" does not\n // mangle a longer word (\"Always …\" → \"ways …\"). The char after the name must\n // be a separator (sentence/clause punctuation or whitespace) or end of string.\n // Keep this set in sync with the separator stripped from `rest` below.\n const boundary = t.charAt(name.length);\n if (boundary && !/[\\s.:,\\-–—]/.test(boundary)) break;\n const rest = t.slice(name.length).replace(/^\\s*[.:,\\-–—]\\s*/i, '').trim();\n if (rest.length === 0 || rest === t) break;\n t = rest;\n }\n return t;\n}\nimport type { EvaluatorEntity } from \"./opportunity.evaluator.js\";\nimport { protocolLogger } from \"../shared/observability/protocol.logger.js\";\nimport type { Opportunity, OpportunityStatus } from \"../shared/interfaces/database.interface.js\";\nimport type { DiscoveryRunInput } from \"../shared/interfaces/discovery-run.interface.js\";\nimport type { ConnectLinkKind } from \"../shared/interfaces/connect-link.interface.js\";\nimport { selectByComposition, deduplicateByPerson, selectDigestCandidates, type DigestDeliveredRow } from \"./opportunity.utils.js\";\nimport { mergePendingQuestions } from \"./opportunity.pending-questions.js\";\nimport { invokeWithAbortSignal } from \"../shared/agent/model-signal.js\";\n\nconst logger = protocolLogger(\"ChatTools:Opportunity\");\n\n/**\n * Pure status × role → ConnectLinkKind matrix.\n *\n * Returns the kind of short-link the viewer can act on directly, or `null` if\n * no direct link makes sense for this combination. Non-null kinds map to:\n *\n * - `connect` — pending opp where viewer is a non-introducer party. Clicking\n * flips the opp to accepted and opens the chat with the counterpart.\n * - `approve_introduction` — draft or latent opp where viewer is an unapproved\n * introducer. Clicking flips approved=true and triggers negotiation. The\n * `draft` case comes from `discover_opportunities` intro mode; the `latent`\n * case comes from background-discovered connector-flow cards surfaced in\n * `list_opportunities`. In both, status remains pre-send and the `/c/<code>`\n * link is the only MCP path to approve.\n * - `outreach` — accepted opp where viewer is a non-introducer party.\n * Clicking opens the existing chat (no state change).\n * - `send_direct` — draft or latent opp where viewer is a non-introducer\n * party. Issued by `discover_opportunities` in direct (no-introducer)\n * mode: the match has already passed evaluation, the row exists in\n * draft state, and the sender just needs to release it. Clicking flips\n * the opp straight to accepted and opens the chat with a greeting —\n * same handler path as `connect`. The counterpart's side sees the new\n * accepted opp and can engage or ignore.\n */\nexport function resolveActionableLinkKind(input: {\n status: string;\n viewerRole: string;\n viewerApproved?: boolean;\n}): ConnectLinkKind | null {\n const { status, viewerRole, viewerApproved } = input;\n const isIntroducer = viewerRole === \"introducer\";\n if (status === \"accepted\") {\n return isIntroducer ? null : \"outreach\";\n }\n if (status === \"pending\") {\n return isIntroducer ? null : \"connect\";\n }\n if (status === \"draft\" || status === \"latent\") {\n if (!isIntroducer) return \"send_direct\";\n return viewerApproved === true ? null : \"approve_introduction\";\n }\n return null;\n}\n\n/**\n * Build the agent-facing profile link for a counterpart — always the Index web\n * profile URL with `?link_preview=false`. Returns `undefined` only if\n * `frontendUrl` is not configured.\n *\n * The `?link_preview=false` hint is honored by chat-gateway runtimes (e.g.\n * OpenClaw's Telegram delivery) that strip link previews when present in the\n * URL; consistent placement matters more than Telegram's own handling.\n *\n * Trailing slashes on frontendUrl are stripped before concatenation.\n */\nexport function buildProfileUrl(\n counterpartUserId: string,\n frontendUrl: string | undefined,\n): string | undefined {\n // The profile link is always the Index web profile, regardless of the\n // counterpart's socials or the viewer's surface. Surface-aware Telegram\n // deep-linking lives on the connect URL (`/c/:code`) — the connect-link\n // controller resolves that to a pre-messaged t.me link — never here.\n if (!frontendUrl) return undefined;\n const base = frontendUrl.replace(/\\/+$/, \"\");\n return `${base}/u/${counterpartUserId}?link_preview=false`;\n}\n\n/**\n * Mint a short-link for `card` if the (status, viewerRole, viewerApproved)\n * combination is actionable; mutate the card in place with `acceptUrl`,\n * `profileUrl`, and `feedCategory`. No-op (and no DB call) if not actionable.\n *\n * Swallows mint errors after logging — the card is still returned without an\n * `acceptUrl`, matching the prior `list_opportunities` resilience behavior.\n */\nexport async function attachActionableLinks(\n card: Record<string, unknown> & {\n opportunityId: string;\n viewerRole: string;\n status: string;\n },\n opts: {\n viewerId: string;\n viewerApproved?: boolean;\n counterpartUserId: string;\n mintConnectLink: NonNullable<ToolDeps[\"mintConnectLink\"]>;\n frontendUrl: string | undefined;\n preferredSurface?: 'telegram' | 'web';\n },\n): Promise<void> {\n // profileUrl is independent of whether the (status, viewerRole) combination\n // is actionable — every counterpart has a profile page worth linking to,\n // even on a fresh draft where there is no acceptUrl yet. Setting it before\n // the early-return below means cards from non-actionable combinations\n // (e.g. draft + party in `discover_opportunities` direct mode) still carry\n // the profile link the agent needs to render. Without this, the agent gets\n // a name with no URL attached and tends to fabricate one.\n const profileUrl = buildProfileUrl(opts.counterpartUserId, opts.frontendUrl);\n if (profileUrl) card.profileUrl = profileUrl;\n\n const kind = resolveActionableLinkKind({\n status: card.status,\n viewerRole: card.viewerRole,\n viewerApproved: opts.viewerApproved,\n });\n logger.info(\"Opportunity actionability decision\", {\n opportunityId: card.opportunityId,\n status: card.status,\n viewerRole: card.viewerRole,\n viewerApproved: opts.viewerApproved,\n kind: kind ?? \"none\",\n });\n if (kind === null) return;\n\n try {\n const { url } = await opts.mintConnectLink({\n userId: opts.viewerId,\n opportunityId: card.opportunityId,\n kind,\n greeting: null,\n preferredSurface: opts.preferredSurface,\n });\n card.acceptUrl = url;\n card.feedCategory = card.viewerRole === \"introducer\" ? \"connector-flow\" : \"connection\";\n } catch (err) {\n logger.warn(\n \"Failed to mint MCP opportunity link — surfacing card without acceptUrl/feedCategory; profileUrl is still attached\",\n {\n opportunityId: card.opportunityId,\n kind,\n error: err instanceof Error ? err.message : String(err),\n },\n );\n }\n}\n\n/**\n * Statuses for which `update_opportunity` must refuse mutations.\n * - `accepted` / `rejected` / `expired`: terminal outcomes.\n * - `negotiating`: in-flight system-driven turn; user-driven mutations would\n * race the negotiation graph. The graph itself transitions out of this state.\n */\nconst UPDATE_OPPORTUNITY_BLOCKED_STATUSES = new Set<OpportunityStatus>([\n \"accepted\",\n \"rejected\",\n \"expired\",\n \"negotiating\",\n]);\n\n/**\n * Maximum number of opportunity cards to show per chat response.\n * Sized for `selectByComposition` to fill both feed buckets — up to 3\n * connection + 3 connector-flow per the digest/ambient prompt rules.\n */\nconst CHAT_DISPLAY_LIMIT = 6;\n\n/**\n * Wider fetch budget so `selectByComposition` has both buckets to balance\n * across, even when one category dominates the natural sort order.\n */\nconst CHAT_FETCH_LIMIT = 30;\n\n/**\n * How many accepted opportunities to scan when building the digest's\n * accepted-counterpart suppression set. Wide enough to cover a month-long\n * popup's accept history without unbounded reads.\n */\nconst ACCEPTED_SUPPRESSION_FETCH_LIMIT = 200;\n\n/** Markdown code fence (three backticks). Avoids embedding ``` in string literals so TS parser stays in sync. */\nconst CODE_FENCE = String.fromCharCode(96, 96, 96);\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/**\n * Build minimal opportunity card data for chat without calling the LLM presenter.\n * Uses only required fields from the opportunity record and counterpart name/avatar\n * so list_opportunities and discovery return quickly.\n *\n * Note: narratorChip.text is generated via regex heuristics (narratorRemarkFromReasoning)\n * rather than the OpportunityPresenter LLM. If narrator quality becomes an issue again,\n * consider making this function async and delegating to OpportunityPresenter.presentHomeCard()\n * which already produces a high-quality narratorRemark via LLM (used by the home graph\n * and discovery pipeline). The trade-off is 5-20s latency per card.\n *\n * Exported for use in tests (opportunity.tools.spec.ts).\n */\nexport function buildMinimalOpportunityCard(\n opp: Opportunity,\n viewerId: string,\n counterpartUserId: string,\n counterpartName: string,\n counterpartAvatar: string | null,\n introducerName?: string | null,\n introducerAvatar?: string | null,\n viewerName?: string,\n secondPartyName?: string,\n secondPartyAvatar?: string | null,\n secondPartyUserId?: string,\n isCounterpartGhost?: boolean,\n): {\n opportunityId: string;\n userId: string;\n name: string;\n avatar: string | null;\n mainText: string;\n cta: string;\n headline: string;\n primaryActionLabel: string;\n secondaryActionLabel: string;\n mutualIntentsLabel: string;\n narratorChip: { name: string; text: string; avatar?: string | null; userId?: string };\n viewerRole: string;\n score: number | undefined;\n status: string;\n isGhost: boolean;\n secondParty?: { name: string; avatar?: string | null; userId?: string };\n} {\n const viewerActor = opp.actors.find((a) => a.userId === viewerId);\n const viewerRole = viewerActor?.role ?? \"party\";\n const introducerActor = opp.actors.find(\n (a) => a.role === \"introducer\" && a.userId !== viewerId,\n );\n const viewerIsIntroducer = opp.actors.some(\n (a) => a.role === \"introducer\" && a.userId === viewerId,\n );\n const reasoning = opp.interpretation?.reasoning ?? \"\";\n const mainText = viewerCentricCardSummary(\n reasoning,\n counterpartName,\n MINIMAL_MAIN_TEXT_MAX_CHARS,\n viewerName,\n introducerName ?? undefined,\n );\n const score =\n typeof opp.interpretation?.confidence === \"number\"\n ? opp.interpretation.confidence\n : undefined;\n const narratorName = viewerIsIntroducer\n ? \"You\"\n : introducerName?.trim() || (introducerActor ? \"Someone\" : \"Index\");\n const primaryActionLabel = getPrimaryActionLabel(viewerRole);\n return {\n opportunityId: opp.id,\n userId: counterpartUserId,\n name: counterpartName,\n avatar: counterpartAvatar,\n mainText,\n cta: \"Start a conversation to connect.\",\n headline: viewerIsIntroducer && secondPartyName\n ? `${counterpartName} → ${secondPartyName}`\n : `Connection with ${counterpartName}`,\n primaryActionLabel,\n secondaryActionLabel: SECONDARY_ACTION_LABEL,\n mutualIntentsLabel: \"Suggested connection\",\n narratorChip: {\n name: narratorName,\n text: narratorRemarkFromReasoning(reasoning, counterpartName, viewerName),\n ...(viewerIsIntroducer\n ? { userId: viewerId, avatar: null }\n : introducerActor\n ? { userId: introducerActor.userId, avatar: introducerAvatar ?? null }\n : {}),\n },\n viewerRole,\n score,\n status: opp.status ?? \"latent\",\n isGhost: isCounterpartGhost ?? false,\n ...(viewerIsIntroducer && secondPartyName\n ? {\n secondParty: {\n name: secondPartyName,\n ...(secondPartyAvatar != null ? { avatar: secondPartyAvatar } : {}),\n ...(secondPartyUserId ? { userId: secondPartyUserId } : {}),\n },\n }\n : {}),\n };\n}\n\n/**\n * Minimal shape consumed by buildOpportunityPresentation for prose rendering.\n * Card data objects in the codebase carry additional frontend-only fields;\n * only these are surfaced to MCP agents.\n */\ntype OpportunityCardLike = Record<string, unknown> & {\n opportunityId: string;\n userId?: string | undefined;\n name?: string | undefined;\n mainText?: string | undefined;\n digestSummary?: string | undefined;\n status?: string | undefined;\n feedCategory?: string | undefined;\n acceptUrl?: string | undefined;\n profileUrl?: string | undefined;\n score?: number | undefined;\n /** Digest-mode cooldown re-show — the user has seen this card before. */\n redelivery?: boolean | undefined;\n};\n\n/**\n * Format opportunity cards into the \"opportunities\" portion of a tool response.\n *\n * Web chat (`isMcp=false`): emits ```opportunity``` code fences with an\n * \"include EXACTLY as-is\" directive so the frontend card renderer can parse\n * and render interactive cards.\n *\n * MCP (`isMcp=true`): emits prose (name, reason, status, profileUrl when\n * present, acceptUrl when present, feedCategory when present) and includes\n * `opportunityId` ONLY for cards without an `acceptUrl` — exposing the UUID\n * alongside an actionable link gave LLMs a foothold to hallucinate bare\n * `/api/opportunities/<id>/connect` URLs (see IND-271). The trailing\n * instruction reminds the agent to synthesize in natural language and never\n * fabricate URLs for cards that don't have them. MCP clients have no card\n * renderer, so code fences would surface as raw JSON to end users.\n */\nexport function buildOpportunityPresentation(\n cards: OpportunityCardLike[],\n opts: {\n isMcp: boolean;\n leadIn: string;\n label?: \"opportunity\" | \"opportunities\";\n /** Include hidden digest metadata markers so scheduled brief tooling can confirm delivery. */\n includeDigestMarkers?: boolean;\n },\n): string {\n if (cards.length === 0) return opts.leadIn;\n\n if (opts.isMcp) {\n const prose = cards\n .map((card, i) => {\n const lines: string[] = [`${i + 1}. ${card.name ?? \"Unknown\"}`];\n if (opts.includeDigestMarkers) {\n const markerId = String(card.opportunityId).replace(/[\\s>]/g, \"\");\n if (markerId) lines.push(` <!-- digest-opportunity:id=${markerId} -->`);\n }\n if (opts.includeDigestMarkers && card.digestSummary) {\n lines.push(` ${card.digestSummary}`);\n } else if (card.mainText) {\n lines.push(` ${card.mainText}`);\n }\n if (card.status) lines.push(` status: ${card.status}`);\n if (card.profileUrl) lines.push(` profileUrl: ${card.profileUrl}`);\n if (card.acceptUrl) lines.push(` acceptUrl: ${card.acceptUrl}`);\n if (card.feedCategory) lines.push(` feedCategory: ${card.feedCategory}`);\n if (opts.includeDigestMarkers && card.score != null) lines.push(` confidence: ${Math.round(card.score * 100)}`);\n if (opts.includeDigestMarkers && card.redelivery) lines.push(` redelivery: true`);\n // Only surface opportunityId when there's no acceptUrl. Exposing the\n // UUID alongside an actionable link gives the LLM a foothold to\n // hallucinate bare `/api/opportunities/<id>/connect` URLs.\n if (!card.acceptUrl) {\n lines.push(` opportunityId: ${card.opportunityId}`);\n }\n return lines.join(\"\\n\");\n })\n .join(\"\\n\\n\");\n const hasLinks = cards.some((c) => c.acceptUrl);\n const hasOpportunityIds = cards.some((c) => !c.acceptUrl);\n const linkInstructions = hasLinks\n ? `For each card that has an acceptUrl, embed it on a short verb phrase (e.g. \"message [Name]\" for connection, \"make intro\" for connector-flow). For each card that has a profileUrl, link the person's name to it. Some cards may have neither — render those as plain text and never fabricate URLs for them. The acceptUrl is opaque and self-contained — embed it verbatim. Do NOT append, encode, or modify any part of any URL. Never render link strips or tables — weave URLs into prose. `\n : \"\";\n const idInstructions = hasOpportunityIds\n ? `Use opportunityId values only when calling update_opportunity (send/accept/reject) or confirm_opportunity_delivery.`\n : \"\";\n return (\n `${opts.leadIn}\\n\\n${prose}\\n\\n` +\n `Summarize these for the user in natural prose — mention first names and a brief match reason per connection. ` +\n `${linkInstructions}` +\n `Do NOT print raw JSON, field labels, or opportunityIds. ` +\n `${idInstructions}`\n );\n }\n\n const label = opts.label ?? (cards.length === 1 ? \"opportunity\" : \"opportunities\");\n const blocks = cards\n .map(\n (card) =>\n CODE_FENCE + \"opportunity\\n\" + sanitizeJsonForCodeFence(JSON.stringify(card)) + \"\\n\" + CODE_FENCE,\n )\n .join(\"\\n\\n\");\n return (\n `${opts.leadIn} IMPORTANT: Include the following ${CODE_FENCE}${label} code blocks EXACTLY as-is in your response (they render as interactive cards):\\n\\n${blocks}`\n );\n}\n\n/**\n * Stable signature of a discovery request, used to coalesce duplicate MCP runs.\n * Two requests with the same signature describe the same discovery and should\n * share a single in-flight run rather than each spawning a fresh (expensive)\n * opportunity-graph execution. Text fields are normalized (trim + lowercase);\n * id lists are sorted so ordering does not matter.\n *\n * Encoded as JSON of a normalized object — NOT a delimiter join — so a\n * user-supplied string containing the delimiter can never make two distinct\n * requests collide. `hint` and each entity's `networkId` are included because\n * they change the discovery result (different reason / different shared index),\n * so requests that differ only in those must NOT coalesce. Natural-language\n * fields (`searchQuery`, `hint`) are lowercased; identifiers and the opaque\n * `continueFrom` pagination token are only trimmed (case-sensitive) so distinct\n * tokens never collapse together.\n */\nfunction discoveryRunSignature(input: DiscoveryRunInput, scopeKey: string): string {\n const text = (s?: string) => (s ?? \"\").trim().toLowerCase();\n const id = (s?: string) => (s ?? \"\").trim();\n // Encode each entity as a JSON tuple string, then sort the strings — a stable\n // total order with a correct comparator (default Array#sort on strings).\n const entities = [...(input.entities ?? [])]\n .map((e) => JSON.stringify([id(e.networkId), id(e.userId)]))\n .sort();\n return JSON.stringify({\n searchQuery: text(input.searchQuery),\n networkId: id(input.networkId),\n intentId: id(input.intentId),\n targetUserId: id(input.targetUserId),\n introTargetUserId: id(input.introTargetUserId),\n continueFrom: id(input.continueFrom),\n hint: text(input.hint),\n partyUserIds: [...(input.partyUserIds ?? [])].map((x) => x.trim()).sort(),\n entities,\n scope: scopeKey,\n });\n}\n\n/**\n * Stable key for the resolved discovery scope of a request. Two requests\n * coalesce only when they resolve to the same reach — the focus index\n * (`networkId`) and the full reachable `indexScope` set. When `query.networkId`\n * is omitted, scope comes from context (network-scoped agent vs unscoped\n * session), so folding it into the signature prevents a scoped caller from\n * coalescing onto an unscoped run and receiving out-of-scope opportunities.\n */\nfunction discoveryScopeKey(ctx: { networkId?: string; indexScope?: string[] }): string {\n return JSON.stringify({\n networkId: (ctx.networkId ?? \"\").trim(),\n indexScope: [...(ctx.indexScope ?? [])].map((s) => s.trim()).sort(),\n });\n}\n\n/**\n * Stable, retry-classified error codes for `confirm_opportunity_delivery`.\n *\n * The plain `error()` envelope only carries a human message, which forced\n * callers (the Hermes digest sweep) to treat every failure — permanent or\n * transient — as retryable, and made \"already delivered but never confirmed\"\n * impossible to distinguish from \"opportunity deleted\". Each code carries an\n * explicit `retryable` flag so deterministic callers can retry transient\n * failures and drop permanent ones instead of re-spamming the ledger.\n */\nexport type ConfirmDeliveryErrorCode =\n | \"unauthenticated\"\n | \"ledger_unavailable\"\n | \"invalid_opportunity_id\"\n | \"opportunity_not_found\"\n | \"not_authorized\"\n | \"confirm_failed\";\n\nfunction confirmDeliveryError(\n code: ConfirmDeliveryErrorCode,\n retryable: boolean,\n message: string,\n): string {\n return JSON.stringify({ success: false, error: message, code, retryable });\n}\n\nexport function createOpportunityTools(defineTool: DefineTool, deps: ToolDeps) {\n const { database, userDb, systemDb, graphs, cache } = deps;\n\n const discoverOpportunities = defineTool({\n name: \"discover_opportunities\",\n description:\n \"Discovers opportunities — connections between users based on complementary intents — and persists them as drafts. \" +\n \"Opportunities are the core output of the discovery engine, representing potential valuable connections between people.\\n\\n\" +\n \"**NOT for person lookup** — use read_user_profiles(query=name) to find people by name.\\n\\n\" +\n \"**Four modes:**\\n\" +\n \"1. **Discovery** (most common): pass `searchQuery` and/or `networkId`. The system finds other users in shared indexes \" +\n \"whose intents semantically complement the query. Uses HyDE embeddings and LLM evaluation for scoring.\\n\" +\n \"2. **Introduction**: pass `partyUserIds` (2+ user IDs) + `entities` (pre-gathered profiles and intents from shared indexes). \" +\n \"You MUST call read_user_profiles and read_intents for each party BEFORE calling this. \" +\n \"Optionally pass `hint` with the user's reason for the introduction.\\n\" +\n \"3. **Direct connection**: pass `targetUserId` + `searchQuery`. Creates an opportunity between the current user and one specific person.\\n\" +\n \"4. **Introducer discovery**: pass `introTargetUserId` (find matches FOR that person; current user becomes the introducer). \" +\n \"Use when user asks 'who should I introduce to [person]?'\\n\\n\" +\n \"**Returns:** In regular chat, opportunity code blocks (render as interactive cards) with opportunityId, match reasoning, confidence score, and status. \" +\n \"In MCP contexts, starts an async discovery run and returns `discoveryRunId` with status `queued`. \" +\n \"Then poll get_discovery_run with that id roughly every 5 seconds until status is `succeeded`, `failed`, or `cancelled`, and present its `result`. \" +\n \"Do NOT call discover_opportunities again for the same request while a run is in progress — a repeat call with the same parameters \" +\n \"returns the SAME in-progress run (with `coalesced: true`), not a new one. Keep polling the run id instead of starting new runs. \" +\n \"All results start as drafts. Supports pagination via `continueFrom` for large result sets.\\n\\n\" +\n \"**Next steps:** Use update_opportunity(opportunityId, status='pending') to send a draft to the other party.\\n\\n\" +\n \"**Discovery-first rule.** For open-ended connection-seeking requests (\\\"find me a mentor\\\", \" +\n \"\\\"who needs a React dev\\\", \\\"looking for investors\\\"), call this tool with `searchQuery` FIRST. \" +\n \"Do NOT call create_intent for these phrasings — create_intent is only for when the user explicitly \" +\n \"asks to \\\"create\\\", \\\"save\\\", \\\"add\\\", or \\\"remember\\\" a signal.\\n\\n\" +\n \"**Personal-index scoping.** When the user says \\\"in my network\\\", \\\"from my contacts\\\", \\\"people I know\\\", \" +\n \"or similar scoping language, pass the user's personal index ID (from memberships where `isPersonal: true`) \" +\n \"as `networkId`. The personal index contains the user's contacts — scoping discovery to it restricts \" +\n \"results to people the user already knows. Without this scoping language, omit networkId to let discovery \" +\n \"run across all indexes.\\n\\n\" +\n \"**Introduction mode prerequisites.** When using `partyUserIds` + `entities`, YOU must pre-fetch each party's \" +\n \"profile and intents before calling this tool. The entities array must include each party's userId, profile, \" +\n \"intents from shared indexes, and the shared networkId. Call read_user_profiles, read_network_memberships, \" +\n \"and read_intents for both parties first. The introducer (current user) must NOT appear in entities.\\n\\n\" +\n \"**Signal-visibility follow-up.** If the response includes `suggestIntentCreationForVisibility: true` and \" +\n \"`suggestedIntentDescription`, after presenting opportunity cards ask the user ONCE whether they'd also like \" +\n \"to create a signal so others can find them. On yes, call create_intent with the suggested description. \" +\n \"Never suggest this after introducer-mode (`introTargetUserId`) calls — the query describes the other person's \" +\n \"needs, not the signed-in user's.\",\n querySchema: z.object({\n continueFrom: z\n .string()\n .optional()\n .describe(\"Pagination token: pass the discoveryId from a previous discover_opportunities result to evaluate the next batch of candidates. Do not combine with searchQuery or other mode parameters — when a fresh searchQuery is also present, the server ignores continueFrom and runs a fresh discovery.\"),\n searchQuery: z\n .string()\n .optional()\n .describe(\"Discovery mode: natural language description of what to look for (e.g. 'AI/ML engineers', 'startup advisors in fintech'). Drives semantic matching against other users' intents and profiles.\"),\n networkId: z\n .string()\n .optional()\n .describe(\"Index UUID to scope discovery to a specific community. Get from read_networks. In an index-scoped chat, omitting this runs discovery across the full reachable scope (the bound community plus the user's personal index); pass an explicit networkId to force single-index discovery. Pass the personal index ID (from read_networks, isPersonal=true) to scope to the user's contacts only.\"),\n intentId: z\n .string()\n .optional()\n .describe(\"Optional intent UUID to use as the discovery source. The intent's description drives matching instead of searchQuery. Get from read_intents. Typically used by background processing, not direct agent calls.\"),\n targetUserId: z\n .string()\n .optional()\n .describe(\"Direct connection mode: create an opportunity with this specific user. Get the userId from read_user_profiles(query=name). Combine with searchQuery to explain the connection reason.\"),\n introTargetUserId: z\n .string()\n .optional()\n .describe(\n \"Introducer discovery mode: find matches FOR this user ID (the current user becomes the introducer). \" +\n \"Get the userId from read_user_profiles(query=name). \" +\n \"Use when the user asks 'who should I introduce to [person]?'. \" +\n \"Do NOT combine with partyUserIds (that's full introduction mode).\"\n ),\n partyUserIds: z\n .array(z.string())\n .optional()\n .describe(\"Introduction mode: array of 2+ user IDs to introduce to each other. Get user IDs from read_user_profiles or read_network_memberships. Must also provide entities with pre-gathered profile/intent data.\"),\n entities: z\n .array(\n z.object({\n userId: z.string(),\n profile: z\n .object({\n name: z.string().optional(),\n bio: z.string().optional(),\n location: z.string().optional(),\n interests: z.array(z.string()).optional(),\n skills: z.array(z.string()).optional(),\n context: z.string().optional(),\n })\n .optional(),\n intents: z\n .array(\n z.object({\n intentId: z.string(),\n payload: z.string(),\n summary: z.string().optional(),\n }),\n )\n .optional(),\n networkId: z\n .string()\n .describe(\"Shared index this entity's data comes from (required for intro mode)\"),\n }),\n )\n .optional()\n .describe(\n \"Introduction mode: pre-gathered profile and intent data for each party being introduced. \" +\n \"Each entry needs userId, networkId (the shared index), and optionally profile (name, bio, skills, interests) and intents (intentId, payload). \" +\n \"Gather this data by calling read_user_profiles and read_intents for each party BEFORE calling discover_opportunities. \" +\n \"All entities must share the same networkId (the shared index where both parties are members).\",\n ),\n hint: z\n .string()\n .optional()\n .describe(\n \"Introduction mode: the user's reason for making this introduction (e.g. 'both working on AI in healthcare', \" +\n \"'complementary skills for a startup'). Helps the evaluator produce better match reasoning.\",\n ),\n }),\n handler: async ({ context, query }) => {\n // Strict scope enforcement: when chat is index-scoped, only allow that index\n if (\n context.networkId &&\n query.networkId?.trim() &&\n query.networkId.trim() !== context.networkId\n ) {\n return error(\n `This chat is scoped to ${context.indexName ?? \"this index\"}. You can only create opportunities in this community.`,\n );\n }\n\n // Distinguish an explicit `query.networkId` override (caller wants discovery\n // scoped to one specific index) from an implicit scoped-chat context\n // (caller is in a scoped chat with no explicit override — discovery should\n // span the chat's reach, i.e. context.indexScope = [bound, personal]).\n // Conflating them via `context.networkId || query.networkId` made the\n // implicit branch unreachable.\n const explicitIndexId = query.networkId?.trim() || undefined;\n const effectiveIndexId = explicitIndexId;\n if (effectiveIndexId && !UUID_REGEX.test(effectiveIndexId)) {\n return error(\"Invalid network ID format.\");\n }\n\n if (context.isMcp && deps.discoveryRuns && deps.discoveryRunQueue) {\n // Coalesce: if an equivalent discovery is already queued/running for this\n // user, return that run instead of spawning a duplicate. An over-eager\n // MCP client that re-fires discover_opportunities (instead of polling\n // get_discovery_run) would otherwise kick off a fresh, expensive\n // opportunity-graph run on every call — the loop that drives the agent\n // into provider rate limits.\n const signature = discoveryRunSignature(\n query as DiscoveryRunInput,\n discoveryScopeKey(context),\n );\n try {\n const active = await deps.discoveryRuns.listActive(context.userId);\n const existing = active.find(\n (r) => discoveryRunSignature(r.input, discoveryScopeKey(r.context)) === signature,\n );\n if (existing) {\n return success({\n status: existing.status === \"running\" ? (\"running\" as const) : (\"queued\" as const),\n discoveryRunId: existing.id,\n coalesced: true,\n message:\n `A discovery run for this exact request is already ${existing.status}. ` +\n `Do NOT call discover_opportunities again — keep calling get_discovery_run with ` +\n `discoveryRunId=\"${existing.id}\" (about every 5 seconds) until it succeeds, fails, ` +\n `or is cancelled, then present its result.`,\n });\n }\n } catch {\n // listActive is a best-effort optimization; fall through to create on error.\n }\n\n const run = await deps.discoveryRuns.create({\n userId: context.userId,\n agentId: context.agentId ?? null,\n input: query as DiscoveryRunInput,\n context: {\n userId: context.userId,\n userName: context.userName,\n userEmail: context.userEmail,\n ...(context.networkId ? { networkId: context.networkId } : {}),\n ...(context.indexName ? { indexName: context.indexName } : {}),\n indexScope: context.indexScope,\n ...(context.sessionId ? { sessionId: context.sessionId } : {}),\n ...(context.agentId ? { agentId: context.agentId } : {}),\n ...(context.clientSurface ? { clientSurface: context.clientSurface } : {}),\n },\n });\n try {\n await deps.discoveryRunQueue.enqueue(run.id);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n await deps.discoveryRuns.markFailed(run.id, message);\n return error(`Failed to enqueue discovery run: ${message}`);\n }\n return success({\n status: \"queued\" as const,\n discoveryRunId: run.id,\n message:\n `Discovery started. Poll get_discovery_run with discoveryRunId=\"${run.id}\" about every 5 seconds ` +\n `until status is succeeded, failed, or cancelled, then present its result. ` +\n `Do NOT call discover_opportunities again for this request while the run is in progress — ` +\n `a repeat call returns this same run, not a new one.`,\n });\n }\n\n // ── Continuation mode ──\n // `continueFrom` is a pagination token for resuming a prior discovery's\n // cached candidates. When a caller (typically an MCP client's LLM) sends\n // a fresh `searchQuery` alongside a stale `continueFrom`, treat it as a\n // fresh search — the explicit search intent wins. Resuming against the\n // stale session's exhausted cache silently produced the \"No more\n // matching opportunities found in the remaining candidates\" response\n // for users who expected fresh results (IND-305).\n if (query.continueFrom && query.searchQuery?.trim()) {\n logger.warn(\"discover_opportunities: dropping stale continueFrom in favor of fresh searchQuery\", {\n userId: context.userId,\n continueFrom: query.continueFrom,\n });\n }\n if (query.continueFrom && !query.searchQuery?.trim()) {\n const _continueTraceEmitter = requestContext.getStore()?.traceEmitter;\n const _graphStart = Date.now();\n _continueTraceEmitter?.({ type: \"graph_start\", name: \"opportunity\" });\n const result = await continueDiscovery({\n opportunityGraph: graphs.opportunity,\n database,\n cache,\n userId: context.userId,\n discoveryId: query.continueFrom,\n expectedIndexId: context.networkId,\n limit: 20,\n presenter: new OpportunityPresenter(),\n useHomeCardFormat: true,\n ...(context.sessionId ? { chatSessionId: context.sessionId } : {}),\n });\n const _graphMs = Date.now() - _graphStart;\n _continueTraceEmitter?.({ type: \"graph_end\", name: \"opportunity\", durationMs: _graphMs });\n\n const allDebugSteps = [...(result.debugSteps ?? [])];\n\n if (!result.found) {\n return success({\n found: false,\n count: 0,\n message: result.message ?? \"No more matching opportunities found in the remaining candidates.\",\n summary: \"No more matches found\",\n ...(result.pagination ? { pagination: result.pagination } : {}),\n debugSteps: allDebugSteps,\n _graphTimings: [{ name: 'opportunity', durationMs: _graphMs, agents: [] }],\n });\n }\n\n // Build card data; cap at CHAT_DISPLAY_LIMIT (remaining feeds into pagination)\n const allCardData = (result.opportunities ?? []).map((opp) => ({\n opportunityId: opp.opportunityId,\n userId: opp.userId,\n name: opp.name,\n avatar: opp.avatar,\n mainText: opp.homeCardPresentation?.personalizedSummary ?? opp.matchReason ?? \"\",\n cta: opp.homeCardPresentation?.suggestedAction,\n headline: opp.homeCardPresentation?.headline,\n primaryActionLabel: opp.homeCardPresentation?.primaryActionLabel,\n secondaryActionLabel: opp.homeCardPresentation?.secondaryActionLabel,\n mutualIntentsLabel: opp.homeCardPresentation?.mutualIntentsLabel,\n narratorChip: opp.narratorChip,\n viewerRole: opp.viewerRole,\n isGhost: opp.isGhost ?? false,\n score: opp.score,\n status: opp.status,\n }));\n const displayedCards = allCardData.slice(0, CHAT_DISPLAY_LIMIT);\n const extraFromCap = allCardData.length - displayedCards.length;\n\n let message = buildOpportunityPresentation(displayedCards, {\n isMcp: context.isMcp ?? false,\n leadIn: `Found ${displayedCards.length} more potential connection(s).`,\n });\n\n const isIntroducerContinuation = !!query.introTargetUserId?.trim();\n const totalRemaining = (result.pagination?.remaining ?? 0) + extraFromCap;\n if (totalRemaining > 0 && result.pagination?.discoveryId) {\n message += `\\n\\nThere are ${totalRemaining} more candidates. Ask if the user wants to see more — they can say \"show me more\" and you should call discover_opportunities with continueFrom=\"${result.pagination.discoveryId}\".`;\n } else if (isIntroducerContinuation) {\n message += `\\n\\nThese are all the introduction candidates I found for this person.`;\n } else {\n message += `\\n\\nThese are all the connections I found. If the user wants to attract more connections, suggest they create a signal — e.g. \"Would you like to create a signal so others looking for someone like you can find you?\" If they agree, call create_intent with a description based on what they were searching for.`;\n }\n\n return success({\n found: true,\n count: displayedCards.length,\n message,\n summary: `Found ${displayedCards.length} more match(es)`,\n ...(result.pagination ? { pagination: result.pagination } : {}),\n debugSteps: allDebugSteps,\n _graphTimings: [{ name: 'opportunity', durationMs: _graphMs, agents: [] }],\n });\n }\n\n // Normalize entity networkIds before any checks to avoid raw-vs-trimmed mismatches.\n const normalizedEntities = query.entities?.map((e) => ({ ...e, networkId: e.networkId?.trim() }));\n\n // Derive partyUserIds from entities when agent passes entities but omits partyUserIds (intro mode).\n // Only derive when all entities share the same networkId to prevent cross-network introductions.\n const partyUserIdsFromEntities =\n normalizedEntities &&\n normalizedEntities.length >= 2 &&\n normalizedEntities.every((e) => e.userId && e.networkId) &&\n new Set(normalizedEntities.map((e) => e.networkId)).size === 1\n ? [...new Set(normalizedEntities.map((e) => e.userId))]\n : undefined;\n const effectivePartyUserIds =\n query.partyUserIds && query.partyUserIds.length >= 2\n ? query.partyUserIds\n : (partyUserIdsFromEntities?.length ?? 0) >= 2\n ? partyUserIdsFromEntities\n : undefined;\n\n // ── Introduction mode ── (validation and persistence via opportunity graph)\n if (effectivePartyUserIds && effectivePartyUserIds.length >= 2) {\n if (!normalizedEntities || normalizedEntities.length === 0) {\n return error(\n \"Introduction requires pre-gathered entity data. \" +\n \"First use read_network_memberships to find shared networks, \" +\n \"then read_user_profiles and read_intents for each party, \" +\n \"then pass the results as entities.\",\n );\n }\n\n const normalizedEntityNetworkIds = normalizedEntities\n .map((e) => e.networkId)\n .filter((id): id is string => Boolean(id));\n\n if (\n normalizedEntityNetworkIds.length !== normalizedEntities.length ||\n new Set(normalizedEntityNetworkIds).size !== 1\n ) {\n return error(\"All entities must include the same shared networkId.\");\n }\n\n const [primaryNetworkId] = normalizedEntityNetworkIds;\n\n const introducedPartyUserIds = effectivePartyUserIds.filter(\n (uid) => uid !== context.userId,\n );\n if (introducedPartyUserIds.length === 0) {\n return error(\n \"No counterpart to introduce. Provide at least one other user ID in partyUserIds (besides yourself).\",\n );\n }\n\n const evaluatorEntities: EvaluatorEntity[] = normalizedEntities.map(\n (e) => ({\n userId: e.userId,\n profile: e.profile ?? {},\n intents: e.intents,\n networkId: e.networkId,\n }),\n );\n\n const _introGraphStart = Date.now();\n const _introTraceEmitter = requestContext.getStore()?.traceEmitter;\n _introTraceEmitter?.({ type: \"graph_start\", name: \"opportunity\" });\n const result = await invokeWithAbortSignal(graphs.opportunity, {\n operationMode: \"create_introduction\",\n userId: context.userId,\n networkId: primaryNetworkId,\n introductionEntities: evaluatorEntities,\n introductionHint: query.hint,\n requiredNetworkId: context.networkId ?? undefined,\n options: {\n initialStatus: \"draft\" as const,\n ...(context.sessionId ? { conversationId: context.sessionId } : {}),\n },\n });\n const _introGraphMs = Date.now() - _introGraphStart;\n _introTraceEmitter?.({ type: \"graph_end\", name: \"opportunity\", durationMs: _introGraphMs });\n\n if (result.error || !result.opportunities?.length) {\n return error(\n result.error ?? \"Failed to create introduction.\",\n );\n }\n\n const created = result.opportunities[0];\n const reasoning =\n created.interpretation?.reasoning ?? \"A suggested connection.\";\n const confidence =\n typeof created.interpretation?.confidence === \"number\"\n ? created.interpretation.confidence\n : parseFloat(String(created.confidence ?? 0)) || 0;\n const introducerUser = await userDb.getUser();\n const firstPartyId = introducedPartyUserIds[0];\n const firstEntity = query.entities?.find((e) => e.userId === firstPartyId);\n const counterpartUser = firstPartyId\n ? await database.getUser(firstPartyId)\n : null;\n const counterpartName =\n firstEntity?.profile?.name ?? firstPartyId ?? \"Someone\";\n\n // Second party — used in the headline and arrow layout for the introducer view (\"A → B\")\n const secondPartyId = introducedPartyUserIds[1];\n const secondEntity = query.entities?.find((e) => e.userId === secondPartyId);\n const secondPartyName = (secondEntity?.profile as { name?: string } | undefined)?.name;\n const secondPartyAvatar = (secondEntity?.profile as { avatar?: string | null } | undefined)?.avatar ?? null;\n const secondPartyUser = secondPartyId ? await database.getUser(secondPartyId) : null;\n\n const viewerIsParty = effectivePartyUserIds.includes(context.userId);\n const viewerRole = viewerIsParty ? \"party\" : \"introducer\";\n const isCounterpartGhost = counterpartUser?.isGhost ?? false;\n const primaryActionLabel = getPrimaryActionLabel(viewerRole);\n const narratorChip = viewerIsParty\n ? {\n name: \"Index\",\n text: narratorRemarkFromReasoning(reasoning, counterpartName, introducerUser?.name ?? undefined),\n }\n : {\n name: \"You\",\n text: narratorRemarkFromReasoning(reasoning, counterpartName, introducerUser?.name ?? undefined),\n userId: context.userId,\n };\n\n const headline =\n !viewerIsParty && secondPartyName\n ? `${counterpartName} → ${secondPartyName}`\n : `Connection with ${counterpartName}`;\n\n const cardData = {\n opportunityId: created.id,\n userId: firstPartyId,\n name: counterpartName,\n avatar:\n counterpartUser?.avatar ??\n (firstEntity?.profile as { avatar?: string | null } | undefined)\n ?.avatar ??\n null,\n mainText: viewerCentricCardSummary(\n reasoning,\n counterpartName,\n MINIMAL_MAIN_TEXT_MAX_CHARS,\n undefined, // viewerName not available in this context; introducer name passed separately\n introducerUser?.name ?? undefined,\n ),\n cta: \"Start a conversation to connect.\",\n headline,\n primaryActionLabel,\n secondaryActionLabel: SECONDARY_ACTION_LABEL,\n mutualIntentsLabel: \"Suggested connection\",\n narratorChip,\n viewerRole,\n isGhost: isCounterpartGhost,\n score: confidence,\n status: created.status ?? \"draft\",\n ...(!viewerIsParty && secondPartyName\n ? {\n secondParty: {\n name: secondPartyName,\n avatar: secondPartyUser?.avatar ?? secondPartyAvatar,\n ...(secondPartyId ? { userId: secondPartyId } : {}),\n },\n }\n : {}),\n };\n\n if (context.isMcp && deps.mintConnectLink) {\n await attachActionableLinks(cardData as Record<string, unknown> & {\n opportunityId: string;\n viewerRole: string;\n status: string;\n }, {\n viewerId: context.userId,\n viewerApproved: false,\n counterpartUserId: firstPartyId,\n mintConnectLink: deps.mintConnectLink,\n frontendUrl: deps.frontendUrl,\n preferredSurface: context.clientSurface,\n });\n }\n\n return success({\n found: true,\n count: 1,\n summary: \"Draft introduction created\",\n message: buildOpportunityPresentation([cardData], {\n isMcp: context.isMcp ?? false,\n leadIn: \"Draft introduction created.\",\n label: \"opportunity\",\n }),\n opportunities: [\n {\n opportunityId: created.id,\n matchReason: reasoning,\n score: confidence,\n status: created.status ?? \"draft\",\n },\n ],\n _graphTimings: [{ name: 'opportunity', durationMs: _introGraphMs, agents: result.agentTimings ?? [] }],\n });\n }\n\n // ── Discovery mode ──\n const searchQuery = query.searchQuery?.trim() ?? \"\";\n\n if (query.intentId != null && query.intentId !== \"\" && !UUID_REGEX.test(query.intentId.trim())) {\n return error(\"Invalid intent ID format.\");\n }\n\n let indexScope: string[];\n const _scopeGraphTimings: Array<{ name: string; durationMs: number; agents: Array<{ name: string; durationMs: number }> }> = [];\n if (effectiveIndexId) {\n if (!UUID_REGEX.test(effectiveIndexId)) {\n return error(\"Invalid network ID format.\");\n }\n const _scopeGraphStart = Date.now();\n const _scopeIndexMembershipTraceEmitter = requestContext.getStore()?.traceEmitter;\n _scopeIndexMembershipTraceEmitter?.({ type: \"graph_start\", name: \"network_membership\" });\n const memberResult = await invokeWithAbortSignal(graphs.networkMembership, {\n userId: context.userId,\n networkId: effectiveIndexId,\n operationMode: \"read\" as const,\n });\n const _scopeIndexMembershipMs = Date.now() - _scopeGraphStart;\n _scopeIndexMembershipTraceEmitter?.({ type: \"graph_end\", name: \"network_membership\", durationMs: _scopeIndexMembershipMs });\n _scopeGraphTimings.push({ name: 'network_membership', durationMs: _scopeIndexMembershipMs, agents: [] });\n if (memberResult.error) {\n return error(\"Network not found or you are not a member.\");\n }\n indexScope = [effectiveIndexId];\n } else if (context.networkId) {\n // Scoped chat: use the agent's full reach so personal-index\n // signals participate in opportunity discovery. See IND-306.\n indexScope = context.indexScope.length > 0\n ? [...context.indexScope]\n : [context.networkId];\n } else {\n // No scope - use all indexes (only in unscoped chat)\n const _scopeGraphStart = Date.now();\n const _scopeIndexTraceEmitter = requestContext.getStore()?.traceEmitter;\n _scopeIndexTraceEmitter?.({ type: \"graph_start\", name: \"index\" });\n const indexResult = await invokeWithAbortSignal(graphs.index, {\n userId: context.userId,\n operationMode: \"read\" as const,\n showAll: true,\n });\n const _scopeIndexMs = Date.now() - _scopeGraphStart;\n _scopeIndexTraceEmitter?.({ type: \"graph_end\", name: \"index\", durationMs: _scopeIndexMs });\n _scopeGraphTimings.push({ name: 'index', durationMs: _scopeIndexMs, agents: [] });\n indexScope = (indexResult.readResult?.memberOf || []).map(\n (m: { networkId: string }) => m.networkId,\n );\n }\n\n const toolDebugSteps: Array<{ step: string; detail?: string }> = [\n { step: \"resolve_index_scope\", detail: `${indexScope.length} index(es)` },\n ];\n\n const triggerIntentId = query.intentId?.trim() || undefined;\n if (triggerIntentId != null && !UUID_REGEX.test(triggerIntentId)) {\n return error(\"Invalid intent ID format.\");\n }\n\n if (query.introTargetUserId?.trim() && query.introTargetUserId.trim() === context.userId) {\n return error(\"You cannot discover introductions for yourself. Try regular discovery instead.\");\n }\n\n const _discoverTraceEmitter = requestContext.getStore()?.traceEmitter;\n const _discoverGraphStart = Date.now();\n _discoverTraceEmitter?.({ type: \"graph_start\", name: \"opportunity\" });\n // Chat-driven invocations run under the orchestrator trigger: persist\n // opens at 'negotiating', negotiate fans out with a 60s park window,\n // each accepted draft streams via traceEmitter, and the persist step\n // surfaces already-accepted pairs. Other callers (maintenance, queue\n // workers) still get the 'ambient' default.\n // Orchestrator trigger fires for both web chat (has sessionId) and MCP\n // (isMcp=true, no sessionId). Both are user-initiated discovery that\n // should persist as `negotiating` and flip to `draft` post-finalize via\n // onCandidateResolved. Ambient/cron paths leave both falsy and use the\n // `pending` default.\n const runDiscoveryOrchestrator = !!context.sessionId || !!context.isMcp;\n const result = await runDiscoverFromQuery({\n opportunityGraph: graphs.opportunity,\n database,\n userId: context.userId,\n query: searchQuery,\n indexScope,\n limit: 20,\n presenter: new OpportunityPresenter(),\n useHomeCardFormat: true,\n triggerIntentId,\n targetUserId: query.targetUserId?.trim() || undefined,\n onBehalfOfUserId: query.introTargetUserId?.trim() || undefined,\n cache,\n // MCP-only: cap the negotiate phase at 20 s so Railway's edge proxy\n // (which 502s the client at ~57 s) never beats the response. The\n // remainder finalizes in the background and is fetched on the\n // user's next list_opportunities call. Removable when IND-274\n // (negotiation conversation continuation) lands.\n ...(context.isMcp ? { negotiateTimeoutMs: 20_000 } : {}),\n ...(context.sessionId ? { chatSessionId: context.sessionId } : {}),\n ...(runDiscoveryOrchestrator && { trigger: 'orchestrator' as const }),\n ...(deps.chatSummary && { chatSummary: deps.chatSummary }),\n ...(deps.questionGenerator && { questionGenerator: deps.questionGenerator }),\n ...(deps.questionerEnqueue && { questionerEnqueue: deps.questionerEnqueue }),\n ...(deps.negotiationSummary && { negotiationSummary: deps.negotiationSummary }),\n // Decision questions add an LLM call after the negotiation phase.\n // Capped at DISCOVERY_QUESTIONS_TIMEOUT_MS (12 s default,\n // env-overridable; see opportunity.discover.ts). Aborted calls return\n // no questions but the rest of the discovery payload still ships.\n // For chat sessions, questions are rendered by the frontend via\n // streamed events (Slice 4). For MCP, they drive a sequential\n // elicitation/create flow (Slice 5) — the MCP tool handler awaits the\n // elicitations before returning the tool result. The per-negotiation\n // summarizer is similarly capped at NEGOTIATION_SUMMARY_TIMEOUT_MS\n // (5 s default per negotiation). Master switch remains\n // ENABLE_DISCOVERY_QUESTIONS.\n enableQuestions:\n process.env.ENABLE_DISCOVERY_QUESTIONS === \"true\" &&\n (!!context.sessionId || !!context.isMcp),\n });\n\n // ── Pending question injection ────────────────────────────────────\n // Look up previously-generated questions relevant to this user's\n // discovery context and merge them into the result alongside any\n // inline-generated questions from the current run.\n const pendingQuestionResult = await mergePendingQuestions({\n findPendingQuestions: deps.findPendingQuestions,\n userId: context.userId,\n sourceType: 'discovery',\n surfacedQuestionIds: new Set(), // Dedup handled at chat.agent level\n });\n const pendingQuestions = pendingQuestionResult.questions;\n\n const _discoverGraphMs = Date.now() - _discoverGraphStart;\n _discoverTraceEmitter?.({ type: \"graph_end\", name: \"opportunity\", durationMs: _discoverGraphMs });\n const _discoverGraphTimings = [\n ..._scopeGraphTimings,\n { name: 'opportunity', durationMs: _discoverGraphMs, agents: [] },\n ];\n\n const allDebugSteps = [\n ...toolDebugSteps,\n ...(result.debugSteps ?? []),\n ];\n\n // Extract negotiation timing from trace (if negotiation ran)\n const negotiateStep = (result.debugSteps ?? []).find(\n s => s.step === 'negotiate' && s.data?.durationMs != null\n );\n const _allGraphTimings = [\n ..._discoverGraphTimings,\n ...(negotiateStep?.data?.durationMs != null\n ? [{ name: 'negotiation', durationMs: negotiateStep.data.durationMs as number, agents: [] }]\n : []),\n ];\n\n const isIntroducerFlow = !!query.introTargetUserId?.trim();\n\n if (result.createIntentSuggested && result.suggestedIntentDescription && !isIntroducerFlow) {\n return success({\n found: false,\n count: 0,\n createIntentSuggested: true,\n suggestedIntentDescription: result.suggestedIntentDescription,\n message:\n \"No matching opportunities found. Call create_intent with the suggested description, then discover_opportunities again.\",\n summary: \"No matches found\",\n ...(result.pagination ? { pagination: result.pagination } : {}),\n debugSteps: allDebugSteps,\n _graphTimings: _allGraphTimings,\n ...(() => {\n const allQ = [...(result.questions ?? []), ...pendingQuestions];\n return allQ.length > 0 ? { questions: allQ } : {};\n })(),\n ...(result.discoveryQuestionsDebug ? { _discoveryQuestionsDebug: result.discoveryQuestionsDebug } : {}),\n });\n }\n\n if (!result.found) {\n return success({\n found: false,\n count: 0,\n message: result.message ?? \"No matching opportunities found.\",\n summary: \"No matches found\",\n ...(result.pagination ? { pagination: result.pagination } : {}),\n debugSteps: allDebugSteps,\n _graphTimings: _allGraphTimings,\n ...(() => {\n const allQ = [...(result.questions ?? []), ...pendingQuestions];\n return allQ.length > 0 ? { questions: allQ } : {};\n })(),\n ...(result.discoveryQuestionsDebug ? { _discoveryQuestionsDebug: result.discoveryQuestionsDebug } : {}),\n });\n }\n\n // Found but only existing connections (no new opportunities created)\n const forMention = result.existingConnectionsForMention ?? result.existingConnections ?? [];\n if ((result.opportunities?.length ?? 0) === 0 && forMention.length > 0) {\n return success({\n found: true,\n count: 0,\n message:\n result.message ??\n \"No new opportunities created; you already have a connection with: \" +\n forMention.map((c) => c.name + (c.status ? \" (\" + c.status + \")\" : \"\")).join(\", \") +\n \". View on your home page.\",\n existingConnections: result.existingConnections,\n summary: \"No new matches (existing connections only)\",\n debugSteps: allDebugSteps,\n _graphTimings: _allGraphTimings,\n ...(() => {\n const allQ = [...(result.questions ?? []), ...pendingQuestions];\n return allQ.length > 0 ? { questions: allQ } : {};\n })(),\n ...(result.discoveryQuestionsDebug ? { _discoveryQuestionsDebug: result.discoveryQuestionsDebug } : {}),\n });\n }\n\n // MCP-only: refresh persisted opp statuses from the DB. The graph captures\n // state.opportunities at persist time, but the negotiate phase mutates each\n // opp's DB row independently. Without this refresh we'd render persist-time\n // 'negotiating' as if it were 'draft'. Also drops rejected/stalled — they\n // are not actionable post-negotiation. Existing-connection cards (cards\n // whose opportunityId is in result.existingConnections) are preserved as-is\n // per opportunity.discover.ts's EXISTING_CONNECTION_CARD_STATUSES contract.\n const existingConnectionIds = new Set(\n (result.existingConnections ?? [])\n .map((c) => c.opportunityId)\n .filter((id): id is string => typeof id === 'string'),\n );\n const candidatesArr = result.opportunities ?? [];\n let negotiatingCount = 0;\n let cards = candidatesArr;\n if (context.isMcp && candidatesArr.length > 0) {\n const newlyCreatedIds = candidatesArr\n .filter((c) => !existingConnectionIds.has(c.opportunityId))\n .map((c) => c.opportunityId);\n const refreshed = newlyCreatedIds.length > 0\n ? await database.getOpportunitiesByIds(newlyCreatedIds)\n : [];\n const statusById = new Map<string, OpportunityStatus>(\n refreshed.map((o) => [o.id, o.status]),\n );\n\n const draftCards: typeof candidatesArr = [];\n for (const card of candidatesArr) {\n if (existingConnectionIds.has(card.opportunityId)) {\n // Re-surfaced opp from a prior run — keep with its discover-time status.\n draftCards.push(card);\n continue;\n }\n const refreshedStatus = statusById.get(card.opportunityId);\n if (refreshedStatus === 'draft') {\n draftCards.push({ ...card, status: refreshedStatus });\n continue;\n }\n if (refreshedStatus === 'negotiating') {\n negotiatingCount += 1;\n continue;\n }\n if (refreshedStatus === 'rejected' || refreshedStatus === 'stalled') {\n continue; // drop\n }\n // 'pending' / 'latent' / unknown — not expected post-IND-287. Treat as\n // negotiating (count only) and log so we can spot wiring regressions.\n logger.warn('[discover_opportunities] unexpected refreshed status — counting as negotiating', {\n opportunityId: card.opportunityId,\n refreshedStatus,\n });\n negotiatingCount += 1;\n }\n cards = draftCards;\n }\n\n // Build card data; cap at CHAT_DISPLAY_LIMIT (remaining feeds into pagination)\n const allCardData = cards.map((opp) => ({\n opportunityId: opp.opportunityId,\n userId: opp.userId,\n name: opp.name,\n avatar: opp.avatar,\n mainText:\n opp.homeCardPresentation?.personalizedSummary ??\n opp.matchReason ??\n \"\",\n cta: opp.homeCardPresentation?.suggestedAction,\n headline: opp.homeCardPresentation?.headline,\n primaryActionLabel: opp.homeCardPresentation?.primaryActionLabel,\n secondaryActionLabel: opp.homeCardPresentation?.secondaryActionLabel,\n mutualIntentsLabel: opp.homeCardPresentation?.mutualIntentsLabel,\n narratorChip: opp.narratorChip,\n viewerRole: opp.viewerRole,\n isGhost: opp.isGhost ?? false,\n score: opp.score,\n status: opp.status,\n ...(opp.secondParty && { secondParty: opp.secondParty }),\n }));\n const displayedCards = allCardData.slice(0, CHAT_DISPLAY_LIMIT);\n const extraFromCap = allCardData.length - displayedCards.length;\n\n if (context.isMcp && deps.mintConnectLink) {\n const mintConnectLink = deps.mintConnectLink;\n await Promise.all(\n displayedCards.map(async (card, idx) => {\n const source = cards[idx];\n await attachActionableLinks(card as Record<string, unknown> & {\n opportunityId: string;\n viewerRole: string;\n status: string;\n }, {\n viewerId: context.userId,\n viewerApproved: source?.viewerApproved,\n counterpartUserId: source?.userId ?? card.userId,\n mintConnectLink,\n frontendUrl: deps.frontendUrl,\n preferredSurface: context.clientSurface,\n });\n }),\n );\n }\n\n let message = buildOpportunityPresentation(displayedCards, {\n isMcp: context.isMcp ?? false,\n leadIn: `Found ${displayedCards.length} potential connection(s).`,\n });\n const existingForMention = result.existingConnectionsForMention ?? result.existingConnections ?? [];\n if (existingForMention.length > 0) {\n message +=\n \"\\n\\nYou already have a connection with: \" +\n existingForMention.map((c) => c.name + (c.status ? \" (\" + c.status + \")\" : \"\")).join(\", \") +\n \". View on your home page.\";\n }\n // Orchestrator-only: dedupAlreadyAccepted surfaces pairs that already\n // have an accepted opp between the users. Tell the LLM so it can guide\n // the user to the existing chat instead of treating this like a brand-\n // new connection.\n if (result.alreadyAcceptedPairs && result.alreadyAcceptedPairs.length > 0) {\n message +=\n `\\n\\nYou already have ${result.alreadyAcceptedPairs.length} accepted opportunity(ies) with some of these candidates — open the existing chat with them rather than creating a new draft.`;\n }\n\n const totalRemaining = (result.pagination?.remaining ?? 0) + extraFromCap;\n if (totalRemaining > 0 && result.pagination?.discoveryId) {\n message += `\\n\\nThere are ${totalRemaining} more candidates. Ask if the user wants to see more — they can say \"show me more\" and you should call discover_opportunities with continueFrom=\"${result.pagination.discoveryId}\".`;\n } else if (isIntroducerFlow) {\n message += `\\n\\nThese are all the introduction candidates I found for this person.`;\n } else {\n message += `\\n\\nThese are all the connections I found. If the user wants to attract more connections, suggest they create a signal — e.g. \"Would you like to create a signal so others looking for someone like you can find you?\" If they agree, call create_intent with a description based on what they were searching for.`;\n }\n\n // MCP-only: tell the LLM how many opps are still negotiating in the background\n // and how to fetch them. This is the deferred-surfacing handshake — the user's\n // next list_opportunities call will pick up the rest as they finalize.\n if (context.isMcp && negotiatingCount > 0) {\n if (displayedCards.length > 0) {\n message += `\\n\\n${negotiatingCount} more opportunit${negotiatingCount === 1 ? 'y is' : 'ies are'} still being evaluated — check back via \\`list_opportunities\\` shortly.`;\n } else {\n // No cards shown. Rebuild the message without the misleading\n // \"Found 0 potential connection(s)\" lead-in but preserve the\n // existing-connections mention and already-accepted-pairs note\n // appended earlier — those are standalone facts independent of\n // any draft cards. Pagination/intro/closing trailers are dropped\n // intentionally (they only make sense when cards are shown).\n let rebuilt = `Found candidates, but they're still being evaluated. Try \\`list_opportunities\\` in a minute — ${negotiatingCount} pending.`;\n if (existingForMention.length > 0) {\n rebuilt +=\n \"\\n\\nYou already have a connection with: \" +\n existingForMention.map((c) => c.name + (c.status ? \" (\" + c.status + \")\" : \"\")).join(\", \") +\n \". View on your home page.\";\n }\n if (result.alreadyAcceptedPairs && result.alreadyAcceptedPairs.length > 0) {\n rebuilt += `\\n\\nYou already have ${result.alreadyAcceptedPairs.length} accepted opportunity(ies) with some of these candidates — open the existing chat with them rather than creating a new draft.`;\n }\n message = rebuilt;\n }\n }\n\n return success({\n found: true,\n count: displayedCards.length,\n message,\n summary: `Found ${displayedCards.length} match(es)`,\n ...(result.existingConnections?.length ? { existingConnections: result.existingConnections } : {}),\n ...(result.pagination ? { pagination: result.pagination } : {}),\n debugSteps: allDebugSteps,\n // Distinct from `createIntentSuggested` (no-results path) intentionally:\n // `handleCreateIntentCallback` in chat.agent.ts auto-creates for that key.\n // This flag is for the results-found path where the agent must ask the user first.\n ...(searchQuery && !query.targetUserId && !isIntroducerFlow\n ? {\n suggestIntentCreationForVisibility: true,\n suggestedIntentDescription: searchQuery,\n }\n : {}),\n ...(() => {\n const allQ = [...(result.questions ?? []), ...pendingQuestions];\n return allQ.length > 0 ? { questions: allQ } : {};\n })(),\n ...(result.discoveryQuestionsDebug ? { _discoveryQuestionsDebug: result.discoveryQuestionsDebug } : {}),\n _graphTimings: _allGraphTimings,\n });\n },\n });\n\n const getDiscoveryRun = defineTool({\n name: \"get_discovery_run\",\n description:\n \"Checks the status of an async discovery run started by discover_opportunities in MCP contexts. \" +\n \"Poll this tool with the discoveryRunId roughly every 5 seconds until status is succeeded, failed, or cancelled. \" +\n \"While status is queued or running, keep polling THIS tool — do NOT call discover_opportunities again (that does not speed anything up and returns the same run). \" +\n \"When succeeded, the result field contains the same discovery payload that discover_opportunities would have returned synchronously.\",\n querySchema: z.object({\n discoveryRunId: z.string().describe(\"Discovery run ID returned by discover_opportunities.\"),\n }),\n handler: async ({ context, query }) => {\n if (!deps.discoveryRuns) {\n return error(\"Async discovery runs are not available in this context.\");\n }\n const run = await deps.discoveryRuns.get(query.discoveryRunId, context.userId);\n if (!run) return error(\"Discovery run not found.\");\n return success({\n discoveryRunId: run.id,\n status: run.status,\n progress: run.progress ?? null,\n result: run.result ?? null,\n error: run.error ?? null,\n cancelRequestedAt: run.cancelRequestedAt?.toISOString?.() ?? null,\n createdAt: run.createdAt.toISOString(),\n startedAt: run.startedAt?.toISOString?.() ?? null,\n completedAt: run.completedAt?.toISOString?.() ?? null,\n });\n },\n });\n\n const cancelDiscoveryRun = defineTool({\n name: \"cancel_discovery_run\",\n description:\n \"Requests cancellation for an async discovery run. If the queued job has not started, it is removed and marked cancelled. \" +\n \"If already running, the worker observes cancellation and stops at the next cancellation check.\",\n querySchema: z.object({\n discoveryRunId: z.string().describe(\"Discovery run ID returned by discover_opportunities.\"),\n }),\n handler: async ({ context, query }) => {\n if (!deps.discoveryRuns || !deps.discoveryRunQueue) {\n return error(\"Async discovery runs are not available in this context.\");\n }\n const existing = await deps.discoveryRuns.get(query.discoveryRunId, context.userId);\n if (!existing) return error(\"Discovery run not found.\");\n if (![\"queued\", \"running\"].includes(existing.status)) {\n return success({\n discoveryRunId: existing.id,\n status: existing.status,\n cancelled: existing.status === \"cancelled\",\n message: `Discovery run is already ${existing.status}.`,\n });\n }\n const run = await deps.discoveryRuns.requestCancel(query.discoveryRunId, context.userId);\n if (!run) return error(\"Discovery run is no longer cancellable.\");\n const removed = await deps.discoveryRunQueue.cancel(run.id);\n if (removed) {\n await deps.discoveryRuns.markCancelled(run.id, \"cancelled before worker start\");\n }\n const updated = await deps.discoveryRuns.get(run.id, context.userId);\n const status = updated?.status ?? (removed ? \"cancelled\" : run.status);\n const message = removed\n ? \"Discovery run cancelled.\"\n : status === \"queued\"\n ? \"Cancellation requested while the discovery run is still queued. It will be skipped or cancelled before work starts.\"\n : status === \"running\"\n ? \"Cancellation requested. The running worker will stop at the next cancellation check.\"\n : `Cancellation requested. Discovery run is now ${status}.`;\n return success({\n discoveryRunId: run.id,\n status,\n cancelled: removed || status === \"cancelled\",\n message,\n });\n },\n });\n\n const listOpportunities = defineTool({\n name: \"list_opportunities\",\n description:\n \"Lists the authenticated user's actionable opportunities (discovered connections). Returns opportunity cards ready for display.\\n\\n\" +\n \"**What are opportunities?** Matches between users whose intents complement each other within shared indexes. \" +\n \"Each opportunity has a status: draft (not yet sent), pending (sent, awaiting response), accepted, rejected, or expired.\\n\\n\" +\n \"**What this returns:** Only draft and pending opportunities — the ones the user can still act on. \" +\n \"Accepted, rejected, and expired ones are not surfaced through this tool.\\n\\n\" +\n \"**When to use:** When the user wants to see their current matches or review what's waiting for their response.\\n\\n\" +\n \"**Returns:** Up to 3 opportunity code blocks (interactive cards) with counterpart name, match reasoning, confidence score, \" +\n \"and current status. Use update_opportunity to act on them (send, accept, reject).\",\n querySchema: z.object({\n networkId: z\n .string()\n .optional()\n .describe(\"Index UUID to filter opportunities to a specific community. Get from read_networks. Defaults to the scoped index in index-scoped chats. Omit to see opportunities across all indexes.\"),\n includeDigestMarkers: z\n .boolean()\n .optional()\n .describe(\"Internal scheduled-digest mode only. When true, includes hidden delivery markers so the digest send pass can confirm only edited-in opportunities.\"),\n }),\n handler: async ({ context, query }) => {\n // Strict scope enforcement: when chat is index-scoped, only allow that index\n if (\n context.networkId &&\n query.networkId?.trim() &&\n query.networkId.trim() !== context.networkId\n ) {\n return error(\n \"This chat is scoped to \" +\n (context.indexName ?? \"this index\") +\n \". You can only list opportunities from this community.\",\n );\n }\n\n const effectiveIndexId =\n (context.networkId || query.networkId?.trim()) ?? undefined;\n if (effectiveIndexId && !UUID_REGEX.test(effectiveIndexId)) {\n return error(\"Invalid network ID format.\");\n }\n\n // The MCP/chat surface exposes actionable opportunities.\n // `latent` is included so the introducer-as-viewer can see their unapproved\n // connector-flow cards (\"do you know someone for X?\"). Other latent visibility\n // rules from isActionableForViewer (latent + no introducer; latent + approved=true\n // mid-negotiation) are correct at the ACL layer but should not flow through the\n // chat tool — patient/peer wait for the negotiation to land them in `pending`.\n const statuses: OpportunityStatus[] = [\"draft\", \"pending\", \"latent\"];\n\n // Fetch wider than CHAT_DISPLAY_LIMIT so selectByComposition has both\n // buckets to balance — otherwise a category that dominates the natural\n // sort order can fill the whole window and starve the other section.\n const fetched = await database.getOpportunitiesForUser(\n context.userId,\n {\n networkId: effectiveIndexId,\n statuses,\n limit: CHAT_FETCH_LIMIT,\n },\n );\n\n const skippedIds: string[] = [];\n const buildListDebugSteps = (): Array<{ step: string; detail?: string; data?: Record<string, unknown> }> => {\n const steps: Array<{ step: string; detail?: string; data?: Record<string, unknown> }> = [];\n if (skippedIds.length > 0) {\n steps.push({\n step: \"opportunity_display_skips\",\n detail: `${skippedIds.length} opportunity card(s) couldn't be displayed`,\n data: {\n skippedCount: skippedIds.length,\n totalOpportunities: fetched.length,\n skippedOpportunityIds: skippedIds,\n },\n });\n }\n return steps;\n };\n const recordCallerMismatch = (opp: Opportunity): void => {\n logger.warn(\"list_opportunities: skipping opportunity where caller is not an actor\", {\n opportunityId: opp.id,\n viewerId: context.userId,\n actorUserIds: opp.actors\n .map((a) => a.userId)\n .filter((userId): userId is string => typeof userId === \"string\"),\n });\n skippedIds.push(opp.id);\n };\n\n // Read invariant: only surface opportunities the caller actually\n // participates in. Apply before latent filtering, dedup/selection, and\n // profile/user batch fetches so a mismatched row cannot influence which\n // valid opportunities are selected or trigger cross-user reads.\n const callerScoped = fetched.filter((opp) => {\n if (opp.actors.some((a) => a.userId === context.userId)) return true;\n recordCallerMismatch(opp);\n return false;\n });\n\n // Latent rows in chat are introducer-as-viewer only. The ACL layer\n // (isActionableForViewer) returns true for several other latent cases —\n // those belong to the home feed, not the digest/ambient surface.\n const visible = callerScoped.filter((opp) => {\n if (opp.status !== \"latent\") return true;\n const me = opp.actors.find((a) => a.userId === context.userId);\n return me?.role === \"introducer\";\n });\n\n // Deduplicate so each counterpart appears at most once — keeps the\n // highest-confidence opportunity per person across discovery runs.\n const deduped = deduplicateByPerson(visible, context.userId);\n\n const isDigestMode = context.isMcp === true && query.includeDigestMarkers === true;\n\n // ── Digest-mode cross-day suppression ──\n // Scheduled briefs must not repeat themselves: drop candidates whose\n // counterpart the user already connected with (accepted opportunity\n // exists — a re-discovery run re-minting the same person must not\n // resurface them), drop candidates already shown per the delivery\n // ledger, and when nothing fresh remains re-show the least-recently\n // shown candidate past the cooldown, flagged as a redelivery so the\n // digest can frame it as a reminder. Chat mode is untouched — a user\n // asking \"show my opportunities\" should always see them.\n // Every fetch here is best-effort: a failed read degrades to no\n // suppression rather than an empty brief.\n let digestPool = deduped;\n let redeliveryIds = new Set<string>();\n if (isDigestMode && deduped.length > 0) {\n const acceptedCounterpartIds = new Set<string>();\n try {\n const acceptedOpps = await database.getOpportunitiesForUser(context.userId, {\n ...(effectiveIndexId ? { networkId: effectiveIndexId } : {}),\n statuses: [\"accepted\"],\n limit: ACCEPTED_SUPPRESSION_FETCH_LIMIT,\n });\n for (const opp of acceptedOpps) {\n for (const actor of opp.actors) {\n if (actor.userId && actor.userId !== context.userId && actor.role !== \"introducer\") {\n acceptedCounterpartIds.add(actor.userId);\n }\n }\n }\n } catch (err) {\n logger.warn(\"digest suppression: failed to fetch accepted opportunities, skipping counterpart suppression\", { err });\n }\n\n let deliveredRows: DigestDeliveredRow[] = [];\n if (deps.deliveryLedger?.getDeliveredOpportunities) {\n try {\n const rows = await deps.deliveryLedger.getDeliveredOpportunities({\n userId: context.userId,\n opportunityIds: deduped.map((opp) => opp.id),\n });\n // Defensive Date coercion — ledger rows may cross a serialization boundary.\n deliveredRows = rows.map((row) => ({\n opportunityId: row.opportunityId,\n deliveredAtStatus: row.deliveredAtStatus,\n deliveredAt: row.deliveredAt instanceof Date ? row.deliveredAt : new Date(row.deliveredAt),\n }));\n } catch (err) {\n logger.warn(\"digest suppression: failed to read delivery ledger, skipping shown-opportunity dedup\", { err });\n }\n }\n\n const digestSelection = selectDigestCandidates(deduped, {\n viewerId: context.userId,\n acceptedCounterpartIds,\n deliveredRows,\n });\n digestPool = digestSelection.pool;\n redeliveryIds = digestSelection.redeliveryIds;\n }\n\n // Compose-balance across feed categories so the digest/ambient prompt\n // can fill both Section A (connection) and Section B (connector-flow).\n // Falls back to the unbalanced view when the helper has nothing to do.\n const selected = digestPool.length > 0\n ? selectByComposition(digestPool, context.userId)\n : digestPool;\n const opportunities = selected.slice(0, CHAT_DISPLAY_LIMIT);\n\n if (!opportunities || opportunities.length === 0) {\n if (skippedIds.length > 0) {\n const listDebugSteps = buildListDebugSteps();\n return success({\n found: false,\n count: 0,\n summary: \"Some opportunities couldn't be displayed\",\n message:\n \"I found opportunities, but couldn't render them. Please try again.\",\n ...(listDebugSteps.length ? { debugSteps: listDebugSteps } : {}),\n });\n }\n // Digest mode: distinguish \"everything was already shown\" from \"nothing\n // exists\" so the brief omits the people section instead of prompting\n // the user to run discovery.\n if (isDigestMode && deduped.length > 0) {\n return success({\n found: false,\n count: 0,\n summary: \"No new opportunities to show\",\n message:\n \"No new opportunities today — everything actionable has already been shown recently. Omit the people section from the digest.\",\n });\n }\n return success({\n found: false,\n count: 0,\n summary: \"No opportunities yet\",\n message:\n \"You have no opportunities yet. Use discover_opportunities to find connections.\",\n });\n }\n\n // Batch-fetch profiles and users for all counterpart and introducer userIds to avoid N+1\n const counterpartUserIds = new Set<string>();\n const introducerUserIds = new Set<string>();\n for (const opp of opportunities) {\n const counterpartActor = opp.actors.find(\n (a) => a.userId !== context.userId && a.role !== \"introducer\",\n );\n if (counterpartActor?.userId) counterpartUserIds.add(counterpartActor.userId);\n const introducerActor = opp.actors.find(\n (a) => a.role === \"introducer\" && a.userId !== context.userId,\n );\n if (introducerActor?.userId) introducerUserIds.add(introducerActor.userId);\n }\n const allUserIds = [\n ...new Set([...counterpartUserIds, ...introducerUserIds]),\n ];\n const [viewerUser, profileResults, userResults] = await Promise.all([\n database.getUser(context.userId),\n Promise.all(allUserIds.map((id) => database.getProfile(id))),\n Promise.all(allUserIds.map((id) => database.getUser(id))),\n ]);\n const viewerName = viewerUser?.name ?? undefined;\n const profileMap = new Map<string, Awaited<ReturnType<typeof database.getProfile>>>();\n const userMap = new Map<string, Awaited<ReturnType<typeof database.getUser>>>();\n allUserIds.forEach((userId, i) => {\n const profile = profileResults[i] ?? null;\n const user = userResults[i] ?? null;\n if (profile) profileMap.set(userId, profile);\n if (user) userMap.set(userId, user);\n });\n\n const cardDataList: Array<Record<string, unknown> & { opportunityId: string }> = [];\n const seenOpportunityIds = new Set<string>();\n\n if (isDigestMode) {\n // ── Digest mode: use LLM presenter for rich, second-person card text ──\n const presenter = new OpportunityPresenter();\n const presenterDb: PresenterDatabase = database;\n const PRESENTER_CONCURRENCY = 6;\n\n for (let i = 0; i < opportunities.length; i += PRESENTER_CONCURRENCY) {\n const chunk = opportunities.slice(i, i + PRESENTER_CONCURRENCY);\n const chunkCards = await Promise.all(\n chunk.map(async (opp) => {\n if (seenOpportunityIds.has(opp.id)) return null;\n seenOpportunityIds.add(opp.id);\n try {\n const counterpartActor = opp.actors.find(\n (a) => a.userId !== context.userId && a.role !== \"introducer\",\n );\n const counterpartUserId = counterpartActor?.userId;\n if (!counterpartUserId) return null;\n\n const viewerIsIntroducerHere = opp.actors.some(\n (a) => a.role === \"introducer\" && a.userId === context.userId,\n );\n const secondPartyActorForHeadline = viewerIsIntroducerHere\n ? opp.actors.find(\n (a) =>\n a.userId !== context.userId &&\n a.userId !== counterpartUserId &&\n a.role !== \"introducer\",\n )\n : undefined;\n\n const introducerActor = opp.actors.find(\n (a) => a.role === \"introducer\" && a.userId !== context.userId,\n );\n const createdByName = opp.detection.createdByName;\n\n const counterpartUser = userMap.get(counterpartUserId) ?? null;\n const counterpartName =\n profileMap.get(counterpartUserId)?.identity?.name ??\n counterpartUser?.name ??\n \"Someone\";\n const introducerName =\n createdByName ??\n (introducerActor\n ? (profileMap.get(introducerActor.userId)?.identity?.name ?? null)\n : null);\n const introducerUser = introducerActor\n ? userMap.get(introducerActor.userId) ?? null\n : null;\n\n const secondPartyUser = secondPartyActorForHeadline\n ? userMap.get(secondPartyActorForHeadline.userId) ?? null\n : null;\n const secondPartyNameForHeadline = secondPartyActorForHeadline\n ? (profileMap.get(secondPartyActorForHeadline.userId)?.identity?.name ??\n secondPartyUser?.name ??\n undefined)\n : undefined;\n\n const viewerActor = opp.actors.find((a) => a.userId === context.userId);\n const viewerRole = viewerActor?.role ?? \"party\";\n const isCounterpartGhost = counterpartUser?.isGhost ?? false;\n\n try {\n const ctx = await gatherPresenterContext(\n presenterDb,\n opp,\n context.userId,\n counterpartUserId,\n );\n\n const presentation = await presenter.presentHomeCard({\n ...ctx,\n opportunityStatus: opp.status,\n });\n\n // Build narrator chip from presenter output\n let narratorChip: { name: string; text: string; avatar?: string | null; userId?: string };\n const introducerIsCounterpart = introducerActor && counterpartActor && introducerActor.userId === counterpartActor.userId;\n if (introducerActor && introducerActor.userId !== context.userId && !introducerIsCounterpart) {\n const narratorName = introducerName?.trim() || \"Someone\";\n narratorChip = {\n name: narratorName,\n text: stripLeadingNarratorName(presentation.narratorRemark, narratorName),\n avatar: introducerUser?.avatar ?? null,\n userId: introducerActor.userId,\n };\n } else if (introducerActor?.userId === context.userId) {\n narratorChip = { name: \"You\", text: presentation.narratorRemark, userId: context.userId };\n } else {\n narratorChip = { name: \"Index\", text: presentation.narratorRemark };\n }\n\n const card: Record<string, unknown> = {\n opportunityId: opp.id,\n userId: counterpartUserId,\n name: counterpartName,\n avatar: counterpartUser?.avatar ?? null,\n mainText: stripUuids(presentation.personalizedSummary),\n digestSummary: stripUuids(presentation.digestSummary),\n cta: presentation.suggestedAction,\n headline: viewerIsIntroducerHere && secondPartyNameForHeadline\n ? `${counterpartName} → ${secondPartyNameForHeadline}`\n : presentation.headline,\n primaryActionLabel: getPrimaryActionLabel(viewerRole),\n secondaryActionLabel: SECONDARY_ACTION_LABEL,\n mutualIntentsLabel: presentation.mutualIntentsLabel,\n narratorChip,\n viewerRole,\n score: typeof opp.interpretation?.confidence === \"number\"\n ? opp.interpretation.confidence\n : undefined,\n status: opp.status,\n isGhost: isCounterpartGhost,\n ...(redeliveryIds.has(opp.id) ? { redelivery: true } : {}),\n ...(viewerIsIntroducerHere && secondPartyNameForHeadline\n ? {\n secondParty: {\n name: secondPartyNameForHeadline,\n ...(secondPartyUser?.avatar != null ? { avatar: secondPartyUser.avatar } : {}),\n ...(secondPartyActorForHeadline?.userId ? { userId: secondPartyActorForHeadline.userId } : {}),\n },\n }\n : {}),\n };\n\n // Attach actionable links for MCP callers\n if (context.isMcp && deps.mintConnectLink) {\n const viewerApproved =\n viewerActor?.role === \"introducer\" ? viewerActor.approved === true : undefined;\n await attachActionableLinks(card as Record<string, unknown> & {\n opportunityId: string;\n viewerRole: string;\n status: string;\n }, {\n viewerId: context.userId,\n viewerApproved,\n counterpartUserId,\n mintConnectLink: deps.mintConnectLink,\n frontendUrl: deps.frontendUrl,\n preferredSurface: context.clientSurface,\n });\n }\n\n return card as Record<string, unknown> & { opportunityId: string };\n } catch (presenterErr) {\n logger.warn(\"LLM presenter failed for list_opportunities digest card, skipping raw fallback\", {\n opportunityId: opp.id,\n err: presenterErr,\n });\n // Scheduled digests should only surface OpportunityPresenter-rendered\n // copy. The minimal fallback reuses evaluator reasoning, which can\n // contain raw narrator phrasing (for example \"The discoverer...\")\n // and is not suitable for AgentVillage morning briefs.\n skippedIds.push(opp.id);\n return null;\n }\n } catch (err) {\n logger.warn(\"Skipping opportunity that failed to build card\", {\n opportunityId: opp.id,\n err,\n });\n skippedIds.push(opp.id);\n return null;\n }\n }),\n );\n for (const card of chunkCards) {\n if (card) cardDataList.push(card);\n }\n }\n } else {\n // ── Chat mode: fast heuristic path (no LLM) ──\n for (const opp of opportunities) {\n if (seenOpportunityIds.has(opp.id)) continue;\n seenOpportunityIds.add(opp.id);\n try {\n const counterpartActor = opp.actors.find(\n (a) => a.userId !== context.userId && a.role !== \"introducer\",\n );\n const counterpartUserId = counterpartActor?.userId;\n if (!counterpartUserId) continue;\n\n const viewerIsIntroducerHere = opp.actors.some(\n (a) => a.role === \"introducer\" && a.userId === context.userId,\n );\n const secondPartyActorForHeadline = viewerIsIntroducerHere\n ? opp.actors.find(\n (a) =>\n a.userId !== context.userId &&\n a.userId !== counterpartUserId &&\n a.role !== \"introducer\",\n )\n : undefined;\n const secondPartyNameForHeadline = secondPartyActorForHeadline\n ? (profileMap.get(secondPartyActorForHeadline.userId)?.identity?.name ??\n userMap.get(secondPartyActorForHeadline.userId)?.name ??\n undefined)\n : undefined;\n\n const introducerActor = opp.actors.find(\n (a) => a.role === \"introducer\" && a.userId !== context.userId,\n );\n const createdByName = opp.detection.createdByName;\n\n const counterpartProfile = profileMap.get(counterpartUserId) ?? null;\n const counterpartUser = userMap.get(counterpartUserId) ?? null;\n const introducerProfile =\n introducerActor && !createdByName\n ? profileMap.get(introducerActor.userId) ?? null\n : null;\n\n const counterpartName =\n counterpartProfile?.identity?.name ??\n counterpartUser?.name ??\n \"Someone\";\n const introducerName =\n createdByName ??\n (introducerActor ? introducerProfile?.identity?.name ?? null : null);\n const introducerUser = introducerActor\n ? userMap.get(introducerActor.userId) ?? null\n : null;\n\n const secondPartyUser = secondPartyActorForHeadline\n ? userMap.get(secondPartyActorForHeadline.userId) ?? null\n : null;\n const cardData = buildMinimalOpportunityCard(\n opp,\n context.userId,\n counterpartUserId,\n counterpartName,\n counterpartUser?.avatar ?? null,\n introducerName,\n introducerUser?.avatar ?? null,\n viewerName,\n secondPartyNameForHeadline,\n secondPartyUser?.avatar ?? null,\n secondPartyActorForHeadline?.userId,\n );\n\n // For MCP callers (e.g. Edge Claw), mint a connect token and attach\n // acceptUrl + profileUrl when the (status, viewerRole) is actionable\n // for the viewer. Non-actionable combos (sender-on-draft,\n // pending-on-introducer-waiting, rejected, etc.) deliberately get\n // no link — the LLM would otherwise hallucinate `/api/.../connect`\n // URLs from the exposed opportunityId.\n if (context.isMcp && deps.mintConnectLink) {\n const viewerActor = opp.actors.find((a) => a.userId === context.userId);\n const viewerApproved =\n viewerActor?.role === \"introducer\" ? viewerActor.approved === true : undefined;\n await attachActionableLinks(cardData as Record<string, unknown> & {\n opportunityId: string;\n viewerRole: string;\n status: string;\n }, {\n viewerId: context.userId,\n viewerApproved,\n counterpartUserId,\n mintConnectLink: deps.mintConnectLink,\n frontendUrl: deps.frontendUrl,\n preferredSurface: context.clientSurface,\n });\n }\n\n cardDataList.push(cardData);\n } catch (err) {\n logger.warn(\"Skipping opportunity that failed to build minimal card\", {\n opportunityId: opp.id,\n err,\n });\n skippedIds.push(opp.id);\n continue;\n }\n }\n }\n\n const listDebugSteps = buildListDebugSteps();\n\n if (cardDataList.length === 0) {\n if (skippedIds.length > 0) {\n return success({\n found: false,\n count: 0,\n summary: \"Some opportunities couldn't be displayed\",\n message:\n \"I found opportunities, but couldn't render them. Please try again.\",\n ...(listDebugSteps.length ? { debugSteps: listDebugSteps } : {}),\n });\n }\n return success({\n found: false,\n count: 0,\n summary: \"No opportunities yet\",\n message:\n \"You have no opportunities yet. Use discover_opportunities to find connections.\",\n });\n }\n\n return success({\n found: true,\n count: cardDataList.length,\n summary: `You have ${cardDataList.length} opportunity(ies)`,\n message: buildOpportunityPresentation(cardDataList, {\n isMcp: context.isMcp ?? false,\n leadIn: `You have ${cardDataList.length} opportunity(ies).`,\n includeDigestMarkers: context.isMcp === true && query.includeDigestMarkers === true,\n }),\n ...(listDebugSteps.length ? { debugSteps: listDebugSteps } : {}),\n });\n },\n });\n\n const updateOpportunity = defineTool({\n name: \"update_opportunity\",\n description:\n \"Updates an opportunity's status, advancing it through the connection lifecycle.\\n\\n\" +\n \"**Status transitions:**\\n\" +\n \"- `pending`: Sends a draft opportunity to the other party. They'll be notified and can accept or reject. \" +\n \"This is the primary action after discover_opportunities returns a draft.\\n\" +\n \"- `accepted`: Accept a received opportunity — opens a direct conversation between both parties. Returns a conversationId to surface to the user.\\n\" +\n \"- `rejected`: Decline a received opportunity.\\n\" +\n \"- `expired`: Mark as expired (typically done by the system after timeout).\\n\\n\" +\n \"**When to use:** After discover_opportunities or list_opportunities returns opportunity cards. \" +\n \"The user clicks 'Send' (pending), 'Accept', or 'Reject' on the card, and the agent calls this tool.\\n\\n\" +\n \"**Returns:** Confirmation with the new status and notification details (who was notified).\",\n querySchema: z.object({\n opportunityId: z\n .string()\n .describe(\"The UUID of the opportunity to update. Get from discover_opportunities or list_opportunities results.\"),\n status: z\n .enum([\"pending\", \"accepted\", \"rejected\", \"expired\"])\n .describe(\n \"New status: 'pending' = send the draft to the other party, 'accepted' = accept the connection, \" +\n \"'rejected' = decline, 'expired' = mark as timed out.\",\n ),\n }),\n handler: async ({ context, query }) => {\n const opportunityId = query.opportunityId?.trim();\n if (!opportunityId || !UUID_REGEX.test(opportunityId)) {\n return error(\"Valid opportunityId required.\");\n }\n\n // Always fetch the opportunity — needed for actor guard and state machine\n const opportunity = await systemDb.getOpportunity(opportunityId);\n if (!opportunity) {\n return error(\"Opportunity not found.\");\n }\n\n // Actor guard: caller must be a party to the opportunity\n const isActor = opportunity.actors?.some((a) => a.userId === context.userId);\n if (!isActor) {\n return error(\"Opportunity not found.\");\n }\n\n // Terminal-state and in-flight-negotiation guard.\n // Not a full state-machine: the Zod enum already constrains the target status,\n // and source statuses like `draft` / `latent` remain permitted.\n if (UPDATE_OPPORTUNITY_BLOCKED_STATUSES.has(opportunity.status)) {\n return error(`This opportunity is already ${opportunity.status} and cannot be updated.`);\n }\n\n // Strict scope enforcement: when chat is index-scoped, the caller's own\n // actor entry on this opportunity must be anchored on the bound network.\n // Mirrors the per-actor filter in getOpportunitiesForUser — relying on\n // `context.networkId` or any-actor matches would let a counterpart's\n // network presence shadow a viewer whose own actor is elsewhere.\n if (context.networkId) {\n const callerOnBoundNetwork = opportunity.actors?.some(\n (a) => a.userId === context.userId && a.networkId === context.networkId,\n );\n if (!callerOnBoundNetwork) {\n return error(\"Opportunity not found.\");\n }\n }\n\n const isSend = query.status === \"pending\";\n const _updateGraphStart = Date.now();\n const _updateTraceEmitter = requestContext.getStore()?.traceEmitter;\n _updateTraceEmitter?.({ type: \"graph_start\", name: \"opportunity\" });\n const result = await invokeWithAbortSignal(graphs.opportunity, {\n userId: context.userId,\n operationMode: isSend ? (\"send\" as const) : (\"update\" as const),\n opportunityId: query.opportunityId,\n ...(isSend ? {} : { newStatus: query.status }),\n });\n const _updateGraphMs = Date.now() - _updateGraphStart;\n _updateTraceEmitter?.({ type: \"graph_end\", name: \"opportunity\", durationMs: _updateGraphMs });\n\n if (result.mutationResult) {\n if (result.mutationResult.success) {\n return success({\n opportunityId: result.mutationResult.opportunityId,\n status: query.status,\n message: result.mutationResult.message,\n ...(result.mutationResult.notified && { notified: result.mutationResult.notified }),\n ...(result.mutationResult.conversationId && {\n conversationId: result.mutationResult.conversationId,\n }),\n _graphTimings: [{ name: 'opportunity', durationMs: _updateGraphMs, agents: result.agentTimings ?? [] }],\n });\n }\n return error(result.mutationResult.error || \"Failed to update opportunity.\");\n }\n return error(\"Failed to update opportunity.\");\n },\n });\n\n const confirmOpportunityDelivery = defineTool({\n name: \"confirm_opportunity_delivery\",\n description:\n \"Marks an opportunity as delivered to the user via the OpenClaw channel. \" +\n \"Call this for each opportunity you decide to surface, BEFORE including it in your delivery message. \" +\n \"The 'trigger' argument records which dispatch path produced this delivery: \" +\n \"'ambient' for real-time critical alerts (target ≤3/day), 'digest' for the daily sweep, \" +\n \"'accepted' for accepted-opportunity notifications to the counterparty. \" +\n \"Idempotent — safe to call even if the opportunity was already confirmed.\",\n querySchema: z.object({\n opportunityId: z\n .string()\n .describe(\"The UUID of the opportunity to mark as delivered.\"),\n trigger: z\n .enum(['ambient', 'digest', 'accepted'])\n .describe(\n \"Which dispatch path produced this delivery. Use 'ambient' if the dispatch prompt says you are in the ambient pass; use 'digest' if it says you are in the daily digest; use 'accepted' for accepted-opportunity notifications to the counterparty.\",\n ),\n }),\n handler: async ({ context, query }) => {\n if (!context.isMcp || !context.agentId) {\n return confirmDeliveryError(\n \"unauthenticated\",\n false,\n \"confirm_opportunity_delivery is only available to authenticated agent MCP contexts.\",\n );\n }\n if (!deps.deliveryLedger) {\n return confirmDeliveryError(\n \"ledger_unavailable\",\n false,\n \"Delivery ledger not available in this context.\",\n );\n }\n if (!UUID_REGEX.test(query.opportunityId)) {\n return confirmDeliveryError(\n \"invalid_opportunity_id\",\n false,\n \"Invalid opportunity ID format.\",\n );\n }\n try {\n const result = await deps.deliveryLedger.confirmOpportunityDelivery({\n opportunityId: query.opportunityId,\n userId: context.userId,\n agentId: context.agentId,\n trigger: query.trigger,\n });\n return success({ status: result });\n } catch (err) {\n const reason = err instanceof Error ? err.message : String(err);\n // Permanent failures — the caller MUST NOT retry. Retrying a deleted\n // opportunity or an unauthorized actor never succeeds and only spams\n // the ledger / MCP transport.\n if (reason === 'opportunity_not_found') {\n logger.warn('confirm_opportunity_delivery: opportunity not found', {\n opportunityId: query.opportunityId,\n });\n return confirmDeliveryError(\n 'opportunity_not_found',\n false,\n 'Opportunity not found — it may have been deleted. Do not retry.',\n );\n }\n if (reason === 'not_authorized') {\n logger.warn('confirm_opportunity_delivery: caller is not an actor', {\n opportunityId: query.opportunityId,\n userId: context.userId,\n });\n return confirmDeliveryError(\n 'not_authorized',\n false,\n 'You are not an actor on this opportunity. Do not retry.',\n );\n }\n // Unknown / transient (e.g. DB connectivity) — safe to retry. The\n // ledger write is idempotent, so a retry that races a prior success\n // returns 'already_delivered' rather than a duplicate row.\n logger.error('Failed to confirm opportunity delivery', { err });\n return confirmDeliveryError(\n 'confirm_failed',\n true,\n 'Failed to confirm opportunity delivery — transient error, safe to retry.',\n );\n }\n },\n });\n\n return [\n discoverOpportunities,\n getDiscoveryRun,\n cancelDiscoveryRun,\n listOpportunities,\n updateOpportunity,\n confirmOpportunityDelivery,\n ] as const;\n}\n"]}