@indexnetwork/protocol 3.6.3-rc.271.1 → 3.6.3-rc.272.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.
Files changed (76) hide show
  1. package/dist/agent/tests/fakes.d.ts.map +1 -1
  2. package/dist/agent/tests/fakes.js.map +1 -1
  3. package/dist/chat/chat.agent.d.ts.map +1 -1
  4. package/dist/chat/chat.agent.js +3 -3
  5. package/dist/chat/chat.agent.js.map +1 -1
  6. package/dist/chat/chat.streamer.d.ts.map +1 -1
  7. package/dist/chat/chat.streamer.js +1 -1
  8. package/dist/chat/chat.streamer.js.map +1 -1
  9. package/dist/chat/chat.summarizer.d.ts.map +1 -1
  10. package/dist/chat/chat.summarizer.js +1 -1
  11. package/dist/chat/chat.summarizer.js.map +1 -1
  12. package/dist/chat/tests/chat.graph.mocks.d.ts.map +1 -1
  13. package/dist/chat/tests/chat.graph.mocks.js +0 -1
  14. package/dist/chat/tests/chat.graph.mocks.js.map +1 -1
  15. package/dist/index.d.ts +21 -21
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +10 -10
  18. package/dist/index.js.map +1 -1
  19. package/dist/intent/intent.graph.js +1 -1
  20. package/dist/intent/intent.graph.js.map +1 -1
  21. package/dist/maintenance/maintenance.graph.d.ts.map +1 -1
  22. package/dist/maintenance/maintenance.graph.js +1 -1
  23. package/dist/maintenance/maintenance.graph.js.map +1 -1
  24. package/dist/negotiation/negotiation.agent.d.ts.map +1 -1
  25. package/dist/negotiation/negotiation.agent.js +1 -1
  26. package/dist/negotiation/negotiation.agent.js.map +1 -1
  27. package/dist/negotiation/negotiation.summarizer.d.ts.map +1 -1
  28. package/dist/negotiation/negotiation.summarizer.js +1 -1
  29. package/dist/negotiation/negotiation.summarizer.js.map +1 -1
  30. package/dist/network/indexer/indexer.graph.d.ts.map +1 -1
  31. package/dist/network/indexer/indexer.graph.js +2 -2
  32. package/dist/network/indexer/indexer.graph.js.map +1 -1
  33. package/dist/opportunity/discovery-question.helper.d.ts.map +1 -1
  34. package/dist/opportunity/discovery-question.helper.js.map +1 -1
  35. package/dist/opportunity/feed/feed.graph.d.ts.map +1 -1
  36. package/dist/opportunity/feed/feed.graph.js +1 -1
  37. package/dist/opportunity/feed/feed.graph.js.map +1 -1
  38. package/dist/opportunity/negotiation-summary.builder.d.ts.map +1 -1
  39. package/dist/opportunity/negotiation-summary.builder.js.map +1 -1
  40. package/dist/opportunity/opportunity.discover.d.ts.map +1 -1
  41. package/dist/opportunity/opportunity.discover.js +1 -1
  42. package/dist/opportunity/opportunity.discover.js.map +1 -1
  43. package/dist/opportunity/opportunity.enricher.d.ts.map +1 -1
  44. package/dist/opportunity/opportunity.enricher.js.map +1 -1
  45. package/dist/opportunity/opportunity.graph.d.ts.map +1 -1
  46. package/dist/opportunity/opportunity.graph.js +5 -5
  47. package/dist/opportunity/opportunity.graph.js.map +1 -1
  48. package/dist/opportunity/opportunity.persist.d.ts.map +1 -1
  49. package/dist/opportunity/opportunity.persist.js.map +1 -1
  50. package/dist/opportunity/question.generator.d.ts.map +1 -1
  51. package/dist/opportunity/question.generator.js +2 -2
  52. package/dist/opportunity/question.generator.js.map +1 -1
  53. package/dist/premise/premise.graph.d.ts.map +1 -1
  54. package/dist/premise/premise.graph.js +1 -1
  55. package/dist/premise/premise.graph.js.map +1 -1
  56. package/dist/profile/profile.graph.js +1 -1
  57. package/dist/profile/profile.graph.js.map +1 -1
  58. package/dist/questioner/questioner.agent.d.ts.map +1 -1
  59. package/dist/questioner/questioner.agent.js +1 -1
  60. package/dist/questioner/questioner.agent.js.map +1 -1
  61. package/dist/questioner/questioner.presets.d.ts.map +1 -1
  62. package/dist/questioner/questioner.presets.js +1 -1
  63. package/dist/questioner/questioner.presets.js.map +1 -1
  64. package/dist/shared/agent/response.streamer.d.ts.map +1 -1
  65. package/dist/shared/agent/response.streamer.js +1 -1
  66. package/dist/shared/agent/response.streamer.js.map +1 -1
  67. package/dist/shared/agent/tool.factory.d.ts.map +1 -1
  68. package/dist/shared/agent/tool.factory.js +1 -1
  69. package/dist/shared/agent/tool.factory.js.map +1 -1
  70. package/dist/shared/agent/tool.helpers.d.ts.map +1 -1
  71. package/dist/shared/agent/tool.helpers.js.map +1 -1
  72. package/dist/shared/assignment/network-assignment.policy.d.ts.map +1 -1
  73. package/dist/shared/assignment/network-assignment.policy.js.map +1 -1
  74. package/dist/shared/interfaces/questioner.interface.d.ts.map +1 -1
  75. package/dist/shared/interfaces/questioner.interface.js.map +1 -1
  76. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"negotiation.agent.js","sourceRoot":"/","sources":["negotiation/negotiation.agent.ts"],"names":[],"mappings":"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","sourcesContent":["import { createModel } from \"../shared/agent/model.config.js\";\nimport { invokeWithAbortSignal } from \"../shared/agent/model-signal.js\";\nimport {\n SystemNegotiationTurnSchema,\n FinalNegotiationTurnSchema,\n type NegotiationTurn,\n type UserNegotiationContext,\n type SeedAssessment,\n} from \"./negotiation.state.js\";\nimport type { NegotiationUserAnswer } from \"../shared/interfaces/database.interface.js\";\n\nconst SYSTEM_PROMPT = `You are the Index Negotiator, an AI agent acting on behalf of {userName}. You represent their interests in a bilateral negotiation about a potential connection on a discovery network.\n\n{discoveryContext}\n{discoveryQueryContext}\nYour user's role in this connection: {role}\nNetwork context: {networkContext}\n\nYour job: Evaluate whether this connection genuinely serves {userName}'s interests given their role. Argue their case honestly — acknowledge weaknesses, but advocate for genuine fit.\n\nRules:\n- On the FIRST turn: Propose the connection case. Explain why it would benefit both parties. Set action to \"propose\".\n- On SUBSEQUENT turns: Evaluate the other agent's arguments. Either:\n - \"counter\" if you have specific objections but see potential\n - \"accept\" if the match genuinely benefits {userName}\n - \"reject\" if the match does not serve {userName}'s needs\n- Focus on concrete intent alignment, not vague overlap.\n- Do NOT reference internal system details like scores, pre-screens, or evaluator outputs.\n- suggestedRoles: \"agent\" = can help, \"patient\" = seeks help, \"peer\" = mutual benefit.\n{finalTurnInstruction}`;\n\nexport interface NegotiationAgentInput {\n ownUser: UserNegotiationContext;\n otherUser: UserNegotiationContext;\n indexContext: { networkId: string; prompt?: string };\n seedAssessment: SeedAssessment;\n history: NegotiationTurn[];\n isFinalTurn?: boolean;\n /** Whether ownUser is the party that initiated the discovery (searched/signalled). */\n isDiscoverer?: boolean;\n /** The explicit search query that triggered discovery (if any). Takes priority over background intents. */\n discoveryQuery?: string;\n /** Whether this negotiation is continuing a prior conversation with the same counterparty. */\n isContinuation?: boolean;\n /** User answers collected by the questioner between negotiation sessions. */\n userAnswers?: NegotiationUserAnswer[];\n}\n\nexport interface IndexNegotiatorConfig {\n /**\n * Hard ceiling on a single LLM turn round-trip, in ms. When the underlying\n * model.invoke call exceeds this, an AbortSignal cancels the request and the\n * promise rejects — the calling turn node catches the rejection and treats it\n * as a failed turn, so one slow upstream call cannot consume the whole\n * negotiate-phase budget.\n *\n * Defaults to `NEGOTIATOR_TURN_TIMEOUT_MS` env var when set, otherwise\n * `DEFAULT_TURN_TIMEOUT_MS`. Sized to clip the p99 tail on Gemini-2.5-Flash\n * (~20 s today on OpenRouter) without trimming p90 (~12 s).\n */\n turnTimeoutMs?: number;\n}\n\nconst DEFAULT_TURN_TIMEOUT_MS = 15_000;\n\n// Resolver-valid range is `(0, Number.MAX_SAFE_INTEGER]`. The upper bound is\n// the runtime ceiling: `AbortSignal.timeout(N)` throws when N is outside\n// `[0, Number.MAX_SAFE_INTEGER]`, so `Number.isFinite` alone isn't enough —\n// values like `1e30` pass finiteness but blow up at the AbortSignal call.\n// The lower bound (`n > 0`) is a design choice rather than a runtime\n// constraint: `AbortSignal.timeout(0)` is technically legal but would abort\n// every turn before the LLM produces a response, so we reject it and fall\n// back to the default just like any other invalid override.\nfunction isValidTimeoutMs(n: number): boolean {\n return Number.isFinite(n) && n > 0 && n <= Number.MAX_SAFE_INTEGER;\n}\n\nfunction resolveTurnTimeoutMs(override?: number): number {\n if (typeof override === \"number\" && isValidTimeoutMs(override)) return override;\n const envValue = process.env.NEGOTIATOR_TURN_TIMEOUT_MS;\n if (envValue) {\n const parsed = Number(envValue);\n if (isValidTimeoutMs(parsed)) return parsed;\n }\n return DEFAULT_TURN_TIMEOUT_MS;\n}\n\n/**\n * Unified system negotiation agent that advocates for its user.\n * Adapts behavior based on turn position (first turn = propose, subsequent = respond).\n * @remarks Uses structured output constrained to NegotiationTurnSchema (without question action).\n */\nexport class IndexNegotiator {\n private readonly turnTimeoutMs: number;\n\n constructor(config?: IndexNegotiatorConfig) {\n this.turnTimeoutMs = resolveTurnTimeoutMs(config?.turnTimeoutMs);\n }\n\n /**\n * Generate a negotiation turn.\n * @param input - User contexts, seed assessment, history, and final turn flag\n * @returns A structured NegotiationTurn\n * @throws If the per-turn timeout fires before the LLM responds.\n */\n async invoke(input: NegotiationAgentInput): Promise<NegotiationTurn> {\n const schema = input.isFinalTurn ? FinalNegotiationTurnSchema : SystemNegotiationTurnSchema;\n const model = createModel(\"negotiator\").withStructuredOutput(schema, { name: \"index_negotiator\" });\n\n const userName = input.ownUser.profile.name ?? \"your user\";\n const role = input.seedAssessment.valencyRole || \"peer\";\n const networkContext = input.indexContext.prompt || \"General discovery\";\n const finalTurnInstruction = input.isFinalTurn\n ? \"\\n\\nIMPORTANT: This is your FINAL turn. You MUST choose either 'accept' or 'reject'. No counter is allowed.\"\n : \"\";\n\n const otherName = input.otherUser.profile.name ?? \"the other user\";\n const discoveryContext = input.isDiscoverer\n ? `${userName} initiated this discovery — they are actively looking for connections. ${otherName} was identified as a potential match.`\n : `${otherName} initiated this discovery and found ${userName} as a potential match. You are representing the discovered party.`;\n\n const discoveryQueryContext = input.discoveryQuery\n ? `\\nDISCOVERY QUERY: ${userName} explicitly searched for \"${input.discoveryQuery}\".\nQUERY PRIORITY RULE: This search query is the PRIMARY criterion for this negotiation. Before evaluating intents or profile overlap, first answer: does ${otherName} satisfy the search query \"${input.discoveryQuery}\"?\n- If the query is a role or identity term (e.g. \"samurai\", \"investors\", \"designers\"): check whether ${otherName} IS that thing based on their profile. Subject-matter adjacency does not count (drawing samurai ≠ being a samurai, raising funding ≠ being an investor).\n- If ${otherName} does NOT satisfy the query: REJECT the match. Background intents cannot rescue a query mismatch.\n- If ${otherName} DOES satisfy the query: PROPOSE or ACCEPT the connection and evaluate fit normally using intents and profile data.`\n : '';\n\n const systemPrompt = SYSTEM_PROMPT\n .replace(/{userName}/g, userName)\n .replace(\"{discoveryContext}\", discoveryContext)\n .replace(\"{discoveryQueryContext}\", discoveryQueryContext)\n .replace(\"{role}\", role)\n .replace(\"{networkContext}\", networkContext)\n .replace(\"{finalTurnInstruction}\", finalTurnInstruction);\n\n const historyText = input.history.length > 0\n ? `\\n\\nNegotiation history:\\n${input.history.map((t, i) => {\n const msgPart = t.message ? ` — message: ${t.message}` : '';\n return `Turn ${i + 1}: ${t.action} — reasoning: ${t.assessment.reasoning}${msgPart}`;\n }).join(\"\\n\")}`\n : \"\";\n\n const continuationContext = input.isContinuation && input.history.length > 0\n ? `\\n\\n--- Prior dialogue with this counterparty ---\n${historyText}\n\n--- New signal under evaluation ---\n${input.discoveryQuery\n ? `Discovery query: \"${input.discoveryQuery}\"`\n : `Seed assessment: ${input.seedAssessment.reasoning}`\n}\n\nPolicy: You are continuing a prior dialogue. If this signal is materially the same as one you previously evaluated, you may resolve quickly. If materially different, evaluate on its own merits.`\n : '';\n\n const userAnswersContext = input.userAnswers && input.userAnswers.length > 0\n ? `\\n\\n--- ${userName}'s additional context (provided between sessions) ---\\n${input.userAnswers.map((a) => {\n const opts = Array.isArray(a.selectedOptions) ? a.selectedOptions : [];\n const parts = opts.length > 0 ? opts.join(', ') : '';\n const free = a.freeText ? (parts ? ` — ${a.freeText}` : a.freeText) : '';\n if (!parts && !free) return '';\n return `- ${parts}${free}`;\n }).filter(Boolean).join(\"\\n\")}\\n`\n : '';\n\n const discoveryQueryReminder = input.discoveryQuery\n ? `\\nREMINDER: ${userName} searched for \"${input.discoveryQuery}\". Evaluate ${otherName} against this query FIRST. If ${otherName} is not a \"${input.discoveryQuery}\", reject.\\n`\n : '';\n\n const intentsLabel = input.discoveryQuery ? 'Background intents (secondary to discovery query)' : 'Intents';\n\n const userMessage = `YOUR USER (${userName}):\nBio: ${input.ownUser.profile.bio ?? \"N/A\"}\nSkills: ${input.ownUser.profile.skills?.join(\", \") ?? \"N/A\"}\n${intentsLabel}:\n${input.ownUser.intents.map((i) => `- ${i.title}: ${i.description}`).join(\"\\n\")}\n\nOTHER USER (${otherName}):\nBio: ${input.otherUser.profile.bio ?? \"N/A\"}\nSkills: ${input.otherUser.profile.skills?.join(\", \") ?? \"N/A\"}\nIntents:\n${input.otherUser.intents.map((i) => `- ${i.title}: ${i.description}`).join(\"\\n\")}\n\nWhy this match was suggested: ${input.seedAssessment.reasoning}${input.isContinuation ? continuationContext : historyText}${userAnswersContext}\n${discoveryQueryReminder}\n${input.history.length === 0 && !input.isContinuation ? \"This is the opening turn. Propose the connection case.\" : \"Evaluate the latest arguments and respond.\"}`;\n\n const result = await invokeWithAbortSignal(\n model,\n [\n { role: \"system\", content: systemPrompt },\n { role: \"user\", content: userMessage },\n ],\n AbortSignal.timeout(this.turnTimeoutMs),\n );\n\n return result as NegotiationTurn;\n }\n}\n"]}
