@indexnetwork/protocol 4.3.4-rc.309.1 → 4.3.4-rc.311.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. package/IMPLEMENTATION.md +2 -2
  2. package/dist/chat/chat.agent.d.ts +1 -1
  3. package/dist/chat/chat.agent.js +1 -1
  4. package/dist/chat/chat.agent.js.map +1 -1
  5. package/dist/chat/chat.graph.d.ts +8 -8
  6. package/dist/chat/chat.prompt.js +30 -30
  7. package/dist/chat/chat.prompt.js.map +1 -1
  8. package/dist/chat/chat.prompt.modules.js +8 -8
  9. package/dist/chat/chat.prompt.modules.js.map +1 -1
  10. package/dist/chat/chat.state.d.ts +5 -4
  11. package/dist/chat/chat.state.d.ts.map +1 -1
  12. package/dist/chat/chat.state.js +2 -2
  13. package/dist/chat/chat.state.js.map +1 -1
  14. package/dist/chat/chat.streamer.d.ts +3 -2
  15. package/dist/chat/chat.streamer.d.ts.map +1 -1
  16. package/dist/chat/chat.streamer.js +2 -2
  17. package/dist/chat/chat.streamer.js.map +1 -1
  18. package/dist/chat/tests/chat.graph.mocks.d.ts +1 -1
  19. package/dist/chat/tests/chat.graph.mocks.js +1 -1
  20. package/dist/chat/tests/chat.graph.mocks.js.map +1 -1
  21. package/dist/contact/contact.tools.js +6 -6
  22. package/dist/contact/contact.tools.js.map +1 -1
  23. package/dist/enrichment/enrichment.tools.js +7 -7
  24. package/dist/enrichment/enrichment.tools.js.map +1 -1
  25. package/dist/integration/integration.tools.js +1 -1
  26. package/dist/integration/integration.tools.js.map +1 -1
  27. package/dist/intent/intent.graph.d.ts +5 -5
  28. package/dist/intent/intent.graph.d.ts.map +1 -1
  29. package/dist/intent/intent.graph.js +9 -9
  30. package/dist/intent/intent.graph.js.map +1 -1
  31. package/dist/intent/intent.indexer.d.ts +1 -1
  32. package/dist/intent/intent.indexer.js +4 -4
  33. package/dist/intent/intent.indexer.js.map +1 -1
  34. package/dist/intent/intent.state.d.ts +9 -8
  35. package/dist/intent/intent.state.d.ts.map +1 -1
  36. package/dist/intent/intent.state.js +7 -7
  37. package/dist/intent/intent.state.js.map +1 -1
  38. package/dist/intent/intent.tools.js +26 -26
  39. package/dist/intent/intent.tools.js.map +1 -1
  40. package/dist/maintenance/maintenance.graph.d.ts +2 -2
  41. package/dist/maintenance/maintenance.graph.d.ts.map +1 -1
  42. package/dist/maintenance/maintenance.graph.js.map +1 -1
  43. package/dist/mcp/mcp.server.d.ts +2 -2
  44. package/dist/mcp/mcp.server.js +4 -4
  45. package/dist/mcp/mcp.server.js.map +1 -1
  46. package/dist/network/indexer/indexer.graph.d.ts +2 -2
  47. package/dist/network/indexer/indexer.graph.d.ts.map +1 -1
  48. package/dist/network/indexer/indexer.graph.js +13 -13
  49. package/dist/network/indexer/indexer.graph.js.map +1 -1
  50. package/dist/network/indexer/indexer.state.d.ts +3 -3
  51. package/dist/network/indexer/indexer.state.d.ts.map +1 -1
  52. package/dist/network/indexer/indexer.state.js +4 -4
  53. package/dist/network/indexer/indexer.state.js.map +1 -1
  54. package/dist/network/membership/membership.graph.d.ts +1 -1
  55. package/dist/network/membership/membership.graph.js +21 -21
  56. package/dist/network/membership/membership.graph.js.map +1 -1
  57. package/dist/network/membership/membership.state.d.ts +2 -2
  58. package/dist/network/membership/membership.state.js +2 -2
  59. package/dist/network/membership/membership.state.js.map +1 -1
  60. package/dist/network/network.graph.d.ts +1 -1
  61. package/dist/network/network.graph.d.ts.map +1 -1
  62. package/dist/network/network.graph.js +13 -13
  63. package/dist/network/network.graph.js.map +1 -1
  64. package/dist/network/network.state.d.ts +3 -3
  65. package/dist/network/network.state.d.ts.map +1 -1
  66. package/dist/network/network.state.js +3 -3
  67. package/dist/network/network.state.js.map +1 -1
  68. package/dist/network/network.tools.d.ts.map +1 -1
  69. package/dist/network/network.tools.js +95 -107
  70. package/dist/network/network.tools.js.map +1 -1
  71. package/dist/opportunity/feed/feed.graph.d.ts +10 -0
  72. package/dist/opportunity/feed/feed.graph.d.ts.map +1 -1
  73. package/dist/opportunity/feed/feed.graph.js +4 -0
  74. package/dist/opportunity/feed/feed.graph.js.map +1 -1
  75. package/dist/opportunity/feed/feed.state.d.ts +2 -0
  76. package/dist/opportunity/feed/feed.state.d.ts.map +1 -1
  77. package/dist/opportunity/feed/feed.state.js +8 -0
  78. package/dist/opportunity/feed/feed.state.js.map +1 -1
  79. package/dist/opportunity/opportunity.discover.d.ts +1 -1
  80. package/dist/opportunity/opportunity.discover.d.ts.map +1 -1
  81. package/dist/opportunity/opportunity.discover.js +1 -1
  82. package/dist/opportunity/opportunity.discover.js.map +1 -1
  83. package/dist/opportunity/opportunity.graph.d.ts +6 -6
  84. package/dist/opportunity/opportunity.graph.js +10 -10
  85. package/dist/opportunity/opportunity.graph.js.map +1 -1
  86. package/dist/opportunity/opportunity.introducer.d.ts +3 -3
  87. package/dist/opportunity/opportunity.introducer.d.ts.map +1 -1
  88. package/dist/opportunity/opportunity.introducer.js +2 -2
  89. package/dist/opportunity/opportunity.introducer.js.map +1 -1
  90. package/dist/opportunity/opportunity.state.d.ts +2 -2
  91. package/dist/opportunity/opportunity.state.js +1 -1
  92. package/dist/opportunity/opportunity.state.js.map +1 -1
  93. package/dist/opportunity/opportunity.tools.d.ts.map +1 -1
  94. package/dist/opportunity/opportunity.tools.js +89 -22
  95. package/dist/opportunity/opportunity.tools.js.map +1 -1
  96. package/dist/premise/premise.graph.d.ts +4 -4
  97. package/dist/premise/premise.indexer.d.ts +1 -1
  98. package/dist/premise/premise.indexer.js +5 -5
  99. package/dist/premise/premise.indexer.js.map +1 -1
  100. package/dist/premise/premise.state.d.ts +2 -1
  101. package/dist/premise/premise.state.d.ts.map +1 -1
  102. package/dist/questioner/questioner.tools.d.ts.map +1 -1
  103. package/dist/questioner/questioner.tools.js +22 -9
  104. package/dist/questioner/questioner.tools.js.map +1 -1
  105. package/dist/shared/agent/tool.factory.d.ts +1 -1
  106. package/dist/shared/agent/tool.factory.js +1 -1
  107. package/dist/shared/agent/tool.factory.js.map +1 -1
  108. package/dist/shared/agent/tool.helpers.d.ts +14 -11
  109. package/dist/shared/agent/tool.helpers.d.ts.map +1 -1
  110. package/dist/shared/agent/tool.helpers.js +2 -2
  111. package/dist/shared/agent/tool.helpers.js.map +1 -1
  112. package/dist/shared/agent/tool.scope.d.ts +7 -1
  113. package/dist/shared/agent/tool.scope.d.ts.map +1 -1
  114. package/dist/shared/agent/tool.scope.js +11 -1
  115. package/dist/shared/agent/tool.scope.js.map +1 -1
  116. package/dist/shared/agent/utility.tools.js +20 -20
  117. package/dist/shared/agent/utility.tools.js.map +1 -1
  118. package/dist/shared/hyde/hyde.graph.d.ts +6 -6
  119. package/dist/shared/hyde/hyde.state.d.ts +2 -2
  120. package/dist/shared/interfaces/database.interface.d.ts +62 -59
  121. package/dist/shared/interfaces/database.interface.d.ts.map +1 -1
  122. package/dist/shared/interfaces/database.interface.js.map +1 -1
  123. package/dist/shared/interfaces/embedder.interface.d.ts +2 -2
  124. package/dist/shared/interfaces/embedder.interface.d.ts.map +1 -1
  125. package/dist/shared/interfaces/embedder.interface.js.map +1 -1
  126. package/dist/shared/interfaces/questioner.interface.d.ts +3 -0
  127. package/dist/shared/interfaces/questioner.interface.d.ts.map +1 -1
  128. package/dist/shared/interfaces/questioner.interface.js.map +1 -1
  129. package/dist/shared/schemas/network-assignment.schema.d.ts +2 -2
  130. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"intent.indexer.js","sourceRoot":"/","sources":["intent/intent.indexer.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ChatOpenAI } from \"@langchain/openai\";\nimport { HumanMessage, SystemMessage } from \"@langchain/core/messages\";\nimport { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport { log } from \"../shared/observability/log.js\";\nimport { Timed } from \"../shared/observability/performance.js\";\nimport { createModel } from \"../shared/agent/model.config.js\";\nimport { invokeWithAbortSignal } from \"../shared/agent/model-signal.js\";\n\n// ──────────────────────────────────────────────────────────────\n// Response schema\n// ──────────────────────────────────────────────────────────────\n\nexport const IntentIndexerOutputSchema = z.object({\n indexScore: z.number().min(0).max(1).describe(\"Score for index appropriateness (0.0-1.0)\"),\n memberScore: z.number().min(0).max(1).describe(\"Score for member preference match (0.0-1.0)\"),\n reasoning: z.string().describe(\"Brief reasoning for the scores\"),\n});\n\n/**\n * Output structure for the Intent Indexer agent.\n */\nexport type IntentIndexerOutput = z.infer<typeof IntentIndexerOutputSchema>;\n\nconst logger = log.lib.from(\"IntentIndexer\");\n\nconst model = createModel(\"intentIndexer\");\n\n// ──────────────────────────────────────────────────────────────\n// 1. SYSTEM PROMPT\n// ──────────────────────────────────────────────────────────────\n\nconst systemPrompt = `\nYou are an expert Intent Evaluator for a social networking protocol.\n\nTASK:\nDetermine if a User Intent is appropriate for a specific Index (community) and matches a Member's sharing preferences.\n\nINPUTS:\n1. Intent: The content/action the user wants to perform.\n2. Index Prompt: The purpose/scope of the target community (Index).\n3. Member Prompt: The specific sharing preferences of the user in that community (optional).\n4. Source: Origin of the intent (file, link, etc.) (optional).\n5. Network Context: Rendered context about the network including type, dates, location, and events (optional).\n\nNETWORK TYPE AWARENESS:\n- When Network Context is provided, use it to inform your scoring.\n- For EVENT networks: consider temporal relevance. An intent about \"meeting at the venue\" is highly relevant to an upcoming event but irrelevant after it ends. Intents about topics aligned with the event's themes should score higher.\n- For COMMUNITY networks: score based on the index prompt and member preferences as usual.\n- If the network context includes dates and the intent is time-sensitive, factor temporal proximity into the score.\n\nSCORING RUBRIC:\n- 0.9-1.0: Highly appropriate, perfect match.\n- 0.7-0.8: Good match, relevant.\n- 0.5-0.6: Moderate, borderline.\n- 0.3-0.4: Low appropriateness, poor fit.\n- 0.0-0.2: Not appropriate.\n\nOUTPUT RULES:\n- Provide \\`indexScore\\` based on how well the Intent fits the Index Prompt.\n- Provide \\`memberScore\\` based on how well the Intent fits the Member Prompt (if provided). If Member Prompt is missing/empty, return 0.0 for memberScore.\n- Provide concise \\`reasoning\\`.\n`;\n\n// ──────────────────────────────────────────────────────────────\n// 2. RESPONSE SCHEMA (Zod)\n// ──────────────────────────────────────────────────────────────\n\nconst responseFormat = IntentIndexerOutputSchema;\n\n// ──────────────────────────────────────────────────────────────\n// 3. TYPE DEFINITIONS\n// ──────────────────────────────────────────────────────────────\n\ntype ResponseType = z.infer<typeof responseFormat>;\n\n// ──────────────────────────────────────────────────────────────\n// 4. CLASS DEFINITION\n// ──────────────────────────────────────────────────────────────\n\nexport class IntentIndexer {\n private model: ReturnType<ChatOpenAI[\"withStructuredOutput\"]>;\n\n constructor() {\n this.model = model.withStructuredOutput(responseFormat, {\n name: \"intent_indexer\",\n });\n }\n\n /**\n * Converts the structured response into a string for logging or embedding.\n * Used when the output needs to be serialized (e.g. for traces).\n */\n private toString(output: ResponseType): string {\n return [\n `indexScore: ${output.indexScore}`,\n `memberScore: ${output.memberScore}`,\n `reasoning: ${output.reasoning}`,\n ].join(\"\\n\");\n }\n\n /**\n * Main entry point. Evaluates the appropriateness of an intent for a given index and member context.\n *\n * @param intent - The intent payload.\n * @param indexPrompt - The purpose of the index (community).\n * @param memberPrompt - The member's sharing preferences (optional).\n * @param sourceName - Optional source name for context (e.g. file, link).\n * @param networkContext - Optional rendered network context (type, dates, metadata).\n * @returns Structured output with indexScore, memberScore, and reasoning, or null on error.\n */\n @Timed()\n public async invoke(\n intent: string,\n indexPrompt: string | null,\n memberPrompt: string | null,\n sourceName?: string | null,\n networkContext?: string | null\n ): Promise<IntentIndexerOutput | null> {\n logger.verbose(\"[IntentIndexer.invoke] Evaluating intent\");\n\n const contextParts: string[] = [];\n if (sourceName) contextParts.push(`Source: ${sourceName}`);\n contextParts.push(indexPrompt ? `Index Purpose: ${indexPrompt}` : \"Index Purpose: (Not provided)\");\n contextParts.push(memberPrompt ? `Member Preferences: ${memberPrompt}` : \"Member Preferences: (Not provided)\");\n if (networkContext) contextParts.push(`Network Context:\\n${networkContext}`);\n\n const prompt = `\n # Context\n ${contextParts.join(\"\\n\")}\n\n # Intent\n ${intent}\n\n Evaluate the appropriateness of this intent.\n `;\n\n const messages = [\n new SystemMessage(systemPrompt),\n new HumanMessage(prompt),\n ];\n\n try {\n const result = await invokeWithAbortSignal(this.model, messages);\n const output = responseFormat.parse(result) as IntentIndexerOutput;\n\n logger.verbose(\"[IntentIndexer.invoke] Evaluation complete\", {\n indexScore: output.indexScore,\n memberScore: output.memberScore,\n });\n return output;\n } catch (error) {\n logger.error(\"[IntentIndexer] Error during execution\", { error });\n return null;\n }\n }\n\n /**\n * Alias for invoke. Evaluates the appropriateness of an intent for a given index and member context.\n * Kept for compatibility with callers (e.g. Index Graph) that use evaluate().\n */\n @Timed()\n public async evaluate(\n intent: string,\n indexPrompt: string | null,\n memberPrompt: string | null,\n sourceName?: string | null,\n networkContext?: string | null\n ): Promise<IntentIndexerOutput | null> {\n return this.invoke(intent, indexPrompt, memberPrompt, sourceName, networkContext);\n }\n\n /**\n * Factory method to expose the agent as a LangChain tool.\n * Useful for composing agents into larger graphs.\n */\n public static asTool() {\n return tool(\n async (args: {\n intent: string;\n indexPrompt: string | null;\n memberPrompt: string | null;\n sourceName?: string | null;\n networkContext?: string | null;\n }) => {\n const agent = new IntentIndexer();\n return await agent.invoke(\n args.intent,\n args.indexPrompt,\n args.memberPrompt,\n args.sourceName,\n args.networkContext\n );\n },\n {\n name: \"intent_indexer\",\n description:\n \"Evaluates whether an intent is appropriate for a specific index (community or event) and matches member sharing preferences.\",\n schema: z.object({\n intent: z.string().describe(\"The intent payload to evaluate\"),\n indexPrompt: z.string().nullable().describe(\"The purpose of the index (community)\"),\n memberPrompt: z.string().nullable().describe(\"The member's sharing preferences\"),\n sourceName: z.string().nullable().optional().describe(\"Optional source name for context\"),\n networkContext: z.string().nullable().optional().describe(\"Optional rendered network context (type, dates, metadata)\"),\n }),\n }\n );\n }\n}\n"]}
