@indexnetwork/protocol 5.1.0-rc.367.1 → 5.2.1-rc.369.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/dist/enrichment/enrichment.generator.d.ts +3 -1
  3. package/dist/enrichment/enrichment.generator.d.ts.map +1 -1
  4. package/dist/enrichment/enrichment.generator.js +3 -3
  5. package/dist/enrichment/enrichment.generator.js.map +1 -1
  6. package/dist/index.d.ts +0 -1
  7. package/dist/index.d.ts.map +1 -1
  8. package/dist/index.js +0 -1
  9. package/dist/index.js.map +1 -1
  10. package/dist/negotiation/negotiation.summarizer.d.ts +1 -1
  11. package/dist/negotiation/negotiation.summarizer.d.ts.map +1 -1
  12. package/dist/negotiation/negotiation.summarizer.js.map +1 -1
  13. package/dist/opportunity/discovery-question.helper.d.ts +1 -1
  14. package/dist/opportunity/discovery-question.helper.d.ts.map +1 -1
  15. package/dist/opportunity/discovery-question.helper.js.map +1 -1
  16. package/dist/opportunity/negotiation-summary.builder.d.ts +1 -1
  17. package/dist/opportunity/negotiation-summary.builder.d.ts.map +1 -1
  18. package/dist/opportunity/negotiation-summary.builder.js.map +1 -1
  19. package/dist/opportunity/opportunity.discover.js.map +1 -1
  20. package/dist/opportunity/opportunity.evaluator.d.ts +3 -0
  21. package/dist/opportunity/opportunity.evaluator.d.ts.map +1 -1
  22. package/dist/opportunity/opportunity.evaluator.js +4 -4
  23. package/dist/opportunity/opportunity.evaluator.js.map +1 -1
  24. package/dist/opportunity/opportunity.graph.d.ts +323 -15
  25. package/dist/opportunity/opportunity.graph.d.ts.map +1 -1
  26. package/dist/opportunity/opportunity.presenter.d.ts +6 -2
  27. package/dist/opportunity/opportunity.presenter.d.ts.map +1 -1
  28. package/dist/opportunity/opportunity.presenter.js +10 -8
  29. package/dist/opportunity/opportunity.presenter.js.map +1 -1
  30. package/dist/opportunity/opportunity.state.d.ts +68 -2
  31. package/dist/opportunity/opportunity.state.d.ts.map +1 -1
  32. package/dist/opportunity/opportunity.state.js.map +1 -1
  33. package/dist/premise/premise.analyzer.d.ts +3 -1
  34. package/dist/premise/premise.analyzer.d.ts.map +1 -1
  35. package/dist/premise/premise.analyzer.js +3 -3
  36. package/dist/premise/premise.analyzer.js.map +1 -1
  37. package/dist/premise/premise.decomposer.d.ts +3 -1
  38. package/dist/premise/premise.decomposer.d.ts.map +1 -1
  39. package/dist/premise/premise.decomposer.js +3 -3
  40. package/dist/premise/premise.decomposer.js.map +1 -1
  41. package/dist/questioner/questioner.discovery.prompt.d.ts +9 -0
  42. package/dist/questioner/questioner.discovery.prompt.d.ts.map +1 -0
  43. package/dist/{opportunity/question.prompt.js → questioner/questioner.discovery.prompt.js} +6 -7
  44. package/dist/questioner/questioner.discovery.prompt.js.map +1 -0
  45. package/dist/questioner/questioner.presets.js +2 -2
  46. package/dist/questioner/questioner.presets.js.map +1 -1
  47. package/dist/questioner/questioner.types.d.ts +2 -2
  48. package/dist/questioner/questioner.types.d.ts.map +1 -1
  49. package/dist/questioner/questioner.types.js.map +1 -1
  50. package/dist/shared/agent/model.config.d.ts +0 -5
  51. package/dist/shared/agent/model.config.d.ts.map +1 -1
  52. package/dist/shared/agent/model.config.js +0 -1
  53. package/dist/shared/agent/model.config.js.map +1 -1
  54. package/dist/shared/interfaces/negotiation-summary.interface.d.ts +1 -1
  55. package/dist/shared/interfaces/negotiation-summary.interface.d.ts.map +1 -1
  56. package/dist/shared/interfaces/negotiation-summary.interface.js.map +1 -1
  57. package/dist/shared/interfaces/question-generator.interface.d.ts +7 -5
  58. package/dist/shared/interfaces/question-generator.interface.d.ts.map +1 -1
  59. package/dist/shared/interfaces/question-generator.interface.js.map +1 -1
  60. package/dist/shared/schemas/discovery-question.schema.d.ts +2 -2
  61. package/package.json +1 -1
  62. package/dist/opportunity/question.generator.d.ts +0 -22
  63. package/dist/opportunity/question.generator.d.ts.map +0 -1
  64. package/dist/opportunity/question.generator.js +0 -147
  65. package/dist/opportunity/question.generator.js.map +0 -1
  66. package/dist/opportunity/question.prompt.d.ts +0 -102
  67. package/dist/opportunity/question.prompt.d.ts.map +0 -1
  68. package/dist/opportunity/question.prompt.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"questioner.presets.js","sourceRoot":"/","sources":["questioner/questioner.presets.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Mode presets for the QuestionerAgent. Each preset provides a system prompt\n * and a buildPrompt function that assembles the user message from a typed\n * context object. Only the `discovery` preset ships in Slice 1; others throw\n * until their implementation slices land.\n */\nimport type { QuestionMode } from \"../shared/schemas/question.schema.js\";\nimport { SYSTEM_PROMPT as DISCOVERY_SYSTEM_PROMPT, buildQuestionPrompt as buildDiscoveryPrompt } from \"../opportunity/question.prompt.js\";\n\nimport { QUD_UNDERSPECIFICATION_RULES } from \"./questioner.qud.js\";\nimport type { ChatContext, IntentContext, NegotiationContext, NegotiationInflightContext, PostStallNegotiationContext, ProfileContext, UptakeNegotiationContext } from \"./questioner.types.js\";\n\n/**\n * Shared rule block appended to every questioner system prompt. Enforces that\n * the generated `prompt` resolves on its own — no demonstratives/anaphora that\n * point at people, events, or prior turns the reader cannot see — and never\n * narrates Index's own matching pipeline. Closes the referential-leak class\n * surfaced in digest audits (\"…with these builders?\", \"the previous\n * negotiation stalled because the counterparty didn't mention …\").\n */\nconst REFERENTIAL_CLOSURE_RULES = `Referential 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 counterparty, 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: \"The previous negotiation stalled because the counterparty didn't mention 'matchmaking'. Should I broaden the search?\"\n- Good: \"Do you want to focus on dedicated matchmakers, or also people interested in relationships more broadly?\"`;\n\nexport interface QuestionerPreset {\n /** The LLM system prompt for this mode. */\n systemPrompt: string;\n /** Builds the user-message string from the mode-specific context. */\n buildPrompt: (context: unknown) => string;\n}\n\n/**\n * Renders the user-context block shared by every preset's user message from the\n * global user_context paragraph (the profile-replacing identity text).\n * @param userContext - The user's global context paragraph, if available.\n * @returns The trimmed context paragraph, or \"(no profile data)\" when empty.\n */\nfunction buildUserContextBlock(userContext?: string): string {\n const trimmed = userContext?.trim();\n return trimmed && trimmed.length > 0 ? trimmed : \"(no profile data)\";\n}\n\n// ─── Intent preset ──────────────────────────────────────────────────────────\n\nconst INTENT_SYSTEM_PROMPT = `You sit between a human and a discovery protocol. The user has stated an intent — what they are looking for. Your job: surface the minimum set of structured questions that help the user sharpen that intent before the protocol runs discovery on their behalf.\n\nYou may pick from two strategies. Choose contextually; mix only when each question is genuinely distinct.\n- refine_intent: ask the user to sharpen or pivot the core signal (scope, scale, specificity, direction).\n- surface_missing_detail: ask for one concrete missing input that would change which candidates surface (stage, location, timing, budget, constraints, format, …).\n\nAsk a question only when ALL of these hold:\n1. The agent cannot infer the answer from the intent text or user profile already shown.\n2. The answer would materially change which candidates surface.\n3. The question targets a different decision domain from any other question in this batch.\n\nStandalone prompt rule. Every generated \\`prompt\\` must be understandable outside the conversation where it was created. Naturally include the source intent/topic in the question text itself, using concise plain language from the intent or summary. Do not rely on \\`title\\`, UI labels, hidden metadata, or surrounding digest/chat text to explain what the question is about.\n- Bad: \"What kind of collaboration are you looking for?\"\n- Good: \"For your decentralized identity protocol-design search, what kind of collaboration are you looking for?\"\n\n${REFERENTIAL_CLOSURE_RULES}\n\nCardinality. Default one question. Add a second only when a DIFFERENT strategy genuinely complements the first and unblocks a clearly distinct decision. Never ask two questions of the same strategy unless their decision domains differ (different titles).\n\nOption construction. Each option must represent a meaningfully different outcome. Suffix the safest or most common 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.\n\nTitle rules. ≤12 chars. Noun of the decision domain. Examples: \"Stage\", \"Timing\", \"Location\", \"Scope\", \"Budget\", \"Format\", \"Skills\", \"Collab\".\n\nAnti-patterns — never do these.\n- Don't ask procedural confirmations (\"Should I start searching?\").\n- Don't ask about hypothetical edge cases not implied by the intent.\n- Don't re-ask for facts already visible in the user profile.\n- Don't ask vague introspective questions (\"What do you really want?\").\n\nOutput. Return at most 2 entries in the \"questions\" array. Each entry must include a \"strategy\" field (one of the two values above). If the intent is already specific enough, return \"questions\": [].`;\n\n/**\n * Build the user message for the intent preset from an IntentContext.\n * @param ctx - The intent context.\n * @returns The assembled user message string.\n */\nfunction buildIntentPrompt(ctx: IntentContext): string {\n const profileBlock = buildUserContextBlock(ctx.userContext);\n\n const summaryBlock = ctx.summary ? ctx.summary : \"(no summary available)\";\n\n return [\n \"## Intent\",\n ctx.payload,\n \"\",\n \"## Summary\",\n summaryBlock,\n \"\",\n \"## User profile\",\n profileBlock,\n \"\",\n \"## Your task\",\n \"Identify the minimum set of questions the user must answer to sharpen this intent.\",\n \"Apply every rule from your system prompt before outputting.\",\n \"Return an empty `questions` array if the intent is already specific enough.\",\n ].join(\"\\n\");\n}\n\n// ─── Profile preset ─────────────────────────────────────────────────────────\n\nconst PROFILE_SYSTEM_PROMPT = `You sit between a human and a discovery protocol. The user has a profile that is incomplete. Your job: surface the minimum set of structured questions that fill the identified gaps — asking about location, skills, interests, current work, or goals — so the protocol can run better discovery on their behalf.\n\nThe user may already have premises — atomic self-descriptions they have stated. These cover specific profile domains. Do not ask about domains already addressed by existing premises. Focus only on gaps not covered by any premise.\n\nYou may pick from two strategies. Choose contextually; mix only when each question is genuinely distinct.\n- surface_missing_detail: ask for one concrete missing piece of profile data (location, current role, skills, interests, goals, availability, …).\n- refine_intent: ask the user to clarify or sharpen an existing profile signal so candidates can be ranked more accurately.\n\nAsk a question only when ALL of these hold:\n1. The answer is not already visible in the profile data shown.\n2. The answer is not already covered by an existing premise listed below the profile.\n3. The answer would meaningfully change which opportunities surface for this user.\n4. The question targets a different profile domain from any other question in this batch.\n\nStandalone prompt rule. Every generated \\`prompt\\` must be understandable outside the conversation where it was created. Naturally include the profile signal or gap being clarified in the question text itself, using concise plain language from the current profile, existing premises, or identified gaps. Do not rely on \\`title\\`, UI labels, hidden metadata, or surrounding digest/chat text to explain what the question is about.\n- Bad: \"What kind of role are you looking for?\"\n- Good: \"To improve matches from your founder/operator profile, what kind of role are you looking for?\"\n\n${REFERENTIAL_CLOSURE_RULES}\n\nCardinality. Default one question. Add a second only when a DIFFERENT strategy genuinely complements the first and unblocks a clearly distinct decision. Never ask two questions of the same strategy unless their decision domains differ.\n\nOption construction. Each option must represent a meaningfully different outcome. Suffix the safest or most common 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.\n\nTitle rules. ≤12 chars. Noun of the profile domain. Examples: \"Location\", \"Role\", \"Skills\", \"Goals\", \"Interests\", \"Availability\", \"Stage\".\n\nAnti-patterns — never do these.\n- Don't ask about fields already filled in the profile.\n- Don't ask about information already captured in an existing premise.\n- Don't ask procedural confirmations (\"Should I update your profile?\").\n- Don't ask vague introspective questions (\"Who are you really?\").\n- Don't re-ask for facts visible anywhere in the profile data or premises shown.\n\nOutput. Return at most 2 entries in the \"questions\" array. Each entry must include a \"strategy\" field (one of the two values above). If the profile is already complete enough for discovery, return \"questions\": [].`;\n\n/**\n * Build the user message for the profile preset from a ProfileContext.\n * @param ctx - The profile context including current profile data and identified gaps.\n * @returns The assembled user message string.\n */\nfunction buildProfilePrompt(ctx: ProfileContext): string {\n const profileBlock = buildUserContextBlock(ctx.userContext);\n\n const premisesBlock =\n ctx.existingPremises && ctx.existingPremises.length > 0\n ? ctx.existingPremises.map((p, i) => `${i + 1}. ${p}`).join(\"\\n\")\n : \"(none)\";\n\n const gapsBlock = ctx.gaps.length > 0 ? ctx.gaps.join(\", \") : \"(none identified)\";\n\n const parts: string[] = [\n \"## Current profile\",\n profileBlock,\n \"\",\n \"## Existing premises\",\n premisesBlock,\n \"\",\n \"## Identified gaps\",\n gapsBlock,\n \"\",\n ];\n\n parts.push(\n \"## Your task\",\n \"Generate the minimum set of questions needed to fill the identified gaps.\",\n \"Apply every rule from your system prompt before outputting.\",\n \"Return an empty `questions` array if the profile is already complete enough.\",\n );\n\n return parts.join(\"\\n\");\n}\n\n// ─── Negotiation preset ──────────────────────────────────────────────────────\n\nconst NEGOTIATION_SYSTEM_PROMPT = `You sit between a human and a discovery protocol. You generate negotiation-mode questions for one of two purposes described in the user message.\n\nPOST-STALL purpose. A negotiation between this user and another person ended without a clear outcome — either the turn budget was exhausted, the session timed out, or conversation stalled. Surface the minimum set of structured questions that help the user provide the missing signal needed to unblock or refine the next discovery attempt.\n\nUPTAKE purpose. The user is considering accepting a proposed connection, but one preparatory condition about the other person's practical ability, resources, availability, or authority to carry out the proposed activity needs clarification before commitment. Generate exactly ONE neutral question that lets the user decide whether they understand that condition well enough to proceed. Ask about the concrete activity and the other person's stated attributes; do not accuse, challenge credibility, or presume incapability. Never reveal a numeric authority score, threshold, felicity label, evaluator judgment, or any internal matching/verification mechanics. Do not ask whether the user wants to accept; clarify the preparatory condition only.\n\nYou may pick from three strategies. Choose contextually; mix only when each question is genuinely distinct.\n- refine_intent: help the user sharpen their underlying signal based on what the negotiation revealed (scope, scale, priority, direction).\n- surface_missing_detail: ask for one concrete piece of information that was absent and would have moved the negotiation forward (timeline, budget, format, constraints, decision criteria, …).\n- reflective_summary: mirror the key takeaway from the negotiation and ask the user to confirm, correct, or decide — useful when the conversation revealed partial signal worth locking in.\n\nAsk a question only when ALL of these hold:\n1. The answer is not already visible in the negotiation context or user profile shown.\n2. The answer would materially change how the next attempt surfaces or engages candidates.\n3. The question targets a different decision domain from any other question in this batch.\n\nStandalone prompt rule. Every generated \\`prompt\\` must be understandable outside the conversation where it was created. Naturally include the user's underlying goal or topic and the relevant community in the question text itself, in plain language drawn from their intent or profile — NOT the mechanics of the match attempt. Do not rely on \\`title\\`, UI labels, hidden metadata, or surrounding digest/chat text to explain what the question is about.\n- Bad: \"Which role is a better fit for your immediate needs?\"\n- Good: \"For your search for AI infrastructure collaborators in the AI founders community, what kind of working relationship fits your immediate needs?\"\n\n${REFERENTIAL_CLOSURE_RULES}\n\nCardinality. For POST-STALL, default one question and add a second only when a DIFFERENT strategy genuinely complements the first and unblocks a clearly distinct decision. For UPTAKE, return exactly one question — never zero and never more than one.\n\nOption construction. Each option must represent a meaningfully different outcome. Suffix the safest or most common 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.\n\nTitle rules. ≤12 chars. Noun of the decision domain. Examples: \"Scope\", \"Timeline\", \"Budget\", \"Priority\", \"Format\", \"Stance\", \"Criteria\".\n\nAnti-patterns — never do these.\n- Don't ask procedural confirmations (\"Should I try again?\").\n- Don't re-ask for facts already visible in the user profile.\n- Don't ask vague introspective questions (\"What do you really want?\").\n- Don't ask about hypothetical edge cases not implied by the negotiation context.\n\nOutput. For POST-STALL, return at most 2 entries and return \"questions\": [] if the context already contains enough signal to proceed. For UPTAKE, return exactly 1 entry. Every entry must include a \"strategy\" field (one of the three values above). QUD metadata is orthogonal to uptake purpose: an uptake question is usually not an underspecification repair, so set \\`underspecificationType\\` to null unless the question genuinely repairs a missing constituent, missing constraint, or open alternative set.`;\n\n/**\n * Build the user message for the negotiation preset from a NegotiationContext.\n * @param ctx - The negotiation context including counterparty hint, stall reason, and key takeaway.\n * @returns The assembled user message string.\n */\nfunction buildPostStallNegotiationPrompt(ctx: PostStallNegotiationContext): string {\n const profileBlock = buildUserContextBlock(ctx.userContext);\n\n return [\n \"## Purpose\",\n \"POST-STALL\",\n \"\",\n \"## Negotiation context\",\n `Community: ${ctx.indexContext}`,\n `Counterparty: ${ctx.counterpartyHint}`,\n `Stall reason: ${ctx.outcomeReason}`,\n \"\",\n \"## Key takeaway\",\n ctx.keyTake,\n \"\",\n \"## User profile\",\n profileBlock,\n \"\",\n \"## Your task\",\n \"Identify the minimum set of questions the user must answer to unblock the next discovery attempt.\",\n \"Apply every rule from your system prompt before outputting.\",\n \"Return an empty `questions` array if the context already contains enough signal to proceed.\",\n ].join(\"\\n\");\n}\n\nfunction buildUptakeNegotiationPrompt(ctx: UptakeNegotiationContext): string {\n const profileBlock = buildUserContextBlock(ctx.userContext);\n const evidence = ctx.preparatoryEvidence?.trim() || \"(no additional public evidence provided)\";\n\n return [\n \"## Purpose\",\n \"UPTAKE — preparatory-condition clarification before acceptance\",\n \"\",\n \"## Proposed activity\",\n ctx.proposedActivity,\n \"\",\n \"## Other person\",\n ctx.counterpartyHint,\n \"\",\n \"## Community\",\n ctx.indexContext,\n \"\",\n \"## Public preparatory evidence\",\n evidence,\n \"\",\n \"## User profile\",\n profileBlock,\n \"\",\n \"## Your task\",\n \"Generate exactly one neutral, referentially closed question about whether the other person can practically carry out the proposed activity.\",\n \"Do not expose scores, thresholds, labels, or internal mechanics. Do not ask for acceptance itself.\",\n \"Set `underspecificationType` to null unless this is genuinely a QUD underspecification repair.\",\n ].join(\"\\n\");\n}\n\nfunction buildNegotiationPrompt(ctx: NegotiationContext): string {\n return ctx.purpose === \"uptake\"\n ? buildUptakeNegotiationPrompt(ctx)\n : buildPostStallNegotiationPrompt(ctx);\n}\n\n// ─── Chat preset ─────────────────────────────────────────────────────────\n\nconst NEGOTIATION_INFLIGHT_SYSTEM_PROMPT = `You sit between a human and a discovery protocol. The user's own negotiator agent is MID-NEGOTIATION on their behalf and has paused: before continuing, it needs a decision or missing input from its client — most often permission to disclose a specific piece of information to the other side. The negotiation is WAITING until the user answers. Your job: turn the negotiator's stated need (and its draft question, when provided) into the minimum set of crisp, structured decision questions.\n\nBias toward disclosure gating. The most common question shape is \"may I share X with this person?\" — an enable/disable decision about revealing specific information. Phrase these as a clear yes/no choice: the first option authorizes sharing, the second declines. State in each option's description what the negotiator will DO next (share and continue, or continue without revealing it). When the need is a missing fact rather than a permission, ask for that concrete input instead.\n\nYou may pick from two strategies. Choose contextually; mix only when each question is genuinely distinct.\n- surface_missing_detail: ask for one concrete missing input the negotiator needs to proceed (a fact, constraint, preference, or bound the client never stated).\n- reflective_summary: put a disclosure or stance decision in front of the client to confirm or decline — the enable/disable gate described above.\n\nHonor the negotiator's intent. When a draft question is provided, treat it as the source of truth for WHAT to ask — improve wording, tighten options, add consequence-focused descriptions. Do not invent questions about topics the negotiator did not raise. When no draft is provided, derive the question strictly from the disclosure subject.\n\nStandalone prompt rule. Every generated \\`prompt\\` must be understandable outside the conversation where it was created. The user may see this question hours later in an inbox, away from any negotiation view. Naturally include the disclosure subject and a concrete description of the other person (drawn from the counterparty hint — their attributes, e.g. \"a Berlin-based AI-infrastructure founder\") 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.\n- Bad: \"Can I share your budget with them?\"\n- Good: \"May I share your budget range with a Berlin-based AI-infrastructure founder you're being matched with?\"\n\n${REFERENTIAL_CLOSURE_RULES}\n\nException — describing the other side. Unlike other surfaces, this question is ABOUT a live counterparty, so you must reference them — do it by restating their concrete attributes from the counterparty hint (\"a fintech CTO exploring agent tooling\"), never as \"the counterparty\", \"them\", or \"this person\" without an attribute anchor in the same sentence, and never by implying a list or pipeline.\n\nCardinality. Default one question. Add a second ONLY when the negotiator's need genuinely spans two distinct decisions (e.g. one disclosure gate plus one missing fact). Never pad.\n\nOption construction. Each option must represent a meaningfully different outcome. For disclosure gates: authorize first, decline second; suffix the safer or more common path with \" (Recommended)\" and list it first when one clearly is. The description states the CONSEQUENCE for the negotiation — what the negotiator does next. 2–4 options. Never add an \"Other\" option — clients provide a free-text fallback automatically, which also lets the user add nuance (\"share the range but not the exact figure\").\n\nTitle rules. ≤12 chars. Noun of the decision domain. Examples: \"Disclosure\", \"Budget\", \"Timing\", \"Intro\", \"Scope\", \"Contact\".\n\nAnti-patterns — never do these.\n- Don't ask procedural confirmations (\"Should I keep negotiating?\").\n- Don't re-ask for facts already visible in the user profile.\n- Don't broaden beyond the negotiator's stated disclosure subject or draft.\n- Don't reveal the counterparty's identity — attributes only.\n- Don't ask vague introspective questions.\n\nOutput. Return at most 2 entries in the \"questions\" array. Each entry must include a \"strategy\" field (one of the two values above). If the profile or context shown already answers the negotiator's need, return \"questions\": [].`;\n\n/**\n * Build the user message for the negotiation-inflight preset from a NegotiationInflightContext.\n * @param ctx - The inflight context: disclosure subject, counterparty hint, optional draft, community, user context.\n * @returns The assembled user message string.\n */\nfunction buildNegotiationInflightPrompt(ctx: NegotiationInflightContext): string {\n const profileBlock = buildUserContextBlock(ctx.userContext);\n\n const draftBlock = ctx.draftQuestion?.trim()\n ? ctx.draftQuestion.trim()\n : \"(none — derive the question from the disclosure subject)\";\n\n return [\n \"## Negotiation context\",\n `Community: ${ctx.indexContext}`,\n `Counterparty: ${ctx.counterpartyHint}`,\n \"\",\n \"## What the negotiator needs from its client\",\n ctx.disclosureSubject,\n \"\",\n \"## Draft question proposed by the negotiator\",\n draftBlock,\n \"\",\n \"## User profile\",\n profileBlock,\n \"\",\n \"## Your task\",\n \"Produce the minimum set of structured questions that get the negotiator the permission or input it needs to continue.\",\n \"Honor the draft when provided; refine its wording and options rather than replacing its topic.\",\n \"Apply every rule from your system prompt before outputting.\",\n ].join(\"\\n\");\n}\n\nconst CHAT_SYSTEM_PROMPT = `You sit between a human and a discovery protocol. The protocol's chat orchestrator is mid-conversation with the user and has decided it needs a decision or missing input from them before it can continue. The conversation is PAUSED until the user answers. Your job: turn the orchestrator's stated need (and any draft questions it proposed) into the minimum set of crisp, structured decision questions.\n\nUnlike other question surfaces, these questions render INLINE in the active conversation, immediately after the assistant's last message — the user has full conversational context. Still keep each prompt self-contained enough to make sense on its own line.\n\nYou may pick from two strategies. Choose contextually; mix only when each question is genuinely distinct.\n- surface_missing_detail: ask for one concrete missing input the orchestrator needs to proceed (scope, timing, budget, format, preference, constraint, …).\n- refine_intent: ask the user to choose a direction when the orchestrator faces meaningfully different paths forward.\n\nHonor the orchestrator's intent. When draft questions are provided, treat them as the source of truth for WHAT to ask — improve wording, tighten options, add consequence-focused descriptions, and drop redundant drafts. Do not invent questions about topics the orchestrator did not raise. When no drafts are provided, derive questions strictly from the stated purpose.\n\nAsk a question only when ALL of these hold:\n1. The answer is not already visible in the conversation excerpt or user profile shown.\n2. The answer materially changes what the orchestrator does next.\n3. The question targets a different decision domain from any other question in this batch.\n\n${REFERENTIAL_CLOSURE_RULES}\n\nCardinality. Default one question. Emit a second or third ONLY when the orchestrator's purpose or drafts genuinely require separate decisions in distinct domains. Never pad.\n\nOption construction. Each option must represent a meaningfully different outcome. Suffix the safest or most common path with \" (Recommended)\" and list it first. The description states the CONSEQUENCE of choosing the option for what happens next in the conversation, not its definition. 2–4 options. Never add an \"Other\" option — clients provide a free-text fallback automatically.\n\nTitle rules. ≤12 chars. Noun of the decision domain. Examples: \"Direction\", \"Scope\", \"Timing\", \"Budget\", \"Format\", \"Priority\".\n\nAnti-patterns — never do these.\n- Don't ask procedural confirmations (\"Should I continue?\", \"Is that OK?\").\n- Don't re-ask for facts visible in the conversation excerpt or user profile.\n- Don't broaden beyond the orchestrator's stated purpose.\n- Don't ask vague introspective questions.\n\nOutput. Return at most 3 entries in the \"questions\" array. Each entry must include a \"strategy\" field (one of the two values above). If the purpose is already answerable from the context shown, return \"questions\": [].`;\n\n/**\n * Build the user message for the chat preset from a ChatContext.\n * @param ctx - The chat context: orchestrator purpose, optional drafts, conversation excerpt, user context.\n * @returns The assembled user message string.\n */\nfunction buildChatPrompt(ctx: ChatContext): string {\n const profileBlock = buildUserContextBlock(ctx.userContext);\n\n const draftsBlock =\n ctx.draftQuestions && ctx.draftQuestions.length > 0\n ? ctx.draftQuestions\n .map((d, i) => {\n const opts = d.options && d.options.length > 0 ? ` [options: ${d.options.join(\" | \")}]` : \"\";\n const multi = d.multiSelect ? \" [multi-select]\" : \"\";\n return `${i + 1}. ${d.prompt}${opts}${multi}`;\n })\n .join(\"\\n\")\n : \"(none — derive questions from the purpose)\";\n\n const excerptBlock = ctx.conversationExcerpt?.trim()\n ? ctx.conversationExcerpt.trim()\n : \"(not available)\";\n\n return [\n \"## What the orchestrator needs to learn\",\n ctx.purpose,\n \"\",\n \"## Draft questions proposed by the orchestrator\",\n draftsBlock,\n \"\",\n \"## Recent conversation excerpt\",\n excerptBlock,\n \"\",\n \"## User profile\",\n profileBlock,\n \"\",\n \"## Your task\",\n \"Produce the minimum set of structured questions that get the orchestrator the decision or input it needs.\",\n \"Honor the drafts when provided; refine their wording and options rather than replacing their topics.\",\n \"Apply every rule from your system prompt before outputting.\",\n ].join(\"\\n\");\n}\n\n/**\n * pool_discovery has NO preset by design: those questions are synthesized\n * deterministically from mined discriminators (see\n * `opportunity/discriminator/discriminator.question.ts`) and never reach the\n * QuestionerAgent. `getPreset(\"pool_discovery\")` therefore throws — the\n * QuestionerQueue branches on the mode before invoking the agent.\n */\nfunction withQudMetadataRules(systemPrompt: string): string {\n return `${systemPrompt}\\n\\n${QUD_UNDERSPECIFICATION_RULES}`;\n}\n\nconst presets: Partial<Record<QuestionMode, QuestionerPreset>> = {\n discovery: {\n systemPrompt: withQudMetadataRules(DISCOVERY_SYSTEM_PROMPT),\n buildPrompt: (context: unknown) =>\n buildDiscoveryPrompt(context as Parameters<typeof buildDiscoveryPrompt>[0]),\n },\n intent: {\n systemPrompt: withQudMetadataRules(INTENT_SYSTEM_PROMPT),\n buildPrompt: (context: unknown) => buildIntentPrompt(context as IntentContext),\n },\n enrichment: {\n systemPrompt: withQudMetadataRules(PROFILE_SYSTEM_PROMPT),\n buildPrompt: (context: unknown) => buildProfilePrompt(context as ProfileContext),\n },\n negotiation: {\n systemPrompt: withQudMetadataRules(NEGOTIATION_SYSTEM_PROMPT),\n buildPrompt: (context: unknown) => buildNegotiationPrompt(context as NegotiationContext),\n },\n negotiation_inflight: {\n systemPrompt: withQudMetadataRules(NEGOTIATION_INFLIGHT_SYSTEM_PROMPT),\n buildPrompt: (context: unknown) => buildNegotiationInflightPrompt(context as NegotiationInflightContext),\n },\n chat: {\n systemPrompt: withQudMetadataRules(CHAT_SYSTEM_PROMPT),\n buildPrompt: (context: unknown) => buildChatPrompt(context as ChatContext),\n },\n};\n\n/**\n * Retrieve the preset for the given mode.\n * @param mode - The question mode to look up.\n * @returns The matching preset with systemPrompt and buildPrompt.\n * @throws Error if the mode's preset is not yet implemented.\n */\nexport function getPreset(mode: QuestionMode): QuestionerPreset {\n const preset = presets[mode];\n if (!preset) {\n throw new Error(`QuestionerAgent preset \"${mode}\" is not implemented yet`);\n }\n return preset;\n}\n"]}