1
+ {"version":3,"file":"negotiation.agent.js","sourceRoot":"/","sources":["negotiation/negotiation.agent.ts"],"names":[],"mappings":"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","sourcesContent":["import { createModel } from \"../shared/agent/model.config.js\";\nimport { invokeWithAbortSignal } from \"../shared/agent/model-signal.js\";\nimport { SystemNegotiationTurnSchema, FinalNegotiationTurnSchema, type NegotiationTurn, type UserNegotiationContext, type SeedAssessment } from \"./negotiation.state.js\";\nimport type { NegotiationUserAnswer } from \"../shared/interfaces/database.interface.js\";\n\nconst SYSTEM_PROMPT = `You are the Index Negotiator, an AI agent acting on behalf of {userName}. You represent their interests in a bilateral negotiation about a potential connection on a discovery network.\n\n{discoveryContext}\n{discoveryQueryContext}\nYour user's role in this connection: {role}\nNetwork context: {networkContext}\n\nYour job: Evaluate whether this connection genuinely serves {userName}'s interests given their role. Argue their case honestly — acknowledge weaknesses, but advocate for genuine fit.\n\nRules:\n- On the FIRST turn: Propose the connection case. Explain why it would benefit both parties. Set action to \"propose\".\n- On SUBSEQUENT turns: Evaluate the other agent's arguments. Either:\n - \"counter\" if you have specific objections but see potential\n - \"accept\" if the match genuinely benefits {userName}\n - \"reject\" if the match does not serve {userName}'s needs\n- Focus on concrete intent alignment, not vague overlap.\n- Do NOT reference internal system details like scores, pre-screens, or evaluator outputs.\n- suggestedRoles: \"agent\" = can help, \"patient\" = seeks help, \"peer\" = mutual benefit.\n{finalTurnInstruction}`;\n\nexport interface NegotiationAgentInput {\n ownUser: UserNegotiationContext;\n otherUser: UserNegotiationContext;\n indexContext: { networkId: string; prompt?: string };\n seedAssessment: SeedAssessment;\n history: NegotiationTurn[];\n isFinalTurn?: boolean;\n /** Whether ownUser is the party that initiated the discovery (searched/signalled). */\n isDiscoverer?: boolean;\n /** The explicit search query that triggered discovery (if any). Takes priority over background intents. */\n discoveryQuery?: string;\n /** Whether this negotiation is continuing a prior conversation with the same counterparty. */\n isContinuation?: boolean;\n /** User answers collected by the questioner between negotiation sessions. */\n userAnswers?: NegotiationUserAnswer[];\n}\n\nexport interface IndexNegotiatorConfig {\n /**\n * Hard ceiling on a single LLM turn round-trip, in ms. When the underlying\n * model.invoke call exceeds this, an AbortSignal cancels the request and the\n * promise rejects — the calling turn node catches the rejection and treats it\n * as a failed turn, so one slow upstream call cannot consume the whole\n * negotiate-phase budget.\n *\n * Defaults to `NEGOTIATOR_TURN_TIMEOUT_MS` env var when set, otherwise\n * `DEFAULT_TURN_TIMEOUT_MS`. Sized to clip the p99 tail on Gemini-2.5-Flash\n * (~20 s today on OpenRouter) without trimming p90 (~12 s).\n */\n turnTimeoutMs?: number;\n}\n\nconst DEFAULT_TURN_TIMEOUT_MS = 15_000;\n\n// Resolver-valid range is `(0, Number.MAX_SAFE_INTEGER]`. The upper bound is\n// the runtime ceiling: `AbortSignal.timeout(N)` throws when N is outside\n// `[0, Number.MAX_SAFE_INTEGER]`, so `Number.isFinite` alone isn't enough —\n// values like `1e30` pass finiteness but blow up at the AbortSignal call.\n// The lower bound (`n > 0`) is a design choice rather than a runtime\n// constraint: `AbortSignal.timeout(0)` is technically legal but would abort\n// every turn before the LLM produces a response, so we reject it and fall\n// back to the default just like any other invalid override.\nfunction isValidTimeoutMs(n: number): boolean {\n return Number.isFinite(n) && n > 0 && n <= Number.MAX_SAFE_INTEGER;\n}\n\nfunction resolveTurnTimeoutMs(override?: number): number {\n if (typeof override === \"number\" && isValidTimeoutMs(override)) return override;\n const envValue = process.env.NEGOTIATOR_TURN_TIMEOUT_MS;\n if (envValue) {\n const parsed = Number(envValue);\n if (isValidTimeoutMs(parsed)) return parsed;\n }\n return DEFAULT_TURN_TIMEOUT_MS;\n}\n\n/**\n * Unified system negotiation agent that advocates for its user.\n * Adapts behavior based on turn position (first turn = propose, subsequent = respond).\n * @remarks Uses structured output constrained to NegotiationTurnSchema (without question action).\n */\nexport class IndexNegotiator {\n private readonly turnTimeoutMs: number;\n\n constructor(config?: IndexNegotiatorConfig) {\n this.turnTimeoutMs = resolveTurnTimeoutMs(config?.turnTimeoutMs);\n }\n\n /**\n * Generate a negotiation turn.\n * @param input - User contexts, seed assessment, history, and final turn flag\n * @returns A structured NegotiationTurn\n * @throws If the per-turn timeout fires before the LLM responds.\n */\n async invoke(input: NegotiationAgentInput): Promise<NegotiationTurn> {\n const schema = input.isFinalTurn ? FinalNegotiationTurnSchema : SystemNegotiationTurnSchema;\n const model = createModel(\"negotiator\").withStructuredOutput(schema, { name: \"index_negotiator\" });\n\n const userName = input.ownUser.profile.name ?? \"your user\";\n const role = input.seedAssessment.valencyRole || \"peer\";\n const networkContext = input.indexContext.prompt || \"General discovery\";\n const finalTurnInstruction = input.isFinalTurn\n ? \"\\n\\nIMPORTANT: This is your FINAL turn. You MUST choose either 'accept' or 'reject'. No counter is allowed.\"\n : \"\";\n\n const otherName = input.otherUser.profile.name ?? \"the other user\";\n const discoveryContext = input.isDiscoverer\n ? `${userName} initiated this discovery — they are actively looking for connections. ${otherName} was identified as a potential match.`\n : `${otherName} initiated this discovery and found ${userName} as a potential match. You are representing the discovered party.`;\n\n const discoveryQueryContext = input.discoveryQuery\n ? `\\nDISCOVERY QUERY: ${userName} explicitly searched for \"${input.discoveryQuery}\".\nQUERY PRIORITY RULE: This search query is the PRIMARY criterion for this negotiation. Before evaluating intents or profile overlap, first answer: does ${otherName} satisfy the search query \"${input.discoveryQuery}\"?\n- If the query is a role or identity term (e.g. \"samurai\", \"investors\", \"designers\"): check whether ${otherName} IS that thing based on their profile. Subject-matter adjacency does not count (drawing samurai ≠ being a samurai, raising funding ≠ being an investor).\n- If ${otherName} does NOT satisfy the query: REJECT the match. Background intents cannot rescue a query mismatch.\n- If ${otherName} DOES satisfy the query: PROPOSE or ACCEPT the connection and evaluate fit normally using intents and profile data.`\n : '';\n\n const systemPrompt = SYSTEM_PROMPT\n .replace(/{userName}/g, userName)\n .replace(\"{discoveryContext}\", discoveryContext)\n .replace(\"{discoveryQueryContext}\", discoveryQueryContext)\n .replace(\"{role}\", role)\n .replace(\"{networkContext}\", networkContext)\n .replace(\"{finalTurnInstruction}\", finalTurnInstruction);\n\n const historyText = input.history.length > 0\n ? `\\n\\nNegotiation history:\\n${input.history.map((t, i) => {\n const msgPart = t.message ? ` — message: ${t.message}` : '';\n return `Turn ${i + 1}: ${t.action} — reasoning: ${t.assessment.reasoning}${msgPart}`;\n }).join(\"\\n\")}`\n : \"\";\n\n const continuationContext = input.isContinuation && input.history.length > 0\n ? `\\n\\n--- Prior dialogue with this counterparty ---\n${historyText}\n\n--- New signal under evaluation ---\n${input.discoveryQuery\n ? `Discovery query: \"${input.discoveryQuery}\"`\n : `Seed assessment: ${input.seedAssessment.reasoning}`\n}\n\nPolicy: You are continuing a prior dialogue. If this signal is materially the same as one you previously evaluated, you may resolve quickly. If materially different, evaluate on its own merits.`\n : '';\n\n const userAnswersContext = input.userAnswers && input.userAnswers.length > 0\n ? `\\n\\n--- ${userName}'s additional context (provided between sessions) ---\\n${input.userAnswers.map((a) => {\n const opts = Array.isArray(a.selectedOptions) ? a.selectedOptions : [];\n const parts = opts.length > 0 ? opts.join(', ') : '';\n const free = a.freeText ? (parts ? ` — ${a.freeText}` : a.freeText) : '';\n if (!parts && !free) return '';\n return `- ${parts}${free}`;\n }).filter(Boolean).join(\"\\n\")}\\n`\n : '';\n\n const discoveryQueryReminder = input.discoveryQuery\n ? `\\nREMINDER: ${userName} searched for \"${input.discoveryQuery}\". Evaluate ${otherName} against this query FIRST. If ${otherName} is not a \"${input.discoveryQuery}\", reject.\\n`\n : '';\n\n const intentsLabel = input.discoveryQuery ? 'Background intents (secondary to discovery query)' : 'Intents';\n\n const userMessage = `YOUR USER (${userName}):\nBio: ${input.ownUser.profile.bio ?? \"N/A\"}\nSkills: ${input.ownUser.profile.skills?.join(\", \") ?? \"N/A\"}\n${intentsLabel}:\n${input.ownUser.intents.map((i) => `- ${i.title}: ${i.description}`).join(\"\\n\")}\n\nOTHER USER (${otherName}):\nBio: ${input.otherUser.profile.bio ?? \"N/A\"}\nSkills: ${input.otherUser.profile.skills?.join(\", \") ?? \"N/A\"}\nIntents:\n${input.otherUser.intents.map((i) => `- ${i.title}: ${i.description}`).join(\"\\n\")}\n\nWhy this match was suggested: ${input.seedAssessment.reasoning}${input.isContinuation ? continuationContext : historyText}${userAnswersContext}\n${discoveryQueryReminder}\n${input.history.length === 0 && !input.isContinuation ? \"This is the opening turn. Propose the connection case.\" : \"Evaluate the latest arguments and respond.\"}`;\n\n const result = await invokeWithAbortSignal(\n model,\n [\n { role: \"system\", content: systemPrompt },\n { role: \"user\", content: userMessage },\n ],\n AbortSignal.timeout(this.turnTimeoutMs),\n );\n\n return result as NegotiationTurn;\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"negotiation.summarizer.d.ts","sourceRoot":"/","sources":["negotiation/negotiation.summarizer.ts"],"names":[],"mappings":"AAiBA,OAAO,EAEL,KAAK,0BAA0B,EAChC,MAAM,gDAAgD,CAAC;AACxD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AAoC9E,qBAAa,qBAAqB;IAChC,OAAO,CAAC,KAAK,CAAiD;;IASxD,SAAS,CACb,WAAW,EAAE,oBAAoB,EACjC,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GACjC,OAAO,CAAC,0BAA0B,GAAG,IAAI,CAAC;CA8B9C;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,oBAAoB,GAAG,0BAA0B,CAqBvF"}
1
+ {"version":3,"file":"negotiation.summarizer.d.ts","sourceRoot":"/","sources":["negotiation/negotiation.summarizer.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAoC,KAAK,0BAA0B,EAAE,MAAM,gDAAgD,CAAC;AACnI,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AAoC9E,qBAAa,qBAAqB;IAChC,OAAO,CAAC,KAAK,CAAiD;;IASxD,SAAS,CACb,WAAW,EAAE,oBAAoB,EACjC,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GACjC,OAAO,CAAC,0BAA0B,GAAG,IAAI,CAAC;CA8B9C;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,oBAAoB,GAAG,0BAA0B,CAqBvF"}
@@ -2,7 +2,7 @@ import { HumanMessage, SystemMessage } from "@langchain/core/messages";
2
2
  import { createModel } from "../shared/agent/model.config.js";
3
3
  import { invokeWithAbortSignal } from "../shared/agent/model-signal.js";
4
4
  import { protocolLogger } from "../shared/observability/protocol.logger.js";
5
- import { DiscoveryNegotiationDigestSchema, } from "../shared/schemas/negotiation-digest.schema.js";
5
+ import { DiscoveryNegotiationDigestSchema } from "../shared/schemas/negotiation-digest.schema.js";
6
6
  const logger = protocolLogger("NegotiationSummarizer");
7
7
  const SYSTEM_PROMPT = `You summarize one negotiation between a seeker's agent and a candidate's agent into a structured digest for downstream decision-question generation.
8
8
 
@@ -1 +1 @@
1
- {"version":3,"file":"negotiation.summarizer.js","sourceRoot":"/","sources":["negotiation/negotiation.summarizer.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * NegotiationSummarizer — pure LLM pass that compresses one DiscoveryNegotiation\n * (potentially several KB of turn reasoning + outcome reasoning) into a\n * DiscoveryNegotiationDigest (≤256 bytes structured). The digest is what the decision-\n * question generator consumes, replacing the raw negotiation blob.\n *\n * Why: a 10-candidate discovery turn used to produce a 60+ KB prompt for the\n * question generator, which stalled upstream Gemini/OpenRouter routes and\n * dropped the connection at ~3 minutes. Per-negotiation summarization caps\n * the question-generator input at a fixed, predictable size.\n */\nimport type { ChatOpenAI } from \"@langchain/openai\";\nimport { HumanMessage, SystemMessage } from \"@langchain/core/messages\";\n\nimport { createModel } from \"../shared/agent/model.config.js\";\nimport { invokeWithAbortSignal } from \"../shared/agent/model-signal.js\";\nimport { protocolLogger } from \"../shared/observability/protocol.logger.js\";\nimport {\n DiscoveryNegotiationDigestSchema,\n type DiscoveryNegotiationDigest,\n} from \"../shared/schemas/negotiation-digest.schema.js\";\nimport type { DiscoveryNegotiation } from \"../opportunity/question.prompt.js\";\n\nconst logger = protocolLogger(\"NegotiationSummarizer\");\n\nconst SYSTEM_PROMPT = `You summarize one negotiation between a seeker's agent and a candidate's agent into a structured digest for downstream decision-question generation.\n\nOutput requirements (ALL fields — set optional fields to null when not applicable):\n- counterpartyHint: copy the input field verbatim, truncated to ≤120 chars.\n- indexContext: copy the input field verbatim, truncated to ≤120 chars.\n- outcomeRole: \"opportunity\" when hasOpportunity=true, else \"no-opportunity\".\n- outcomeReason: when outcomeRole=\"no-opportunity\", set to \"turn_cap\" / \"timeout\" if the input's reason matches; else \"rejected\" (if a turn explicitly rejected) or \"stalled\". When outcomeRole=\"opportunity\", set to null.\n- keyTake: ONE sentence (≤180 chars). Describe the decisive moment, the alignment gap, or the recurring signal — anything a question generator could use to formulate a clarifying question. NOT a generic outcome restatement. Anchor in a concrete detail from the negotiation if possible (a role mismatch, a missing input the candidate flagged, a pivot one party suggested).\n- suggestedRoles: when both parties agreed on roles (the last turn's suggestedRoles), copy them from input. Otherwise set to null.\n\nDo not include candidate identity, PII, names, or IDs. Reuse only counterpartyHint and indexContext as provided.`;\n\nfunction buildUserPrompt(n: DiscoveryNegotiation): string {\n const turnLines = n.turns\n .map(\n (t, i) =>\n `[${i + 1}] action=${t.action} roles=${t.suggestedRoles.ownUser}↔${t.suggestedRoles.otherUser} reasoning=${t.reasoning}`,\n )\n .join(\"\\n\");\n return [\n `counterpartyHint: ${n.counterpartyHint}`,\n `indexContext: ${n.indexContext}`,\n `turns (${n.turns.length}):`,\n turnLines || \"(no turns)\",\n `outcome.hasOpportunity: ${n.outcome.hasOpportunity}`,\n `outcome.reasoning: ${n.outcome.reasoning}`,\n n.outcome.reason ? `outcome.reason: ${n.outcome.reason}` : \"\",\n ]\n .filter(Boolean)\n .join(\"\\n\");\n}\n\nexport class NegotiationSummarizer {\n private model: ReturnType<ChatOpenAI[\"withStructuredOutput\"]>;\n\n constructor() {\n const llm = createModel(\"negotiationSummarizer\");\n this.model = llm.withStructuredOutput(DiscoveryNegotiationDigestSchema, {\n name: \"negotiation_digest\",\n });\n }\n\n async summarize(\n negotiation: DiscoveryNegotiation,\n options?: { signal?: AbortSignal },\n ): Promise<DiscoveryNegotiationDigest | null> {\n const user = buildUserPrompt(negotiation);\n let raw: unknown;\n try {\n raw = await invokeWithAbortSignal(\n this.model,\n [new SystemMessage(SYSTEM_PROMPT), new HumanMessage(user)],\n options?.signal,\n );\n } catch (err) {\n const aborted = options?.signal?.aborted ?? false;\n if (aborted) {\n logger.info(\"NegotiationSummarizer aborted by signal\", {\n reason: options?.signal?.reason instanceof Error ? options.signal.reason.message : String(options?.signal?.reason ?? \"unknown\"),\n });\n } else {\n logger.warn(\"NegotiationSummarizer LLM call failed\", {\n error: err instanceof Error ? err.message : String(err),\n });\n }\n return null;\n }\n\n const parsed = DiscoveryNegotiationDigestSchema.safeParse(raw);\n if (!parsed.success) {\n logger.warn(\"NegotiationSummarizer parse failed\", { error: parsed.error.message });\n return null;\n }\n return parsed.data;\n }\n}\n\n/**\n * Deterministic fallback when the LLM summarizer fails or isn't wired. Produces\n * a minimal but valid digest so the question generator still has *some* signal.\n */\nexport function buildFallbackDigest(n: DiscoveryNegotiation): DiscoveryNegotiationDigest {\n const outcomeRole = n.outcome.hasOpportunity ? \"opportunity\" : \"no-opportunity\";\n const lastTurn = n.turns[n.turns.length - 1];\n const keyTakeRaw =\n n.outcome.reasoning && n.outcome.reasoning.trim().length > 0\n ? n.outcome.reasoning\n : `${n.turns.length} turn(s); ended ${outcomeRole}`;\n return {\n counterpartyHint: n.counterpartyHint.slice(0, 120),\n indexContext: n.indexContext.slice(0, 120),\n outcomeRole,\n outcomeReason:\n outcomeRole === \"no-opportunity\"\n ? ((n.outcome.reason ?? \"stalled\") as \"turn_cap\" | \"timeout\" | \"stalled\")\n : null,\n keyTake: keyTakeRaw.slice(0, 180),\n suggestedRoles:\n lastTurn?.action === \"accept\" && lastTurn.suggestedRoles\n ? lastTurn.suggestedRoles\n : null,\n };\n}\n"]}
1
+ {"version":3,"file":"negotiation.summarizer.js","sourceRoot":"/","sources":["negotiation/negotiation.summarizer.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * NegotiationSummarizer — pure LLM pass that compresses one DiscoveryNegotiation\n * (potentially several KB of turn reasoning + outcome reasoning) into a\n * DiscoveryNegotiationDigest (≤256 bytes structured). The digest is what the decision-\n * question generator consumes, replacing the raw negotiation blob.\n *\n * Why: a 10-candidate discovery turn used to produce a 60+ KB prompt for the\n * question generator, which stalled upstream Gemini/OpenRouter routes and\n * dropped the connection at ~3 minutes. Per-negotiation summarization caps\n * the question-generator input at a fixed, predictable size.\n */\nimport type { ChatOpenAI } from \"@langchain/openai\";\nimport { HumanMessage, SystemMessage } from \"@langchain/core/messages\";\n\nimport { createModel } from \"../shared/agent/model.config.js\";\nimport { invokeWithAbortSignal } from \"../shared/agent/model-signal.js\";\nimport { protocolLogger } from \"../shared/observability/protocol.logger.js\";\nimport { DiscoveryNegotiationDigestSchema, type DiscoveryNegotiationDigest } from \"../shared/schemas/negotiation-digest.schema.js\";\nimport type { DiscoveryNegotiation } from \"../opportunity/question.prompt.js\";\n\nconst logger = protocolLogger(\"NegotiationSummarizer\");\n\nconst SYSTEM_PROMPT = `You summarize one negotiation between a seeker's agent and a candidate's agent into a structured digest for downstream decision-question generation.\n\nOutput requirements (ALL fields — set optional fields to null when not applicable):\n- counterpartyHint: copy the input field verbatim, truncated to ≤120 chars.\n- indexContext: copy the input field verbatim, truncated to ≤120 chars.\n- outcomeRole: \"opportunity\" when hasOpportunity=true, else \"no-opportunity\".\n- outcomeReason: when outcomeRole=\"no-opportunity\", set to \"turn_cap\" / \"timeout\" if the input's reason matches; else \"rejected\" (if a turn explicitly rejected) or \"stalled\". When outcomeRole=\"opportunity\", set to null.\n- keyTake: ONE sentence (≤180 chars). Describe the decisive moment, the alignment gap, or the recurring signal — anything a question generator could use to formulate a clarifying question. NOT a generic outcome restatement. Anchor in a concrete detail from the negotiation if possible (a role mismatch, a missing input the candidate flagged, a pivot one party suggested).\n- suggestedRoles: when both parties agreed on roles (the last turn's suggestedRoles), copy them from input. Otherwise set to null.\n\nDo not include candidate identity, PII, names, or IDs. Reuse only counterpartyHint and indexContext as provided.`;\n\nfunction buildUserPrompt(n: DiscoveryNegotiation): string {\n const turnLines = n.turns\n .map(\n (t, i) =>\n `[${i + 1}] action=${t.action} roles=${t.suggestedRoles.ownUser}↔${t.suggestedRoles.otherUser} reasoning=${t.reasoning}`,\n )\n .join(\"\\n\");\n return [\n `counterpartyHint: ${n.counterpartyHint}`,\n `indexContext: ${n.indexContext}`,\n `turns (${n.turns.length}):`,\n turnLines || \"(no turns)\",\n `outcome.hasOpportunity: ${n.outcome.hasOpportunity}`,\n `outcome.reasoning: ${n.outcome.reasoning}`,\n n.outcome.reason ? `outcome.reason: ${n.outcome.reason}` : \"\",\n ]\n .filter(Boolean)\n .join(\"\\n\");\n}\n\nexport class NegotiationSummarizer {\n private model: ReturnType<ChatOpenAI[\"withStructuredOutput\"]>;\n\n constructor() {\n const llm = createModel(\"negotiationSummarizer\");\n this.model = llm.withStructuredOutput(DiscoveryNegotiationDigestSchema, {\n name: \"negotiation_digest\",\n });\n }\n\n async summarize(\n negotiation: DiscoveryNegotiation,\n options?: { signal?: AbortSignal },\n ): Promise<DiscoveryNegotiationDigest | null> {\n const user = buildUserPrompt(negotiation);\n let raw: unknown;\n try {\n raw = await invokeWithAbortSignal(\n this.model,\n [new SystemMessage(SYSTEM_PROMPT), new HumanMessage(user)],\n options?.signal,\n );\n } catch (err) {\n const aborted = options?.signal?.aborted ?? false;\n if (aborted) {\n logger.info(\"NegotiationSummarizer aborted by signal\", {\n reason: options?.signal?.reason instanceof Error ? options.signal.reason.message : String(options?.signal?.reason ?? \"unknown\"),\n });\n } else {\n logger.warn(\"NegotiationSummarizer LLM call failed\", {\n error: err instanceof Error ? err.message : String(err),\n });\n }\n return null;\n }\n\n const parsed = DiscoveryNegotiationDigestSchema.safeParse(raw);\n if (!parsed.success) {\n logger.warn(\"NegotiationSummarizer parse failed\", { error: parsed.error.message });\n return null;\n }\n return parsed.data;\n }\n}\n\n/**\n * Deterministic fallback when the LLM summarizer fails or isn't wired. Produces\n * a minimal but valid digest so the question generator still has *some* signal.\n */\nexport function buildFallbackDigest(n: DiscoveryNegotiation): DiscoveryNegotiationDigest {\n const outcomeRole = n.outcome.hasOpportunity ? \"opportunity\" : \"no-opportunity\";\n const lastTurn = n.turns[n.turns.length - 1];\n const keyTakeRaw =\n n.outcome.reasoning && n.outcome.reasoning.trim().length > 0\n ? n.outcome.reasoning\n : `${n.turns.length} turn(s); ended ${outcomeRole}`;\n return {\n counterpartyHint: n.counterpartyHint.slice(0, 120),\n indexContext: n.indexContext.slice(0, 120),\n outcomeRole,\n outcomeReason:\n outcomeRole === \"no-opportunity\"\n ? ((n.outcome.reason ?? \"stalled\") as \"turn_cap\" | \"timeout\" | \"stalled\")\n : null,\n keyTake: keyTakeRaw.slice(0, 180),\n suggestedRoles:\n lastTurn?.action === \"accept\" && lastTurn.suggestedRoles\n ? lastTurn.suggestedRoles\n : null,\n };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"indexer.graph.d.ts","sourceRoot":"/","sources":["network/indexer/indexer.graph.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAI/D,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,+CAA+C,CAAC;AAIhG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAGzE,OAAO,EAEL,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,KAAK,gBAAgB,EACtB,MAAM,oBAAoB,CAAC;AAI5B;;;;;;;;;GASG;AACH,qBAAa,yBAAyB;IAElC,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,eAAe;gBADf,QAAQ,EAAE,0BAA0B,EACpC,eAAe,EAAE,aAAa;IAGjC,WAAW;;;;;;;;;;;;;;;;;;;;;2BAgDR,CAAC;4BAA4B,CAAC;sBAC5B,CAAX;wBAAyB,CAAA;yBACb,CAAC;8BACF,CAAR;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2BAHM,CAAC;4BAA4B,CAAC;sBAC5B,CAAX;wBAAyB,CAAA;yBACb,CAAC;8BACF,CAAR;;;;;;;;;2BAHM,CAAC;4BAA4B,CAAC;sBAC5B,CAAX;wBAAyB,CAAA;yBACb,CAAC;8BACF,CAAR;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2BAHM,CAAC;4BAA4B,CAAC;sBAC5B,CAAX;wBAAyB,CAAA;yBACb,CAAC;8BACF,CAAR;;;;;;;;;2BAHM,CAAC;4BAA4B,CAAC;sBAC5B,CAAX;wBAAyB,CAAA;yBACb,CAAC;8BACF,CAAR;;;;;;;;;2BAHM,CAAC;4BAA4B,CAAC;sBAC5B,CAAX;wBAAyB,CAAA;yBACb,CAAC;8BACF,CAAR;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2BAHM,CAAC;4BAA4B,CAAC;sBAC5B,CAAX;wBAAyB,CAAA;yBACb,CAAC;8BACF,CAAR;;;;;;;;;2BAHM,CAAC;4BAA4B,CAAC;sBAC5B,CAAX;wBAAyB,CAAA;yBACb,CAAC;8BACF,CAAR;;;;;;;;;2BAHM,CAAC;4BAA4B,CAAC;sBAC5B,CAAX;wBAAyB,CAAA;yBACb,CAAC;8BACF,CAAR;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8BAQ0E,gBAAgB;;;;;;;;;;;8BAed,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8BA0FlB,gBAAgB;;;;;;;;;;;;;;;8BAUjB,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqM9F"}
1
+ {"version":3,"file":"indexer.graph.d.ts","sourceRoot":"/","sources":["network/indexer/indexer.graph.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAE/D,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,+CAA+C,CAAC;AAIhG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAGzE,OAAO,EAA2B,KAAK,iBAAiB,EAAE,KAAK,kBAAkB,EAAE,KAAK,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAIrI;;;;;;;;;GASG;AACH,qBAAa,yBAAyB;IAElC,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,eAAe;gBADf,QAAQ,EAAE,0BAA0B,EACpC,eAAe,EAAE,aAAa;IAGjC,WAAW;;;;;;;;;;;;;;;;;;;;;2BAgDI,CAAC;4BAA4B,CAAC;sBACxC,CAAC;wBACD,CAAZ;yBAAyB,CAAC;8BACX,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2BAHM,CAAC;4BAA4B,CAAC;sBACxC,CAAC;wBACD,CAAZ;yBAAyB,CAAC;8BACX,CAAC;;;;;;;;;2BAHM,CAAC;4BAA4B,CAAC;sBACxC,CAAC;wBACD,CAAZ;yBAAyB,CAAC;8BACX,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2BAHM,CAAC;4BAA4B,CAAC;sBACxC,CAAC;wBACD,CAAZ;yBAAyB,CAAC;8BACX,CAAC;;;;;;;;;2BAHM,CAAC;4BAA4B,CAAC;sBACxC,CAAC;wBACD,CAAZ;yBAAyB,CAAC;8BACX,CAAC;;;;;;;;;2BAHM,CAAC;4BAA4B,CAAC;sBACxC,CAAC;wBACD,CAAZ;yBAAyB,CAAC;8BACX,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2BAHM,CAAC;4BAA4B,CAAC;sBACxC,CAAC;wBACD,CAAZ;yBAAyB,CAAC;8BACX,CAAC;;;;;;;;;2BAHM,CAAC;4BAA4B,CAAC;sBACxC,CAAC;wBACD,CAAZ;yBAAyB,CAAC;8BACX,CAAC;;;;;;;;;2BAHM,CAAC;4BAA4B,CAAC;sBACxC,CAAC;wBACD,CAAZ;yBAAyB,CAAC;8BACX,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8BAQ8D,gBAAgB;;;;;;;;;;;8BAed,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8BA0FlB,gBAAgB;;;;;;;;;;;;;;;8BAUjB,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqM9F"}
@@ -1,10 +1,10 @@
1
1
  import { StateGraph, START, END } from "@langchain/langgraph";
2
- import { buildNetworkAssignmentDecision, } from "../../shared/assignment/network-assignment.policy.js";
2
+ import { buildNetworkAssignmentDecision } from "../../shared/assignment/network-assignment.policy.js";
3
3
  import { protocolLogger } from "../../shared/observability/protocol.logger.js";
4
4
  import { timed } from "../../shared/observability/performance.js";
5
5
  import { requestContext } from "../../shared/observability/request-context.js";
6
6
  import { renderNetworkContext } from "../../shared/network/metadata.renderer.js";
7
- import { IntentNetworkGraphState, } from "./indexer.state.js";
7
+ import { IntentNetworkGraphState } from "./indexer.state.js";
8
8
  const logger = protocolLogger("IntentNetworkGraphFactory");
9
9
  /**
10
10
  * Factory class to build and compile the Intent Index Graph.
@@ -1 +1 @@
1
- {"version":3,"file":"indexer.graph.js","sourceRoot":"/","sources":["network/indexer/indexer.graph.ts"],"names":[],"mappings":"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","sourcesContent":["import { StateGraph, START, END } from \"@langchain/langgraph\";\n\nimport { IntentIndexer } from \"../../intent/intent.indexer.js\";\nimport {\n buildNetworkAssignmentDecision,\n} from \"../../shared/assignment/network-assignment.policy.js\";\nimport type { IntentNetworkGraphDatabase } from \"../../shared/interfaces/database.interface.js\";\nimport { protocolLogger } from \"../../shared/observability/protocol.logger.js\";\nimport { timed } from \"../../shared/observability/performance.js\";\nimport { requestContext } from \"../../shared/observability/request-context.js\";\nimport type { DebugMetaAgent } from \"../../chat/chat-streaming.types.js\";\nimport { renderNetworkContext } from \"../../shared/network/metadata.renderer.js\";\n\nimport {\n IntentNetworkGraphState,\n type IntentForIndexing,\n type IndexMemberContext,\n type AssignmentResult,\n} from \"./indexer.state.js\";\n\nconst logger = protocolLogger(\"IntentNetworkGraphFactory\");\n\n/**\n * Factory class to build and compile the Intent Index Graph.\n *\n * Handles CRUD for the intent_indexes junction table:\n * - create: Assign an intent to an index (direct or evaluated via IntentIndexer agent)\n * - read: List intent-index links (by intentId or by networkId)\n * - delete: Unassign an intent from an index\n *\n * The evaluate-based assignment flow is migrated from the old Index Graph.\n */\nexport class IntentNetworkGraphFactory {\n constructor(\n private database: IntentNetworkGraphDatabase,\n private intentNetworker: IntentIndexer,\n ) {}\n\n public createGraph() {\n const indexer = this.intentNetworker;\n\n // --- NODE DEFINITIONS ---\n\n /**\n * Assign Node: Assign an intent to an index.\n * Two sub-paths:\n * - Direct assignment (skipEvaluation=true): assign immediately\n * - Evaluated assignment (skipEvaluation=false): load intent + index context, evaluate via IntentIndexer\n */\n const assignNode = async (state: typeof IntentNetworkGraphState.State) => {\n return timed(\"IntentNetworkGraph.assign\", async () => {\n const intentId = state.intentId;\n const networkId = state.networkId;\n logger.verbose(\"Assign intent to index\", { userId: state.userId, intentId, networkId, skipEvaluation: state.skipEvaluation });\n\n const agentTimingsAccum: DebugMetaAgent[] = [];\n\n if (!intentId || !networkId) {\n return { agentTimings: agentTimingsAccum, mutationResult: { success: false, error: \"Both intentId and networkId are required.\" } };\n }\n\n try {\n // Validate ownership and membership\n const intent = await this.database.getIntent(intentId);\n if (!intent) {\n return { agentTimings: agentTimingsAccum, mutationResult: { success: false, error: \"Intent not found.\" } };\n }\n if (intent.userId !== state.userId) {\n return { agentTimings: agentTimingsAccum, mutationResult: { success: false, error: \"You can only add your own intents to a network.\" } };\n }\n const [isMember, isOwner] = await Promise.all([\n this.database.isNetworkMember(networkId, state.userId),\n this.database.isIndexOwner(networkId, state.userId),\n ]);\n if (!isMember && !isOwner) {\n return { agentTimings: agentTimingsAccum, mutationResult: { success: false, error: \"You are not a member of that network.\" } };\n }\n\n // Check if already assigned\n const alreadyAssigned = await this.database.isIntentAssignedToIndex(intentId, networkId);\n if (alreadyAssigned) {\n return { agentTimings: agentTimingsAccum, mutationResult: { success: true, message: \"That intent is already in this network.\" } };\n }\n\n // Direct assignment (skip evaluation)\n if (state.skipEvaluation) {\n const decision = buildNetworkAssignmentDecision({\n resourceType: \"intent\",\n mode: \"manual_override\",\n scope: \"network\",\n evaluator: \"intent-network-graph\",\n source: \"manual-index-assignment\",\n createdAt: new Date().toISOString(),\n });\n await this.database.assignIntentToNetwork(intentId, networkId, decision.finalScore, decision.metadata);\n return {\n agentTimings: agentTimingsAccum,\n assignmentResult: { networkId, assigned: true, success: true } as AssignmentResult,\n mutationResult: { success: true, message: \"Intent saved to the network.\" },\n };\n }\n\n // Evaluated assignment (migrated from old Index Graph)\n const intentForIndexing = await this.database.getIntentForIndexing(intentId);\n if (!intentForIndexing) {\n return { agentTimings: agentTimingsAccum, mutationResult: { success: false, error: \"Intent not found for networking.\" } };\n }\n\n const indexContext = await this.database.getNetworkAssignmentContext(networkId, intentForIndexing.userId);\n if (!indexContext) {\n return {\n agentTimings: agentTimingsAccum,\n assignmentResult: { networkId, assigned: false, success: false } as AssignmentResult,\n mutationResult: { success: false, error: \"Network assignment context not found.\" },\n };\n }\n const indexPrompt = indexContext.indexPrompt ?? null;\n const memberPrompt = indexContext.memberPrompt ?? null;\n const hasNoPrompts = !indexPrompt?.trim() && !memberPrompt?.trim();\n if (hasNoPrompts) {\n const decision = buildNetworkAssignmentDecision({\n resourceType: \"intent\",\n mode: \"automatic\",\n scope: \"network\",\n indexPrompt,\n memberPrompt,\n evaluator: \"intent-indexer\",\n source: \"intent-network-graph\",\n createdAt: new Date().toISOString(),\n });\n await this.database.assignIntentToNetwork(intentId, networkId, decision.finalScore, decision.metadata);\n return {\n agentTimings: agentTimingsAccum,\n assignmentResult: { networkId, assigned: true, success: true } as AssignmentResult,\n mutationResult: { success: true, message: \"Intent assigned to network (no prompts).\" },\n };\n }\n\n // Run IntentIndexer evaluation\n const sourceName = intentForIndexing.sourceType\n ? `${intentForIndexing.sourceType}:${intentForIndexing.sourceId ?? \"\"}`\n : undefined;\n\n // Render network context (type, metadata) for the evaluator\n const network = await this.database.getNetwork(networkId);\n const renderedContext = network\n ? renderNetworkContext({\n type: network.type ?? 'community',\n title: network.title,\n prompt: network.prompt,\n metadata: network.metadata ?? {},\n })\n : null;\n\n const _traceEmitterIndexer = requestContext.getStore()?.traceEmitter;\n const _indexerStart = Date.now();\n _traceEmitterIndexer?.({ type: \"agent_start\", name: \"intent-indexer\" });\n let result: Awaited<ReturnType<typeof indexer.evaluate>> | null = null;\n try {\n result = await indexer.evaluate(\n intentForIndexing.payload,\n indexPrompt,\n memberPrompt,\n sourceName,\n renderedContext\n );\n } finally {\n const _indexerMs = Date.now() - _indexerStart;\n agentTimingsAccum.push({ name: 'intent.indexer', durationMs: _indexerMs });\n _traceEmitterIndexer?.({ type: \"agent_end\", name: \"intent-indexer\", durationMs: _indexerMs, summary: result ? `Scored: index=${result.indexScore.toFixed(2)}, member=${result.memberScore.toFixed(2)}` : \"intent-indexer failed\" });\n }\n\n if (!result) {\n return {\n agentTimings: agentTimingsAccum,\n evaluation: null,\n shouldAssign: false,\n finalScore: 0,\n mutationResult: { success: false, error: \"Evaluation returned no result.\" },\n };\n }\n\n const decision = buildNetworkAssignmentDecision({\n resourceType: \"intent\",\n mode: \"automatic\",\n scope: \"network\",\n indexPrompt,\n memberPrompt,\n rawScores: { indexScore: result.indexScore, memberScore: result.memberScore },\n evaluator: \"intent-indexer\",\n source: \"intent-network-graph\",\n reason: result.reasoning,\n createdAt: new Date().toISOString(),\n });\n\n if (decision.assigned) {\n await this.database.assignIntentToNetwork(intentId, networkId, decision.finalScore, decision.metadata);\n return {\n agentTimings: agentTimingsAccum,\n evaluation: result,\n shouldAssign: true,\n finalScore: decision.finalScore,\n assignmentResult: { networkId, assigned: true, success: true } as AssignmentResult,\n mutationResult: { success: true, message: `Intent assigned to network (score: ${decision.finalScore.toFixed(2)}).` },\n };\n }\n\n return {\n agentTimings: agentTimingsAccum,\n evaluation: result,\n shouldAssign: false,\n finalScore: decision.finalScore,\n assignmentResult: { networkId, assigned: false, success: true } as AssignmentResult,\n mutationResult: { success: false, error: `Intent did not qualify for this network (score: ${decision.finalScore.toFixed(2)}).` },\n };\n } catch (err) {\n logger.error(\"Assign failed\", { error: err });\n return { agentTimings: agentTimingsAccum, mutationResult: { success: false, error: \"Failed to assign intent to network.\" } };\n }\n });\n };\n\n /**\n * Read Node: Query intent-index relationships.\n * - By intentId only: list all indexes the intent is in (owner only)\n * - By networkId only: list intents in the index (member only)\n * - By both intentId and networkId: check if specific link exists (owner only)\n */\n const readNode = async (state: typeof IntentNetworkGraphState.State) => {\n return timed(\"IntentNetworkGraph.read\", async () => {\n const intentId = state.intentId;\n const networkId = state.networkId;\n logger.verbose(\"Read intent-index links\", { userId: state.userId, intentId, networkId, queryUserId: state.queryUserId });\n\n try {\n // By both: check if specific intent-index link exists\n if (intentId && networkId) {\n const intent = await this.database.getIntent(intentId);\n if (!intent) {\n return { readResult: { links: [], count: 0, mode: \"check_link\" }, error: \"Intent not found.\" };\n }\n if (intent.userId !== state.userId) {\n return { readResult: { links: [], count: 0, mode: \"check_link\" }, error: \"You can only check links for your own intents.\" };\n }\n const isLinked = await this.database.isIntentAssignedToIndex(intentId, networkId);\n return {\n readResult: {\n links: isLinked ? [{ intentId, networkId }] : [],\n count: isLinked ? 1 : 0,\n mode: \"check_link\",\n note: isLinked ? \"Intent is linked to this network.\" : \"Intent is not linked to this network.\",\n },\n };\n }\n\n // By intent only: list all indexes for this intent\n if (intentId) {\n const intent = await this.database.getIntent(intentId);\n if (!intent) {\n return { readResult: { links: [], count: 0, mode: \"networks_for_intent\" }, error: \"Intent not found.\" };\n }\n if (intent.userId !== state.userId) {\n return { readResult: { links: [], count: 0, mode: \"networks_for_intent\" }, error: \"You can only list networks for your own intents.\" };\n }\n const networkIds = await this.database.getNetworkIdsForIntent(intentId);\n return {\n readResult: {\n links: networkIds.map((id) => ({ intentId, networkId: id })),\n count: networkIds.length,\n mode: \"networks_for_intent\",\n note: \"To show network titles, use read_networks.\",\n },\n };\n }\n\n // By index: list intents in the index\n if (!networkId) {\n return {\n readResult: { links: [], count: 0, mode: \"unknown\" },\n error: \"Provide networkId or intentId.\",\n };\n }\n\n const [isMember, isOwner] = await Promise.all([\n this.database.isNetworkMember(networkId, state.userId),\n this.database.isIndexOwner(networkId, state.userId),\n ]);\n if (!isMember && !isOwner) {\n return {\n readResult: { links: [], count: 0, mode: \"intents_in_network\" },\n error: \"Network not found or you are not a member.\",\n };\n }\n\n // All intents or filtered by user\n if (!state.queryUserId) {\n const intents = await this.database.getNetworkIntentsForMember(networkId, state.userId, { limit: 50, offset: 0 });\n return {\n readResult: {\n links: intents.map((i) => ({\n intentId: i.id,\n networkId,\n intentTitle: i.payload,\n userId: i.userId,\n userName: i.userName,\n createdAt: i.createdAt,\n relevancyScore: i.relevancyScore,\n })),\n count: intents.length,\n mode: \"intents_in_network\",\n note: \"To show network title and full intent details, use read_networks and read_intents.\",\n },\n };\n }\n\n // Specific user's intents\n const intents = await this.database.getIntentsInIndexForMember(state.queryUserId, networkId);\n return {\n readResult: {\n links: intents.map((i) => ({\n intentId: i.id,\n networkId,\n intentTitle: i.payload,\n createdAt: i.createdAt,\n relevancyScore: i.relevancyScore,\n })),\n count: intents.length,\n mode: \"intents_in_network\",\n note: \"To show network title and full intent details, use read_networks and read_intents.\",\n },\n };\n } catch (err) {\n logger.error(\"Read intent-index failed\", { error: err });\n return { error: \"Failed to fetch intent-network links.\" };\n }\n });\n };\n\n /**\n * Unassign Node: Remove an intent from an index.\n */\n const unassignNode = async (state: typeof IntentNetworkGraphState.State) => {\n return timed(\"IntentNetworkGraph.unassign\", async () => {\n const intentId = state.intentId;\n const networkId = state.networkId;\n logger.verbose(\"Unassign intent from index\", { userId: state.userId, intentId, networkId });\n\n if (!intentId || !networkId) {\n return { mutationResult: { success: false, error: \"Both intentId and networkId are required.\" } };\n }\n\n try {\n const intent = await this.database.getIntent(intentId);\n if (!intent) {\n return { mutationResult: { success: false, error: \"Intent not found.\" } };\n }\n if (intent.userId !== state.userId) {\n return { mutationResult: { success: false, error: \"You can only remove your own intents from a network.\" } };\n }\n const [isMember, isOwner] = await Promise.all([\n this.database.isNetworkMember(networkId, state.userId),\n this.database.isIndexOwner(networkId, state.userId),\n ]);\n if (!isMember && !isOwner) {\n return { mutationResult: { success: false, error: \"You are not a member of that network.\" } };\n }\n\n const assigned = await this.database.isIntentAssignedToIndex(intentId, networkId);\n if (!assigned) {\n return { mutationResult: { success: true, message: \"That intent is not in this network.\" } };\n }\n\n await this.database.unassignIntentFromIndex(intentId, networkId);\n return { mutationResult: { success: true, message: \"Intent removed from the index.\" } };\n } catch (err) {\n logger.error(\"Unassign failed\", { error: err });\n return { mutationResult: { success: false, error: \"Failed to remove intent from network.\" } };\n }\n });\n };\n\n // --- CONDITIONAL ROUTING ---\n\n const routeByMode = (state: typeof IntentNetworkGraphState.State): string => {\n switch (state.operationMode) {\n case 'create': return 'assign';\n case 'read': return 'read';\n case 'delete': return 'unassign';\n default: return 'read';\n }\n };\n\n // --- GRAPH ASSEMBLY ---\n\n const workflow = new StateGraph(IntentNetworkGraphState)\n .addNode(\"assign\", assignNode)\n .addNode(\"read\", readNode)\n .addNode(\"unassign\", unassignNode)\n .addConditionalEdges(START, routeByMode, {\n assign: \"assign\",\n read: \"read\",\n unassign: \"unassign\",\n })\n .addEdge(\"assign\", END)\n .addEdge(\"read\", END)\n .addEdge(\"unassign\", END);\n\n return workflow.compile();\n }\n}\n"]}
1
+ {"version":3,"file":"indexer.graph.js","sourceRoot":"/","sources":["network/indexer/indexer.graph.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,sBAAsB,CAAC;AAG9D,OAAO,EAAE,8BAA8B,EAAE,MAAM,sDAAsD,CAAC;AAEtG,OAAO,EAAE,cAAc,EAAE,MAAM,+CAA+C,CAAC;AAC/E,OAAO,EAAE,KAAK,EAAE,MAAM,2CAA2C,CAAC;AAClE,OAAO,EAAE,cAAc,EAAE,MAAM,+CAA+C,CAAC;AAE/E,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AAEjF,OAAO,EAAE,uBAAuB,EAA0E,MAAM,oBAAoB,CAAC;AAErI,MAAM,MAAM,GAAG,cAAc,CAAC,2BAA2B,CAAC,CAAC;AAE3D;;;;;;;;;GASG;AACH,MAAM,OAAO,yBAAyB;IACpC,YACU,QAAoC,EACpC,eAA8B;QAD9B,aAAQ,GAAR,QAAQ,CAA4B;QACpC,oBAAe,GAAf,eAAe,CAAe;IACrC,CAAC;IAEG,WAAW;QAChB,MAAM,OAAO,GAAG,IAAI,CAAC,eAAe,CAAC;QAErC,2BAA2B;QAE3B;;;;;WAKG;QACH,MAAM,UAAU,GAAG,KAAK,EAAE,KAA2C,EAAE,EAAE;YACvE,OAAO,KAAK,CAAC,2BAA2B,EAAE,KAAK,IAAI,EAAE;gBACnD,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;gBAChC,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC;gBAClC,MAAM,CAAC,OAAO,CAAC,wBAAwB,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,cAAc,EAAE,KAAK,CAAC,cAAc,EAAE,CAAC,CAAC;gBAE9H,MAAM,iBAAiB,GAAqB,EAAE,CAAC;gBAE/C,IAAI,CAAC,QAAQ,IAAI,CAAC,SAAS,EAAE,CAAC;oBAC5B,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,cAAc,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,2CAA2C,EAAE,EAAE,CAAC;gBACrI,CAAC;gBAED,IAAI,CAAC;oBACH,oCAAoC;oBACpC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;oBACvD,IAAI,CAAC,MAAM,EAAE,CAAC;wBACZ,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,cAAc,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,mBAAmB,EAAE,EAAE,CAAC;oBAC7G,CAAC;oBACD,IAAI,MAAM,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,EAAE,CAAC;wBACnC,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,cAAc,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,iDAAiD,EAAE,EAAE,CAAC;oBAC3I,CAAC;oBACD,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;wBAC5C,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,SAAS,EAAE,KAAK,CAAC,MAAM,CAAC;wBACtD,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,SAAS,EAAE,KAAK,CAAC,MAAM,CAAC;qBACpD,CAAC,CAAC;oBACH,IAAI,CAAC,QAAQ,IAAI,CAAC,OAAO,EAAE,CAAC;wBAC1B,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,cAAc,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,uCAAuC,EAAE,EAAE,CAAC;oBACjI,CAAC;oBAED,4BAA4B;oBAC5B,MAAM,eAAe,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,uBAAuB,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;oBACzF,IAAI,eAAe,EAAE,CAAC;wBACpB,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,cAAc,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,yCAAyC,EAAE,EAAE,CAAC;oBACpI,CAAC;oBAED,sCAAsC;oBACtC,IAAI,KAAK,CAAC,cAAc,EAAE,CAAC;wBACzB,MAAM,QAAQ,GAAG,8BAA8B,CAAC;4BAC9C,YAAY,EAAE,QAAQ;4BACtB,IAAI,EAAE,iBAAiB;4BACvB,KAAK,EAAE,SAAS;4BAChB,SAAS,EAAE,sBAAsB;4BACjC,MAAM,EAAE,yBAAyB;4BACjC,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;yBACpC,CAAC,CAAC;wBACH,MAAM,IAAI,CAAC,QAAQ,CAAC,qBAAqB,CAAC,QAAQ,EAAE,SAAS,EAAE,QAAQ,CAAC,UAAU,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC;wBACvG,OAAO;4BACL,YAAY,EAAE,iBAAiB;4BAC/B,gBAAgB,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAsB;4BAClF,cAAc,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,8BAA8B,EAAE;yBAC3E,CAAC;oBACJ,CAAC;oBAED,uDAAuD;oBACvD,MAAM,iBAAiB,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,oBAAoB,CAAC,QAAQ,CAAC,CAAC;oBAC7E,IAAI,CAAC,iBAAiB,EAAE,CAAC;wBACvB,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,cAAc,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,kCAAkC,EAAE,EAAE,CAAC;oBAC5H,CAAC;oBAED,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,2BAA2B,CAAC,SAAS,EAAE,iBAAiB,CAAC,MAAM,CAAC,CAAC;oBAC1G,IAAI,CAAC,YAAY,EAAE,CAAC;wBAClB,OAAO;4BACL,YAAY,EAAE,iBAAiB;4BAC/B,gBAAgB,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAsB;4BACpF,cAAc,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,uCAAuC,EAAE;yBACnF,CAAC;oBACJ,CAAC;oBACD,MAAM,WAAW,GAAG,YAAY,CAAC,WAAW,IAAI,IAAI,CAAC;oBACrD,MAAM,YAAY,GAAG,YAAY,CAAC,YAAY,IAAI,IAAI,CAAC;oBACvD,MAAM,YAAY,GAAG,CAAC,WAAW,EAAE,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE,IAAI,EAAE,CAAC;oBACnE,IAAI,YAAY,EAAE,CAAC;wBACjB,MAAM,QAAQ,GAAG,8BAA8B,CAAC;4BAC9C,YAAY,EAAE,QAAQ;4BACtB,IAAI,EAAE,WAAW;4BACjB,KAAK,EAAE,SAAS;4BAChB,WAAW;4BACX,YAAY;4BACZ,SAAS,EAAE,gBAAgB;4BAC3B,MAAM,EAAE,sBAAsB;4BAC9B,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;yBACpC,CAAC,CAAC;wBACH,MAAM,IAAI,CAAC,QAAQ,CAAC,qBAAqB,CAAC,QAAQ,EAAE,SAAS,EAAE,QAAQ,CAAC,UAAU,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC;wBACvG,OAAO;4BACL,YAAY,EAAE,iBAAiB;4BAC/B,gBAAgB,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAsB;4BAClF,cAAc,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,0CAA0C,EAAE;yBACvF,CAAC;oBACJ,CAAC;oBAED,+BAA+B;oBAC/B,MAAM,UAAU,GAAG,iBAAiB,CAAC,UAAU;wBAC7C,CAAC,CAAC,GAAG,iBAAiB,CAAC,UAAU,IAAI,iBAAiB,CAAC,QAAQ,IAAI,EAAE,EAAE;wBACvE,CAAC,CAAC,SAAS,CAAC;oBAEd,4DAA4D;oBAC5D,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;oBAC1D,MAAM,eAAe,GAAG,OAAO;wBAC7B,CAAC,CAAC,oBAAoB,CAAC;4BACnB,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,WAAW;4BACjC,KAAK,EAAE,OAAO,CAAC,KAAK;4BACpB,MAAM,EAAE,OAAO,CAAC,MAAM;4BACtB,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,EAAE;yBACjC,CAAC;wBACJ,CAAC,CAAC,IAAI,CAAC;oBAET,MAAM,oBAAoB,GAAG,cAAc,CAAC,QAAQ,EAAE,EAAE,YAAY,CAAC;oBACrE,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;oBACjC,oBAAoB,EAAE,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,gBAAgB,EAAE,CAAC,CAAC;oBACxE,IAAI,MAAM,GAAwD,IAAI,CAAC;oBACvE,IAAI,CAAC;wBACH,MAAM,GAAG,MAAM,OAAO,CAAC,QAAQ,CAC7B,iBAAiB,CAAC,OAAO,EACzB,WAAW,EACX,YAAY,EACZ,UAAU,EACV,eAAe,CAChB,CAAC;oBACJ,CAAC;4BAAS,CAAC;wBACT,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,aAAa,CAAC;wBAC9C,iBAAiB,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC,CAAC;wBAC3E,oBAAoB,EAAE,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,gBAAgB,EAAE,UAAU,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,iBAAiB,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,YAAY,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,uBAAuB,EAAE,CAAC,CAAC;oBACtO,CAAC;oBAED,IAAI,CAAC,MAAM,EAAE,CAAC;wBACZ,OAAO;4BACL,YAAY,EAAE,iBAAiB;4BAC/B,UAAU,EAAE,IAAI;4BAChB,YAAY,EAAE,KAAK;4BACnB,UAAU,EAAE,CAAC;4BACb,cAAc,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,gCAAgC,EAAE;yBAC5E,CAAC;oBACJ,CAAC;oBAED,MAAM,QAAQ,GAAG,8BAA8B,CAAC;wBAC9C,YAAY,EAAE,QAAQ;wBACtB,IAAI,EAAE,WAAW;wBACjB,KAAK,EAAE,SAAS;wBAChB,WAAW;wBACX,YAAY;wBACZ,SAAS,EAAE,EAAE,UAAU,EAAE,MAAM,CAAC,UAAU,EAAE,WAAW,EAAE,MAAM,CAAC,WAAW,EAAE;wBAC7E,SAAS,EAAE,gBAAgB;wBAC3B,MAAM,EAAE,sBAAsB;wBAC9B,MAAM,EAAE,MAAM,CAAC,SAAS;wBACxB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;qBACpC,CAAC,CAAC;oBAEH,IAAI,QAAQ,CAAC,QAAQ,EAAE,CAAC;wBACtB,MAAM,IAAI,CAAC,QAAQ,CAAC,qBAAqB,CAAC,QAAQ,EAAE,SAAS,EAAE,QAAQ,CAAC,UAAU,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC;wBACvG,OAAO;4BACL,YAAY,EAAE,iBAAiB;4BAC/B,UAAU,EAAE,MAAM;4BAClB,YAAY,EAAE,IAAI;4BAClB,UAAU,EAAE,QAAQ,CAAC,UAAU;4BAC/B,gBAAgB,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAsB;4BAClF,cAAc,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,sCAAsC,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE;yBACrH,CAAC;oBACJ,CAAC;oBAED,OAAO;wBACL,YAAY,EAAE,iBAAiB;wBAC/B,UAAU,EAAE,MAAM;wBAClB,YAAY,EAAE,KAAK;wBACnB,UAAU,EAAE,QAAQ,CAAC,UAAU;wBAC/B,gBAAgB,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAsB;wBACnF,cAAc,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,mDAAmD,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE;qBACjI,CAAC;gBACJ,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,MAAM,CAAC,KAAK,CAAC,eAAe,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;oBAC9C,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,cAAc,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,qCAAqC,EAAE,EAAE,CAAC;gBAC/H,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC,CAAC;QAEF;;;;;WAKG;QACH,MAAM,QAAQ,GAAG,KAAK,EAAE,KAA2C,EAAE,EAAE;YACrE,OAAO,KAAK,CAAC,yBAAyB,EAAE,KAAK,IAAI,EAAE;gBACjD,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;gBAChC,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC;gBAClC,MAAM,CAAC,OAAO,CAAC,yBAAyB,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;gBAEzH,IAAI,CAAC;oBACH,sDAAsD;oBACtD,IAAI,QAAQ,IAAI,SAAS,EAAE,CAAC;wBAC1B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;wBACvD,IAAI,CAAC,MAAM,EAAE,CAAC;4BACZ,OAAO,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAC;wBACjG,CAAC;wBACD,IAAI,MAAM,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,EAAE,CAAC;4BACnC,OAAO,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,KAAK,EAAE,gDAAgD,EAAE,CAAC;wBAC9H,CAAC;wBACD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,uBAAuB,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;wBAClF,OAAO;4BACL,UAAU,EAAE;gCACV,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE;gCAChD,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gCACvB,IAAI,EAAE,YAAY;gCAClB,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,mCAAmC,CAAC,CAAC,CAAC,uCAAuC;6BAC/F;yBACF,CAAC;oBACJ,CAAC;oBAED,mDAAmD;oBACnD,IAAI,QAAQ,EAAE,CAAC;wBACb,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;wBACvD,IAAI,CAAC,MAAM,EAAE,CAAC;4BACZ,OAAO,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,qBAAqB,EAAE,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAC;wBAC1G,CAAC;wBACD,IAAI,MAAM,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,EAAE,CAAC;4BACnC,OAAO,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,qBAAqB,EAAE,EAAE,KAAK,EAAE,kDAAkD,EAAE,CAAC;wBACzI,CAAC;wBACD,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,sBAAsB,CAAC,QAAQ,CAAC,CAAC;wBACxE,OAAO;4BACL,UAAU,EAAE;gCACV,KAAK,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,CAAC;gCAC5D,KAAK,EAAE,UAAU,CAAC,MAAM;gCACxB,IAAI,EAAE,qBAAqB;gCAC3B,IAAI,EAAE,4CAA4C;6BACnD;yBACF,CAAC;oBACJ,CAAC;oBAED,sCAAsC;oBACtC,IAAI,CAAC,SAAS,EAAE,CAAC;wBACf,OAAO;4BACL,UAAU,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE;4BACpD,KAAK,EAAE,gCAAgC;yBACxC,CAAC;oBACJ,CAAC;oBAED,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;wBAC5C,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,SAAS,EAAE,KAAK,CAAC,MAAM,CAAC;wBACtD,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,SAAS,EAAE,KAAK,CAAC,MAAM,CAAC;qBACpD,CAAC,CAAC;oBACH,IAAI,CAAC,QAAQ,IAAI,CAAC,OAAO,EAAE,CAAC;wBAC1B,OAAO;4BACL,UAAU,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,oBAAoB,EAAE;4BAC/D,KAAK,EAAE,4CAA4C;yBACpD,CAAC;oBACJ,CAAC;oBAED,kCAAkC;oBAClC,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;wBACvB,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,0BAA0B,CAAC,SAAS,EAAE,KAAK,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;wBAClH,OAAO;4BACL,UAAU,EAAE;gCACV,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;oCACzB,QAAQ,EAAE,CAAC,CAAC,EAAE;oCACd,SAAS;oCACT,WAAW,EAAE,CAAC,CAAC,OAAO;oCACtB,MAAM,EAAE,CAAC,CAAC,MAAM;oCAChB,QAAQ,EAAE,CAAC,CAAC,QAAQ;oCACpB,SAAS,EAAE,CAAC,CAAC,SAAS;oCACtB,cAAc,EAAE,CAAC,CAAC,cAAc;iCACjC,CAAC,CAAC;gCACH,KAAK,EAAE,OAAO,CAAC,MAAM;gCACrB,IAAI,EAAE,oBAAoB;gCAC1B,IAAI,EAAE,oFAAoF;6BAC3F;yBACF,CAAC;oBACJ,CAAC;oBAED,0BAA0B;oBAC1B,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,0BAA0B,CAAC,KAAK,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;oBAC7F,OAAO;wBACL,UAAU,EAAE;4BACV,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gCACzB,QAAQ,EAAE,CAAC,CAAC,EAAE;gCACd,SAAS;gCACT,WAAW,EAAE,CAAC,CAAC,OAAO;gCACtB,SAAS,EAAE,CAAC,CAAC,SAAS;gCACtB,cAAc,EAAE,CAAC,CAAC,cAAc;6BACjC,CAAC,CAAC;4BACH,KAAK,EAAE,OAAO,CAAC,MAAM;4BACrB,IAAI,EAAE,oBAAoB;4BAC1B,IAAI,EAAE,oFAAoF;yBAC3F;qBACF,CAAC;gBACJ,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,MAAM,CAAC,KAAK,CAAC,0BAA0B,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;oBACzD,OAAO,EAAE,KAAK,EAAE,uCAAuC,EAAE,CAAC;gBAC5D,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC,CAAC;QAEF;;WAEG;QACH,MAAM,YAAY,GAAG,KAAK,EAAE,KAA2C,EAAE,EAAE;YACzE,OAAO,KAAK,CAAC,6BAA6B,EAAE,KAAK,IAAI,EAAE;gBACrD,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;gBAChC,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC;gBAClC,MAAM,CAAC,OAAO,CAAC,4BAA4B,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,CAAC;gBAE5F,IAAI,CAAC,QAAQ,IAAI,CAAC,SAAS,EAAE,CAAC;oBAC5B,OAAO,EAAE,cAAc,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,2CAA2C,EAAE,EAAE,CAAC;gBACpG,CAAC;gBAED,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;oBACvD,IAAI,CAAC,MAAM,EAAE,CAAC;wBACZ,OAAO,EAAE,cAAc,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,mBAAmB,EAAE,EAAE,CAAC;oBAC5E,CAAC;oBACD,IAAI,MAAM,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,EAAE,CAAC;wBACnC,OAAO,EAAE,cAAc,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,sDAAsD,EAAE,EAAE,CAAC;oBAC/G,CAAC;oBACD,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;wBAC5C,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,SAAS,EAAE,KAAK,CAAC,MAAM,CAAC;wBACtD,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,SAAS,EAAE,KAAK,CAAC,MAAM,CAAC;qBACpD,CAAC,CAAC;oBACH,IAAI,CAAC,QAAQ,IAAI,CAAC,OAAO,EAAE,CAAC;wBAC1B,OAAO,EAAE,cAAc,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,uCAAuC,EAAE,EAAE,CAAC;oBAChG,CAAC;oBAED,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,uBAAuB,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;oBAClF,IAAI,CAAC,QAAQ,EAAE,CAAC;wBACd,OAAO,EAAE,cAAc,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,qCAAqC,EAAE,EAAE,CAAC;oBAC/F,CAAC;oBAED,MAAM,IAAI,CAAC,QAAQ,CAAC,uBAAuB,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;oBACjE,OAAO,EAAE,cAAc,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,gCAAgC,EAAE,EAAE,CAAC;gBAC1F,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,MAAM,CAAC,KAAK,CAAC,iBAAiB,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;oBAChD,OAAO,EAAE,cAAc,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,uCAAuC,EAAE,EAAE,CAAC;gBAChG,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC,CAAC;QAEF,8BAA8B;QAE9B,MAAM,WAAW,GAAG,CAAC,KAA2C,EAAU,EAAE;YAC1E,QAAQ,KAAK,CAAC,aAAa,EAAE,CAAC;gBAC5B,KAAK,QAAQ,CAAC,CAAC,OAAO,QAAQ,CAAC;gBAC/B,KAAK,MAAM,CAAC,CAAC,OAAO,MAAM,CAAC;gBAC3B,KAAK,QAAQ,CAAC,CAAC,OAAO,UAAU,CAAC;gBACjC,OAAO,CAAC,CAAC,OAAO,MAAM,CAAC;YACzB,CAAC;QACH,CAAC,CAAC;QAEF,yBAAyB;QAEzB,MAAM,QAAQ,GAAG,IAAI,UAAU,CAAC,uBAAuB,CAAC;aACrD,OAAO,CAAC,QAAQ,EAAE,UAAU,CAAC;aAC7B,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC;aACzB,OAAO,CAAC,UAAU,EAAE,YAAY,CAAC;aACjC,mBAAmB,CAAC,KAAK,EAAE,WAAW,EAAE;YACvC,MAAM,EAAE,QAAQ;YAChB,IAAI,EAAE,MAAM;YACZ,QAAQ,EAAE,UAAU;SACrB,CAAC;aACD,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC;aACtB,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;aACpB,OAAO,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;QAE5B,OAAO,QAAQ,CAAC,OAAO,EAAE,CAAC;IAC5B,CAAC;CACF","sourcesContent":["import { StateGraph, START, END } from \"@langchain/langgraph\";\n\nimport { IntentIndexer } from \"../../intent/intent.indexer.js\";\nimport { buildNetworkAssignmentDecision } from \"../../shared/assignment/network-assignment.policy.js\";\nimport type { IntentNetworkGraphDatabase } from \"../../shared/interfaces/database.interface.js\";\nimport { protocolLogger } from \"../../shared/observability/protocol.logger.js\";\nimport { timed } from \"../../shared/observability/performance.js\";\nimport { requestContext } from \"../../shared/observability/request-context.js\";\nimport type { DebugMetaAgent } from \"../../chat/chat-streaming.types.js\";\nimport { renderNetworkContext } from \"../../shared/network/metadata.renderer.js\";\n\nimport { IntentNetworkGraphState, type IntentForIndexing, type IndexMemberContext, type AssignmentResult } from \"./indexer.state.js\";\n\nconst logger = protocolLogger(\"IntentNetworkGraphFactory\");\n\n/**\n * Factory class to build and compile the Intent Index Graph.\n *\n * Handles CRUD for the intent_indexes junction table:\n * - create: Assign an intent to an index (direct or evaluated via IntentIndexer agent)\n * - read: List intent-index links (by intentId or by networkId)\n * - delete: Unassign an intent from an index\n *\n * The evaluate-based assignment flow is migrated from the old Index Graph.\n */\nexport class IntentNetworkGraphFactory {\n constructor(\n private database: IntentNetworkGraphDatabase,\n private intentNetworker: IntentIndexer,\n ) {}\n\n public createGraph() {\n const indexer = this.intentNetworker;\n\n // --- NODE DEFINITIONS ---\n\n /**\n * Assign Node: Assign an intent to an index.\n * Two sub-paths:\n * - Direct assignment (skipEvaluation=true): assign immediately\n * - Evaluated assignment (skipEvaluation=false): load intent + index context, evaluate via IntentIndexer\n */\n const assignNode = async (state: typeof IntentNetworkGraphState.State) => {\n return timed(\"IntentNetworkGraph.assign\", async () => {\n const intentId = state.intentId;\n const networkId = state.networkId;\n logger.verbose(\"Assign intent to index\", { userId: state.userId, intentId, networkId, skipEvaluation: state.skipEvaluation });\n\n const agentTimingsAccum: DebugMetaAgent[] = [];\n\n if (!intentId || !networkId) {\n return { agentTimings: agentTimingsAccum, mutationResult: { success: false, error: \"Both intentId and networkId are required.\" } };\n }\n\n try {\n // Validate ownership and membership\n const intent = await this.database.getIntent(intentId);\n if (!intent) {\n return { agentTimings: agentTimingsAccum, mutationResult: { success: false, error: \"Intent not found.\" } };\n }\n if (intent.userId !== state.userId) {\n return { agentTimings: agentTimingsAccum, mutationResult: { success: false, error: \"You can only add your own intents to a network.\" } };\n }\n const [isMember, isOwner] = await Promise.all([\n this.database.isNetworkMember(networkId, state.userId),\n this.database.isIndexOwner(networkId, state.userId),\n ]);\n if (!isMember && !isOwner) {\n return { agentTimings: agentTimingsAccum, mutationResult: { success: false, error: \"You are not a member of that network.\" } };\n }\n\n // Check if already assigned\n const alreadyAssigned = await this.database.isIntentAssignedToIndex(intentId, networkId);\n if (alreadyAssigned) {\n return { agentTimings: agentTimingsAccum, mutationResult: { success: true, message: \"That intent is already in this network.\" } };\n }\n\n // Direct assignment (skip evaluation)\n if (state.skipEvaluation) {\n const decision = buildNetworkAssignmentDecision({\n resourceType: \"intent\",\n mode: \"manual_override\",\n scope: \"network\",\n evaluator: \"intent-network-graph\",\n source: \"manual-index-assignment\",\n createdAt: new Date().toISOString(),\n });\n await this.database.assignIntentToNetwork(intentId, networkId, decision.finalScore, decision.metadata);\n return {\n agentTimings: agentTimingsAccum,\n assignmentResult: { networkId, assigned: true, success: true } as AssignmentResult,\n mutationResult: { success: true, message: \"Intent saved to the network.\" },\n };\n }\n\n // Evaluated assignment (migrated from old Index Graph)\n const intentForIndexing = await this.database.getIntentForIndexing(intentId);\n if (!intentForIndexing) {\n return { agentTimings: agentTimingsAccum, mutationResult: { success: false, error: \"Intent not found for networking.\" } };\n }\n\n const indexContext = await this.database.getNetworkAssignmentContext(networkId, intentForIndexing.userId);\n if (!indexContext) {\n return {\n agentTimings: agentTimingsAccum,\n assignmentResult: { networkId, assigned: false, success: false } as AssignmentResult,\n mutationResult: { success: false, error: \"Network assignment context not found.\" },\n };\n }\n const indexPrompt = indexContext.indexPrompt ?? null;\n const memberPrompt = indexContext.memberPrompt ?? null;\n const hasNoPrompts = !indexPrompt?.trim() && !memberPrompt?.trim();\n if (hasNoPrompts) {\n const decision = buildNetworkAssignmentDecision({\n resourceType: \"intent\",\n mode: \"automatic\",\n scope: \"network\",\n indexPrompt,\n memberPrompt,\n evaluator: \"intent-indexer\",\n source: \"intent-network-graph\",\n createdAt: new Date().toISOString(),\n });\n await this.database.assignIntentToNetwork(intentId, networkId, decision.finalScore, decision.metadata);\n return {\n agentTimings: agentTimingsAccum,\n assignmentResult: { networkId, assigned: true, success: true } as AssignmentResult,\n mutationResult: { success: true, message: \"Intent assigned to network (no prompts).\" },\n };\n }\n\n // Run IntentIndexer evaluation\n const sourceName = intentForIndexing.sourceType\n ? `${intentForIndexing.sourceType}:${intentForIndexing.sourceId ?? \"\"}`\n : undefined;\n\n // Render network context (type, metadata) for the evaluator\n const network = await this.database.getNetwork(networkId);\n const renderedContext = network\n ? renderNetworkContext({\n type: network.type ?? 'community',\n title: network.title,\n prompt: network.prompt,\n metadata: network.metadata ?? {},\n })\n : null;\n\n const _traceEmitterIndexer = requestContext.getStore()?.traceEmitter;\n const _indexerStart = Date.now();\n _traceEmitterIndexer?.({ type: \"agent_start\", name: \"intent-indexer\" });\n let result: Awaited<ReturnType<typeof indexer.evaluate>> | null = null;\n try {\n result = await indexer.evaluate(\n intentForIndexing.payload,\n indexPrompt,\n memberPrompt,\n sourceName,\n renderedContext\n );\n } finally {\n const _indexerMs = Date.now() - _indexerStart;\n agentTimingsAccum.push({ name: 'intent.indexer', durationMs: _indexerMs });\n _traceEmitterIndexer?.({ type: \"agent_end\", name: \"intent-indexer\", durationMs: _indexerMs, summary: result ? `Scored: index=${result.indexScore.toFixed(2)}, member=${result.memberScore.toFixed(2)}` : \"intent-indexer failed\" });\n }\n\n if (!result) {\n return {\n agentTimings: agentTimingsAccum,\n evaluation: null,\n shouldAssign: false,\n finalScore: 0,\n mutationResult: { success: false, error: \"Evaluation returned no result.\" },\n };\n }\n\n const decision = buildNetworkAssignmentDecision({\n resourceType: \"intent\",\n mode: \"automatic\",\n scope: \"network\",\n indexPrompt,\n memberPrompt,\n rawScores: { indexScore: result.indexScore, memberScore: result.memberScore },\n evaluator: \"intent-indexer\",\n source: \"intent-network-graph\",\n reason: result.reasoning,\n createdAt: new Date().toISOString(),\n });\n\n if (decision.assigned) {\n await this.database.assignIntentToNetwork(intentId, networkId, decision.finalScore, decision.metadata);\n return {\n agentTimings: agentTimingsAccum,\n evaluation: result,\n shouldAssign: true,\n finalScore: decision.finalScore,\n assignmentResult: { networkId, assigned: true, success: true } as AssignmentResult,\n mutationResult: { success: true, message: `Intent assigned to network (score: ${decision.finalScore.toFixed(2)}).` },\n };\n }\n\n return {\n agentTimings: agentTimingsAccum,\n evaluation: result,\n shouldAssign: false,\n finalScore: decision.finalScore,\n assignmentResult: { networkId, assigned: false, success: true } as AssignmentResult,\n mutationResult: { success: false, error: `Intent did not qualify for this network (score: ${decision.finalScore.toFixed(2)}).` },\n };\n } catch (err) {\n logger.error(\"Assign failed\", { error: err });\n return { agentTimings: agentTimingsAccum, mutationResult: { success: false, error: \"Failed to assign intent to network.\" } };\n }\n });\n };\n\n /**\n * Read Node: Query intent-index relationships.\n * - By intentId only: list all indexes the intent is in (owner only)\n * - By networkId only: list intents in the index (member only)\n * - By both intentId and networkId: check if specific link exists (owner only)\n */\n const readNode = async (state: typeof IntentNetworkGraphState.State) => {\n return timed(\"IntentNetworkGraph.read\", async () => {\n const intentId = state.intentId;\n const networkId = state.networkId;\n logger.verbose(\"Read intent-index links\", { userId: state.userId, intentId, networkId, queryUserId: state.queryUserId });\n\n try {\n // By both: check if specific intent-index link exists\n if (intentId && networkId) {\n const intent = await this.database.getIntent(intentId);\n if (!intent) {\n return { readResult: { links: [], count: 0, mode: \"check_link\" }, error: \"Intent not found.\" };\n }\n if (intent.userId !== state.userId) {\n return { readResult: { links: [], count: 0, mode: \"check_link\" }, error: \"You can only check links for your own intents.\" };\n }\n const isLinked = await this.database.isIntentAssignedToIndex(intentId, networkId);\n return {\n readResult: {\n links: isLinked ? [{ intentId, networkId }] : [],\n count: isLinked ? 1 : 0,\n mode: \"check_link\",\n note: isLinked ? \"Intent is linked to this network.\" : \"Intent is not linked to this network.\",\n },\n };\n }\n\n // By intent only: list all indexes for this intent\n if (intentId) {\n const intent = await this.database.getIntent(intentId);\n if (!intent) {\n return { readResult: { links: [], count: 0, mode: \"networks_for_intent\" }, error: \"Intent not found.\" };\n }\n if (intent.userId !== state.userId) {\n return { readResult: { links: [], count: 0, mode: \"networks_for_intent\" }, error: \"You can only list networks for your own intents.\" };\n }\n const networkIds = await this.database.getNetworkIdsForIntent(intentId);\n return {\n readResult: {\n links: networkIds.map((id) => ({ intentId, networkId: id })),\n count: networkIds.length,\n mode: \"networks_for_intent\",\n note: \"To show network titles, use read_networks.\",\n },\n };\n }\n\n // By index: list intents in the index\n if (!networkId) {\n return {\n readResult: { links: [], count: 0, mode: \"unknown\" },\n error: \"Provide networkId or intentId.\",\n };\n }\n\n const [isMember, isOwner] = await Promise.all([\n this.database.isNetworkMember(networkId, state.userId),\n this.database.isIndexOwner(networkId, state.userId),\n ]);\n if (!isMember && !isOwner) {\n return {\n readResult: { links: [], count: 0, mode: \"intents_in_network\" },\n error: \"Network not found or you are not a member.\",\n };\n }\n\n // All intents or filtered by user\n if (!state.queryUserId) {\n const intents = await this.database.getNetworkIntentsForMember(networkId, state.userId, { limit: 50, offset: 0 });\n return {\n readResult: {\n links: intents.map((i) => ({\n intentId: i.id,\n networkId,\n intentTitle: i.payload,\n userId: i.userId,\n userName: i.userName,\n createdAt: i.createdAt,\n relevancyScore: i.relevancyScore,\n })),\n count: intents.length,\n mode: \"intents_in_network\",\n note: \"To show network title and full intent details, use read_networks and read_intents.\",\n },\n };\n }\n\n // Specific user's intents\n const intents = await this.database.getIntentsInIndexForMember(state.queryUserId, networkId);\n return {\n readResult: {\n links: intents.map((i) => ({\n intentId: i.id,\n networkId,\n intentTitle: i.payload,\n createdAt: i.createdAt,\n relevancyScore: i.relevancyScore,\n })),\n count: intents.length,\n mode: \"intents_in_network\",\n note: \"To show network title and full intent details, use read_networks and read_intents.\",\n },\n };\n } catch (err) {\n logger.error(\"Read intent-index failed\", { error: err });\n return { error: \"Failed to fetch intent-network links.\" };\n }\n });\n };\n\n /**\n * Unassign Node: Remove an intent from an index.\n */\n const unassignNode = async (state: typeof IntentNetworkGraphState.State) => {\n return timed(\"IntentNetworkGraph.unassign\", async () => {\n const intentId = state.intentId;\n const networkId = state.networkId;\n logger.verbose(\"Unassign intent from index\", { userId: state.userId, intentId, networkId });\n\n if (!intentId || !networkId) {\n return { mutationResult: { success: false, error: \"Both intentId and networkId are required.\" } };\n }\n\n try {\n const intent = await this.database.getIntent(intentId);\n if (!intent) {\n return { mutationResult: { success: false, error: \"Intent not found.\" } };\n }\n if (intent.userId !== state.userId) {\n return { mutationResult: { success: false, error: \"You can only remove your own intents from a network.\" } };\n }\n const [isMember, isOwner] = await Promise.all([\n this.database.isNetworkMember(networkId, state.userId),\n this.database.isIndexOwner(networkId, state.userId),\n ]);\n if (!isMember && !isOwner) {\n return { mutationResult: { success: false, error: \"You are not a member of that network.\" } };\n }\n\n const assigned = await this.database.isIntentAssignedToIndex(intentId, networkId);\n if (!assigned) {\n return { mutationResult: { success: true, message: \"That intent is not in this network.\" } };\n }\n\n await this.database.unassignIntentFromIndex(intentId, networkId);\n return { mutationResult: { success: true, message: \"Intent removed from the index.\" } };\n } catch (err) {\n logger.error(\"Unassign failed\", { error: err });\n return { mutationResult: { success: false, error: \"Failed to remove intent from network.\" } };\n }\n });\n };\n\n // --- CONDITIONAL ROUTING ---\n\n const routeByMode = (state: typeof IntentNetworkGraphState.State): string => {\n switch (state.operationMode) {\n case 'create': return 'assign';\n case 'read': return 'read';\n case 'delete': return 'unassign';\n default: return 'read';\n }\n };\n\n // --- GRAPH ASSEMBLY ---\n\n const workflow = new StateGraph(IntentNetworkGraphState)\n .addNode(\"assign\", assignNode)\n .addNode(\"read\", readNode)\n .addNode(\"unassign\", unassignNode)\n .addConditionalEdges(START, routeByMode, {\n assign: \"assign\",\n read: \"read\",\n unassign: \"unassign\",\n })\n .addEdge(\"assign\", END)\n .addEdge(\"read\", END)\n .addEdge(\"unassign\", END);\n\n return workflow.compile();\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"discovery-question.helper.d.ts","sourceRoot":"/","sources":["opportunity/discovery-question.helper.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0CAA0C,CAAC;AAClF,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,gDAAgD,CAAC;AACjG,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,KAAK,EACV,sBAAsB,EAEtB,gBAAgB,EACjB,MAAM,sBAAsB,CAAC;AAE9B,MAAM,WAAW,+BAA+B;IAC9C,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACxC,kBAAkB,EAAE,0BAA0B,EAAE,CAAC;IACjD,OAAO,EAAE,gBAAgB,CAAC;IAC1B,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAChC,GAAG,EAAE,MAAM,CAAC;CACb;AAED,qGAAqG;AACrG,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,+BAA+B,GAAG,sBAAsB,CASzG"}
1
+ {"version":3,"file":"discovery-question.helper.d.ts","sourceRoot":"/","sources":["opportunity/discovery-question.helper.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0CAA0C,CAAC;AAClF,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,gDAAgD,CAAC;AACjG,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,KAAK,EAAE,sBAAsB,EAA0B,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAE7G,MAAM,WAAW,+BAA+B;IAC9C,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACxC,kBAAkB,EAAE,0BAA0B,EAAE,CAAC;IACjD,OAAO,EAAE,gBAAgB,CAAC;IAC1B,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAChC,GAAG,EAAE,MAAM,CAAC;CACb;AAED,qGAAqG;AACrG,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,+BAA+B,GAAG,sBAAsB,CASzG"}
@@ -1 +1 @@
1
- {"version":3,"file":"discovery-question.helper.js","sourceRoot":"/","sources":["opportunity/discovery-question.helper.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAoBH,qGAAqG;AACrG,MAAM,UAAU,2BAA2B,CAAC,IAAqC;IAC/E,OAAO;QACL,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,aAAa,EAAE,oBAAoB,CAAC,IAAI,CAAC,aAAa,CAAC;QACvD,kBAAkB,EAAE,IAAI,CAAC,kBAAkB;QAC3C,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,GAAG,CAAC,IAAI,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5E,GAAG,EAAE,IAAI,CAAC,GAAG;KACd,CAAC;AACJ,CAAC;AAED,SAAS,oBAAoB,CAAC,OAAiC;IAC7D,IAAI,CAAC,OAAO;QAAE,OAAO,EAAE,CAAC;IACxB,MAAM,GAAG,GAA2B,EAAE,CAAC;IACvC,IAAI,OAAO,CAAC,QAAQ,EAAE,IAAI;QAAE,GAAG,CAAC,IAAI,GAAG,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC;IAC7D,IAAI,OAAO,CAAC,QAAQ,EAAE,GAAG;QAAE,GAAG,CAAC,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC;IAC1D,IAAI,OAAO,CAAC,QAAQ,EAAE,QAAQ;QAAE,GAAG,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC;IACzE,IAAI,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM;QAAE,GAAG,CAAC,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC;IAC/E,IAAI,OAAO,CAAC,UAAU,EAAE,SAAS,EAAE,MAAM;QAAE,GAAG,CAAC,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC;IACxF,OAAO,GAAG,CAAC;AACb,CAAC","sourcesContent":["/**\n * Pure mapper from opportunity-graph outputs + optional chat digest to a\n * `DiscoveryQuestionInput`. No I/O. Side-effect-free.\n */\n\nimport type { ChatContextDigest } from \"../shared/schemas/chat-context.schema.js\";\nimport type { DiscoveryNegotiationDigest } from \"../shared/schemas/negotiation-digest.schema.js\";\nimport type { SourceProfileData } from \"./opportunity.state.js\";\nimport type {\n DiscoveryQuestionInput,\n DiscoverySourceProfile,\n DiscoverySummary,\n} from \"./question.prompt.js\";\n\nexport interface BuildDiscoveryQuestionInputArgs {\n query: string;\n sourceProfile: SourceProfileData | null;\n negotiationDigests: DiscoveryNegotiationDigest[];\n summary: DiscoverySummary;\n chatContext?: ChatContextDigest;\n now: string;\n}\n\n/** @deprecated Use QuestionerAgent discovery preset instead. Will be removed in a future version. */\nexport function buildDiscoveryQuestionInput(args: BuildDiscoveryQuestionInputArgs): DiscoveryQuestionInput {\n return {\n query: args.query,\n sourceProfile: extractSourceProfile(args.sourceProfile),\n negotiationDigests: args.negotiationDigests,\n summary: args.summary,\n ...(args.chatContext !== undefined ? { chatContext: args.chatContext } : {}),\n now: args.now,\n };\n}\n\nfunction extractSourceProfile(profile: SourceProfileData | null): DiscoverySourceProfile {\n if (!profile) return {};\n const out: DiscoverySourceProfile = {};\n if (profile.identity?.name) out.name = profile.identity.name;\n if (profile.identity?.bio) out.bio = profile.identity.bio;\n if (profile.identity?.location) out.location = profile.identity.location;\n if (profile.attributes?.skills?.length) out.skills = profile.attributes.skills;\n if (profile.attributes?.interests?.length) out.interests = profile.attributes.interests;\n return out;\n}\n"]}
1
+ {"version":3,"file":"discovery-question.helper.js","sourceRoot":"/","sources":["opportunity/discovery-question.helper.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAgBH,qGAAqG;AACrG,MAAM,UAAU,2BAA2B,CAAC,IAAqC;IAC/E,OAAO;QACL,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,aAAa,EAAE,oBAAoB,CAAC,IAAI,CAAC,aAAa,CAAC;QACvD,kBAAkB,EAAE,IAAI,CAAC,kBAAkB;QAC3C,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,GAAG,CAAC,IAAI,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5E,GAAG,EAAE,IAAI,CAAC,GAAG;KACd,CAAC;AACJ,CAAC;AAED,SAAS,oBAAoB,CAAC,OAAiC;IAC7D,IAAI,CAAC,OAAO;QAAE,OAAO,EAAE,CAAC;IACxB,MAAM,GAAG,GAA2B,EAAE,CAAC;IACvC,IAAI,OAAO,CAAC,QAAQ,EAAE,IAAI;QAAE,GAAG,CAAC,IAAI,GAAG,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC;IAC7D,IAAI,OAAO,CAAC,QAAQ,EAAE,GAAG;QAAE,GAAG,CAAC,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC;IAC1D,IAAI,OAAO,CAAC,QAAQ,EAAE,QAAQ;QAAE,GAAG,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC;IACzE,IAAI,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM;QAAE,GAAG,CAAC,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC;IAC/E,IAAI,OAAO,CAAC,UAAU,EAAE,SAAS,EAAE,MAAM;QAAE,GAAG,CAAC,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC;IACxF,OAAO,GAAG,CAAC;AACb,CAAC","sourcesContent":["/**\n * Pure mapper from opportunity-graph outputs + optional chat digest to a\n * `DiscoveryQuestionInput`. No I/O. Side-effect-free.\n */\n\nimport type { ChatContextDigest } from \"../shared/schemas/chat-context.schema.js\";\nimport type { DiscoveryNegotiationDigest } from \"../shared/schemas/negotiation-digest.schema.js\";\nimport type { SourceProfileData } from \"./opportunity.state.js\";\nimport type { DiscoveryQuestionInput, DiscoverySourceProfile, DiscoverySummary } from \"./question.prompt.js\";\n\nexport interface BuildDiscoveryQuestionInputArgs {\n query: string;\n sourceProfile: SourceProfileData | null;\n negotiationDigests: DiscoveryNegotiationDigest[];\n summary: DiscoverySummary;\n chatContext?: ChatContextDigest;\n now: string;\n}\n\n/** @deprecated Use QuestionerAgent discovery preset instead. Will be removed in a future version. */\nexport function buildDiscoveryQuestionInput(args: BuildDiscoveryQuestionInputArgs): DiscoveryQuestionInput {\n return {\n query: args.query,\n sourceProfile: extractSourceProfile(args.sourceProfile),\n negotiationDigests: args.negotiationDigests,\n summary: args.summary,\n ...(args.chatContext !== undefined ? { chatContext: args.chatContext } : {}),\n now: args.now,\n };\n}\n\nfunction extractSourceProfile(profile: SourceProfileData | null): DiscoverySourceProfile {\n if (!profile) return {};\n const out: DiscoverySourceProfile = {};\n if (profile.identity?.name) out.name = profile.identity.name;\n if (profile.identity?.bio) out.bio = profile.identity.bio;\n if (profile.identity?.location) out.location = profile.identity.location;\n if (profile.attributes?.skills?.length) out.skills = profile.attributes.skills;\n if (profile.attributes?.interests?.length) out.interests = profile.attributes.interests;\n return out;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"feed.graph.d.ts","sourceRoot":"/","sources":["opportunity/feed/feed.graph.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAMH,OAAO,KAAK,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,+CAA+C,CAAC;AAC1G,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4CAA4C,CAAC;AACnF,OAAO,EAEL,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,mBAAmB,EAEzB,MAAM,iBAAiB,CAAC;AAOzB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAOzE,8HAA8H;AAC9H,KAAK,WAAW,GAAG,iBAAiB,CAAC;AAErC,MAAM,MAAM,oBAAoB,GAAG;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,8GAA8G;IAC9G,QAAQ,CAAC,EAAE,iBAAiB,EAAE,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,IAAI,EAAE;QAAE,kBAAkB,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5D,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,kFAAkF;AAClF,eAAO,MAAM,qBAAqB,EAAE,iBAAiB,EAA0B,CAAC;AAgBhF,0HAA0H;AAC1H,eAAO,MAAM,wBAAwB,EAAE,iBAAiB,EAEhC,CAAC;AAOzB;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAarF;AA4ED,qBAAa,gBAAgB;IACf,OAAO,CAAC,QAAQ;IAAe,OAAO,CAAC,KAAK;gBAApC,QAAQ,EAAE,WAAW,EAAU,KAAK,EAAE,gBAAgB;IAE1E,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwiBZ"}
1
+ {"version":3,"file":"feed.graph.d.ts","sourceRoot":"/","sources":["opportunity/feed/feed.graph.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAMH,OAAO,KAAK,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,+CAA+C,CAAC;AAC1G,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4CAA4C,CAAC;AACnF,OAAO,EAAkB,KAAK,YAAY,EAAE,KAAK,WAAW,EAAE,KAAK,mBAAmB,EAAwB,MAAM,iBAAiB,CAAC;AAOtI,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAOzE,8HAA8H;AAC9H,KAAK,WAAW,GAAG,iBAAiB,CAAC;AAErC,MAAM,MAAM,oBAAoB,GAAG;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,8GAA8G;IAC9G,QAAQ,CAAC,EAAE,iBAAiB,EAAE,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,IAAI,EAAE;QAAE,kBAAkB,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5D,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,kFAAkF;AAClF,eAAO,MAAM,qBAAqB,EAAE,iBAAiB,EAA0B,CAAC;AAgBhF,0HAA0H;AAC1H,eAAO,MAAM,wBAAwB,EAAE,iBAAiB,EAEhC,CAAC;AAOzB;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAarF;AA4ED,qBAAa,gBAAgB;IACf,OAAO,CAAC,QAAQ;IAAe,OAAO,CAAC,KAAK;gBAApC,QAAQ,EAAE,WAAW,EAAU,KAAK,EAAE,gBAAgB;IAE1E,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwiBZ"}
@@ -10,7 +10,7 @@
10
10
  */
11
11
  import { createHash } from 'crypto';
12
12
  import { StateGraph, START, END } from '@langchain/langgraph';
13
- import { HomeGraphState, } from './feed.state.js';
13
+ import { HomeGraphState } from './feed.state.js';
14
14
  import { OpportunityPresenter, gatherPresenterContext } from '../opportunity.presenter.js';
15
15
  import { loadNegotiationContext } from '../negotiation-context.loader.js';
16
16
  import { HomeCategorizerAgent } from './feed.categorizer.js';