1
+ {"version":3,"file":"intent.indexer.js","sourceRoot":"/","sources":["intent/intent.indexer.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ChatOpenAI } from \"@langchain/openai\";\nimport { HumanMessage, SystemMessage } from \"@langchain/core/messages\";\nimport { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport { log } from \"../shared/observability/log.js\";\nimport { Timed } from \"../shared/observability/performance.js\";\nimport { createModel } from \"../shared/agent/model.config.js\";\nimport { invokeWithAbortSignal } from \"../shared/agent/model-signal.js\";\n\n// ──────────────────────────────────────────────────────────────\n// Response schema\n// ──────────────────────────────────────────────────────────────\n\nexport const IntentIndexerOutputSchema = z.object({\n indexScore: z.number().min(0).max(1).describe(\"Score for index appropriateness (0.0-1.0)\"),\n memberScore: z.number().min(0).max(1).describe(\"Score for member preference match (0.0-1.0)\"),\n reasoning: z.string().describe(\"Brief reasoning for the scores\"),\n});\n\n/**\n * Output structure for the Intent Indexer agent.\n */\nexport type IntentIndexerOutput = z.infer<typeof IntentIndexerOutputSchema>;\n\nconst logger = log.lib.from(\"IntentIndexer\");\n\nconst model = createModel(\"intentIndexer\");\n\n// ──────────────────────────────────────────────────────────────\n// 1. SYSTEM PROMPT\n// ──────────────────────────────────────────────────────────────\n\nconst systemPrompt = `\nYou are an expert Intent Evaluator for a social networking protocol.\n\nTASK:\nDetermine if a User Intent is appropriate for a specific Index (community) and matches a Member's sharing preferences.\n\nINPUTS:\n1. Intent: The content/action the user wants to perform.\n2. Network Prompt: The purpose/scope of the target community (Index).\n3. Member Prompt: The specific sharing preferences of the user in that community (optional).\n4. Source: Origin of the intent (file, link, etc.) (optional).\n5. Network Context: Rendered context about the network including type, dates, location, and events (optional).\n\nNETWORK TYPE AWARENESS:\n- When Network Context is provided, use it to inform your scoring.\n- For EVENT networks: consider temporal relevance. An intent about \"meeting at the venue\" is highly relevant to an upcoming event but irrelevant after it ends. Intents about topics aligned with the event's themes should score higher.\n- For COMMUNITY networks: score based on the network prompt and member preferences as usual.\n- If the network context includes dates and the intent is time-sensitive, factor temporal proximity into the score.\n\nSCORING RUBRIC:\n- 0.9-1.0: Highly appropriate, perfect match.\n- 0.7-0.8: Good match, relevant.\n- 0.5-0.6: Moderate, borderline.\n- 0.3-0.4: Low appropriateness, poor fit.\n- 0.0-0.2: Not appropriate.\n\nOUTPUT RULES:\n- Provide \\`indexScore\\` based on how well the Intent fits the Network Prompt.\n- Provide \\`memberScore\\` based on how well the Intent fits the Member Prompt (if provided). If Member Prompt is missing/empty, return 0.0 for memberScore.\n- Provide concise \\`reasoning\\`.\n`;\n\n// ──────────────────────────────────────────────────────────────\n// 2. RESPONSE SCHEMA (Zod)\n// ──────────────────────────────────────────────────────────────\n\nconst responseFormat = IntentIndexerOutputSchema;\n\n// ──────────────────────────────────────────────────────────────\n// 3. TYPE DEFINITIONS\n// ──────────────────────────────────────────────────────────────\n\ntype ResponseType = z.infer<typeof responseFormat>;\n\n// ──────────────────────────────────────────────────────────────\n// 4. CLASS DEFINITION\n// ──────────────────────────────────────────────────────────────\n\nexport class IntentIndexer {\n private model: ReturnType<ChatOpenAI[\"withStructuredOutput\"]>;\n\n constructor() {\n this.model = model.withStructuredOutput(responseFormat, {\n name: \"intent_indexer\",\n });\n }\n\n /**\n * Converts the structured response into a string for logging or embedding.\n * Used when the output needs to be serialized (e.g. for traces).\n */\n private toString(output: ResponseType): string {\n return [\n `indexScore: ${output.indexScore}`,\n `memberScore: ${output.memberScore}`,\n `reasoning: ${output.reasoning}`,\n ].join(\"\\n\");\n }\n\n /**\n * Main entry point. Evaluates the appropriateness of an intent for a given index and member context.\n *\n * @param intent - The intent payload.\n * @param indexPrompt - The purpose of the index (community).\n * @param memberPrompt - The member's sharing preferences (optional).\n * @param sourceName - Optional source name for context (e.g. file, link).\n * @param networkContext - Optional rendered network context (type, dates, metadata).\n * @returns Structured output with indexScore, memberScore, and reasoning, or null on error.\n */\n @Timed()\n public async invoke(\n intent: string,\n indexPrompt: string | null,\n memberPrompt: string | null,\n sourceName?: string | null,\n networkContext?: string | null\n ): Promise<IntentIndexerOutput | null> {\n logger.verbose(\"[IntentIndexer.invoke] Evaluating intent\");\n\n const contextParts: string[] = [];\n if (sourceName) contextParts.push(`Source: ${sourceName}`);\n contextParts.push(indexPrompt ? `Index Purpose: ${indexPrompt}` : \"Index Purpose: (Not provided)\");\n contextParts.push(memberPrompt ? `Member Preferences: ${memberPrompt}` : \"Member Preferences: (Not provided)\");\n if (networkContext) contextParts.push(`Network Context:\\n${networkContext}`);\n\n const prompt = `\n # Context\n ${contextParts.join(\"\\n\")}\n\n # Intent\n ${intent}\n\n Evaluate the appropriateness of this intent.\n `;\n\n const messages = [\n new SystemMessage(systemPrompt),\n new HumanMessage(prompt),\n ];\n\n try {\n const result = await invokeWithAbortSignal(this.model, messages);\n const output = responseFormat.parse(result) as IntentIndexerOutput;\n\n logger.verbose(\"[IntentIndexer.invoke] Evaluation complete\", {\n indexScore: output.indexScore,\n memberScore: output.memberScore,\n });\n return output;\n } catch (error) {\n logger.error(\"[IntentIndexer] Error during execution\", { error });\n return null;\n }\n }\n\n /**\n * Alias for invoke. Evaluates the appropriateness of an intent for a given index and member context.\n * Kept for compatibility with callers (e.g. Network Graph) that use evaluate().\n */\n @Timed()\n public async evaluate(\n intent: string,\n indexPrompt: string | null,\n memberPrompt: string | null,\n sourceName?: string | null,\n networkContext?: string | null\n ): Promise<IntentIndexerOutput | null> {\n return this.invoke(intent, indexPrompt, memberPrompt, sourceName, networkContext);\n }\n\n /**\n * Factory method to expose the agent as a LangChain tool.\n * Useful for composing agents into larger graphs.\n */\n public static asTool() {\n return tool(\n async (args: {\n intent: string;\n indexPrompt: string | null;\n memberPrompt: string | null;\n sourceName?: string | null;\n networkContext?: string | null;\n }) => {\n const agent = new IntentIndexer();\n return await agent.invoke(\n args.intent,\n args.indexPrompt,\n args.memberPrompt,\n args.sourceName,\n args.networkContext\n );\n },\n {\n name: \"intent_indexer\",\n description:\n \"Evaluates whether an intent is appropriate for a specific index (community or event) and matches member sharing preferences.\",\n schema: z.object({\n intent: z.string().describe(\"The intent payload to evaluate\"),\n indexPrompt: z.string().nullable().describe(\"The purpose of the index (community)\"),\n memberPrompt: z.string().nullable().describe(\"The member's sharing preferences\"),\n sourceName: z.string().nullable().optional().describe(\"Optional source name for context\"),\n networkContext: z.string().nullable().optional().describe(\"Optional rendered network context (type, dates, metadata)\"),\n }),\n }\n );\n }\n}\n"]}
@@ -2,6 +2,7 @@ import { BaseMessage } from "@langchain/core/messages";
2
2
  import { InferredIntent } from "./intent.inferrer.js";