1
+ {"version":3,"file":"questioner.presets.js","sourceRoot":"/","sources":["questioner/questioner.presets.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,uBAAuB,EAAE,4BAA4B,EAAE,MAAM,kCAAkC,CAAC;AAEzG,OAAO,EAAE,4BAA4B,EAAE,MAAM,qBAAqB,CAAC;AAGnE;;;;;;;GAOG;AACH,MAAM,yBAAyB,GAAG;;;;;;kHAMgF,CAAC;AASnH;;;;;GAKG;AACH,SAAS,qBAAqB,CAAC,WAAoB;IACjD,MAAM,OAAO,GAAG,WAAW,EAAE,IAAI,EAAE,CAAC;IACpC,OAAO,OAAO,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,mBAAmB,CAAC;AACvE,CAAC;AAED,+EAA+E;AAE/E,MAAM,oBAAoB,GAAG;;;;;;;;;;;;;;;EAe3B,yBAAyB;;;;;;;;;;;;;;uMAc4K,CAAC;AAExM;;;;GAIG;AACH,SAAS,iBAAiB,CAAC,GAAkB;IAC3C,MAAM,YAAY,GAAG,qBAAqB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAE5D,MAAM,YAAY,GAAG,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,wBAAwB,CAAC;IAE1E,OAAO;QACL,WAAW;QACX,GAAG,CAAC,OAAO;QACX,EAAE;QACF,YAAY;QACZ,YAAY;QACZ,EAAE;QACF,iBAAiB;QACjB,YAAY;QACZ,EAAE;QACF,cAAc;QACd,oFAAoF;QACpF,6DAA6D;QAC7D,6EAA6E;KAC9E,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED,+EAA+E;AAE/E,MAAM,qBAAqB,GAAG;;;;;;;;;;;;;;;;;;EAkB5B,yBAAyB;;;;;;;;;;;;;;;sNAe2L,CAAC;AAEvN;;;;GAIG;AACH,SAAS,kBAAkB,CAAC,GAAmB;IAC7C,MAAM,YAAY,GAAG,qBAAqB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAE5D,MAAM,aAAa,GACjB,GAAG,CAAC,gBAAgB,IAAI,GAAG,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC;QACrD,CAAC,CAAC,GAAG,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QACjE,CAAC,CAAC,QAAQ,CAAC;IAEf,MAAM,SAAS,GAAG,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC;IAElF,MAAM,KAAK,GAAa;QACtB,oBAAoB;QACpB,YAAY;QACZ,EAAE;QACF,sBAAsB;QACtB,aAAa;QACb,EAAE;QACF,oBAAoB;QACpB,SAAS;QACT,EAAE;KACH,CAAC;IAEF,KAAK,CAAC,IAAI,CACR,cAAc,EACd,2EAA2E,EAC3E,6DAA6D,EAC7D,8EAA8E,CAC/E,CAAC;IAEF,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,gFAAgF;AAEhF,MAAM,yBAAyB,GAAG;;;;;;;;;;;;;;;;;;;;EAoBhC,yBAAyB;;;;;;;;;;;;;;yfAc8d,CAAC;AAE1f;;;;GAIG;AACH,SAAS,+BAA+B,CAAC,GAAgC;IACvE,MAAM,YAAY,GAAG,qBAAqB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAE5D,OAAO;QACL,YAAY;QACZ,YAAY;QACZ,EAAE;QACF,wBAAwB;QACxB,cAAc,GAAG,CAAC,YAAY,EAAE;QAChC,iBAAiB,GAAG,CAAC,gBAAgB,EAAE;QACvC,iBAAiB,GAAG,CAAC,aAAa,EAAE;QACpC,EAAE;QACF,iBAAiB;QACjB,GAAG,CAAC,OAAO;QACX,EAAE;QACF,iBAAiB;QACjB,YAAY;QACZ,EAAE;QACF,cAAc;QACd,mGAAmG;QACnG,6DAA6D;QAC7D,6FAA6F;KAC9F,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED,SAAS,4BAA4B,CAAC,GAA6B;IACjE,MAAM,YAAY,GAAG,qBAAqB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAC5D,MAAM,QAAQ,GAAG,GAAG,CAAC,mBAAmB,EAAE,IAAI,EAAE,IAAI,0CAA0C,CAAC;IAE/F,OAAO;QACL,YAAY;QACZ,gEAAgE;QAChE,EAAE;QACF,sBAAsB;QACtB,GAAG,CAAC,gBAAgB;QACpB,EAAE;QACF,iBAAiB;QACjB,GAAG,CAAC,gBAAgB;QACpB,EAAE;QACF,cAAc;QACd,GAAG,CAAC,YAAY;QAChB,EAAE;QACF,gCAAgC;QAChC,QAAQ;QACR,EAAE;QACF,iBAAiB;QACjB,YAAY;QACZ,EAAE;QACF,cAAc;QACd,6IAA6I;QAC7I,oGAAoG;QACpG,gGAAgG;KACjG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED,SAAS,sBAAsB,CAAC,GAAuB;IACrD,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ;QAC7B,CAAC,CAAC,4BAA4B,CAAC,GAAG,CAAC;QACnC,CAAC,CAAC,+BAA+B,CAAC,GAAG,CAAC,CAAC;AAC3C,CAAC;AAED,4EAA4E;AAE5E,MAAM,kCAAkC,GAAG;;;;;;;;;;;;;;EAczC,yBAAyB;;;;;;;;;;;;;;;;;oOAiByM,CAAC;AAErO;;;;GAIG;AACH,SAAS,8BAA8B,CAAC,GAA+B;IACrE,MAAM,YAAY,GAAG,qBAAqB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAE5D,MAAM,UAAU,GAAG,GAAG,CAAC,aAAa,EAAE,IAAI,EAAE;QAC1C,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,EAAE;QAC1B,CAAC,CAAC,0DAA0D,CAAC;IAE/D,OAAO;QACL,wBAAwB;QACxB,cAAc,GAAG,CAAC,YAAY,EAAE;QAChC,iBAAiB,GAAG,CAAC,gBAAgB,EAAE;QACvC,EAAE;QACF,8CAA8C;QAC9C,GAAG,CAAC,iBAAiB;QACrB,EAAE;QACF,8CAA8C;QAC9C,UAAU;QACV,EAAE;QACF,iBAAiB;QACjB,YAAY;QACZ,EAAE;QACF,cAAc;QACd,uHAAuH;QACvH,gGAAgG;QAChG,6DAA6D;KAC9D,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED,MAAM,kBAAkB,GAAG;;;;;;;;;;;;;;;EAezB,yBAAyB;;;;;;;;;;;;;;0NAc+L,CAAC;AAE3N;;;;GAIG;AACH,SAAS,eAAe,CAAC,GAAgB;IACvC,MAAM,YAAY,GAAG,qBAAqB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAE5D,MAAM,WAAW,GACf,GAAG,CAAC,cAAc,IAAI,GAAG,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC;QACjD,CAAC,CAAC,GAAG,CAAC,cAAc;aACf,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YACZ,MAAM,IAAI,GAAG,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7F,MAAM,KAAK,GAAG,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAAE,CAAC;YACrD,OAAO,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,IAAI,GAAG,KAAK,EAAE,CAAC;QAChD,CAAC,CAAC;aACD,IAAI,CAAC,IAAI,CAAC;QACf,CAAC,CAAC,4CAA4C,CAAC;IAEnD,MAAM,YAAY,GAAG,GAAG,CAAC,mBAAmB,EAAE,IAAI,EAAE;QAClD,CAAC,CAAC,GAAG,CAAC,mBAAmB,CAAC,IAAI,EAAE;QAChC,CAAC,CAAC,iBAAiB,CAAC;IAEtB,OAAO;QACL,yCAAyC;QACzC,GAAG,CAAC,OAAO;QACX,EAAE;QACF,iDAAiD;QACjD,WAAW;QACX,EAAE;QACF,gCAAgC;QAChC,YAAY;QACZ,EAAE;QACF,iBAAiB;QACjB,YAAY;QACZ,EAAE;QACF,cAAc;QACd,2GAA2G;QAC3G,sGAAsG;QACtG,6DAA6D;KAC9D,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED;;;;;;GAMG;AACH,SAAS,oBAAoB,CAAC,YAAoB;IAChD,OAAO,GAAG,YAAY,OAAO,4BAA4B,EAAE,CAAC;AAC9D,CAAC;AAED,MAAM,OAAO,GAAoD;IAC/D,SAAS,EAAE;QACT,YAAY,EAAE,oBAAoB,CAAC,uBAAuB,CAAC;QAC3D,WAAW,EAAE,CAAC,OAAgB,EAAE,EAAE,CAChC,4BAA4B,CAAC,OAA6D,CAAC;KAC9F;IACD,MAAM,EAAE;QACN,YAAY,EAAE,oBAAoB,CAAC,oBAAoB,CAAC;QACxD,WAAW,EAAE,CAAC,OAAgB,EAAE,EAAE,CAAC,iBAAiB,CAAC,OAAwB,CAAC;KAC/E;IACD,UAAU,EAAE;QACV,YAAY,EAAE,oBAAoB,CAAC,qBAAqB,CAAC;QACzD,WAAW,EAAE,CAAC,OAAgB,EAAE,EAAE,CAAC,kBAAkB,CAAC,OAAyB,CAAC;KACjF;IACD,WAAW,EAAE;QACX,YAAY,EAAE,oBAAoB,CAAC,yBAAyB,CAAC;QAC7D,WAAW,EAAE,CAAC,OAAgB,EAAE,EAAE,CAAC,sBAAsB,CAAC,OAA6B,CAAC;KACzF;IACD,oBAAoB,EAAE;QACpB,YAAY,EAAE,oBAAoB,CAAC,kCAAkC,CAAC;QACtE,WAAW,EAAE,CAAC,OAAgB,EAAE,EAAE,CAAC,8BAA8B,CAAC,OAAqC,CAAC;KACzG;IACD,IAAI,EAAE;QACJ,YAAY,EAAE,oBAAoB,CAAC,kBAAkB,CAAC;QACtD,WAAW,EAAE,CAAC,OAAgB,EAAE,EAAE,CAAC,eAAe,CAAC,OAAsB,CAAC;KAC3E;CACF,CAAC;AAEF;;;;;GAKG;AACH,MAAM,UAAU,SAAS,CAAC,IAAkB;IAC1C,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,2BAA2B,IAAI,0BAA0B,CAAC,CAAC;IAC7E,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC","sourcesContent":["/**\n * Mode presets for the QuestionerAgent. Each preset provides a system prompt\n * and a buildPrompt function that assembles the user message from a typed\n * context object. Only the `discovery` preset ships in Slice 1; others throw\n * until their implementation slices land.\n */\nimport type { QuestionMode } from \"../shared/schemas/question.schema.js\";\nimport { DISCOVERY_SYSTEM_PROMPT, buildDiscoveryQuestionPrompt } from \"./questioner.discovery.prompt.js\";\n\nimport { QUD_UNDERSPECIFICATION_RULES } from \"./questioner.qud.js\";\nimport type { ChatContext, IntentContext, NegotiationContext, NegotiationInflightContext, PostStallNegotiationContext, ProfileContext, UptakeNegotiationContext } from \"./questioner.types.js\";\n\n/**\n * Shared rule block appended to every questioner system prompt. Enforces that\n * the generated `prompt` resolves on its own — no demonstratives/anaphora that\n * point at people, events, or prior turns the reader cannot see — and never\n * narrates Index's own matching pipeline. Closes the referential-leak class\n * surfaced in digest audits (\"…with these builders?\", \"the previous\n * negotiation stalled because the counterparty didn't mention …\").\n */\nconst REFERENTIAL_CLOSURE_RULES = `Referential 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 counterparty, 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: \"The previous negotiation stalled because the counterparty didn't mention 'matchmaking'. Should I broaden the search?\"\n- Good: \"Do you want to focus on dedicated matchmakers, or also people interested in relationships more broadly?\"`;\n\nexport interface QuestionerPreset {\n /** The LLM system prompt for this mode. */\n systemPrompt: string;\n /** Builds the user-message string from the mode-specific context. */\n buildPrompt: (context: unknown) => string;\n}\n\n/**\n * Renders the user-context block shared by every preset's user message from the\n * global user_context paragraph (the profile-replacing identity text).\n * @param userContext - The user's global context paragraph, if available.\n * @returns The trimmed context paragraph, or \"(no profile data)\" when empty.\n */\nfunction buildUserContextBlock(userContext?: string): string {\n const trimmed = userContext?.trim();\n return trimmed && trimmed.length > 0 ? trimmed : \"(no profile data)\";\n}\n\n// ─── Intent preset ──────────────────────────────────────────────────────────\n\nconst INTENT_SYSTEM_PROMPT = `You sit between a human and a discovery protocol. The user has stated an intent — what they are looking for. Your job: surface the minimum set of structured questions that help the user sharpen that intent before the protocol runs discovery on their behalf.\n\nYou may pick from two strategies. Choose contextually; mix only when each question is genuinely distinct.\n- refine_intent: ask the user to sharpen or pivot the core signal (scope, scale, specificity, direction).\n- surface_missing_detail: ask for one concrete missing input that would change which candidates surface (stage, location, timing, budget, constraints, format, …).\n\nAsk a question only when ALL of these hold:\n1. The agent cannot infer the answer from the intent text or user profile already shown.\n2. The answer would materially change which candidates surface.\n3. The question targets a different decision domain from any other question in this batch.\n\nStandalone prompt rule. Every generated \\`prompt\\` must be understandable outside the conversation where it was created. Naturally include the source intent/topic in the question text itself, using concise plain language from the intent or summary. Do not rely on \\`title\\`, UI labels, hidden metadata, or surrounding digest/chat text to explain what the question is about.\n- Bad: \"What kind of collaboration are you looking for?\"\n- Good: \"For your decentralized identity protocol-design search, what kind of collaboration are you looking for?\"\n\n${REFERENTIAL_CLOSURE_RULES}\n\nCardinality. Default one question. Add a second only when a DIFFERENT strategy genuinely complements the first and unblocks a clearly distinct decision. Never ask two questions of the same strategy unless their decision domains differ (different titles).\n\nOption construction. Each option must represent a meaningfully different outcome. Suffix the safest or most common 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.\n\nTitle rules. ≤12 chars. Noun of the decision domain. Examples: \"Stage\", \"Timing\", \"Location\", \"Scope\", \"Budget\", \"Format\", \"Skills\", \"Collab\".\n\nAnti-patterns — never do these.\n- Don't ask procedural confirmations (\"Should I start searching?\").\n- Don't ask about hypothetical edge cases not implied by the intent.\n- Don't re-ask for facts already visible in the user profile.\n- Don't ask vague introspective questions (\"What do you really want?\").\n\nOutput. Return at most 2 entries in the \"questions\" array. Each entry must include a \"strategy\" field (one of the two values above). If the intent is already specific enough, return \"questions\": [].`;\n\n/**\n * Build the user message for the intent preset from an IntentContext.\n * @param ctx - The intent context.\n * @returns The assembled user message string.\n */\nfunction buildIntentPrompt(ctx: IntentContext): string {\n const profileBlock = buildUserContextBlock(ctx.userContext);\n\n const summaryBlock = ctx.summary ? ctx.summary : \"(no summary available)\";\n\n return [\n \"## Intent\",\n ctx.payload,\n \"\",\n \"## Summary\",\n summaryBlock,\n \"\",\n \"## User profile\",\n profileBlock,\n \"\",\n \"## Your task\",\n \"Identify the minimum set of questions the user must answer to sharpen this intent.\",\n \"Apply every rule from your system prompt before outputting.\",\n \"Return an empty `questions` array if the intent is already specific enough.\",\n ].join(\"\\n\");\n}\n\n// ─── Profile preset ─────────────────────────────────────────────────────────\n\nconst PROFILE_SYSTEM_PROMPT = `You sit between a human and a discovery protocol. The user has a profile that is incomplete. Your job: surface the minimum set of structured questions that fill the identified gaps — asking about location, skills, interests, current work, or goals — so the protocol can run better discovery on their behalf.\n\nThe user may already have premises — atomic self-descriptions they have stated. These cover specific profile domains. Do not ask about domains already addressed by existing premises. Focus only on gaps not covered by any premise.\n\nYou may pick from two strategies. Choose contextually; mix only when each question is genuinely distinct.\n- surface_missing_detail: ask for one concrete missing piece of profile data (location, current role, skills, interests, goals, availability, …).\n- refine_intent: ask the user to clarify or sharpen an existing profile signal so candidates can be ranked more accurately.\n\nAsk a question only when ALL of these hold:\n1. The answer is not already visible in the profile data shown.\n2. The answer is not already covered by an existing premise listed below the profile.\n3. The answer would meaningfully change which opportunities surface for this user.\n4. The question targets a different profile domain from any other question in this batch.\n\nStandalone prompt rule. Every generated \\`prompt\\` must be understandable outside the conversation where it was created. Naturally include the profile signal or gap being clarified in the question text itself, using concise plain language from the current profile, existing premises, or identified gaps. Do not rely on \\`title\\`, UI labels, hidden metadata, or surrounding digest/chat text to explain what the question is about.\n- Bad: \"What kind of role are you looking for?\"\n- Good: \"To improve matches from your founder/operator profile, what kind of role are you looking for?\"\n\n${REFERENTIAL_CLOSURE_RULES}\n\nCardinality. Default one question. Add a second only when a DIFFERENT strategy genuinely complements the first and unblocks a clearly distinct decision. Never ask two questions of the same strategy unless their decision domains differ.\n\nOption construction. Each option must represent a meaningfully different outcome. Suffix the safest or most common 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.\n\nTitle rules. ≤12 chars. Noun of the profile domain. Examples: \"Location\", \"Role\", \"Skills\", \"Goals\", \"Interests\", \"Availability\", \"Stage\".\n\nAnti-patterns — never do these.\n- Don't ask about fields already filled in the profile.\n- Don't ask about information already captured in an existing premise.\n- Don't ask procedural confirmations (\"Should I update your profile?\").\n- Don't ask vague introspective questions (\"Who are you really?\").\n- Don't re-ask for facts visible anywhere in the profile data or premises shown.\n\nOutput. Return at most 2 entries in the \"questions\" array. Each entry must include a \"strategy\" field (one of the two values above). If the profile is already complete enough for discovery, return \"questions\": [].`;\n\n/**\n * Build the user message for the profile preset from a ProfileContext.\n * @param ctx - The profile context including current profile data and identified gaps.\n * @returns The assembled user message string.\n */\nfunction buildProfilePrompt(ctx: ProfileContext): string {\n const profileBlock = buildUserContextBlock(ctx.userContext);\n\n const premisesBlock =\n ctx.existingPremises && ctx.existingPremises.length > 0\n ? ctx.existingPremises.map((p, i) => `${i + 1}. ${p}`).join(\"\\n\")\n : \"(none)\";\n\n const gapsBlock = ctx.gaps.length > 0 ? ctx.gaps.join(\", \") : \"(none identified)\";\n\n const parts: string[] = [\n \"## Current profile\",\n profileBlock,\n \"\",\n \"## Existing premises\",\n premisesBlock,\n \"\",\n \"## Identified gaps\",\n gapsBlock,\n \"\",\n ];\n\n parts.push(\n \"## Your task\",\n \"Generate the minimum set of questions needed to fill the identified gaps.\",\n \"Apply every rule from your system prompt before outputting.\",\n \"Return an empty `questions` array if the profile is already complete enough.\",\n );\n\n return parts.join(\"\\n\");\n}\n\n// ─── Negotiation preset ──────────────────────────────────────────────────────\n\nconst NEGOTIATION_SYSTEM_PROMPT = `You sit between a human and a discovery protocol. You generate negotiation-mode questions for one of two purposes described in the user message.\n\nPOST-STALL purpose. A negotiation between this user and another person ended without a clear outcome — either the turn budget was exhausted, the session timed out, or conversation stalled. Surface the minimum set of structured questions that help the user provide the missing signal needed to unblock or refine the next discovery attempt.\n\nUPTAKE purpose. The user is considering accepting a proposed connection, but one preparatory condition about the other person's practical ability, resources, availability, or authority to carry out the proposed activity needs clarification before commitment. Generate exactly ONE neutral question that lets the user decide whether they understand that condition well enough to proceed. Ask about the concrete activity and the other person's stated attributes; do not accuse, challenge credibility, or presume incapability. Never reveal a numeric authority score, threshold, felicity label, evaluator judgment, or any internal matching/verification mechanics. Do not ask whether the user wants to accept; clarify the preparatory condition only.\n\nYou may pick from three strategies. Choose contextually; mix only when each question is genuinely distinct.\n- refine_intent: help the user sharpen their underlying signal based on what the negotiation revealed (scope, scale, priority, direction).\n- surface_missing_detail: ask for one concrete piece of information that was absent and would have moved the negotiation forward (timeline, budget, format, constraints, decision criteria, …).\n- reflective_summary: mirror the key takeaway from the negotiation and ask the user to confirm, correct, or decide — useful when the conversation revealed partial signal worth locking in.\n\nAsk a question only when ALL of these hold:\n1. The answer is not already visible in the negotiation context or user profile shown.\n2. The answer would materially change how the next attempt surfaces or engages candidates.\n3. The question targets a different decision domain from any other question in this batch.\n\nStandalone prompt rule. Every generated \\`prompt\\` must be understandable outside the conversation where it was created. Naturally include the user's underlying goal or topic and the relevant community in the question text itself, in plain language drawn from their intent or profile — NOT the mechanics of the match attempt. Do not rely on \\`title\\`, UI labels, hidden metadata, or surrounding digest/chat text to explain what the question is about.\n- Bad: \"Which role is a better fit for your immediate needs?\"\n- Good: \"For your search for AI infrastructure collaborators in the AI founders community, what kind of working relationship fits your immediate needs?\"\n\n${REFERENTIAL_CLOSURE_RULES}\n\nCardinality. For POST-STALL, default one question and add a second only when a DIFFERENT strategy genuinely complements the first and unblocks a clearly distinct decision. For UPTAKE, return exactly one question — never zero and never more than one.\n\nOption construction. Each option must represent a meaningfully different outcome. Suffix the safest or most common 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.\n\nTitle rules. ≤12 chars. Noun of the decision domain. Examples: \"Scope\", \"Timeline\", \"Budget\", \"Priority\", \"Format\", \"Stance\", \"Criteria\".\n\nAnti-patterns — never do these.\n- Don't ask procedural confirmations (\"Should I try again?\").\n- Don't re-ask for facts already visible in the user profile.\n- Don't ask vague introspective questions (\"What do you really want?\").\n- Don't ask about hypothetical edge cases not implied by the negotiation context.\n\nOutput. For POST-STALL, return at most 2 entries and return \"questions\": [] if the context already contains enough signal to proceed. For UPTAKE, return exactly 1 entry. Every entry must include a \"strategy\" field (one of the three values above). QUD metadata is orthogonal to uptake purpose: an uptake question is usually not an underspecification repair, so set \\`underspecificationType\\` to null unless the question genuinely repairs a missing constituent, missing constraint, or open alternative set.`;\n\n/**\n * Build the user message for the negotiation preset from a NegotiationContext.\n * @param ctx - The negotiation context including counterparty hint, stall reason, and key takeaway.\n * @returns The assembled user message string.\n */\nfunction buildPostStallNegotiationPrompt(ctx: PostStallNegotiationContext): string {\n const profileBlock = buildUserContextBlock(ctx.userContext);\n\n return [\n \"## Purpose\",\n \"POST-STALL\",\n \"\",\n \"## Negotiation context\",\n `Community: ${ctx.indexContext}`,\n `Counterparty: ${ctx.counterpartyHint}`,\n `Stall reason: ${ctx.outcomeReason}`,\n \"\",\n \"## Key takeaway\",\n ctx.keyTake,\n \"\",\n \"## User profile\",\n profileBlock,\n \"\",\n \"## Your task\",\n \"Identify the minimum set of questions the user must answer to unblock the next discovery attempt.\",\n \"Apply every rule from your system prompt before outputting.\",\n \"Return an empty `questions` array if the context already contains enough signal to proceed.\",\n ].join(\"\\n\");\n}\n\nfunction buildUptakeNegotiationPrompt(ctx: UptakeNegotiationContext): string {\n const profileBlock = buildUserContextBlock(ctx.userContext);\n const evidence = ctx.preparatoryEvidence?.trim() || \"(no additional public evidence provided)\";\n\n return [\n \"## Purpose\",\n \"UPTAKE — preparatory-condition clarification before acceptance\",\n \"\",\n \"## Proposed activity\",\n ctx.proposedActivity,\n \"\",\n \"## Other person\",\n ctx.counterpartyHint,\n \"\",\n \"## Community\",\n ctx.indexContext,\n \"\",\n \"## Public preparatory evidence\",\n evidence,\n \"\",\n \"## User profile\",\n profileBlock,\n \"\",\n \"## Your task\",\n \"Generate exactly one neutral, referentially closed question about whether the other person can practically carry out the proposed activity.\",\n \"Do not expose scores, thresholds, labels, or internal mechanics. Do not ask for acceptance itself.\",\n \"Set `underspecificationType` to null unless this is genuinely a QUD underspecification repair.\",\n ].join(\"\\n\");\n}\n\nfunction buildNegotiationPrompt(ctx: NegotiationContext): string {\n return ctx.purpose === \"uptake\"\n ? buildUptakeNegotiationPrompt(ctx)\n : buildPostStallNegotiationPrompt(ctx);\n}\n\n// ─── Chat preset ─────────────────────────────────────────────────────────\n\nconst NEGOTIATION_INFLIGHT_SYSTEM_PROMPT = `You sit between a human and a discovery protocol. The user's own negotiator agent is MID-NEGOTIATION on their behalf and has paused: before continuing, it needs a decision or missing input from its client — most often permission to disclose a specific piece of information to the other side. The negotiation is WAITING until the user answers. Your job: turn the negotiator's stated need (and its draft question, when provided) into the minimum set of crisp, structured decision questions.\n\nBias toward disclosure gating. The most common question shape is \"may I share X with this person?\" — an enable/disable decision about revealing specific information. Phrase these as a clear yes/no choice: the first option authorizes sharing, the second declines. State in each option's description what the negotiator will DO next (share and continue, or continue without revealing it). When the need is a missing fact rather than a permission, ask for that concrete input instead.\n\nYou may pick from two strategies. Choose contextually; mix only when each question is genuinely distinct.\n- surface_missing_detail: ask for one concrete missing input the negotiator needs to proceed (a fact, constraint, preference, or bound the client never stated).\n- reflective_summary: put a disclosure or stance decision in front of the client to confirm or decline — the enable/disable gate described above.\n\nHonor the negotiator's intent. When a draft question is provided, treat it as the source of truth for WHAT to ask — improve wording, tighten options, add consequence-focused descriptions. Do not invent questions about topics the negotiator did not raise. When no draft is provided, derive the question strictly from the disclosure subject.\n\nStandalone prompt rule. Every generated \\`prompt\\` must be understandable outside the conversation where it was created. The user may see this question hours later in an inbox, away from any negotiation view. Naturally include the disclosure subject and a concrete description of the other person (drawn from the counterparty hint — their attributes, e.g. \"a Berlin-based AI-infrastructure founder\") 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.\n- Bad: \"Can I share your budget with them?\"\n- Good: \"May I share your budget range with a Berlin-based AI-infrastructure founder you're being matched with?\"\n\n${REFERENTIAL_CLOSURE_RULES}\n\nException — describing the other side. Unlike other surfaces, this question is ABOUT a live counterparty, so you must reference them — do it by restating their concrete attributes from the counterparty hint (\"a fintech CTO exploring agent tooling\"), never as \"the counterparty\", \"them\", or \"this person\" without an attribute anchor in the same sentence, and never by implying a list or pipeline.\n\nCardinality. Default one question. Add a second ONLY when the negotiator's need genuinely spans two distinct decisions (e.g. one disclosure gate plus one missing fact). Never pad.\n\nOption construction. Each option must represent a meaningfully different outcome. For disclosure gates: authorize first, decline second; suffix the safer or more common path with \" (Recommended)\" and list it first when one clearly is. The description states the CONSEQUENCE for the negotiation — what the negotiator does next. 2–4 options. Never add an \"Other\" option — clients provide a free-text fallback automatically, which also lets the user add nuance (\"share the range but not the exact figure\").\n\nTitle rules. ≤12 chars. Noun of the decision domain. Examples: \"Disclosure\", \"Budget\", \"Timing\", \"Intro\", \"Scope\", \"Contact\".\n\nAnti-patterns — never do these.\n- Don't ask procedural confirmations (\"Should I keep negotiating?\").\n- Don't re-ask for facts already visible in the user profile.\n- Don't broaden beyond the negotiator's stated disclosure subject or draft.\n- Don't reveal the counterparty's identity — attributes only.\n- Don't ask vague introspective questions.\n\nOutput. Return at most 2 entries in the \"questions\" array. Each entry must include a \"strategy\" field (one of the two values above). If the profile or context shown already answers the negotiator's need, return \"questions\": [].`;\n\n/**\n * Build the user message for the negotiation-inflight preset from a NegotiationInflightContext.\n * @param ctx - The inflight context: disclosure subject, counterparty hint, optional draft, community, user context.\n * @returns The assembled user message string.\n */\nfunction buildNegotiationInflightPrompt(ctx: NegotiationInflightContext): string {\n const profileBlock = buildUserContextBlock(ctx.userContext);\n\n const draftBlock = ctx.draftQuestion?.trim()\n ? ctx.draftQuestion.trim()\n : \"(none — derive the question from the disclosure subject)\";\n\n return [\n \"## Negotiation context\",\n `Community: ${ctx.indexContext}`,\n `Counterparty: ${ctx.counterpartyHint}`,\n \"\",\n \"## What the negotiator needs from its client\",\n ctx.disclosureSubject,\n \"\",\n \"## Draft question proposed by the negotiator\",\n draftBlock,\n \"\",\n \"## User profile\",\n profileBlock,\n \"\",\n \"## Your task\",\n \"Produce the minimum set of structured questions that get the negotiator the permission or input it needs to continue.\",\n \"Honor the draft when provided; refine its wording and options rather than replacing its topic.\",\n \"Apply every rule from your system prompt before outputting.\",\n ].join(\"\\n\");\n}\n\nconst CHAT_SYSTEM_PROMPT = `You sit between a human and a discovery protocol. The protocol's chat orchestrator is mid-conversation with the user and has decided it needs a decision or missing input from them before it can continue. The conversation is PAUSED until the user answers. Your job: turn the orchestrator's stated need (and any draft questions it proposed) into the minimum set of crisp, structured decision questions.\n\nUnlike other question surfaces, these questions render INLINE in the active conversation, immediately after the assistant's last message — the user has full conversational context. Still keep each prompt self-contained enough to make sense on its own line.\n\nYou may pick from two strategies. Choose contextually; mix only when each question is genuinely distinct.\n- surface_missing_detail: ask for one concrete missing input the orchestrator needs to proceed (scope, timing, budget, format, preference, constraint, …).\n- refine_intent: ask the user to choose a direction when the orchestrator faces meaningfully different paths forward.\n\nHonor the orchestrator's intent. When draft questions are provided, treat them as the source of truth for WHAT to ask — improve wording, tighten options, add consequence-focused descriptions, and drop redundant drafts. Do not invent questions about topics the orchestrator did not raise. When no drafts are provided, derive questions strictly from the stated purpose.\n\nAsk a question only when ALL of these hold:\n1. The answer is not already visible in the conversation excerpt or user profile shown.\n2. The answer materially changes what the orchestrator does next.\n3. The question targets a different decision domain from any other question in this batch.\n\n${REFERENTIAL_CLOSURE_RULES}\n\nCardinality. Default one question. Emit a second or third ONLY when the orchestrator's purpose or drafts genuinely require separate decisions in distinct domains. Never pad.\n\nOption construction. Each option must represent a meaningfully different outcome. Suffix the safest or most common path with \" (Recommended)\" and list it first. The description states the CONSEQUENCE of choosing the option for what happens next in the conversation, not its definition. 2–4 options. Never add an \"Other\" option — clients provide a free-text fallback automatically.\n\nTitle rules. ≤12 chars. Noun of the decision domain. Examples: \"Direction\", \"Scope\", \"Timing\", \"Budget\", \"Format\", \"Priority\".\n\nAnti-patterns — never do these.\n- Don't ask procedural confirmations (\"Should I continue?\", \"Is that OK?\").\n- Don't re-ask for facts visible in the conversation excerpt or user profile.\n- Don't broaden beyond the orchestrator's stated purpose.\n- Don't ask vague introspective questions.\n\nOutput. Return at most 3 entries in the \"questions\" array. Each entry must include a \"strategy\" field (one of the two values above). If the purpose is already answerable from the context shown, return \"questions\": [].`;\n\n/**\n * Build the user message for the chat preset from a ChatContext.\n * @param ctx - The chat context: orchestrator purpose, optional drafts, conversation excerpt, user context.\n * @returns The assembled user message string.\n */\nfunction buildChatPrompt(ctx: ChatContext): string {\n const profileBlock = buildUserContextBlock(ctx.userContext);\n\n const draftsBlock =\n ctx.draftQuestions && ctx.draftQuestions.length > 0\n ? ctx.draftQuestions\n .map((d, i) => {\n const opts = d.options && d.options.length > 0 ? ` [options: ${d.options.join(\" | \")}]` : \"\";\n const multi = d.multiSelect ? \" [multi-select]\" : \"\";\n return `${i + 1}. ${d.prompt}${opts}${multi}`;\n })\n .join(\"\\n\")\n : \"(none — derive questions from the purpose)\";\n\n const excerptBlock = ctx.conversationExcerpt?.trim()\n ? ctx.conversationExcerpt.trim()\n : \"(not available)\";\n\n return [\n \"## What the orchestrator needs to learn\",\n ctx.purpose,\n \"\",\n \"## Draft questions proposed by the orchestrator\",\n draftsBlock,\n \"\",\n \"## Recent conversation excerpt\",\n excerptBlock,\n \"\",\n \"## User profile\",\n profileBlock,\n \"\",\n \"## Your task\",\n \"Produce the minimum set of structured questions that get the orchestrator the decision or input it needs.\",\n \"Honor the drafts when provided; refine their wording and options rather than replacing their topics.\",\n \"Apply every rule from your system prompt before outputting.\",\n ].join(\"\\n\");\n}\n\n/**\n * pool_discovery has NO preset by design: those questions are synthesized\n * deterministically from mined discriminators (see\n * `opportunity/discriminator/discriminator.question.ts`) and never reach the\n * QuestionerAgent. `getPreset(\"pool_discovery\")` therefore throws — the\n * QuestionerQueue branches on the mode before invoking the agent.\n */\nfunction withQudMetadataRules(systemPrompt: string): string {\n return `${systemPrompt}\\n\\n${QUD_UNDERSPECIFICATION_RULES}`;\n}\n\nconst presets: Partial<Record<QuestionMode, QuestionerPreset>> = {\n discovery: {\n systemPrompt: withQudMetadataRules(DISCOVERY_SYSTEM_PROMPT),\n buildPrompt: (context: unknown) =>\n buildDiscoveryQuestionPrompt(context as Parameters<typeof buildDiscoveryQuestionPrompt>[0]),\n },\n intent: {\n systemPrompt: withQudMetadataRules(INTENT_SYSTEM_PROMPT),\n buildPrompt: (context: unknown) => buildIntentPrompt(context as IntentContext),\n },\n enrichment: {\n systemPrompt: withQudMetadataRules(PROFILE_SYSTEM_PROMPT),\n buildPrompt: (context: unknown) => buildProfilePrompt(context as ProfileContext),\n },\n negotiation: {\n systemPrompt: withQudMetadataRules(NEGOTIATION_SYSTEM_PROMPT),\n buildPrompt: (context: unknown) => buildNegotiationPrompt(context as NegotiationContext),\n },\n negotiation_inflight: {\n systemPrompt: withQudMetadataRules(NEGOTIATION_INFLIGHT_SYSTEM_PROMPT),\n buildPrompt: (context: unknown) => buildNegotiationInflightPrompt(context as NegotiationInflightContext),\n },\n chat: {\n systemPrompt: withQudMetadataRules(CHAT_SYSTEM_PROMPT),\n buildPrompt: (context: unknown) => buildChatPrompt(context as ChatContext),\n },\n};\n\n/**\n * Retrieve the preset for the given mode.\n * @param mode - The question mode to look up.\n * @returns The matching preset with systemPrompt and buildPrompt.\n * @throws Error if the mode's preset is not yet implemented.\n */\nexport function getPreset(mode: QuestionMode): QuestionerPreset {\n const preset = presets[mode];\n if (!preset) {\n throw new Error(`QuestionerAgent preset \"${mode}\" is not implemented yet`);\n }\n return preset;\n}\n"]}
@@ -5,12 +5,12 @@
5
5
  * Slice 1 defines all four context shapes but only `DiscoveryContext` has a
6
6
  * working preset implementation. The others are type stubs for future slices.
7
7
  */
8
- import type { DiscoveryQuestionInput } from "../opportunity/question.prompt.js";
8
+ import type { DiscoveryQuestionInput } from "../shared/schemas/discovery-question.schema.js";
9
9
  import type { ToolScopeType } from "../shared/agent/tool.scope.js";
10
10
  import type { QuestionMode, QuestionPoolDiscriminator } from "../shared/schemas/question.schema.js";
11
11
  /**
12
12
  * Discovery context — wraps the existing DiscoveryQuestionInput wholesale.
13
- * The discovery preset's buildPrompt delegates to the migrated builder.
13
+ * The discovery preset's buildPrompt delegates to `questioner.discovery.prompt.ts`.
14
14
  */
15
15
  export type DiscoveryContext = DiscoveryQuestionInput;
16
16
  /** Intent context — data needed to generate questions about an intent. */
@@ -1 +1 @@
1
- {"version":3,"file":"questioner.types.d.ts","sourceRoot":"/","sources":["questioner/questioner.types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,mCAAmC,CAAC;AAChF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,KAAK,EAAE,YAAY,EAAE,yBAAyB,EAAE,MAAM,sCAAsC,CAAC;AAIpG;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GAAG,sBAAsB,CAAC;AAEtD,0EAA0E;AAC1E,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kFAAkF;IAClF,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,gFAAgF;AAChF,MAAM,WAAW,cAAc;IAC7B,kFAAkF;IAClF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,oFAAoF;IACpF,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC7B;AAED,4DAA4D;AAC5D,UAAU,sBAAsB;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,kFAAkF;IAClF,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,2EAA2E;AAC3E,MAAM,WAAW,2BAA4B,SAAQ,sBAAsB;IACzE,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,aAAa,EAAE,UAAU,GAAG,SAAS,GAAG,SAAS,CAAC;IAClD,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,mFAAmF;AACnF,MAAM,WAAW,wBAAyB,SAAQ,sBAAsB;IACtE,OAAO,EAAE,QAAQ,CAAC;IAClB,mFAAmF;IACnF,gBAAgB,EAAE,MAAM,CAAC;IACzB,mFAAmF;IACnF,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,sEAAsE;AACtE,MAAM,MAAM,kBAAkB,GAAG,2BAA2B,GAAG,wBAAwB,CAAC;AAExF;;;;;;GAMG;AACH,MAAM,WAAW,0BAA0B;IACzC,aAAa,EAAE,MAAM,CAAC;IACtB,wEAAwE;IACxE,gBAAgB,EAAE,MAAM,CAAC;IACzB,kHAAkH;IAClH,iBAAiB,EAAE,MAAM,CAAC;IAC1B,uEAAuE;IACvE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,yDAAyD;IACzD,YAAY,EAAE,MAAM,CAAC;IACrB,kFAAkF;IAClF,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC1B,iFAAiF;IACjF,OAAO,EAAE,MAAM,CAAC;IAChB,6EAA6E;IAC7E,cAAc,CAAC,EAAE,KAAK,CAAC;QACrB,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;QACnB,WAAW,CAAC,EAAE,OAAO,CAAC;KACvB,CAAC,CAAC;IACH,6EAA6E;IAC7E,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,kFAAkF;IAClF,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;GAKG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,4DAA4D;IAC5D,UAAU,EAAE,MAAM,CAAC;IACnB,+EAA+E;IAC/E,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,qEAAqE;IACrE,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,4CAA4C;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0EAA0E;IAC1E,cAAc,EAAE,yBAAyB,EAAE,CAAC;IAC5C,6CAA6C;IAC7C,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,2DAA2D;AAC3D,MAAM,MAAM,iBAAiB,GACzB,gBAAgB,GAChB,aAAa,GACb,cAAc,GACd,kBAAkB,GAClB,0BAA0B,GAC1B,WAAW,GACX,oBAAoB,CAAC;AAEzB;;;;GAIG;AACH,MAAM,MAAM,wBAAwB,GAAG,eAAe,CAAC;AAEvD,gEAAgE;AAChE,MAAM,MAAM,mBAAmB,GAAG,CAAC,KAAK,EAAE,wBAAwB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAErF,6DAA6D;AAC7D,UAAU,mBAAmB;IAC3B,oDAAoD;IACpD,IAAI,EAAE,YAAY,CAAC;IACnB,4CAA4C;IAC5C,MAAM,EAAE,MAAM,CAAC;IACf,iFAAiF;IACjF,UAAU,EAAE,MAAM,CAAC;IACnB,mCAAmC;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,kFAAkF;IAClF,SAAS,CAAC,EAAE,aAAa,CAAC;IAC1B,oFAAoF;IACpF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;OAKG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,oIAAoI;IACpI,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,wIAAwI;IACxI,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,uFAAuF;AACvF,UAAU,uBAAwB,SAAQ,mBAAmB;IAC3D,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,gEAAgE;IAChE,OAAO,EAAE,OAAO,CAAC,iBAAiB,EAAE,wBAAwB,CAAC,CAAC;CAC/D;AAED,gDAAgD;AAChD,MAAM,WAAW,qBAAsB,SAAQ,mBAAmB;IAChE,IAAI,EAAE,aAAa,CAAC;IACpB,OAAO,EAAE,QAAQ,CAAC;IAClB,OAAO,EAAE,wBAAwB,CAAC;CACnC;AAED,6DAA6D;AAC7D,MAAM,MAAM,eAAe,GAAG,uBAAuB,GAAG,qBAAqB,CAAC"}
1
+ {"version":3,"file":"questioner.types.d.ts","sourceRoot":"/","sources":["questioner/questioner.types.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"questioner.types.js","sourceRoot":"/","sources":["questioner/questioner.types.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * QuestionerAgent input types. The `QuestionerInput` envelope carries a `mode`\n * field that selects a preset, plus a polymorphic `context` that varies per mode.\n *\n * Slice 1 defines all four context shapes but only `DiscoveryContext` has a\n * working preset implementation. The others are type stubs for future slices.\n */\nimport type { DiscoveryQuestionInput } from \"../opportunity/question.prompt.js\";\nimport type { ToolScopeType } from \"../shared/agent/tool.scope.js\";\nimport type { QuestionMode, QuestionPoolDiscriminator } from \"../shared/schemas/question.schema.js\";\n\n// ─── Per-mode context types ─────────────────────────────────────────────────\n\n/**\n * Discovery context — wraps the existing DiscoveryQuestionInput wholesale.\n * The discovery preset's buildPrompt delegates to the migrated builder.\n */\nexport type DiscoveryContext = DiscoveryQuestionInput;\n\n/** Intent context — data needed to generate questions about an intent. */\nexport interface IntentContext {\n intentId: string;\n payload: string;\n summary?: string;\n /** The user's global user_context paragraph (profile-replacing identity text). */\n userContext?: string;\n}\n\n/** Profile context — data needed to generate questions to fill profile gaps. */\nexport interface ProfileContext {\n /** The user's global user_context paragraph (profile-replacing identity text). */\n userContext?: string;\n gaps: string[];\n /** Existing premise texts the user has already stated (e.g. \"I live in Berlin\"). */\n existingPremises?: string[];\n}\n\n/** Shared context fields for negotiation-mode questions. */\ninterface NegotiationContextBase {\n negotiationId: string;\n counterpartyHint: string;\n indexContext: string;\n /** The user's global user_context paragraph (profile-replacing identity text). */\n userContext?: string;\n}\n\n/** Post-stall negotiation context. Preserves the existing source shape. */\nexport interface PostStallNegotiationContext extends NegotiationContextBase {\n purpose?: undefined;\n outcomeReason: \"turn_cap\" | \"timeout\" | \"stalled\";\n keyTake: string;\n}\n\n/** Pre-accept uptake context targeting a counterparty's preparatory conditions. */\nexport interface UptakeNegotiationContext extends NegotiationContextBase {\n purpose: \"uptake\";\n /** Plain-language activity or commitment whose feasibility needs clarification. */\n proposedActivity: string;\n /** Public evidence already available about capability, resources, or authority. */\n preparatoryEvidence?: string;\n}\n\n/** Negotiation context discriminated by internal question purpose. */\nexport type NegotiationContext = PostStallNegotiationContext | UptakeNegotiationContext;\n\n/**\n * Negotiation-inflight context — a negotiator mid-negotiation wants to ask its\n * OWN client a question before continuing (the `ask_user` action, P3.2). The\n * negotiator states the disclosure subject and optionally drafts the question;\n * the QuestionerAgent refines it into polished disclosure-gating questions.\n * Distinct from {@link NegotiationContext}, which covers post-stall questions.\n */\nexport interface NegotiationInflightContext {\n negotiationId: string;\n /** Anonymized counterparty description (attributes, never identity). */\n counterpartyHint: string;\n /** What the negotiator wants permission to share or needs to know (e.g. \"budget range\", \"availability in Q3\"). */\n disclosureSubject: string;\n /** Draft question authored by the negotiator. The agent refines it. */\n draftQuestion?: string;\n /** Community / index context the negotiation runs in. */\n indexContext: string;\n /** The user's global user_context paragraph (profile-replacing identity text). */\n userContext?: string;\n}\n\n/**\n * Chat context — data for orchestrator-initiated mid-conversation questions\n * (the `ask_user_question` tool). The orchestrator states what it needs to\n * learn; the QuestionerAgent turns that into polished structured questions,\n * grounded in the recent conversation and the user's identity context.\n */\nexport interface ChatContext {\n /** What the orchestrator needs to learn and why (authored by the chat model). */\n purpose: string;\n /** Draft questions proposed by the orchestrator. The agent refines these. */\n draftQuestions?: Array<{\n prompt: string;\n options?: string[];\n multiSelect?: boolean;\n }>;\n /** Recent conversation excerpt for grounding (most recent messages last). */\n conversationExcerpt?: string;\n /** The user's global user_context paragraph (profile-replacing identity text). */\n userContext?: string;\n}\n\n/**\n * Pool-discovery context — mined discriminators from a discovery-run pool\n * (IND-418). No generator LLM runs for this mode: the QuestionerQueue\n * synthesizes the question deterministically from the top discriminator and\n * stashes the rest as interview-mode alternates.\n */\nexport interface PoolDiscoveryContext {\n intentId: string;\n /** Truncated intent payload (+ summary) display snippet. */\n intentText: string;\n /** Stable hash of the full normalized payload + summary used for freshness. */\n intentFingerprint?: string;\n poolSize: number;\n /** Exact bounded candidate opportunity IDs supplied to synthesis. */\n opportunityIds: string[];\n /** Discovery run that produced the pool. */\n runId?: string;\n /** Eligible discriminators, VoI-descending (asked + chain alternates). */\n discriminators: QuestionPoolDiscriminator[];\n /** ISO-8601 timestamp of the mining pass. */\n minedAt: string;\n}\n\n/** Discriminated union: mode selects the context shape. */\nexport type QuestionerContext =\n | DiscoveryContext\n | IntentContext\n | ProfileContext\n | NegotiationContext\n | NegotiationInflightContext\n | ChatContext\n | PoolDiscoveryContext;\n\n/**\n * Payload shape accepted by the questionerEnqueue callback. Covers all\n * question modes — the composition root bridges this to the concrete\n * QuestionerQueue.\n */\nexport type QuestionerEnqueuePayload = QuestionerInput;\n\n/** Callback signature for async question generation enqueue. */\nexport type QuestionerEnqueueFn = (input: QuestionerEnqueuePayload) => Promise<void>;\n\n/** Top-level input envelope for QuestionerAgent.invoke(). */\ninterface QuestionerInputBase {\n /** Selects the preset (system prompt + builder). */\n mode: QuestionMode;\n /** User the questions are generated for. */\n userId: string;\n /** Entity type that triggered this (e.g. \"opportunity\", \"intent\", \"profile\"). */\n sourceType: string;\n /** ID of the triggering entity. */\n sourceId: string;\n /** Scoped question context. Network scopes persist as QuestionActor.networkId. */\n scopeType?: ToolScopeType;\n /** Scoped question id. When scopeType is `network`, this is the actor networkId. */\n scopeId?: string;\n /**\n * Intent that triggered the run that generated these questions. Persisted as\n * `detection.triggeredBy` so intent-scoped surfaces (e.g. the intent page)\n * can find them. Independent of `scopeType`/`scopeId`, which may carry a\n * network scope at the same time.\n */\n triggeredByIntentId?: string;\n /** Conversation ID — set when the question originates from a chat session. Persisted on the question row for frontend filtering. */\n conversationId?: string;\n /** Assistant message ID — set when we know which message triggered the question. Stored in detection.messageId for inline anchoring. */\n messageId?: string;\n}\n\n/** Existing question inputs, including post-stall negotiation source compatibility. */\ninterface StandardQuestionerInput extends QuestionerInputBase {\n purpose?: undefined;\n /** Mode-specific context. Must align with the selected mode. */\n context: Exclude<QuestionerContext, UptakeNegotiationContext>;\n}\n\n/** Negotiation-mode uptake generation input. */\nexport interface UptakeQuestionerInput extends QuestionerInputBase {\n mode: \"negotiation\";\n purpose: \"uptake\";\n context: UptakeNegotiationContext;\n}\n\n/** Top-level input discriminated by the internal purpose. */\nexport type QuestionerInput = StandardQuestionerInput | UptakeQuestionerInput;\n"]}
1
+ {"version":3,"file":"questioner.types.js","sourceRoot":"/","sources":["questioner/questioner.types.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * QuestionerAgent input types. The `QuestionerInput` envelope carries a `mode`\n * field that selects a preset, plus a polymorphic `context` that varies per mode.\n *\n * Slice 1 defines all four context shapes but only `DiscoveryContext` has a\n * working preset implementation. The others are type stubs for future slices.\n */\nimport type { DiscoveryQuestionInput } from \"../shared/schemas/discovery-question.schema.js\";\nimport type { ToolScopeType } from \"../shared/agent/tool.scope.js\";\nimport type { QuestionMode, QuestionPoolDiscriminator } from \"../shared/schemas/question.schema.js\";\n\n// ─── Per-mode context types ─────────────────────────────────────────────────\n\n/**\n * Discovery context — wraps the existing DiscoveryQuestionInput wholesale.\n * The discovery preset's buildPrompt delegates to `questioner.discovery.prompt.ts`.\n */\nexport type DiscoveryContext = DiscoveryQuestionInput;\n\n/** Intent context — data needed to generate questions about an intent. */\nexport interface IntentContext {\n intentId: string;\n payload: string;\n summary?: string;\n /** The user's global user_context paragraph (profile-replacing identity text). */\n userContext?: string;\n}\n\n/** Profile context — data needed to generate questions to fill profile gaps. */\nexport interface ProfileContext {\n /** The user's global user_context paragraph (profile-replacing identity text). */\n userContext?: string;\n gaps: string[];\n /** Existing premise texts the user has already stated (e.g. \"I live in Berlin\"). */\n existingPremises?: string[];\n}\n\n/** Shared context fields for negotiation-mode questions. */\ninterface NegotiationContextBase {\n negotiationId: string;\n counterpartyHint: string;\n indexContext: string;\n /** The user's global user_context paragraph (profile-replacing identity text). */\n userContext?: string;\n}\n\n/** Post-stall negotiation context. Preserves the existing source shape. */\nexport interface PostStallNegotiationContext extends NegotiationContextBase {\n purpose?: undefined;\n outcomeReason: \"turn_cap\" | \"timeout\" | \"stalled\";\n keyTake: string;\n}\n\n/** Pre-accept uptake context targeting a counterparty's preparatory conditions. */\nexport interface UptakeNegotiationContext extends NegotiationContextBase {\n purpose: \"uptake\";\n /** Plain-language activity or commitment whose feasibility needs clarification. */\n proposedActivity: string;\n /** Public evidence already available about capability, resources, or authority. */\n preparatoryEvidence?: string;\n}\n\n/** Negotiation context discriminated by internal question purpose. */\nexport type NegotiationContext = PostStallNegotiationContext | UptakeNegotiationContext;\n\n/**\n * Negotiation-inflight context — a negotiator mid-negotiation wants to ask its\n * OWN client a question before continuing (the `ask_user` action, P3.2). The\n * negotiator states the disclosure subject and optionally drafts the question;\n * the QuestionerAgent refines it into polished disclosure-gating questions.\n * Distinct from {@link NegotiationContext}, which covers post-stall questions.\n */\nexport interface NegotiationInflightContext {\n negotiationId: string;\n /** Anonymized counterparty description (attributes, never identity). */\n counterpartyHint: string;\n /** What the negotiator wants permission to share or needs to know (e.g. \"budget range\", \"availability in Q3\"). */\n disclosureSubject: string;\n /** Draft question authored by the negotiator. The agent refines it. */\n draftQuestion?: string;\n /** Community / index context the negotiation runs in. */\n indexContext: string;\n /** The user's global user_context paragraph (profile-replacing identity text). */\n userContext?: string;\n}\n\n/**\n * Chat context — data for orchestrator-initiated mid-conversation questions\n * (the `ask_user_question` tool). The orchestrator states what it needs to\n * learn; the QuestionerAgent turns that into polished structured questions,\n * grounded in the recent conversation and the user's identity context.\n */\nexport interface ChatContext {\n /** What the orchestrator needs to learn and why (authored by the chat model). */\n purpose: string;\n /** Draft questions proposed by the orchestrator. The agent refines these. */\n draftQuestions?: Array<{\n prompt: string;\n options?: string[];\n multiSelect?: boolean;\n }>;\n /** Recent conversation excerpt for grounding (most recent messages last). */\n conversationExcerpt?: string;\n /** The user's global user_context paragraph (profile-replacing identity text). */\n userContext?: string;\n}\n\n/**\n * Pool-discovery context — mined discriminators from a discovery-run pool\n * (IND-418). No generator LLM runs for this mode: the QuestionerQueue\n * synthesizes the question deterministically from the top discriminator and\n * stashes the rest as interview-mode alternates.\n */\nexport interface PoolDiscoveryContext {\n intentId: string;\n /** Truncated intent payload (+ summary) display snippet. */\n intentText: string;\n /** Stable hash of the full normalized payload + summary used for freshness. */\n intentFingerprint?: string;\n poolSize: number;\n /** Exact bounded candidate opportunity IDs supplied to synthesis. */\n opportunityIds: string[];\n /** Discovery run that produced the pool. */\n runId?: string;\n /** Eligible discriminators, VoI-descending (asked + chain alternates). */\n discriminators: QuestionPoolDiscriminator[];\n /** ISO-8601 timestamp of the mining pass. */\n minedAt: string;\n}\n\n/** Discriminated union: mode selects the context shape. */\nexport type QuestionerContext =\n | DiscoveryContext\n | IntentContext\n | ProfileContext\n | NegotiationContext\n | NegotiationInflightContext\n | ChatContext\n | PoolDiscoveryContext;\n\n/**\n * Payload shape accepted by the questionerEnqueue callback. Covers all\n * question modes — the composition root bridges this to the concrete\n * QuestionerQueue.\n */\nexport type QuestionerEnqueuePayload = QuestionerInput;\n\n/** Callback signature for async question generation enqueue. */\nexport type QuestionerEnqueueFn = (input: QuestionerEnqueuePayload) => Promise<void>;\n\n/** Top-level input envelope for QuestionerAgent.invoke(). */\ninterface QuestionerInputBase {\n /** Selects the preset (system prompt + builder). */\n mode: QuestionMode;\n /** User the questions are generated for. */\n userId: string;\n /** Entity type that triggered this (e.g. \"opportunity\", \"intent\", \"profile\"). */\n sourceType: string;\n /** ID of the triggering entity. */\n sourceId: string;\n /** Scoped question context. Network scopes persist as QuestionActor.networkId. */\n scopeType?: ToolScopeType;\n /** Scoped question id. When scopeType is `network`, this is the actor networkId. */\n scopeId?: string;\n /**\n * Intent that triggered the run that generated these questions. Persisted as\n * `detection.triggeredBy` so intent-scoped surfaces (e.g. the intent page)\n * can find them. Independent of `scopeType`/`scopeId`, which may carry a\n * network scope at the same time.\n */\n triggeredByIntentId?: string;\n /** Conversation ID — set when the question originates from a chat session. Persisted on the question row for frontend filtering. */\n conversationId?: string;\n /** Assistant message ID — set when we know which message triggered the question. Stored in detection.messageId for inline anchoring. */\n messageId?: string;\n}\n\n/** Existing question inputs, including post-stall negotiation source compatibility. */\ninterface StandardQuestionerInput extends QuestionerInputBase {\n purpose?: undefined;\n /** Mode-specific context. Must align with the selected mode. */\n context: Exclude<QuestionerContext, UptakeNegotiationContext>;\n}\n\n/** Negotiation-mode uptake generation input. */\nexport interface UptakeQuestionerInput extends QuestionerInputBase {\n mode: \"negotiation\";\n purpose: \"uptake\";\n context: UptakeNegotiationContext;\n}\n\n/** Top-level input discriminated by the internal purpose. */\nexport type QuestionerInput = StandardQuestionerInput | UptakeQuestionerInput;\n"]}
@@ -103,11 +103,6 @@ declare function getModelConfig(config?: ModelConfig): {
103
103
  readonly temperature: 0.2;
104
104
  readonly maxTokens: 512;
105
105
  };
106
- readonly discoveryQuestionGenerator: {
107
- readonly model: "google/gemini-2.5-flash";
108
- readonly temperature: 0.5;
109
- readonly maxTokens: 1024;
110
- };
111
106
  readonly questioner: {
112
107
  readonly model: "google/gemini-2.5-flash";
113
108
  readonly temperature: 0.5;
@@ -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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6BAsCmD,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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6BAqCmD,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"}
@@ -20,7 +20,6 @@ function getModelConfig(config) {
20
20
  chatTitleGenerator: { model: "google/gemini-2.5-flash", temperature: 0.3, maxTokens: 32 },
21
21
  negotiationInsights: { model: "google/gemini-2.5-flash", temperature: 0.4, maxTokens: 512 },
22
22
  chatContextSummarizer: { model: "google/gemini-2.5-flash", temperature: 0.2, maxTokens: 512 },
23
- discoveryQuestionGenerator: { model: "google/gemini-2.5-flash", temperature: 0.5, maxTokens: 1024 },
24
23
  questioner: { model: "google/gemini-2.5-flash", temperature: 0.5, maxTokens: 1024 },
25
24
  negotiationSummarizer: { model: "google/gemini-2.5-flash", temperature: 0.2, maxTokens: 256 },
26
25
  poolDiscriminatorMiner: { model: "google/gemini-2.5-flash", temperature: 0.2, maxTokens: 4096 },
@@ -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 hydeValidator: { model: \"google/gemini-2.5-flash\", temperature: 0.0, maxTokens: 2048 },\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 poolDiscriminatorMiner: { model: \"google/gemini-2.5-flash\", temperature: 0.2, maxTokens: 4096 },\n poolDiscriminatorAssigner: { model: \"google/gemini-2.5-flash\", temperature: 0.1, maxTokens: 16384 },\n negotiationEvidenceMiner: { model: \"google/gemini-2.5-flash\", temperature: 0.2, maxTokens: 4096 },\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 hydeValidator: { model: \"google/gemini-2.5-flash\", temperature: 0.0, maxTokens: 2048 },\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 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 poolDiscriminatorMiner: { model: \"google/gemini-2.5-flash\", temperature: 0.2, maxTokens: 4096 },\n poolDiscriminatorAssigner: { model: \"google/gemini-2.5-flash\", temperature: 0.1, maxTokens: 16384 },\n negotiationEvidenceMiner: { model: \"google/gemini-2.5-flash\", temperature: 0.2, maxTokens: 4096 },\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"]}
@@ -6,7 +6,7 @@
6
6
  * Pattern mirrors ChatSummaryReader: protocol defines the read shape, the
7
7
  * backend (or any consumer) provides the implementation.
8
8
  */
9
- import type { DiscoveryNegotiation } from "../../opportunity/question.prompt.js";
9
+ import type { DiscoveryNegotiation } from "../schemas/discovery-question.schema.js";
10
10
  import type { DiscoveryNegotiationDigest } from "../schemas/negotiation-digest.schema.js";
11
11
  export interface NegotiationSummaryReader {
12
12
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"negotiation-summary.interface.d.ts","sourceRoot":"/","sources":["shared/interfaces/negotiation-summary.interface.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sCAAsC,CAAC;AACjF,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,yCAAyC,CAAC;AAE1F,MAAM,WAAW,wBAAwB;IACvC;;;;;;;;;OASG;IACH,SAAS,CACP,WAAW,EAAE,oBAAoB,EACjC,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GACjC,OAAO,CAAC,0BAA0B,GAAG,IAAI,CAAC,CAAC;CAC/C"}
1
+ {"version":3,"file":"negotiation-summary.interface.d.ts","sourceRoot":"/","sources":["shared/interfaces/negotiation-summary.interface.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,yCAAyC,CAAC;AACpF,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,yCAAyC,CAAC;AAE1F,MAAM,WAAW,wBAAwB;IACvC;;;;;;;;;OASG;IACH,SAAS,CACP,WAAW,EAAE,oBAAoB,EACjC,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GACjC,OAAO,CAAC,0BAA0B,GAAG,IAAI,CAAC,CAAC;CAC/C"}
@@ -1 +1 @@
1
- {"version":3,"file":"negotiation-summary.interface.js","sourceRoot":"/","sources":["shared/interfaces/negotiation-summary.interface.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Protocol-side contract for summarizing discovery negotiations into compact\n * digests. The protocol layer only sees this shape; the LLM implementation\n * (NegotiationSummarizer) is injected through dependency wiring.\n *\n * Pattern mirrors ChatSummaryReader: protocol defines the read shape, the\n * backend (or any consumer) provides the implementation.\n */\nimport type { DiscoveryNegotiation } from \"../../opportunity/question.prompt.js\";\nimport type { DiscoveryNegotiationDigest } from \"../schemas/negotiation-digest.schema.js\";\n\nexport interface NegotiationSummaryReader {\n /**\n * Summarize a single negotiation into a compact digest.\n *\n * @param negotiation The raw negotiation to compress.\n * @param options.signal Optional AbortSignal. When aborted (deadline reached or\n * upstream cancel) the in-flight LLM call is cancelled and `null` is returned —\n * callers fall back to a deterministic digest so question generation can\n * still proceed.\n * @returns the digest, or `null` when summarization fails or is aborted.\n */\n summarize(\n negotiation: DiscoveryNegotiation,\n options?: { signal?: AbortSignal },\n ): Promise<DiscoveryNegotiationDigest | null>;\n}\n"]}
1
+ {"version":3,"file":"negotiation-summary.interface.js","sourceRoot":"/","sources":["shared/interfaces/negotiation-summary.interface.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Protocol-side contract for summarizing discovery negotiations into compact\n * digests. The protocol layer only sees this shape; the LLM implementation\n * (NegotiationSummarizer) is injected through dependency wiring.\n *\n * Pattern mirrors ChatSummaryReader: protocol defines the read shape, the\n * backend (or any consumer) provides the implementation.\n */\nimport type { DiscoveryNegotiation } from \"../schemas/discovery-question.schema.js\";\nimport type { DiscoveryNegotiationDigest } from \"../schemas/negotiation-digest.schema.js\";\n\nexport interface NegotiationSummaryReader {\n /**\n * Summarize a single negotiation into a compact digest.\n *\n * @param negotiation The raw negotiation to compress.\n * @param options.signal Optional AbortSignal. When aborted (deadline reached or\n * upstream cancel) the in-flight LLM call is cancelled and `null` is returned —\n * callers fall back to a deterministic digest so question generation can\n * still proceed.\n * @returns the digest, or `null` when summarization fails or is aborted.\n */\n summarize(\n negotiation: DiscoveryNegotiation,\n options?: { signal?: AbortSignal },\n ): Promise<DiscoveryNegotiationDigest | null>;\n}\n"]}
@@ -1,11 +1,13 @@
1
1
  /**
2
- * @deprecated Use QuestionerAgent instead. Will be removed in a future version.
2
+ * @deprecated Inline question generation is superseded by the async
3
+ * QuestionerQueue path (`questionerEnqueue`). Will be removed once the inline
4
+ * fallback in `opportunity.discover.ts` is retired.
3
5
  *
4
6
  * Protocol-level read contract for decision-question generation. Implementations
5
- * live in the backend (see `QuestionGeneratorService`) and are injected into the
6
- * protocol via `ProtocolDeps`/`ToolContext`. The protocol module never constructs
7
- * its own LLM-bound `QuestionGenerator` callers inject one (or `undefined` to
8
- * opt out).
7
+ * live in the backend (see `QuestionGeneratorService`, which delegates to the
8
+ * QuestionerAgent's `discovery` mode) and are injected into the protocol via
9
+ * `ProtocolDeps`/`ToolContext`. The protocol module never constructs its own
10
+ * LLM-bound generator — callers inject one (or `undefined` to opt out).
9
11
  */
10
12
  import type { DiscoveryQuestionInput } from "../schemas/discovery-question.schema.js";
11
13
  import type { QuestionGenerationResult } from "../schemas/question.schema.js";
@@ -1 +1 @@
1
- {"version":3,"file":"question-generator.interface.d.ts","sourceRoot":"/","sources":["shared/interfaces/question-generator.interface.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,yCAAyC,CAAC;AACtF,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AAE9E,MAAM,WAAW,uBAAuB;IACtC;;;;;;;;;;OAUG;IACH,QAAQ,CACN,KAAK,EAAE,sBAAsB,EAC7B,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GACjC,OAAO,CAAC,wBAAwB,GAAG,IAAI,CAAC,CAAC;CAC7C"}
1
+ {"version":3,"file":"question-generator.interface.d.ts","sourceRoot":"/","sources":["shared/interfaces/question-generator.interface.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,yCAAyC,CAAC;AACtF,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AAE9E,MAAM,WAAW,uBAAuB;IACtC;;;;;;;;;;OAUG;IACH,QAAQ,CACN,KAAK,EAAE,sBAAsB,EAC7B,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GACjC,OAAO,CAAC,wBAAwB,GAAG,IAAI,CAAC,CAAC;CAC7C"}
@@ -1 +1 @@
1
- {"version":3,"file":"question-generator.interface.js","sourceRoot":"/","sources":["shared/interfaces/question-generator.interface.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * @deprecated Use QuestionerAgent instead. Will be removed in a future version.\n *\n * Protocol-level read contract for decision-question generation. Implementations\n * live in the backend (see `QuestionGeneratorService`) and are injected into the\n * protocol via `ProtocolDeps`/`ToolContext`. The protocol module never constructs\n * its own LLM-bound `QuestionGenerator` — callers inject one (or `undefined` to\n * opt out).\n */\nimport type { DiscoveryQuestionInput } from \"../schemas/discovery-question.schema.js\";\nimport type { QuestionGenerationResult } from \"../schemas/question.schema.js\";\n\nexport interface QuestionGeneratorReader {\n /**\n * Run the question generator over a single discovery turn.\n *\n * @param input Discovery turn payload (query + negotiation digests + chat context).\n * @param options.signal Optional AbortSignal. When aborted (deadline reached or\n * upstream cancel) the in-flight LLM call is cancelled and `null` is returned —\n * discovery still emits its response, just without questions.\n * @returns The structured result, or `null` when generation failed,\n * guardrails dropped all candidates, the underlying LLM threw, or\n * the call was aborted.\n */\n generate(\n input: DiscoveryQuestionInput,\n options?: { signal?: AbortSignal },\n ): Promise<QuestionGenerationResult | null>;\n}\n"]}
1
+ {"version":3,"file":"question-generator.interface.js","sourceRoot":"/","sources":["shared/interfaces/question-generator.interface.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * @deprecated Inline question generation is superseded by the async\n * QuestionerQueue path (`questionerEnqueue`). Will be removed once the inline\n * fallback in `opportunity.discover.ts` is retired.\n *\n * Protocol-level read contract for decision-question generation. Implementations\n * live in the backend (see `QuestionGeneratorService`, which delegates to the\n * QuestionerAgent's `discovery` mode) and are injected into the protocol via\n * `ProtocolDeps`/`ToolContext`. The protocol module never constructs its own\n * LLM-bound generator — callers inject one (or `undefined` to opt out).\n */\nimport type { DiscoveryQuestionInput } from \"../schemas/discovery-question.schema.js\";\nimport type { QuestionGenerationResult } from \"../schemas/question.schema.js\";\n\nexport interface QuestionGeneratorReader {\n /**\n * Run the question generator over a single discovery turn.\n *\n * @param input Discovery turn payload (query + negotiation digests + chat context).\n * @param options.signal Optional AbortSignal. When aborted (deadline reached or\n * upstream cancel) the in-flight LLM call is cancelled and `null` is returned —\n * discovery still emits its response, just without questions.\n * @returns The structured result, or `null` when generation failed,\n * guardrails dropped all candidates, the underlying LLM threw, or\n * the call was aborted.\n */\n generate(\n input: DiscoveryQuestionInput,\n options?: { signal?: AbortSignal },\n ): Promise<QuestionGenerationResult | null>;\n}\n"]}
@@ -146,6 +146,7 @@ export declare const DiscoveryNegotiationSchema: z.ZodObject<{
146
146
  };
147
147
  counterpartyHint: string;
148
148
  indexContext: string;
149
+ counterpartyId: string;
149
150
  turns: {
150
151
  reasoning: string;
151
152
  action: "propose" | "accept" | "reject" | "counter" | "question" | "outreach" | "withdraw" | "decline" | "ask_user";
@@ -154,7 +155,6 @@ export declare const DiscoveryNegotiationSchema: z.ZodObject<{
154
155
  otherUser: "agent" | "patient" | "peer";
155
156
  };
156
157
  }[];
157
- counterpartyId: string;
158
158
  seedAssessmentScore?: number | undefined;
159
159
  }, {
160
160
  outcome: {
@@ -168,6 +168,7 @@ export declare const DiscoveryNegotiationSchema: z.ZodObject<{
168
168
  };
169
169
  counterpartyHint: string;
170
170
  indexContext: string;
171
+ counterpartyId: string;
171
172
  turns: {
172
173
  reasoning: string;
173
174
  action: "propose" | "accept" | "reject" | "counter" | "question" | "outreach" | "withdraw" | "decline" | "ask_user";
@@ -176,7 +177,6 @@ export declare const DiscoveryNegotiationSchema: z.ZodObject<{
176
177
  otherUser: "agent" | "patient" | "peer";
177
178
  };
178
179
  }[];
179
- counterpartyId: string;
180
180
  seedAssessmentScore?: number | undefined;
181
181
  }>;
182
182
  export type DiscoveryNegotiation = z.infer<typeof DiscoveryNegotiationSchema>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@indexnetwork/protocol",
3
- "version": "5.1.0-rc.367.1",
3
+ "version": "5.2.1-rc.369.1",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -1,22 +0,0 @@
1
- import { type QuestionGenerationResult } from "../shared/schemas/question.schema.js";
2
- import { type DiscoveryQuestionInput } from "./question.prompt.js";
3
- /** @deprecated Use QuestionerAgent instead. Will be removed in a future version. */
4
- export declare class QuestionGenerator {
5
- private model;
6
- constructor();
7
- /**
8
- * Generate up to 3 decision questions from the given discovery turn.
9
- *
10
- * @param input Discovery turn payload.
11
- * @param options.signal Optional AbortSignal. Passed to LangChain so an
12
- * aborted call cancels the underlying HTTP fetch instead of leaving a
13
- * floating promise burning OpenRouter capacity.
14
- * @returns A result with parallel questions[] and strategies[] arrays,
15
- * or null when the LLM fails, the output is malformed, the call was
16
- * aborted, or the guardrails leave zero questions standing.
17
- */
18
- generate(input: DiscoveryQuestionInput, options?: {
19
- signal?: AbortSignal;
20
- }): Promise<QuestionGenerationResult | null>;
21
- }
22
- //# sourceMappingURL=question.generator.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"question.generator.d.ts","sourceRoot":"/","sources":["opportunity/question.generator.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAkD,KAAK,wBAAwB,EAAoD,MAAM,sCAAsC,CAAC;AAMvL,OAAO,EAAsC,KAAK,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAOvG,oFAAoF;AACpF,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,KAAK,CAA2C;;IAQxD;;;;;;;;;;OAUG;IAEG,QAAQ,CACZ,KAAK,EAAE,sBAAsB,EAC7B,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GACjC,OAAO,CAAC,wBAAwB,GAAG,IAAI,CAAC;CA6C5C"}