@indexnetwork/protocol 4.12.0-rc.352.1 → 4.14.0-rc.354.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 (68) hide show
  1. package/CHANGELOG.md +3 -0
  2. package/dist/index.d.ts +10 -7
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +5 -4
  5. package/dist/index.js.map +1 -1
  6. package/dist/opportunity/discriminator/discriminator.adjustments.d.ts +25 -0
  7. package/dist/opportunity/discriminator/discriminator.adjustments.d.ts.map +1 -1
  8. package/dist/opportunity/discriminator/discriminator.adjustments.js +32 -7
  9. package/dist/opportunity/discriminator/discriminator.adjustments.js.map +1 -1
  10. package/dist/opportunity/discriminator/discriminator.assigner.d.ts +79 -0
  11. package/dist/opportunity/discriminator/discriminator.assigner.d.ts.map +1 -0
  12. package/dist/opportunity/discriminator/discriminator.assigner.js +154 -0
  13. package/dist/opportunity/discriminator/discriminator.assigner.js.map +1 -0
  14. package/dist/opportunity/discriminator/discriminator.env.d.ts +7 -0
  15. package/dist/opportunity/discriminator/discriminator.env.d.ts.map +1 -1
  16. package/dist/opportunity/discriminator/discriminator.env.js +7 -0
  17. package/dist/opportunity/discriminator/discriminator.env.js.map +1 -1
  18. package/dist/opportunity/discriminator/discriminator.miner.d.ts +14 -0
  19. package/dist/opportunity/discriminator/discriminator.miner.d.ts.map +1 -1
  20. package/dist/opportunity/discriminator/discriminator.miner.js +14 -5
  21. package/dist/opportunity/discriminator/discriminator.miner.js.map +1 -1
  22. package/dist/opportunity/opportunity.graph.d.ts +17 -2
  23. package/dist/opportunity/opportunity.graph.d.ts.map +1 -1
  24. package/dist/opportunity/opportunity.graph.js +85 -2
  25. package/dist/opportunity/opportunity.graph.js.map +1 -1
  26. package/dist/opportunity/opportunity.pending-questions.d.ts.map +1 -1
  27. package/dist/opportunity/opportunity.pending-questions.js +2 -1
  28. package/dist/opportunity/opportunity.pending-questions.js.map +1 -1
  29. package/dist/opportunity/opportunity.tools.d.ts.map +1 -1
  30. package/dist/opportunity/opportunity.tools.js +85 -3
  31. package/dist/opportunity/opportunity.tools.js.map +1 -1
  32. package/dist/questioner/questioner.env.d.ts +9 -0
  33. package/dist/questioner/questioner.env.d.ts.map +1 -1
  34. package/dist/questioner/questioner.env.js +19 -0
  35. package/dist/questioner/questioner.env.js.map +1 -1
  36. package/dist/questioner/questioner.presets.d.ts.map +1 -1
  37. package/dist/questioner/questioner.presets.js +44 -4
  38. package/dist/questioner/questioner.presets.js.map +1 -1
  39. package/dist/questioner/questioner.tools.d.ts.map +1 -1
  40. package/dist/questioner/questioner.tools.js +3 -3
  41. package/dist/questioner/questioner.tools.js.map +1 -1
  42. package/dist/questioner/questioner.types.d.ts +34 -7
  43. package/dist/questioner/questioner.types.d.ts.map +1 -1
  44. package/dist/questioner/questioner.types.js.map +1 -1
  45. package/dist/shared/agent/model.config.d.ts +5 -0
  46. package/dist/shared/agent/model.config.d.ts.map +1 -1
  47. package/dist/shared/agent/model.config.js +1 -0
  48. package/dist/shared/agent/model.config.js.map +1 -1
  49. package/dist/shared/agent/tool.factory.d.ts.map +1 -1
  50. package/dist/shared/agent/tool.factory.js +2 -1
  51. package/dist/shared/agent/tool.factory.js.map +1 -1
  52. package/dist/shared/agent/tool.helpers.d.ts +9 -1
  53. package/dist/shared/agent/tool.helpers.d.ts.map +1 -1
  54. package/dist/shared/agent/tool.helpers.js.map +1 -1
  55. package/dist/shared/interfaces/database.interface.d.ts +2 -0
  56. package/dist/shared/interfaces/database.interface.d.ts.map +1 -1
  57. package/dist/shared/interfaces/database.interface.js.map +1 -1
  58. package/dist/shared/interfaces/questioner.interface.d.ts +2 -1
  59. package/dist/shared/interfaces/questioner.interface.d.ts.map +1 -1
  60. package/dist/shared/interfaces/questioner.interface.js.map +1 -1
  61. package/dist/shared/schemas/pending-question.schema.d.ts +3 -1
  62. package/dist/shared/schemas/pending-question.schema.d.ts.map +1 -1
  63. package/dist/shared/schemas/pending-question.schema.js.map +1 -1
  64. package/dist/shared/schemas/question.schema.d.ts +7 -0
  65. package/dist/shared/schemas/question.schema.d.ts.map +1 -1
  66. package/dist/shared/schemas/question.schema.js +4 -0
  67. package/dist/shared/schemas/question.schema.js.map +1 -1
  68. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"opportunity.pending-questions.d.ts","sourceRoot":"/","sources":["opportunity/opportunity.pending-questions.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,8CAA8C,CAAC;AAI3F,kEAAkE;AAClE,eAAO,MAAM,qBAAqB,IAAI,CAAC;AAEvC,MAAM,WAAW,0BAA0B;IACzC,oBAAoB,CAAC,EAAE,CACrB,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE;QAAE,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,QAAQ,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,KAC7G,OAAO,CAAC,sBAAsB,EAAE,CAAC,CAAC;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iEAAiE;IACjE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sCAAsC;IACtC,SAAS,CAAC,EAAE,QAAQ,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,0DAA0D;IAC1D,mBAAmB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,2BAA2B;IAC1C,0EAA0E;IAC1E,SAAS,EAAE,sBAAsB,EAAE,CAAC;IACpC,0FAA0F;IAC1F,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,0BAA0B,GAChC,OAAO,CAAC,2BAA2B,CAAC,CA+BtC"}