3
3
  import { SemanticVerifierOutput } from "./intent.verifier.js";
4
4
  import type { DebugMetaAgent } from '../chat/chat-streaming.types.js';
5
+ import type { ToolScopeType } from '../shared/agent/tool.scope.js';
5
6
  /**
6
7
  * Extended InferredIntent that includes verification results.
7
8
  * We attach the verification output directly to the intent object
@@ -81,13 +82,13 @@ export declare const IntentGraphState: import("@langchain/langgraph").Annotation
81
82
  */
82
83
  targetIntentIds: import("@langchain/langgraph").BaseChannel<string[] | undefined, string[] | import("@langchain/langgraph").OverwriteValue<string[] | undefined> | undefined, unknown>;
83
84
  /**
84
- * Optional index scope (index ID). Used for linking created intents to an index
85
+ * Optional network scope (network ID). Used for linking created intents to a network
85
86
  * and for scoping read operations. Prep always fetches ALL user intents via
86
- * getActiveIntents(userId) regardless of index scope (for global dedup/reconciliation).
87
+ * getActiveIntents(userId) regardless of network scope (for global dedup/reconciliation).
87
88
  */
88
89
  networkId: import("@langchain/langgraph").BaseChannel<string | undefined, string | import("@langchain/langgraph").OverwriteValue<string | undefined> | undefined, unknown>;
