@indexnetwork/protocol 3.6.3-rc.269.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 (77) hide show
  1. package/README.md +90 -26
  2. package/dist/agent/tests/fakes.d.ts.map +1 -1
  3. package/dist/agent/tests/fakes.js.map +1 -1
  4. package/dist/chat/chat.agent.d.ts.map +1 -1
  5. package/dist/chat/chat.agent.js +3 -3
  6. package/dist/chat/chat.agent.js.map +1 -1
  7. package/dist/chat/chat.streamer.d.ts.map +1 -1
  8. package/dist/chat/chat.streamer.js +1 -1
  9. package/dist/chat/chat.streamer.js.map +1 -1
  10. package/dist/chat/chat.summarizer.d.ts.map +1 -1
  11. package/dist/chat/chat.summarizer.js +1 -1
  12. package/dist/chat/chat.summarizer.js.map +1 -1
  13. package/dist/chat/tests/chat.graph.mocks.d.ts.map +1 -1
  14. package/dist/chat/tests/chat.graph.mocks.js +0 -1
  15. package/dist/chat/tests/chat.graph.mocks.js.map +1 -1
  16. package/dist/index.d.ts +21 -21
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js +10 -10
  19. package/dist/index.js.map +1 -1
  20. package/dist/intent/intent.graph.js +1 -1
  21. package/dist/intent/intent.graph.js.map +1 -1
  22. package/dist/maintenance/maintenance.graph.d.ts.map +1 -1
  23. package/dist/maintenance/maintenance.graph.js +1 -1
  24. package/dist/maintenance/maintenance.graph.js.map +1 -1
  25. package/dist/negotiation/negotiation.agent.d.ts.map +1 -1
  26. package/dist/negotiation/negotiation.agent.js +1 -1
  27. package/dist/negotiation/negotiation.agent.js.map +1 -1
  28. package/dist/negotiation/negotiation.summarizer.d.ts.map +1 -1
  29. package/dist/negotiation/negotiation.summarizer.js +1 -1
  30. package/dist/negotiation/negotiation.summarizer.js.map +1 -1
  31. package/dist/network/indexer/indexer.graph.d.ts.map +1 -1
  32. package/dist/network/indexer/indexer.graph.js +2 -2
  33. package/dist/network/indexer/indexer.graph.js.map +1 -1
  34. package/dist/opportunity/discovery-question.helper.d.ts.map +1 -1
  35. package/dist/opportunity/discovery-question.helper.js.map +1 -1
  36. package/dist/opportunity/feed/feed.graph.d.ts.map +1 -1
  37. package/dist/opportunity/feed/feed.graph.js +1 -1
  38. package/dist/opportunity/feed/feed.graph.js.map +1 -1
  39. package/dist/opportunity/negotiation-summary.builder.d.ts.map +1 -1
  40. package/dist/opportunity/negotiation-summary.builder.js.map +1 -1
  41. package/dist/opportunity/opportunity.discover.d.ts.map +1 -1
  42. package/dist/opportunity/opportunity.discover.js +1 -1
  43. package/dist/opportunity/opportunity.discover.js.map +1 -1
  44. package/dist/opportunity/opportunity.enricher.d.ts.map +1 -1
  45. package/dist/opportunity/opportunity.enricher.js.map +1 -1
  46. package/dist/opportunity/opportunity.graph.d.ts.map +1 -1
  47. package/dist/opportunity/opportunity.graph.js +5 -5
  48. package/dist/opportunity/opportunity.graph.js.map +1 -1
  49. package/dist/opportunity/opportunity.persist.d.ts.map +1 -1
  50. package/dist/opportunity/opportunity.persist.js.map +1 -1
  51. package/dist/opportunity/question.generator.d.ts.map +1 -1
  52. package/dist/opportunity/question.generator.js +2 -2
  53. package/dist/opportunity/question.generator.js.map +1 -1
  54. package/dist/premise/premise.graph.d.ts.map +1 -1
  55. package/dist/premise/premise.graph.js +1 -1
  56. package/dist/premise/premise.graph.js.map +1 -1
  57. package/dist/profile/profile.graph.js +1 -1
  58. package/dist/profile/profile.graph.js.map +1 -1
  59. package/dist/questioner/questioner.agent.d.ts.map +1 -1
  60. package/dist/questioner/questioner.agent.js +1 -1
  61. package/dist/questioner/questioner.agent.js.map +1 -1
  62. package/dist/questioner/questioner.presets.d.ts.map +1 -1
  63. package/dist/questioner/questioner.presets.js +1 -1
  64. package/dist/questioner/questioner.presets.js.map +1 -1
  65. package/dist/shared/agent/response.streamer.d.ts.map +1 -1
  66. package/dist/shared/agent/response.streamer.js +1 -1
  67. package/dist/shared/agent/response.streamer.js.map +1 -1
  68. package/dist/shared/agent/tool.factory.d.ts.map +1 -1
  69. package/dist/shared/agent/tool.factory.js +1 -1
  70. package/dist/shared/agent/tool.factory.js.map +1 -1
  71. package/dist/shared/agent/tool.helpers.d.ts.map +1 -1
  72. package/dist/shared/agent/tool.helpers.js.map +1 -1
  73. package/dist/shared/assignment/network-assignment.policy.d.ts.map +1 -1
  74. package/dist/shared/assignment/network-assignment.policy.js.map +1 -1
  75. package/dist/shared/interfaces/questioner.interface.d.ts.map +1 -1
  76. package/dist/shared/interfaces/questioner.interface.js.map +1 -1
  77. package/package.json +1 -1
