@indexnetwork/protocol 4.5.0-rc.335.1 → 4.5.0-rc.337.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 (48) hide show
  1. package/dist/chat/chat-streaming.types.d.ts +1 -1
  2. package/dist/chat/chat-streaming.types.d.ts.map +1 -1
  3. package/dist/chat/chat-streaming.types.js.map +1 -1
  4. package/dist/chat/chat.agent.d.ts +1 -1
  5. package/dist/chat/chat.agent.d.ts.map +1 -1
  6. package/dist/chat/chat.agent.js.map +1 -1
  7. package/dist/index.d.ts +6 -4
  8. package/dist/index.d.ts.map +1 -1
  9. package/dist/index.js +3 -2
  10. package/dist/index.js.map +1 -1
  11. package/dist/negotiation/negotiation.agent.d.ts +9 -0
  12. package/dist/negotiation/negotiation.agent.d.ts.map +1 -1
  13. package/dist/negotiation/negotiation.agent.js +11 -3
  14. package/dist/negotiation/negotiation.agent.js.map +1 -1
  15. package/dist/negotiation/negotiation.graph.d.ts +133 -35
  16. package/dist/negotiation/negotiation.graph.d.ts.map +1 -1
  17. package/dist/negotiation/negotiation.graph.js +197 -9
  18. package/dist/negotiation/negotiation.graph.js.map +1 -1
  19. package/dist/negotiation/negotiation.protocol.d.ts +250 -2
  20. package/dist/negotiation/negotiation.protocol.d.ts.map +1 -1
  21. package/dist/negotiation/negotiation.protocol.js +57 -8
  22. package/dist/negotiation/negotiation.protocol.js.map +1 -1
  23. package/dist/negotiation/negotiation.reflect.d.ts +199 -0
  24. package/dist/negotiation/negotiation.reflect.d.ts.map +1 -0
  25. package/dist/negotiation/negotiation.reflect.js +153 -0
  26. package/dist/negotiation/negotiation.reflect.js.map +1 -0
  27. package/dist/negotiation/negotiation.state.d.ts +40 -7
  28. package/dist/negotiation/negotiation.state.d.ts.map +1 -1
  29. package/dist/negotiation/negotiation.state.js +5 -1
  30. package/dist/negotiation/negotiation.state.js.map +1 -1
  31. package/dist/opportunity/question.prompt.d.ts +1 -1
  32. package/dist/opportunity/question.prompt.d.ts.map +1 -1
  33. package/dist/opportunity/question.prompt.js.map +1 -1
  34. package/dist/shared/agent/model.config.d.ts +5 -0
  35. package/dist/shared/agent/model.config.d.ts.map +1 -1
  36. package/dist/shared/agent/model.config.js +1 -0
  37. package/dist/shared/agent/model.config.js.map +1 -1
  38. package/dist/shared/interfaces/negotiation-events.interface.d.ts +30 -0
  39. package/dist/shared/interfaces/negotiation-events.interface.d.ts.map +1 -1
  40. package/dist/shared/interfaces/negotiation-events.interface.js.map +1 -1
  41. package/dist/shared/schemas/discovery-question.schema.d.ts +8 -8
  42. package/dist/shared/schemas/discovery-question.schema.js +1 -1
  43. package/dist/shared/schemas/discovery-question.schema.js.map +1 -1
  44. package/dist/shared/schemas/negotiation-state.schema.d.ts +41 -4
  45. package/dist/shared/schemas/negotiation-state.schema.d.ts.map +1 -1
  46. package/dist/shared/schemas/negotiation-state.schema.js +14 -0
  47. package/dist/shared/schemas/negotiation-state.schema.js.map +1 -1
  48. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"question.prompt.d.ts","sourceRoot":"/","sources":["opportunity/question.prompt.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0CAA0C,CAAC;AAClF,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,gDAAgD,CAAC;AAEjG,wDAAwD;AACxD,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;AAE3D,qCAAqC;AACrC,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,UAAU,GAAG,UAAU,GAAG,UAAU,GAAG,SAAS,CAAC;IACvG,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE;QAAE,OAAO,EAAE,eAAe,CAAC;QAAC,SAAS,EAAE,eAAe,CAAA;KAAE,CAAC;CAC1E;AAED,gCAAgC;AAChC,MAAM,WAAW,gBAAgB;IAC/B,cAAc,EAAE,OAAO,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,eAAe,CAAA;KAAE,CAAC,CAAC;IAC/D,0EAA0E;IAC1E,MAAM,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;CACjC;AAED,2DAA2D;AAC3D,MAAM,WAAW,oBAAoB;IACnC,2FAA2F;IAC3F,cAAc,EAAE,MAAM,CAAC;IACvB,4EAA4E;IAC5E,gBAAgB,EAAE,MAAM,CAAC;IACzB,+DAA+D;IAC/D,YAAY,EAAE,MAAM,CAAC;IACrB,2DAA2D;IAC3D,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,OAAO,EAAE,gBAAgB,CAAC;IAC1B;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,yEAAyE;AACzE,MAAM,WAAW,gBAAgB;IAC/B,eAAe,EAAE,MAAM,CAAC;IACxB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,sFAAsF;IACtF,YAAY,EAAE,MAAM,CAAC;IACrB,8DAA8D;IAC9D,gBAAgB,EAAE,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC,CAAC;CAC5D;AAED;;;;GAIG;AACH,MAAM,WAAW,sBAAsB;IACrC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,4CAA4C;AAC5C,MAAM,WAAW,sBAAsB;IACrC,sFAAsF;IACtF,KAAK,EAAE,MAAM,CAAC;IACd,oFAAoF;IACpF,WAAW,EAAE,MAAM,CAAC;IACpB;;;;;OAKG;IACH,kBAAkB,EAAE,0BAA0B,EAAE,CAAC;IACjD,OAAO,EAAE,gBAAgB,CAAC;IAC1B,iEAAiE;IACjE,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAChC,4DAA4D;IAC5D,GAAG,EAAE,MAAM,CAAC;CACb;AAED,2GAA2G;AAC3G,eAAO,MAAM,aAAa,yyLA0C0J,CAAC;AAErL;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,sBAAsB,GAAG,MAAM,CAmCzE"}