89
90
  /** Focused request scope type for write-side assignment and follow-up queues. */
90
- scopeType: import("@langchain/langgraph").BaseChannel<"network" | undefined, "network" | import("@langchain/langgraph").OverwriteValue<"network" | undefined> | undefined, unknown>;
91
+ scopeType: import("@langchain/langgraph").BaseChannel<ToolScopeType | undefined, ToolScopeType | import("@langchain/langgraph").OverwriteValue<ToolScopeType | undefined> | undefined, unknown>;
91
92
  /** Focused request scope id. When scopeType is `network`, this is the focused network id. */
92
93
  scopeId: import("@langchain/langgraph").BaseChannel<string | undefined, string | import("@langchain/langgraph").OverwriteValue<string | undefined> | undefined, unknown>;
93
94
  /**
@@ -154,20 +155,20 @@ export declare const IntentGraphState: import("@langchain/langgraph").Annotation
154
155
  /** Timing records for each agent invocation within this graph run. */
155
156
  agentTimings: import("@langchain/langgraph").BaseChannel<DebugMetaAgent[], DebugMetaAgent[] | import("@langchain/langgraph").OverwriteValue<DebugMetaAgent[]>, unknown>;
156
157
  /**
157
- * For read mode: the set of index IDs the caller's agent can reach.
158
+ * For read mode: the set of network IDs the caller's agent can reach.
158
159
  * When set and neither networkId nor queryUserId is provided, the graph
159
- * returns the caller's own intents across all indexes in this set (scope-aware
160
+ * returns the caller's own intents across all networks in this set (scope-aware
160
161
  * default path). Derived by the tool layer from the scope envelope plus memberships.
161
162
  */
162
163
  indexScope: import("@langchain/langgraph").BaseChannel<string[] | undefined, string[] | import("@langchain/langgraph").OverwriteValue<string[] | undefined> | undefined, unknown>;
163
164
  /**
164
- * For read mode: filter intents by a specific user when reading in an index.
165
- * When omitted and index-scoped, returns all intents in the index.
165
+ * For read mode: filter intents by a specific user when reading in a network.
166
+ * When omitted and network-scoped, returns all intents in the network.
166
167
  */
167
168
  queryUserId: import("@langchain/langgraph").BaseChannel<string | undefined, string | import("@langchain/langgraph").OverwriteValue<string | undefined> | undefined, unknown>;
168
169
  /**
169
170
  * For read mode: when true, return all of the current user's intents
170
- * ignoring index scope. Used before create_intent to detect duplicates.
171
+ * ignoring network scope. Used before create_intent to detect duplicates.
171
172
  */
172
173
  allUserIntents: import("@langchain/langgraph").BaseChannel<boolean, boolean | import("@langchain/langgraph").OverwriteValue<boolean>, unknown>;