1
+ {"version":3,"file":"opportunity.pending-questions.d.ts","sourceRoot":"/","sources":["opportunity/opportunity.pending-questions.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,8CAA8C,CAAC;AAI3F,kEAAkE;AAClE,eAAO,MAAM,qBAAqB,IAAI,CAAC;AAEvC,MAAM,WAAW,0BAA0B;IACzC,oBAAoB,CAAC,EAAE,CACrB,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE;QAAE,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,QAAQ,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,KAC7G,OAAO,CAAC,sBAAsB,EAAE,CAAC,CAAC;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iEAAiE;IACjE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sCAAsC;IACtC,SAAS,CAAC,EAAE,QAAQ,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,0DAA0D;IAC1D,mBAAmB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,2BAA2B;IAC1C,0EAA0E;IAC1E,SAAS,EAAE,sBAAsB,EAAE,CAAC;IACpC,0FAA0F;IAC1F,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,0BAA0B,GAChC,OAAO,CAAC,2BAA2B,CAAC,CAgCtC"}
@@ -34,8 +34,9 @@ export async function mergePendingQuestions(input) {
34
34
  // Deduplicate against already-surfaced IDs in this session
35
35
  const fresh = pending.filter((q) => !input.surfacedQuestionIds.has(q.id));
36
36
  const capped = fresh.slice(0, MAX_PENDING_QUESTIONS);
37
+ const publicQuestions = capped.map(({ actors: _actors, purpose: _purpose, ...question }) => question);
37
38
  return {
38
- questions: capped,
39
+ questions: publicQuestions,
39
40
  surfacedIds: capped.map((q) => q.id),
40
41
  };
41
42
  }
@@ -1 +1 @@
1
- {"version":3,"file":"opportunity.pending-questions.js","sourceRoot":"/","sources":["opportunity/opportunity.pending-questions.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,4CAA4C,CAAC;AAG5E,MAAM,MAAM,GAAG,cAAc,CAAC,kBAAkB,CAAC,CAAC;AAElD,kEAAkE;AAClE,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC;AA0BvC;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,KAAiC;IAEjC,IAAI,CAAC,KAAK,CAAC,oBAAoB,EAAE,CAAC;QAChC,OAAO,EAAE,SAAS,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC;IAC5C,CAAC;IAED,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,UAAU,IAAI,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,SAAS,CAAC,CAAC;IACnF,MAAM,OAAO,GAAG,UAAU;QACxB,CAAC,CAAC;YACE,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7D,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACvD,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC1D,GAAG,CAAC,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACpG;QACH,CAAC,CAAC,SAAS,CAAC;IAEd,IAAI,OAAiC,CAAC;IACtC,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,KAAK,CAAC,oBAAoB,CAAC,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,IAAI,CAAC,oDAAoD,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;QAClF,OAAO,EAAE,SAAS,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC;IAC5C,CAAC;IAED,2DAA2D;IAC3D,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC1E,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,qBAAqB,CAAC,CAAC;IAErD,OAAO;QACL,SAAS,EAAE,MAAM;QACjB,WAAW,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACrC,CAAC;AACJ,CAAC","sourcesContent":["/**\n * Helper for merging pending questions from the DB into tool results.\n * Extracted so it can be unit-tested independently of the tool handler.\n */\nimport { protocolLogger } from \"../shared/observability/protocol.logger.js\";\nimport type { PendingQuestionSummary } from \"../shared/schemas/pending-question.schema.js\";\n\nconst logger = protocolLogger(\"PendingQuestions\");\n\n/** Maximum pending questions attached to a single tool result. */\nexport const MAX_PENDING_QUESTIONS = 3;\n\nexport interface MergePendingQuestionsInput {\n findPendingQuestions?: (\n userId: string,\n filters?: { sourceType?: string; sourceId?: string; networkId?: string; scopeType?: 'intent'; scopeId?: string },\n ) => Promise<PendingQuestionSummary[]>;\n userId: string;\n sourceType?: string;\n sourceId?: string;\n /** Restrict to questions whose actor carries this network id. */\n networkId?: string;\n /** Optional selected-intent scope. */\n scopeType?: 'intent';\n scopeId?: string;\n /** IDs already shown in this chat session — skip them. */\n surfacedQuestionIds: Set<string>;\n}\n\nexport interface MergePendingQuestionsResult {\n /** Questions to attach to the tool result (under the `questions` key). */\n questions: PendingQuestionSummary[];\n /** IDs of the questions that were included (caller should add to surfacedQuestionIds). */\n surfacedIds: string[];\n}\n\n/**\n * Query pending questions and filter out already-surfaced ones.\n * Returns at most MAX_PENDING_QUESTIONS entries.\n */\nexport async function mergePendingQuestions(\n input: MergePendingQuestionsInput,\n): Promise<MergePendingQuestionsResult> {\n if (!input.findPendingQuestions) {\n return { questions: [], surfacedIds: [] };\n }\n\n const hasFilters = Boolean(input.sourceType || input.networkId || input.scopeType);\n const filters = hasFilters\n ? {\n ...(input.sourceType ? { sourceType: input.sourceType } : {}),\n ...(input.sourceId ? { sourceId: input.sourceId } : {}),\n ...(input.networkId ? { networkId: input.networkId } : {}),\n ...(input.scopeType && input.scopeId ? { scopeType: input.scopeType, scopeId: input.scopeId } : {}),\n }\n : undefined;\n\n let pending: PendingQuestionSummary[];\n try {\n pending = await input.findPendingQuestions(input.userId, filters);\n } catch (err) {\n logger.warn('Failed to fetch pending questions, returning empty', { error: err });\n return { questions: [], surfacedIds: [] };\n }\n\n // Deduplicate against already-surfaced IDs in this session\n const fresh = pending.filter((q) => !input.surfacedQuestionIds.has(q.id));\n const capped = fresh.slice(0, MAX_PENDING_QUESTIONS);\n\n return {\n questions: capped,\n surfacedIds: capped.map((q) => q.id),\n };\n}\n"]}
1
+ {"version":3,"file":"opportunity.pending-questions.js","sourceRoot":"/","sources":["opportunity/opportunity.pending-questions.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,4CAA4C,CAAC;AAG5E,MAAM,MAAM,GAAG,cAAc,CAAC,kBAAkB,CAAC,CAAC;AAElD,kEAAkE;AAClE,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC;AA0BvC;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,KAAiC;IAEjC,IAAI,CAAC,KAAK,CAAC,oBAAoB,EAAE,CAAC;QAChC,OAAO,EAAE,SAAS,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC;IAC5C,CAAC;IAED,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,UAAU,IAAI,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,SAAS,CAAC,CAAC;IACnF,MAAM,OAAO,GAAG,UAAU;QACxB,CAAC,CAAC;YACE,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7D,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACvD,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC1D,GAAG,CAAC,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACpG;QACH,CAAC,CAAC,SAAS,CAAC;IAEd,IAAI,OAAiC,CAAC;IACtC,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,KAAK,CAAC,oBAAoB,CAAC,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,IAAI,CAAC,oDAAoD,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;QAClF,OAAO,EAAE,SAAS,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC;IAC5C,CAAC;IAED,2DAA2D;IAC3D,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC1E,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,qBAAqB,CAAC,CAAC;IACrD,MAAM,eAAe,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,QAAQ,EAAE,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC;IAEtG,OAAO;QACL,SAAS,EAAE,eAAe;QAC1B,WAAW,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACrC,CAAC;AACJ,CAAC","sourcesContent":["/**\n * Helper for merging pending questions from the DB into tool results.\n * Extracted so it can be unit-tested independently of the tool handler.\n */\nimport { protocolLogger } from \"../shared/observability/protocol.logger.js\";\nimport type { PendingQuestionSummary } from \"../shared/schemas/pending-question.schema.js\";\n\nconst logger = protocolLogger(\"PendingQuestions\");\n\n/** Maximum pending questions attached to a single tool result. */\nexport const MAX_PENDING_QUESTIONS = 3;\n\nexport interface MergePendingQuestionsInput {\n findPendingQuestions?: (\n userId: string,\n filters?: { sourceType?: string; sourceId?: string; networkId?: string; scopeType?: 'intent'; scopeId?: string },\n ) => Promise<PendingQuestionSummary[]>;\n userId: string;\n sourceType?: string;\n sourceId?: string;\n /** Restrict to questions whose actor carries this network id. */\n networkId?: string;\n /** Optional selected-intent scope. */\n scopeType?: 'intent';\n scopeId?: string;\n /** IDs already shown in this chat session — skip them. */\n surfacedQuestionIds: Set<string>;\n}\n\nexport interface MergePendingQuestionsResult {\n /** Questions to attach to the tool result (under the `questions` key). */\n questions: PendingQuestionSummary[];\n /** IDs of the questions that were included (caller should add to surfacedQuestionIds). */\n surfacedIds: string[];\n}\n\n/**\n * Query pending questions and filter out already-surfaced ones.\n * Returns at most MAX_PENDING_QUESTIONS entries.\n */\nexport async function mergePendingQuestions(\n input: MergePendingQuestionsInput,\n): Promise<MergePendingQuestionsResult> {\n if (!input.findPendingQuestions) {\n return { questions: [], surfacedIds: [] };\n }\n\n const hasFilters = Boolean(input.sourceType || input.networkId || input.scopeType);\n const filters = hasFilters\n ? {\n ...(input.sourceType ? { sourceType: input.sourceType } : {}),\n ...(input.sourceId ? { sourceId: input.sourceId } : {}),\n ...(input.networkId ? { networkId: input.networkId } : {}),\n ...(input.scopeType && input.scopeId ? { scopeType: input.scopeType, scopeId: input.scopeId } : {}),\n }\n : undefined;\n\n let pending: PendingQuestionSummary[];\n try {\n pending = await input.findPendingQuestions(input.userId, filters);\n } catch (err) {\n logger.warn('Failed to fetch pending questions, returning empty', { error: err });\n return { questions: [], surfacedIds: [] };\n }\n\n // Deduplicate against already-surfaced IDs in this session\n const fresh = pending.filter((q) => !input.surfacedQuestionIds.has(q.id));\n const capped = fresh.slice(0, MAX_PENDING_QUESTIONS);\n const publicQuestions = capped.map(({ actors: _actors, purpose: _purpose, ...question }) => question);\n\n return {\n questions: publicQuestions,\n surfacedIds: capped.map((q) => q.id),\n };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"opportunity.tools.d.ts","sourceRoot":"/","sources":["opportunity/opportunity.tools.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"opportunity.tools.d.ts","sourceRoot":"/","sources":["opportunity/opportunity.tools.ts"],"names":[],"mappings":"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"}
@@ -6,7 +6,7 @@ import { MINIMAL_MAIN_TEXT_MAX_CHARS, getPrimaryActionLabel, SECONDARY_ACTION_LA
6
6
  import { narratorRemarkFromReasoning, stripUuids } from "./opportunity.presentation.js";
7
7
  import { safeFallbackSummary, getSafePresentationOrSkip } from "./opportunity.safe-presentation.js";
8
8
  import { runDiscoverFromQuery, continueDiscovery } from "./opportunity.discover.js";
9
- import { isDiscoveryQuestionsEnabled } from "../questioner/questioner.env.js";
9
+ import { isDiscoveryQuestionsEnabled, isUptakeGuardEnabled } from "../questioner/questioner.env.js";
10
10
  import { OpportunityPresenter, gatherPresenterContext } from "./opportunity.presenter.js";
11
11
  import { loadNegotiationContext } from "./negotiation-context.loader.js";
12
12
  function stripLeadingNarratorName(remark, narratorName) {
@@ -183,6 +183,28 @@ const UPDATE_OPPORTUNITY_BLOCKED_STATUSES = new Set([
183
183
  "expired",
184
184
  "negotiating",
185
185
  ]);
186
+ function publicUptakeQuestion(question) {
187
+ return {
188
+ id: question.id,
189
+ title: question.title,
190
+ prompt: question.prompt,
191
+ options: question.options,
192
+ multiSelect: question.multiSelect,
193
+ };
194
+ }
195
+ function uptakeAdvisory(opportunityId, questions) {
196
+ return JSON.stringify({
197
+ success: false,
198
+ error: "Resolve the pending uptake questions or explicitly continue anyway.",
199
+ advisory: {
200
+ code: "unresolved_uptake_questions",
201
+ advisoryOnly: true,
202
+ opportunityId,
203
+ questions,
204
+ acknowledgedUptakeQuestionIds: questions.map((question) => question.id),
205
+ },
206
+ });
207
+ }
186
208
  function matchesSelectedIntentScope(opportunity, viewerId, scope) {
187
209
  if (scope?.scopeType !== 'intent' || !scope.scopeId)
188
210
  return true;
@@ -1917,8 +1939,9 @@ export function createOpportunityTools(defineTool, deps) {
1917
1939
  "- `rejected`: Decline a received opportunity.\n" +
1918
1940
  "- `expired`: Mark as expired (typically done by the system after timeout).\n\n" +
1919
1941
  "**When to use:** After discover_opportunities or list_opportunities returns opportunity cards. " +
1920
- "The user clicks 'Send' (pending), 'Accept', or 'Reject' on the card, and the agent calls this tool.\n\n" +
1921
- "**Returns:** Confirmation with the new status and notification details (who was notified).",
1942
+ "The user clicks 'Send' (pending), 'Accept', or 'Reject' on the card, and the agent calls this tool. " +
1943
+ "An accepted transition may first return a non-success uptake advisory with preparatory questions. Surface those questions, then retry with all returned question ids in acknowledgedUptakeQuestionIds; acknowledgement confirms presentation, not an answer.\n\n" +
1944
+ "**Returns:** Confirmation with the new status and notification details (who was notified), or a structured uptake advisory without mutation.",
1922
1945
  querySchema: z.object({
1923
1946
  opportunityId: z
1924
1947
  .string()
@@ -1927,6 +1950,10 @@ export function createOpportunityTools(defineTool, deps) {
1927
1950
  .enum(["pending", "accepted", "rejected", "expired"])
1928
1951
  .describe("New status: 'pending' = send the draft to the other party, 'accepted' = accept the connection, " +
1929
1952
  "'rejected' = decline, 'expired' = mark as timed out."),
1953
+ acknowledgedUptakeQuestionIds: z
1954
+ .array(z.string().min(1))
1955
+ .optional()
1956
+ .describe("On an acknowledged retry after an uptake advisory, include every question id returned by that advisory."),
1930
1957
  scopeType: z
1931
1958
  .enum(['intent'])
1932
1959
  .optional()
@@ -1991,6 +2018,61 @@ export function createOpportunityTools(defineTool, deps) {
1991
2018
  if (!matchesSelectedIntentScope(opportunity, context.userId, effectiveIntentScope)) {
1992
2019
  return error("Opportunity not found.");
1993
2020
  }
2021
+ // The caller actor's own network is the exact question lookup boundary,
2022
+ // even for an otherwise unscoped request. A focused network may only be
2023
+ // equal to this after the guard above.
2024
+ // Unscoped callers query all of their exact opportunity questions; a
2025
+ // network-scoped caller is clamped to the bound network. Selecting the
2026
+ // first duplicate actor row would miss a valid question on another
2027
+ // shared network.
2028
+ const uptakeNetworkId = scopedNetworkId;
2029
+ // Soft uptake interlock: only acceptance is advisory-gated. All existing
2030
+ // actor/scope/privacy guards run first so the question lookup cannot be
2031
+ // used to probe opportunities or networks the caller cannot access.
2032
+ if (query.status === "accepted" && isUptakeGuardEnabled() && deps.findPendingQuestions) {
2033
+ try {
2034
+ const pending = await deps.findPendingQuestions(context.userId, {
2035
+ sourceType: "opportunity",
2036
+ sourceId: opportunityId,
2037
+ modes: ["negotiation"],
2038
+ purpose: "uptake",
2039
+ ...(uptakeNetworkId ? { networkId: uptakeNetworkId } : {}),
2040
+ });
2041
+ // Defense in depth if a host overlooks one or more filters. Actor
2042
+ // internals are checked here and never serialized into the advisory.
2043
+ const exactPending = pending.filter((question) => {
2044
+ if (question.sourceType !== "opportunity" ||
2045
+ question.sourceId !== opportunityId ||
2046
+ question.mode !== "negotiation" ||
2047
+ question.purpose !== "uptake") {
2048
+ return false;
2049
+ }
2050
+ if (!question.actors?.some((actor) => actor.userId === context.userId))
2051
+ return false;
2052
+ if (uptakeNetworkId && !question.actors.some((actor) => actor.userId === context.userId && actor.networkId === uptakeNetworkId)) {
2053
+ return false;
2054
+ }
2055
+ return true;
2056
+ });
2057
+ const acknowledged = new Set(query.acknowledgedUptakeQuestionIds ?? []);
2058
+ if (exactPending.some((question) => !acknowledged.has(question.id))) {
2059
+ return uptakeAdvisory(opportunityId, exactPending.map(publicUptakeQuestion));
2060
+ }
2061
+ }
2062
+ catch (err) {
2063
+ logger.warn("update_opportunity: uptake question lookup failed open", {
2064
+ opportunityId,
2065
+ userId: context.userId,
2066
+ error: err instanceof Error ? err.message : String(err),
2067
+ });
2068
+ deps.reportToolError?.(err, {
2069
+ subsystem: "opportunity",
2070
+ operation: "opportunity.uptake_lookup",
2071
+ toolName: "update_opportunity",
2072
+ userId: context.userId,
2073
+ });
2074
+ }
2075
+ }
1994
2076
  const isSend = query.status === "pending";
1995
2077
  const _updateGraphStart = Date.now();
1996
2078
  const _updateTraceEmitter = requestContext.getStore()?.traceEmitter;