@@ -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":"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","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';
@@ -1 +1 @@
1
- {"version":3,"file":"feed.graph.js","sourceRoot":"/","sources":["opportunity/feed/feed.graph.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAEpC,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,sBAAsB,CAAC;AAI9D,OAAO,EACL,cAAc,GAKf,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,oBAAoB,EAAE,sBAAsB,EAA0B,MAAM,6BAA6B,CAAC;AACnH,OAAO,EAAE,sBAAsB,EAAE,MAAM,kCAAkC,CAAC;AAC1E,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC5G,OAAO,EAAE,sBAAsB,EAA6B,MAAM,wCAAwC,CAAC;AAC3G,OAAO,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAEzF,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,MAAM,MAAM,GAAG,cAAc,CAAC,WAAW,CAAC,CAAC;AAoB3C,kFAAkF;AAClF,MAAM,CAAC,MAAM,qBAAqB,GAAwB,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;AAEhF,8EAA8E;AAC9E,oFAAoF;AACpF,sFAAsF;AACtF,MAAM,2BAA2B,GAAoC;IACnE,MAAM,EAAE,IAAI;IACZ,KAAK,EAAE,IAAI;IACX,WAAW,EAAE,IAAI;IACjB,OAAO,EAAE,IAAI;IACb,OAAO,EAAE,IAAI;IACb,QAAQ,EAAE,IAAI;IACd,QAAQ,EAAE,IAAI;IACd,OAAO,EAAE,IAAI;CACd,CAAC;AAEF,0HAA0H;AAC1H,MAAM,CAAC,MAAM,wBAAwB,GAAwB,MAAM,CAAC,IAAI,CACtE,2BAA2B,CACL,CAAC;AAEzB,MAAM,qBAAqB,GAAG,EAAE,CAAC;AACjC,MAAM,wBAAwB,GAAG,EAAE,CAAC;AACpC,MAAM,4BAA4B,GAAG,GAAG,CAAC;AACzC,MAAM,cAAc,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,sBAAsB;AAE3D;;;;GAIG;AACH,MAAM,UAAU,wBAAwB,CAAC,MAAc,EAAE,YAAoB;IAC3E,IAAI,CAAC,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;IACtB,IAAI,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE;QAAE,OAAO,MAAM,CAAC;IAC9C,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,EAAE,CAAC;IACjC,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IACrC,SAAS,CAAC;QACR,MAAM,KAAK,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;QAC9B,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,SAAS,CAAC;YAAE,MAAM;QACxC,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QACzE,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC;YAAE,MAAM;QAC3C,CAAC,GAAG,IAAI,CAAC;IACX,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED,oFAAoF;AACpF,MAAM,aAAa,GAAG,CAAC,KAAc,EAAU,EAAE;IAC/C,IAAI,KAAK,IAAI,IAAI;QAAE,OAAO,CAAC,CAAC;IAC5B,IAAI,KAAK,YAAY,IAAI,EAAE,CAAC;QAC1B,MAAM,CAAC,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC;QAC1B,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACpC,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACtE,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC;QACpC,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACpC,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC,CAAC;AAEF,0FAA0F;AAC1F,MAAM,aAAa,GAAG,CAAC,GAAyD,EAAU,EAAE;IAC1F,MAAM,UAAU,GAAG,GAAG,CAAC,cAAc,EAAE,UAAU,CAAC;IAClD,IAAI,OAAO,UAAU,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC;QAAE,OAAO,UAAU,CAAC;IACnF,IAAI,OAAO,UAAU,KAAK,QAAQ,EAAE,CAAC;QACnC,MAAM,CAAC,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC;QACjC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YAAE,OAAO,CAAC,CAAC;IACjC,CAAC;IACD,MAAM,OAAO,GAAG,GAAG,CAAC,UAAU,CAAC;IAC/B,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC;QAAE,OAAO,OAAO,CAAC;IAC1E,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;QAChC,MAAM,CAAC,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;QAC9B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YAAE,OAAO,CAAC,CAAC;IACjC,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC,CAAC;AAEF,wFAAwF;AACxF,MAAM,2BAA2B,GAAG,CAClC,GAAyD,EACzD,QAAgB,EACH,EAAE;IACf,MAAM,GAAG,GAAG,IAAI,GAAG,EAAU,CAAC;IAC9B,KAAK,MAAM,CAAC,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;QAC3B,IAAI,CAAC,CAAC,IAAI,KAAK,YAAY,IAAI,CAAC,CAAC,MAAM,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;YACjE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QACpB,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC,CAAC;AAEF,MAAM,2BAA2B,GAAG,CAClC,WAAiE,EACjE,QAAgB,EACyB,EAAE;IAC3C,MAAM,UAAU,GAAG,WAAW,CAAC,MAAM,CAAC,MAAM,CAC1C,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,CACpE,CAAC;IACF,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,+EAA+E;IAC/E,MAAM,YAAY,GAAG,IAAI,GAAG,CAAiB;QAC3C,CAAC,SAAS,EAAE,CAAC,CAAC;QACd,CAAC,OAAO,EAAE,CAAC,CAAC;QACZ,CAAC,OAAO,EAAE,CAAC,CAAC;QACZ,CAAC,MAAM,EAAE,CAAC,CAAC;KACZ,CAAC,CAAC;IAEH,MAAM,MAAM,GAAG,CAAC,GAAG,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QAC3C,MAAM,SAAS,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QACjD,MAAM,SAAS,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QACjD,IAAI,SAAS,KAAK,SAAS;YAAE,OAAO,SAAS,GAAG,SAAS,CAAC;QAC1D,OAAO,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IACH,OAAO,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;AAC3B,CAAC,CAAC;AAEF,MAAM,OAAO,gBAAgB;IAC3B,YAAoB,QAAqB,EAAU,KAAuB;QAAtD,aAAQ,GAAR,QAAQ,CAAa;QAAU,UAAK,GAAL,KAAK,CAAkB;IAAG,CAAC;IAE9E,WAAW;QACT,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;QAC7C,MAAM,WAAW,GAAG,IAAI,oBAAoB,EAAE,CAAC;QAE/C,MAAM,qBAAqB,GAAG,KAAK,EAAE,KAAkC,EAAE,EAAE;YACzE,OAAO,KAAK,CAAC,6BAA6B,EAAE,KAAK,IAAI,EAAE;gBACrD,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;oBAClB,OAAO,EAAE,KAAK,EAAE,oBAAoB,EAAE,CAAC;gBACzC,CAAC;gBACD,IAAI,CAAC;oBACH,qEAAqE;oBACrE,wEAAwE;oBACxE,+DAA+D;oBAC/D,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC;oBAChE,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,IAAI,qBAAqB,CAAC;oBACzD,MAAM,OAAO,GAA2E;wBACtF,KAAK,EAAE,UAAU;wBACjB,QAAQ;qBACT,CAAC;oBACF,IAAI,KAAK,CAAC,SAAS;wBAAE,OAAO,CAAC,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC;oBACzD,yFAAyF;oBACzF,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,uBAAuB,CAAC,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;oBAC/E,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CACjC,qBAAqB,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,CAC5D,CAAC;oBACF,MAAM,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAC5C,qBAAqB,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,CAC5D,CAAC;oBACF,MAAM,MAAM,GAAG,CAAC,GAAG,cAAc,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;wBAC/C,oEAAoE;wBACpE,gEAAgE;wBAChE,mDAAmD;wBACnD,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,IAAI,EAAE,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC;wBACpG,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,IAAI,EAAE,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC;wBACpG,IAAI,aAAa,KAAK,aAAa;4BAAE,OAAO,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;wBACnE,MAAM,KAAK,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;wBAC/B,MAAM,KAAK,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;wBAC/B,IAAI,KAAK,KAAK,KAAK;4BAAE,OAAO,KAAK,GAAG,KAAK,CAAC;wBAC1C,MAAM,KAAK,GAAG,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;wBACzC,MAAM,KAAK,GAAG,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;wBACzC,OAAO,KAAK,GAAG,KAAK,CAAC;oBACvB,CAAC,CAAC,CAAC;oBACH,MAAM,WAAW,GAAG,IAAI,GAAG,EAAU,CAAC;oBACtC,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE;wBACpC,MAAM,cAAc,GAAG,2BAA2B,CAAC,GAAG,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;wBACtE,MAAM,UAAU,GAAG,CAAC,GAAG,cAAc,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;wBACzE,IAAI,UAAU;4BAAE,OAAO,KAAK,CAAC;wBAC7B,KAAK,MAAM,EAAE,IAAI,cAAc;4BAAE,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;wBACrD,OAAO,IAAI,CAAC;oBACd,CAAC,CAAC,CAAC;oBACH,MAAM,aAAa,GAAG,mBAAmB,CAAC,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;oBACjE,OAAO,EAAE,aAAa,EAAE,CAAC;gBAC3B,CAAC;gBAAC,OAAO,CAAC,EAAE,CAAC;oBACX,MAAM,CAAC,KAAK,CAAC,oCAAoC,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;oBACjE,OAAO,EAAE,KAAK,EAAE,8BAA8B,EAAE,aAAa,EAAE,EAAE,EAAE,CAAC;gBACtE,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC,CAAC;QAEF,MAAM,uBAAuB,GAAG,KAAK,EAAE,KAAkC,EAAE,EAAE;YAC3E,OAAO,KAAK,CAAC,+BAA+B,EAAE,KAAK,IAAI,EAAE;gBACvD,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC;gBACxC,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBAC/B,OAAO,EAAE,WAAW,EAAE,IAAI,GAAG,EAAE,EAAE,qBAAqB,EAAE,EAAE,EAAE,CAAC;gBAC/D,CAAC;gBAED,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;oBAClB,MAAM,CAAC,OAAO,CAAC,8DAA8D,CAAC,CAAC;oBAC/E,OAAO,EAAE,WAAW,EAAE,IAAI,GAAG,EAAE,EAAE,qBAAqB,EAAE,aAAa,EAAE,CAAC;gBAC1E,CAAC;gBAED,IAAI,CAAC;oBACH,+DAA+D;oBAC/D,iEAAiE;oBACjE,+DAA+D;oBAC/D,qDAAqD;oBACrD,EAAE;oBACF,8DAA8D;oBAC9D,oEAAoE;oBACpE,MAAM,SAAS,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,KAAK,aAAa,CAAC,CAAC;oBAC9E,MAAM,eAAe,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,KAAK,aAAa,CAAC,CAAC;oBAEpF,MAAM,IAAI,GAAG,SAAS,CAAC,GAAG,CACxB,CAAC,GAAG,EAAE,EAAE,CAAC,aAAa,GAAG,CAAC,EAAE,IAAI,GAAG,CAAC,MAAM,IAAI,MAAM,EAAE,CACvD,CAAC;oBACF,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAe,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;oBAEjF,MAAM,WAAW,GAAG,IAAI,GAAG,EAAwB,CAAC;oBACpD,MAAM,qBAAqB,GAAyB,CAAC,GAAG,eAAe,CAAC,CAAC;oBAEzE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;wBAC1C,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;wBAC1B,IAAI,MAAM,EAAE,CAAC;4BACX,MAAM,aAAa,GAAG,aAAa,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;4BAC1D,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,GAAG,MAAM,EAAE,UAAU,EAAE,aAAa,EAAE,CAAC,CAAC;wBAC7E,CAAC;6BAAM,CAAC;4BACN,qBAAqB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;wBAC3C,CAAC;oBACH,CAAC;oBAED,MAAM,CAAC,OAAO,CAAC,iCAAiC,EAAE;wBAChD,KAAK,EAAE,aAAa,CAAC,MAAM;wBAC3B,SAAS,EAAE,WAAW,CAAC,IAAI;wBAC3B,WAAW,EAAE,qBAAqB,CAAC,MAAM;qBAC1C,CAAC,CAAC;oBAEH,OAAO,EAAE,WAAW,EAAE,qBAAqB,EAAE,CAAC;gBAChD,CAAC;gBAAC,OAAO,CAAC,EAAE,CAAC;oBACX,MAAM,CAAC,IAAI,CAAC,6DAA6D,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;oBACzF,OAAO,EAAE,WAAW,EAAE,IAAI,GAAG,EAAE,EAAE,qBAAqB,EAAE,aAAa,EAAE,CAAC;gBAC1E,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC,CAAC;QAEF,MAAM,mBAAmB,GAAG,CAAC,KAAkC,EAAU,EAAE;YACzE,IAAI,KAAK,CAAC,qBAAqB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC3C,OAAO,UAAU,CAAC;YACpB,CAAC;YACD,MAAM,CAAC,OAAO,CAAC,+DAA+D,CAAC,CAAC;YAChF,OAAO,MAAM,CAAC;QAChB,CAAC,CAAC;QAEF,MAAM,oBAAoB,GAAG,KAAK,EAAE,KAAkC,EAAE,EAAE;YACxE,OAAO,KAAK,CAAC,4BAA4B,EAAE,KAAK,IAAI,EAAE;gBACtD,MAAM,aAAa,GAAG,KAAK,CAAC,qBAAqB,CAAC,MAAM,GAAG,CAAC;oBAC1D,CAAC,CAAC,KAAK,CAAC,qBAAqB;oBAC7B,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC;gBACxB,MAAM,CAAC,OAAO,CAAC,oCAAoC,EAAE,EAAE,mBAAmB,EAAE,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;gBAC1H,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBAC/B,MAAM,CAAC,OAAO,CAAC,mCAAmC,EAAE,EAAE,kBAAkB,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,CAAC,CAAC;oBACjG,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,kBAAkB,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC5F,CAAC;gBACD,MAAM,EAAE,GAAG,IAAI,CAAC,QAA2C,CAAC;gBAC5D,MAAM,KAAK,GAAmB,EAAE,CAAC;gBACjC,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAU,CAAC;gBAC3C,KAAK,MAAM,GAAG,IAAI,aAAa,EAAE,CAAC;oBAChC,KAAK,MAAM,CAAC,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;wBAC3B,IAAI,CAAC,CAAC,MAAM;4BAAE,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;oBAC/C,CAAC;gBACH,CAAC;gBAED,MAAM,WAAW,GAAG,MAAM,OAAO,CAAC,GAAG,CACnC,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;oBAChD,IAAI,CAAC;wBACH,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;wBACjD,OAAO,CAAC,MAAM,EAAE,IAAI,IAAI,IAAI,CAAU,CAAC;oBACzC,CAAC;oBAAC,MAAM,CAAC;wBACP,OAAO,CAAC,MAAM,EAAE,IAAI,CAAU,CAAC;oBACjC,CAAC;gBACH,CAAC,CAAC,CACH,CAAC;gBACF,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,CAAC;gBAErC,MAAM,WAAW,GAAG,IAAI,GAAG,CACzB,KAAK,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CACrD,CAAC;gBAEF,MAAM,iBAAiB,GAAqB,EAAE,CAAC;gBAE/C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,aAAa,CAAC,MAAM,EAAE,CAAC,IAAI,wBAAwB,EAAE,CAAC;oBACxE,MAAM,KAAK,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,wBAAwB,CAAC,CAAC;oBACnE,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,GAAG,CAClC,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE;wBACtC,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC;wBAClE,MAAM,WAAW,GAAG,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,CAAC,CAAC;wBAC9E,MAAM,UAAU,GAAG,WAAW,EAAE,IAAI,IAAI,OAAO,CAAC;wBAChD,MAAM,YAAY,GAAG,UAAU,KAAK,YAAY,CAAC;wBACjD,MAAM,mBAAmB,GAAG,YAAY,IAAI,WAAW,CAAC,MAAM,KAAK,SAAS,CAAC;wBAC7E,MAAM,cAAc,GAAG,2BAA2B,CAAC,WAAW,EAAE,KAAK,CAAC,MAAM,CAAC;+BACxE,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC;wBAC1F,MAAM,gBAAgB,GAAG,WAAW,CAAC,MAAM,CAAC,IAAI,CAC9C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC,IAAI,KAAK,YAAY,IAAI,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CACvF,CAAC;wBACF,MAAM,UAAU,GAAG,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC;wBAC3E,IAAI,UAAU,GAAG,CAAC,cAAc,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;4BACrE,CAAC,CAAC,cAAc;4BAChB,CAAC,CAAC,CAAC,gBAAgB,IAAI,cAAc,CAAC,CAAC;wBACzC,6JAA6J;wBAC7J,IAAI,CAAC,UAAU,IAAI,UAAU,IAAI,UAAU,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,IAAI,UAAU,CAAC,MAAM,EAAE,CAAC;4BACzF,UAAU,GAAG,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE,CAAC;wBACpE,CAAC;wBACD,MAAM,SAAS,GAAG,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;wBAC7E,MAAM,sBAAsB,GAAG,WAAW,CAAC,MAAM,CAAC,MAAM,CACtD,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC,IAAI,KAAK,YAAY,CAC5D,CAAC;wBACF,0EAA0E;wBAC1E,qEAAqE;wBACrE,MAAM,oBAAoB,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,sBAAsB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;wBACvF,MAAM,gBAAgB,GAAG,oBAAoB;6BAC1C,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,IAAI,IAAI,SAAS,CAAC;6BACjD,IAAI,EAAE,CAAC;wBACV,sFAAsF;wBACtF,4EAA4E;wBAC5E,4EAA4E;wBAC5E,mFAAmF;wBACnF,MAAM,mBAAmB,GAAG,YAAY,IAAI,oBAAoB,CAAC,MAAM,GAAG,CAAC,CAAC;wBAC5E,IAAI,QAAQ,GAAG,YAAY,IAAI,gBAAgB,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,mBAAmB;4BAChF,CAAC,CAAC,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC;4BAC9B,CAAC,CAAC,CAAC,SAAS,EAAE,IAAI,IAAI,SAAS,CAAC,CAAC;wBACnC,mHAAmH;wBACnH,IAAI,CAAC,QAAQ,KAAK,SAAS,IAAI,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,IAAI,UAAU,EAAE,MAAM,IAAI,EAAE,CAAC,UAAU,EAAE,CAAC;4BACzF,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;gCACnE,MAAM,CAAC,KAAK,CAAC,wCAAwC,EAAE,EAAE,gBAAgB,EAAE,UAAU,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;gCAC5G,OAAO,IAAI,CAAC;4BACd,CAAC,CAAC,CAAC;4BACH,MAAM,WAAW,GAAG,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;4BACpD,IAAI,WAAW;gCAAE,QAAQ,GAAG,WAAW,CAAC;wBAC1C,CAAC;wBACD,MAAM,UAAU,GAAG,SAAS,EAAE,MAAM,IAAI,IAAI,CAAC;wBAC7C,MAAM,gBAAgB,GACpB,CAAC,OAAO,WAAW,CAAC,cAAc,EAAE,SAAS,KAAK,QAAQ;4BACxD,CAAC,CAAC,WAAW,CAAC,cAAc,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,4BAA4B,CAAC;4BACzG,CAAC,CAAC,EAAE,CAAC,IAAI,yBAAyB,CAAC;wBAEvC,+FAA+F;wBAC/F,IAAI,eAAsF,CAAC;wBAC3F,IAAI,YAAY,IAAI,sBAAsB,CAAC,MAAM,GAAG,CAAC,IAAI,UAAU,EAAE,CAAC;4BACpE,MAAM,WAAW,GAAG,sBAAsB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,UAAU,CAAC,MAAM,CAAC,CAAC;4BACvF,IAAI,WAAW,EAAE,CAAC;gCAChB,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC;gCAC3D,eAAe,GAAG;oCAChB,IAAI,EAAE,UAAU,EAAE,IAAI,IAAI,SAAS;oCACnC,MAAM,EAAE,UAAU,EAAE,MAAM,IAAI,IAAI;oCAClC,MAAM,EAAE,WAAW,CAAC,MAAM;iCAC3B,CAAC;4BACJ,CAAC;wBACH,CAAC;wBAED,MAAM,kBAAkB,GAAG,SAAS,EAAE,OAAO,IAAI,KAAK,CAAC;wBACvD,MAAM,2BAA2B,GAAG,YAAY,IAAI,WAAW,CAAC,MAAM,KAAK,QAAQ,CAAC;wBACpF,MAAM,YAAY,GAAG,GAAiB,EAAE,CAAC,CAAC;4BACxC,aAAa,EAAE,WAAW,CAAC,EAAE;4BAC7B,MAAM,EAAE,UAAU,EAAE,MAAM,IAAI,EAAE;4BAChC,IAAI,EAAE,QAAQ;4BACd,MAAM,EAAE,UAAU;4BAClB,QAAQ,EAAE,gBAAgB,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC;4BACxC,GAAG,EAAE,YAAY;gCACf,CAAC,CAAC,CAAC,2BAA2B,CAAC,CAAC,CAAC,gDAAgD,CAAC,CAAC,CAAC,iDAAiD,CAAC;gCACtI,CAAC,CAAC,8CAA8C;4BAClD,kBAAkB,EAAE,qBAAqB,CAAC,UAAU,CAAC;4BACrD,oBAAoB,EAAE,sBAAsB;4BAC5C,kBAAkB,EAAE,YAAY,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,kBAAkB;4BACzE,YAAY,EAAE,YAAY;gCACxB,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE;gCAC9D,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,eAAe,EAAE;4BAC5C,UAAU;4BACV,OAAO,EAAE,kBAAkB;4BAC3B,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,eAAe,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;4BAC5D,UAAU,EAAE,SAAS;yBACtB,CAAC,CAAC;wBAEH,IAAI,CAAC;4BACH,MAAM,CAAC,GAAG,EAAE,kBAAkB,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;gCAClD,sBAAsB,CACpB,EAAE,EACF,WAAW,EACX,KAAK,CAAC,MAAM,EACZ,UAAU,EAAE,MAAM,CACnB;gCACD,sBAAsB,CAAC,EAAE,EAAE,WAAW,CAAC,EAAE,EAAE,WAAW,CAAC,MAAM,CAAC;6BAC/D,CAAC,CAAC;4BACH,MAAM,SAAS,GAAG;gCAChB,GAAG,GAAG;gCACN,iBAAiB,EAAE,SAAS;gCAC5B,iBAAiB,EAAE,WAAW,CAAC,MAAM;gCACrC,GAAG,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,kBAAkB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;6BACtD,CAAC;4BACF,MAAM,sBAAsB,GAAG,cAAc,CAAC,QAAQ,EAAE,EAAE,YAAY,CAAC;4BACvE,MAAM,cAAc,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;4BAClC,sBAAsB,EAAE,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,uBAAuB,EAAE,CAAC,CAAC;4BACjF,MAAM,YAAY,GAAG,MAAM,SAAS,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;4BAChE,MAAM,kBAAkB,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,cAAc,CAAC;4BACvD,iBAAiB,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,uBAAuB,EAAE,UAAU,EAAE,kBAAkB,EAAE,CAAC,CAAC;4BAC1F,sBAAsB,EAAE,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,uBAAuB,EAAE,UAAU,EAAE,kBAAkB,EAAE,OAAO,EAAE,cAAc,QAAQ,EAAE,EAAE,CAAC,CAAC;4BAClJ,IAAI,YAAiG,CAAC;4BACtG,8FAA8F;4BAC9F,8FAA8F;4BAC9F,MAAM,uBAAuB,GAAG,UAAU,IAAI,UAAU,IAAI,UAAU,CAAC,MAAM,KAAK,UAAU,CAAC,MAAM,CAAC;4BACpG,IAAI,UAAU,IAAI,UAAU,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,IAAI,CAAC,uBAAuB,EAAE,CAAC;gCACjF,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC;gCACzD,MAAM,YAAY,GAAG,SAAS,EAAE,IAAI,IAAI,SAAS,CAAC;gCAClD,YAAY,GAAG;oCACb,IAAI,EAAE,YAAY;oCAClB,IAAI,EAAE,wBAAwB,CAAC,YAAY,CAAC,cAAc,EAAE,YAAY,CAAC;oCACzE,MAAM,EAAE,SAAS,EAAE,MAAM,IAAI,IAAI;oCACjC,MAAM,EAAE,UAAU,CAAC,MAAM;iCAC1B,CAAC;4BACJ,CAAC;iCAAM,IAAI,UAAU,EAAE,MAAM,KAAK,KAAK,CAAC,MAAM,EAAE,CAAC;gCAC/C,YAAY,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,YAAY,CAAC,cAAc,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC;4BAC1F,CAAC;iCAAM,CAAC;gCACN,YAAY,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY,CAAC,cAAc,EAAE,CAAC;4BACtE,CAAC;4BACD,OAAO;gCACL,aAAa,EAAE,WAAW,CAAC,EAAE;gCAC7B,MAAM,EAAE,UAAU,EAAE,MAAM,IAAI,EAAE;gCAChC,IAAI,EAAE,QAAQ;gCACd,MAAM,EAAE,UAAU;gCAClB,QAAQ,EAAE,YAAY,CAAC,mBAAmB;gCAC1C,GAAG,EAAE,YAAY,CAAC,eAAe;gCACjC,QAAQ,EAAE,YAAY,CAAC,QAAQ;gCAC/B,kBAAkB,EAAE,qBAAqB,CAAC,UAAU,CAAC;gCACrD,oBAAoB,EAAE,sBAAsB;gCAC5C,kBAAkB,EAAE,YAAY,CAAC,kBAAkB;gCACnD,YAAY;gCACZ,UAAU;gCACV,OAAO,EAAE,kBAAkB;gCAC3B,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,eAAe,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gCAC5D,UAAU,EAAE,SAAS;6BACC,CAAC;wBAC3B,CAAC;wBAAC,OAAO,CAAC,EAAE,CAAC;4BACX,MAAM,CAAC,IAAI,CAAC,4CAA4C,EAAE,EAAE,aAAa,EAAE,WAAW,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;4BACvG,OAAO,YAAY,EAAE,CAAC;wBACxB,CAAC;oBACH,CAAC,CAAC,CACH,CAAC;oBACF,KAAK,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,CAAC;gBAC5B,CAAC;gBACD,MAAM,CAAC,OAAO,CAAC,mCAAmC,EAAE,EAAE,kBAAkB,EAAE,KAAK,CAAC,aAAa,CAAC,MAAM,EAAE,aAAa,EAAE,CAAC,EAAE,CAAC,CAAC;gBAC1H,OAAO;oBACL,KAAK;oBACL,YAAY,EAAE,iBAAiB;oBAC/B,IAAI,EAAE,EAAE,kBAAkB,EAAE,KAAK,CAAC,aAAa,CAAC,MAAM,EAAE,aAAa,EAAE,CAAC,EAAE;iBAC3E,CAAC;YACF,CAAC,CAAC,CAAC;QACL,CAAC,CAAC;QAEF,MAAM,yBAAyB,GAAG,KAAK,EAAE,KAAkC,EAAE,EAAE;YAC7E,OAAO,KAAK,CAAC,iCAAiC,EAAE,KAAK,IAAI,EAAE;gBACzD,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,aAAa,EAAE,GAAG,KAAK,CAAC;gBAE5D,mDAAmD;gBACnD,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC;gBAC9E,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;gBAE7E,IAAI,CAAC;oBACH,MAAM,OAAO,CAAC,GAAG,CACf,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;wBACpB,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;wBAClD,0DAA0D;wBAC1D,IAAI,CAAC,MAAM,IAAI,MAAM,KAAK,aAAa;4BAAE,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;wBAClE,mEAAmE;wBACnE,yDAAyD;wBACzD,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS;4BAAE,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;wBACpE,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CACnB,aAAa,IAAI,CAAC,aAAa,IAAI,MAAM,IAAI,MAAM,EAAE,EACrD,IAAI,EACJ,EAAE,GAAG,EAAE,cAAc,EAAE,CACxB,CAAC;oBACJ,CAAC,CAAC,CACH,CAAC;gBACJ,CAAC;gBAAC,OAAO,CAAC,EAAE,CAAC;oBACX,MAAM,CAAC,IAAI,CAAC,kEAAkE,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;gBAChG,CAAC;gBAED,yCAAyC;gBACzC,MAAM,QAAQ,GAAmB,CAAC,GAAG,KAAK,CAAC,CAAC;gBAC5C,KAAK,MAAM,CAAC,KAAK,EAAE,UAAU,CAAC,IAAI,WAAW,EAAE,CAAC;oBAC9C,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,KAAK,KAAK,CAAC,EAAE,CAAC;wBAClD,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;oBAC5B,CAAC;gBACH,CAAC;gBAED,sDAAsD;gBACtD,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC;gBAErD,MAAM,CAAC,OAAO,CAAC,mCAAmC,EAAE;oBAClD,WAAW,EAAE,QAAQ,CAAC,MAAM;oBAC5B,UAAU,EAAE,QAAQ,CAAC,MAAM;iBAC5B,CAAC,CAAC;gBAEH,OAAO;oBACL,KAAK,EAAE,QAAQ;oBACf,IAAI,EAAE,EAAE,kBAAkB,EAAE,KAAK,CAAC,aAAa,CAAC,MAAM,EAAE,aAAa,EAAE,CAAC,EAAE;iBAC3E,CAAC;YACJ,CAAC,CAAC,CAAC;QACL,CAAC,CAAC;QAEF,MAAM,yBAAyB,GAAG,KAAK,EAAE,KAAkC,EAAE,EAAE;YAC7E,OAAO,KAAK,CAAC,iCAAiC,EAAE,KAAK,IAAI,EAAE;gBACzD,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBAC7B,OAAO,EAAE,gBAAgB,EAAE,KAAK,EAAE,CAAC;gBACrC,CAAC;gBAED,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;oBAClB,MAAM,CAAC,OAAO,CAAC,gEAAgE,CAAC,CAAC;oBACjF,OAAO,EAAE,gBAAgB,EAAE,KAAK,EAAE,CAAC;gBACrC,CAAC;gBAED,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK;yBACvB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC;yBAC3B,IAAI,CAAC,GAAG,CAAC,CAAC;oBACb,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;oBAC5E,MAAM,GAAG,GAAG,mBAAmB,KAAK,CAAC,MAAM,IAAI,IAAI,EAAE,CAAC;oBAEtD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAwB,GAAG,CAAC,CAAC;oBAChE,IAAI,MAAM,EAAE,CAAC;wBACX,MAAM,CAAC,OAAO,CAAC,6CAA6C,CAAC,CAAC;wBAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,EAAE,gBAAgB,EAAE,IAAI,EAAE,CAAC;oBAC9D,CAAC;oBAED,MAAM,CAAC,OAAO,CAAC,8CAA8C,CAAC,CAAC;gBACjE,CAAC;gBAAC,OAAO,CAAC,EAAE,CAAC;oBACX,MAAM,CAAC,IAAI,CAAC,+DAA+D,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;gBAC7F,CAAC;gBACD,OAAO,EAAE,gBAAgB,EAAE,KAAK,EAAE,CAAC;YACrC,CAAC,CAAC,CAAC;QACL,CAAC,CAAC;QAEF,MAAM,gBAAgB,GAAG,CAAC,KAAkC,EAAU,EAAE;YACtE,IAAI,KAAK,CAAC,gBAAgB,EAAE,CAAC;gBAC3B,MAAM,CAAC,OAAO,CAAC,kDAAkD,CAAC,CAAC;gBACnE,OAAO,MAAM,CAAC;YAChB,CAAC;YACD,OAAO,YAAY,CAAC;QACtB,CAAC,CAAC;QAEF,MAAM,yBAAyB,GAAG,KAAK,EAAE,KAAkC,EAAE,EAAE;YAC7E,OAAO,KAAK,CAAC,iCAAiC,EAAE,KAAK,IAAI,EAAE;gBACzD,MAAM,CAAC,OAAO,CAAC,yCAAyC,EAAE,EAAE,WAAW,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;gBAC/F,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBAC7B,MAAM,CAAC,OAAO,CAAC,wCAAwC,EAAE,EAAE,qBAAqB,EAAE,CAAC,EAAE,CAAC,CAAC;oBACvF,OAAO,EAAE,gBAAgB,EAAE,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE,CAAC;gBACpD,CAAC;gBACD,MAAM,iBAAiB,GAAqB,EAAE,CAAC;gBAC/C,MAAM,gBAAgB,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;oBAC/C,KAAK,EAAE,CAAC,CAAC,UAAU;oBACnB,QAAQ,EAAE,CAAC,CAAC,QAAQ;oBACpB,QAAQ,EAAE,CAAC,CAAC,QAAQ;oBACpB,IAAI,EAAE,CAAC,CAAC,IAAI;oBACZ,UAAU,EAAE,CAAC,CAAC,UAAU,KAAK,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS;oBACpE,iBAAiB,EAAE,CAAC,CAAC,UAAU,KAAK,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS;iBACzE,CAAC,CAAC,CAAC;gBACJ,MAAM,wBAAwB,GAAG,cAAc,CAAC,QAAQ,EAAE,EAAE,YAAY,CAAC;gBACzE,MAAM,gBAAgB,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;gBACpC,wBAAwB,EAAE,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAAC,CAAC;gBAC9E,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,WAAW,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC;gBACpE,MAAM,oBAAoB,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,gBAAgB,CAAC;gBAC3D,iBAAiB,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,kBAAkB,EAAE,UAAU,EAAE,oBAAoB,EAAE,CAAC,CAAC;gBACvF,wBAAwB,EAAE,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,kBAAkB,EAAE,UAAU,EAAE,oBAAoB,EAAE,OAAO,EAAE,oBAAoB,QAAQ,CAAC,MAAM,aAAa,EAAE,CAAC,CAAC;gBACzK,MAAM,SAAS,GAA0B,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;oBAC5D,GAAG,CAAC;oBACJ,WAAW,EAAE,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC;iBAC3E,CAAC,CAAC,CAAC;gBACJ,MAAM,CAAC,OAAO,CAAC,wCAAwC,EAAE,EAAE,qBAAqB,EAAE,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC;gBACtG,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,YAAY,EAAE,iBAAiB,EAAE,CAAC;YAC1E,CAAC,CAAC,CAAC;QACL,CAAC,CAAC;QAEF,MAAM,2BAA2B,GAAG,KAAK,EAAE,KAAkC,EAAE,EAAE;YAC/E,OAAO,KAAK,CAAC,mCAAmC,EAAE,KAAK,IAAI,EAAE;gBAC3D,IAAI,KAAK,CAAC,gBAAgB,IAAI,KAAK,CAAC,gBAAgB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBAClE,OAAO,EAAE,CAAC;gBACZ,CAAC;gBAED,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK;yBACvB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC;yBAC3B,IAAI,CAAC,GAAG,CAAC,CAAC;oBACb,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;oBAC5E,MAAM,GAAG,GAAG,mBAAmB,KAAK,CAAC,MAAM,IAAI,IAAI,EAAE,CAAC;oBAEtD,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,gBAAgB,EAAE,EAAE,GAAG,EAAE,cAAc,EAAE,CAAC,CAAC;oBAE3E,MAAM,CAAC,OAAO,CAAC,4CAA4C,EAAE;wBAC3D,YAAY,EAAE,KAAK,CAAC,gBAAgB,CAAC,MAAM;qBAC5C,CAAC,CAAC;gBACL,CAAC;gBAAC,OAAO,CAAC,EAAE,CAAC;oBACX,MAAM,CAAC,IAAI,CAAC,oEAAoE,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;gBAClG,CAAC;gBAED,OAAO,EAAE,CAAC;YACZ,CAAC,CAAC,CAAC;QACL,CAAC,CAAC;QAEF,MAAM,oBAAoB,GAAG,KAAK,EAAE,KAAkC,EAAE,EAAE;YACxE,OAAO,KAAK,CAAC,4BAA4B,EAAE,KAAK,IAAI,EAAE;gBACpD,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;gBAC1B,MAAM,SAAS,GAAG,KAAK,CAAC,gBAAgB,CAAC;gBACzC,MAAM,CAAC,OAAO,CAAC,oCAAoC,EAAE,EAAE,WAAW,EAAE,KAAK,CAAC,MAAM,EAAE,eAAe,EAAE,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC;gBACvH,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBACvB,MAAM,CAAC,OAAO,CAAC,mCAAmC,EAAE,EAAE,kBAAkB,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,CAAC,CAAC;oBACjG,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,kBAAkB,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC7E,CAAC;gBACD,MAAM,WAAW,GAAG,IAAI,GAAG,EAAU,CAAC;gBACtC,MAAM,QAAQ,GAAkB,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;oBAClD,MAAM,QAAQ,GAAG,sBAAsB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;oBACpD,MAAM,KAAK,GAAsB,CAAC,CAAC,WAAW;yBAC3C,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;yBAChE,KAAK,CAAC,CAAC,EAAE,qBAAqB,CAAC;yBAC/B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;wBACT,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;wBACnB,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;wBACtB,MAAM,EAAE,UAAU,EAAE,GAAG,IAAI,EAAE,GAAG,IAAI,CAAC;wBACrC,OAAO,IAAI,CAAC;oBACd,CAAC,CAAC,CAAC;oBACL,OAAO;wBACL,EAAE,EAAE,CAAC,CAAC,EAAE;wBACR,KAAK,EAAE,CAAC,CAAC,KAAK;wBACd,QAAQ,EAAE,CAAC,CAAC,QAAQ;wBACpB,QAAQ;wBACR,KAAK;qBACN,CAAC;gBACJ,CAAC,CAAC,CAAC;gBAEH,mEAAmE;gBACnE,gEAAgE;gBAChE,2EAA2E;gBAC3E,MAAM,uBAAuB,GAAG,CAAC,OAAoB,EAAU,EAAE;oBAC/D,MAAM,aAAa,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,KAAK,YAAY,CAAC,CAAC;oBACrF,IAAI,aAAa;wBAAE,OAAO,CAAC,CAAC,CAAC,0CAA0C;oBACvE,MAAM,gBAAgB,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,KAAK,YAAY,CAAC,CAAC;oBACxF,IAAI,gBAAgB;wBAAE,OAAO,CAAC,CAAC,CAAC,oCAAoC;oBACpE,OAAO,CAAC,CAAC,CAAC,iCAAiC;gBAC7C,CAAC,CAAC;gBACF,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,uBAAuB,CAAC,CAAC,CAAC,GAAG,uBAAuB,CAAC,CAAC,CAAC,CAAC,CAAC;gBACjF,MAAM,IAAI,GAAG;oBACX,kBAAkB,EAAE,KAAK,CAAC,aAAa,CAAC,MAAM;oBAC9C,aAAa,EAAE,QAAQ,CAAC,MAAM;iBAC/B,CAAC;gBACF,MAAM,CAAC,OAAO,CAAC,mCAAmC,EAAE,EAAE,kBAAkB,EAAE,IAAI,CAAC,kBAAkB,EAAE,aAAa,EAAE,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC;gBACxI,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;YAC5B,CAAC,CAAC,CAAC;QACL,CAAC,CAAC;QAEF,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,cAAc,CAAC;aACzC,OAAO,CAAC,mBAAmB,EAAE,qBAAqB,CAAC;aACnD,OAAO,CAAC,qBAAqB,EAAE,uBAAuB,CAAC;aACvD,OAAO,CAAC,kBAAkB,EAAE,oBAAoB,CAAC;aACjD,OAAO,CAAC,uBAAuB,EAAE,yBAAyB,CAAC;aAC3D,OAAO,CAAC,uBAAuB,EAAE,yBAAyB,CAAC;aAC3D,OAAO,CAAC,uBAAuB,EAAE,yBAAyB,CAAC;aAC3D,OAAO,CAAC,yBAAyB,EAAE,2BAA2B,CAAC;aAC/D,OAAO,CAAC,kBAAkB,EAAE,oBAAoB,CAAC;aACjD,OAAO,CAAC,KAAK,EAAE,mBAAmB,CAAC;aACnC,OAAO,CAAC,mBAAmB,EAAE,qBAAqB,CAAC;aACnD,mBAAmB,CAAC,qBAAqB,EAAE,mBAAmB,EAAE;YAC/D,QAAQ,EAAE,kBAAkB;YAC5B,IAAI,EAAE,uBAAuB;SAC9B,CAAC;aACD,OAAO,CAAC,kBAAkB,EAAE,uBAAuB,CAAC;aACpD,OAAO,CAAC,uBAAuB,EAAE,uBAAuB,CAAC;aACzD,mBAAmB,CAAC,uBAAuB,EAAE,gBAAgB,EAAE;YAC9D,UAAU,EAAE,uBAAuB;YACnC,IAAI,EAAE,kBAAkB;SACzB,CAAC;aACD,OAAO,CAAC,uBAAuB,EAAE,yBAAyB,CAAC;aAC3D,OAAO,CAAC,yBAAyB,EAAE,kBAAkB,CAAC;aACtD,OAAO,CAAC,kBAAkB,EAAE,GAAG,CAAC,CAAC;QAEpC,OAAO,KAAK,CAAC,OAAO,EAAE,CAAC;IACzB,CAAC;CACF","sourcesContent":["/**\n * Home Graph: Build the opportunity home view with dynamic sections.\n *\n * Independent of ChatGraph. Flow:\n * loadOpportunities → checkPresenterCache → [generateCardText if misses] → cachePresenterResults\n * → checkCategorizerCache → [categorizeDynamically if miss] → cacheCategorizerResults → normalizeAndSort\n *\n * Uses OpportunityPresenter for card text and an LLM to categorize cards into dynamic sections\n * with titles and Lucide icon names. Caches presenter and categorizer results via OpportunityCache.\n */\n\nimport { createHash } from 'crypto';\n\nimport { StateGraph, START, END } from '@langchain/langgraph';\n\nimport type { HomeGraphDatabase, OpportunityStatus } from '../../shared/interfaces/database.interface.js';\nimport type { OpportunityCache } from '../../shared/interfaces/cache.interface.js';\nimport {\n HomeGraphState,\n type HomeCardItem,\n type HomeSection,\n type HomeSectionProposal,\n type HomeSectionItem,\n} from './feed.state.js';\nimport { OpportunityPresenter, gatherPresenterContext, type PresenterDatabase } from '../opportunity.presenter.js';\nimport { loadNegotiationContext } from '../negotiation-context.loader.js';\nimport { HomeCategorizerAgent } from './feed.categorizer.js';\nimport { canUserSeeOpportunity, isActionableForViewer, selectByComposition } from '../opportunity.utils.js';\nimport { resolveHomeSectionIcon, DEFAULT_HOME_SECTION_ICON } from '../../shared/ui/lucide.icon-catalog.js';\nimport { getPrimaryActionLabel, SECONDARY_ACTION_LABEL } from '../opportunity.labels.js';\nimport type { DebugMetaAgent } from '../../chat/chat-streaming.types.js';\nimport { protocolLogger } from '../../shared/observability/protocol.logger.js';\nimport { timed } from '../../shared/observability/performance.js';\nimport { requestContext } from \"../../shared/observability/request-context.js\";\n\nconst logger = protocolLogger('HomeGraph');\n\n/** Database must satisfy both HomeGraphDatabase and presenter context (getProfile, getActiveIntents, getNetwork, getUser). */\ntype HomeGraphDb = HomeGraphDatabase;\n\nexport type HomeGraphInvokeInput = {\n userId: string;\n networkId?: string;\n limit?: number;\n noCache?: boolean;\n /** When set, filter loaded opportunities to these lifecycle statuses. Defaults to `DEFAULT_HOME_STATUSES`. */\n statuses?: OpportunityStatus[];\n};\n\nexport type HomeGraphInvokeResult = {\n sections: HomeSection[];\n meta: { totalOpportunities: number; totalSections: number };\n error?: string;\n};\n\n/** Default home-feed statuses: the lifecycle stages a viewer can act on today. */\nexport const DEFAULT_HOME_STATUSES: OpportunityStatus[] = ['latent', 'pending'];\n\n// Exhaustive registry — keys must cover every OpportunityStatus union member.\n// Adding a new status to OpportunityStatus without adding a key here is a TS error,\n// which is the whole point: prevents ALL_OPPORTUNITY_STATUSES from silently drifting.\nconst OPPORTUNITY_STATUS_REGISTRY: Record<OpportunityStatus, true> = {\n latent: true,\n draft: true,\n negotiating: true,\n pending: true,\n stalled: true,\n accepted: true,\n rejected: true,\n expired: true,\n};\n\n/** Full status enumeration. Pass this to `HomeGraphInvokeInput.statuses` to restore pre-Issue-3 (unfiltered) behavior. */\nexport const ALL_OPPORTUNITY_STATUSES: OpportunityStatus[] = Object.keys(\n OPPORTUNITY_STATUS_REGISTRY,\n) as OpportunityStatus[];\n\nconst MAX_ITEMS_PER_SECTION = 20;\nconst PRESENTATION_CONCURRENCY = 50;\nconst MAX_REASONING_SNIPPET_LENGTH = 240;\nconst HOME_CACHE_TTL = 24 * 60 * 60; // 24 hours in seconds\n\n/**\n * Strip leading narrator name from remark when the UI already prepends \"Name: \" to the chip.\n * Avoids duplication like \"Yankı Ekin Yüksel: Yankı Ekin Yüksel introduced you two...\"\n * Repeats until no leading name (handles \"Name: Name rest\").\n */\nexport function stripLeadingNarratorName(remark: string, narratorName: string): string {\n let t = remark.trim();\n if (!t || !narratorName.trim()) return remark;\n const name = narratorName.trim();\n const nameLower = name.toLowerCase();\n for (;;) {\n const lower = t.toLowerCase();\n if (!lower.startsWith(nameLower)) break;\n const rest = t.slice(name.length).replace(/^\\s*[:,\\-–—]\\s*/i, '').trim();\n if (rest.length === 0 || rest === t) break;\n t = rest;\n }\n return t;\n}\n\n/** Normalize timestamp for sorting; returns numeric ms or 0 for invalid/missing. */\nconst safeParseDate = (value: unknown): number => {\n if (value == null) return 0;\n if (value instanceof Date) {\n const t = value.getTime();\n return Number.isFinite(t) ? t : 0;\n }\n if (typeof value === 'number' && Number.isFinite(value)) return value;\n if (typeof value === 'string') {\n const t = new Date(value).getTime();\n return Number.isFinite(t) ? t : 0;\n }\n return 0;\n};\n\n/** Confidence score for sorting (interpretation.confidence or opportunity.confidence). */\nconst getConfidence = (opp: typeof HomeGraphState.State['opportunities'][number]): number => {\n const fromInterp = opp.interpretation?.confidence;\n if (typeof fromInterp === 'number' && !Number.isNaN(fromInterp)) return fromInterp;\n if (typeof fromInterp === 'string') {\n const n = parseFloat(fromInterp);\n if (!Number.isNaN(n)) return n;\n }\n const fromRow = opp.confidence;\n if (typeof fromRow === 'number' && !Number.isNaN(fromRow)) return fromRow;\n if (typeof fromRow === 'string') {\n const n = parseFloat(fromRow);\n if (!Number.isNaN(n)) return n;\n }\n return 0;\n};\n\n/** Unique non-introducer, non-viewer userIds for an opportunity (actors can repeat). */\nconst getUniqueCounterpartUserIds = (\n opp: typeof HomeGraphState.State['opportunities'][number],\n viewerId: string\n): Set<string> => {\n const ids = new Set<string>();\n for (const a of opp.actors) {\n if (a.role !== 'introducer' && a.userId !== viewerId && a.userId) {\n ids.add(a.userId);\n }\n }\n return ids;\n};\n\nconst pickDisplayCounterpartActor = (\n opportunity: typeof HomeGraphState.State['opportunities'][number],\n viewerId: string\n): { userId: string; role: string } | null => {\n const candidates = opportunity.actors.filter(\n (actor) => actor.userId !== viewerId && actor.role !== 'introducer'\n );\n if (candidates.length === 0) {\n return null;\n }\n\n // Prefer direct counterpart roles when available, then stable sort by user id.\n const rolePriority = new Map<string, number>([\n ['patient', 0],\n ['party', 1],\n ['agent', 2],\n ['peer', 3],\n ]);\n\n const sorted = [...candidates].sort((a, b) => {\n const aPriority = rolePriority.get(a.role) ?? 99;\n const bPriority = rolePriority.get(b.role) ?? 99;\n if (aPriority !== bPriority) return aPriority - bPriority;\n return a.userId.localeCompare(b.userId);\n });\n return sorted[0] ?? null;\n};\n\nexport class HomeGraphFactory {\n constructor(private database: HomeGraphDb, private cache: OpportunityCache) {}\n\n createGraph() {\n const presenter = new OpportunityPresenter();\n const categorizer = new HomeCategorizerAgent();\n\n const loadOpportunitiesNode = async (state: typeof HomeGraphState.State) => {\n return timed(\"HomeGraph.loadOpportunities\", async () => {\n if (!state.userId) {\n return { error: 'userId is required' };\n }\n try {\n // Minimum of 50 ensures enough candidates across all feed categories\n // (connection, connector-flow, expired) for selectByComposition to fill\n // its soft targets, even after visibility filtering and dedup.\n const fetchLimit = Math.min(150, Math.max(50, state.limit * 3));\n const statuses = state.statuses ?? DEFAULT_HOME_STATUSES;\n const options: { limit?: number; networkId?: string; statuses?: OpportunityStatus[] } = {\n limit: fetchLimit,\n statuses,\n };\n if (state.networkId) options.networkId = state.networkId;\n // Do not pass conversationId: home view excludes draft opportunities (chat-only drafts).\n const raw = await this.database.getOpportunitiesForUser(state.userId, options);\n const visible = raw.filter((opp) =>\n canUserSeeOpportunity(opp.actors, opp.status, state.userId)\n );\n const visibleForFeed = visible.filter((opp) =>\n isActionableForViewer(opp.actors, opp.status, state.userId)\n );\n const sorted = [...visibleForFeed].sort((a, b) => {\n // Connections before connector-flow so dedup claims counterpart IDs\n // for direct connections first — prevents introducer cards from\n // shadowing a user's own connection opportunities.\n const aIsIntroducer = a.actors.some((ac) => ac.userId === state.userId && ac.role === 'introducer');\n const bIsIntroducer = b.actors.some((ac) => ac.userId === state.userId && ac.role === 'introducer');\n if (aIsIntroducer !== bIsIntroducer) return aIsIntroducer ? 1 : -1;\n const confA = getConfidence(a);\n const confB = getConfidence(b);\n if (confB !== confA) return confB - confA;\n const aTime = safeParseDate(a.updatedAt);\n const bTime = safeParseDate(b.updatedAt);\n return bTime - aTime;\n });\n const seenUserIds = new Set<string>();\n const deduped = sorted.filter((opp) => {\n const counterpartIds = getUniqueCounterpartUserIds(opp, state.userId);\n const hasOverlap = [...counterpartIds].some((id) => seenUserIds.has(id));\n if (hasOverlap) return false;\n for (const id of counterpartIds) seenUserIds.add(id);\n return true;\n });\n const opportunities = selectByComposition(deduped, state.userId);\n return { opportunities };\n } catch (e) {\n logger.error('HomeGraph loadOpportunities failed', { error: e });\n return { error: 'Failed to load opportunities', opportunities: [] };\n }\n });\n };\n\n const checkPresenterCacheNode = async (state: typeof HomeGraphState.State) => {\n return timed(\"HomeGraph.checkPresenterCache\", async () => {\n const { opportunities, userId } = state;\n if (opportunities.length === 0) {\n return { cachedCards: new Map(), uncachedOpportunities: [] };\n }\n\n if (state.noCache) {\n logger.verbose('[HomeGraph:checkPresenterCache] noCache=true, skipping cache');\n return { cachedCards: new Map(), uncachedOpportunities: opportunities };\n }\n\n try {\n // Negotiating cards are templated (no LLM call) and their text\n // depends on the live turn count, which changes between requests\n // without changing the opportunity status. Skip cache entirely\n // for them so each render reflects the current turn.\n //\n // For all other statuses, include status in the key so status\n // transitions (e.g. negotiating → pending) don't serve stale cards.\n const cacheable = opportunities.filter((opp) => opp.status !== 'negotiating');\n const liveNegotiating = opportunities.filter((opp) => opp.status === 'negotiating');\n\n const keys = cacheable.map(\n (opp) => `home:card:${opp.id}:${opp.status}:${userId}`\n );\n const results = keys.length > 0 ? await this.cache.mget<HomeCardItem>(keys) : [];\n\n const cachedCards = new Map<string, HomeCardItem>();\n const uncachedOpportunities: typeof opportunities = [...liveNegotiating];\n\n for (let i = 0; i < cacheable.length; i++) {\n const cached = results[i];\n if (cached) {\n const originalIndex = opportunities.indexOf(cacheable[i]);\n cachedCards.set(cacheable[i].id, { ...cached, _cardIndex: originalIndex });\n } else {\n uncachedOpportunities.push(cacheable[i]);\n }\n }\n\n logger.verbose('[HomeGraph:checkPresenterCache]', {\n total: opportunities.length,\n cacheHits: cachedCards.size,\n cacheMisses: uncachedOpportunities.length,\n });\n\n return { cachedCards, uncachedOpportunities };\n } catch (e) {\n logger.warn('[HomeGraph:checkPresenterCache] cache unavailable, skipping', { error: e });\n return { cachedCards: new Map(), uncachedOpportunities: opportunities };\n }\n });\n };\n\n const shouldGenerateCards = (state: typeof HomeGraphState.State): string => {\n if (state.uncachedOpportunities.length > 0) {\n return 'generate';\n }\n logger.verbose('[HomeGraph] All presenter results cached, skipping generation');\n return 'skip';\n };\n\n const generateCardTextNode = async (state: typeof HomeGraphState.State) => {\n return timed(\"HomeGraph.generateCardText\", async () => {\n const opportunities = state.uncachedOpportunities.length > 0\n ? state.uncachedOpportunities\n : state.opportunities;\n logger.verbose('[HomeGraph:generateCardText] entry', { opportunitiesLength: opportunities.length, userId: state.userId });\n if (opportunities.length === 0) {\n logger.verbose('[HomeGraph:generateCardText] exit', { totalOpportunities: 0, totalSections: 0 });\n return { cards: [], agentTimings: [], meta: { totalOpportunities: 0, totalSections: 0 } };\n }\n const db = this.database as PresenterDatabase & HomeGraphDb;\n const cards: HomeCardItem[] = [];\n const relevantActorIds = new Set<string>();\n for (const opp of opportunities) {\n for (const a of opp.actors) {\n if (a.userId) relevantActorIds.add(a.userId);\n }\n }\n\n const userEntries = await Promise.all(\n Array.from(relevantActorIds).map(async (userId) => {\n try {\n const user = await this.database.getUser(userId);\n return [userId, user ?? null] as const;\n } catch {\n return [userId, null] as const;\n }\n })\n );\n const userMap = new Map(userEntries);\n\n const oppIndexMap = new Map(\n state.opportunities.map((opp, idx) => [opp.id, idx])\n );\n\n const agentTimingsAccum: DebugMetaAgent[] = [];\n\n for (let i = 0; i < opportunities.length; i += PRESENTATION_CONCURRENCY) {\n const chunk = opportunities.slice(i, i + PRESENTATION_CONCURRENCY);\n const chunkCards = await Promise.all(\n chunk.map(async (opportunity, offset) => {\n const cardIndex = oppIndexMap.get(opportunity.id) ?? (i + offset);\n const viewerActor = opportunity.actors.find((a) => a.userId === state.userId);\n const viewerRole = viewerActor?.role ?? 'party';\n const isIntroducer = viewerRole === 'introducer';\n const isPendingIntroducer = isIntroducer && opportunity.status === 'pending';\n const preferredActor = pickDisplayCounterpartActor(opportunity, state.userId)\n ?? opportunity.actors.find((a) => a.userId !== state.userId && a.role !== 'introducer');\n const actorWithProfile = opportunity.actors.find(\n (a) => a.userId !== state.userId && a.role !== 'introducer' && !!userMap.get(a.userId)\n );\n const introducer = opportunity.actors.find((a) => a.role === 'introducer');\n let otherActor = (preferredActor && userMap.get(preferredActor.userId))\n ? preferredActor\n : (actorWithProfile ?? preferredActor);\n // When the only other participant is the introducer (no separate party), use introducer as display counterpart so the card shows a name instead of \"Unknown\"\n if (!otherActor && introducer && introducer.userId !== state.userId && introducer.userId) {\n otherActor = { userId: introducer.userId, role: introducer.role };\n }\n const otherUser = otherActor ? userMap.get(otherActor.userId) ?? null : null;\n const introducerCounterparts = opportunity.actors.filter(\n (a) => a.userId !== state.userId && a.role !== 'introducer'\n );\n // Deduplicate by userId — actors array can contain multiple rows per user\n // (e.g. from different intents), which would produce repeated names.\n const uniqueCounterpartIds = [...new Set(introducerCounterparts.map((a) => a.userId))];\n const participantNames = uniqueCounterpartIds\n .map((uid) => userMap.get(uid)?.name ?? 'Unknown')\n .sort();\n // When secondPartyData will be present (2+ counterparts), use single counterpart name\n // because the frontend arrow layout renders \"card.name → secondParty.name\".\n // Using the joined \"A ↔ B\" format here would produce redundant \"A ↔ B → B\".\n // Only use the joined format when there is a single counterpart (no arrow layout).\n const willHaveSecondParty = isIntroducer && uniqueCounterpartIds.length > 1;\n let userName = isIntroducer && participantNames.length > 0 && !willHaveSecondParty\n ? participantNames.join(' ↔ ')\n : (otherUser?.name ?? 'Unknown');\n // Fallback to profile identity name when users.name is missing (e.g. profile has display name, users row does not)\n if ((userName === 'Unknown' || !userName?.trim()) && otherActor?.userId && db.getProfile) {\n const profile = await db.getProfile(otherActor.userId).catch((err) => {\n logger.debug('[HomeGraph] getProfile fallback failed', { otherActorUserId: otherActor.userId, error: err });\n return null;\n });\n const profileName = profile?.identity?.name?.trim();\n if (profileName) userName = profileName;\n }\n const userAvatar = otherUser?.avatar ?? null;\n const reasoningSnippet =\n (typeof opportunity.interpretation?.reasoning === 'string'\n ? opportunity.interpretation.reasoning.replace(/\\s+/g, ' ').trim().slice(0, MAX_REASONING_SNIPPET_LENGTH)\n : '') || 'A promising connection.';\n\n // Build secondParty for introducer arrow layout (the party that isn't the display counterpart)\n let secondPartyData: { name: string; avatar?: string | null; userId?: string } | undefined;\n if (isIntroducer && introducerCounterparts.length > 1 && otherActor) {\n const secondActor = introducerCounterparts.find((a) => a.userId !== otherActor.userId);\n if (secondActor) {\n const secondUser = userMap.get(secondActor.userId) ?? null;\n secondPartyData = {\n name: secondUser?.name ?? 'Unknown',\n avatar: secondUser?.avatar ?? null,\n userId: secondActor.userId,\n };\n }\n }\n\n const isCounterpartGhost = otherUser?.isGhost ?? false;\n const isPendingIntroducerFallback = isIntroducer && opportunity.status !== 'latent';\n const fallbackCard = (): HomeCardItem => ({\n opportunityId: opportunity.id,\n userId: otherActor?.userId ?? '',\n name: userName,\n avatar: userAvatar,\n mainText: reasoningSnippet.slice(0, 300),\n cta: isIntroducer\n ? (isPendingIntroducerFallback ? 'Share this introduction to get things started.' : 'Take a look and decide if this is a good match.')\n : 'Take a look and decide whether to reach out.',\n primaryActionLabel: getPrimaryActionLabel(viewerRole),\n secondaryActionLabel: SECONDARY_ACTION_LABEL,\n mutualIntentsLabel: isIntroducer ? 'Connector match' : 'Shared interests',\n narratorChip: isIntroducer\n ? { name: 'You', text: 'Worth a look.', userId: state.userId }\n : { name: 'Index', text: 'Worth a look.' },\n viewerRole,\n isGhost: isCounterpartGhost,\n ...(secondPartyData ? { secondParty: secondPartyData } : {}),\n _cardIndex: cardIndex,\n });\n\n try {\n const [ctx, negotiationContext] = await Promise.all([\n gatherPresenterContext(\n db,\n opportunity,\n state.userId,\n otherActor?.userId,\n ),\n loadNegotiationContext(db, opportunity.id, opportunity.status),\n ]);\n const homeInput = {\n ...ctx,\n mutualIntentCount: undefined,\n opportunityStatus: opportunity.status,\n ...(negotiationContext ? { negotiationContext } : {}),\n };\n const _traceEmitterPresenter = requestContext.getStore()?.traceEmitter;\n const presenterStart = Date.now();\n _traceEmitterPresenter?.({ type: \"agent_start\", name: \"opportunity-presenter\" });\n const presentation = await presenter.presentHomeCard(homeInput);\n const _presenterDuration = Date.now() - presenterStart;\n agentTimingsAccum.push({ name: 'opportunity.presenter', durationMs: _presenterDuration });\n _traceEmitterPresenter?.({ type: \"agent_end\", name: \"opportunity-presenter\", durationMs: _presenterDuration, summary: `Presented: ${userName}` });\n let narratorChip: { name: string; text: string; avatar?: string | null; userId?: string } | undefined;\n // Only show a person as narrator when they are the introducer and not the display counterpart\n // (bad data can have same user as introducer and party, e.g. \"Amina introduced you to Amina\")\n const introducerIsCounterpart = introducer && otherActor && introducer.userId === otherActor.userId;\n if (introducer && introducer.userId !== state.userId && !introducerIsCounterpart) {\n const introUser = userMap.get(introducer.userId) ?? null;\n const narratorName = introUser?.name ?? 'Someone';\n narratorChip = {\n name: narratorName,\n text: stripLeadingNarratorName(presentation.narratorRemark, narratorName),\n avatar: introUser?.avatar ?? null,\n userId: introducer.userId,\n };\n } else if (introducer?.userId === state.userId) {\n narratorChip = { name: 'You', text: presentation.narratorRemark, userId: state.userId };\n } else {\n narratorChip = { name: 'Index', text: presentation.narratorRemark };\n }\n return {\n opportunityId: opportunity.id,\n userId: otherActor?.userId ?? '',\n name: userName,\n avatar: userAvatar,\n mainText: presentation.personalizedSummary,\n cta: presentation.suggestedAction,\n headline: presentation.headline,\n primaryActionLabel: getPrimaryActionLabel(viewerRole),\n secondaryActionLabel: SECONDARY_ACTION_LABEL,\n mutualIntentsLabel: presentation.mutualIntentsLabel,\n narratorChip,\n viewerRole,\n isGhost: isCounterpartGhost,\n ...(secondPartyData ? { secondParty: secondPartyData } : {}),\n _cardIndex: cardIndex,\n } satisfies HomeCardItem;\n } catch (e) {\n logger.warn('HomeGraph presenter failed for opportunity', { opportunityId: opportunity.id, error: e });\n return fallbackCard();\n }\n })\n );\n cards.push(...chunkCards);\n }\n logger.verbose('[HomeGraph:generateCardText] exit', { totalOpportunities: state.opportunities.length, totalSections: 0 });\n return {\n cards,\n agentTimings: agentTimingsAccum,\n meta: { totalOpportunities: state.opportunities.length, totalSections: 0 },\n };\n });\n };\n\n const cachePresenterResultsNode = async (state: typeof HomeGraphState.State) => {\n return timed(\"HomeGraph.cachePresenterResults\", async () => {\n const { cards, cachedCards, userId, opportunities } = state;\n\n // Only cache cards that weren't already from cache\n const newCards = cards.filter((card) => !cachedCards.has(card.opportunityId));\n const statusById = new Map(opportunities.map((opp) => [opp.id, opp.status]));\n\n try {\n await Promise.all(\n newCards.map((card) => {\n const status = statusById.get(card.opportunityId);\n // Skip persisting negotiating cards — see read-side note.\n if (!status || status === 'negotiating') return Promise.resolve();\n // Skip caching cards with unresolved names — transient DB failures\n // would persist \"Unknown\" placeholders for the full TTL.\n if (!card.name || card.name === 'Unknown') return Promise.resolve();\n return this.cache.set(\n `home:card:${card.opportunityId}:${status}:${userId}`,\n card,\n { ttl: HOME_CACHE_TTL }\n );\n })\n );\n } catch (e) {\n logger.warn('[HomeGraph:cachePresenterResults] cache write failed, continuing', { error: e });\n }\n\n // Merge cached cards into full card list\n const allCards: HomeCardItem[] = [...cards];\n for (const [oppId, cachedCard] of cachedCards) {\n if (!cards.some((c) => c.opportunityId === oppId)) {\n allCards.push(cachedCard);\n }\n }\n\n // Re-sort by _cardIndex to maintain original ordering\n allCards.sort((a, b) => a._cardIndex - b._cardIndex);\n\n logger.verbose('[HomeGraph:cachePresenterResults]', {\n newlyCached: newCards.length,\n totalCards: allCards.length,\n });\n\n return {\n cards: allCards,\n meta: { totalOpportunities: state.opportunities.length, totalSections: 0 },\n };\n });\n };\n\n const checkCategorizerCacheNode = async (state: typeof HomeGraphState.State) => {\n return timed(\"HomeGraph.checkCategorizerCache\", async () => {\n if (state.cards.length === 0) {\n return { categoryCacheHit: false };\n }\n\n if (state.noCache) {\n logger.verbose('[HomeGraph:checkCategorizerCache] noCache=true, skipping cache');\n return { categoryCacheHit: false };\n }\n\n try {\n const oppIds = state.cards\n .map((c) => c.opportunityId)\n .join(',');\n const hash = createHash('sha256').update(oppIds).digest('hex').slice(0, 16);\n const key = `home:categories:${state.userId}:${hash}`;\n\n const cached = await this.cache.get<HomeSectionProposal[]>(key);\n if (cached) {\n logger.verbose('[HomeGraph:checkCategorizerCache] cache hit');\n return { sectionProposals: cached, categoryCacheHit: true };\n }\n\n logger.verbose('[HomeGraph:checkCategorizerCache] cache miss');\n } catch (e) {\n logger.warn('[HomeGraph:checkCategorizerCache] cache unavailable, skipping', { error: e });\n }\n return { categoryCacheHit: false };\n });\n };\n\n const shouldCategorize = (state: typeof HomeGraphState.State): string => {\n if (state.categoryCacheHit) {\n logger.verbose('[HomeGraph] Categorizer results cached, skipping');\n return 'skip';\n }\n return 'categorize';\n };\n\n const categorizeDynamicallyNode = async (state: typeof HomeGraphState.State) => {\n return timed(\"HomeGraph.categorizeDynamically\", async () => {\n logger.verbose('[HomeGraph:categorizeDynamically] entry', { cardsLength: state.cards.length });\n if (state.cards.length === 0) {\n logger.verbose('[HomeGraph:categorizeDynamically] exit', { sectionProposalsCount: 0 });\n return { sectionProposals: [], agentTimings: [] };\n }\n const agentTimingsAccum: DebugMetaAgent[] = [];\n const categorizerInput = state.cards.map((c) => ({\n index: c._cardIndex,\n headline: c.headline,\n mainText: c.mainText,\n name: c.name,\n viewerRole: c.viewerRole === 'introducer' ? 'introducer' : undefined,\n opportunityStatus: c.viewerRole === 'introducer' ? 'pending' : undefined,\n }));\n const _traceEmitterCategorizer = requestContext.getStore()?.traceEmitter;\n const categorizerStart = Date.now();\n _traceEmitterCategorizer?.({ type: \"agent_start\", name: \"home-categorizer\" });\n const { sections } = await categorizer.categorize(categorizerInput);\n const _categorizerDuration = Date.now() - categorizerStart;\n agentTimingsAccum.push({ name: 'home.categorizer', durationMs: _categorizerDuration });\n _traceEmitterCategorizer?.({ type: \"agent_end\", name: \"home-categorizer\", durationMs: _categorizerDuration, summary: `Categorized into ${sections.length} section(s)` });\n const proposals: HomeSectionProposal[] = sections.map((s) => ({\n ...s,\n itemIndices: s.itemIndices.filter((i) => i >= 0 && i < state.cards.length),\n }));\n logger.verbose('[HomeGraph:categorizeDynamically] exit', { sectionProposalsCount: proposals.length });\n return { sectionProposals: proposals, agentTimings: agentTimingsAccum };\n });\n };\n\n const cacheCategorizerResultsNode = async (state: typeof HomeGraphState.State) => {\n return timed(\"HomeGraph.cacheCategorizerResults\", async () => {\n if (state.categoryCacheHit || state.sectionProposals.length === 0) {\n return {};\n }\n\n try {\n const oppIds = state.cards\n .map((c) => c.opportunityId)\n .join(',');\n const hash = createHash('sha256').update(oppIds).digest('hex').slice(0, 16);\n const key = `home:categories:${state.userId}:${hash}`;\n\n await this.cache.set(key, state.sectionProposals, { ttl: HOME_CACHE_TTL });\n\n logger.verbose('[HomeGraph:cacheCategorizerResults] cached', {\n sectionCount: state.sectionProposals.length,\n });\n } catch (e) {\n logger.warn('[HomeGraph:cacheCategorizerResults] cache write failed, continuing', { error: e });\n }\n\n return {};\n });\n };\n\n const normalizeAndSortNode = async (state: typeof HomeGraphState.State) => {\n return timed(\"HomeGraph.normalizeAndSort\", async () => {\n const cards = state.cards;\n const proposals = state.sectionProposals;\n logger.verbose('[HomeGraph:normalizeAndSort] entry', { cardsLength: cards.length, proposalsLength: proposals.length });\n if (cards.length === 0) {\n logger.verbose('[HomeGraph:normalizeAndSort] exit', { totalOpportunities: 0, totalSections: 0 });\n return { sections: [], meta: { totalOpportunities: 0, totalSections: 0 } };\n }\n const usedIndices = new Set<number>();\n const sections: HomeSection[] = proposals.map((p) => {\n const iconName = resolveHomeSectionIcon(p.iconName);\n const items: HomeSectionItem[] = p.itemIndices\n .filter((i) => i >= 0 && i < cards.length && !usedIndices.has(i))\n .slice(0, MAX_ITEMS_PER_SECTION)\n .map((i) => {\n usedIndices.add(i);\n const card = cards[i];\n const { _cardIndex, ...rest } = card;\n return rest;\n });\n return {\n id: p.id,\n title: p.title,\n subtitle: p.subtitle,\n iconName,\n items,\n };\n });\n\n // Enforce category ordering: sections with connections first, then\n // connector-flow only, then expired only. This prevents the LLM\n // categorizer from placing introducer sections before connection sections.\n const sectionCategoryPriority = (section: HomeSection): number => {\n const hasConnection = section.items.some((item) => item.viewerRole !== 'introducer');\n if (hasConnection) return 0; // mixed or connection-only sections first\n const hasConnectorFlow = section.items.some((item) => item.viewerRole === 'introducer');\n if (hasConnectorFlow) return 1; // connector-flow only sections next\n return 2; // empty or expired sections last\n };\n sections.sort((a, b) => sectionCategoryPriority(a) - sectionCategoryPriority(b));\n const meta = {\n totalOpportunities: state.opportunities.length,\n totalSections: sections.length,\n };\n logger.verbose('[HomeGraph:normalizeAndSort] exit', { totalOpportunities: meta.totalOpportunities, totalSections: meta.totalSections });\n return { sections, meta };\n });\n };\n\n const graph = new StateGraph(HomeGraphState)\n .addNode('loadOpportunities', loadOpportunitiesNode)\n .addNode('checkPresenterCache', checkPresenterCacheNode)\n .addNode('generateCardText', generateCardTextNode)\n .addNode('cachePresenterResults', cachePresenterResultsNode)\n .addNode('checkCategorizerCache', checkCategorizerCacheNode)\n .addNode('categorizeDynamically', categorizeDynamicallyNode)\n .addNode('cacheCategorizerResults', cacheCategorizerResultsNode)\n .addNode('normalizeAndSort', normalizeAndSortNode)\n .addEdge(START, 'loadOpportunities')\n .addEdge('loadOpportunities', 'checkPresenterCache')\n .addConditionalEdges('checkPresenterCache', shouldGenerateCards, {\n generate: 'generateCardText',\n skip: 'cachePresenterResults',\n })\n .addEdge('generateCardText', 'cachePresenterResults')\n .addEdge('cachePresenterResults', 'checkCategorizerCache')\n .addConditionalEdges('checkCategorizerCache', shouldCategorize, {\n categorize: 'categorizeDynamically',\n skip: 'normalizeAndSort',\n })\n .addEdge('categorizeDynamically', 'cacheCategorizerResults')\n .addEdge('cacheCategorizerResults', 'normalizeAndSort')\n .addEdge('normalizeAndSort', END);\n\n return graph.compile();\n }\n}\n"]}
1
+ {"version":3,"file":"feed.graph.js","sourceRoot":"/","sources":["opportunity/feed/feed.graph.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Home Graph: Build the opportunity home view with dynamic sections.\n *\n * Independent of ChatGraph. Flow:\n * loadOpportunities → checkPresenterCache → [generateCardText if misses] → cachePresenterResults\n * → checkCategorizerCache → [categorizeDynamically if miss] → cacheCategorizerResults → normalizeAndSort\n *\n * Uses OpportunityPresenter for card text and an LLM to categorize cards into dynamic sections\n * with titles and Lucide icon names. Caches presenter and categorizer results via OpportunityCache.\n */\n\nimport { createHash } from 'crypto';\n\nimport { StateGraph, START, END } from '@langchain/langgraph';\n\nimport type { HomeGraphDatabase, OpportunityStatus } from '../../shared/interfaces/database.interface.js';\nimport type { OpportunityCache } from '../../shared/interfaces/cache.interface.js';\nimport { HomeGraphState, type HomeCardItem, type HomeSection, type HomeSectionProposal, type HomeSectionItem } from './feed.state.js';\nimport { OpportunityPresenter, gatherPresenterContext, type PresenterDatabase } from '../opportunity.presenter.js';\nimport { loadNegotiationContext } from '../negotiation-context.loader.js';\nimport { HomeCategorizerAgent } from './feed.categorizer.js';\nimport { canUserSeeOpportunity, isActionableForViewer, selectByComposition } from '../opportunity.utils.js';\nimport { resolveHomeSectionIcon, DEFAULT_HOME_SECTION_ICON } from '../../shared/ui/lucide.icon-catalog.js';\nimport { getPrimaryActionLabel, SECONDARY_ACTION_LABEL } from '../opportunity.labels.js';\nimport type { DebugMetaAgent } from '../../chat/chat-streaming.types.js';\nimport { protocolLogger } from '../../shared/observability/protocol.logger.js';\nimport { timed } from '../../shared/observability/performance.js';\nimport { requestContext } from \"../../shared/observability/request-context.js\";\n\nconst logger = protocolLogger('HomeGraph');\n\n/** Database must satisfy both HomeGraphDatabase and presenter context (getProfile, getActiveIntents, getNetwork, getUser). */\ntype HomeGraphDb = HomeGraphDatabase;\n\nexport type HomeGraphInvokeInput = {\n userId: string;\n networkId?: string;\n limit?: number;\n noCache?: boolean;\n /** When set, filter loaded opportunities to these lifecycle statuses. Defaults to `DEFAULT_HOME_STATUSES`. */\n statuses?: OpportunityStatus[];\n};\n\nexport type HomeGraphInvokeResult = {\n sections: HomeSection[];\n meta: { totalOpportunities: number; totalSections: number };\n error?: string;\n};\n\n/** Default home-feed statuses: the lifecycle stages a viewer can act on today. */\nexport const DEFAULT_HOME_STATUSES: OpportunityStatus[] = ['latent', 'pending'];\n\n// Exhaustive registry — keys must cover every OpportunityStatus union member.\n// Adding a new status to OpportunityStatus without adding a key here is a TS error,\n// which is the whole point: prevents ALL_OPPORTUNITY_STATUSES from silently drifting.\nconst OPPORTUNITY_STATUS_REGISTRY: Record<OpportunityStatus, true> = {\n latent: true,\n draft: true,\n negotiating: true,\n pending: true,\n stalled: true,\n accepted: true,\n rejected: true,\n expired: true,\n};\n\n/** Full status enumeration. Pass this to `HomeGraphInvokeInput.statuses` to restore pre-Issue-3 (unfiltered) behavior. */\nexport const ALL_OPPORTUNITY_STATUSES: OpportunityStatus[] = Object.keys(\n OPPORTUNITY_STATUS_REGISTRY,\n) as OpportunityStatus[];\n\nconst MAX_ITEMS_PER_SECTION = 20;\nconst PRESENTATION_CONCURRENCY = 50;\nconst MAX_REASONING_SNIPPET_LENGTH = 240;\nconst HOME_CACHE_TTL = 24 * 60 * 60; // 24 hours in seconds\n\n/**\n * Strip leading narrator name from remark when the UI already prepends \"Name: \" to the chip.\n * Avoids duplication like \"Yankı Ekin Yüksel: Yankı Ekin Yüksel introduced you two...\"\n * Repeats until no leading name (handles \"Name: Name rest\").\n */\nexport function stripLeadingNarratorName(remark: string, narratorName: string): string {\n let t = remark.trim();\n if (!t || !narratorName.trim()) return remark;\n const name = narratorName.trim();\n const nameLower = name.toLowerCase();\n for (;;) {\n const lower = t.toLowerCase();\n if (!lower.startsWith(nameLower)) break;\n const rest = t.slice(name.length).replace(/^\\s*[:,\\-–—]\\s*/i, '').trim();\n if (rest.length === 0 || rest === t) break;\n t = rest;\n }\n return t;\n}\n\n/** Normalize timestamp for sorting; returns numeric ms or 0 for invalid/missing. */\nconst safeParseDate = (value: unknown): number => {\n if (value == null) return 0;\n if (value instanceof Date) {\n const t = value.getTime();\n return Number.isFinite(t) ? t : 0;\n }\n if (typeof value === 'number' && Number.isFinite(value)) return value;\n if (typeof value === 'string') {\n const t = new Date(value).getTime();\n return Number.isFinite(t) ? t : 0;\n }\n return 0;\n};\n\n/** Confidence score for sorting (interpretation.confidence or opportunity.confidence). */\nconst getConfidence = (opp: typeof HomeGraphState.State['opportunities'][number]): number => {\n const fromInterp = opp.interpretation?.confidence;\n if (typeof fromInterp === 'number' && !Number.isNaN(fromInterp)) return fromInterp;\n if (typeof fromInterp === 'string') {\n const n = parseFloat(fromInterp);\n if (!Number.isNaN(n)) return n;\n }\n const fromRow = opp.confidence;\n if (typeof fromRow === 'number' && !Number.isNaN(fromRow)) return fromRow;\n if (typeof fromRow === 'string') {\n const n = parseFloat(fromRow);\n if (!Number.isNaN(n)) return n;\n }\n return 0;\n};\n\n/** Unique non-introducer, non-viewer userIds for an opportunity (actors can repeat). */\nconst getUniqueCounterpartUserIds = (\n opp: typeof HomeGraphState.State['opportunities'][number],\n viewerId: string\n): Set<string> => {\n const ids = new Set<string>();\n for (const a of opp.actors) {\n if (a.role !== 'introducer' && a.userId !== viewerId && a.userId) {\n ids.add(a.userId);\n }\n }\n return ids;\n};\n\nconst pickDisplayCounterpartActor = (\n opportunity: typeof HomeGraphState.State['opportunities'][number],\n viewerId: string\n): { userId: string; role: string } | null => {\n const candidates = opportunity.actors.filter(\n (actor) => actor.userId !== viewerId && actor.role !== 'introducer'\n );\n if (candidates.length === 0) {\n return null;\n }\n\n // Prefer direct counterpart roles when available, then stable sort by user id.\n const rolePriority = new Map<string, number>([\n ['patient', 0],\n ['party', 1],\n ['agent', 2],\n ['peer', 3],\n ]);\n\n const sorted = [...candidates].sort((a, b) => {\n const aPriority = rolePriority.get(a.role) ?? 99;\n const bPriority = rolePriority.get(b.role) ?? 99;\n if (aPriority !== bPriority) return aPriority - bPriority;\n return a.userId.localeCompare(b.userId);\n });\n return sorted[0] ?? null;\n};\n\nexport class HomeGraphFactory {\n constructor(private database: HomeGraphDb, private cache: OpportunityCache) {}\n\n createGraph() {\n const presenter = new OpportunityPresenter();\n const categorizer = new HomeCategorizerAgent();\n\n const loadOpportunitiesNode = async (state: typeof HomeGraphState.State) => {\n return timed(\"HomeGraph.loadOpportunities\", async () => {\n if (!state.userId) {\n return { error: 'userId is required' };\n }\n try {\n // Minimum of 50 ensures enough candidates across all feed categories\n // (connection, connector-flow, expired) for selectByComposition to fill\n // its soft targets, even after visibility filtering and dedup.\n const fetchLimit = Math.min(150, Math.max(50, state.limit * 3));\n const statuses = state.statuses ?? DEFAULT_HOME_STATUSES;\n const options: { limit?: number; networkId?: string; statuses?: OpportunityStatus[] } = {\n limit: fetchLimit,\n statuses,\n };\n if (state.networkId) options.networkId = state.networkId;\n // Do not pass conversationId: home view excludes draft opportunities (chat-only drafts).\n const raw = await this.database.getOpportunitiesForUser(state.userId, options);\n const visible = raw.filter((opp) =>\n canUserSeeOpportunity(opp.actors, opp.status, state.userId)\n );\n const visibleForFeed = visible.filter((opp) =>\n isActionableForViewer(opp.actors, opp.status, state.userId)\n );\n const sorted = [...visibleForFeed].sort((a, b) => {\n // Connections before connector-flow so dedup claims counterpart IDs\n // for direct connections first — prevents introducer cards from\n // shadowing a user's own connection opportunities.\n const aIsIntroducer = a.actors.some((ac) => ac.userId === state.userId && ac.role === 'introducer');\n const bIsIntroducer = b.actors.some((ac) => ac.userId === state.userId && ac.role === 'introducer');\n if (aIsIntroducer !== bIsIntroducer) return aIsIntroducer ? 1 : -1;\n const confA = getConfidence(a);\n const confB = getConfidence(b);\n if (confB !== confA) return confB - confA;\n const aTime = safeParseDate(a.updatedAt);\n const bTime = safeParseDate(b.updatedAt);\n return bTime - aTime;\n });\n const seenUserIds = new Set<string>();\n const deduped = sorted.filter((opp) => {\n const counterpartIds = getUniqueCounterpartUserIds(opp, state.userId);\n const hasOverlap = [...counterpartIds].some((id) => seenUserIds.has(id));\n if (hasOverlap) return false;\n for (const id of counterpartIds) seenUserIds.add(id);\n return true;\n });\n const opportunities = selectByComposition(deduped, state.userId);\n return { opportunities };\n } catch (e) {\n logger.error('HomeGraph loadOpportunities failed', { error: e });\n return { error: 'Failed to load opportunities', opportunities: [] };\n }\n });\n };\n\n const checkPresenterCacheNode = async (state: typeof HomeGraphState.State) => {\n return timed(\"HomeGraph.checkPresenterCache\", async () => {\n const { opportunities, userId } = state;\n if (opportunities.length === 0) {\n return { cachedCards: new Map(), uncachedOpportunities: [] };\n }\n\n if (state.noCache) {\n logger.verbose('[HomeGraph:checkPresenterCache] noCache=true, skipping cache');\n return { cachedCards: new Map(), uncachedOpportunities: opportunities };\n }\n\n try {\n // Negotiating cards are templated (no LLM call) and their text\n // depends on the live turn count, which changes between requests\n // without changing the opportunity status. Skip cache entirely\n // for them so each render reflects the current turn.\n //\n // For all other statuses, include status in the key so status\n // transitions (e.g. negotiating → pending) don't serve stale cards.\n const cacheable = opportunities.filter((opp) => opp.status !== 'negotiating');\n const liveNegotiating = opportunities.filter((opp) => opp.status === 'negotiating');\n\n const keys = cacheable.map(\n (opp) => `home:card:${opp.id}:${opp.status}:${userId}`\n );\n const results = keys.length > 0 ? await this.cache.mget<HomeCardItem>(keys) : [];\n\n const cachedCards = new Map<string, HomeCardItem>();\n const uncachedOpportunities: typeof opportunities = [...liveNegotiating];\n\n for (let i = 0; i < cacheable.length; i++) {\n const cached = results[i];\n if (cached) {\n const originalIndex = opportunities.indexOf(cacheable[i]);\n cachedCards.set(cacheable[i].id, { ...cached, _cardIndex: originalIndex });\n } else {\n uncachedOpportunities.push(cacheable[i]);\n }\n }\n\n logger.verbose('[HomeGraph:checkPresenterCache]', {\n total: opportunities.length,\n cacheHits: cachedCards.size,\n cacheMisses: uncachedOpportunities.length,\n });\n\n return { cachedCards, uncachedOpportunities };\n } catch (e) {\n logger.warn('[HomeGraph:checkPresenterCache] cache unavailable, skipping', { error: e });\n return { cachedCards: new Map(), uncachedOpportunities: opportunities };\n }\n });\n };\n\n const shouldGenerateCards = (state: typeof HomeGraphState.State): string => {\n if (state.uncachedOpportunities.length > 0) {\n return 'generate';\n }\n logger.verbose('[HomeGraph] All presenter results cached, skipping generation');\n return 'skip';\n };\n\n const generateCardTextNode = async (state: typeof HomeGraphState.State) => {\n return timed(\"HomeGraph.generateCardText\", async () => {\n const opportunities = state.uncachedOpportunities.length > 0\n ? state.uncachedOpportunities\n : state.opportunities;\n logger.verbose('[HomeGraph:generateCardText] entry', { opportunitiesLength: opportunities.length, userId: state.userId });\n if (opportunities.length === 0) {\n logger.verbose('[HomeGraph:generateCardText] exit', { totalOpportunities: 0, totalSections: 0 });\n return { cards: [], agentTimings: [], meta: { totalOpportunities: 0, totalSections: 0 } };\n }\n const db = this.database as PresenterDatabase & HomeGraphDb;\n const cards: HomeCardItem[] = [];\n const relevantActorIds = new Set<string>();\n for (const opp of opportunities) {\n for (const a of opp.actors) {\n if (a.userId) relevantActorIds.add(a.userId);\n }\n }\n\n const userEntries = await Promise.all(\n Array.from(relevantActorIds).map(async (userId) => {\n try {\n const user = await this.database.getUser(userId);\n return [userId, user ?? null] as const;\n } catch {\n return [userId, null] as const;\n }\n })\n );\n const userMap = new Map(userEntries);\n\n const oppIndexMap = new Map(\n state.opportunities.map((opp, idx) => [opp.id, idx])\n );\n\n const agentTimingsAccum: DebugMetaAgent[] = [];\n\n for (let i = 0; i < opportunities.length; i += PRESENTATION_CONCURRENCY) {\n const chunk = opportunities.slice(i, i + PRESENTATION_CONCURRENCY);\n const chunkCards = await Promise.all(\n chunk.map(async (opportunity, offset) => {\n const cardIndex = oppIndexMap.get(opportunity.id) ?? (i + offset);\n const viewerActor = opportunity.actors.find((a) => a.userId === state.userId);\n const viewerRole = viewerActor?.role ?? 'party';\n const isIntroducer = viewerRole === 'introducer';\n const isPendingIntroducer = isIntroducer && opportunity.status === 'pending';\n const preferredActor = pickDisplayCounterpartActor(opportunity, state.userId)\n ?? opportunity.actors.find((a) => a.userId !== state.userId && a.role !== 'introducer');\n const actorWithProfile = opportunity.actors.find(\n (a) => a.userId !== state.userId && a.role !== 'introducer' && !!userMap.get(a.userId)\n );\n const introducer = opportunity.actors.find((a) => a.role === 'introducer');\n let otherActor = (preferredActor && userMap.get(preferredActor.userId))\n ? preferredActor\n : (actorWithProfile ?? preferredActor);\n // When the only other participant is the introducer (no separate party), use introducer as display counterpart so the card shows a name instead of \"Unknown\"\n if (!otherActor && introducer && introducer.userId !== state.userId && introducer.userId) {\n otherActor = { userId: introducer.userId, role: introducer.role };\n }\n const otherUser = otherActor ? userMap.get(otherActor.userId) ?? null : null;\n const introducerCounterparts = opportunity.actors.filter(\n (a) => a.userId !== state.userId && a.role !== 'introducer'\n );\n // Deduplicate by userId — actors array can contain multiple rows per user\n // (e.g. from different intents), which would produce repeated names.\n const uniqueCounterpartIds = [...new Set(introducerCounterparts.map((a) => a.userId))];\n const participantNames = uniqueCounterpartIds\n .map((uid) => userMap.get(uid)?.name ?? 'Unknown')\n .sort();\n // When secondPartyData will be present (2+ counterparts), use single counterpart name\n // because the frontend arrow layout renders \"card.name → secondParty.name\".\n // Using the joined \"A ↔ B\" format here would produce redundant \"A ↔ B → B\".\n // Only use the joined format when there is a single counterpart (no arrow layout).\n const willHaveSecondParty = isIntroducer && uniqueCounterpartIds.length > 1;\n let userName = isIntroducer && participantNames.length > 0 && !willHaveSecondParty\n ? participantNames.join(' ↔ ')\n : (otherUser?.name ?? 'Unknown');\n // Fallback to profile identity name when users.name is missing (e.g. profile has display name, users row does not)\n if ((userName === 'Unknown' || !userName?.trim()) && otherActor?.userId && db.getProfile) {\n const profile = await db.getProfile(otherActor.userId).catch((err) => {\n logger.debug('[HomeGraph] getProfile fallback failed', { otherActorUserId: otherActor.userId, error: err });\n return null;\n });\n const profileName = profile?.identity?.name?.trim();\n if (profileName) userName = profileName;\n }\n const userAvatar = otherUser?.avatar ?? null;\n const reasoningSnippet =\n (typeof opportunity.interpretation?.reasoning === 'string'\n ? opportunity.interpretation.reasoning.replace(/\\s+/g, ' ').trim().slice(0, MAX_REASONING_SNIPPET_LENGTH)\n : '') || 'A promising connection.';\n\n // Build secondParty for introducer arrow layout (the party that isn't the display counterpart)\n let secondPartyData: { name: string; avatar?: string | null; userId?: string } | undefined;\n if (isIntroducer && introducerCounterparts.length > 1 && otherActor) {\n const secondActor = introducerCounterparts.find((a) => a.userId !== otherActor.userId);\n if (secondActor) {\n const secondUser = userMap.get(secondActor.userId) ?? null;\n secondPartyData = {\n name: secondUser?.name ?? 'Unknown',\n avatar: secondUser?.avatar ?? null,\n userId: secondActor.userId,\n };\n }\n }\n\n const isCounterpartGhost = otherUser?.isGhost ?? false;\n const isPendingIntroducerFallback = isIntroducer && opportunity.status !== 'latent';\n const fallbackCard = (): HomeCardItem => ({\n opportunityId: opportunity.id,\n userId: otherActor?.userId ?? '',\n name: userName,\n avatar: userAvatar,\n mainText: reasoningSnippet.slice(0, 300),\n cta: isIntroducer\n ? (isPendingIntroducerFallback ? 'Share this introduction to get things started.' : 'Take a look and decide if this is a good match.')\n : 'Take a look and decide whether to reach out.',\n primaryActionLabel: getPrimaryActionLabel(viewerRole),\n secondaryActionLabel: SECONDARY_ACTION_LABEL,\n mutualIntentsLabel: isIntroducer ? 'Connector match' : 'Shared interests',\n narratorChip: isIntroducer\n ? { name: 'You', text: 'Worth a look.', userId: state.userId }\n : { name: 'Index', text: 'Worth a look.' },\n viewerRole,\n isGhost: isCounterpartGhost,\n ...(secondPartyData ? { secondParty: secondPartyData } : {}),\n _cardIndex: cardIndex,\n });\n\n try {\n const [ctx, negotiationContext] = await Promise.all([\n gatherPresenterContext(\n db,\n opportunity,\n state.userId,\n otherActor?.userId,\n ),\n loadNegotiationContext(db, opportunity.id, opportunity.status),\n ]);\n const homeInput = {\n ...ctx,\n mutualIntentCount: undefined,\n opportunityStatus: opportunity.status,\n ...(negotiationContext ? { negotiationContext } : {}),\n };\n const _traceEmitterPresenter = requestContext.getStore()?.traceEmitter;\n const presenterStart = Date.now();\n _traceEmitterPresenter?.({ type: \"agent_start\", name: \"opportunity-presenter\" });\n const presentation = await presenter.presentHomeCard(homeInput);\n const _presenterDuration = Date.now() - presenterStart;\n agentTimingsAccum.push({ name: 'opportunity.presenter', durationMs: _presenterDuration });\n _traceEmitterPresenter?.({ type: \"agent_end\", name: \"opportunity-presenter\", durationMs: _presenterDuration, summary: `Presented: ${userName}` });\n let narratorChip: { name: string; text: string; avatar?: string | null; userId?: string } | undefined;\n // Only show a person as narrator when they are the introducer and not the display counterpart\n // (bad data can have same user as introducer and party, e.g. \"Amina introduced you to Amina\")\n const introducerIsCounterpart = introducer && otherActor && introducer.userId === otherActor.userId;\n if (introducer && introducer.userId !== state.userId && !introducerIsCounterpart) {\n const introUser = userMap.get(introducer.userId) ?? null;\n const narratorName = introUser?.name ?? 'Someone';\n narratorChip = {\n name: narratorName,\n text: stripLeadingNarratorName(presentation.narratorRemark, narratorName),\n avatar: introUser?.avatar ?? null,\n userId: introducer.userId,\n };\n } else if (introducer?.userId === state.userId) {\n narratorChip = { name: 'You', text: presentation.narratorRemark, userId: state.userId };\n } else {\n narratorChip = { name: 'Index', text: presentation.narratorRemark };\n }\n return {\n opportunityId: opportunity.id,\n userId: otherActor?.userId ?? '',\n name: userName,\n avatar: userAvatar,\n mainText: presentation.personalizedSummary,\n cta: presentation.suggestedAction,\n headline: presentation.headline,\n primaryActionLabel: getPrimaryActionLabel(viewerRole),\n secondaryActionLabel: SECONDARY_ACTION_LABEL,\n mutualIntentsLabel: presentation.mutualIntentsLabel,\n narratorChip,\n viewerRole,\n isGhost: isCounterpartGhost,\n ...(secondPartyData ? { secondParty: secondPartyData } : {}),\n _cardIndex: cardIndex,\n } satisfies HomeCardItem;\n } catch (e) {\n logger.warn('HomeGraph presenter failed for opportunity', { opportunityId: opportunity.id, error: e });\n return fallbackCard();\n }\n })\n );\n cards.push(...chunkCards);\n }\n logger.verbose('[HomeGraph:generateCardText] exit', { totalOpportunities: state.opportunities.length, totalSections: 0 });\n return {\n cards,\n agentTimings: agentTimingsAccum,\n meta: { totalOpportunities: state.opportunities.length, totalSections: 0 },\n };\n });\n };\n\n const cachePresenterResultsNode = async (state: typeof HomeGraphState.State) => {\n return timed(\"HomeGraph.cachePresenterResults\", async () => {\n const { cards, cachedCards, userId, opportunities } = state;\n\n // Only cache cards that weren't already from cache\n const newCards = cards.filter((card) => !cachedCards.has(card.opportunityId));\n const statusById = new Map(opportunities.map((opp) => [opp.id, opp.status]));\n\n try {\n await Promise.all(\n newCards.map((card) => {\n const status = statusById.get(card.opportunityId);\n // Skip persisting negotiating cards — see read-side note.\n if (!status || status === 'negotiating') return Promise.resolve();\n // Skip caching cards with unresolved names — transient DB failures\n // would persist \"Unknown\" placeholders for the full TTL.\n if (!card.name || card.name === 'Unknown') return Promise.resolve();\n return this.cache.set(\n `home:card:${card.opportunityId}:${status}:${userId}`,\n card,\n { ttl: HOME_CACHE_TTL }\n );\n })\n );\n } catch (e) {\n logger.warn('[HomeGraph:cachePresenterResults] cache write failed, continuing', { error: e });\n }\n\n // Merge cached cards into full card list\n const allCards: HomeCardItem[] = [...cards];\n for (const [oppId, cachedCard] of cachedCards) {\n if (!cards.some((c) => c.opportunityId === oppId)) {\n allCards.push(cachedCard);\n }\n }\n\n // Re-sort by _cardIndex to maintain original ordering\n allCards.sort((a, b) => a._cardIndex - b._cardIndex);\n\n logger.verbose('[HomeGraph:cachePresenterResults]', {\n newlyCached: newCards.length,\n totalCards: allCards.length,\n });\n\n return {\n cards: allCards,\n meta: { totalOpportunities: state.opportunities.length, totalSections: 0 },\n };\n });\n };\n\n const checkCategorizerCacheNode = async (state: typeof HomeGraphState.State) => {\n return timed(\"HomeGraph.checkCategorizerCache\", async () => {\n if (state.cards.length === 0) {\n return { categoryCacheHit: false };\n }\n\n if (state.noCache) {\n logger.verbose('[HomeGraph:checkCategorizerCache] noCache=true, skipping cache');\n return { categoryCacheHit: false };\n }\n\n try {\n const oppIds = state.cards\n .map((c) => c.opportunityId)\n .join(',');\n const hash = createHash('sha256').update(oppIds).digest('hex').slice(0, 16);\n const key = `home:categories:${state.userId}:${hash}`;\n\n const cached = await this.cache.get<HomeSectionProposal[]>(key);\n if (cached) {\n logger.verbose('[HomeGraph:checkCategorizerCache] cache hit');\n return { sectionProposals: cached, categoryCacheHit: true };\n }\n\n logger.verbose('[HomeGraph:checkCategorizerCache] cache miss');\n } catch (e) {\n logger.warn('[HomeGraph:checkCategorizerCache] cache unavailable, skipping', { error: e });\n }\n return { categoryCacheHit: false };\n });\n };\n\n const shouldCategorize = (state: typeof HomeGraphState.State): string => {\n if (state.categoryCacheHit) {\n logger.verbose('[HomeGraph] Categorizer results cached, skipping');\n return 'skip';\n }\n return 'categorize';\n };\n\n const categorizeDynamicallyNode = async (state: typeof HomeGraphState.State) => {\n return timed(\"HomeGraph.categorizeDynamically\", async () => {\n logger.verbose('[HomeGraph:categorizeDynamically] entry', { cardsLength: state.cards.length });\n if (state.cards.length === 0) {\n logger.verbose('[HomeGraph:categorizeDynamically] exit', { sectionProposalsCount: 0 });\n return { sectionProposals: [], agentTimings: [] };\n }\n const agentTimingsAccum: DebugMetaAgent[] = [];\n const categorizerInput = state.cards.map((c) => ({\n index: c._cardIndex,\n headline: c.headline,\n mainText: c.mainText,\n name: c.name,\n viewerRole: c.viewerRole === 'introducer' ? 'introducer' : undefined,\n opportunityStatus: c.viewerRole === 'introducer' ? 'pending' : undefined,\n }));\n const _traceEmitterCategorizer = requestContext.getStore()?.traceEmitter;\n const categorizerStart = Date.now();\n _traceEmitterCategorizer?.({ type: \"agent_start\", name: \"home-categorizer\" });\n const { sections } = await categorizer.categorize(categorizerInput);\n const _categorizerDuration = Date.now() - categorizerStart;\n agentTimingsAccum.push({ name: 'home.categorizer', durationMs: _categorizerDuration });\n _traceEmitterCategorizer?.({ type: \"agent_end\", name: \"home-categorizer\", durationMs: _categorizerDuration, summary: `Categorized into ${sections.length} section(s)` });\n const proposals: HomeSectionProposal[] = sections.map((s) => ({\n ...s,\n itemIndices: s.itemIndices.filter((i) => i >= 0 && i < state.cards.length),\n }));\n logger.verbose('[HomeGraph:categorizeDynamically] exit', { sectionProposalsCount: proposals.length });\n return { sectionProposals: proposals, agentTimings: agentTimingsAccum };\n });\n };\n\n const cacheCategorizerResultsNode = async (state: typeof HomeGraphState.State) => {\n return timed(\"HomeGraph.cacheCategorizerResults\", async () => {\n if (state.categoryCacheHit || state.sectionProposals.length === 0) {\n return {};\n }\n\n try {\n const oppIds = state.cards\n .map((c) => c.opportunityId)\n .join(',');\n const hash = createHash('sha256').update(oppIds).digest('hex').slice(0, 16);\n const key = `home:categories:${state.userId}:${hash}`;\n\n await this.cache.set(key, state.sectionProposals, { ttl: HOME_CACHE_TTL });\n\n logger.verbose('[HomeGraph:cacheCategorizerResults] cached', {\n sectionCount: state.sectionProposals.length,\n });\n } catch (e) {\n logger.warn('[HomeGraph:cacheCategorizerResults] cache write failed, continuing', { error: e });\n }\n\n return {};\n });\n };\n\n const normalizeAndSortNode = async (state: typeof HomeGraphState.State) => {\n return timed(\"HomeGraph.normalizeAndSort\", async () => {\n const cards = state.cards;\n const proposals = state.sectionProposals;\n logger.verbose('[HomeGraph:normalizeAndSort] entry', { cardsLength: cards.length, proposalsLength: proposals.length });\n if (cards.length === 0) {\n logger.verbose('[HomeGraph:normalizeAndSort] exit', { totalOpportunities: 0, totalSections: 0 });\n return { sections: [], meta: { totalOpportunities: 0, totalSections: 0 } };\n }\n const usedIndices = new Set<number>();\n const sections: HomeSection[] = proposals.map((p) => {\n const iconName = resolveHomeSectionIcon(p.iconName);\n const items: HomeSectionItem[] = p.itemIndices\n .filter((i) => i >= 0 && i < cards.length && !usedIndices.has(i))\n .slice(0, MAX_ITEMS_PER_SECTION)\n .map((i) => {\n usedIndices.add(i);\n const card = cards[i];\n const { _cardIndex, ...rest } = card;\n return rest;\n });\n return {\n id: p.id,\n title: p.title,\n subtitle: p.subtitle,\n iconName,\n items,\n };\n });\n\n // Enforce category ordering: sections with connections first, then\n // connector-flow only, then expired only. This prevents the LLM\n // categorizer from placing introducer sections before connection sections.\n const sectionCategoryPriority = (section: HomeSection): number => {\n const hasConnection = section.items.some((item) => item.viewerRole !== 'introducer');\n if (hasConnection) return 0; // mixed or connection-only sections first\n const hasConnectorFlow = section.items.some((item) => item.viewerRole === 'introducer');\n if (hasConnectorFlow) return 1; // connector-flow only sections next\n return 2; // empty or expired sections last\n };\n sections.sort((a, b) => sectionCategoryPriority(a) - sectionCategoryPriority(b));\n const meta = {\n totalOpportunities: state.opportunities.length,\n totalSections: sections.length,\n };\n logger.verbose('[HomeGraph:normalizeAndSort] exit', { totalOpportunities: meta.totalOpportunities, totalSections: meta.totalSections });\n return { sections, meta };\n });\n };\n\n const graph = new StateGraph(HomeGraphState)\n .addNode('loadOpportunities', loadOpportunitiesNode)\n .addNode('checkPresenterCache', checkPresenterCacheNode)\n .addNode('generateCardText', generateCardTextNode)\n .addNode('cachePresenterResults', cachePresenterResultsNode)\n .addNode('checkCategorizerCache', checkCategorizerCacheNode)\n .addNode('categorizeDynamically', categorizeDynamicallyNode)\n .addNode('cacheCategorizerResults', cacheCategorizerResultsNode)\n .addNode('normalizeAndSort', normalizeAndSortNode)\n .addEdge(START, 'loadOpportunities')\n .addEdge('loadOpportunities', 'checkPresenterCache')\n .addConditionalEdges('checkPresenterCache', shouldGenerateCards, {\n generate: 'generateCardText',\n skip: 'cachePresenterResults',\n })\n .addEdge('generateCardText', 'cachePresenterResults')\n .addEdge('cachePresenterResults', 'checkCategorizerCache')\n .addConditionalEdges('checkCategorizerCache', shouldCategorize, {\n categorize: 'categorizeDynamically',\n skip: 'normalizeAndSort',\n })\n .addEdge('categorizeDynamically', 'cacheCategorizerResults')\n .addEdge('cacheCategorizerResults', 'normalizeAndSort')\n .addEdge('normalizeAndSort', END);\n\n return graph.compile();\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"negotiation-summary.builder.d.ts","sourceRoot":"/","sources":["opportunity/negotiation-summary.builder.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EACV,eAAe,EACf,kBAAkB,EACnB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,KAAK,EACV,oBAAoB,EAEpB,gBAAgB,EAGjB,MAAM,sBAAsB,CAAC;AAE9B;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACpC,eAAe,EAAE,MAAM,CAAC;IACxB,4EAA4E;IAC5E,gBAAgB,EAAE,MAAM,CAAC;IACzB,oDAAoD;IACpD,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,eAAe,EAAE,CAAC;IACzB,OAAO,EAAE,kBAAkB,CAAC;IAC5B,uDAAuD;IACvD,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,CAAC,EAAE,qBAAqB,GAAG,oBAAoB,CAyBrF;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,qBAAqB,EAAE,GAAG,gBAAgB,CA4B5F"}
1
+ {"version":3,"file":"negotiation-summary.builder.d.ts","sourceRoot":"/","sources":["opportunity/negotiation-summary.builder.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAC/F,OAAO,KAAK,EAAE,oBAAoB,EAAoB,gBAAgB,EAAkC,MAAM,sBAAsB,CAAC;AAErI;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACpC,eAAe,EAAE,MAAM,CAAC;IACxB,4EAA4E;IAC5E,gBAAgB,EAAE,MAAM,CAAC;IACzB,oDAAoD;IACpD,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,eAAe,EAAE,CAAC;IACzB,OAAO,EAAE,kBAAkB,CAAC;IAC5B,uDAAuD;IACvD,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,CAAC,EAAE,qBAAqB,GAAG,oBAAoB,CAyBrF;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,qBAAqB,EAAE,GAAG,gBAAgB,CA4B5F"}