173
174
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"intent.state.d.ts","sourceRoot":"/","sources":["intent/intent.state.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAE9D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAGtE;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG,cAAc,GAAG;IAC5C,YAAY,CAAC,EAAE,sBAAsB,CAAC;IACtC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,wCAAwC;IACxC,UAAU,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAC3C,mCAAmC;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,+CAA+C;IAC/C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mDAAmD;IACnD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,8BAA8B;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,eAAO,MAAM,gBAAgB;IAG3B;;;OAGG;;;;;;IAGH;;OAEG;;;;;;IAGH;;;OAGG;;;;;;IAGH;;;;;OAKG;;IAMH;;;;;;;;;OASG;;IAMH;;;OAGG;;IAMH;;;;OAIG;;IAMH,iFAAiF;;IAMjF,6FAA6F;;IAQ7F;;;OAGG;;IAQH;;OAEG;;;;;;;;;;;;;;;;;IAMH;;;OAGG;;IAQH;;OAEG;;IAMH;;;OAGG;;IAQH;;;OAGG;;IAQH;;;;OAIG;;cAC6B,MAAM;iBAAW,MAAM;eAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;cAAvD,MAAM;iBAAW,MAAM;eAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;cAAvD,MAAM;iBAAW,MAAM;eAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;IAKvF,sEAAsE;;IAQtE;;;;;OAKG;;IAMH;;;OAGG;;IAMH;;;OAGG;;IAMH;;OAEG;;eAEM,MAAM;iBACJ,KAAK,CAAC;YACb,EAAE,EAAE,MAAM,CAAC;YACX,WAAW,EAAE,MAAM,CAAC;YACpB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;YACvB,SAAS,EAAE,IAAI,CAAC;YAChB,MAAM,CAAC,EAAE,MAAM,CAAC;YAChB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;SAC1B,CAAC;kBACQ,MAAM;oBACJ,MAAM;;eAVX,MAAM;iBACJ,KAAK,CAAC;YACb,EAAE,EAAE,MAAM,CAAC;YACX,WAAW,EAAE,MAAM,CAAC;YACpB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;YACvB,SAAS,EAAE,IAAI,CAAC;YAChB,MAAM,CAAC,EAAE,MAAM,CAAC;YAChB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;SAC1B,CAAC;kBACQ,MAAM;oBACJ,MAAM;;eAVX,MAAM;iBACJ,KAAK,CAAC;YACb,EAAE,EAAE,MAAM,CAAC;YACX,WAAW,EAAE,MAAM,CAAC;YACpB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;YACvB,SAAS,EAAE,IAAI,CAAC;YAChB,MAAM,CAAC,EAAE,MAAM,CAAC;YAChB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;SAC1B,CAAC;kBACQ,MAAM;oBACJ,MAAM;;EAKpB,CAAC"}
1
+ {"version":3,"file":"intent.state.d.ts","sourceRoot":"/","sources":["intent/intent.state.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAE9D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAEnE;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG,cAAc,GAAG;IAC5C,YAAY,CAAC,EAAE,sBAAsB,CAAC;IACtC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,wCAAwC;IACxC,UAAU,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAC3C,mCAAmC;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,+CAA+C;IAC/C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mDAAmD;IACnD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,8BAA8B;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,eAAO,MAAM,gBAAgB;IAG3B;;;OAGG;;;;;;IAGH;;OAEG;;;;;;IAGH;;;OAGG;;;;;;IAGH;;;;;OAKG;;IAMH;;;;;;;;;OASG;;IAMH;;;OAGG;;IAMH;;;;OAIG;;IAMH,iFAAiF;;IAMjF,6FAA6F;;IAQ7F;;;OAGG;;IAQH;;OAEG;;;;;;;;;;;;;;;;;IAMH;;;OAGG;;IAQH;;OAEG;;IAMH;;;OAGG;;IAQH;;;OAGG;;IAQH;;;;OAIG;;cAC6B,MAAM;iBAAW,MAAM;eAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;cAAvD,MAAM;iBAAW,MAAM;eAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;cAAvD,MAAM;iBAAW,MAAM;eAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;IAKvF,sEAAsE;;IAQtE;;;;;OAKG;;IAMH;;;OAGG;;IAMH;;;OAGG;;IAMH;;OAEG;;eAEM,MAAM;iBACJ,KAAK,CAAC;YACb,EAAE,EAAE,MAAM,CAAC;YACX,WAAW,EAAE,MAAM,CAAC;YACpB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;YACvB,SAAS,EAAE,IAAI,CAAC;YAChB,MAAM,CAAC,EAAE,MAAM,CAAC;YAChB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;SAC1B,CAAC;kBACQ,MAAM;oBACJ,MAAM;;eAVX,MAAM;iBACJ,KAAK,CAAC;YACb,EAAE,EAAE,MAAM,CAAC;YACX,WAAW,EAAE,MAAM,CAAC;YACpB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;YACvB,SAAS,EAAE,IAAI,CAAC;YAChB,MAAM,CAAC,EAAE,MAAM,CAAC;YAChB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;SAC1B,CAAC;kBACQ,MAAM;oBACJ,MAAM;;eAVX,MAAM;iBACJ,KAAK,CAAC;YACb,EAAE,EAAE,MAAM,CAAC;YACX,WAAW,EAAE,MAAM,CAAC;YACpB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;YACvB,SAAS,EAAE,IAAI,CAAC;YAChB,MAAM,CAAC,EAAE,MAAM,CAAC;YAChB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;SAC1B,CAAC;kBACQ,MAAM;oBACJ,MAAM;;EAKpB,CAAC"}
@@ -52,9 +52,9 @@ export const IntentGraphState = Annotation.Root({
52
52
  default: () => undefined,
53
53
  }),
54
54
  /**
55
- * Optional index scope (index ID). Used for linking created intents to an index
55
+ * Optional network scope (network ID). Used for linking created intents to a network
56
56
  * and for scoping read operations. Prep always fetches ALL user intents via
57
- * getActiveIntents(userId) regardless of index scope (for global dedup/reconciliation).
57
+ * getActiveIntents(userId) regardless of network scope (for global dedup/reconciliation).
58
58
  */
59
59
  networkId: Annotation({
60
60
  reducer: (curr, next) => next ?? curr,
@@ -137,9 +137,9 @@ export const IntentGraphState = Annotation.Root({
137
137
  }),
138
138
  // --- Read Mode Fields ---
139
139
  /**
140
- * For read mode: the set of index IDs the caller's agent can reach.
140
+ * For read mode: the set of network IDs the caller's agent can reach.
141
141
  * When set and neither networkId nor queryUserId is provided, the graph
142
- * returns the caller's own intents across all indexes in this set (scope-aware
142
+ * returns the caller's own intents across all networks in this set (scope-aware
143
143
  * default path). Derived by the tool layer from the scope envelope plus memberships.
144
144
  */
145
145
  indexScope: Annotation({
@@ -147,8 +147,8 @@ export const IntentGraphState = Annotation.Root({
147
147
  default: () => undefined,
148
148
  }),
149
149
  /**
150
- * For read mode: filter intents by a specific user when reading in an index.
151
- * When omitted and index-scoped, returns all intents in the index.
150
+ * For read mode: filter intents by a specific user when reading in a network.
151
+ * When omitted and network-scoped, returns all intents in the network.
152
152
  */
153
153
  queryUserId: Annotation({
154
154
  reducer: (curr, next) => next ?? curr,
@@ -156,7 +156,7 @@ export const IntentGraphState = Annotation.Root({
156
156
  }),
157
157
  /**
158
158
  * For read mode: when true, return all of the current user's intents
159
- * ignoring index scope. Used before create_intent to detect duplicates.
159
+ * ignoring network scope. Used before create_intent to detect duplicates.
160
160
  */
161
161
  allUserIntents: Annotation({
162
162
  reducer: (curr, next) => next ?? curr,
@@ -1 +1 @@
1
- {"version":3,"file":"intent.state.js","sourceRoot":"/","sources":["intent/intent.state.ts"],"names":[],"mappings":"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","sourcesContent":["import { Annotation } from \"@langchain/langgraph\";\nimport { BaseMessage } from \"@langchain/core/messages\";\nimport { InferredIntent } from \"./intent.inferrer.js\";\nimport { SemanticVerifierOutput } from \"./intent.verifier.js\";\nimport { IntentReconcilerOutput } from \"./intent.reconciler.js\";\nimport type { DebugMetaAgent } from '../chat/chat-streaming.types.js';\nimport type { ToolScopeType } from '../shared/agent/tool.scope.js';\n\n/**\n * Extended InferredIntent that includes verification results.\n * We attach the verification output directly to the intent object\n * as it flows through the graph.\n */\nexport type VerifiedIntent = InferredIntent & {\n verification?: SemanticVerifierOutput;\n score?: number; // Calculated min(authority, sincerity, clarity)\n};\n\n/**\n * Result of executing a single reconciler action.\n */\nexport interface ExecutionResult {\n /** The action type that was executed */\n actionType: 'create' | 'update' | 'expire';\n /** Whether the action succeeded */\n success: boolean;\n /** The intent ID (created/updated/archived) */\n intentId?: string;\n /** Final payload (sanitized, for create/update) */\n payload?: string;\n /** Error message if failed */\n error?: string;\n}\n\n/**\n * The Graph State using LangGraph Annotations.\n * This acts as the central bus for data flowing through our graph.\n */\nexport const IntentGraphState = Annotation.Root({\n // --- Inputs (Required at start) ---\n\n /**\n * The unique identifier of the user whose intents are being processed.\n * Required for database operations.\n */\n userId: Annotation<string>,\n\n /**\n * The user's profile context (Identity, Narrative, etc.)\n */\n userProfile: Annotation<string>,\n\n /**\n * Explicit input content (e.g., user message).\n * Optional - graph might run on implicit only.\n */\n inputContent: Annotation<string | undefined>,\n\n /**\n * Conversation history for context-aware intent inference.\n * Used to resolve anaphoric references (\"that intent\", \"this goal\").\n * Limited to recent messages (typically last 10) for token efficiency.\n * Optional - if not provided, intent inference uses only inputContent.\n */\n conversationContext: Annotation<BaseMessage[] | undefined>({\n reducer: (curr, next) => next ?? curr,\n default: () => undefined,\n }),\n\n /**\n * Operation mode controls graph flow and determines which nodes execute.\n * - 'create': Full pipeline (prep → inference → verification → reconciliation → execution)\n * - 'update': Skip verification if no new intents (prep → inference → reconciliation → execution)\n * - 'delete': Skip inference and verification (prep → reconciliation → execution)\n * - 'read': Fast path (prep → queryNode → END) — reads intents without LLM calls\n * - 'propose': Inference + verification only, stops before reconciliation (no DB writes)\n *\n * Defaults to 'create' for backward compatibility.\n */\n operationMode: Annotation<'create' | 'update' | 'delete' | 'read' | 'propose'>({\n reducer: (curr, next) => next ?? curr,\n default: () => 'create' as const,\n }),\n\n /**\n * For update/delete operations, specifies which intent IDs to target.\n * Optional - used when modifying or removing specific intents.\n */\n targetIntentIds: Annotation<string[] | undefined>({\n reducer: (curr, next) => next ?? curr,\n default: () => undefined,\n }),\n\n /**\n * Optional index scope (index ID). Used for linking created intents to an index\n * and for scoping read operations. Prep always fetches ALL user intents via\n * getActiveIntents(userId) regardless of index scope (for global dedup/reconciliation).\n */\n networkId: Annotation<string | undefined>({\n reducer: (curr, next) => next ?? curr,\n default: () => undefined,\n }),\n\n /** Focused request scope type for write-side assignment and follow-up queues. */\n scopeType: Annotation<ToolScopeType | undefined>({\n reducer: (curr, next) => next ?? curr,\n default: () => undefined,\n }),\n\n /** Focused request scope id. When scopeType is `network`, this is the focused network id. */\n scopeId: Annotation<string | undefined>({\n reducer: (curr, next) => next ?? curr,\n default: () => undefined,\n }),\n\n // --- Populated by Graph (Prep Node) ---\n\n /**\n * The formatted string of currently active intents.\n * Always populated by prep via getActiveIntents(userId).\n */\n activeIntents: Annotation<string>({\n reducer: (curr, next) => next,\n default: () => \"\",\n }),\n\n // --- Intermediate State ---\n\n /**\n * List of raw intents extracted from text.\n */\n inferredIntents: Annotation<InferredIntent[]>({\n reducer: (curr, next) => next, // Overwrite with new inference\n default: () => [],\n }),\n\n /**\n * List of intents that have passed semantic verification.\n * Invalid intents are filtered out before reaching this state.\n */\n verifiedIntents: Annotation<VerifiedIntent[]>({\n reducer: (curr, next) => next,\n default: () => [],\n }),\n\n // --- Output ---\n\n /**\n * Final actions to be performed on the DB (Create, Update, Expire).\n */\n actions: Annotation<IntentReconcilerOutput['actions']>({\n reducer: (curr, next) => next,\n default: () => [],\n }),\n\n /**\n * Results of executing actions against the database.\n * Populated by executorNode after actions are persisted.\n */\n executionResults: Annotation<ExecutionResult[]>({\n reducer: (curr, next) => next,\n default: () => [],\n }),\n\n // --- Error State ---\n\n /**\n * If set, indicates a fatal error that should short-circuit the graph to END.\n * Populated by prep when a precondition fails (e.g. missing profile).\n */\n error: Annotation<string | undefined>({\n reducer: (curr, next) => next ?? curr,\n default: () => undefined,\n }),\n\n // --- Trace Output ---\n\n /**\n * Accumulated trace entries from each graph node.\n * Used for observability: surfaces internal processing steps (inference,\n * verification with Felicity scores, reconciliation) to the frontend.\n */\n trace: Annotation<Array<{ node: string; detail?: string; data?: Record<string, unknown> }>>({\n reducer: (curr, next) => [...curr, ...(next || [])],\n default: () => [],\n }),\n\n /** Timing records for each agent invocation within this graph run. */\n agentTimings: Annotation<DebugMetaAgent[]>({\n reducer: (acc, val) => [...acc, ...val],\n default: () => [],\n }),\n\n // --- Read Mode Fields ---\n\n /**\n * For read mode: the set of index IDs the caller's agent can reach.\n * When set and neither networkId nor queryUserId is provided, the graph\n * returns the caller's own intents across all indexes in this set (scope-aware\n * default path). Derived by the tool layer from the scope envelope plus memberships.\n */\n indexScope: Annotation<string[] | undefined>({\n reducer: (_curr, next) => next,\n default: () => undefined,\n }),\n\n /**\n * For read mode: filter intents by a specific user when reading in an index.\n * When omitted and index-scoped, returns all intents in the index.\n */\n queryUserId: Annotation<string | undefined>({\n reducer: (curr, next) => next ?? curr,\n default: () => undefined,\n }),\n\n /**\n * For read mode: when true, return all of the current user's intents\n * ignoring index scope. Used before create_intent to detect duplicates.\n */\n allUserIntents: Annotation<boolean>({\n reducer: (curr, next) => next ?? curr,\n default: () => false,\n }),\n\n /**\n * Output of read mode: queried intents with count and optional metadata.\n */\n readResult: Annotation<{\n count: number;\n intents: Array<{\n id: string;\n description: string;\n summary: string | null;\n createdAt: Date;\n userId?: string;\n userName?: string | null;\n }>;\n message?: string;\n networkId?: string;\n } | undefined>({\n reducer: (curr, next) => next,\n default: () => undefined,\n }),\n});\n"]}
1
+ {"version":3,"file":"intent.state.js","sourceRoot":"/","sources":["intent/intent.state.ts"],"names":[],"mappings":"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","sourcesContent":["import { Annotation } from \"@langchain/langgraph\";\nimport { BaseMessage } from \"@langchain/core/messages\";\nimport { InferredIntent } from \"./intent.inferrer.js\";\nimport { SemanticVerifierOutput } from \"./intent.verifier.js\";\nimport { IntentReconcilerOutput } from \"./intent.reconciler.js\";\nimport type { DebugMetaAgent } from '../chat/chat-streaming.types.js';\nimport type { ToolScopeType } from '../shared/agent/tool.scope.js';\n\n/**\n * Extended InferredIntent that includes verification results.\n * We attach the verification output directly to the intent object\n * as it flows through the graph.\n */\nexport type VerifiedIntent = InferredIntent & {\n verification?: SemanticVerifierOutput;\n score?: number; // Calculated min(authority, sincerity, clarity)\n};\n\n/**\n * Result of executing a single reconciler action.\n */\nexport interface ExecutionResult {\n /** The action type that was executed */\n actionType: 'create' | 'update' | 'expire';\n /** Whether the action succeeded */\n success: boolean;\n /** The intent ID (created/updated/archived) */\n intentId?: string;\n /** Final payload (sanitized, for create/update) */\n payload?: string;\n /** Error message if failed */\n error?: string;\n}\n\n/**\n * The Graph State using LangGraph Annotations.\n * This acts as the central bus for data flowing through our graph.\n */\nexport const IntentGraphState = Annotation.Root({\n // --- Inputs (Required at start) ---\n\n /**\n * The unique identifier of the user whose intents are being processed.\n * Required for database operations.\n */\n userId: Annotation<string>,\n\n /**\n * The user's profile context (Identity, Narrative, etc.)\n */\n userProfile: Annotation<string>,\n\n /**\n * Explicit input content (e.g., user message).\n * Optional - graph might run on implicit only.\n */\n inputContent: Annotation<string | undefined>,\n\n /**\n * Conversation history for context-aware intent inference.\n * Used to resolve anaphoric references (\"that intent\", \"this goal\").\n * Limited to recent messages (typically last 10) for token efficiency.\n * Optional - if not provided, intent inference uses only inputContent.\n */\n conversationContext: Annotation<BaseMessage[] | undefined>({\n reducer: (curr, next) => next ?? curr,\n default: () => undefined,\n }),\n\n /**\n * Operation mode controls graph flow and determines which nodes execute.\n * - 'create': Full pipeline (prep → inference → verification → reconciliation → execution)\n * - 'update': Skip verification if no new intents (prep → inference → reconciliation → execution)\n * - 'delete': Skip inference and verification (prep → reconciliation → execution)\n * - 'read': Fast path (prep → queryNode → END) — reads intents without LLM calls\n * - 'propose': Inference + verification only, stops before reconciliation (no DB writes)\n *\n * Defaults to 'create' for backward compatibility.\n */\n operationMode: Annotation<'create' | 'update' | 'delete' | 'read' | 'propose'>({\n reducer: (curr, next) => next ?? curr,\n default: () => 'create' as const,\n }),\n\n /**\n * For update/delete operations, specifies which intent IDs to target.\n * Optional - used when modifying or removing specific intents.\n */\n targetIntentIds: Annotation<string[] | undefined>({\n reducer: (curr, next) => next ?? curr,\n default: () => undefined,\n }),\n\n /**\n * Optional network scope (network ID). Used for linking created intents to a network\n * and for scoping read operations. Prep always fetches ALL user intents via\n * getActiveIntents(userId) regardless of network scope (for global dedup/reconciliation).\n */\n networkId: Annotation<string | undefined>({\n reducer: (curr, next) => next ?? curr,\n default: () => undefined,\n }),\n\n /** Focused request scope type for write-side assignment and follow-up queues. */\n scopeType: Annotation<ToolScopeType | undefined>({\n reducer: (curr, next) => next ?? curr,\n default: () => undefined,\n }),\n\n /** Focused request scope id. When scopeType is `network`, this is the focused network id. */\n scopeId: Annotation<string | undefined>({\n reducer: (curr, next) => next ?? curr,\n default: () => undefined,\n }),\n\n // --- Populated by Graph (Prep Node) ---\n\n /**\n * The formatted string of currently active intents.\n * Always populated by prep via getActiveIntents(userId).\n */\n activeIntents: Annotation<string>({\n reducer: (curr, next) => next,\n default: () => \"\",\n }),\n\n // --- Intermediate State ---\n\n /**\n * List of raw intents extracted from text.\n */\n inferredIntents: Annotation<InferredIntent[]>({\n reducer: (curr, next) => next, // Overwrite with new inference\n default: () => [],\n }),\n\n /**\n * List of intents that have passed semantic verification.\n * Invalid intents are filtered out before reaching this state.\n */\n verifiedIntents: Annotation<VerifiedIntent[]>({\n reducer: (curr, next) => next,\n default: () => [],\n }),\n\n // --- Output ---\n\n /**\n * Final actions to be performed on the DB (Create, Update, Expire).\n */\n actions: Annotation<IntentReconcilerOutput['actions']>({\n reducer: (curr, next) => next,\n default: () => [],\n }),\n\n /**\n * Results of executing actions against the database.\n * Populated by executorNode after actions are persisted.\n */\n executionResults: Annotation<ExecutionResult[]>({\n reducer: (curr, next) => next,\n default: () => [],\n }),\n\n // --- Error State ---\n\n /**\n * If set, indicates a fatal error that should short-circuit the graph to END.\n * Populated by prep when a precondition fails (e.g. missing profile).\n */\n error: Annotation<string | undefined>({\n reducer: (curr, next) => next ?? curr,\n default: () => undefined,\n }),\n\n // --- Trace Output ---\n\n /**\n * Accumulated trace entries from each graph node.\n * Used for observability: surfaces internal processing steps (inference,\n * verification with Felicity scores, reconciliation) to the frontend.\n */\n trace: Annotation<Array<{ node: string; detail?: string; data?: Record<string, unknown> }>>({\n reducer: (curr, next) => [...curr, ...(next || [])],\n default: () => [],\n }),\n\n /** Timing records for each agent invocation within this graph run. */\n agentTimings: Annotation<DebugMetaAgent[]>({\n reducer: (acc, val) => [...acc, ...val],\n default: () => [],\n }),\n\n // --- Read Mode Fields ---\n\n /**\n * For read mode: the set of network IDs the caller's agent can reach.\n * When set and neither networkId nor queryUserId is provided, the graph\n * returns the caller's own intents across all networks in this set (scope-aware\n * default path). Derived by the tool layer from the scope envelope plus memberships.\n */\n indexScope: Annotation<string[] | undefined>({\n reducer: (_curr, next) => next,\n default: () => undefined,\n }),\n\n /**\n * For read mode: filter intents by a specific user when reading in a network.\n * When omitted and network-scoped, returns all intents in the network.\n */\n queryUserId: Annotation<string | undefined>({\n reducer: (curr, next) => next ?? curr,\n default: () => undefined,\n }),\n\n /**\n * For read mode: when true, return all of the current user's intents\n * ignoring network scope. Used before create_intent to detect duplicates.\n */\n allUserIntents: Annotation<boolean>({\n reducer: (curr, next) => next ?? curr,\n default: () => false,\n }),\n\n /**\n * Output of read mode: queried intents with count and optional metadata.\n */\n readResult: Annotation<{\n count: number;\n intents: Array<{\n id: string;\n description: string;\n summary: string | null;\n createdAt: Date;\n userId?: string;\n userName?: string | null;\n }>;\n message?: string;\n networkId?: string;\n } | undefined>({\n reducer: (curr, next) => next,\n default: () => undefined,\n }),\n});\n"]}
@@ -13,7 +13,7 @@ const logger = protocolLogger("ChatTools:Intent");
13
13
  function sanitizeJsonForCodeFence(json) {
14
14
  return json.replace(/`/g, "\\u0060");
15
15
  }
16
- /** When context is index-scoped, verifies the caller is still a member of that index. Returns error message or null. */
16
+ /** When context is network-scoped, verifies the caller is still a member of that index. Returns error message or null. */
17
17
  async function ensureScopedMembership(context, systemDb) {
18
18
  const scopedNetworkId = focusedNetworkId(context);
19
19
  if (!scopedNetworkId)
@@ -62,17 +62,17 @@ export function createIntentTools(defineTool, deps) {
62
62
  description: "Retrieves intents (signals of interest/need, e.g. 'Looking for a React developer in Berlin'). " +
63
63
  "Intents are the core unit of discovery — they represent what users are seeking and drive semantic matching for opportunities.\n\n" +
64
64
  "**Usage modes:**\n" +
65
- "- No parameters: returns the **caller's own** active intents. In an index-scoped chat the result is clamped to the reachable indexes (the bound index plus the user's personal index). In an unscoped chat the result spans all of the user's active intents. There is no implicit default to the scoped index — to browse the bound community's intents, pass `networkId` explicitly.\n" +
65
+ "- No parameters: returns the **caller's own** active intents. In an network-scoped chat the result is clamped to the reachable networks (the bound network plus the user's personal network). In an unscoped chat the result spans all of the user's active intents. There is no implicit default to the scoped network — to browse the bound community's intents, pass `networkId` explicitly.\n" +
66
66
  "- With networkId: returns **all members'** intents in that index (community browse path). Add userId to filter to one member.\n" +
67
- "- With userId in an index-scoped chat: reads that member's intents in the bound index. The target user must be a member of that index.\n" +
68
- "- With userId in an unscoped chat: only works for the current user (cannot read another user's global intents without an index scope).\n\n" +
69
- "**Workflow:** To explore what members of an index are looking for, first call read_network_memberships(networkId) to list members, " +
67
+ "- With userId in an network-scoped chat: reads that member's intents in the bound network. The target user must be a member of that index.\n" +
68
+ "- With userId in an unscoped chat: only works for the current user (cannot read another user's global intents without an network scope).\n\n" +
69
+ "**Workflow:** To explore what members of a network are looking for, first call read_network_memberships(networkId) to list members, " +
70
70
  "then read_intents(networkId) to see all intents in that community. " +
71
71
  "Each intent includes: id, description (payload), summary, confidence (0-1), inferenceType (explicit/implicit), status, and linked indexes.\n\n" +
72
72
  "**Returns:** Paginated list of intents with count. Use the intent IDs in subsequent calls to update_intent, delete_intent, or create_intent_index.",
73
73
  querySchema: z.object({
74
- networkId: z.string().optional().describe("Index UUID — filters intents to this index (community browse path: returns all members' intents). There is no implicit default in index-scoped chats; omit to get caller-owned intents across the reachable indexes, or pass the scoped index UUID to browse community members. Get index IDs from read_networks."),
75
- userId: z.string().optional().describe("User ID — filters to this user's intents. In an index-scoped chat, this reads that member's intents in the bound index (no networkId required). In an unscoped chat, only the current user is allowed without networkId; cross-user reads require an index scope. Omit for caller-owned intents."),
74
+ networkId: z.string().optional().describe("Network UUID — filters intents to this network (community browse path: returns all members' intents). There is no implicit default in network-scoped chats; omit to get caller-owned intents across the reachable networks, or pass the scoped network UUID to browse community members. Get network IDs from read_networks."),
75
+ userId: z.string().optional().describe("User ID — filters to this user's intents. In an network-scoped chat, this reads that member's intents in the bound network (no networkId required). In an unscoped chat, only the current user is allowed without networkId; cross-user reads require an network scope. Omit for caller-owned intents."),
76
76
  limit: z.number().int().min(1).max(100).optional().describe("Page size (1-100). Defaults to returning all results if omitted."),
77
77
  page: z.number().int().min(1).optional().describe("Page number (1-based). Only used when limit is also provided."),
78
78
  }),
@@ -95,14 +95,14 @@ export function createIntentTools(defineTool, deps) {
95
95
  if (scopedNetworkId && explicitNetworkId && explicitNetworkId !== scopedNetworkId) {
96
96
  return error(`This chat is scoped to ${scopedIndexLabel}. You can only read intents from this community.`);
97
97
  }
98
- // Cross-user read in scoped chat: target user must be a member of the scoped index
98
+ // Cross-user read in scoped chat: target user must be a member of the scoped network
99
99
  if (scopedNetworkId && explicitUserId && explicitUserId !== context.userId) {
100
100
  const isInScopedIndex = await deps.systemDb.isNetworkMember(scopedNetworkId, explicitUserId);
101
101
  if (!isInScopedIndex) {
102
102
  return error(`This chat is scoped to ${scopedIndexLabel}. You can only read intents from members of this community.`);
103
103
  }
104
104
  }
105
- // Cross-user global read is disallowed without an index scope
105
+ // Cross-user global read is disallowed without an network scope
106
106
  if (!explicitNetworkId && !scopedNetworkId && explicitUserId && explicitUserId !== context.userId) {
107
107
  return error("Cannot read another user's global intents. Use networkId to scope to a shared network.");
108
108
  }
@@ -141,7 +141,7 @@ export function createIntentTools(defineTool, deps) {
141
141
  graphInput.allUserIntents = true;
142
142
  }
143
143
  else if (scopedNetworkId) {
144
- // Scoped chat, implicit read: caller-only across reachable indexes.
144
+ // Scoped chat, implicit read: caller-only across reachable networks.
145
145
  graphInput.indexScope = deriveAllowedNetworkIds({
146
146
  memberships: context.userNetworks,
147
147
  scopeType: 'network',
@@ -206,7 +206,7 @@ export function createIntentTools(defineTool, deps) {
206
206
  "to create_user_context are handled by that tool directly — do not scrape first.",
207
207
  querySchema: z.object({
208
208
  description: z.string().describe("A clear, specific description of what the user is looking for. Should be concept-based, not a raw URL. If the user shared a URL, scrape it first with scrape_url and pass the synthesized content here. Vague descriptions will be rejected — include what kind, what for, and/or timeframe."),
209
- networkId: z.string().optional().describe("Index UUID to link the intent to upon creation. Defaults to the scoped index in index-scoped chats. Get index IDs from read_networks. If omitted, the system auto-assigns to relevant indexes based on their prompts."),
209
+ networkId: z.string().optional().describe("Network UUID to link the intent to upon creation. Defaults to the scoped network in network-scoped chats. Get network IDs from read_networks. If omitted, the system auto-assigns to relevant networks based on their prompts."),
210
210
  autoApprove: z.boolean().optional().describe("When true, automatically persists all verified intents without returning proposal cards for manual approval. MCP agents SHOULD set this to true since there is no UI for card-based approval. Web chat agents should omit or set to false to get interactive proposal cards."),
211
211
  }),
212
212
  handler: async ({ context, query }) => {
@@ -386,7 +386,7 @@ export function createIntentTools(defineTool, deps) {
386
386
  }
387
387
  const scopedNetworkId = focusedNetworkId(context);
388
388
  const scopedIndexLabel = focusedNetworkLabel(context);
389
- // Strict scope enforcement: when chat is index-scoped, verify intent is linked to that index
389
+ // Strict scope enforcement: when chat is network-scoped, verify intent is linked to that index
390
390
  if (scopedNetworkId) {
391
391
  const db = deps.userDb;
392
392
  const intentNetworks = await db.getNetworkIdsForIntent(intentId);
@@ -452,7 +452,7 @@ export function createIntentTools(defineTool, deps) {
452
452
  }
453
453
  const scopedNetworkId = focusedNetworkId(context);
454
454
  const scopedIndexLabel = focusedNetworkLabel(context);
455
- // Strict scope enforcement: when chat is index-scoped, verify intent is linked to that index
455
+ // Strict scope enforcement: when chat is network-scoped, verify intent is linked to that index
456
456
  if (scopedNetworkId) {
457
457
  const db = deps.userDb;
458
458
  const intentNetworks = await db.getNetworkIdsForIntent(intentId);
@@ -483,14 +483,14 @@ export function createIntentTools(defineTool, deps) {
483
483
  // ─────────────────────────────────────────────────────────────────────────────
484
484
  const createIntentIndex = defineTool({
485
485
  name: "create_intent_index",
486
- description: "Manually links an intent to an index (community), making it visible to other members and eligible for opportunity discovery within that index. " +
486
+ description: "Manually links an intent to a network (community), making it visible to other members and eligible for opportunity discovery within that index. " +
487
487
  "Normally intents are auto-assigned to relevant indexes on creation, but use this to explicitly add an intent to an additional index.\n\n" +
488
488
  "**When to use:** When the user wants to share an existing intent with a specific community they belong to, " +
489
- "or when auto-assignment missed an index the user considers relevant.\n\n" +
489
+ "or when auto-assignment missed a network the user considers relevant.\n\n" +
490
490
  "**Returns:** Confirmation that the link was created. The intent will now appear in that index's intent list and participate in discovery within that community.",
491
491
  querySchema: z.object({
492
492
  intentId: z.string().describe("The UUID of the intent to link. Get this from read_intents results."),
493
- networkId: z.string().optional().describe("The UUID of the index to link the intent to. Get this from read_networks. Defaults to the scoped index in index-scoped chats."),
493
+ networkId: z.string().optional().describe("The UUID of the network to link the intent to. Get this from read_networks. Defaults to the scoped network in network-scoped chats."),
494
494
  }),
495
495
  handler: async ({ context, query }) => {
496
496
  const scopeErr = await ensureScopedMembership(context, deps.systemDb);
@@ -503,7 +503,7 @@ export function createIntentTools(defineTool, deps) {
503
503
  if (!UUID_REGEX.test(intentId) || !UUID_REGEX.test(networkId)) {
504
504
  return error("Invalid ID format. Both must be UUIDs.");
505
505
  }
506
- // Strict scope enforcement: when chat is index-scoped, only allow linking to that index
506
+ // Strict scope enforcement: when chat is network-scoped, only allow linking to that index
507
507
  if (scopedNetworkId && networkId !== scopedNetworkId) {
508
508
  return error(`This chat is scoped to ${scopedIndexLabel}. You can only link intents to this community.`);
509
509
  }
@@ -537,13 +537,13 @@ export function createIntentTools(defineTool, deps) {
537
537
  "**Usage modes:**\n" +
538
538
  "- With networkId: lists all intents linked to that index. Add userId to filter to one member's intents in that index.\n" +
539
539
  "- With intentId + networkId: checks whether a specific intent is linked to a specific index.\n" +
540
- "- intentId alone requires a networkId (the system won't reveal all indexes an intent is in).\n\n" +
540
+ "- intentId alone requires a networkId (the system won't reveal all networks an intent is in).\n\n" +
541
541
  "**When to use:** To audit which intents are active in a community, verify an intent's index assignment before unlinking, " +
542
542
  "or check if a newly created intent was auto-assigned to the expected index.\n\n" +
543
- "**Returns:** List of intent-index links with relevancy scores (0-1, how well the intent fits the index's purpose).",
543
+ "**Returns:** List of intent-network links with relevancy scores (0-1, how well the intent fits the network's purpose).",
544
544
  querySchema: z.object({
545
545
  intentId: z.string().optional().describe("Intent UUID — check if this specific intent is linked to the specified index. Must be combined with networkId."),
546
- networkId: z.string().optional().describe("Index UUID — list all intents linked to this index. Get this from read_networks. Defaults to scoped index in index-scoped chats."),
546
+ networkId: z.string().optional().describe("Network UUID — list all intents linked to this network. Get this from read_networks. Defaults to scoped network in network-scoped chats."),
547
547
  userId: z.string().optional().describe("Filter results to this user's intents within the specified index. Omit to see all members' intents."),
548
548
  }),
549
549
  handler: async ({ context, query }) => {
@@ -564,18 +564,18 @@ export function createIntentTools(defineTool, deps) {
564
564
  if (!intentId && !networkId) {
565
565
  return error("Provide networkId or intentId.");
566
566
  }
567
- // Strict scope enforcement: when chat is index-scoped, only allow querying that index
567
+ // Strict scope enforcement: when chat is network-scoped, only allow querying that index
568
568
  if (scopedNetworkId && networkId && networkId !== scopedNetworkId) {
569
569
  return error(`This chat is scoped to ${scopedIndexLabel}. You can only read intent links from this community.`);
570
570
  }
571
571
  // When only intentId is provided, enforce scope - don't reveal all linked indexes
572
572
  if (intentId && !networkId) {
573
573
  if (scopedNetworkId) {
574
- // When scoped, only check if intent is linked to the scoped index
574
+ // When scoped, only check if intent is linked to the scoped network
575
575
  networkId = scopedNetworkId;
576
576
  }
577
577
  else {
578
- // When unscoped, still don't reveal all indexes - require explicit networkId
578
+ // When unscoped, still don't reveal all networks - require explicit networkId
579
579
  return error("Please provide a networkId to check if the intent is linked to a specific network. Listing all linked networks is not supported.");
580
580
  }
581
581
  }
@@ -599,14 +599,14 @@ export function createIntentTools(defineTool, deps) {
599
599
  });
600
600
  const deleteIntentIndex = defineTool({
601
601
  name: "delete_intent_index",
602
- description: "Removes the link between an intent and an index. The intent itself is NOT deleted — it just stops being visible in that community " +
602
+ description: "Removes the link between an intent and a network. The intent itself is NOT deleted — it just stops being visible in that community " +
603
603
  "and no longer participates in opportunity discovery within that index. The intent may still be linked to other indexes.\n\n" +
604
604
  "**When to use:** When the user wants to withdraw an intent from a specific community without archiving it entirely. " +
605
605
  "Use read_intent_indexes first to verify the link exists.\n\n" +
606
606
  "**Returns:** Confirmation that the link was removed. To fully remove an intent, use delete_intent instead.",
607
607
  querySchema: z.object({
608
608
  intentId: z.string().describe("The UUID of the intent to unlink. Get this from read_intents or read_intent_indexes."),
609
- networkId: z.string().optional().describe("The UUID of the index to unlink from. Get this from read_networks. Defaults to the scoped index in index-scoped chats."),
609
+ networkId: z.string().optional().describe("The UUID of the network to unlink from. Get this from read_networks. Defaults to the scoped network in network-scoped chats."),
610
610
  }),
611
611
  handler: async ({ context, query }) => {
612
612
  const scopeErr = await ensureScopedMembership(context, deps.systemDb);
@@ -619,7 +619,7 @@ export function createIntentTools(defineTool, deps) {
619
619
  if (!UUID_REGEX.test(intentId) || !UUID_REGEX.test(networkId)) {
620
620
  return error("Invalid ID format. Both must be UUIDs.");
621
621
  }
622
- // Strict scope enforcement: when chat is index-scoped, only allow unlinking from that index
622
+ // Strict scope enforcement: when chat is network-scoped, only allow unlinking from that index
623
623
  if (scopedNetworkId && networkId !== scopedNetworkId) {
624
624
  return error(`This chat is scoped to ${scopedIndexLabel}. You can only unlink intents from this community.`);
625
625
  }