1
+ {"version":3,"file":"question.prompt.d.ts","sourceRoot":"/","sources":["opportunity/question.prompt.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0CAA0C,CAAC;AAClF,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,gDAAgD,CAAC;AAEjG,wDAAwD;AACxD,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;AAE3D,qCAAqC;AACrC,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,UAAU,GAAG,UAAU,GAAG,UAAU,GAAG,SAAS,GAAG,UAAU,CAAC;IACpH,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE;QAAE,OAAO,EAAE,eAAe,CAAC;QAAC,SAAS,EAAE,eAAe,CAAA;KAAE,CAAC;CAC1E;AAED,gCAAgC;AAChC,MAAM,WAAW,gBAAgB;IAC/B,cAAc,EAAE,OAAO,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,eAAe,CAAA;KAAE,CAAC,CAAC;IAC/D,0EAA0E;IAC1E,MAAM,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;CACjC;AAED,2DAA2D;AAC3D,MAAM,WAAW,oBAAoB;IACnC,2FAA2F;IAC3F,cAAc,EAAE,MAAM,CAAC;IACvB,4EAA4E;IAC5E,gBAAgB,EAAE,MAAM,CAAC;IACzB,+DAA+D;IAC/D,YAAY,EAAE,MAAM,CAAC;IACrB,2DAA2D;IAC3D,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,OAAO,EAAE,gBAAgB,CAAC;IAC1B;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,yEAAyE;AACzE,MAAM,WAAW,gBAAgB;IAC/B,eAAe,EAAE,MAAM,CAAC;IACxB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,sFAAsF;IACtF,YAAY,EAAE,MAAM,CAAC;IACrB,8DAA8D;IAC9D,gBAAgB,EAAE,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC,CAAC;CAC5D;AAED;;;;GAIG;AACH,MAAM,WAAW,sBAAsB;IACrC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,4CAA4C;AAC5C,MAAM,WAAW,sBAAsB;IACrC,sFAAsF;IACtF,KAAK,EAAE,MAAM,CAAC;IACd,oFAAoF;IACpF,WAAW,EAAE,MAAM,CAAC;IACpB;;;;;OAKG;IACH,kBAAkB,EAAE,0BAA0B,EAAE,CAAC;IACjD,OAAO,EAAE,gBAAgB,CAAC;IAC1B,iEAAiE;IACjE,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAChC,4DAA4D;IAC5D,GAAG,EAAE,MAAM,CAAC;CACb;AAED,2GAA2G;AAC3G,eAAO,MAAM,aAAa,yyLA0C0J,CAAC;AAErL;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,sBAAsB,GAAG,MAAM,CAmCzE"}
@@ -1 +1 @@
1
- {"version":3,"file":"question.prompt.js","sourceRoot":"/","sources":["opportunity/question.prompt.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @deprecated Use QuestionerAgent and questioner presets instead. Will be removed in a future version.\n *\n * Prompt module for the decision-question generator: the system prompt\n * constant, the `DiscoveryQuestionInput` contract, and a pure string-building\n * `buildQuestionPrompt` that assembles the user message.\n *\n * Pure: no I/O, no LLM call. The generator class (`question.generator.ts`)\n * orchestrates this module + an LLM client.\n */\nimport type { ChatContextDigest } from \"../shared/schemas/chat-context.schema.js\";\nimport type { DiscoveryNegotiationDigest } from \"../shared/schemas/negotiation-digest.schema.js\";\n\n/** Roles used in the existing negotiation framework. */\nexport type NegotiationRole = \"agent\" | \"patient\" | \"peer\";\n\n/** One turn within a negotiation. */\nexport interface DiscoveryTurn {\n action: \"propose\" | \"accept\" | \"reject\" | \"counter\" | \"question\" | \"outreach\" | \"withdraw\" | \"decline\";\n reasoning: string;\n suggestedRoles: { ownUser: NegotiationRole; otherUser: NegotiationRole };\n}\n\n/** Outcome of a negotiation. */\nexport interface DiscoveryOutcome {\n hasOpportunity: boolean;\n reasoning: string;\n agreedRoles?: Array<{ userId: string; role: NegotiationRole }>;\n /** Why the negotiation stopped, when not by an explicit accept/reject. */\n reason?: \"turn_cap\" | \"timeout\";\n}\n\n/** One negotiation that ran during this discovery turn. */\nexport interface DiscoveryNegotiation {\n /** Opaque counterparty identifier; NEVER surfaced to the user (kept out of the prompt). */\n counterpartyId: string;\n /** Abstract profile slice for the LLM (e.g. \"AI infra founder, Berlin\"). */\n counterpartyHint: string;\n /** The network/community prompt this negotiation ran under. */\n indexContext: string;\n /** Last 6 turns are retained; earlier ones are dropped. */\n turns: DiscoveryTurn[];\n outcome: DiscoveryOutcome;\n /**\n * Optional pre-negotiation evaluator score (0..1). When more than\n * `MAX_NEGOTIATIONS` candidates exist, this is used as a tie-breaker after\n * `turns.length` to decide which to keep.\n */\n seedAssessmentScore?: number;\n}\n\n/** Aggregate counters across all negotiations in this discovery turn. */\nexport interface DiscoverySummary {\n totalCandidates: number;\n opportunitiesFound: number;\n noOpportunityCount: number;\n /** Subset of `noOpportunityCount` where the negotiation hit a turn-cap or timeout. */\n timeoutCount: number;\n /** Map of role → count across all outcomes' `agreedRoles`. */\n roleDistribution: Partial<Record<NegotiationRole, number>>;\n}\n\n/**\n * The seeker's profile slice the generator used to see. Retained as an exported\n * type for backward compatibility; the question prompt now consumes the global\n * `userContext` paragraph instead of these discrete fields.\n */\nexport interface DiscoverySourceProfile {\n name?: string;\n bio?: string;\n location?: string;\n skills?: string[];\n interests?: string[];\n}\n\n/** Full input to the question generator. */\nexport interface DiscoveryQuestionInput {\n /** The seeker's original natural-language query / signal that triggered discovery. */\n query: string;\n /** The seeker's global user_context paragraph (profile-replacing identity text). */\n userContext: string;\n /**\n * Compact per-negotiation digests from THIS discovery turn. Each digest is a\n * fixed-size structured summary (counterparty hint, index, outcome role,\n * keyTake) — pre-summarized so this prompt stays small regardless of how\n * many candidates were negotiated. Raw negotiations are NOT passed here.\n */\n negotiationDigests: DiscoveryNegotiationDigest[];\n summary: DiscoverySummary;\n /** Distilled chat-session digest, when a session is in scope. */\n chatContext?: ChatContextDigest;\n /** ISO timestamp used as the \"now\" anchor in the prompt. */\n now: string;\n}\n\n/** @deprecated Use QuestionerAgent and questioner presets instead. Will be removed in a future version. */\nexport const SYSTEM_PROMPT = `You help write user-facing follow-up questions after Index has reviewed potential connections for a human. Your job: surface the minimum set of structured decision questions the human must answer to make the next discovery turn sharper, or improve their outlook on the intent.\n\nYou may pick from five strategies. Choose contextually; mix when multiple questions genuinely complement.\n- refine_intent: ask the user to sharpen or pivot their original signal.\n- surface_missing_detail: ask for one concrete missing input (stage, location, timing, scope, …).\n- open_adjacent_thread: offer a pivot suggested by recurring connection signals.\n- reflective_summary: mirror what the connection review revealed and ask the user to decide.\n- surface_emergent_knowledge: cite a fact you learned from the connection review and ask the user to decide in light of it.\n\nAsk a question only when ALL of these hold:\n1. Index cannot resolve the decision autonomously from the evidence shown.\n2. The answer would materially change which people surface next.\n3. The same fact is NOT already in chatContext.statedFacts, NOT already asked in chatContext.openQuestions, and NOT already shared in chatContext.surfacedFindings.\n\nStandalone prompt rule. Every generated \\`prompt\\` must be understandable outside the conversation where it was created. Naturally include the original query, discovery pattern, connection pattern, or concrete learned fact in the question text itself. Do not rely on \\`title\\`, UI labels, hidden metadata, or surrounding digest/chat text to explain what the question is about. For example, prefer \"For your AI crypto decentralized deep-tech search, which area is most critical right now?\" over \"Which area is most critical right now?\"\n\nReferential closure. The prompt must resolve entirely on its own, with no dangling references. The reader sees ONLY the question text — never the people you reviewed, the events on their calendar, or this conversation. Do not use demonstratives or definite anaphora that point at things the reader cannot see: \"these builders\", \"those founders\", \"these researchers\", \"these conversations\", \"this lunch\", \"the speaker\". If you reference a person, name them. If you reference a group, restate the concrete shared attribute inside the question itself (\"founders working on decentralized identity\"), never \"these founders\". Never imply a list, set, or prior exchange the reader is not currently looking at.\n- Bad: \"What kind of collaboration are you looking for with these builders?\"\n- Good: \"You're meeting people building agent infrastructure — what kind of collaboration are you looking for?\"\n\nNo process narration. Never describe Index's own activity or internal state. Forbidden: \"the previous negotiation\", \"the negotiation stalled\", \"opportunities found so far\", \"my search\", \"the counterparty\", \"candidates reviewed\", restating why a match did or did not happen, or quoting words a counterparty did or did not use. Ask about the user's goal or intent directly, never about the matching pipeline.\n- Bad: \"All opportunities found so far are related to 'Edge Esmeralda'. Would you like to broaden the search?\"\n- Good: \"Do you want to focus on people at Edge Esmeralda, or also connect beyond it?\"\n\nCardinality. Default one question. Add a second only when a DIFFERENT strategy genuinely complements the first (e.g. one surface_emergent_knowledge + one refine_intent). Add a third only when there are ≥3 substantive people reviewed and three distinct strategies each unblock a real decision. Two questions of the same strategy are acceptable only if their decision domains differ (different titles). Avoid stacking three pulls (info-from-user); balance with pushes (info-to-user via reflective_summary / surface_emergent_knowledge).\n\nOrdering. Questions whose answer unblocks the most connection reviews come first; then highest-impact; then ambiguity-clarifying. Reviews that needed more detail or ran out of time signal under-specification — prioritize.\n\nUser-facing language. Every title, prompt, option label, and option description is shown directly to the user. Never mention raw protocol mechanics or internal labels such as \"agent\", \"patient\", \"peer\", \"suggestedRoles\", \"role distribution\", \"counterparty\", \"negotiation\", \"turn_cap\", \"timeout\", or \"candidate\". Use natural language instead: people, matches, connections, mutual collaboration, someone who can help, or someone seeking help.\n\nOption construction. Each option must represent a meaningfully different outcome. Suffix the safest path with \" (Recommended)\" and list it first. The description states the CONSEQUENCE of choosing the option, not its definition. 2–4 options. Never add an \"Other\" option — clients provide a free-text fallback automatically. For surface_emergent_knowledge questions, anchor the prompt in the concrete cited fact (\"Multiple people flagged that…\") and let the options represent decisions in light of that fact, not different versions of the fact.\n\nTitle rules. ≤12 chars. Noun of the decision domain. Discovery examples: \"Stage\", \"Timing\", \"Role\", \"Location\", \"Stack\", \"Budget\", \"Scope\", \"Format\".\n\nAnti-patterns — never do these.\n- Don't ask procedural confirmations (\"Should I look again?\").\n- Don't ask about hypothetical edge cases that didn't occur.\n- Don't ask about specific person identities; treat the provided person summary as the only allowed reference.\n- Don't repeat anything in chatContext.openQuestions.\n- Don't re-surface anything in chatContext.surfacedFindings.\n- Don't ask for facts in chatContext.statedFacts.\n\nOutput. Return at most 3 entries in the \"questions\" array. Each entry must include a \"strategy\" field (one of the five values). If nothing is worth asking, return \"questions\": [].`;\n\n/**\n * @deprecated Use QuestionerAgent and questioner presets instead. Will be removed in a future version.\n *\n * Pure builder: assembles the user message string from a structured input.\n */\nexport function buildQuestionPrompt(input: DiscoveryQuestionInput): string {\n const profileSummary = input.userContext?.trim() || \"(no profile data)\";\n const connectionReviewBlocks = renderConnectionReviewDigests(input.negotiationDigests);\n const chatContextBlock = input.chatContext\n ? renderDigest(input.chatContext)\n : \"(no chat context available)\";\n const engagementPattern = renderEngagementPattern(input.summary.roleDistribution);\n\n return [\n \"## Seeker's query\",\n input.query,\n \"\",\n \"## Seeker profile\",\n profileSummary,\n \"\",\n \"## This discovery turn\",\n `- ${input.summary.totalCandidates} people reviewed`,\n `- ${input.summary.opportunitiesFound} promising connections found`,\n `- ${input.summary.noOpportunityCount} reviews did not find enough fit (${input.summary.timeoutCount} needed more detail or time)`,\n `- Engagement pattern: ${engagementPattern}`,\n \"\",\n \"## Connection review evidence (compact digests)\",\n connectionReviewBlocks,\n \"\",\n \"## What the user has already said in this session\",\n chatContextBlock,\n \"\",\n \"## Now\",\n input.now,\n \"\",\n \"## Your task\",\n \"Identify the minimum set of decision questions the seeker must answer to make\",\n \"the next discovery turn sharper. Apply every rule from your system prompt\",\n \"before outputting. Return an empty `questions` array if nothing is worth asking.\",\n ].join(\"\\n\");\n}\n\n/**\n * Render the negotiation-digest collection into compact one-liners. Each digest\n * is fixed-size (≤ ~400 chars after rendering), so the rendered block scales\n * linearly with candidate count: 10 candidates ≈ 4 KB, well within budget.\n */\nfunction renderConnectionReviewDigests(digests: DiscoveryNegotiationDigest[]): string {\n if (digests.length === 0) return \"(no connection reviews)\";\n return digests\n .map((d) => {\n const relationshipSignal = d.suggestedRoles\n ? [` Relationship signal: ${renderRelationshipSignal(d.suggestedRoles)}`]\n : [];\n return [\n `- Person: ${d.counterpartyHint}`,\n ` Community context: ${d.indexContext}`,\n ` Outcome: ${renderOutcome(d)}`,\n ...relationshipSignal,\n ` Take: ${d.keyTake}`,\n ].join(\"\\n\");\n })\n .join(\"\\n\\n\");\n}\n\nfunction renderEngagementPattern(dist: Partial<Record<NegotiationRole, number>>): string {\n const parts: string[] = [];\n if ((dist.peer ?? 0) > 0) {\n parts.push(`${dist.peer} mutual collaboration${dist.peer === 1 ? \"\" : \"s\"}`);\n }\n if ((dist.agent ?? 0) > 0) {\n parts.push(`${dist.agent} where the user could offer help or expertise`);\n }\n if ((dist.patient ?? 0) > 0) {\n parts.push(`${dist.patient} where the user seemed to be seeking help or expertise`);\n }\n return parts.length > 0 ? parts.join(\", \") : \"(no engagement pattern available)\";\n}\n\nfunction renderOutcome(digest: DiscoveryNegotiationDigest): string {\n const outcome = digest.outcomeRole === \"opportunity\"\n ? \"promising connection\"\n : \"not enough fit\";\n const reason = renderOutcomeReason(digest.outcomeReason);\n return reason ? `${outcome} (${reason})` : outcome;\n}\n\nfunction renderOutcomeReason(reason: DiscoveryNegotiationDigest[\"outcomeReason\"]): string {\n switch (reason) {\n case \"turn_cap\":\n return \"needed more detail\";\n case \"timeout\":\n return \"ran out of time\";\n case \"rejected\":\n return \"not enough mutual interest\";\n case \"stalled\":\n return \"stalled\";\n case null:\n return \"\";\n }\n}\n\nfunction renderRelationshipSignal(roles: NonNullable<DiscoveryNegotiationDigest[\"suggestedRoles\"]>): string {\n if (roles.ownUser === \"peer\" && roles.otherUser === \"peer\") return \"mutual collaboration\";\n if (roles.ownUser === \"agent\" && roles.otherUser === \"patient\") {\n return \"the user could offer help or expertise\";\n }\n if (roles.ownUser === \"patient\" && roles.otherUser === \"agent\") {\n return \"the user seemed to be seeking help or expertise\";\n }\n if (roles.ownUser === \"agent\") return \"the user could offer help or expertise\";\n if (roles.ownUser === \"patient\") return \"the user seemed to be seeking help or expertise\";\n return \"collaboration fit\";\n}\n\nfunction renderDigest(d: ChatContextDigest): string {\n const lines: string[] = [];\n if (d.statedFacts.length > 0) {\n lines.push(\"Stated facts:\");\n for (const f of d.statedFacts) lines.push(` - ${f}`);\n }\n if (d.openQuestions.length > 0) {\n lines.push(\"Open questions (assistant already asked):\");\n for (const q of d.openQuestions) lines.push(` - ${q}`);\n }\n if (d.rejectionReasons.length > 0) {\n lines.push(\"User pushback / rejections:\");\n for (const r of d.rejectionReasons) lines.push(` - ${r}`);\n }\n if (d.surfacedFindings.length > 0) {\n lines.push(\"Findings already surfaced to user:\");\n for (const f of d.surfacedFindings) lines.push(` - ${f}`);\n }\n return lines.length > 0 ? lines.join(\"\\n\") : \"(digest is empty)\";\n}\n\n"]}
1
+ {"version":3,"file":"question.prompt.js","sourceRoot":"/","sources":["opportunity/question.prompt.ts"],"names":[],"mappings":"AA+FA,2GAA2G;AAC3G,MAAM,CAAC,MAAM,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oLA0CuJ,CAAC;AAErL;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,KAA6B;IAC/D,MAAM,cAAc,GAAG,KAAK,CAAC,WAAW,EAAE,IAAI,EAAE,IAAI,mBAAmB,CAAC;IACxE,MAAM,sBAAsB,GAAG,6BAA6B,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;IACvF,MAAM,gBAAgB,GAAG,KAAK,CAAC,WAAW;QACxC,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC,WAAW,CAAC;QACjC,CAAC,CAAC,6BAA6B,CAAC;IAClC,MAAM,iBAAiB,GAAG,uBAAuB,CAAC,KAAK,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAElF,OAAO;QACL,mBAAmB;QACnB,KAAK,CAAC,KAAK;QACX,EAAE;QACF,mBAAmB;QACnB,cAAc;QACd,EAAE;QACF,wBAAwB;QACxB,KAAK,KAAK,CAAC,OAAO,CAAC,eAAe,kBAAkB;QACpD,KAAK,KAAK,CAAC,OAAO,CAAC,kBAAkB,8BAA8B;QACnE,KAAK,KAAK,CAAC,OAAO,CAAC,kBAAkB,qCAAqC,KAAK,CAAC,OAAO,CAAC,YAAY,8BAA8B;QAClI,yBAAyB,iBAAiB,EAAE;QAC5C,EAAE;QACF,iDAAiD;QACjD,sBAAsB;QACtB,EAAE;QACF,mDAAmD;QACnD,gBAAgB;QAChB,EAAE;QACF,QAAQ;QACR,KAAK,CAAC,GAAG;QACT,EAAE;QACF,cAAc;QACd,+EAA+E;QAC/E,2EAA2E;QAC3E,kFAAkF;KACnF,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED;;;;GAIG;AACH,SAAS,6BAA6B,CAAC,OAAqC;IAC1E,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,yBAAyB,CAAC;IAC3D,OAAO,OAAO;SACX,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACT,MAAM,kBAAkB,GAAG,CAAC,CAAC,cAAc;YACzC,CAAC,CAAC,CAAC,0BAA0B,wBAAwB,CAAC,CAAC,CAAC,cAAc,CAAC,EAAE,CAAC;YAC1E,CAAC,CAAC,EAAE,CAAC;QACP,OAAO;YACL,aAAa,CAAC,CAAC,gBAAgB,EAAE;YACjC,wBAAwB,CAAC,CAAC,YAAY,EAAE;YACxC,cAAc,aAAa,CAAC,CAAC,CAAC,EAAE;YAChC,GAAG,kBAAkB;YACrB,WAAW,CAAC,CAAC,OAAO,EAAE;SACvB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACf,CAAC,CAAC;SACD,IAAI,CAAC,MAAM,CAAC,CAAC;AAClB,CAAC;AAED,SAAS,uBAAuB,CAAC,IAA8C;IAC7E,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;QACzB,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,wBAAwB,IAAI,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;IAC/E,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1B,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,+CAA+C,CAAC,CAAC;IAC3E,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;QAC5B,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,OAAO,wDAAwD,CAAC,CAAC;IACtF,CAAC;IACD,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,mCAAmC,CAAC;AACnF,CAAC;AAED,SAAS,aAAa,CAAC,MAAkC;IACvD,MAAM,OAAO,GAAG,MAAM,CAAC,WAAW,KAAK,aAAa;QAClD,CAAC,CAAC,sBAAsB;QACxB,CAAC,CAAC,gBAAgB,CAAC;IACrB,MAAM,MAAM,GAAG,mBAAmB,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;IACzD,OAAO,MAAM,CAAC,CAAC,CAAC,GAAG,OAAO,KAAK,MAAM,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC;AACrD,CAAC;AAED,SAAS,mBAAmB,CAAC,MAAmD;IAC9E,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,UAAU;YACb,OAAO,oBAAoB,CAAC;QAC9B,KAAK,SAAS;YACZ,OAAO,iBAAiB,CAAC;QAC3B,KAAK,UAAU;YACb,OAAO,4BAA4B,CAAC;QACtC,KAAK,SAAS;YACZ,OAAO,SAAS,CAAC;QACnB,KAAK,IAAI;YACP,OAAO,EAAE,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,wBAAwB,CAAC,KAAgE;IAChG,IAAI,KAAK,CAAC,OAAO,KAAK,MAAM,IAAI,KAAK,CAAC,SAAS,KAAK,MAAM;QAAE,OAAO,sBAAsB,CAAC;IAC1F,IAAI,KAAK,CAAC,OAAO,KAAK,OAAO,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;QAC/D,OAAO,wCAAwC,CAAC;IAClD,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,KAAK,SAAS,IAAI,KAAK,CAAC,SAAS,KAAK,OAAO,EAAE,CAAC;QAC/D,OAAO,iDAAiD,CAAC;IAC3D,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,KAAK,OAAO;QAAE,OAAO,wCAAwC,CAAC;IAC/E,IAAI,KAAK,CAAC,OAAO,KAAK,SAAS;QAAE,OAAO,iDAAiD,CAAC;IAC1F,OAAO,mBAAmB,CAAC;AAC7B,CAAC;AAED,SAAS,YAAY,CAAC,CAAoB;IACxC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,CAAC,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7B,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QAC5B,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,WAAW;YAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACxD,CAAC;IACD,IAAI,CAAC,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/B,KAAK,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAC;QACxD,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,aAAa;YAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC1D,CAAC;IACD,IAAI,CAAC,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAClC,KAAK,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;QAC1C,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,gBAAgB;YAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC7D,CAAC;IACD,IAAI,CAAC,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAClC,KAAK,CAAC,IAAI,CAAC,oCAAoC,CAAC,CAAC;QACjD,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,gBAAgB;YAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC7D,CAAC;IACD,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC;AACnE,CAAC","sourcesContent":["/**\n * @deprecated Use QuestionerAgent and questioner presets instead. Will be removed in a future version.\n *\n * Prompt module for the decision-question generator: the system prompt\n * constant, the `DiscoveryQuestionInput` contract, and a pure string-building\n * `buildQuestionPrompt` that assembles the user message.\n *\n * Pure: no I/O, no LLM call. The generator class (`question.generator.ts`)\n * orchestrates this module + an LLM client.\n */\nimport type { ChatContextDigest } from \"../shared/schemas/chat-context.schema.js\";\nimport type { DiscoveryNegotiationDigest } from \"../shared/schemas/negotiation-digest.schema.js\";\n\n/** Roles used in the existing negotiation framework. */\nexport type NegotiationRole = \"agent\" | \"patient\" | \"peer\";\n\n/** One turn within a negotiation. */\nexport interface DiscoveryTurn {\n action: \"propose\" | \"accept\" | \"reject\" | \"counter\" | \"question\" | \"outreach\" | \"withdraw\" | \"decline\" | \"ask_user\";\n reasoning: string;\n suggestedRoles: { ownUser: NegotiationRole; otherUser: NegotiationRole };\n}\n\n/** Outcome of a negotiation. */\nexport interface DiscoveryOutcome {\n hasOpportunity: boolean;\n reasoning: string;\n agreedRoles?: Array<{ userId: string; role: NegotiationRole }>;\n /** Why the negotiation stopped, when not by an explicit accept/reject. */\n reason?: \"turn_cap\" | \"timeout\";\n}\n\n/** One negotiation that ran during this discovery turn. */\nexport interface DiscoveryNegotiation {\n /** Opaque counterparty identifier; NEVER surfaced to the user (kept out of the prompt). */\n counterpartyId: string;\n /** Abstract profile slice for the LLM (e.g. \"AI infra founder, Berlin\"). */\n counterpartyHint: string;\n /** The network/community prompt this negotiation ran under. */\n indexContext: string;\n /** Last 6 turns are retained; earlier ones are dropped. */\n turns: DiscoveryTurn[];\n outcome: DiscoveryOutcome;\n /**\n * Optional pre-negotiation evaluator score (0..1). When more than\n * `MAX_NEGOTIATIONS` candidates exist, this is used as a tie-breaker after\n * `turns.length` to decide which to keep.\n */\n seedAssessmentScore?: number;\n}\n\n/** Aggregate counters across all negotiations in this discovery turn. */\nexport interface DiscoverySummary {\n totalCandidates: number;\n opportunitiesFound: number;\n noOpportunityCount: number;\n /** Subset of `noOpportunityCount` where the negotiation hit a turn-cap or timeout. */\n timeoutCount: number;\n /** Map of role → count across all outcomes' `agreedRoles`. */\n roleDistribution: Partial<Record<NegotiationRole, number>>;\n}\n\n/**\n * The seeker's profile slice the generator used to see. Retained as an exported\n * type for backward compatibility; the question prompt now consumes the global\n * `userContext` paragraph instead of these discrete fields.\n */\nexport interface DiscoverySourceProfile {\n name?: string;\n bio?: string;\n location?: string;\n skills?: string[];\n interests?: string[];\n}\n\n/** Full input to the question generator. */\nexport interface DiscoveryQuestionInput {\n /** The seeker's original natural-language query / signal that triggered discovery. */\n query: string;\n /** The seeker's global user_context paragraph (profile-replacing identity text). */\n userContext: string;\n /**\n * Compact per-negotiation digests from THIS discovery turn. Each digest is a\n * fixed-size structured summary (counterparty hint, index, outcome role,\n * keyTake) — pre-summarized so this prompt stays small regardless of how\n * many candidates were negotiated. Raw negotiations are NOT passed here.\n */\n negotiationDigests: DiscoveryNegotiationDigest[];\n summary: DiscoverySummary;\n /** Distilled chat-session digest, when a session is in scope. */\n chatContext?: ChatContextDigest;\n /** ISO timestamp used as the \"now\" anchor in the prompt. */\n now: string;\n}\n\n/** @deprecated Use QuestionerAgent and questioner presets instead. Will be removed in a future version. */\nexport const SYSTEM_PROMPT = `You help write user-facing follow-up questions after Index has reviewed potential connections for a human. Your job: surface the minimum set of structured decision questions the human must answer to make the next discovery turn sharper, or improve their outlook on the intent.\n\nYou may pick from five strategies. Choose contextually; mix when multiple questions genuinely complement.\n- refine_intent: ask the user to sharpen or pivot their original signal.\n- surface_missing_detail: ask for one concrete missing input (stage, location, timing, scope, …).\n- open_adjacent_thread: offer a pivot suggested by recurring connection signals.\n- reflective_summary: mirror what the connection review revealed and ask the user to decide.\n- surface_emergent_knowledge: cite a fact you learned from the connection review and ask the user to decide in light of it.\n\nAsk a question only when ALL of these hold:\n1. Index cannot resolve the decision autonomously from the evidence shown.\n2. The answer would materially change which people surface next.\n3. The same fact is NOT already in chatContext.statedFacts, NOT already asked in chatContext.openQuestions, and NOT already shared in chatContext.surfacedFindings.\n\nStandalone prompt rule. Every generated \\`prompt\\` must be understandable outside the conversation where it was created. Naturally include the original query, discovery pattern, connection pattern, or concrete learned fact in the question text itself. Do not rely on \\`title\\`, UI labels, hidden metadata, or surrounding digest/chat text to explain what the question is about. For example, prefer \"For your AI crypto decentralized deep-tech search, which area is most critical right now?\" over \"Which area is most critical right now?\"\n\nReferential closure. The prompt must resolve entirely on its own, with no dangling references. The reader sees ONLY the question text — never the people you reviewed, the events on their calendar, or this conversation. Do not use demonstratives or definite anaphora that point at things the reader cannot see: \"these builders\", \"those founders\", \"these researchers\", \"these conversations\", \"this lunch\", \"the speaker\". If you reference a person, name them. If you reference a group, restate the concrete shared attribute inside the question itself (\"founders working on decentralized identity\"), never \"these founders\". Never imply a list, set, or prior exchange the reader is not currently looking at.\n- Bad: \"What kind of collaboration are you looking for with these builders?\"\n- Good: \"You're meeting people building agent infrastructure — what kind of collaboration are you looking for?\"\n\nNo process narration. Never describe Index's own activity or internal state. Forbidden: \"the previous negotiation\", \"the negotiation stalled\", \"opportunities found so far\", \"my search\", \"the counterparty\", \"candidates reviewed\", restating why a match did or did not happen, or quoting words a counterparty did or did not use. Ask about the user's goal or intent directly, never about the matching pipeline.\n- Bad: \"All opportunities found so far are related to 'Edge Esmeralda'. Would you like to broaden the search?\"\n- Good: \"Do you want to focus on people at Edge Esmeralda, or also connect beyond it?\"\n\nCardinality. Default one question. Add a second only when a DIFFERENT strategy genuinely complements the first (e.g. one surface_emergent_knowledge + one refine_intent). Add a third only when there are ≥3 substantive people reviewed and three distinct strategies each unblock a real decision. Two questions of the same strategy are acceptable only if their decision domains differ (different titles). Avoid stacking three pulls (info-from-user); balance with pushes (info-to-user via reflective_summary / surface_emergent_knowledge).\n\nOrdering. Questions whose answer unblocks the most connection reviews come first; then highest-impact; then ambiguity-clarifying. Reviews that needed more detail or ran out of time signal under-specification — prioritize.\n\nUser-facing language. Every title, prompt, option label, and option description is shown directly to the user. Never mention raw protocol mechanics or internal labels such as \"agent\", \"patient\", \"peer\", \"suggestedRoles\", \"role distribution\", \"counterparty\", \"negotiation\", \"turn_cap\", \"timeout\", or \"candidate\". Use natural language instead: people, matches, connections, mutual collaboration, someone who can help, or someone seeking help.\n\nOption construction. Each option must represent a meaningfully different outcome. Suffix the safest path with \" (Recommended)\" and list it first. The description states the CONSEQUENCE of choosing the option, not its definition. 2–4 options. Never add an \"Other\" option — clients provide a free-text fallback automatically. For surface_emergent_knowledge questions, anchor the prompt in the concrete cited fact (\"Multiple people flagged that…\") and let the options represent decisions in light of that fact, not different versions of the fact.\n\nTitle rules. ≤12 chars. Noun of the decision domain. Discovery examples: \"Stage\", \"Timing\", \"Role\", \"Location\", \"Stack\", \"Budget\", \"Scope\", \"Format\".\n\nAnti-patterns — never do these.\n- Don't ask procedural confirmations (\"Should I look again?\").\n- Don't ask about hypothetical edge cases that didn't occur.\n- Don't ask about specific person identities; treat the provided person summary as the only allowed reference.\n- Don't repeat anything in chatContext.openQuestions.\n- Don't re-surface anything in chatContext.surfacedFindings.\n- Don't ask for facts in chatContext.statedFacts.\n\nOutput. Return at most 3 entries in the \"questions\" array. Each entry must include a \"strategy\" field (one of the five values). If nothing is worth asking, return \"questions\": [].`;\n\n/**\n * @deprecated Use QuestionerAgent and questioner presets instead. Will be removed in a future version.\n *\n * Pure builder: assembles the user message string from a structured input.\n */\nexport function buildQuestionPrompt(input: DiscoveryQuestionInput): string {\n const profileSummary = input.userContext?.trim() || \"(no profile data)\";\n const connectionReviewBlocks = renderConnectionReviewDigests(input.negotiationDigests);\n const chatContextBlock = input.chatContext\n ? renderDigest(input.chatContext)\n : \"(no chat context available)\";\n const engagementPattern = renderEngagementPattern(input.summary.roleDistribution);\n\n return [\n \"## Seeker's query\",\n input.query,\n \"\",\n \"## Seeker profile\",\n profileSummary,\n \"\",\n \"## This discovery turn\",\n `- ${input.summary.totalCandidates} people reviewed`,\n `- ${input.summary.opportunitiesFound} promising connections found`,\n `- ${input.summary.noOpportunityCount} reviews did not find enough fit (${input.summary.timeoutCount} needed more detail or time)`,\n `- Engagement pattern: ${engagementPattern}`,\n \"\",\n \"## Connection review evidence (compact digests)\",\n connectionReviewBlocks,\n \"\",\n \"## What the user has already said in this session\",\n chatContextBlock,\n \"\",\n \"## Now\",\n input.now,\n \"\",\n \"## Your task\",\n \"Identify the minimum set of decision questions the seeker must answer to make\",\n \"the next discovery turn sharper. Apply every rule from your system prompt\",\n \"before outputting. Return an empty `questions` array if nothing is worth asking.\",\n ].join(\"\\n\");\n}\n\n/**\n * Render the negotiation-digest collection into compact one-liners. Each digest\n * is fixed-size (≤ ~400 chars after rendering), so the rendered block scales\n * linearly with candidate count: 10 candidates ≈ 4 KB, well within budget.\n */\nfunction renderConnectionReviewDigests(digests: DiscoveryNegotiationDigest[]): string {\n if (digests.length === 0) return \"(no connection reviews)\";\n return digests\n .map((d) => {\n const relationshipSignal = d.suggestedRoles\n ? [` Relationship signal: ${renderRelationshipSignal(d.suggestedRoles)}`]\n : [];\n return [\n `- Person: ${d.counterpartyHint}`,\n ` Community context: ${d.indexContext}`,\n ` Outcome: ${renderOutcome(d)}`,\n ...relationshipSignal,\n ` Take: ${d.keyTake}`,\n ].join(\"\\n\");\n })\n .join(\"\\n\\n\");\n}\n\nfunction renderEngagementPattern(dist: Partial<Record<NegotiationRole, number>>): string {\n const parts: string[] = [];\n if ((dist.peer ?? 0) > 0) {\n parts.push(`${dist.peer} mutual collaboration${dist.peer === 1 ? \"\" : \"s\"}`);\n }\n if ((dist.agent ?? 0) > 0) {\n parts.push(`${dist.agent} where the user could offer help or expertise`);\n }\n if ((dist.patient ?? 0) > 0) {\n parts.push(`${dist.patient} where the user seemed to be seeking help or expertise`);\n }\n return parts.length > 0 ? parts.join(\", \") : \"(no engagement pattern available)\";\n}\n\nfunction renderOutcome(digest: DiscoveryNegotiationDigest): string {\n const outcome = digest.outcomeRole === \"opportunity\"\n ? \"promising connection\"\n : \"not enough fit\";\n const reason = renderOutcomeReason(digest.outcomeReason);\n return reason ? `${outcome} (${reason})` : outcome;\n}\n\nfunction renderOutcomeReason(reason: DiscoveryNegotiationDigest[\"outcomeReason\"]): string {\n switch (reason) {\n case \"turn_cap\":\n return \"needed more detail\";\n case \"timeout\":\n return \"ran out of time\";\n case \"rejected\":\n return \"not enough mutual interest\";\n case \"stalled\":\n return \"stalled\";\n case null:\n return \"\";\n }\n}\n\nfunction renderRelationshipSignal(roles: NonNullable<DiscoveryNegotiationDigest[\"suggestedRoles\"]>): string {\n if (roles.ownUser === \"peer\" && roles.otherUser === \"peer\") return \"mutual collaboration\";\n if (roles.ownUser === \"agent\" && roles.otherUser === \"patient\") {\n return \"the user could offer help or expertise\";\n }\n if (roles.ownUser === \"patient\" && roles.otherUser === \"agent\") {\n return \"the user seemed to be seeking help or expertise\";\n }\n if (roles.ownUser === \"agent\") return \"the user could offer help or expertise\";\n if (roles.ownUser === \"patient\") return \"the user seemed to be seeking help or expertise\";\n return \"collaboration fit\";\n}\n\nfunction renderDigest(d: ChatContextDigest): string {\n const lines: string[] = [];\n if (d.statedFacts.length > 0) {\n lines.push(\"Stated facts:\");\n for (const f of d.statedFacts) lines.push(` - ${f}`);\n }\n if (d.openQuestions.length > 0) {\n lines.push(\"Open questions (assistant already asked):\");\n for (const q of d.openQuestions) lines.push(` - ${q}`);\n }\n if (d.rejectionReasons.length > 0) {\n lines.push(\"User pushback / rejections:\");\n for (const r of d.rejectionReasons) lines.push(` - ${r}`);\n }\n if (d.surfacedFindings.length > 0) {\n lines.push(\"Findings already surfaced to user:\");\n for (const f of d.surfacedFindings) lines.push(` - ${f}`);\n }\n return lines.length > 0 ? lines.join(\"\\n\") : \"(digest is empty)\";\n}\n\n"]}
@@ -70,6 +70,11 @@ declare function getModelConfig(config?: ModelConfig): {
70
70
  readonly temperature: 0.2;
71
71
  readonly maxTokens: 1024;
72
72
  };
73
+ readonly negotiationReflector: {
74
+ readonly model: "google/gemini-2.5-flash";
75
+ readonly temperature: 0.3;
76
+ readonly maxTokens: 2048;
77
+ };
73
78
  readonly homeCategorizer: {
74
79
  readonly model: "google/gemini-2.5-flash";
75
80
  };
@@ -1 +1 @@
1
- {"version":3,"file":"model.config.d.ts","sourceRoot":"/","sources":["shared/agent/model.config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,KAAK,EAAE,sBAAsB,EAAE,6BAA6B,EAAE,MAAM,sCAAsC,CAAC;AAClH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAElE,iDAAiD;AACjD,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,SAAS,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;CAC7F;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,WAAW;IAC1B,oEAAoE;IACpE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,sEAAsE;IACtE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,uEAAuE;IACvE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uFAAuF;IACvF,mBAAmB,CAAC,EAAE,SAAS,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC;CACvE;AAED,iBAAS,cAAc,CAAC,MAAM,CAAC,EAAE,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6BAiCmD,WAAW,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC;;;;EAK/I;AAED,iEAAiE;AACjE,MAAM,MAAM,UAAU,GAAG,MAAM,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AAEjE;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,MAAM,CAE5E;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,UAAU,CAG/E;AAmDD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,UAAU,GAAG,SAAS,CAMnG;AAkCD;;;;;;;;;;;;;;;GAeG;AAEH,wBAAgB,qBAAqB,CAAC,SAAS,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC/F,KAAK,EAAE,UAAU,EACjB,YAAY,EAAE,cAAc,CAAC,SAAS,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjE,OAAO,CAAC,EAAE,6BAA6B,CAAC,KAAK,CAAC,EAC9C,MAAM,CAAC,EAAE,WAAW,GACnB,QAAQ,CAAC,sBAAsB,EAAE,SAAS,CAAC,CAK7C;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,UAAU,EACjB,MAAM,CAAC,EAAE,WAAW,GACnB,QAAQ,CAAC,sBAAsB,EAAE,cAAc,CAAC,CAElD"}
1
+ {"version":3,"file":"model.config.d.ts","sourceRoot":"/","sources":["shared/agent/model.config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,KAAK,EAAE,sBAAsB,EAAE,6BAA6B,EAAE,MAAM,sCAAsC,CAAC;AAClH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAElE,iDAAiD;AACjD,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,SAAS,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;CAC7F;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,WAAW;IAC1B,oEAAoE;IACpE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,sEAAsE;IACtE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,uEAAuE;IACvE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uFAAuF;IACvF,mBAAmB,CAAC,EAAE,SAAS,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC;CACvE;AAED,iBAAS,cAAc,CAAC,MAAM,CAAC,EAAE,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6BAkCmD,WAAW,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC;;;;EAK/I;AAED,iEAAiE;AACjE,MAAM,MAAM,UAAU,GAAG,MAAM,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AAEjE;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,MAAM,CAE5E;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,UAAU,CAG/E;AAmDD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,UAAU,GAAG,SAAS,CAMnG;AAkCD;;;;;;;;;;;;;;;GAeG;AAEH,wBAAgB,qBAAqB,CAAC,SAAS,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC/F,KAAK,EAAE,UAAU,EACjB,YAAY,EAAE,cAAc,CAAC,SAAS,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjE,OAAO,CAAC,EAAE,6BAA6B,CAAC,KAAK,CAAC,EAC9C,MAAM,CAAC,EAAE,WAAW,GACnB,QAAQ,CAAC,sBAAsB,EAAE,SAAS,CAAC,CAK7C;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,UAAU,EACjB,MAAM,CAAC,EAAE,WAAW,GACnB,QAAQ,CAAC,sBAAsB,EAAE,cAAc,CAAC,CAElD"}
@@ -13,6 +13,7 @@ function getModelConfig(config) {
13
13
  opportunityPresenter: { model: "google/gemini-2.5-flash" },
14
14
  negotiator: { model: "google/gemini-2.5-flash" },
15
15
  negotiationScreener: { model: "google/gemini-2.5-flash", temperature: 0.2, maxTokens: 1024 },
16
+ negotiationReflector: { model: "google/gemini-2.5-flash", temperature: 0.3, maxTokens: 2048 },
16
17
  homeCategorizer: { model: "google/gemini-2.5-flash" },
17
18
  suggestionGenerator: { model: "google/gemini-2.5-flash", temperature: 0.4, maxTokens: 512 },
18
19
  chatTitleGenerator: { model: "google/gemini-2.5-flash", temperature: 0.3, maxTokens: 32 },
@@ -1 +1 @@
1
- {"version":3,"file":"model.config.js","sourceRoot":"/","sources":["shared/agent/model.config.ts"],"names":[],"mappings":"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","sourcesContent":["import { ChatOpenAI } from \"@langchain/openai\";\nimport type { AIMessageChunk } from \"@langchain/core/messages\";\nimport type { BaseLanguageModelInput, StructuredOutputMethodOptions } from \"@langchain/core/language_models/base\";\nimport type { Runnable } from \"@langchain/core/runnables\";\nimport type { InteropZodType } from \"@langchain/core/utils/types\";\n\n/** Settings that can be configured per agent. */\nexport interface ModelSettings {\n model: string;\n temperature?: number;\n maxTokens?: number;\n reasoning?: { effort?: 'minimal' | 'low' | 'medium' | 'high' | 'xhigh'; exclude?: boolean };\n}\n\n/**\n * Runtime configuration for the protocol package.\n * When passed via `ToolContext.modelConfig`, all fields (`apiKey`, `baseURL`, `chatModel`,\n * `chatReasoningEffort`) are honored by `ChatAgent` when the chat graph runs.\n * Other protocol agents don't read from `ToolContext` but may accept an explicit `ModelConfig`\n * as a direct parameter to `createModel()`.\n * All fields fall back to environment variables if not provided.\n */\nexport interface ModelConfig {\n /** OpenRouter API key. Falls back to OPENROUTER_API_KEY env var. */\n apiKey?: string;\n /** OpenRouter base URL. Falls back to OPENROUTER_BASE_URL env var. */\n baseURL?: string;\n /** Override the chat agent model. Falls back to CHAT_MODEL env var. */\n chatModel?: string;\n /** Override the chat reasoning effort. Falls back to CHAT_REASONING_EFFORT env var. */\n chatReasoningEffort?: 'minimal' | 'low' | 'medium' | 'high' | 'xhigh';\n}\n\nfunction getModelConfig(config?: ModelConfig) {\n return {\n intentInferrer: { model: \"google/gemini-2.5-flash\" },\n intentIndexer: { model: \"google/gemini-2.5-flash\" },\n intentVerifier: { model: \"google/gemini-2.5-flash\" },\n intentReconciler: { model: \"google/gemini-2.5-flash\" },\n intentClarifier: { model: \"google/gemini-2.5-flash\" },\n profileGenerator: { model: \"google/gemini-2.5-flash\" },\n hydeGenerator: { model: \"google/gemini-2.5-flash\" },\n lensInferrer: { model: \"google/gemini-2.5-flash\" },\n opportunityEvaluator: { model: \"google/gemini-2.5-flash\" },\n opportunityPresenter: { model: \"google/gemini-2.5-flash\" },\n negotiator: { model: \"google/gemini-2.5-flash\" },\n negotiationScreener: { model: \"google/gemini-2.5-flash\", temperature: 0.2, maxTokens: 1024 },\n homeCategorizer: { model: \"google/gemini-2.5-flash\" },\n suggestionGenerator: { model: \"google/gemini-2.5-flash\", temperature: 0.4, maxTokens: 512 },\n chatTitleGenerator: { model: \"google/gemini-2.5-flash\", temperature: 0.3, maxTokens: 32 },\n negotiationInsights: { model: \"google/gemini-2.5-flash\", temperature: 0.4, maxTokens: 512 },\n chatContextSummarizer: { model: \"google/gemini-2.5-flash\", temperature: 0.2, maxTokens: 512 },\n discoveryQuestionGenerator: { model: \"google/gemini-2.5-flash\", temperature: 0.5, maxTokens: 1024 },\n questioner: { model: \"google/gemini-2.5-flash\", temperature: 0.5, maxTokens: 1024 },\n negotiationSummarizer: { model: \"google/gemini-2.5-flash\", temperature: 0.2, maxTokens: 256 },\n inviteGenerator: { model: \"google/gemini-2.5-flash\", temperature: 0.3, maxTokens: 512 },\n premiseAnalyzer: { model: \"google/gemini-2.5-flash\" },\n premiseDecomposer: { model: \"google/gemini-2.5-flash\" },\n premiseIndexer: { model: \"google/gemini-2.5-flash\" },\n userContextGenerator: { model: \"google/gemini-2.5-flash\", temperature: 0.3, maxTokens: 512 },\n networkRecommender: { model: \"google/gemini-2.5-flash\", temperature: 0.2, maxTokens: 512 },\n interruptClassifier: { model: \"google/gemini-2.5-flash\", temperature: 0.0, maxTokens: 16 },\n chat: {\n model: config?.chatModel ?? process.env.CHAT_MODEL ?? \"google/gemini-3-pro-preview\",\n maxTokens: 8192,\n reasoning: {\n effort: (config?.chatReasoningEffort ?? process.env.CHAT_REASONING_EFFORT ?? \"low\") as NonNullable<ModelSettings[\"reasoning\"]>[\"effort\"],\n exclude: true,\n },\n },\n } as const;\n}\n\n/** Key identifying one of the per-agent model configurations. */\nexport type ModelAgent = keyof ReturnType<typeof getModelConfig>;\n\n/**\n * Returns the model name string for the given agent key.\n * @param agent - Key from MODEL_CONFIG identifying which agent's settings to use.\n * @param config - Optional runtime config overrides.\n */\nexport function getModelName(agent: ModelAgent, config?: ModelConfig): string {\n return getModelConfig(config)[agent].model;\n}\n\n/**\n * Creates a ChatOpenAI instance configured for OpenRouter.\n * @param agent - Key identifying which agent's model settings to use.\n * @param config - Optional runtime config overrides.\n */\nexport function createModel(agent: ModelAgent, config?: ModelConfig): ChatOpenAI {\n const cfg = getModelConfig(config)[agent] as ModelSettings;\n return instantiateModel(agent, cfg, config);\n}\n\n/** Instantiates a ChatOpenAI from explicit settings (shared by primary + fallback creation). */\nfunction instantiateModel(agent: string, cfg: ModelSettings, config?: ModelConfig): ChatOpenAI {\n const apiKey = config?.apiKey ?? process.env.OPENROUTER_API_KEY;\n if (!apiKey?.trim()) {\n throw new Error(`createModel(${agent}): OPENROUTER_API_KEY is required. Pass via the config argument, ToolContext.modelConfig.apiKey, or set the OPENROUTER_API_KEY environment variable.`);\n }\n // Hard upper bound on a single LLM call. Without this, langchain's HTTP\n // client waits until the upstream cuts the socket (~3 minutes via\n // OpenRouter), blocking the entire chat response. 60 s is generous enough\n // for slow providers but bounds the worst case.\n const timeoutEnv = Number.parseInt(process.env.OPENROUTER_REQUEST_TIMEOUT_MS ?? \"\", 10);\n const timeout = Number.isFinite(timeoutEnv) && timeoutEnv > 0 ? timeoutEnv : 60_000;\n // ChatOpenAI defaults to maxRetries=2. That means a single hung upstream\n // provider gets retried up to 2 more times, each waiting `timeout` before\n // failing — so worst-case latency becomes timeout * 3. Cap retries at 1\n // so the worst case stays bounded at ~2 * timeout. Configurable via\n // OPENROUTER_MAX_RETRIES.\n const retriesEnv = Number.parseInt(process.env.OPENROUTER_MAX_RETRIES ?? \"\", 10);\n const maxRetries = Number.isFinite(retriesEnv) && retriesEnv >= 0 ? retriesEnv : 1;\n return new ChatOpenAI({\n model: cfg.model,\n configuration: {\n baseURL: config?.baseURL ?? process.env.OPENROUTER_BASE_URL ?? \"https://openrouter.ai/api/v1\",\n apiKey,\n },\n temperature: cfg.temperature,\n maxTokens: cfg.maxTokens,\n timeout,\n maxRetries,\n ...(cfg.reasoning && { modelKwargs: { reasoning: cfg.reasoning } }),\n });\n}\n\n/**\n * Default cross-vendor fallback model. The per-agent primaries run on Google's\n * provider lane (gemini-2.5-flash); a same-key OpenRouter fallback on a\n * different vendor survives Google-side outages.\n * Override via OPENROUTER_FALLBACK_MODEL; set it to \"none\" (or \"off\") to disable.\n */\nconst DEFAULT_FALLBACK_MODEL = \"openai/gpt-4o-mini\";\n\nfunction getFallbackModelName(): string | undefined {\n const raw = process.env.OPENROUTER_FALLBACK_MODEL;\n if (raw === undefined) return DEFAULT_FALLBACK_MODEL;\n const value = raw.trim();\n if (!value || value.toLowerCase() === \"none\" || value.toLowerCase() === \"off\") return undefined;\n return value;\n}\n\n/**\n * Creates the fallback ChatOpenAI for an agent, or undefined when fallbacks\n * are disabled or the fallback would be the same model as the primary.\n * Reuses the agent's sampling settings but drops `reasoning` kwargs, which are\n * primary-model specific.\n */\nexport function createFallbackModel(agent: ModelAgent, config?: ModelConfig): ChatOpenAI | undefined {\n const fallbackName = getFallbackModelName();\n if (!fallbackName) return undefined;\n const cfg = getModelConfig(config)[agent] as ModelSettings;\n if (cfg.model === fallbackName) return undefined;\n return instantiateModel(agent, { ...cfg, model: fallbackName, reasoning: undefined }, config);\n}\n\n/**\n * Number of attempts (1 = no retry) for runnable-level retries added by\n * `createStructuredModel` / `createResilientModel`. These wrap ChatOpenAI's\n * own HTTP-level `maxRetries` and additionally cover structured-output\n * parse/validation failures. Configurable via OPENROUTER_RUNNABLE_MAX_ATTEMPTS.\n */\nfunction getRunnableMaxAttempts(): number {\n const env = Number.parseInt(process.env.OPENROUTER_RUNNABLE_MAX_ATTEMPTS ?? \"\", 10);\n return Number.isFinite(env) && env >= 1 ? env : 2;\n}\n\n/**\n * Stops runnable-level retries when the failure was a caller abort —\n * retrying a cancelled request only delays cancellation. Thrown errors from\n * `onFailedAttempt` abort the retry loop.\n */\nfunction abortAwareFailedAttemptHandler(error: Error): void {\n if (error?.name === \"AbortError\" || error?.name === \"APIUserAbortError\") throw error;\n}\n\nfunction withResilience<RunOutput>(\n primary: Runnable<BaseLanguageModelInput, RunOutput>,\n fallback: Runnable<BaseLanguageModelInput, RunOutput> | undefined,\n): Runnable<BaseLanguageModelInput, RunOutput> {\n const attempts = getRunnableMaxAttempts();\n let runnable: Runnable<BaseLanguageModelInput, RunOutput> = attempts > 1\n ? primary.withRetry({ stopAfterAttempt: attempts, onFailedAttempt: abortAwareFailedAttemptHandler })\n : primary;\n if (fallback) runnable = runnable.withFallbacks([fallback]);\n return runnable;\n}\n\n/**\n * Creates a structured-output model with runnable-level retry and cross-model\n * fallback. Equivalent to `createModel(agent).withStructuredOutput(schema, options)`\n * plus `.withRetry(...)` and `.withFallbacks([...])`.\n *\n * Retry covers transient provider errors *and* schema parse/validation\n * failures; the fallback model (see OPENROUTER_FALLBACK_MODEL) is bound to the\n * same schema so a provider outage degrades to a different vendor instead of\n * failing the call. Abort signals pass through: aborts are never retried and\n * skip the fallback.\n *\n * @param agent - Key identifying which agent's model settings to use.\n * @param outputSchema - Zod schema or JSON-schema response format.\n * @param options - Same options as `withStructuredOutput` (e.g. `{ name }`).\n * @param config - Optional runtime model config overrides.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any -- mirrors ChatOpenAI.withStructuredOutput's constraint; `unknown` rejects zod-inferred interface types\nexport function createStructuredModel<RunOutput extends Record<string, any> = Record<string, any>>(\n agent: ModelAgent,\n outputSchema: InteropZodType<RunOutput> | Record<string, unknown>,\n options?: StructuredOutputMethodOptions<false>,\n config?: ModelConfig,\n): Runnable<BaseLanguageModelInput, RunOutput> {\n const primary = createModel(agent, config).withStructuredOutput<RunOutput>(outputSchema, options);\n const fallbackModel = createFallbackModel(agent, config);\n const fallback = fallbackModel?.withStructuredOutput<RunOutput>(outputSchema, options);\n return withResilience(primary, fallback);\n}\n\n/**\n * Creates a plain-completion model with runnable-level retry and cross-model\n * fallback, for call sites that `invoke()` the model directly (no\n * `withStructuredOutput`/`bindTools`/`stream` chaining).\n *\n * @param agent - Key identifying which agent's model settings to use.\n * @param config - Optional runtime model config overrides.\n */\nexport function createResilientModel(\n agent: ModelAgent,\n config?: ModelConfig,\n): Runnable<BaseLanguageModelInput, AIMessageChunk> {\n return withResilience(createModel(agent, config), createFallbackModel(agent, config));\n}\n"]}
1
+ {"version":3,"file":"model.config.js","sourceRoot":"/","sources":["shared/agent/model.config.ts"],"names":[],"mappings":"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","sourcesContent":["import { ChatOpenAI } from \"@langchain/openai\";\nimport type { AIMessageChunk } from \"@langchain/core/messages\";\nimport type { BaseLanguageModelInput, StructuredOutputMethodOptions } from \"@langchain/core/language_models/base\";\nimport type { Runnable } from \"@langchain/core/runnables\";\nimport type { InteropZodType } from \"@langchain/core/utils/types\";\n\n/** Settings that can be configured per agent. */\nexport interface ModelSettings {\n model: string;\n temperature?: number;\n maxTokens?: number;\n reasoning?: { effort?: 'minimal' | 'low' | 'medium' | 'high' | 'xhigh'; exclude?: boolean };\n}\n\n/**\n * Runtime configuration for the protocol package.\n * When passed via `ToolContext.modelConfig`, all fields (`apiKey`, `baseURL`, `chatModel`,\n * `chatReasoningEffort`) are honored by `ChatAgent` when the chat graph runs.\n * Other protocol agents don't read from `ToolContext` but may accept an explicit `ModelConfig`\n * as a direct parameter to `createModel()`.\n * All fields fall back to environment variables if not provided.\n */\nexport interface ModelConfig {\n /** OpenRouter API key. Falls back to OPENROUTER_API_KEY env var. */\n apiKey?: string;\n /** OpenRouter base URL. Falls back to OPENROUTER_BASE_URL env var. */\n baseURL?: string;\n /** Override the chat agent model. Falls back to CHAT_MODEL env var. */\n chatModel?: string;\n /** Override the chat reasoning effort. Falls back to CHAT_REASONING_EFFORT env var. */\n chatReasoningEffort?: 'minimal' | 'low' | 'medium' | 'high' | 'xhigh';\n}\n\nfunction getModelConfig(config?: ModelConfig) {\n return {\n intentInferrer: { model: \"google/gemini-2.5-flash\" },\n intentIndexer: { model: \"google/gemini-2.5-flash\" },\n intentVerifier: { model: \"google/gemini-2.5-flash\" },\n intentReconciler: { model: \"google/gemini-2.5-flash\" },\n intentClarifier: { model: \"google/gemini-2.5-flash\" },\n profileGenerator: { model: \"google/gemini-2.5-flash\" },\n hydeGenerator: { model: \"google/gemini-2.5-flash\" },\n lensInferrer: { model: \"google/gemini-2.5-flash\" },\n opportunityEvaluator: { model: \"google/gemini-2.5-flash\" },\n opportunityPresenter: { model: \"google/gemini-2.5-flash\" },\n negotiator: { model: \"google/gemini-2.5-flash\" },\n negotiationScreener: { model: \"google/gemini-2.5-flash\", temperature: 0.2, maxTokens: 1024 },\n negotiationReflector: { model: \"google/gemini-2.5-flash\", temperature: 0.3, maxTokens: 2048 },\n homeCategorizer: { model: \"google/gemini-2.5-flash\" },\n suggestionGenerator: { model: \"google/gemini-2.5-flash\", temperature: 0.4, maxTokens: 512 },\n chatTitleGenerator: { model: \"google/gemini-2.5-flash\", temperature: 0.3, maxTokens: 32 },\n negotiationInsights: { model: \"google/gemini-2.5-flash\", temperature: 0.4, maxTokens: 512 },\n chatContextSummarizer: { model: \"google/gemini-2.5-flash\", temperature: 0.2, maxTokens: 512 },\n discoveryQuestionGenerator: { model: \"google/gemini-2.5-flash\", temperature: 0.5, maxTokens: 1024 },\n questioner: { model: \"google/gemini-2.5-flash\", temperature: 0.5, maxTokens: 1024 },\n negotiationSummarizer: { model: \"google/gemini-2.5-flash\", temperature: 0.2, maxTokens: 256 },\n inviteGenerator: { model: \"google/gemini-2.5-flash\", temperature: 0.3, maxTokens: 512 },\n premiseAnalyzer: { model: \"google/gemini-2.5-flash\" },\n premiseDecomposer: { model: \"google/gemini-2.5-flash\" },\n premiseIndexer: { model: \"google/gemini-2.5-flash\" },\n userContextGenerator: { model: \"google/gemini-2.5-flash\", temperature: 0.3, maxTokens: 512 },\n networkRecommender: { model: \"google/gemini-2.5-flash\", temperature: 0.2, maxTokens: 512 },\n interruptClassifier: { model: \"google/gemini-2.5-flash\", temperature: 0.0, maxTokens: 16 },\n chat: {\n model: config?.chatModel ?? process.env.CHAT_MODEL ?? \"google/gemini-3-pro-preview\",\n maxTokens: 8192,\n reasoning: {\n effort: (config?.chatReasoningEffort ?? process.env.CHAT_REASONING_EFFORT ?? \"low\") as NonNullable<ModelSettings[\"reasoning\"]>[\"effort\"],\n exclude: true,\n },\n },\n } as const;\n}\n\n/** Key identifying one of the per-agent model configurations. */\nexport type ModelAgent = keyof ReturnType<typeof getModelConfig>;\n\n/**\n * Returns the model name string for the given agent key.\n * @param agent - Key from MODEL_CONFIG identifying which agent's settings to use.\n * @param config - Optional runtime config overrides.\n */\nexport function getModelName(agent: ModelAgent, config?: ModelConfig): string {\n return getModelConfig(config)[agent].model;\n}\n\n/**\n * Creates a ChatOpenAI instance configured for OpenRouter.\n * @param agent - Key identifying which agent's model settings to use.\n * @param config - Optional runtime config overrides.\n */\nexport function createModel(agent: ModelAgent, config?: ModelConfig): ChatOpenAI {\n const cfg = getModelConfig(config)[agent] as ModelSettings;\n return instantiateModel(agent, cfg, config);\n}\n\n/** Instantiates a ChatOpenAI from explicit settings (shared by primary + fallback creation). */\nfunction instantiateModel(agent: string, cfg: ModelSettings, config?: ModelConfig): ChatOpenAI {\n const apiKey = config?.apiKey ?? process.env.OPENROUTER_API_KEY;\n if (!apiKey?.trim()) {\n throw new Error(`createModel(${agent}): OPENROUTER_API_KEY is required. Pass via the config argument, ToolContext.modelConfig.apiKey, or set the OPENROUTER_API_KEY environment variable.`);\n }\n // Hard upper bound on a single LLM call. Without this, langchain's HTTP\n // client waits until the upstream cuts the socket (~3 minutes via\n // OpenRouter), blocking the entire chat response. 60 s is generous enough\n // for slow providers but bounds the worst case.\n const timeoutEnv = Number.parseInt(process.env.OPENROUTER_REQUEST_TIMEOUT_MS ?? \"\", 10);\n const timeout = Number.isFinite(timeoutEnv) && timeoutEnv > 0 ? timeoutEnv : 60_000;\n // ChatOpenAI defaults to maxRetries=2. That means a single hung upstream\n // provider gets retried up to 2 more times, each waiting `timeout` before\n // failing — so worst-case latency becomes timeout * 3. Cap retries at 1\n // so the worst case stays bounded at ~2 * timeout. Configurable via\n // OPENROUTER_MAX_RETRIES.\n const retriesEnv = Number.parseInt(process.env.OPENROUTER_MAX_RETRIES ?? \"\", 10);\n const maxRetries = Number.isFinite(retriesEnv) && retriesEnv >= 0 ? retriesEnv : 1;\n return new ChatOpenAI({\n model: cfg.model,\n configuration: {\n baseURL: config?.baseURL ?? process.env.OPENROUTER_BASE_URL ?? \"https://openrouter.ai/api/v1\",\n apiKey,\n },\n temperature: cfg.temperature,\n maxTokens: cfg.maxTokens,\n timeout,\n maxRetries,\n ...(cfg.reasoning && { modelKwargs: { reasoning: cfg.reasoning } }),\n });\n}\n\n/**\n * Default cross-vendor fallback model. The per-agent primaries run on Google's\n * provider lane (gemini-2.5-flash); a same-key OpenRouter fallback on a\n * different vendor survives Google-side outages.\n * Override via OPENROUTER_FALLBACK_MODEL; set it to \"none\" (or \"off\") to disable.\n */\nconst DEFAULT_FALLBACK_MODEL = \"openai/gpt-4o-mini\";\n\nfunction getFallbackModelName(): string | undefined {\n const raw = process.env.OPENROUTER_FALLBACK_MODEL;\n if (raw === undefined) return DEFAULT_FALLBACK_MODEL;\n const value = raw.trim();\n if (!value || value.toLowerCase() === \"none\" || value.toLowerCase() === \"off\") return undefined;\n return value;\n}\n\n/**\n * Creates the fallback ChatOpenAI for an agent, or undefined when fallbacks\n * are disabled or the fallback would be the same model as the primary.\n * Reuses the agent's sampling settings but drops `reasoning` kwargs, which are\n * primary-model specific.\n */\nexport function createFallbackModel(agent: ModelAgent, config?: ModelConfig): ChatOpenAI | undefined {\n const fallbackName = getFallbackModelName();\n if (!fallbackName) return undefined;\n const cfg = getModelConfig(config)[agent] as ModelSettings;\n if (cfg.model === fallbackName) return undefined;\n return instantiateModel(agent, { ...cfg, model: fallbackName, reasoning: undefined }, config);\n}\n\n/**\n * Number of attempts (1 = no retry) for runnable-level retries added by\n * `createStructuredModel` / `createResilientModel`. These wrap ChatOpenAI's\n * own HTTP-level `maxRetries` and additionally cover structured-output\n * parse/validation failures. Configurable via OPENROUTER_RUNNABLE_MAX_ATTEMPTS.\n */\nfunction getRunnableMaxAttempts(): number {\n const env = Number.parseInt(process.env.OPENROUTER_RUNNABLE_MAX_ATTEMPTS ?? \"\", 10);\n return Number.isFinite(env) && env >= 1 ? env : 2;\n}\n\n/**\n * Stops runnable-level retries when the failure was a caller abort —\n * retrying a cancelled request only delays cancellation. Thrown errors from\n * `onFailedAttempt` abort the retry loop.\n */\nfunction abortAwareFailedAttemptHandler(error: Error): void {\n if (error?.name === \"AbortError\" || error?.name === \"APIUserAbortError\") throw error;\n}\n\nfunction withResilience<RunOutput>(\n primary: Runnable<BaseLanguageModelInput, RunOutput>,\n fallback: Runnable<BaseLanguageModelInput, RunOutput> | undefined,\n): Runnable<BaseLanguageModelInput, RunOutput> {\n const attempts = getRunnableMaxAttempts();\n let runnable: Runnable<BaseLanguageModelInput, RunOutput> = attempts > 1\n ? primary.withRetry({ stopAfterAttempt: attempts, onFailedAttempt: abortAwareFailedAttemptHandler })\n : primary;\n if (fallback) runnable = runnable.withFallbacks([fallback]);\n return runnable;\n}\n\n/**\n * Creates a structured-output model with runnable-level retry and cross-model\n * fallback. Equivalent to `createModel(agent).withStructuredOutput(schema, options)`\n * plus `.withRetry(...)` and `.withFallbacks([...])`.\n *\n * Retry covers transient provider errors *and* schema parse/validation\n * failures; the fallback model (see OPENROUTER_FALLBACK_MODEL) is bound to the\n * same schema so a provider outage degrades to a different vendor instead of\n * failing the call. Abort signals pass through: aborts are never retried and\n * skip the fallback.\n *\n * @param agent - Key identifying which agent's model settings to use.\n * @param outputSchema - Zod schema or JSON-schema response format.\n * @param options - Same options as `withStructuredOutput` (e.g. `{ name }`).\n * @param config - Optional runtime model config overrides.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any -- mirrors ChatOpenAI.withStructuredOutput's constraint; `unknown` rejects zod-inferred interface types\nexport function createStructuredModel<RunOutput extends Record<string, any> = Record<string, any>>(\n agent: ModelAgent,\n outputSchema: InteropZodType<RunOutput> | Record<string, unknown>,\n options?: StructuredOutputMethodOptions<false>,\n config?: ModelConfig,\n): Runnable<BaseLanguageModelInput, RunOutput> {\n const primary = createModel(agent, config).withStructuredOutput<RunOutput>(outputSchema, options);\n const fallbackModel = createFallbackModel(agent, config);\n const fallback = fallbackModel?.withStructuredOutput<RunOutput>(outputSchema, options);\n return withResilience(primary, fallback);\n}\n\n/**\n * Creates a plain-completion model with runnable-level retry and cross-model\n * fallback, for call sites that `invoke()` the model directly (no\n * `withStructuredOutput`/`bindTools`/`stream` chaining).\n *\n * @param agent - Key identifying which agent's model settings to use.\n * @param config - Optional runtime model config overrides.\n */\nexport function createResilientModel(\n agent: ModelAgent,\n config?: ModelConfig,\n): Runnable<BaseLanguageModelInput, AIMessageChunk> {\n return withResilience(createModel(agent, config), createFallbackModel(agent, config));\n}\n"]}
@@ -22,5 +22,35 @@ export interface NegotiationTimeoutQueue {
22
22
  * @param negotiationId - The negotiation task ID
23
23
  */
24
24
  cancelTimeout(negotiationId: string): Promise<void>;
25
+ /**
26
+ * Arm the answer-window timer for an `ask_user` pause (P3.2). Fires after
27
+ * `delayMs` (typically 24 h); the worker resumes the negotiation with a
28
+ * conservative no-disclosure default when the task is still
29
+ * `input_required`, and no-ops otherwise (stale job).
30
+ *
31
+ * Optional so fakes and pre-P3.2 implementations stay valid; the graph only
32
+ * offers `ask_user` when this method is present.
33
+ *
34
+ * @param negotiationId - The paused negotiation task ID
35
+ * @param payload - Resume coordinates + observability context
36
+ * @param delayMs - Delay before the expiry fires
37
+ * @returns The job ID for cancellation
38
+ */
39
+ enqueueAskUserExpiry?(negotiationId: string, payload: AskUserExpiryPayload, delayMs: number): Promise<string>;
40
+ /**
41
+ * Cancel a pending ask_user answer-window timer (the client answered in
42
+ * time, or the negotiation reached a terminal state another way).
43
+ * @param negotiationId - The paused negotiation task ID
44
+ */
45
+ cancelAskUserExpiry?(negotiationId: string): Promise<void>;
46
+ }
47
+ /** Payload carried by an ask_user answer-window expiry job. */
48
+ export interface AskUserExpiryPayload {
49
+ /** Opportunity to resume via the run-existing continuation path. */
50
+ opportunityId: string;
51
+ /** The asking side's client (the user who was asked and did not answer). */
52
+ userId: string;
53
+ /** What the negotiator wanted permission to share / needed to know. */
54
+ disclosureSubject: string;
25
55
  }
26
56
  //# sourceMappingURL=negotiation-events.interface.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"negotiation-events.interface.d.ts","sourceRoot":"/","sources":["shared/interfaces/negotiation-events.interface.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;GAIG;AACH,MAAM,WAAW,uBAAuB;IACtC;;;;;;OAMG;IACH,cAAc,CAAC,aAAa,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAE5F;;;OAGG;IACH,aAAa,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACrD"}
1
+ {"version":3,"file":"negotiation-events.interface.d.ts","sourceRoot":"/","sources":["shared/interfaces/negotiation-events.interface.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;GAIG;AACH,MAAM,WAAW,uBAAuB;IACtC;;;;;;OAMG;IACH,cAAc,CAAC,aAAa,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAE5F;;;OAGG;IACH,aAAa,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEpD;;;;;;;;;;;;;OAaG;IACH,oBAAoB,CAAC,CACnB,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,oBAAoB,EAC7B,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,CAAC,CAAC;IAEnB;;;;OAIG;IACH,mBAAmB,CAAC,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5D;AAED,+DAA+D;AAC/D,MAAM,WAAW,oBAAoB;IACnC,oEAAoE;IACpE,aAAa,EAAE,MAAM,CAAC;IACtB,4EAA4E;IAC5E,MAAM,EAAE,MAAM,CAAC;IACf,uEAAuE;IACvE,iBAAiB,EAAE,MAAM,CAAC;CAC3B"}
@@ -1 +1 @@
1
- {"version":3,"file":"negotiation-events.interface.js","sourceRoot":"/","sources":["shared/interfaces/negotiation-events.interface.ts"],"names":[],"mappings":"AAAA;;;;GAIG","sourcesContent":["/**\n * Interfaces for negotiation yield/resume support.\n * Used by the negotiation graph and dispatcher to manage timeouts\n * for external agents that haven't responded yet.\n */\n\n/**\n * Manages delayed timeout jobs for negotiations waiting on external agents.\n * When a negotiation yields, a timeout is enqueued. If the external agent\n * responds before the timeout, the job is cancelled.\n */\nexport interface NegotiationTimeoutQueue {\n /**\n * Enqueue a delayed timeout job.\n * @param negotiationId - The negotiation task ID\n * @param turnNumber - Current turn number (used to detect stale jobs)\n * @param delayMs - Delay in milliseconds before the timeout fires\n * @returns The BullMQ job ID for cancellation\n */\n enqueueTimeout(negotiationId: string, turnNumber: number, delayMs: number): Promise<string>;\n\n /**\n * Cancel a pending timeout job for a negotiation.\n * @param negotiationId - The negotiation task ID\n */\n cancelTimeout(negotiationId: string): Promise<void>;\n}\n"]}
1
+ {"version":3,"file":"negotiation-events.interface.js","sourceRoot":"/","sources":["shared/interfaces/negotiation-events.interface.ts"],"names":[],"mappings":"AAAA;;;;GAIG","sourcesContent":["/**\n * Interfaces for negotiation yield/resume support.\n * Used by the negotiation graph and dispatcher to manage timeouts\n * for external agents that haven't responded yet.\n */\n\n/**\n * Manages delayed timeout jobs for negotiations waiting on external agents.\n * When a negotiation yields, a timeout is enqueued. If the external agent\n * responds before the timeout, the job is cancelled.\n */\nexport interface NegotiationTimeoutQueue {\n /**\n * Enqueue a delayed timeout job.\n * @param negotiationId - The negotiation task ID\n * @param turnNumber - Current turn number (used to detect stale jobs)\n * @param delayMs - Delay in milliseconds before the timeout fires\n * @returns The BullMQ job ID for cancellation\n */\n enqueueTimeout(negotiationId: string, turnNumber: number, delayMs: number): Promise<string>;\n\n /**\n * Cancel a pending timeout job for a negotiation.\n * @param negotiationId - The negotiation task ID\n */\n cancelTimeout(negotiationId: string): Promise<void>;\n\n /**\n * Arm the answer-window timer for an `ask_user` pause (P3.2). Fires after\n * `delayMs` (typically 24 h); the worker resumes the negotiation with a\n * conservative no-disclosure default when the task is still\n * `input_required`, and no-ops otherwise (stale job).\n *\n * Optional so fakes and pre-P3.2 implementations stay valid; the graph only\n * offers `ask_user` when this method is present.\n *\n * @param negotiationId - The paused negotiation task ID\n * @param payload - Resume coordinates + observability context\n * @param delayMs - Delay before the expiry fires\n * @returns The job ID for cancellation\n */\n enqueueAskUserExpiry?(\n negotiationId: string,\n payload: AskUserExpiryPayload,\n delayMs: number,\n ): Promise<string>;\n\n /**\n * Cancel a pending ask_user answer-window timer (the client answered in\n * time, or the negotiation reached a terminal state another way).\n * @param negotiationId - The paused negotiation task ID\n */\n cancelAskUserExpiry?(negotiationId: string): Promise<void>;\n}\n\n/** Payload carried by an ask_user answer-window expiry job. */\nexport interface AskUserExpiryPayload {\n /** Opportunity to resume via the run-existing continuation path. */\n opportunityId: string;\n /** The asking side's client (the user who was asked and did not answer). */\n userId: string;\n /** What the negotiator wanted permission to share / needed to know. */\n disclosureSubject: string;\n}\n"]}
@@ -10,7 +10,7 @@ import type { ChatContextDigest } from "./chat-context.schema.js";
10
10
  export declare const NegotiationRoleSchema: z.ZodEnum<["agent", "patient", "peer"]>;
11
11
  export type NegotiationRole = z.infer<typeof NegotiationRoleSchema>;
12
12
  export declare const DiscoveryTurnSchema: z.ZodObject<{
13
- action: z.ZodEnum<["propose", "accept", "reject", "counter", "question", "outreach", "withdraw", "decline"]>;
13
+ action: z.ZodEnum<["propose", "accept", "reject", "counter", "question", "outreach", "withdraw", "decline", "ask_user"]>;
14
14
  reasoning: z.ZodString;
15
15
  suggestedRoles: z.ZodObject<{
16
16
  ownUser: z.ZodEnum<["agent", "patient", "peer"]>;
@@ -24,14 +24,14 @@ export declare const DiscoveryTurnSchema: z.ZodObject<{
24
24
  }>;
25
25
  }, "strip", z.ZodTypeAny, {
26
26
  reasoning: string;
27
- action: "propose" | "accept" | "reject" | "counter" | "question" | "outreach" | "withdraw" | "decline";
27
+ action: "propose" | "accept" | "reject" | "counter" | "question" | "outreach" | "withdraw" | "decline" | "ask_user";
28
28
  suggestedRoles: {
29
29
  ownUser: "agent" | "patient" | "peer";
30
30
  otherUser: "agent" | "patient" | "peer";
31
31
  };
32
32
  }, {
33
33
  reasoning: string;
34
- action: "propose" | "accept" | "reject" | "counter" | "question" | "outreach" | "withdraw" | "decline";
34
+ action: "propose" | "accept" | "reject" | "counter" | "question" | "outreach" | "withdraw" | "decline" | "ask_user";
35
35
  suggestedRoles: {
36
36
  ownUser: "agent" | "patient" | "peer";
37
37
  otherUser: "agent" | "patient" | "peer";
@@ -75,7 +75,7 @@ export declare const DiscoveryNegotiationSchema: z.ZodObject<{
75
75
  counterpartyHint: z.ZodString;
76
76
  indexContext: z.ZodString;
77
77
  turns: z.ZodArray<z.ZodObject<{
78
- action: z.ZodEnum<["propose", "accept", "reject", "counter", "question", "outreach", "withdraw", "decline"]>;
78
+ action: z.ZodEnum<["propose", "accept", "reject", "counter", "question", "outreach", "withdraw", "decline", "ask_user"]>;
79
79
  reasoning: z.ZodString;
80
80
  suggestedRoles: z.ZodObject<{
81
81
  ownUser: z.ZodEnum<["agent", "patient", "peer"]>;
@@ -89,14 +89,14 @@ export declare const DiscoveryNegotiationSchema: z.ZodObject<{
89
89
  }>;
90
90
  }, "strip", z.ZodTypeAny, {
91
91
  reasoning: string;
92
- action: "propose" | "accept" | "reject" | "counter" | "question" | "outreach" | "withdraw" | "decline";
92
+ action: "propose" | "accept" | "reject" | "counter" | "question" | "outreach" | "withdraw" | "decline" | "ask_user";
93
93
  suggestedRoles: {
94
94
  ownUser: "agent" | "patient" | "peer";
95
95
  otherUser: "agent" | "patient" | "peer";
96
96
  };
97
97
  }, {
98
98
  reasoning: string;
99
- action: "propose" | "accept" | "reject" | "counter" | "question" | "outreach" | "withdraw" | "decline";
99
+ action: "propose" | "accept" | "reject" | "counter" | "question" | "outreach" | "withdraw" | "decline" | "ask_user";
100
100
  suggestedRoles: {
101
101
  ownUser: "agent" | "patient" | "peer";
102
102
  otherUser: "agent" | "patient" | "peer";
@@ -148,7 +148,7 @@ export declare const DiscoveryNegotiationSchema: z.ZodObject<{
148
148
  indexContext: string;
149
149
  turns: {
150
150
  reasoning: string;
151
- action: "propose" | "accept" | "reject" | "counter" | "question" | "outreach" | "withdraw" | "decline";
151
+ action: "propose" | "accept" | "reject" | "counter" | "question" | "outreach" | "withdraw" | "decline" | "ask_user";
152
152
  suggestedRoles: {
153
153
  ownUser: "agent" | "patient" | "peer";
154
154
  otherUser: "agent" | "patient" | "peer";
@@ -170,7 +170,7 @@ export declare const DiscoveryNegotiationSchema: z.ZodObject<{
170
170
  indexContext: string;
171
171
  turns: {
172
172
  reasoning: string;
173
- action: "propose" | "accept" | "reject" | "counter" | "question" | "outreach" | "withdraw" | "decline";
173
+ action: "propose" | "accept" | "reject" | "counter" | "question" | "outreach" | "withdraw" | "decline" | "ask_user";
174
174
  suggestedRoles: {
175
175
  ownUser: "agent" | "patient" | "peer";
176
176
  otherUser: "agent" | "patient" | "peer";
@@ -8,7 +8,7 @@ import { z } from "zod";
8
8
  // ─── Primitives ───────────────────────────────────────────────────────────────
9
9
  export const NegotiationRoleSchema = z.enum(["agent", "patient", "peer"]);
10
10
  export const DiscoveryTurnSchema = z.object({
11
- action: z.enum(["propose", "accept", "reject", "counter", "question", "outreach", "withdraw", "decline"]),
11
+ action: z.enum(["propose", "accept", "reject", "counter", "question", "outreach", "withdraw", "decline", "ask_user"]),
12
12
  reasoning: z.string(),
13
13
  suggestedRoles: z.object({
14
14
  ownUser: NegotiationRoleSchema,
@@ -1 +1 @@
1
- {"version":3,"file":"discovery-question.schema.js","sourceRoot":"/","sources":["shared/schemas/discovery-question.schema.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,iFAAiF;AAEjF,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC;AAG1E,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1C,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;IACzG,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB,cAAc,EAAE,CAAC,CAAC,MAAM,CAAC;QACvB,OAAO,EAAE,qBAAqB;QAC9B,SAAS,EAAE,qBAAqB;KACjC,CAAC;CACH,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC7C,cAAc,EAAE,CAAC,CAAC,OAAO,EAAE;IAC3B,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB,WAAW,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;QAC5B,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;QAClB,IAAI,EAAE,qBAAqB;KAC5B,CAAC,CAAC,CAAC,QAAQ,EAAE;IACd,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC,CAAC,QAAQ,EAAE;CACnD,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,CAAC,MAAM,CAAC;IACjD,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE;IAC1B,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE;IAC5B,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE;IACxB,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,mBAAmB,CAAC;IACnC,OAAO,EAAE,sBAAsB;IAC/B,mBAAmB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC3C,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC7C,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE;IAC3B,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE;IAC9B,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE;IAC9B,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE;IACxB,gBAAgB,EAAE,CAAC,CAAC,MAAM,CAAC,qBAAqB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;CAC9D,CAAC,CAAC;AASH,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAC,CAAC,MAAM,CAAC;IACnD,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC3B,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC1B,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC/B,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;IACtC,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;CAC1C,CAAC,CAAC","sourcesContent":["/**\n * DiscoveryQuestionInput and nested types.\n * Leaf types have full Zod schemas. The composite DiscoveryQuestionInput is\n * a pure interface referencing cross-schema types (DiscoveryNegotiationDigest,\n * ChatContextDigest) to avoid Zod cross-schema runtime coupling.\n */\nimport { z } from \"zod\";\nimport type { DiscoveryNegotiationDigest } from \"./negotiation-digest.schema.js\";\nimport type { ChatContextDigest } from \"./chat-context.schema.js\";\n\n// ─── Primitives ───────────────────────────────────────────────────────────────\n\nexport const NegotiationRoleSchema = z.enum([\"agent\", \"patient\", \"peer\"]);\nexport type NegotiationRole = z.infer<typeof NegotiationRoleSchema>;\n\nexport const DiscoveryTurnSchema = z.object({\n action: z.enum([\"propose\", \"accept\", \"reject\", \"counter\", \"question\", \"outreach\", \"withdraw\", \"decline\"]),\n reasoning: z.string(),\n suggestedRoles: z.object({\n ownUser: NegotiationRoleSchema,\n otherUser: NegotiationRoleSchema,\n }),\n});\nexport type DiscoveryTurn = z.infer<typeof DiscoveryTurnSchema>;\n\nexport const DiscoveryOutcomeSchema = z.object({\n hasOpportunity: z.boolean(),\n reasoning: z.string(),\n agreedRoles: z.array(z.object({\n userId: z.string(),\n role: NegotiationRoleSchema,\n })).optional(),\n reason: z.enum([\"turn_cap\", \"timeout\"]).optional(),\n});\nexport type DiscoveryOutcome = z.infer<typeof DiscoveryOutcomeSchema>;\n\nexport const DiscoveryNegotiationSchema = z.object({\n counterpartyId: z.string(),\n counterpartyHint: z.string(),\n indexContext: z.string(),\n turns: z.array(DiscoveryTurnSchema),\n outcome: DiscoveryOutcomeSchema,\n seedAssessmentScore: z.number().optional(),\n});\nexport type DiscoveryNegotiation = z.infer<typeof DiscoveryNegotiationSchema>;\n\nexport const DiscoverySummarySchema = z.object({\n totalCandidates: z.number(),\n opportunitiesFound: z.number(),\n noOpportunityCount: z.number(),\n timeoutCount: z.number(),\n roleDistribution: z.record(NegotiationRoleSchema, z.number()),\n});\nexport type DiscoverySummary = {\n totalCandidates: number;\n opportunitiesFound: number;\n noOpportunityCount: number;\n timeoutCount: number;\n roleDistribution: Partial<Record<NegotiationRole, number>>;\n};\n\nexport const DiscoverySourceProfileSchema = z.object({\n name: z.string().optional(),\n bio: z.string().optional(),\n location: z.string().optional(),\n skills: z.array(z.string()).optional(),\n interests: z.array(z.string()).optional(),\n});\nexport type DiscoverySourceProfile = z.infer<typeof DiscoverySourceProfileSchema>;\n\n// ─── Composite input (pure interface — references cross-schema types) ─────────\n\n/**\n * Full input to the question generator.\n * Defined as a pure interface so it can reference DiscoveryNegotiationDigest\n * and ChatContextDigest from sibling schemas without Zod runtime coupling.\n */\nexport interface DiscoveryQuestionInput {\n query: string;\n /** The seeker's global user_context paragraph (profile-replacing identity text). */\n userContext: string;\n negotiationDigests: DiscoveryNegotiationDigest[];\n summary: DiscoverySummary;\n chatContext?: ChatContextDigest;\n now: string;\n}"]}
1
+ {"version":3,"file":"discovery-question.schema.js","sourceRoot":"/","sources":["shared/schemas/discovery-question.schema.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,iFAAiF;AAEjF,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC;AAG1E,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1C,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;IACrH,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB,cAAc,EAAE,CAAC,CAAC,MAAM,CAAC;QACvB,OAAO,EAAE,qBAAqB;QAC9B,SAAS,EAAE,qBAAqB;KACjC,CAAC;CACH,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC7C,cAAc,EAAE,CAAC,CAAC,OAAO,EAAE;IAC3B,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB,WAAW,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;QAC5B,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;QAClB,IAAI,EAAE,qBAAqB;KAC5B,CAAC,CAAC,CAAC,QAAQ,EAAE;IACd,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC,CAAC,QAAQ,EAAE;CACnD,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,CAAC,MAAM,CAAC;IACjD,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE;IAC1B,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE;IAC5B,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE;IACxB,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,mBAAmB,CAAC;IACnC,OAAO,EAAE,sBAAsB;IAC/B,mBAAmB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC3C,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC7C,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE;IAC3B,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE;IAC9B,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE;IAC9B,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE;IACxB,gBAAgB,EAAE,CAAC,CAAC,MAAM,CAAC,qBAAqB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;CAC9D,CAAC,CAAC;AASH,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAC,CAAC,MAAM,CAAC;IACnD,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC3B,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC1B,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC/B,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;IACtC,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;CAC1C,CAAC,CAAC","sourcesContent":["/**\n * DiscoveryQuestionInput and nested types.\n * Leaf types have full Zod schemas. The composite DiscoveryQuestionInput is\n * a pure interface referencing cross-schema types (DiscoveryNegotiationDigest,\n * ChatContextDigest) to avoid Zod cross-schema runtime coupling.\n */\nimport { z } from \"zod\";\nimport type { DiscoveryNegotiationDigest } from \"./negotiation-digest.schema.js\";\nimport type { ChatContextDigest } from \"./chat-context.schema.js\";\n\n// ─── Primitives ───────────────────────────────────────────────────────────────\n\nexport const NegotiationRoleSchema = z.enum([\"agent\", \"patient\", \"peer\"]);\nexport type NegotiationRole = z.infer<typeof NegotiationRoleSchema>;\n\nexport const DiscoveryTurnSchema = z.object({\n action: z.enum([\"propose\", \"accept\", \"reject\", \"counter\", \"question\", \"outreach\", \"withdraw\", \"decline\", \"ask_user\"]),\n reasoning: z.string(),\n suggestedRoles: z.object({\n ownUser: NegotiationRoleSchema,\n otherUser: NegotiationRoleSchema,\n }),\n});\nexport type DiscoveryTurn = z.infer<typeof DiscoveryTurnSchema>;\n\nexport const DiscoveryOutcomeSchema = z.object({\n hasOpportunity: z.boolean(),\n reasoning: z.string(),\n agreedRoles: z.array(z.object({\n userId: z.string(),\n role: NegotiationRoleSchema,\n })).optional(),\n reason: z.enum([\"turn_cap\", \"timeout\"]).optional(),\n});\nexport type DiscoveryOutcome = z.infer<typeof DiscoveryOutcomeSchema>;\n\nexport const DiscoveryNegotiationSchema = z.object({\n counterpartyId: z.string(),\n counterpartyHint: z.string(),\n indexContext: z.string(),\n turns: z.array(DiscoveryTurnSchema),\n outcome: DiscoveryOutcomeSchema,\n seedAssessmentScore: z.number().optional(),\n});\nexport type DiscoveryNegotiation = z.infer<typeof DiscoveryNegotiationSchema>;\n\nexport const DiscoverySummarySchema = z.object({\n totalCandidates: z.number(),\n opportunitiesFound: z.number(),\n noOpportunityCount: z.number(),\n timeoutCount: z.number(),\n roleDistribution: z.record(NegotiationRoleSchema, z.number()),\n});\nexport type DiscoverySummary = {\n totalCandidates: number;\n opportunitiesFound: number;\n noOpportunityCount: number;\n timeoutCount: number;\n roleDistribution: Partial<Record<NegotiationRole, number>>;\n};\n\nexport const DiscoverySourceProfileSchema = z.object({\n name: z.string().optional(),\n bio: z.string().optional(),\n location: z.string().optional(),\n skills: z.array(z.string()).optional(),\n interests: z.array(z.string()).optional(),\n});\nexport type DiscoverySourceProfile = z.infer<typeof DiscoverySourceProfileSchema>;\n\n// ─── Composite input (pure interface — references cross-schema types) ─────────\n\n/**\n * Full input to the question generator.\n * Defined as a pure interface so it can reference DiscoveryNegotiationDigest\n * and ChatContextDigest from sibling schemas without Zod runtime coupling.\n */\nexport interface DiscoveryQuestionInput {\n query: string;\n /** The seeker's global user_context paragraph (profile-replacing identity text). */\n userContext: string;\n negotiationDigests: DiscoveryNegotiationDigest[];\n summary: DiscoverySummary;\n chatContext?: ChatContextDigest;\n now: string;\n}"]}
@@ -14,14 +14,32 @@ import { z } from "zod";
14
14
  * `protocolVersion` and the acting user's seat — see
15
15
  * `negotiation/negotiation.protocol.ts` for the seat-scoped schemas.
16
16
  */
17
- export declare const NEGOTIATION_ACTIONS: readonly ["propose", "accept", "reject", "counter", "question", "outreach", "withdraw", "decline"];
17
+ export declare const NEGOTIATION_ACTIONS: readonly ["propose", "accept", "reject", "counter", "question", "outreach", "withdraw", "decline", "ask_user"];
18
18
  export type NegotiationAction = (typeof NEGOTIATION_ACTIONS)[number];
19
19
  /** Negotiation seat under the v2 client-advocate protocol. */
20
20
  export type NegotiationSeat = "initiator" | "counterparty";
21
21
  /** Negotiation protocol version stamped on task metadata. */
22
22
  export type NegotiationProtocolVersion = "v1" | "v2";
23
+ /**
24
+ * Payload for the v2 `ask_user` action (P3.2): the negotiator pauses the
25
+ * negotiation to consult its OWN client. `disclosureSubject` states what the
26
+ * negotiator wants permission to share or needs to know; `draftQuestion` is
27
+ * the negotiator's own phrasing, refined by the questioner's
28
+ * `negotiation_inflight` preset before delivery.
29
+ */
30
+ export declare const AskUserPayloadSchema: z.ZodObject<{
31
+ disclosureSubject: z.ZodString;
32
+ draftQuestion: z.ZodOptional<z.ZodNullable<z.ZodString>>;
33
+ }, "strip", z.ZodTypeAny, {
34
+ disclosureSubject: string;
35
+ draftQuestion?: string | null | undefined;
36
+ }, {
37
+ disclosureSubject: string;
38
+ draftQuestion?: string | null | undefined;
39
+ }>;
40
+ export type AskUserPayload = z.infer<typeof AskUserPayloadSchema>;
23
41
  export declare const NegotiationTurnSchema: z.ZodObject<{
24
- action: z.ZodEnum<["propose", "accept", "reject", "counter", "question", "outreach", "withdraw", "decline"]>;
42
+ action: z.ZodEnum<["propose", "accept", "reject", "counter", "question", "outreach", "withdraw", "decline", "ask_user"]>;
25
43
  assessment: z.ZodObject<{
26
44
  reasoning: z.ZodString;
27
45
  suggestedRoles: z.ZodObject<{
@@ -48,8 +66,19 @@ export declare const NegotiationTurnSchema: z.ZodObject<{
48
66
  };
49
67
  }>;
50
68
  message: z.ZodOptional<z.ZodNullable<z.ZodString>>;
69
+ /** Present when action is `ask_user` (v2, P3.2). */
70
+ askUser: z.ZodOptional<z.ZodNullable<z.ZodObject<{
71
+ disclosureSubject: z.ZodString;
72
+ draftQuestion: z.ZodOptional<z.ZodNullable<z.ZodString>>;
73
+ }, "strip", z.ZodTypeAny, {
74
+ disclosureSubject: string;
75
+ draftQuestion?: string | null | undefined;
76
+ }, {
77
+ disclosureSubject: string;
78
+ draftQuestion?: string | null | undefined;
79
+ }>>>;
51
80
  }, "strip", z.ZodTypeAny, {
52
- action: "propose" | "accept" | "reject" | "counter" | "question" | "outreach" | "withdraw" | "decline";
81
+ action: "propose" | "accept" | "reject" | "counter" | "question" | "outreach" | "withdraw" | "decline" | "ask_user";
53
82
  assessment: {
54
83
  reasoning: string;
55
84
  suggestedRoles: {
@@ -58,8 +87,12 @@ export declare const NegotiationTurnSchema: z.ZodObject<{
58
87
  };
59
88
  };
60
89
  message?: string | null | undefined;
90
+ askUser?: {
91
+ disclosureSubject: string;
92
+ draftQuestion?: string | null | undefined;
93
+ } | null | undefined;
61
94
  }, {
62
- action: "propose" | "accept" | "reject" | "counter" | "question" | "outreach" | "withdraw" | "decline";
95
+ action: "propose" | "accept" | "reject" | "counter" | "question" | "outreach" | "withdraw" | "decline" | "ask_user";
63
96
  assessment: {
64
97
  reasoning: string;
65
98
  suggestedRoles: {
@@ -68,6 +101,10 @@ export declare const NegotiationTurnSchema: z.ZodObject<{
68
101
  };
69
102
  };
70
103
  message?: string | null | undefined;
104
+ askUser?: {
105
+ disclosureSubject: string;
106
+ draftQuestion?: string | null | undefined;
107
+ } | null | undefined;
71
108
  }>;
72
109
  export type NegotiationTurn = z.infer<typeof NegotiationTurnSchema>;
73
110
  export declare const NegotiationOutcomeSchema: z.ZodObject<{
@@ -1 +1 @@
1
- {"version":3,"file":"negotiation-state.schema.d.ts","sourceRoot":"/","sources":["shared/schemas/negotiation-state.schema.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB;;;;;;;;;GASG;AACH,eAAO,MAAM,mBAAmB,oGAGtB,CAAC;AACX,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAC;AAErE,8DAA8D;AAC9D,MAAM,MAAM,eAAe,GAAG,WAAW,GAAG,cAAc,CAAC;AAE3D,6DAA6D;AAC7D,MAAM,MAAM,0BAA0B,GAAG,IAAI,GAAG,IAAI,CAAC;AAErD,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAUhC,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEpE,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EASnC,CAAC;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAI1E,kDAAkD;AAClD,MAAM,WAAW,sBAAsB;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACvF,OAAO,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;CACtG;AAED,qDAAqD;AACrD,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAClD"}
1
+ {"version":3,"file":"negotiation-state.schema.d.ts","sourceRoot":"/","sources":["shared/schemas/negotiation-state.schema.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB;;;;;;;;;GASG;AACH,eAAO,MAAM,mBAAmB,gHAItB,CAAC;AACX,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAC;AAErE,8DAA8D;AAC9D,MAAM,MAAM,eAAe,GAAG,WAAW,GAAG,cAAc,CAAC;AAE3D,6DAA6D;AAC7D,MAAM,MAAM,0BAA0B,GAAG,IAAI,GAAG,IAAI,CAAC;AAErD;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;EAG/B,CAAC;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAElE,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAUhC,oDAAoD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAEpD,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEpE,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EASnC,CAAC;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAI1E,kDAAkD;AAClD,MAAM,WAAW,sBAAsB;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACvF,OAAO,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;CACtG;AAED,qDAAqD;AACrD,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAClD"}
@@ -18,7 +18,19 @@ import { z } from "zod";
18
18
  export const NEGOTIATION_ACTIONS = [
19
19
  "propose", "accept", "reject", "counter", "question",
20
20
  "outreach", "withdraw", "decline",
21
+ "ask_user",
21
22
  ];
23
+ /**
24
+ * Payload for the v2 `ask_user` action (P3.2): the negotiator pauses the
25
+ * negotiation to consult its OWN client. `disclosureSubject` states what the
26
+ * negotiator wants permission to share or needs to know; `draftQuestion` is
27
+ * the negotiator's own phrasing, refined by the questioner's
28
+ * `negotiation_inflight` preset before delivery.
29
+ */
30
+ export const AskUserPayloadSchema = z.object({
31
+ disclosureSubject: z.string(),
32
+ draftQuestion: z.string().nullable().optional(),
33
+ });
22
34
  export const NegotiationTurnSchema = z.object({
23
35
  action: z.enum(NEGOTIATION_ACTIONS),
24
36
  assessment: z.object({
@@ -29,6 +41,8 @@ export const NegotiationTurnSchema = z.object({
29
41
  }),
30
42
  }),
31
43
  message: z.string().nullable().optional(),
44
+ /** Present when action is `ask_user` (v2, P3.2). */
45
+ askUser: AskUserPayloadSchema.nullable().optional(),
32
46
  });
33
47
  export const NegotiationOutcomeSchema = z.object({
34
48
  hasOpportunity: z.boolean(),
@@ -1 +1 @@
1
- {"version":3,"file":"negotiation-state.schema.js","sourceRoot":"/","sources":["shared/schemas/negotiation-state.schema.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,iFAAiF;AAEjF;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU;IACpD,UAAU,EAAE,UAAU,EAAE,SAAS;CACzB,CAAC;AASX,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC5C,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC;IACnC,UAAU,EAAE,CAAC,CAAC,MAAM,CAAC;QACnB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;QACrB,cAAc,EAAE,CAAC,CAAC,MAAM,CAAC;YACvB,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;YAC7C,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;SAChD,CAAC;KACH,CAAC;IACF,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;CAC1C,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC/C,cAAc,EAAE,CAAC,CAAC,OAAO,EAAE;IAC3B,WAAW,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;QAC5B,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;QAClB,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;KAC3C,CAAC,CAAC;IACH,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC,CAAC,QAAQ,EAAE;CACnD,CAAC,CAAC","sourcesContent":["/**\n * Negotiation state DTOs extracted from negotiation/negotiation.state.ts for\n * consumption by shared interfaces. This shared module owns the DTO schemas;\n * LangGraph Annotation.Root stays in the domain file.\n */\nimport { z } from \"zod\";\n\n// ─── Zod schemas (available for runtime validation) ───────────────────────────\n\n/**\n * Union of every negotiation turn action across protocol versions.\n *\n * v1 vocabulary: `propose | accept | reject | counter | question`.\n * v2 (client-advocate seat rules) renames `propose`→`outreach` and splits\n * `reject` into `withdraw` (initiator seat) / `decline` (counterparty seat).\n * Which subset is valid for a given turn depends on the task's\n * `protocolVersion` and the acting user's seat — see\n * `negotiation/negotiation.protocol.ts` for the seat-scoped schemas.\n */\nexport const NEGOTIATION_ACTIONS = [\n \"propose\", \"accept\", \"reject\", \"counter\", \"question\",\n \"outreach\", \"withdraw\", \"decline\",\n] as const;\nexport type NegotiationAction = (typeof NEGOTIATION_ACTIONS)[number];\n\n/** Negotiation seat under the v2 client-advocate protocol. */\nexport type NegotiationSeat = \"initiator\" | \"counterparty\";\n\n/** Negotiation protocol version stamped on task metadata. */\nexport type NegotiationProtocolVersion = \"v1\" | \"v2\";\n\nexport const NegotiationTurnSchema = z.object({\n action: z.enum(NEGOTIATION_ACTIONS),\n assessment: z.object({\n reasoning: z.string(),\n suggestedRoles: z.object({\n ownUser: z.enum([\"agent\", \"patient\", \"peer\"]),\n otherUser: z.enum([\"agent\", \"patient\", \"peer\"]),\n }),\n }),\n message: z.string().nullable().optional(),\n});\nexport type NegotiationTurn = z.infer<typeof NegotiationTurnSchema>;\n\nexport const NegotiationOutcomeSchema = z.object({\n hasOpportunity: z.boolean(),\n agreedRoles: z.array(z.object({\n userId: z.string(),\n role: z.enum([\"agent\", \"patient\", \"peer\"]),\n })),\n reasoning: z.string(),\n turnCount: z.number(),\n reason: z.enum([\"turn_cap\", \"timeout\"]).optional(),\n});\nexport type NegotiationOutcome = z.infer<typeof NegotiationOutcomeSchema>;\n\n// ─── Pure interfaces ──────────────────────────────────────────────────────────\n\n/** Context each agent receives about its user. */\nexport interface UserNegotiationContext {\n id: string;\n intents: Array<{ id: string; title: string; description: string; confidence: number }>;\n profile: { name?: string; bio?: string; location?: string; interests?: string[]; skills?: string[] };\n}\n\n/** Seed assessment from the evaluator pre-filter. */\nexport interface SeedAssessment {\n reasoning: string;\n valencyRole: string;\n actors?: Array<{ userId: string; role: string }>;\n}"]}
1
+ {"version":3,"file":"negotiation-state.schema.js","sourceRoot":"/","sources":["shared/schemas/negotiation-state.schema.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,iFAAiF;AAEjF;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU;IACpD,UAAU,EAAE,UAAU,EAAE,SAAS;IACjC,UAAU;CACF,CAAC;AASX;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3C,iBAAiB,EAAE,CAAC,CAAC,MAAM,EAAE;IAC7B,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;CAChD,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC5C,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC;IACnC,UAAU,EAAE,CAAC,CAAC,MAAM,CAAC;QACnB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;QACrB,cAAc,EAAE,CAAC,CAAC,MAAM,CAAC;YACvB,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;YAC7C,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;SAChD,CAAC;KACH,CAAC;IACF,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IACzC,oDAAoD;IACpD,OAAO,EAAE,oBAAoB,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;CACpD,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC/C,cAAc,EAAE,CAAC,CAAC,OAAO,EAAE;IAC3B,WAAW,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;QAC5B,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;QAClB,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;KAC3C,CAAC,CAAC;IACH,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC,CAAC,QAAQ,EAAE;CACnD,CAAC,CAAC","sourcesContent":["/**\n * Negotiation state DTOs extracted from negotiation/negotiation.state.ts for\n * consumption by shared interfaces. This shared module owns the DTO schemas;\n * LangGraph Annotation.Root stays in the domain file.\n */\nimport { z } from \"zod\";\n\n// ─── Zod schemas (available for runtime validation) ───────────────────────────\n\n/**\n * Union of every negotiation turn action across protocol versions.\n *\n * v1 vocabulary: `propose | accept | reject | counter | question`.\n * v2 (client-advocate seat rules) renames `propose`→`outreach` and splits\n * `reject` into `withdraw` (initiator seat) / `decline` (counterparty seat).\n * Which subset is valid for a given turn depends on the task's\n * `protocolVersion` and the acting user's seat — see\n * `negotiation/negotiation.protocol.ts` for the seat-scoped schemas.\n */\nexport const NEGOTIATION_ACTIONS = [\n \"propose\", \"accept\", \"reject\", \"counter\", \"question\",\n \"outreach\", \"withdraw\", \"decline\",\n \"ask_user\",\n] as const;\nexport type NegotiationAction = (typeof NEGOTIATION_ACTIONS)[number];\n\n/** Negotiation seat under the v2 client-advocate protocol. */\nexport type NegotiationSeat = \"initiator\" | \"counterparty\";\n\n/** Negotiation protocol version stamped on task metadata. */\nexport type NegotiationProtocolVersion = \"v1\" | \"v2\";\n\n/**\n * Payload for the v2 `ask_user` action (P3.2): the negotiator pauses the\n * negotiation to consult its OWN client. `disclosureSubject` states what the\n * negotiator wants permission to share or needs to know; `draftQuestion` is\n * the negotiator's own phrasing, refined by the questioner's\n * `negotiation_inflight` preset before delivery.\n */\nexport const AskUserPayloadSchema = z.object({\n disclosureSubject: z.string(),\n draftQuestion: z.string().nullable().optional(),\n});\nexport type AskUserPayload = z.infer<typeof AskUserPayloadSchema>;\n\nexport const NegotiationTurnSchema = z.object({\n action: z.enum(NEGOTIATION_ACTIONS),\n assessment: z.object({\n reasoning: z.string(),\n suggestedRoles: z.object({\n ownUser: z.enum([\"agent\", \"patient\", \"peer\"]),\n otherUser: z.enum([\"agent\", \"patient\", \"peer\"]),\n }),\n }),\n message: z.string().nullable().optional(),\n /** Present when action is `ask_user` (v2, P3.2). */\n askUser: AskUserPayloadSchema.nullable().optional(),\n});\nexport type NegotiationTurn = z.infer<typeof NegotiationTurnSchema>;\n\nexport const NegotiationOutcomeSchema = z.object({\n hasOpportunity: z.boolean(),\n agreedRoles: z.array(z.object({\n userId: z.string(),\n role: z.enum([\"agent\", \"patient\", \"peer\"]),\n })),\n reasoning: z.string(),\n turnCount: z.number(),\n reason: z.enum([\"turn_cap\", \"timeout\"]).optional(),\n});\nexport type NegotiationOutcome = z.infer<typeof NegotiationOutcomeSchema>;\n\n// ─── Pure interfaces ──────────────────────────────────────────────────────────\n\n/** Context each agent receives about its user. */\nexport interface UserNegotiationContext {\n id: string;\n intents: Array<{ id: string; title: string; description: string; confidence: number }>;\n profile: { name?: string; bio?: string; location?: string; interests?: string[]; skills?: string[] };\n}\n\n/** Seed assessment from the evaluator pre-filter. */\nexport interface SeedAssessment {\n reasoning: string;\n valencyRole: string;\n actors?: Array<{ userId: string; role: string }>;\n}"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@indexnetwork/protocol",
3
- "version": "4.5.0-rc.335.1",
3
+ "version": "4.5.0-rc.337.1",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",