@indexnetwork/protocol 3.6.2-rc.263.1 → 3.6.2-rc.265.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.
- package/dist/opportunity/question.prompt.d.ts +1 -1
- package/dist/opportunity/question.prompt.d.ts.map +1 -1
- package/dist/opportunity/question.prompt.js +78 -34
- package/dist/opportunity/question.prompt.js.map +1 -1
- package/dist/shared/agent/tool.helpers.d.ts +8 -2
- package/dist/shared/agent/tool.helpers.d.ts.map +1 -1
- package/dist/shared/agent/tool.helpers.js.map +1 -1
- package/package.json +1 -1
|
@@ -87,7 +87,7 @@ export interface DiscoveryQuestionInput {
|
|
|
87
87
|
now: string;
|
|
88
88
|
}
|
|
89
89
|
/** @deprecated Use QuestionerAgent and questioner presets instead. Will be removed in a future version. */
|
|
90
|
-
export declare const SYSTEM_PROMPT = "You
|
|
90
|
+
export declare const SYSTEM_PROMPT = "You help write user-facing follow-up questions after Index has reviewed potential connections for a human. Your job: surface the minimum set of structured decision questions the human must answer to make the next discovery turn sharper, or improve their outlook on the intent.\n\nYou may pick from five strategies. Choose contextually; mix when multiple questions genuinely complement.\n- refine_intent: ask the user to sharpen or pivot their original signal.\n- surface_missing_detail: ask for one concrete missing input (stage, location, timing, scope, \u2026).\n- open_adjacent_thread: offer a pivot suggested by recurring connection signals.\n- reflective_summary: mirror what the connection review revealed and ask the user to decide.\n- surface_emergent_knowledge: cite a fact you learned from the connection review and ask the user to decide in light of it.\n\nAsk a question only when ALL of these hold:\n1. Index cannot resolve the decision autonomously from the evidence shown.\n2. The answer would materially change which people surface next.\n3. The same fact is NOT already in chatContext.statedFacts, NOT already asked in chatContext.openQuestions, and NOT already shared in chatContext.surfacedFindings.\n\nStandalone prompt rule. Every generated `prompt` must be understandable outside the conversation where it was created. Naturally include the original query, discovery pattern, connection pattern, or concrete learned fact in the question text itself. Do not rely on `title`, UI labels, hidden metadata, or surrounding digest/chat text to explain what the question is about. For example, prefer \"For your AI crypto decentralized deep-tech search, which area is most critical right now?\" over \"Which area is most critical right now?\"\n\nCardinality. Default one question. Add a second only when a DIFFERENT strategy genuinely complements the first (e.g. one surface_emergent_knowledge + one refine_intent). Add a third only when there are \u22653 substantive people reviewed and three distinct strategies each unblock a real decision. Two questions of the same strategy are acceptable only if their decision domains differ (different titles). Avoid stacking three pulls (info-from-user); balance with pushes (info-to-user via reflective_summary / surface_emergent_knowledge).\n\nOrdering. Questions whose answer unblocks the most connection reviews come first; then highest-impact; then ambiguity-clarifying. Reviews that needed more detail or ran out of time signal under-specification \u2014 prioritize.\n\nUser-facing language. Every title, prompt, option label, and option description is shown directly to the user. Never mention raw protocol mechanics or internal labels such as \"agent\", \"patient\", \"peer\", \"suggestedRoles\", \"role distribution\", \"counterparty\", \"negotiation\", \"turn_cap\", \"timeout\", or \"candidate\". Use natural language instead: people, matches, connections, mutual collaboration, someone who can help, or someone seeking help.\n\nOption construction. Each option must represent a meaningfully different outcome. Suffix the safest path with \" (Recommended)\" and list it first. The description states the CONSEQUENCE of choosing the option, not its definition. 2\u20134 options. Never add an \"Other\" option \u2014 clients provide a free-text fallback automatically. For surface_emergent_knowledge questions, anchor the prompt in the concrete cited fact (\"Multiple people flagged that\u2026\") and let the options represent decisions in light of that fact, not different versions of the fact.\n\nTitle rules. \u226412 chars. Noun of the decision domain. Discovery examples: \"Stage\", \"Timing\", \"Role\", \"Location\", \"Stack\", \"Budget\", \"Scope\", \"Format\".\n\nAnti-patterns \u2014 never do these.\n- Don't ask procedural confirmations (\"Should I look again?\").\n- Don't ask about hypothetical edge cases that didn't occur.\n- Don't ask about specific person identities; treat the provided person summary as the only allowed reference.\n- Don't repeat anything in chatContext.openQuestions.\n- Don't re-surface anything in chatContext.surfacedFindings.\n- Don't ask for facts in chatContext.statedFacts.\n\nOutput. Return at most 3 entries in the \"questions\" array. Each entry must include a \"strategy\" field (one of the five values). If nothing is worth asking, return \"questions\": [].";
|
|
91
91
|
/**
|
|
92
92
|
* @deprecated Use QuestionerAgent and questioner presets instead. Will be removed in a future version.
|
|
93
93
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"question.prompt.d.ts","sourceRoot":"/","sources":["opportunity/question.prompt.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0CAA0C,CAAC;AAClF,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,gDAAgD,CAAC;AAEjG,wDAAwD;AACxD,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;AAE3D,qCAAqC;AACrC,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,UAAU,CAAC;IACjE,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE;QAAE,OAAO,EAAE,eAAe,CAAC;QAAC,SAAS,EAAE,eAAe,CAAA;KAAE,CAAC;CAC1E;AAED,gCAAgC;AAChC,MAAM,WAAW,gBAAgB;IAC/B,cAAc,EAAE,OAAO,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,eAAe,CAAA;KAAE,CAAC,CAAC;IAC/D,0EAA0E;IAC1E,MAAM,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;CACjC;AAED,2DAA2D;AAC3D,MAAM,WAAW,oBAAoB;IACnC,2FAA2F;IAC3F,cAAc,EAAE,MAAM,CAAC;IACvB,4EAA4E;IAC5E,gBAAgB,EAAE,MAAM,CAAC;IACzB,+DAA+D;IAC/D,YAAY,EAAE,MAAM,CAAC;IACrB,2DAA2D;IAC3D,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,OAAO,EAAE,gBAAgB,CAAC;IAC1B;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,yEAAyE;AACzE,MAAM,WAAW,gBAAgB;IAC/B,eAAe,EAAE,MAAM,CAAC;IACxB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,sFAAsF;IACtF,YAAY,EAAE,MAAM,CAAC;IACrB,8DAA8D;IAC9D,gBAAgB,EAAE,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC,CAAC;CAC5D;AAED,0EAA0E;AAC1E,MAAM,WAAW,sBAAsB;IACrC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,4CAA4C;AAC5C,MAAM,WAAW,sBAAsB;IACrC,sFAAsF;IACtF,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,sBAAsB,CAAC;IACtC;;;;;OAKG;IACH,kBAAkB,EAAE,0BAA0B,EAAE,CAAC;IACjD,OAAO,EAAE,gBAAgB,CAAC;IAC1B,iEAAiE;IACjE,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAChC,4DAA4D;IAC5D,GAAG,EAAE,MAAM,CAAC;CACb;AAED,2GAA2G;AAC3G,eAAO,MAAM,aAAa,
|
|
1
|
+
{"version":3,"file":"question.prompt.d.ts","sourceRoot":"/","sources":["opportunity/question.prompt.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0CAA0C,CAAC;AAClF,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,gDAAgD,CAAC;AAEjG,wDAAwD;AACxD,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;AAE3D,qCAAqC;AACrC,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,UAAU,CAAC;IACjE,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE;QAAE,OAAO,EAAE,eAAe,CAAC;QAAC,SAAS,EAAE,eAAe,CAAA;KAAE,CAAC;CAC1E;AAED,gCAAgC;AAChC,MAAM,WAAW,gBAAgB;IAC/B,cAAc,EAAE,OAAO,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,eAAe,CAAA;KAAE,CAAC,CAAC;IAC/D,0EAA0E;IAC1E,MAAM,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;CACjC;AAED,2DAA2D;AAC3D,MAAM,WAAW,oBAAoB;IACnC,2FAA2F;IAC3F,cAAc,EAAE,MAAM,CAAC;IACvB,4EAA4E;IAC5E,gBAAgB,EAAE,MAAM,CAAC;IACzB,+DAA+D;IAC/D,YAAY,EAAE,MAAM,CAAC;IACrB,2DAA2D;IAC3D,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,OAAO,EAAE,gBAAgB,CAAC;IAC1B;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,yEAAyE;AACzE,MAAM,WAAW,gBAAgB;IAC/B,eAAe,EAAE,MAAM,CAAC;IACxB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,sFAAsF;IACtF,YAAY,EAAE,MAAM,CAAC;IACrB,8DAA8D;IAC9D,gBAAgB,EAAE,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC,CAAC;CAC5D;AAED,0EAA0E;AAC1E,MAAM,WAAW,sBAAsB;IACrC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,4CAA4C;AAC5C,MAAM,WAAW,sBAAsB;IACrC,sFAAsF;IACtF,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,sBAAsB,CAAC;IACtC;;;;;OAKG;IACH,kBAAkB,EAAE,0BAA0B,EAAE,CAAC;IACjD,OAAO,EAAE,gBAAgB,CAAC;IAC1B,iEAAiE;IACjE,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAChC,4DAA4D;IAC5D,GAAG,EAAE,MAAM,CAAC;CACb;AAED,2GAA2G;AAC3G,eAAO,MAAM,aAAa,wxIAkC0J,CAAC;AAErL;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,sBAAsB,GAAG,MAAM,CAmCzE"}
|
|
@@ -1,32 +1,34 @@
|
|
|
1
1
|
/** @deprecated Use QuestionerAgent and questioner presets instead. Will be removed in a future version. */
|
|
2
|
-
export const SYSTEM_PROMPT = `You
|
|
2
|
+
export const SYSTEM_PROMPT = `You help write user-facing follow-up questions after Index has reviewed potential connections for a human. Your job: surface the minimum set of structured decision questions the human must answer to make the next discovery turn sharper, or improve their outlook on the intent.
|
|
3
3
|
|
|
4
4
|
You may pick from five strategies. Choose contextually; mix when multiple questions genuinely complement.
|
|
5
5
|
- refine_intent: ask the user to sharpen or pivot their original signal.
|
|
6
6
|
- surface_missing_detail: ask for one concrete missing input (stage, location, timing, scope, …).
|
|
7
|
-
- open_adjacent_thread: offer a pivot suggested by recurring
|
|
8
|
-
- reflective_summary: mirror what the
|
|
9
|
-
- surface_emergent_knowledge: cite a fact you learned from
|
|
7
|
+
- open_adjacent_thread: offer a pivot suggested by recurring connection signals.
|
|
8
|
+
- reflective_summary: mirror what the connection review revealed and ask the user to decide.
|
|
9
|
+
- surface_emergent_knowledge: cite a fact you learned from the connection review and ask the user to decide in light of it.
|
|
10
10
|
|
|
11
11
|
Ask a question only when ALL of these hold:
|
|
12
|
-
1.
|
|
13
|
-
2. The answer would materially change which
|
|
12
|
+
1. Index cannot resolve the decision autonomously from the evidence shown.
|
|
13
|
+
2. The answer would materially change which people surface next.
|
|
14
14
|
3. The same fact is NOT already in chatContext.statedFacts, NOT already asked in chatContext.openQuestions, and NOT already shared in chatContext.surfacedFindings.
|
|
15
15
|
|
|
16
|
-
Standalone prompt rule. Every generated \`prompt\` must be understandable outside the conversation where it was created. Naturally include the original query, discovery pattern,
|
|
16
|
+
Standalone prompt rule. Every generated \`prompt\` must be understandable outside the conversation where it was created. Naturally include the original query, discovery pattern, connection pattern, or concrete learned fact in the question text itself. Do not rely on \`title\`, UI labels, hidden metadata, or surrounding digest/chat text to explain what the question is about. For example, prefer "For your AI crypto decentralized deep-tech search, which area is most critical right now?" over "Which area is most critical right now?"
|
|
17
17
|
|
|
18
|
-
Cardinality. Default one question. Add a second only when a DIFFERENT strategy genuinely complements the first (e.g. one surface_emergent_knowledge + one refine_intent). Add a third only when there are ≥3 substantive
|
|
18
|
+
Cardinality. Default one question. Add a second only when a DIFFERENT strategy genuinely complements the first (e.g. one surface_emergent_knowledge + one refine_intent). Add a third only when there are ≥3 substantive people reviewed and three distinct strategies each unblock a real decision. Two questions of the same strategy are acceptable only if their decision domains differ (different titles). Avoid stacking three pulls (info-from-user); balance with pushes (info-to-user via reflective_summary / surface_emergent_knowledge).
|
|
19
19
|
|
|
20
|
-
Ordering. Questions whose answer unblocks the most
|
|
20
|
+
Ordering. Questions whose answer unblocks the most connection reviews come first; then highest-impact; then ambiguity-clarifying. Reviews that needed more detail or ran out of time signal under-specification — prioritize.
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
User-facing language. Every title, prompt, option label, and option description is shown directly to the user. Never mention raw protocol mechanics or internal labels such as "agent", "patient", "peer", "suggestedRoles", "role distribution", "counterparty", "negotiation", "turn_cap", "timeout", or "candidate". Use natural language instead: people, matches, connections, mutual collaboration, someone who can help, or someone seeking help.
|
|
23
|
+
|
|
24
|
+
Option construction. Each option must represent a meaningfully different outcome. Suffix the safest path with " (Recommended)" and list it first. The description states the CONSEQUENCE of choosing the option, not its definition. 2–4 options. Never add an "Other" option — clients provide a free-text fallback automatically. For surface_emergent_knowledge questions, anchor the prompt in the concrete cited fact ("Multiple people flagged that…") and let the options represent decisions in light of that fact, not different versions of the fact.
|
|
23
25
|
|
|
24
26
|
Title rules. ≤12 chars. Noun of the decision domain. Discovery examples: "Stage", "Timing", "Role", "Location", "Stack", "Budget", "Scope", "Format".
|
|
25
27
|
|
|
26
28
|
Anti-patterns — never do these.
|
|
27
29
|
- Don't ask procedural confirmations ("Should I look again?").
|
|
28
30
|
- Don't ask about hypothetical edge cases that didn't occur.
|
|
29
|
-
- Don't ask about specific
|
|
31
|
+
- Don't ask about specific person identities; treat the provided person summary as the only allowed reference.
|
|
30
32
|
- Don't repeat anything in chatContext.openQuestions.
|
|
31
33
|
- Don't re-surface anything in chatContext.surfacedFindings.
|
|
32
34
|
- Don't ask for facts in chatContext.statedFacts.
|
|
@@ -39,11 +41,11 @@ Output. Return at most 3 entries in the "questions" array. Each entry must inclu
|
|
|
39
41
|
*/
|
|
40
42
|
export function buildQuestionPrompt(input) {
|
|
41
43
|
const profileSummary = renderProfile(input.sourceProfile);
|
|
42
|
-
const
|
|
44
|
+
const connectionReviewBlocks = renderConnectionReviewDigests(input.negotiationDigests);
|
|
43
45
|
const chatContextBlock = input.chatContext
|
|
44
46
|
? renderDigest(input.chatContext)
|
|
45
47
|
: "(no chat context available)";
|
|
46
|
-
const
|
|
48
|
+
const engagementPattern = renderEngagementPattern(input.summary.roleDistribution);
|
|
47
49
|
return [
|
|
48
50
|
"## Seeker's query",
|
|
49
51
|
input.query,
|
|
@@ -52,13 +54,13 @@ export function buildQuestionPrompt(input) {
|
|
|
52
54
|
profileSummary,
|
|
53
55
|
"",
|
|
54
56
|
"## This discovery turn",
|
|
55
|
-
`- ${input.summary.totalCandidates}
|
|
56
|
-
`- ${input.summary.opportunitiesFound}
|
|
57
|
-
`- ${input.summary.noOpportunityCount}
|
|
58
|
-
`-
|
|
57
|
+
`- ${input.summary.totalCandidates} people reviewed`,
|
|
58
|
+
`- ${input.summary.opportunitiesFound} promising connections found`,
|
|
59
|
+
`- ${input.summary.noOpportunityCount} reviews did not find enough fit (${input.summary.timeoutCount} needed more detail or time)`,
|
|
60
|
+
`- Engagement pattern: ${engagementPattern}`,
|
|
59
61
|
"",
|
|
60
|
-
"##
|
|
61
|
-
|
|
62
|
+
"## Connection review evidence (compact digests)",
|
|
63
|
+
connectionReviewBlocks,
|
|
62
64
|
"",
|
|
63
65
|
"## What the user has already said in this session",
|
|
64
66
|
chatContextBlock,
|
|
@@ -77,19 +79,19 @@ export function buildQuestionPrompt(input) {
|
|
|
77
79
|
* is fixed-size (≤ ~400 chars after rendering), so the rendered block scales
|
|
78
80
|
* linearly with candidate count: 10 candidates ≈ 4 KB, well within budget.
|
|
79
81
|
*/
|
|
80
|
-
function
|
|
82
|
+
function renderConnectionReviewDigests(digests) {
|
|
81
83
|
if (digests.length === 0)
|
|
82
|
-
return "(no
|
|
84
|
+
return "(no connection reviews)";
|
|
83
85
|
return digests
|
|
84
86
|
.map((d) => {
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
: "";
|
|
87
|
+
const relationshipSignal = d.suggestedRoles
|
|
88
|
+
? [` Relationship signal: ${renderRelationshipSignal(d.suggestedRoles)}`]
|
|
89
|
+
: [];
|
|
89
90
|
return [
|
|
90
|
-
`-
|
|
91
|
-
`
|
|
92
|
-
` Outcome: ${d
|
|
91
|
+
`- Person: ${d.counterpartyHint}`,
|
|
92
|
+
` Community context: ${d.indexContext}`,
|
|
93
|
+
` Outcome: ${renderOutcome(d)}`,
|
|
94
|
+
...relationshipSignal,
|
|
93
95
|
` Take: ${d.keyTake}`,
|
|
94
96
|
].join("\n");
|
|
95
97
|
})
|
|
@@ -109,12 +111,54 @@ function renderProfile(p) {
|
|
|
109
111
|
lines.push(`Interests: ${p.interests.join(", ")}`);
|
|
110
112
|
return lines.length > 0 ? lines.join("\n") : "(no profile data)";
|
|
111
113
|
}
|
|
112
|
-
function
|
|
113
|
-
const
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
114
|
+
function renderEngagementPattern(dist) {
|
|
115
|
+
const parts = [];
|
|
116
|
+
if ((dist.peer ?? 0) > 0) {
|
|
117
|
+
parts.push(`${dist.peer} mutual collaboration${dist.peer === 1 ? "" : "s"}`);
|
|
118
|
+
}
|
|
119
|
+
if ((dist.agent ?? 0) > 0) {
|
|
120
|
+
parts.push(`${dist.agent} where the user could offer help or expertise`);
|
|
121
|
+
}
|
|
122
|
+
if ((dist.patient ?? 0) > 0) {
|
|
123
|
+
parts.push(`${dist.patient} where the user seemed to be seeking help or expertise`);
|
|
124
|
+
}
|
|
125
|
+
return parts.length > 0 ? parts.join(", ") : "(no engagement pattern available)";
|
|
126
|
+
}
|
|
127
|
+
function renderOutcome(digest) {
|
|
128
|
+
const outcome = digest.outcomeRole === "opportunity"
|
|
129
|
+
? "promising connection"
|
|
130
|
+
: "not enough fit";
|
|
131
|
+
const reason = renderOutcomeReason(digest.outcomeReason);
|
|
132
|
+
return reason ? `${outcome} (${reason})` : outcome;
|
|
133
|
+
}
|
|
134
|
+
function renderOutcomeReason(reason) {
|
|
135
|
+
switch (reason) {
|
|
136
|
+
case "turn_cap":
|
|
137
|
+
return "needed more detail";
|
|
138
|
+
case "timeout":
|
|
139
|
+
return "ran out of time";
|
|
140
|
+
case "rejected":
|
|
141
|
+
return "not enough mutual interest";
|
|
142
|
+
case "stalled":
|
|
143
|
+
return "stalled";
|
|
144
|
+
case null:
|
|
145
|
+
return "";
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
function renderRelationshipSignal(roles) {
|
|
149
|
+
if (roles.ownUser === "peer" && roles.otherUser === "peer")
|
|
150
|
+
return "mutual collaboration";
|
|
151
|
+
if (roles.ownUser === "agent" && roles.otherUser === "patient") {
|
|
152
|
+
return "the user could offer help or expertise";
|
|
153
|
+
}
|
|
154
|
+
if (roles.ownUser === "patient" && roles.otherUser === "agent") {
|
|
155
|
+
return "the user seemed to be seeking help or expertise";
|
|
156
|
+
}
|
|
157
|
+
if (roles.ownUser === "agent")
|
|
158
|
+
return "the user could offer help or expertise";
|
|
159
|
+
if (roles.ownUser === "patient")
|
|
160
|
+
return "the user seemed to be seeking help or expertise";
|
|
161
|
+
return "collaboration fit";
|
|
118
162
|
}
|
|
119
163
|
function renderDigest(d) {
|
|
120
164
|
const lines = [];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"question.prompt.js","sourceRoot":"/","sources":["opportunity/question.prompt.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @deprecated Use QuestionerAgent and questioner presets instead. Will be removed in a future version.\n *\n * Prompt module for the decision-question generator: the system prompt\n * constant, the `DiscoveryQuestionInput` contract, and a pure string-building\n * `buildQuestionPrompt` that assembles the user message.\n *\n * Pure: no I/O, no LLM call. The generator class (`question.generator.ts`)\n * orchestrates this module + an LLM client.\n */\nimport type { ChatContextDigest } from \"../shared/schemas/chat-context.schema.js\";\nimport type { DiscoveryNegotiationDigest } from \"../shared/schemas/negotiation-digest.schema.js\";\n\n/** Roles used in the existing negotiation framework. */\nexport type NegotiationRole = \"agent\" | \"patient\" | \"peer\";\n\n/** One turn within a negotiation. */\nexport interface DiscoveryTurn {\n action: \"propose\" | \"accept\" | \"reject\" | \"counter\" | \"question\";\n reasoning: string;\n suggestedRoles: { ownUser: NegotiationRole; otherUser: NegotiationRole };\n}\n\n/** Outcome of a negotiation. */\nexport interface DiscoveryOutcome {\n hasOpportunity: boolean;\n reasoning: string;\n agreedRoles?: Array<{ userId: string; role: NegotiationRole }>;\n /** Why the negotiation stopped, when not by an explicit accept/reject. */\n reason?: \"turn_cap\" | \"timeout\";\n}\n\n/** One negotiation that ran during this discovery turn. */\nexport interface DiscoveryNegotiation {\n /** Opaque counterparty identifier; NEVER surfaced to the user (kept out of the prompt). */\n counterpartyId: string;\n /** Abstract profile slice for the LLM (e.g. \"AI infra founder, Berlin\"). */\n counterpartyHint: string;\n /** The network/community prompt this negotiation ran under. */\n indexContext: string;\n /** Last 6 turns are retained; earlier ones are dropped. */\n turns: DiscoveryTurn[];\n outcome: DiscoveryOutcome;\n /**\n * Optional pre-negotiation evaluator score (0..1). When more than\n * `MAX_NEGOTIATIONS` candidates exist, this is used as a tie-breaker after\n * `turns.length` to decide which to keep.\n */\n seedAssessmentScore?: number;\n}\n\n/** Aggregate counters across all negotiations in this discovery turn. */\nexport interface DiscoverySummary {\n totalCandidates: number;\n opportunitiesFound: number;\n noOpportunityCount: number;\n /** Subset of `noOpportunityCount` where the negotiation hit a turn-cap or timeout. */\n timeoutCount: number;\n /** Map of role → count across all outcomes' `agreedRoles`. */\n roleDistribution: Partial<Record<NegotiationRole, number>>;\n}\n\n/** The seeker's profile slice the generator sees. All fields optional. */\nexport interface DiscoverySourceProfile {\n name?: string;\n bio?: string;\n location?: string;\n skills?: string[];\n interests?: string[];\n}\n\n/** Full input to the question generator. */\nexport interface DiscoveryQuestionInput {\n /** The seeker's original natural-language query / signal that triggered discovery. */\n query: string;\n sourceProfile: DiscoverySourceProfile;\n /**\n * Compact per-negotiation digests from THIS discovery turn. Each digest is a\n * fixed-size structured summary (counterparty hint, index, outcome role,\n * keyTake) — pre-summarized so this prompt stays small regardless of how\n * many candidates were negotiated. Raw negotiations are NOT passed here.\n */\n negotiationDigests: DiscoveryNegotiationDigest[];\n summary: DiscoverySummary;\n /** Distilled chat-session digest, when a session is in scope. */\n chatContext?: ChatContextDigest;\n /** ISO timestamp used as the \"now\" anchor in the prompt. */\n now: string;\n}\n\n/** @deprecated Use QuestionerAgent and questioner presets instead. Will be removed in a future version. */\nexport const SYSTEM_PROMPT = `You sit between a human and a discovery protocol that just ran negotiations on their behalf. Your job: surface the minimum set of structured decision questions the human must answer to make the next discovery turn sharper, or improve their outlook on the intent.\n\nYou may pick from five strategies. Choose contextually; mix when multiple questions genuinely complement.\n- refine_intent: ask the user to sharpen or pivot their original signal.\n- surface_missing_detail: ask for one concrete missing input (stage, location, timing, scope, …).\n- open_adjacent_thread: offer a pivot suggested by recurring counterparty signals.\n- reflective_summary: mirror what the negotiations revealed and ask the user to decide.\n- surface_emergent_knowledge: cite a fact you learned from negotiations and ask the user to decide in light of it.\n\nAsk a question only when ALL of these hold:\n1. The agent cannot resolve the decision autonomously from the evidence shown.\n2. The answer would materially change which candidates surface next.\n3. The same fact is NOT already in chatContext.statedFacts, NOT already asked in chatContext.openQuestions, and NOT already shared in chatContext.surfacedFindings.\n\nStandalone prompt rule. Every generated \\`prompt\\` must be understandable outside the conversation where it was created. Naturally include the original query, discovery pattern, negotiation pattern, or concrete learned fact in the question text itself. Do not rely on \\`title\\`, UI labels, hidden metadata, or surrounding digest/chat text to explain what the question is about. For example, prefer \"For your AI crypto decentralized deep-tech search, which area is most critical right now?\" over \"Which area is most critical right now?\"\n\nCardinality. Default one question. Add a second only when a DIFFERENT strategy genuinely complements the first (e.g. one surface_emergent_knowledge + one refine_intent). Add a third only when there are ≥3 substantive candidates and three distinct strategies each unblock a real decision. Two questions of the same strategy are acceptable only if their decision domains differ (different titles). Avoid stacking three pulls (info-from-user); balance with pushes (info-to-user via reflective_summary / surface_emergent_knowledge).\n\nOrdering. Questions whose answer unblocks the most failed negotiations come first; then highest-impact; then ambiguity-clarifying. Negotiations whose outcome.reason is \"turn_cap\" or \"timeout\" signal under-specification — prioritize.\n\nOption construction. Each option must represent a meaningfully different outcome. Suffix the safest path with \" (Recommended)\" and list it first. The description states the CONSEQUENCE of choosing the option, not its definition. 2–4 options. Never add an \"Other\" option — clients provide a free-text fallback automatically. For surface_emergent_knowledge questions, anchor the prompt in the concrete cited fact (\"Multiple candidates flagged that…\") and let the options represent decisions in light of that fact, not different versions of the fact.\n\nTitle rules. ≤12 chars. Noun of the decision domain. Discovery examples: \"Stage\", \"Timing\", \"Role\", \"Location\", \"Stack\", \"Budget\", \"Scope\", \"Format\".\n\nAnti-patterns — never do these.\n- Don't ask procedural confirmations (\"Should I look again?\").\n- Don't ask about hypothetical edge cases that didn't occur.\n- Don't ask about specific candidate identities; treat counterpartyHint as the only allowed reference.\n- Don't repeat anything in chatContext.openQuestions.\n- Don't re-surface anything in chatContext.surfacedFindings.\n- Don't ask for facts in chatContext.statedFacts.\n\nOutput. Return at most 3 entries in the \"questions\" array. Each entry must include a \"strategy\" field (one of the five values). If nothing is worth asking, return \"questions\": [].`;\n\n/**\n * @deprecated Use QuestionerAgent and questioner presets instead. Will be removed in a future version.\n *\n * Pure builder: assembles the user message string from a structured input.\n */\nexport function buildQuestionPrompt(input: DiscoveryQuestionInput): string {\n const profileSummary = renderProfile(input.sourceProfile);\n const negotiationBlocks = renderDiscoveryNegotiationDigests(input.negotiationDigests);\n const chatContextBlock = input.chatContext\n ? renderDigest(input.chatContext)\n : \"(no chat context available)\";\n const roleDistribution = renderRoleDistribution(input.summary.roleDistribution);\n\n return [\n \"## Seeker's query\",\n input.query,\n \"\",\n \"## Seeker profile\",\n profileSummary,\n \"\",\n \"## This discovery turn\",\n `- ${input.summary.totalCandidates} candidates evaluated`,\n `- ${input.summary.opportunitiesFound} opportunities found`,\n `- ${input.summary.noOpportunityCount} ended without opportunity (${input.summary.timeoutCount} hit turn-cap/timeout)`,\n `- Role distribution across outcomes: ${roleDistribution}`,\n \"\",\n \"## Negotiation evidence (compact digests)\",\n negotiationBlocks,\n \"\",\n \"## What the user has already said in this session\",\n chatContextBlock,\n \"\",\n \"## Now\",\n input.now,\n \"\",\n \"## Your task\",\n \"Identify the minimum set of decision questions the seeker must answer to make\",\n \"the next discovery turn sharper. Apply every rule from your system prompt\",\n \"before outputting. Return an empty `questions` array if nothing is worth asking.\",\n ].join(\"\\n\");\n}\n\n/**\n * Render the negotiation-digest collection into compact one-liners. Each digest\n * is fixed-size (≤ ~400 chars after rendering), so the rendered block scales\n * linearly with candidate count: 10 candidates ≈ 4 KB, well within budget.\n */\nfunction renderDiscoveryNegotiationDigests(digests: DiscoveryNegotiationDigest[]): string {\n if (digests.length === 0) return \"(no negotiations)\";\n return digests\n .map((d) => {\n const reasonSuffix = d.outcomeReason ? ` (${d.outcomeReason})` : \"\";\n const rolesSuffix = d.suggestedRoles\n ? ` — roles=${d.suggestedRoles.ownUser}↔${d.suggestedRoles.otherUser}`\n : \"\";\n return [\n `- Counterparty: ${d.counterpartyHint}`,\n ` Index: ${d.indexContext}`,\n ` Outcome: ${d.outcomeRole}${reasonSuffix}${rolesSuffix}`,\n ` Take: ${d.keyTake}`,\n ].join(\"\\n\");\n })\n .join(\"\\n\\n\");\n}\n\nfunction renderProfile(p: DiscoverySourceProfile): string {\n const lines: string[] = [];\n if (p.name) lines.push(`Name: ${p.name}`);\n if (p.bio) lines.push(`Bio: ${p.bio}`);\n if (p.location) lines.push(`Location: ${p.location}`);\n if (p.skills && p.skills.length > 0) lines.push(`Skills: ${p.skills.join(\", \")}`);\n if (p.interests && p.interests.length > 0) lines.push(`Interests: ${p.interests.join(\", \")}`);\n return lines.length > 0 ? lines.join(\"\\n\") : \"(no profile data)\";\n}\n\nfunction renderRoleDistribution(dist: Partial<Record<NegotiationRole, number>>): string {\n const entries = (Object.entries(dist) as Array<[NegotiationRole, number]>)\n .filter(([, n]) => n > 0);\n if (entries.length === 0) return \"(none)\";\n return entries.map(([role, n]) => `${role}=${n}`).join(\", \");\n}\n\nfunction renderDigest(d: ChatContextDigest): string {\n const lines: string[] = [];\n if (d.statedFacts.length > 0) {\n lines.push(\"Stated facts:\");\n for (const f of d.statedFacts) lines.push(` - ${f}`);\n }\n if (d.openQuestions.length > 0) {\n lines.push(\"Open questions (assistant already asked):\");\n for (const q of d.openQuestions) lines.push(` - ${q}`);\n }\n if (d.rejectionReasons.length > 0) {\n lines.push(\"User pushback / rejections:\");\n for (const r of d.rejectionReasons) lines.push(` - ${r}`);\n }\n if (d.surfacedFindings.length > 0) {\n lines.push(\"Findings already surfaced to user:\");\n for (const f of d.surfacedFindings) lines.push(` - ${f}`);\n }\n return lines.length > 0 ? lines.join(\"\\n\") : \"(digest is empty)\";\n}\n\n"]}
|
|
1
|
+
{"version":3,"file":"question.prompt.js","sourceRoot":"/","sources":["opportunity/question.prompt.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @deprecated Use QuestionerAgent and questioner presets instead. Will be removed in a future version.\n *\n * Prompt module for the decision-question generator: the system prompt\n * constant, the `DiscoveryQuestionInput` contract, and a pure string-building\n * `buildQuestionPrompt` that assembles the user message.\n *\n * Pure: no I/O, no LLM call. The generator class (`question.generator.ts`)\n * orchestrates this module + an LLM client.\n */\nimport type { ChatContextDigest } from \"../shared/schemas/chat-context.schema.js\";\nimport type { DiscoveryNegotiationDigest } from \"../shared/schemas/negotiation-digest.schema.js\";\n\n/** Roles used in the existing negotiation framework. */\nexport type NegotiationRole = \"agent\" | \"patient\" | \"peer\";\n\n/** One turn within a negotiation. */\nexport interface DiscoveryTurn {\n action: \"propose\" | \"accept\" | \"reject\" | \"counter\" | \"question\";\n reasoning: string;\n suggestedRoles: { ownUser: NegotiationRole; otherUser: NegotiationRole };\n}\n\n/** Outcome of a negotiation. */\nexport interface DiscoveryOutcome {\n hasOpportunity: boolean;\n reasoning: string;\n agreedRoles?: Array<{ userId: string; role: NegotiationRole }>;\n /** Why the negotiation stopped, when not by an explicit accept/reject. */\n reason?: \"turn_cap\" | \"timeout\";\n}\n\n/** One negotiation that ran during this discovery turn. */\nexport interface DiscoveryNegotiation {\n /** Opaque counterparty identifier; NEVER surfaced to the user (kept out of the prompt). */\n counterpartyId: string;\n /** Abstract profile slice for the LLM (e.g. \"AI infra founder, Berlin\"). */\n counterpartyHint: string;\n /** The network/community prompt this negotiation ran under. */\n indexContext: string;\n /** Last 6 turns are retained; earlier ones are dropped. */\n turns: DiscoveryTurn[];\n outcome: DiscoveryOutcome;\n /**\n * Optional pre-negotiation evaluator score (0..1). When more than\n * `MAX_NEGOTIATIONS` candidates exist, this is used as a tie-breaker after\n * `turns.length` to decide which to keep.\n */\n seedAssessmentScore?: number;\n}\n\n/** Aggregate counters across all negotiations in this discovery turn. */\nexport interface DiscoverySummary {\n totalCandidates: number;\n opportunitiesFound: number;\n noOpportunityCount: number;\n /** Subset of `noOpportunityCount` where the negotiation hit a turn-cap or timeout. */\n timeoutCount: number;\n /** Map of role → count across all outcomes' `agreedRoles`. */\n roleDistribution: Partial<Record<NegotiationRole, number>>;\n}\n\n/** The seeker's profile slice the generator sees. All fields optional. */\nexport interface DiscoverySourceProfile {\n name?: string;\n bio?: string;\n location?: string;\n skills?: string[];\n interests?: string[];\n}\n\n/** Full input to the question generator. */\nexport interface DiscoveryQuestionInput {\n /** The seeker's original natural-language query / signal that triggered discovery. */\n query: string;\n sourceProfile: DiscoverySourceProfile;\n /**\n * Compact per-negotiation digests from THIS discovery turn. Each digest is a\n * fixed-size structured summary (counterparty hint, index, outcome role,\n * keyTake) — pre-summarized so this prompt stays small regardless of how\n * many candidates were negotiated. Raw negotiations are NOT passed here.\n */\n negotiationDigests: DiscoveryNegotiationDigest[];\n summary: DiscoverySummary;\n /** Distilled chat-session digest, when a session is in scope. */\n chatContext?: ChatContextDigest;\n /** ISO timestamp used as the \"now\" anchor in the prompt. */\n now: string;\n}\n\n/** @deprecated Use QuestionerAgent and questioner presets instead. Will be removed in a future version. */\nexport const SYSTEM_PROMPT = `You help write user-facing follow-up questions after Index has reviewed potential connections for a human. Your job: surface the minimum set of structured decision questions the human must answer to make the next discovery turn sharper, or improve their outlook on the intent.\n\nYou may pick from five strategies. Choose contextually; mix when multiple questions genuinely complement.\n- refine_intent: ask the user to sharpen or pivot their original signal.\n- surface_missing_detail: ask for one concrete missing input (stage, location, timing, scope, …).\n- open_adjacent_thread: offer a pivot suggested by recurring connection signals.\n- reflective_summary: mirror what the connection review revealed and ask the user to decide.\n- surface_emergent_knowledge: cite a fact you learned from the connection review and ask the user to decide in light of it.\n\nAsk a question only when ALL of these hold:\n1. Index cannot resolve the decision autonomously from the evidence shown.\n2. The answer would materially change which people surface next.\n3. The same fact is NOT already in chatContext.statedFacts, NOT already asked in chatContext.openQuestions, and NOT already shared in chatContext.surfacedFindings.\n\nStandalone prompt rule. Every generated \\`prompt\\` must be understandable outside the conversation where it was created. Naturally include the original query, discovery pattern, connection pattern, or concrete learned fact in the question text itself. Do not rely on \\`title\\`, UI labels, hidden metadata, or surrounding digest/chat text to explain what the question is about. For example, prefer \"For your AI crypto decentralized deep-tech search, which area is most critical right now?\" over \"Which area is most critical right now?\"\n\nCardinality. Default one question. Add a second only when a DIFFERENT strategy genuinely complements the first (e.g. one surface_emergent_knowledge + one refine_intent). Add a third only when there are ≥3 substantive people reviewed and three distinct strategies each unblock a real decision. Two questions of the same strategy are acceptable only if their decision domains differ (different titles). Avoid stacking three pulls (info-from-user); balance with pushes (info-to-user via reflective_summary / surface_emergent_knowledge).\n\nOrdering. Questions whose answer unblocks the most connection reviews come first; then highest-impact; then ambiguity-clarifying. Reviews that needed more detail or ran out of time signal under-specification — prioritize.\n\nUser-facing language. Every title, prompt, option label, and option description is shown directly to the user. Never mention raw protocol mechanics or internal labels such as \"agent\", \"patient\", \"peer\", \"suggestedRoles\", \"role distribution\", \"counterparty\", \"negotiation\", \"turn_cap\", \"timeout\", or \"candidate\". Use natural language instead: people, matches, connections, mutual collaboration, someone who can help, or someone seeking help.\n\nOption construction. Each option must represent a meaningfully different outcome. Suffix the safest path with \" (Recommended)\" and list it first. The description states the CONSEQUENCE of choosing the option, not its definition. 2–4 options. Never add an \"Other\" option — clients provide a free-text fallback automatically. For surface_emergent_knowledge questions, anchor the prompt in the concrete cited fact (\"Multiple people flagged that…\") and let the options represent decisions in light of that fact, not different versions of the fact.\n\nTitle rules. ≤12 chars. Noun of the decision domain. Discovery examples: \"Stage\", \"Timing\", \"Role\", \"Location\", \"Stack\", \"Budget\", \"Scope\", \"Format\".\n\nAnti-patterns — never do these.\n- Don't ask procedural confirmations (\"Should I look again?\").\n- Don't ask about hypothetical edge cases that didn't occur.\n- Don't ask about specific person identities; treat the provided person summary as the only allowed reference.\n- Don't repeat anything in chatContext.openQuestions.\n- Don't re-surface anything in chatContext.surfacedFindings.\n- Don't ask for facts in chatContext.statedFacts.\n\nOutput. Return at most 3 entries in the \"questions\" array. Each entry must include a \"strategy\" field (one of the five values). If nothing is worth asking, return \"questions\": [].`;\n\n/**\n * @deprecated Use QuestionerAgent and questioner presets instead. Will be removed in a future version.\n *\n * Pure builder: assembles the user message string from a structured input.\n */\nexport function buildQuestionPrompt(input: DiscoveryQuestionInput): string {\n const profileSummary = renderProfile(input.sourceProfile);\n const connectionReviewBlocks = renderConnectionReviewDigests(input.negotiationDigests);\n const chatContextBlock = input.chatContext\n ? renderDigest(input.chatContext)\n : \"(no chat context available)\";\n const engagementPattern = renderEngagementPattern(input.summary.roleDistribution);\n\n return [\n \"## Seeker's query\",\n input.query,\n \"\",\n \"## Seeker profile\",\n profileSummary,\n \"\",\n \"## This discovery turn\",\n `- ${input.summary.totalCandidates} people reviewed`,\n `- ${input.summary.opportunitiesFound} promising connections found`,\n `- ${input.summary.noOpportunityCount} reviews did not find enough fit (${input.summary.timeoutCount} needed more detail or time)`,\n `- Engagement pattern: ${engagementPattern}`,\n \"\",\n \"## Connection review evidence (compact digests)\",\n connectionReviewBlocks,\n \"\",\n \"## What the user has already said in this session\",\n chatContextBlock,\n \"\",\n \"## Now\",\n input.now,\n \"\",\n \"## Your task\",\n \"Identify the minimum set of decision questions the seeker must answer to make\",\n \"the next discovery turn sharper. Apply every rule from your system prompt\",\n \"before outputting. Return an empty `questions` array if nothing is worth asking.\",\n ].join(\"\\n\");\n}\n\n/**\n * Render the negotiation-digest collection into compact one-liners. Each digest\n * is fixed-size (≤ ~400 chars after rendering), so the rendered block scales\n * linearly with candidate count: 10 candidates ≈ 4 KB, well within budget.\n */\nfunction renderConnectionReviewDigests(digests: DiscoveryNegotiationDigest[]): string {\n if (digests.length === 0) return \"(no connection reviews)\";\n return digests\n .map((d) => {\n const relationshipSignal = d.suggestedRoles\n ? [` Relationship signal: ${renderRelationshipSignal(d.suggestedRoles)}`]\n : [];\n return [\n `- Person: ${d.counterpartyHint}`,\n ` Community context: ${d.indexContext}`,\n ` Outcome: ${renderOutcome(d)}`,\n ...relationshipSignal,\n ` Take: ${d.keyTake}`,\n ].join(\"\\n\");\n })\n .join(\"\\n\\n\");\n}\n\nfunction renderProfile(p: DiscoverySourceProfile): string {\n const lines: string[] = [];\n if (p.name) lines.push(`Name: ${p.name}`);\n if (p.bio) lines.push(`Bio: ${p.bio}`);\n if (p.location) lines.push(`Location: ${p.location}`);\n if (p.skills && p.skills.length > 0) lines.push(`Skills: ${p.skills.join(\", \")}`);\n if (p.interests && p.interests.length > 0) lines.push(`Interests: ${p.interests.join(\", \")}`);\n return lines.length > 0 ? lines.join(\"\\n\") : \"(no profile data)\";\n}\n\nfunction renderEngagementPattern(dist: Partial<Record<NegotiationRole, number>>): string {\n const parts: string[] = [];\n if ((dist.peer ?? 0) > 0) {\n parts.push(`${dist.peer} mutual collaboration${dist.peer === 1 ? \"\" : \"s\"}`);\n }\n if ((dist.agent ?? 0) > 0) {\n parts.push(`${dist.agent} where the user could offer help or expertise`);\n }\n if ((dist.patient ?? 0) > 0) {\n parts.push(`${dist.patient} where the user seemed to be seeking help or expertise`);\n }\n return parts.length > 0 ? parts.join(\", \") : \"(no engagement pattern available)\";\n}\n\nfunction renderOutcome(digest: DiscoveryNegotiationDigest): string {\n const outcome = digest.outcomeRole === \"opportunity\"\n ? \"promising connection\"\n : \"not enough fit\";\n const reason = renderOutcomeReason(digest.outcomeReason);\n return reason ? `${outcome} (${reason})` : outcome;\n}\n\nfunction renderOutcomeReason(reason: DiscoveryNegotiationDigest[\"outcomeReason\"]): string {\n switch (reason) {\n case \"turn_cap\":\n return \"needed more detail\";\n case \"timeout\":\n return \"ran out of time\";\n case \"rejected\":\n return \"not enough mutual interest\";\n case \"stalled\":\n return \"stalled\";\n case null:\n return \"\";\n }\n}\n\nfunction renderRelationshipSignal(roles: NonNullable<DiscoveryNegotiationDigest[\"suggestedRoles\"]>): string {\n if (roles.ownUser === \"peer\" && roles.otherUser === \"peer\") return \"mutual collaboration\";\n if (roles.ownUser === \"agent\" && roles.otherUser === \"patient\") {\n return \"the user could offer help or expertise\";\n }\n if (roles.ownUser === \"patient\" && roles.otherUser === \"agent\") {\n return \"the user seemed to be seeking help or expertise\";\n }\n if (roles.ownUser === \"agent\") return \"the user could offer help or expertise\";\n if (roles.ownUser === \"patient\") return \"the user seemed to be seeking help or expertise\";\n return \"collaboration fit\";\n}\n\nfunction renderDigest(d: ChatContextDigest): string {\n const lines: string[] = [];\n if (d.statedFacts.length > 0) {\n lines.push(\"Stated facts:\");\n for (const f of d.statedFacts) lines.push(` - ${f}`);\n }\n if (d.openQuestions.length > 0) {\n lines.push(\"Open questions (assistant already asked):\");\n for (const q of d.openQuestions) lines.push(` - ${q}`);\n }\n if (d.rejectionReasons.length > 0) {\n lines.push(\"User pushback / rejections:\");\n for (const r of d.rejectionReasons) lines.push(` - ${r}`);\n }\n if (d.surfacedFindings.length > 0) {\n lines.push(\"Findings already surfaced to user:\");\n for (const f of d.surfacedFindings) lines.push(` - ${f}`);\n }\n return lines.length > 0 ? lines.join(\"\\n\") : \"(digest is empty)\";\n}\n\n"]}
|
|
@@ -190,7 +190,10 @@ export interface ToolContext {
|
|
|
190
190
|
profileRuns?: ProfileRunStore;
|
|
191
191
|
/** Queue for async MCP profile run execution (optional — absent in non-MCP/test contexts). */
|
|
192
192
|
profileRunQueue?: ProfileRunQueue;
|
|
193
|
-
/**
|
|
193
|
+
/**
|
|
194
|
+
* Legacy direct-token minting for opportunity accept redirects.
|
|
195
|
+
* Prefer `mintConnectLink` for user-facing links.
|
|
196
|
+
*/
|
|
194
197
|
mintConnectToken?: (userId: string, opportunityId: string) => Promise<string>;
|
|
195
198
|
/** Mints (or reuses) a short connect link, snapshotting the greeting (optional — absent in non-MCP contexts). */
|
|
196
199
|
mintConnectLink?: MintConnectLink;
|
|
@@ -375,7 +378,10 @@ export interface ToolDeps {
|
|
|
375
378
|
profileRuns?: ProfileRunStore;
|
|
376
379
|
/** Queue for async MCP profile run execution (optional — absent in non-MCP/test contexts). */
|
|
377
380
|
profileRunQueue?: ProfileRunQueue;
|
|
378
|
-
/**
|
|
381
|
+
/**
|
|
382
|
+
* Legacy direct-token minting for opportunity accept redirects.
|
|
383
|
+
* Prefer `mintConnectLink` for user-facing links.
|
|
384
|
+
*/
|
|
379
385
|
mintConnectToken?: (userId: string, opportunityId: string) => Promise<string>;
|
|
380
386
|
/** Mints (or reuses) a short connect link, snapshotting the greeting (optional — absent in non-MCP contexts). */
|
|
381
387
|
mintConnectLink?: MintConnectLink;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool.helpers.d.ts","sourceRoot":"/","sources":["shared/agent/tool.helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,KAAK,EACV,0BAA0B,EAC1B,iBAAiB,EACjB,UAAU,EACV,YAAY,EACZ,cAAc,EACd,wBAAwB,EACzB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oCAAoC,CAAC;AAClE,OAAO,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAC;AACzE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,2CAA2C,CAAC;AAC1F,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wCAAwC,CAAC;AACjF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AAChF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uCAAuC,CAAC;AAC7E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AACzE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yCAAyC,CAAC;AACjF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yCAAyC,CAAC;AACjF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gDAAgD,CAAC;AACxF,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,+CAA+C,CAAC;AAC7F,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,gDAAgD,CAAC;AAC/F,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qCAAqC,CAAC;AACpE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,+CAA+C,CAAC;AAC7F,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6CAA6C,CAAC;AACnF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4CAA4C,CAAC;AACjF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAC/E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAChF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,sCAAsC,CAAC;AAChF,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAC;AACpF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,KAAK,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,0CAA0C,CAAC;AACrG,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,wCAAwC,CAAC;AAE/F,MAAM,MAAM,cAAc,GAAG,eAAe,GAAG,IAAI,CAAC;AAEpD,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;IACpE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAMD,6DAA6D;AAE7D,MAAM,MAAM,aAAa,GAAG;IAAE,MAAM,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,CAAA;CAAE,CAAC;AAMrE;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IAElC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kEAAkE;IAClE,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB,IAAI,EAAE,UAAU,CAAC;IACjB,WAAW,EAAE,cAAc,CAAC;IAC5B,YAAY,EAAE,iBAAiB,EAAE,CAAC;IAClC;;;;;;;OAOG;IACH,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,WAAW,CAAC,EAAE;QACZ,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;QACtB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACnC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KACvC,CAAC;IACF,oBAAoB,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;IAC1C,oFAAoF;IACpF,YAAY,EAAE,OAAO,CAAC;IACtB,+CAA+C;IAC/C,OAAO,EAAE,OAAO,CAAC;IACjB,4GAA4G;IAC5G,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4FAA4F;IAC5F,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,+EAA+E;IAC/E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,UAAU,GAAG,KAAK,CAAC;CACpC;AAED;;;;;;GAMG;AACH,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,oFAAoF;IACpF,QAAQ,EAAE,0BAA0B,CAAC;IACrC,uHAAuH;IACvH,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,0IAA0I;IAC1I,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,0GAA0G;IAC1G,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;;;;;OAUG;IACH,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,+GAA+G;IAC/G,SAAS,CAAC,EAAE,MAAM,CAAC;IAGnB,qDAAqD;IACrD,KAAK,EAAE,KAAK,CAAC;IACb,sEAAsE;IACtE,SAAS,EAAE,SAAS,CAAC;IACrB,mEAAmE;IACnE,WAAW,EAAE,kBAAkB,CAAC;IAChC,kFAAkF;IAClF,WAAW,EAAE,gBAAgB,CAAC;IAC9B,qCAAqC;IACrC,cAAc,EAAE,qBAAqB,CAAC;IACtC,4DAA4D;IAC5D,WAAW,EAAE,iBAAiB,CAAC;IAC/B,kGAAkG;IAClG,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAChC,+FAA+F;IAC/F,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC,oFAAoF;IACpF,iBAAiB,CAAC,EAAE,uBAAuB,CAAC;IAC5C;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,mBAAmB,CAAC;IACxC,6FAA6F;IAC7F,kBAAkB,CAAC,EAAE,wBAAwB,CAAC;IAC9C,qDAAqD;IACrD,QAAQ,EAAE,eAAe,CAAC;IAC1B,gEAAgE;IAChE,mBAAmB,EAAE,wBAAwB,CAAC;IAC9C,kEAAkE;IAClE,mBAAmB,EAAE;QACnB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;YACvD,QAAQ,EAAE,MAAM,CAAC;YACjB,OAAO,EAAE,MAAM,CAAC;YAChB,WAAW,EAAE,MAAM,CAAC;YACpB,gBAAgB,EAAE,MAAM,CAAC;SAC1B,CAAC,CAAC;KACJ,CAAC;IACF,+CAA+C;IAC/C,kBAAkB,EAAE,CAAC,EAAE,EAAE,0BAA0B,EAAE,MAAM,EAAE,MAAM,KAAK,YAAY,CAAC;IACrF,iDAAiD;IACjD,oBAAoB,EAAE,CAAC,EAAE,EAAE,0BAA0B,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,EAAE,QAAQ,CAAC,EAAE,QAAQ,KAAK,cAAc,CAAC;IACpI,sFAAsF;IACtF,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,mGAAmG;IACnG,uBAAuB,CAAC,EAAE,uBAAuB,CAAC;IAClD,6FAA6F;IAC7F,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,+EAA+E;IAC/E,6BAA6B,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAClE,wGAAwG;IACxG,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,6EAA6E;IAC7E,sBAAsB,CAAC,EAAE,CAAC,aAAa,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAClF,oGAAoG;IACpG,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,6FAA6F;IAC7F,aAAa,CAAC,EAAE,iBAAiB,CAAC;IAClC,gGAAgG;IAChG,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC,2FAA2F;IAC3F,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B,8FAA8F;IAC9F,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,8GAA8G;IAC9G,gBAAgB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC9E,iHAAiH;IACjH,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,2FAA2F;IAC3F,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0GAA0G;IAC1G,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,wFAAwF;IACxF,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,4EAA4E;IAC5E,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,eAAe,KAAK,IAAI,CAAC;IACpE;;;;;OAKG;IACH,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC;QAC1F,OAAO,EAAE,OAAO,CAAC;QACjB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC;KAC9B,CAAC,CAAC;IACH,sGAAsG;IACtG,aAAa,CAAC,EAAE;QACd,SAAS,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;QACxD,SAAS,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;QACxD,WAAW,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;KAC3D,CAAC;CACH;AAED;;;;GAIG;AACH,MAAM,MAAM,YAAY,GAAG,IAAI,CAAC,WAAW,EAAE,QAAQ,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,GAAG,UAAU,CAAC,CAAC;AAEzG;;;GAGG;AACH,qBAAa,sBAAuB,SAAQ,KAAK;aAG7B,UAAU,EAAE,MAAM;aAClB,IAAI,EAAE,gBAAgB,GAAG,iBAAiB,GAAG,2BAA2B;gBAFxF,OAAO,EAAE,MAAM,EACC,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,gBAAgB,GAAG,iBAAiB,GAAG,2BAA2B;CAK3F;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CAAC,MAAM,EAAE;IAC/C,QAAQ,EAAE,IAAI,CACZ,0BAA0B,EAC1B,SAAS,GAAG,YAAY,GAAG,uBAAuB,GAAG,sBAAsB,GAAG,YAAY,GAAG,cAAc,GAAG,iBAAiB,CAChI,CAAC;IACF,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kFAAkF;IAClF,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAgG/B;AAMD;;;GAGG;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,IAAI,EAAE;IACnD,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,CAAC,CAAC;IACf,OAAO,EAAE,CAAC,KAAK,EAAE;QAAE,OAAO,EAAE,mBAAmB,CAAC;QAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;KAAE,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;CAE1F,KAAK,GAAG,CAAC;AAEV;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC;IAClB,OAAO,EAAE,CAAC,KAAK,EAAE;QAAE,OAAO,EAAE,mBAAmB,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;CACvF;AAED;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;AAM1D;;;GAGG;AACH,MAAM,WAAW,QAAQ;IACvB,oFAAoF;IACpF,QAAQ,EAAE,0BAA0B,CAAC;IACrC,mFAAmF;IACnF,MAAM,EAAE,YAAY,CAAC;IACrB,sGAAsG;IACtG,QAAQ,EAAE,cAAc,CAAC;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,OAAO,qCAAqC,EAAE,QAAQ,CAAC;IACjE,KAAK,EAAE,KAAK,CAAC;IACb,WAAW,EAAE,kBAAkB,CAAC;IAChC,cAAc,EAAE,qBAAqB,CAAC;IACtC,mBAAmB,EAAE;QACnB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;YACvD,QAAQ,EAAE,MAAM,CAAC;YACjB,OAAO,EAAE,MAAM,CAAC;YAChB,WAAW,EAAE,MAAM,CAAC;YACpB,gBAAgB,EAAE,MAAM,CAAC;SAC1B,CAAC,CAAC;KACJ,CAAC;IACF,QAAQ,EAAE,eAAe,CAAC;IAC1B,gEAAgE;IAChE,mBAAmB,EAAE,wBAAwB,CAAC;IAC9C,qFAAqF;IACrF,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAChC,kGAAkG;IAClG,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAChC;;;OAGG;IACH,oBAAoB,CAAC,EAAE;QACrB,oBAAoB,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;QAC5D,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;KAC1D,CAAC;IACF;;;OAGG;IACH,uBAAuB,CAAC,EAAE;QACxB,eAAe,CAAC,EAAE,MAAM;YAAE,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;SAAE,CAAC;QAC9E,sBAAsB,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;KACnE,CAAC;IACF,+FAA+F;IAC/F,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC,oFAAoF;IACpF,iBAAiB,CAAC,EAAE,uBAAuB,CAAC;IAC5C;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,mBAAmB,CAAC;IACxC;;;;;OAKG;IACH,oBAAoB,CAAC,EAAE,CACrB,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE;QACR,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,iEAAiE;QACjE,KAAK,CAAC,EAAE,YAAY,EAAE,CAAC;QACvB,oEAAoE;QACpE,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,KACE,OAAO,CAAC,sBAAsB,EAAE,CAAC,CAAC;IACvC,6FAA6F;IAC7F,kBAAkB,CAAC,EAAE,wBAAwB,CAAC;IAC9C,mGAAmG;IACnG,uBAAuB,CAAC,EAAE,uBAAuB,CAAC;IAClD,6FAA6F;IAC7F,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,+EAA+E;IAC/E,6BAA6B,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAClE,wGAAwG;IACxG,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,oGAAoG;IACpG,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,6FAA6F;IAC7F,aAAa,CAAC,EAAE,iBAAiB,CAAC;IAClC,gGAAgG;IAChG,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC,2FAA2F;IAC3F,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B,8FAA8F;IAC9F,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,8GAA8G;IAC9G,gBAAgB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC9E,iHAAiH;IACjH,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,2FAA2F;IAC3F,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0GAA0G;IAC1G,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,4EAA4E;IAC5E,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,eAAe,KAAK,IAAI,CAAC;IACpE;;;;;OAKG;IACH,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC;QAC1F,OAAO,EAAE,OAAO,CAAC;QACjB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC;KAC9B,CAAC,CAAC;IACH,sGAAsG;IACtG,aAAa,CAAC,EAAE;QACd,SAAS,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;QACxD,SAAS,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;QACxD,WAAW,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;KAC3D,CAAC;IACF,MAAM,EAAE;QACN,OAAO,EAAE,aAAa,CAAC;QACvB,MAAM,EAAE,aAAa,CAAC;QACtB,KAAK,EAAE,aAAa,CAAC;QACrB,iBAAiB,EAAE,aAAa,CAAC;QACjC,WAAW,EAAE,aAAa,CAAC;QAC3B,WAAW,EAAE,wBAAwB,CAAC;QACtC,OAAO,EAAE,aAAa,CAAC;KACxB,CAAC;IACF;;;OAGG;IACH,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE;QACtB,WAAW,EAAE;YAAE,GAAG,EAAE,MAAM,CAAC;YAAC,QAAQ,EAAE,MAAM,CAAC;YAAC,SAAS,EAAE,MAAM,EAAE,CAAC;YAAC,MAAM,EAAE,MAAM,EAAE,CAAA;SAAE,CAAC;QACtF,QAAQ,EAAE,KAAK,CAAC;YAAE,SAAS,EAAE,MAAM,CAAC;YAAC,eAAe,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;KACjE,KAAK,OAAO,CAAC;QAAE,gBAAgB,EAAE,MAAM,EAAE,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;CACtD;AAMD,wBAAgB,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,MAAM,CAE1C;AAED,wBAAgB,KAAK,CACnB,OAAO,EAAE,MAAM,EACf,UAAU,CAAC,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAAC,GACpF,MAAM,CAMR;AAED,6DAA6D;AAC7D,wBAAgB,kBAAkB,CAAC,MAAM,EAAE;IACzC,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;CACjB,GAAG,MAAM,CAMT;AAgBD,uFAAuF;AACvF,eAAO,MAAM,UAAU,QAAoE,CAAC;AAE5F;;;GAGG;AACH,wBAAsB,iBAAiB,CACrC,QAAQ,EAAE;IAAE,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC,CAAA;CAAE,EACnF,UAAU,EAAE,MAAM,EAAE,GACnB,OAAO,CAAC,MAAM,EAAE,CAAC,CAMnB;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAWvD;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CA2BlD;AAgBD;;;;;;;;;;;;GAYG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAe7D"}
|
|
1
|
+
{"version":3,"file":"tool.helpers.d.ts","sourceRoot":"/","sources":["shared/agent/tool.helpers.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool.helpers.js","sourceRoot":"/","sources":["shared/agent/tool.helpers.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from \"zod\";\nimport type { ModelConfig } from \"./model.config.js\";\nimport type { ProfileDocument } from \"../schemas/profile.schema.js\";\nimport type {\n ChatGraphCompositeDatabase,\n NetworkMembership,\n UserRecord,\n UserDatabase,\n SystemDatabase,\n NegotiationGraphDatabase,\n} from \"../interfaces/database.interface.js\";\nimport type { Scraper } from \"../interfaces/scraper.interface.js\";\nimport type { Cache, HydeCache } from \"../interfaces/cache.interface.js\";\nimport type { CompiledOpportunityGraph } from \"../../opportunity/opportunity.discover.js\";\nimport type { IntegrationAdapter } from \"../interfaces/integration.interface.js\";\nimport type { ContactServiceAdapter } from \"../interfaces/contact.interface.js\";\nimport type { ProfileEnricher } from \"../interfaces/enrichment.interface.js\";\nimport type { IntentGraphQueue } from \"../interfaces/queue.interface.js\";\nimport type { ChatSessionReader } from \"../interfaces/chat-session.interface.js\";\nimport type { ChatSummaryReader } from \"../interfaces/chat-summary.interface.js\";\nimport type { ChatMessageWriter } from \"../interfaces/chat-message-writer.interface.js\";\nimport type { QuestionGeneratorReader } from \"../interfaces/question-generator.interface.js\";\nimport type { NegotiationSummaryReader } from \"../interfaces/negotiation-summary.interface.js\";\nimport type { Embedder } from \"../interfaces/embedder.interface.js\";\nimport type { AgentDatabase } from \"../interfaces/agent.interface.js\";\nimport type { NegotiationTimeoutQueue } from \"../interfaces/negotiation-events.interface.js\";\nimport type { AgentDispatcher } from \"../interfaces/agent-dispatcher.interface.js\";\nimport type { DeliveryLedger } from \"../interfaces/delivery-ledger.interface.js\";\nimport type { MintConnectLink } from \"../interfaces/connect-link.interface.js\";\nimport type { QuestionerDatabase } from \"../interfaces/questioner.interface.js\";\nimport type { QuestionerEnqueueFn } from \"../../questioner/questioner.types.js\";\nimport type { PendingQuestionSummary } from \"../schemas/pending-question.schema.js\";\nimport type { QuestionMode } from \"../schemas/question.schema.js\";\nimport type { DiscoveryRunQueue, DiscoveryRunStore } from \"../interfaces/discovery-run.interface.js\";\nimport type { ProfileRunQueue, ProfileRunStore } from \"../interfaces/profile-run.interface.js\";\n\nexport type ProfileContext = ProfileDocument | null;\n\nexport interface ToolErrorReport {\n operation: string;\n subsystem?: string;\n toolName?: string;\n userId?: string;\n tags?: Record<string, string | number | boolean | null | undefined>;\n context?: Record<string, unknown>;\n}\n\n// ═══════════════════════════════════════════════════════════════════════════════\n// COMPILED GRAPH TYPE\n// ═══════════════════════════════════════════════════════════════════════════════\n\n/** Minimal interface for an invokable compiled LangGraph. */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type CompiledGraph = { invoke: (input: any) => Promise<any> };\n\n// ═══════════════════════════════════════════════════════════════════════════════\n// TOOL CONTEXT TYPES\n// ═══════════════════════════════════════════════════════════════════════════════\n\n/**\n * Resolved context available to every tool handler.\n * Contains the current user and optional index identity, resolved from DB at init.\n * The LLM can see this context (via system prompt) but cannot change it.\n */\nexport interface ResolvedToolContext {\n // Legacy flat fields (kept for backwards compatibility in tools/prompts).\n userId: string;\n userName: string;\n userEmail: string;\n networkId?: string;\n indexName?: string;\n /** True when chat is index-scoped and the user owns the index. */\n isOwner?: boolean;\n // Rich identity context for prompt/tool orchestration.\n user: UserRecord;\n userProfile: ProfileContext;\n userNetworks: NetworkMembership[];\n /**\n * The set of index IDs this caller can reach in the current request.\n * For unscoped chats: every index the user is a member of.\n * For network-scoped agents: `[boundNetwork, personalIndex]`.\n * This is the same set used to clamp the DB-level systemDb.\n * Tools that filter intents/profiles default to this set; `networkId` is\n * the \"primary focus\" hint, not a read filter.\n */\n indexScope: string[];\n scopedIndex?: {\n id: string;\n title: string;\n prompt: string | null;\n type?: string;\n metadata?: Record<string, unknown>;\n permissions?: Record<string, unknown>;\n };\n scopedMembershipRole?: \"owner\" | \"member\";\n /** True when user has not completed onboarding (onboarding.completedAt is null). */\n isOnboarding: boolean;\n /** True when the user has a non-empty name. */\n hasName: boolean;\n /** Chat session ID when tools are used in a chat; used for draft opportunities (context.conversationId). */\n sessionId?: string;\n /** True when the request originates from an MCP transport (no interactive UI available). */\n isMcp?: boolean;\n /** Agent ID when the request originates from an API key linked to an agent. */\n agentId?: string;\n /**\n * Receiver's rendering surface declared by the MCP client via the\n * `x-index-surface` request header. `'telegram'` means the MCP response is\n * being rendered inside a Telegram chat; anything\n * else (including `undefined`) is treated as web. Forwarded into\n * `mintConnectLink` so the click-time redirect can branch.\n */\n clientSurface?: 'telegram' | 'web';\n}\n\n/**\n * Dependencies passed when creating tools for a user session.\n * Includes DB adapters, embedder, and scraper.\n *\n * Note: userDb and systemDb are optional inputs - if not provided, createChatTools\n * will create them internally from the chatDatabaseAdapter singleton.\n */\nexport interface ToolContext {\n userId: string;\n /** @deprecated Use userDb or systemDb instead. Kept for backwards compatibility. */\n database: ChatGraphCompositeDatabase;\n /** Context-bound database for accessing the authenticated user's own resources. Created internally if not provided. */\n userDb?: UserDatabase;\n /** Context-bound database for LLM/system operations on cross-user resources within shared indexes. Created internally if not provided. */\n systemDb?: SystemDatabase;\n embedder: Embedder;\n scraper: Scraper;\n /** When set, chat is scoped to this index; tools use it as default for read_intents and create_intent. */\n networkId?: string;\n /**\n * Optional override of the resolved `indexScope`. `resolveChatContext` always\n * computes `indexScope` from the user's memberships (clamped to [bound,\n * personal] when `networkId` is set). When the caller has already computed\n * a clamped scope — notably the MCP server, which clamps via\n * `applyNetworkScopeToContext` for network-scoped agents — passing it on\n * `ToolContext.indexScope` causes `createChatTools` (in tool.factory.ts) to\n * override `resolvedContext.indexScope` with this value rather than the\n * freshly computed one. See ResolvedToolContext.indexScope for the\n * resolved-side semantics.\n */\n indexScope?: string[];\n /** Chat session ID when creating tools for a chat; enables draft opportunities with context.conversationId. */\n sessionId?: string;\n\n // ─── Protocol-level dependencies (injected by composition root) ──────────\n /** General-purpose cache (e.g. for tool results). */\n cache: Cache;\n /** Dedicated cache for HyDE graph (may be same instance as cache). */\n hydeCache: HydeCache;\n /** External integration platform adapter (OAuth, tool actions). */\n integration: IntegrationAdapter;\n /** Queue for enqueuing follow-up intent processing (HyDE generation/deletion). */\n intentQueue: IntentGraphQueue;\n /** Contact management operations. */\n contactService: ContactServiceAdapter;\n /** Chat session reader for loading conversation history. */\n chatSession: ChatSessionReader;\n /** Read-through chat-session digest. Optional; consumers fall back to undefined `chatContext`. */\n chatSummary?: ChatSummaryReader;\n /** Writes user messages into the user's most-recent chat session (Slice 5 MCP elicitation). */\n chatMessageWriter?: ChatMessageWriter;\n /** Decision-question generator. Optional; consumers fall back to no `questions`. */\n questionGenerator?: QuestionGeneratorReader;\n /**\n * Optional async question enqueue callback. When provided, question generation\n * is dispatched asynchronously to the QuestionerQueue instead of running inline.\n * Injected by the composition root when QUESTIONER_ENABLED=true.\n */\n questionerEnqueue?: QuestionerEnqueueFn;\n /** Negotiation-digest summarizer. Optional; consumers fall back to deterministic digests. */\n negotiationSummary?: NegotiationSummaryReader;\n /** Profile enrichment from external data sources. */\n enricher: ProfileEnricher;\n /** Database adapter for negotiation/conversation operations. */\n negotiationDatabase: NegotiationGraphDatabase;\n /** Integration importer for bulk contact import from toolkits. */\n integrationImporter: {\n importContacts(userId: string, toolkit: string): Promise<{\n imported: number;\n skipped: number;\n newContacts: number;\n existingContacts: number;\n }>;\n };\n /** Factory for user-scoped database access. */\n createUserDatabase: (db: ChatGraphCompositeDatabase, userId: string) => UserDatabase;\n /** Factory for system-scoped database access. */\n createSystemDatabase: (db: ChatGraphCompositeDatabase, userId: string, indexScope: string[], embedder?: Embedder) => SystemDatabase;\n /** Optional runtime LLM config. Pass to override env vars for API key, model, etc. */\n modelConfig?: ModelConfig;\n /** Manages negotiation timeout jobs (optional — enables AI fallback on external agent timeout). */\n negotiationTimeoutQueue?: NegotiationTimeoutQueue;\n /** Agent registry database adapter (optional — absent when host does not support agents). */\n agentDatabase?: AgentDatabase;\n /** Grants the default system-agent permissions after onboarding (optional). */\n grantDefaultSystemPermissions?: (userId: string) => Promise<void>;\n /** Dispatcher for routing negotiation turns to personal agents (optional — falls back to system AI). */\n agentDispatcher?: AgentDispatcher;\n /** Enqueue a negotiate_existing job after introducer approval (optional). */\n queueNegotiateExisting?: (opportunityId: string, userId: string) => Promise<void>;\n /** Delivery ledger for committing opportunity delivery rows (optional — absent in chat context). */\n deliveryLedger?: DeliveryLedger;\n /** Persistence for async MCP discovery runs (optional — absent in non-MCP/test contexts). */\n discoveryRuns?: DiscoveryRunStore;\n /** Queue for async MCP discovery run execution (optional — absent in non-MCP/test contexts). */\n discoveryRunQueue?: DiscoveryRunQueue;\n /** Persistence for async MCP profile runs (optional — absent in non-MCP/test contexts). */\n profileRuns?: ProfileRunStore;\n /** Queue for async MCP profile run execution (optional — absent in non-MCP/test contexts). */\n profileRunQueue?: ProfileRunQueue;\n /** Mints a short-lived connect token for opportunity accept links (optional — absent in non-MCP contexts). */\n mintConnectToken?: (userId: string, opportunityId: string) => Promise<string>;\n /** Mints (or reuses) a short connect link, snapshotting the greeting (optional — absent in non-MCP contexts). */\n mintConnectLink?: MintConnectLink;\n /** Frontend base URL for building profile links (e.g. https://index.network, optional). */\n frontendUrl?: string;\n /** API base URL for building opportunity accept links (e.g. https://protocol.index.network, optional). */\n apiBaseUrl?: string;\n /** Persistence for structured questions generated by the QuestionerAgent (optional). */\n questionerDatabase?: QuestionerDatabase;\n /** Optional host-side error reporter for swallowed protocol/tool errors. */\n reportToolError?: (error: unknown, report: ToolErrorReport) => void;\n /**\n * Optional host-side per-principal MCP call throttle. Invoked once per MCP\n * tool dispatch (after identity resolves, before any DB work). When the\n * returned decision is `allowed: false`, the dispatch short-circuits with a\n * rate-limit error carrying `retryAfterSec`. Absent in chat/test contexts.\n */\n mcpRateLimiter?: (input: { userId: string; agentId?: string; toolName: string }) => Promise<{\n allowed: boolean;\n retryAfterSec?: number;\n limit?: number;\n scope?: 'tool' | 'principal';\n }>;\n /** Optional premise lifecycle event callbacks. Fired by premise tools after successful operations. */\n premiseEvents?: {\n onCreated?: (premiseId: string, userId: string) => void;\n onUpdated?: (premiseId: string, userId: string) => void;\n onRetracted?: (premiseId: string, userId: string) => void;\n };\n}\n\n/**\n * All external dependencies needed to initialize the protocol tool engine.\n * The host application (composition root) must provide concrete implementations.\n * This is the subset of ToolContext that is NOT per-request (no userId, indexId, sessionId).\n */\nexport type ProtocolDeps = Omit<ToolContext, 'userId' | 'indexId' | 'sessionId' | 'userDb' | 'systemDb'>;\n\n/**\n * Thrown when a requested chat scope is invalid for the authenticated user.\n * Controllers can map this to an HTTP status code.\n */\nexport class ChatContextAccessError extends Error {\n constructor(\n message: string,\n public readonly statusCode: number,\n public readonly code: \"USER_NOT_FOUND\" | \"INDEX_NOT_FOUND\" | \"INDEX_MEMBERSHIP_REQUIRED\"\n ) {\n super(message);\n this.name = \"ChatContextAccessError\";\n }\n}\n\n/**\n * Resolve the canonical context used by chat tools and system prompt.\n * This preloads user identity, profile, index memberships, and scoped index role.\n */\nexport async function resolveChatContext(params: {\n database: Pick<\n ChatGraphCompositeDatabase,\n \"getUser\" | \"getProfile\" | \"getNetworkMemberships\" | \"getNetworkMembership\" | \"getNetwork\" | \"isIndexOwner\" | \"isNetworkMember\"\n >;\n userId: string;\n networkId?: string;\n /** Chat session ID for draft opportunities (stored as context.conversationId). */\n sessionId?: string;\n}): Promise<ResolvedToolContext> {\n const { database, userId, networkId, sessionId } = params;\n\n const [user, rawProfile, userNetworks] = await Promise.all([\n database.getUser(userId),\n database.getProfile(userId),\n database.getNetworkMemberships(userId),\n ]);\n\n const userProfile: ProfileContext = rawProfile ?? null;\n\n if (!user) {\n throw new ChatContextAccessError(\n \"User not found\",\n 404,\n \"USER_NOT_FOUND\"\n );\n }\n\n let scopedIndex: ResolvedToolContext[\"scopedIndex\"] = undefined;\n let scopedMembershipRole: ResolvedToolContext[\"scopedMembershipRole\"] = undefined;\n let isOwner = false;\n let indexName: string | undefined;\n\n if (networkId) {\n const [index, isMember, owner] = await Promise.all([\n database.getNetwork(networkId),\n database.isNetworkMember(networkId, userId),\n database.isIndexOwner(networkId, userId),\n ]);\n\n if (!index) {\n throw new ChatContextAccessError(\n \"Index not found\",\n 404,\n \"INDEX_NOT_FOUND\"\n );\n }\n\n if (!isMember) {\n throw new ChatContextAccessError(\n \"You are not a member of this index\",\n 403,\n \"INDEX_MEMBERSHIP_REQUIRED\"\n );\n }\n\n let membership = userNetworks.find((m) => m.networkId === index.id);\n if (membership === undefined) {\n membership = (await database.getNetworkMembership(index.id, userId)) ?? undefined;\n }\n scopedIndex = {\n id: index.id,\n title: index.title,\n prompt: membership?.indexPrompt ?? null,\n type: index.type ?? 'community',\n metadata: index.metadata ?? {},\n permissions: index.permissions ?? {},\n };\n isOwner = owner;\n indexName = index.title;\n scopedMembershipRole = owner ? \"owner\" : \"member\";\n }\n\n const userName = user.name ?? \"Unknown\";\n const userEmail = user.email ?? \"\";\n const hasName = !!user.name?.trim();\n\n // When scoped to an index, clamp the caller's reach to [scopedIndex, personalIndex]\n // so the chat's data model matches its \"focus\" semantic: a chat scoped to a\n // community sees that community plus the user's personal index, not their\n // other unrelated memberships. Mirrors the MCP path's clamp for network-scoped\n // agents (see applyNetworkScopeToContext / computeAgentIndexScope).\n const indexScope = networkId\n ? userNetworks\n .filter((m) => m.networkId === networkId || m.isPersonal === true)\n .map((m) => m.networkId)\n : userNetworks.map((m) => m.networkId);\n\n return {\n userId,\n userName,\n userEmail,\n networkId,\n indexName,\n isOwner,\n user,\n userProfile,\n userNetworks,\n indexScope,\n scopedIndex,\n scopedMembershipRole,\n isOnboarding: !(user.onboarding?.completedAt),\n hasName,\n ...(sessionId !== undefined ? { sessionId } : {}),\n };\n}\n\n// ═══════════════════════════════════════════════════════════════════════════════\n// DEFINE TOOL TYPE\n// ═══════════════════════════════════════════════════════════════════════════════\n\n/**\n * Type for the `defineTool` closure created in `createChatTools`.\n * Auto-injects resolved context and provides uniform logging / error handling.\n */\nexport type DefineTool = <T extends z.ZodType>(opts: {\n name: string;\n description: string;\n querySchema: T;\n handler: (input: { context: ResolvedToolContext; query: z.infer<T> }) => Promise<string>;\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\n}) => any;\n\n/**\n * A raw tool definition before LangChain wrapping.\n * Used by the tool registry for direct HTTP invocation.\n */\nexport interface RawToolDefinition {\n name: string;\n description: string;\n schema: z.ZodType;\n handler: (input: { context: ResolvedToolContext; query: unknown }) => Promise<string>;\n}\n\n/**\n * Registry mapping tool names to their raw definitions.\n */\nexport type ToolRegistry = Map<string, RawToolDefinition>;\n\n// ═══════════════════════════════════════════════════════════════════════════════\n// TOOL DEPENDENCIES\n// ═══════════════════════════════════════════════════════════════════════════════\n\n/**\n * Shared dependencies available to all tool domain factories.\n * Passed by `createChatTools` after compiling all subgraphs.\n */\nexport interface ToolDeps {\n /** @deprecated Use userDb or systemDb instead. Kept for backwards compatibility. */\n database: ChatGraphCompositeDatabase;\n /** Context-bound database for accessing the authenticated user's own resources. */\n userDb: UserDatabase;\n /** Context-bound database for LLM/system operations on cross-user resources within shared indexes. */\n systemDb: SystemDatabase;\n scraper: Scraper;\n embedder: import('../interfaces/embedder.interface.js').Embedder;\n cache: Cache;\n integration: IntegrationAdapter;\n contactService: ContactServiceAdapter;\n integrationImporter: {\n importContacts(userId: string, toolkit: string): Promise<{\n imported: number;\n skipped: number;\n newContacts: number;\n existingContacts: number;\n }>;\n };\n enricher: ProfileEnricher;\n /** Database adapter for negotiation/conversation operations. */\n negotiationDatabase: NegotiationGraphDatabase;\n /** Chat session reader for exposing the caller's past conversations as MCP tools. */\n chatSession?: ChatSessionReader;\n /** Read-through chat-session digest. Optional; consumers fall back to undefined `chatContext`. */\n chatSummary?: ChatSummaryReader;\n /**\n * Test seam for opportunity discovery helpers. Production compositions leave\n * this unset so tools call the real discovery module directly.\n */\n opportunityDiscovery?: {\n runDiscoverFromQuery?: (input: unknown) => Promise<unknown>;\n continueDiscovery?: (input: unknown) => Promise<unknown>;\n };\n /**\n * Test seam for opportunity card presentation helpers. Production\n * compositions leave this unset so tools construct the real presenter.\n */\n opportunityPresentation?: {\n createPresenter?: () => { presentHomeCard(input: unknown): Promise<unknown> };\n gatherPresenterContext?: (...args: unknown[]) => Promise<unknown>;\n };\n /** Writes user messages into the user's most-recent chat session (Slice 5 MCP elicitation). */\n chatMessageWriter?: ChatMessageWriter;\n /** Decision-question generator. Optional; consumers fall back to no `questions`. */\n questionGenerator?: QuestionGeneratorReader;\n /**\n * Optional async question enqueue callback. When provided, question generation\n * is dispatched asynchronously to the QuestionerQueue instead of running inline\n * via the `questionGenerator`. Injected by the composition root when\n * QUESTIONER_ENABLED=true.\n */\n questionerEnqueue?: QuestionerEnqueueFn;\n /**\n * Lookup pending questions for a user, optionally filtered by source,\n * detection mode, or capped by count (hosts apply `limit` SQL-side).\n * Used by tools to attach contextually relevant questions to their results.\n * Injected by the composition root — absent when question delivery is disabled.\n */\n findPendingQuestions?: (\n userId: string,\n filters?: {\n sourceType?: string;\n sourceId?: string;\n /** Restrict to questions whose detection mode is in this set. */\n modes?: QuestionMode[];\n /** Maximum rows to return; hosts should apply this in the query. */\n limit?: number;\n },\n ) => Promise<PendingQuestionSummary[]>;\n /** Negotiation-digest summarizer. Optional; consumers fall back to deterministic digests. */\n negotiationSummary?: NegotiationSummaryReader;\n /** Manages negotiation timeout jobs (optional — enables AI fallback on external agent timeout). */\n negotiationTimeoutQueue?: NegotiationTimeoutQueue;\n /** Agent registry database adapter (optional — absent when host does not support agents). */\n agentDatabase?: AgentDatabase;\n /** Grants the default system-agent permissions after onboarding (optional). */\n grantDefaultSystemPermissions?: (userId: string) => Promise<void>;\n /** Dispatcher for routing negotiation turns to personal agents (optional — falls back to system AI). */\n agentDispatcher?: AgentDispatcher;\n /** Delivery ledger for committing opportunity delivery rows (optional — absent in chat context). */\n deliveryLedger?: DeliveryLedger;\n /** Persistence for async MCP discovery runs (optional — absent in non-MCP/test contexts). */\n discoveryRuns?: DiscoveryRunStore;\n /** Queue for async MCP discovery run execution (optional — absent in non-MCP/test contexts). */\n discoveryRunQueue?: DiscoveryRunQueue;\n /** Persistence for async MCP profile runs (optional — absent in non-MCP/test contexts). */\n profileRuns?: ProfileRunStore;\n /** Queue for async MCP profile run execution (optional — absent in non-MCP/test contexts). */\n profileRunQueue?: ProfileRunQueue;\n /** Mints a short-lived connect token for opportunity accept links (optional — absent in non-MCP contexts). */\n mintConnectToken?: (userId: string, opportunityId: string) => Promise<string>;\n /** Mints (or reuses) a short connect link, snapshotting the greeting (optional — absent in non-MCP contexts). */\n mintConnectLink?: MintConnectLink;\n /** Frontend base URL for building profile links (e.g. https://index.network, optional). */\n frontendUrl?: string;\n /** API base URL for building opportunity accept links (e.g. https://protocol.index.network, optional). */\n apiBaseUrl?: string;\n /** Optional host-side error reporter for swallowed protocol/tool errors. */\n reportToolError?: (error: unknown, report: ToolErrorReport) => void;\n /**\n * Optional host-side per-principal MCP call throttle. Invoked once per MCP\n * tool dispatch (after identity resolves, before any DB work). When the\n * returned decision is `allowed: false`, the dispatch short-circuits with a\n * rate-limit error carrying `retryAfterSec`. Absent in chat/test contexts.\n */\n mcpRateLimiter?: (input: { userId: string; agentId?: string; toolName: string }) => Promise<{\n allowed: boolean;\n retryAfterSec?: number;\n limit?: number;\n scope?: 'tool' | 'principal';\n }>;\n /** Optional premise lifecycle event callbacks. Fired by premise tools after successful operations. */\n premiseEvents?: {\n onCreated?: (premiseId: string, userId: string) => void;\n onUpdated?: (premiseId: string, userId: string) => void;\n onRetracted?: (premiseId: string, userId: string) => void;\n };\n graphs: {\n profile: CompiledGraph;\n intent: CompiledGraph;\n index: CompiledGraph;\n networkMembership: CompiledGraph;\n intentIndex: CompiledGraph;\n opportunity: CompiledOpportunityGraph;\n premise: CompiledGraph;\n };\n /**\n * Optional network ranking override for `read_networks`. Injected by tests or custom compositions.\n * When absent, defaults to `NetworkRecommender.invoke()` with a lazy module-level singleton.\n */\n networkRanker?: (input: {\n userProfile: { bio: string; location: string; interests: string[]; skills: string[] };\n networks: Array<{ networkId: string; renderedContext: string }>;\n }) => Promise<{ rankedNetworkIds: string[] } | null>;\n}\n\n// ═══════════════════════════════════════════════════════════════════════════════\n// TOOL RESULT HELPERS\n// ═══════════════════════════════════════════════════════════════════════════════\n\nexport function success<T>(data: T): string {\n return JSON.stringify({ success: true, data });\n}\n\nexport function error(\n message: string,\n debugSteps?: Array<{ step: string; detail?: string; data?: Record<string, unknown> }>\n): string {\n return JSON.stringify({\n success: false,\n error: message,\n ...(debugSteps?.length ? { debugSteps } : {}),\n });\n}\n\n/** Return needsClarification for missing required fields. */\nexport function needsClarification(params: {\n missingFields: string[];\n message: string;\n}): string {\n return JSON.stringify({\n success: false,\n needsClarification: true,\n ...params,\n });\n}\n\n// ═══════════════════════════════════════════════════════════════════════════════\n// CONSTANTS & UTILITIES\n// ═══════════════════════════════════════════════════════════════════════════════\n\n/** Matches http/https URLs in text; captures full URL. */\nconst URL_IN_TEXT_REGEX = /https?:\\/\\/[^\\s\"'<>)\\]]+/gi;\n\n/**\n * Matches bare domain URLs without protocol (e.g. github.com/foo, www.example.com).\n * Requires at least a SLD.TLD pattern followed by optional path.\n * Negative lookbehind ensures we don't double-match URLs already caught by URL_IN_TEXT_REGEX.\n */\nconst BARE_URL_REGEX = /(?<!\\w:\\/\\/)(?<![/\\w])(?:www\\.)?[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.(?:com|org|net|io|dev|co|ai|app|xyz|me|info|gg|so|sh|cc|ly|fm|tv|to|tech|design|network|world|edu|gov|mil|int|us|uk|eu|de|fr|ca|au|jp|cn|in|br|nl|se|no|fi|dk|ch|at|be|it|es|pt|pl|cz|ru|kr|tw|hk|sg|nz|za|mx|ar|cl|id|ph|th|vn|my|ie)(?:\\/[^\\s\"'<>)\\]]*)?/gi;\n\n/** UUID v4 format: 8-4-4-4-12 hex chars (e.g. c2505011-2e45-426e-81dd-b9abb9b72023) */\nexport const UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n\n/**\n * Resolves an array of network IDs to their display titles.\n * Skips any IDs that don't resolve (deleted or invalid networks).\n */\nexport async function resolveIndexNames(\n database: { getNetwork(id: string): Promise<{ id: string; title: string } | null> },\n networkIds: string[]\n): Promise<string[]> {\n if (networkIds.length === 0) return [];\n const results = await Promise.all(\n networkIds.map(id => database.getNetwork(id))\n );\n return results.filter(Boolean).map(idx => idx!.title);\n}\n\n/**\n * Normalize a URL string: if it lacks a protocol, prepend \"https://\".\n * Returns the normalized URL or null if the result is not a valid URL.\n */\nexport function normalizeUrl(raw: string): string | null {\n let url = raw.replace(/[.,;:!?)]+$/, \"\").trim();\n if (!/^https?:\\/\\//i.test(url)) {\n url = `https://${url}`;\n }\n try {\n new URL(url);\n return url;\n } catch {\n return null;\n }\n}\n\n/**\n * Extract unique, valid URLs from a string (e.g. user message or details).\n * Handles both full URLs (https://...) and bare domains (github.com/...).\n */\nexport function extractUrls(text: string): string[] {\n if (!text || typeof text !== \"string\") return [];\n\n const seen = new Set<string>();\n const out: string[] = [];\n\n // Pass 1: full protocol URLs\n const fullMatches = text.match(URL_IN_TEXT_REGEX) ?? [];\n for (const raw of fullMatches) {\n const url = normalizeUrl(raw);\n if (url && !seen.has(url)) {\n seen.add(url);\n out.push(url);\n }\n }\n\n // Pass 2: bare domain URLs (e.g. github.com/foo)\n const bareMatches = text.match(BARE_URL_REGEX) ?? [];\n for (const raw of bareMatches) {\n const url = normalizeUrl(raw);\n if (url && !seen.has(url)) {\n seen.add(url);\n out.push(url);\n }\n }\n\n return out;\n}\n\nconst SENSITIVE_FIELD_KEYS = new Set([\n \"secret\",\n \"webhooksecret\",\n \"password\",\n \"apikey\",\n \"token\",\n \"accesstoken\",\n \"refreshtoken\",\n \"privatekey\",\n \"authtoken\",\n \"bearertoken\",\n \"clientsecret\",\n]);\n\n/**\n * Recursively redacts sensitive field values from an arbitrary payload before\n * it is passed to a structured logger. Matches field names case-insensitively\n * and ignoring underscores, so `api_key`, `apiKey`, and `API_KEY` all match.\n * Non-sensitive fields are passed through unchanged. Never mutates the input —\n * returns a new value.\n *\n * Intended for structured-log redaction only. Do NOT use as a security\n * boundary for data in motion.\n *\n * @param value - Arbitrary JSON-like payload (query object, config blob, etc.)\n * @returns A new value with sensitive fields replaced by `\"[redacted]\"`.\n */\nexport function redactSensitiveFields(value: unknown): unknown {\n if (value === null || typeof value !== \"object\") return value;\n if (Array.isArray(value)) {\n return value.map((item) => redactSensitiveFields(item));\n }\n const out: Record<string, unknown> = {};\n for (const [key, inner] of Object.entries(value as Record<string, unknown>)) {\n const normalized = key.toLowerCase().replace(/_/g, \"\");\n if (SENSITIVE_FIELD_KEYS.has(normalized)) {\n out[key] = \"[redacted]\";\n } else {\n out[key] = redactSensitiveFields(inner);\n }\n }\n return out;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"tool.helpers.js","sourceRoot":"/","sources":["shared/agent/tool.helpers.ts"],"names":[],"mappings":"AAiQA;;;GAGG;AACH,MAAM,OAAO,sBAAuB,SAAQ,KAAK;IAC/C,YACE,OAAe,EACC,UAAkB,EAClB,IAAwE;QAExF,KAAK,CAAC,OAAO,CAAC,CAAC;QAHC,eAAU,GAAV,UAAU,CAAQ;QAClB,SAAI,GAAJ,IAAI,CAAoE;QAGxF,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;IACvC,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,MASxC;IACC,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,GAAG,MAAM,CAAC;IAE1D,MAAM,CAAC,IAAI,EAAE,UAAU,EAAE,YAAY,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QACzD,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC;QACxB,QAAQ,CAAC,UAAU,CAAC,MAAM,CAAC;QAC3B,QAAQ,CAAC,qBAAqB,CAAC,MAAM,CAAC;KACvC,CAAC,CAAC;IAEH,MAAM,WAAW,GAAmB,UAAU,IAAI,IAAI,CAAC;IAEvD,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,sBAAsB,CAC9B,gBAAgB,EAChB,GAAG,EACH,gBAAgB,CACjB,CAAC;IACJ,CAAC;IAED,IAAI,WAAW,GAAuC,SAAS,CAAC;IAChE,IAAI,oBAAoB,GAAgD,SAAS,CAAC;IAClF,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,IAAI,SAA6B,CAAC;IAElC,IAAI,SAAS,EAAE,CAAC;QACd,MAAM,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YACjD,QAAQ,CAAC,UAAU,CAAC,SAAS,CAAC;YAC9B,QAAQ,CAAC,eAAe,CAAC,SAAS,EAAE,MAAM,CAAC;YAC3C,QAAQ,CAAC,YAAY,CAAC,SAAS,EAAE,MAAM,CAAC;SACzC,CAAC,CAAC;QAEH,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,IAAI,sBAAsB,CAC9B,iBAAiB,EACjB,GAAG,EACH,iBAAiB,CAClB,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,MAAM,IAAI,sBAAsB,CAC9B,oCAAoC,EACpC,GAAG,EACH,2BAA2B,CAC5B,CAAC;QACJ,CAAC;QAED,IAAI,UAAU,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,KAAK,KAAK,CAAC,EAAE,CAAC,CAAC;QACpE,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;YAC7B,UAAU,GAAG,CAAC,MAAM,QAAQ,CAAC,oBAAoB,CAAC,KAAK,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC,IAAI,SAAS,CAAC;QACpF,CAAC;QACD,WAAW,GAAG;YACZ,EAAE,EAAE,KAAK,CAAC,EAAE;YACZ,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,MAAM,EAAE,UAAU,EAAE,WAAW,IAAI,IAAI;YACvC,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,WAAW;YAC/B,QAAQ,EAAE,KAAK,CAAC,QAAQ,IAAI,EAAE;YAC9B,WAAW,EAAE,KAAK,CAAC,WAAW,IAAI,EAAE;SACrC,CAAC;QACF,OAAO,GAAG,KAAK,CAAC;QAChB,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC;QACxB,oBAAoB,GAAG,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC;IACpD,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,IAAI,SAAS,CAAC;IACxC,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;IACnC,MAAM,OAAO,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC;IAEpC,oFAAoF;IACpF,4EAA4E;IAC5E,0EAA0E;IAC1E,+EAA+E;IAC/E,oEAAoE;IACpE,MAAM,UAAU,GAAG,SAAS;QAC1B,CAAC,CAAC,YAAY;aACT,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,KAAK,SAAS,IAAI,CAAC,CAAC,UAAU,KAAK,IAAI,CAAC;aACjE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;QAC5B,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IAEzC,OAAO;QACL,MAAM;QACN,QAAQ;QACR,SAAS;QACT,SAAS;QACT,SAAS;QACT,OAAO;QACP,IAAI;QACJ,WAAW;QACX,YAAY;QACZ,UAAU;QACV,WAAW;QACX,oBAAoB;QACpB,YAAY,EAAE,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC;QAC7C,OAAO;QACP,GAAG,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAClD,CAAC;AACJ,CAAC;AAuLD,kFAAkF;AAClF,sBAAsB;AACtB,kFAAkF;AAElF,MAAM,UAAU,OAAO,CAAI,IAAO;IAChC,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;AACjD,CAAC;AAED,MAAM,UAAU,KAAK,CACnB,OAAe,EACf,UAAqF;IAErF,OAAO,IAAI,CAAC,SAAS,CAAC;QACpB,OAAO,EAAE,KAAK;QACd,KAAK,EAAE,OAAO;QACd,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC9C,CAAC,CAAC;AACL,CAAC;AAED,6DAA6D;AAC7D,MAAM,UAAU,kBAAkB,CAAC,MAGlC;IACC,OAAO,IAAI,CAAC,SAAS,CAAC;QACpB,OAAO,EAAE,KAAK;QACd,kBAAkB,EAAE,IAAI;QACxB,GAAG,MAAM;KACV,CAAC,CAAC;AACL,CAAC;AAED,kFAAkF;AAClF,wBAAwB;AACxB,kFAAkF;AAElF,0DAA0D;AAC1D,MAAM,iBAAiB,GAAG,4BAA4B,CAAC;AAEvD;;;;GAIG;AACH,MAAM,cAAc,GAAG,+TAA+T,CAAC;AAEvV,uFAAuF;AACvF,MAAM,CAAC,MAAM,UAAU,GAAG,iEAAiE,CAAC;AAE5F;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,QAAmF,EACnF,UAAoB;IAEpB,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACvC,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAC/B,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAC9C,CAAC;IACF,OAAO,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAI,CAAC,KAAK,CAAC,CAAC;AACxD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,GAAW;IACtC,IAAI,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAChD,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/B,GAAG,GAAG,WAAW,GAAG,EAAE,CAAC;IACzB,CAAC;IACD,IAAI,CAAC;QACH,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QACb,OAAO,GAAG,CAAC;IACb,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,EAAE,CAAC;IAEjD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,GAAG,GAAa,EAAE,CAAC;IAEzB,6BAA6B;IAC7B,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,IAAI,EAAE,CAAC;IACxD,KAAK,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;QAC9B,MAAM,GAAG,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;QAC9B,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YAC1B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACd,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAChB,CAAC;IACH,CAAC;IAED,iDAAiD;IACjD,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;IACrD,KAAK,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;QAC9B,MAAM,GAAG,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;QAC9B,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YAC1B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACd,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAChB,CAAC;IACH,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,oBAAoB,GAAG,IAAI,GAAG,CAAC;IACnC,QAAQ;IACR,eAAe;IACf,UAAU;IACV,QAAQ;IACR,OAAO;IACP,aAAa;IACb,cAAc;IACd,YAAY;IACZ,WAAW;IACX,aAAa;IACb,cAAc;CACf,CAAC,CAAC;AAEH;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,qBAAqB,CAAC,KAAc;IAClD,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC9D,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC,CAAC;IAC1D,CAAC;IACD,MAAM,GAAG,GAA4B,EAAE,CAAC;IACxC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAgC,CAAC,EAAE,CAAC;QAC5E,MAAM,UAAU,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACvD,IAAI,oBAAoB,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;YACzC,GAAG,CAAC,GAAG,CAAC,GAAG,YAAY,CAAC;QAC1B,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,GAAG,CAAC,GAAG,qBAAqB,CAAC,KAAK,CAAC,CAAC;QAC1C,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC","sourcesContent":["import { z } from \"zod\";\nimport type { ModelConfig } from \"./model.config.js\";\nimport type { ProfileDocument } from \"../schemas/profile.schema.js\";\nimport type {\n ChatGraphCompositeDatabase,\n NetworkMembership,\n UserRecord,\n UserDatabase,\n SystemDatabase,\n NegotiationGraphDatabase,\n} from \"../interfaces/database.interface.js\";\nimport type { Scraper } from \"../interfaces/scraper.interface.js\";\nimport type { Cache, HydeCache } from \"../interfaces/cache.interface.js\";\nimport type { CompiledOpportunityGraph } from \"../../opportunity/opportunity.discover.js\";\nimport type { IntegrationAdapter } from \"../interfaces/integration.interface.js\";\nimport type { ContactServiceAdapter } from \"../interfaces/contact.interface.js\";\nimport type { ProfileEnricher } from \"../interfaces/enrichment.interface.js\";\nimport type { IntentGraphQueue } from \"../interfaces/queue.interface.js\";\nimport type { ChatSessionReader } from \"../interfaces/chat-session.interface.js\";\nimport type { ChatSummaryReader } from \"../interfaces/chat-summary.interface.js\";\nimport type { ChatMessageWriter } from \"../interfaces/chat-message-writer.interface.js\";\nimport type { QuestionGeneratorReader } from \"../interfaces/question-generator.interface.js\";\nimport type { NegotiationSummaryReader } from \"../interfaces/negotiation-summary.interface.js\";\nimport type { Embedder } from \"../interfaces/embedder.interface.js\";\nimport type { AgentDatabase } from \"../interfaces/agent.interface.js\";\nimport type { NegotiationTimeoutQueue } from \"../interfaces/negotiation-events.interface.js\";\nimport type { AgentDispatcher } from \"../interfaces/agent-dispatcher.interface.js\";\nimport type { DeliveryLedger } from \"../interfaces/delivery-ledger.interface.js\";\nimport type { MintConnectLink } from \"../interfaces/connect-link.interface.js\";\nimport type { QuestionerDatabase } from \"../interfaces/questioner.interface.js\";\nimport type { QuestionerEnqueueFn } from \"../../questioner/questioner.types.js\";\nimport type { PendingQuestionSummary } from \"../schemas/pending-question.schema.js\";\nimport type { QuestionMode } from \"../schemas/question.schema.js\";\nimport type { DiscoveryRunQueue, DiscoveryRunStore } from \"../interfaces/discovery-run.interface.js\";\nimport type { ProfileRunQueue, ProfileRunStore } from \"../interfaces/profile-run.interface.js\";\n\nexport type ProfileContext = ProfileDocument | null;\n\nexport interface ToolErrorReport {\n operation: string;\n subsystem?: string;\n toolName?: string;\n userId?: string;\n tags?: Record<string, string | number | boolean | null | undefined>;\n context?: Record<string, unknown>;\n}\n\n// ═══════════════════════════════════════════════════════════════════════════════\n// COMPILED GRAPH TYPE\n// ═══════════════════════════════════════════════════════════════════════════════\n\n/** Minimal interface for an invokable compiled LangGraph. */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type CompiledGraph = { invoke: (input: any) => Promise<any> };\n\n// ═══════════════════════════════════════════════════════════════════════════════\n// TOOL CONTEXT TYPES\n// ═══════════════════════════════════════════════════════════════════════════════\n\n/**\n * Resolved context available to every tool handler.\n * Contains the current user and optional index identity, resolved from DB at init.\n * The LLM can see this context (via system prompt) but cannot change it.\n */\nexport interface ResolvedToolContext {\n // Legacy flat fields (kept for backwards compatibility in tools/prompts).\n userId: string;\n userName: string;\n userEmail: string;\n networkId?: string;\n indexName?: string;\n /** True when chat is index-scoped and the user owns the index. */\n isOwner?: boolean;\n // Rich identity context for prompt/tool orchestration.\n user: UserRecord;\n userProfile: ProfileContext;\n userNetworks: NetworkMembership[];\n /**\n * The set of index IDs this caller can reach in the current request.\n * For unscoped chats: every index the user is a member of.\n * For network-scoped agents: `[boundNetwork, personalIndex]`.\n * This is the same set used to clamp the DB-level systemDb.\n * Tools that filter intents/profiles default to this set; `networkId` is\n * the \"primary focus\" hint, not a read filter.\n */\n indexScope: string[];\n scopedIndex?: {\n id: string;\n title: string;\n prompt: string | null;\n type?: string;\n metadata?: Record<string, unknown>;\n permissions?: Record<string, unknown>;\n };\n scopedMembershipRole?: \"owner\" | \"member\";\n /** True when user has not completed onboarding (onboarding.completedAt is null). */\n isOnboarding: boolean;\n /** True when the user has a non-empty name. */\n hasName: boolean;\n /** Chat session ID when tools are used in a chat; used for draft opportunities (context.conversationId). */\n sessionId?: string;\n /** True when the request originates from an MCP transport (no interactive UI available). */\n isMcp?: boolean;\n /** Agent ID when the request originates from an API key linked to an agent. */\n agentId?: string;\n /**\n * Receiver's rendering surface declared by the MCP client via the\n * `x-index-surface` request header. `'telegram'` means the MCP response is\n * being rendered inside a Telegram chat; anything\n * else (including `undefined`) is treated as web. Forwarded into\n * `mintConnectLink` so the click-time redirect can branch.\n */\n clientSurface?: 'telegram' | 'web';\n}\n\n/**\n * Dependencies passed when creating tools for a user session.\n * Includes DB adapters, embedder, and scraper.\n *\n * Note: userDb and systemDb are optional inputs - if not provided, createChatTools\n * will create them internally from the chatDatabaseAdapter singleton.\n */\nexport interface ToolContext {\n userId: string;\n /** @deprecated Use userDb or systemDb instead. Kept for backwards compatibility. */\n database: ChatGraphCompositeDatabase;\n /** Context-bound database for accessing the authenticated user's own resources. Created internally if not provided. */\n userDb?: UserDatabase;\n /** Context-bound database for LLM/system operations on cross-user resources within shared indexes. Created internally if not provided. */\n systemDb?: SystemDatabase;\n embedder: Embedder;\n scraper: Scraper;\n /** When set, chat is scoped to this index; tools use it as default for read_intents and create_intent. */\n networkId?: string;\n /**\n * Optional override of the resolved `indexScope`. `resolveChatContext` always\n * computes `indexScope` from the user's memberships (clamped to [bound,\n * personal] when `networkId` is set). When the caller has already computed\n * a clamped scope — notably the MCP server, which clamps via\n * `applyNetworkScopeToContext` for network-scoped agents — passing it on\n * `ToolContext.indexScope` causes `createChatTools` (in tool.factory.ts) to\n * override `resolvedContext.indexScope` with this value rather than the\n * freshly computed one. See ResolvedToolContext.indexScope for the\n * resolved-side semantics.\n */\n indexScope?: string[];\n /** Chat session ID when creating tools for a chat; enables draft opportunities with context.conversationId. */\n sessionId?: string;\n\n // ─── Protocol-level dependencies (injected by composition root) ──────────\n /** General-purpose cache (e.g. for tool results). */\n cache: Cache;\n /** Dedicated cache for HyDE graph (may be same instance as cache). */\n hydeCache: HydeCache;\n /** External integration platform adapter (OAuth, tool actions). */\n integration: IntegrationAdapter;\n /** Queue for enqueuing follow-up intent processing (HyDE generation/deletion). */\n intentQueue: IntentGraphQueue;\n /** Contact management operations. */\n contactService: ContactServiceAdapter;\n /** Chat session reader for loading conversation history. */\n chatSession: ChatSessionReader;\n /** Read-through chat-session digest. Optional; consumers fall back to undefined `chatContext`. */\n chatSummary?: ChatSummaryReader;\n /** Writes user messages into the user's most-recent chat session (Slice 5 MCP elicitation). */\n chatMessageWriter?: ChatMessageWriter;\n /** Decision-question generator. Optional; consumers fall back to no `questions`. */\n questionGenerator?: QuestionGeneratorReader;\n /**\n * Optional async question enqueue callback. When provided, question generation\n * is dispatched asynchronously to the QuestionerQueue instead of running inline.\n * Injected by the composition root when QUESTIONER_ENABLED=true.\n */\n questionerEnqueue?: QuestionerEnqueueFn;\n /** Negotiation-digest summarizer. Optional; consumers fall back to deterministic digests. */\n negotiationSummary?: NegotiationSummaryReader;\n /** Profile enrichment from external data sources. */\n enricher: ProfileEnricher;\n /** Database adapter for negotiation/conversation operations. */\n negotiationDatabase: NegotiationGraphDatabase;\n /** Integration importer for bulk contact import from toolkits. */\n integrationImporter: {\n importContacts(userId: string, toolkit: string): Promise<{\n imported: number;\n skipped: number;\n newContacts: number;\n existingContacts: number;\n }>;\n };\n /** Factory for user-scoped database access. */\n createUserDatabase: (db: ChatGraphCompositeDatabase, userId: string) => UserDatabase;\n /** Factory for system-scoped database access. */\n createSystemDatabase: (db: ChatGraphCompositeDatabase, userId: string, indexScope: string[], embedder?: Embedder) => SystemDatabase;\n /** Optional runtime LLM config. Pass to override env vars for API key, model, etc. */\n modelConfig?: ModelConfig;\n /** Manages negotiation timeout jobs (optional — enables AI fallback on external agent timeout). */\n negotiationTimeoutQueue?: NegotiationTimeoutQueue;\n /** Agent registry database adapter (optional — absent when host does not support agents). */\n agentDatabase?: AgentDatabase;\n /** Grants the default system-agent permissions after onboarding (optional). */\n grantDefaultSystemPermissions?: (userId: string) => Promise<void>;\n /** Dispatcher for routing negotiation turns to personal agents (optional — falls back to system AI). */\n agentDispatcher?: AgentDispatcher;\n /** Enqueue a negotiate_existing job after introducer approval (optional). */\n queueNegotiateExisting?: (opportunityId: string, userId: string) => Promise<void>;\n /** Delivery ledger for committing opportunity delivery rows (optional — absent in chat context). */\n deliveryLedger?: DeliveryLedger;\n /** Persistence for async MCP discovery runs (optional — absent in non-MCP/test contexts). */\n discoveryRuns?: DiscoveryRunStore;\n /** Queue for async MCP discovery run execution (optional — absent in non-MCP/test contexts). */\n discoveryRunQueue?: DiscoveryRunQueue;\n /** Persistence for async MCP profile runs (optional — absent in non-MCP/test contexts). */\n profileRuns?: ProfileRunStore;\n /** Queue for async MCP profile run execution (optional — absent in non-MCP/test contexts). */\n profileRunQueue?: ProfileRunQueue;\n /**\n * Legacy direct-token minting for opportunity accept redirects.\n * Prefer `mintConnectLink` for user-facing links.\n */\n mintConnectToken?: (userId: string, opportunityId: string) => Promise<string>;\n /** Mints (or reuses) a short connect link, snapshotting the greeting (optional — absent in non-MCP contexts). */\n mintConnectLink?: MintConnectLink;\n /** Frontend base URL for building profile links (e.g. https://index.network, optional). */\n frontendUrl?: string;\n /** API base URL for building opportunity accept links (e.g. https://protocol.index.network, optional). */\n apiBaseUrl?: string;\n /** Persistence for structured questions generated by the QuestionerAgent (optional). */\n questionerDatabase?: QuestionerDatabase;\n /** Optional host-side error reporter for swallowed protocol/tool errors. */\n reportToolError?: (error: unknown, report: ToolErrorReport) => void;\n /**\n * Optional host-side per-principal MCP call throttle. Invoked once per MCP\n * tool dispatch (after identity resolves, before any DB work). When the\n * returned decision is `allowed: false`, the dispatch short-circuits with a\n * rate-limit error carrying `retryAfterSec`. Absent in chat/test contexts.\n */\n mcpRateLimiter?: (input: { userId: string; agentId?: string; toolName: string }) => Promise<{\n allowed: boolean;\n retryAfterSec?: number;\n limit?: number;\n scope?: 'tool' | 'principal';\n }>;\n /** Optional premise lifecycle event callbacks. Fired by premise tools after successful operations. */\n premiseEvents?: {\n onCreated?: (premiseId: string, userId: string) => void;\n onUpdated?: (premiseId: string, userId: string) => void;\n onRetracted?: (premiseId: string, userId: string) => void;\n };\n}\n\n/**\n * All external dependencies needed to initialize the protocol tool engine.\n * The host application (composition root) must provide concrete implementations.\n * This is the subset of ToolContext that is NOT per-request (no userId, indexId, sessionId).\n */\nexport type ProtocolDeps = Omit<ToolContext, 'userId' | 'indexId' | 'sessionId' | 'userDb' | 'systemDb'>;\n\n/**\n * Thrown when a requested chat scope is invalid for the authenticated user.\n * Controllers can map this to an HTTP status code.\n */\nexport class ChatContextAccessError extends Error {\n constructor(\n message: string,\n public readonly statusCode: number,\n public readonly code: \"USER_NOT_FOUND\" | \"INDEX_NOT_FOUND\" | \"INDEX_MEMBERSHIP_REQUIRED\"\n ) {\n super(message);\n this.name = \"ChatContextAccessError\";\n }\n}\n\n/**\n * Resolve the canonical context used by chat tools and system prompt.\n * This preloads user identity, profile, index memberships, and scoped index role.\n */\nexport async function resolveChatContext(params: {\n database: Pick<\n ChatGraphCompositeDatabase,\n \"getUser\" | \"getProfile\" | \"getNetworkMemberships\" | \"getNetworkMembership\" | \"getNetwork\" | \"isIndexOwner\" | \"isNetworkMember\"\n >;\n userId: string;\n networkId?: string;\n /** Chat session ID for draft opportunities (stored as context.conversationId). */\n sessionId?: string;\n}): Promise<ResolvedToolContext> {\n const { database, userId, networkId, sessionId } = params;\n\n const [user, rawProfile, userNetworks] = await Promise.all([\n database.getUser(userId),\n database.getProfile(userId),\n database.getNetworkMemberships(userId),\n ]);\n\n const userProfile: ProfileContext = rawProfile ?? null;\n\n if (!user) {\n throw new ChatContextAccessError(\n \"User not found\",\n 404,\n \"USER_NOT_FOUND\"\n );\n }\n\n let scopedIndex: ResolvedToolContext[\"scopedIndex\"] = undefined;\n let scopedMembershipRole: ResolvedToolContext[\"scopedMembershipRole\"] = undefined;\n let isOwner = false;\n let indexName: string | undefined;\n\n if (networkId) {\n const [index, isMember, owner] = await Promise.all([\n database.getNetwork(networkId),\n database.isNetworkMember(networkId, userId),\n database.isIndexOwner(networkId, userId),\n ]);\n\n if (!index) {\n throw new ChatContextAccessError(\n \"Index not found\",\n 404,\n \"INDEX_NOT_FOUND\"\n );\n }\n\n if (!isMember) {\n throw new ChatContextAccessError(\n \"You are not a member of this index\",\n 403,\n \"INDEX_MEMBERSHIP_REQUIRED\"\n );\n }\n\n let membership = userNetworks.find((m) => m.networkId === index.id);\n if (membership === undefined) {\n membership = (await database.getNetworkMembership(index.id, userId)) ?? undefined;\n }\n scopedIndex = {\n id: index.id,\n title: index.title,\n prompt: membership?.indexPrompt ?? null,\n type: index.type ?? 'community',\n metadata: index.metadata ?? {},\n permissions: index.permissions ?? {},\n };\n isOwner = owner;\n indexName = index.title;\n scopedMembershipRole = owner ? \"owner\" : \"member\";\n }\n\n const userName = user.name ?? \"Unknown\";\n const userEmail = user.email ?? \"\";\n const hasName = !!user.name?.trim();\n\n // When scoped to an index, clamp the caller's reach to [scopedIndex, personalIndex]\n // so the chat's data model matches its \"focus\" semantic: a chat scoped to a\n // community sees that community plus the user's personal index, not their\n // other unrelated memberships. Mirrors the MCP path's clamp for network-scoped\n // agents (see applyNetworkScopeToContext / computeAgentIndexScope).\n const indexScope = networkId\n ? userNetworks\n .filter((m) => m.networkId === networkId || m.isPersonal === true)\n .map((m) => m.networkId)\n : userNetworks.map((m) => m.networkId);\n\n return {\n userId,\n userName,\n userEmail,\n networkId,\n indexName,\n isOwner,\n user,\n userProfile,\n userNetworks,\n indexScope,\n scopedIndex,\n scopedMembershipRole,\n isOnboarding: !(user.onboarding?.completedAt),\n hasName,\n ...(sessionId !== undefined ? { sessionId } : {}),\n };\n}\n\n// ═══════════════════════════════════════════════════════════════════════════════\n// DEFINE TOOL TYPE\n// ═══════════════════════════════════════════════════════════════════════════════\n\n/**\n * Type for the `defineTool` closure created in `createChatTools`.\n * Auto-injects resolved context and provides uniform logging / error handling.\n */\nexport type DefineTool = <T extends z.ZodType>(opts: {\n name: string;\n description: string;\n querySchema: T;\n handler: (input: { context: ResolvedToolContext; query: z.infer<T> }) => Promise<string>;\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\n}) => any;\n\n/**\n * A raw tool definition before LangChain wrapping.\n * Used by the tool registry for direct HTTP invocation.\n */\nexport interface RawToolDefinition {\n name: string;\n description: string;\n schema: z.ZodType;\n handler: (input: { context: ResolvedToolContext; query: unknown }) => Promise<string>;\n}\n\n/**\n * Registry mapping tool names to their raw definitions.\n */\nexport type ToolRegistry = Map<string, RawToolDefinition>;\n\n// ═══════════════════════════════════════════════════════════════════════════════\n// TOOL DEPENDENCIES\n// ═══════════════════════════════════════════════════════════════════════════════\n\n/**\n * Shared dependencies available to all tool domain factories.\n * Passed by `createChatTools` after compiling all subgraphs.\n */\nexport interface ToolDeps {\n /** @deprecated Use userDb or systemDb instead. Kept for backwards compatibility. */\n database: ChatGraphCompositeDatabase;\n /** Context-bound database for accessing the authenticated user's own resources. */\n userDb: UserDatabase;\n /** Context-bound database for LLM/system operations on cross-user resources within shared indexes. */\n systemDb: SystemDatabase;\n scraper: Scraper;\n embedder: import('../interfaces/embedder.interface.js').Embedder;\n cache: Cache;\n integration: IntegrationAdapter;\n contactService: ContactServiceAdapter;\n integrationImporter: {\n importContacts(userId: string, toolkit: string): Promise<{\n imported: number;\n skipped: number;\n newContacts: number;\n existingContacts: number;\n }>;\n };\n enricher: ProfileEnricher;\n /** Database adapter for negotiation/conversation operations. */\n negotiationDatabase: NegotiationGraphDatabase;\n /** Chat session reader for exposing the caller's past conversations as MCP tools. */\n chatSession?: ChatSessionReader;\n /** Read-through chat-session digest. Optional; consumers fall back to undefined `chatContext`. */\n chatSummary?: ChatSummaryReader;\n /**\n * Test seam for opportunity discovery helpers. Production compositions leave\n * this unset so tools call the real discovery module directly.\n */\n opportunityDiscovery?: {\n runDiscoverFromQuery?: (input: unknown) => Promise<unknown>;\n continueDiscovery?: (input: unknown) => Promise<unknown>;\n };\n /**\n * Test seam for opportunity card presentation helpers. Production\n * compositions leave this unset so tools construct the real presenter.\n */\n opportunityPresentation?: {\n createPresenter?: () => { presentHomeCard(input: unknown): Promise<unknown> };\n gatherPresenterContext?: (...args: unknown[]) => Promise<unknown>;\n };\n /** Writes user messages into the user's most-recent chat session (Slice 5 MCP elicitation). */\n chatMessageWriter?: ChatMessageWriter;\n /** Decision-question generator. Optional; consumers fall back to no `questions`. */\n questionGenerator?: QuestionGeneratorReader;\n /**\n * Optional async question enqueue callback. When provided, question generation\n * is dispatched asynchronously to the QuestionerQueue instead of running inline\n * via the `questionGenerator`. Injected by the composition root when\n * QUESTIONER_ENABLED=true.\n */\n questionerEnqueue?: QuestionerEnqueueFn;\n /**\n * Lookup pending questions for a user, optionally filtered by source,\n * detection mode, or capped by count (hosts apply `limit` SQL-side).\n * Used by tools to attach contextually relevant questions to their results.\n * Injected by the composition root — absent when question delivery is disabled.\n */\n findPendingQuestions?: (\n userId: string,\n filters?: {\n sourceType?: string;\n sourceId?: string;\n /** Restrict to questions whose detection mode is in this set. */\n modes?: QuestionMode[];\n /** Maximum rows to return; hosts should apply this in the query. */\n limit?: number;\n },\n ) => Promise<PendingQuestionSummary[]>;\n /** Negotiation-digest summarizer. Optional; consumers fall back to deterministic digests. */\n negotiationSummary?: NegotiationSummaryReader;\n /** Manages negotiation timeout jobs (optional — enables AI fallback on external agent timeout). */\n negotiationTimeoutQueue?: NegotiationTimeoutQueue;\n /** Agent registry database adapter (optional — absent when host does not support agents). */\n agentDatabase?: AgentDatabase;\n /** Grants the default system-agent permissions after onboarding (optional). */\n grantDefaultSystemPermissions?: (userId: string) => Promise<void>;\n /** Dispatcher for routing negotiation turns to personal agents (optional — falls back to system AI). */\n agentDispatcher?: AgentDispatcher;\n /** Delivery ledger for committing opportunity delivery rows (optional — absent in chat context). */\n deliveryLedger?: DeliveryLedger;\n /** Persistence for async MCP discovery runs (optional — absent in non-MCP/test contexts). */\n discoveryRuns?: DiscoveryRunStore;\n /** Queue for async MCP discovery run execution (optional — absent in non-MCP/test contexts). */\n discoveryRunQueue?: DiscoveryRunQueue;\n /** Persistence for async MCP profile runs (optional — absent in non-MCP/test contexts). */\n profileRuns?: ProfileRunStore;\n /** Queue for async MCP profile run execution (optional — absent in non-MCP/test contexts). */\n profileRunQueue?: ProfileRunQueue;\n /**\n * Legacy direct-token minting for opportunity accept redirects.\n * Prefer `mintConnectLink` for user-facing links.\n */\n mintConnectToken?: (userId: string, opportunityId: string) => Promise<string>;\n /** Mints (or reuses) a short connect link, snapshotting the greeting (optional — absent in non-MCP contexts). */\n mintConnectLink?: MintConnectLink;\n /** Frontend base URL for building profile links (e.g. https://index.network, optional). */\n frontendUrl?: string;\n /** API base URL for building opportunity accept links (e.g. https://protocol.index.network, optional). */\n apiBaseUrl?: string;\n /** Optional host-side error reporter for swallowed protocol/tool errors. */\n reportToolError?: (error: unknown, report: ToolErrorReport) => void;\n /**\n * Optional host-side per-principal MCP call throttle. Invoked once per MCP\n * tool dispatch (after identity resolves, before any DB work). When the\n * returned decision is `allowed: false`, the dispatch short-circuits with a\n * rate-limit error carrying `retryAfterSec`. Absent in chat/test contexts.\n */\n mcpRateLimiter?: (input: { userId: string; agentId?: string; toolName: string }) => Promise<{\n allowed: boolean;\n retryAfterSec?: number;\n limit?: number;\n scope?: 'tool' | 'principal';\n }>;\n /** Optional premise lifecycle event callbacks. Fired by premise tools after successful operations. */\n premiseEvents?: {\n onCreated?: (premiseId: string, userId: string) => void;\n onUpdated?: (premiseId: string, userId: string) => void;\n onRetracted?: (premiseId: string, userId: string) => void;\n };\n graphs: {\n profile: CompiledGraph;\n intent: CompiledGraph;\n index: CompiledGraph;\n networkMembership: CompiledGraph;\n intentIndex: CompiledGraph;\n opportunity: CompiledOpportunityGraph;\n premise: CompiledGraph;\n };\n /**\n * Optional network ranking override for `read_networks`. Injected by tests or custom compositions.\n * When absent, defaults to `NetworkRecommender.invoke()` with a lazy module-level singleton.\n */\n networkRanker?: (input: {\n userProfile: { bio: string; location: string; interests: string[]; skills: string[] };\n networks: Array<{ networkId: string; renderedContext: string }>;\n }) => Promise<{ rankedNetworkIds: string[] } | null>;\n}\n\n// ═══════════════════════════════════════════════════════════════════════════════\n// TOOL RESULT HELPERS\n// ═══════════════════════════════════════════════════════════════════════════════\n\nexport function success<T>(data: T): string {\n return JSON.stringify({ success: true, data });\n}\n\nexport function error(\n message: string,\n debugSteps?: Array<{ step: string; detail?: string; data?: Record<string, unknown> }>\n): string {\n return JSON.stringify({\n success: false,\n error: message,\n ...(debugSteps?.length ? { debugSteps } : {}),\n });\n}\n\n/** Return needsClarification for missing required fields. */\nexport function needsClarification(params: {\n missingFields: string[];\n message: string;\n}): string {\n return JSON.stringify({\n success: false,\n needsClarification: true,\n ...params,\n });\n}\n\n// ═══════════════════════════════════════════════════════════════════════════════\n// CONSTANTS & UTILITIES\n// ═══════════════════════════════════════════════════════════════════════════════\n\n/** Matches http/https URLs in text; captures full URL. */\nconst URL_IN_TEXT_REGEX = /https?:\\/\\/[^\\s\"'<>)\\]]+/gi;\n\n/**\n * Matches bare domain URLs without protocol (e.g. github.com/foo, www.example.com).\n * Requires at least a SLD.TLD pattern followed by optional path.\n * Negative lookbehind ensures we don't double-match URLs already caught by URL_IN_TEXT_REGEX.\n */\nconst BARE_URL_REGEX = /(?<!\\w:\\/\\/)(?<![/\\w])(?:www\\.)?[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.(?:com|org|net|io|dev|co|ai|app|xyz|me|info|gg|so|sh|cc|ly|fm|tv|to|tech|design|network|world|edu|gov|mil|int|us|uk|eu|de|fr|ca|au|jp|cn|in|br|nl|se|no|fi|dk|ch|at|be|it|es|pt|pl|cz|ru|kr|tw|hk|sg|nz|za|mx|ar|cl|id|ph|th|vn|my|ie)(?:\\/[^\\s\"'<>)\\]]*)?/gi;\n\n/** UUID v4 format: 8-4-4-4-12 hex chars (e.g. c2505011-2e45-426e-81dd-b9abb9b72023) */\nexport const UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n\n/**\n * Resolves an array of network IDs to their display titles.\n * Skips any IDs that don't resolve (deleted or invalid networks).\n */\nexport async function resolveIndexNames(\n database: { getNetwork(id: string): Promise<{ id: string; title: string } | null> },\n networkIds: string[]\n): Promise<string[]> {\n if (networkIds.length === 0) return [];\n const results = await Promise.all(\n networkIds.map(id => database.getNetwork(id))\n );\n return results.filter(Boolean).map(idx => idx!.title);\n}\n\n/**\n * Normalize a URL string: if it lacks a protocol, prepend \"https://\".\n * Returns the normalized URL or null if the result is not a valid URL.\n */\nexport function normalizeUrl(raw: string): string | null {\n let url = raw.replace(/[.,;:!?)]+$/, \"\").trim();\n if (!/^https?:\\/\\//i.test(url)) {\n url = `https://${url}`;\n }\n try {\n new URL(url);\n return url;\n } catch {\n return null;\n }\n}\n\n/**\n * Extract unique, valid URLs from a string (e.g. user message or details).\n * Handles both full URLs (https://...) and bare domains (github.com/...).\n */\nexport function extractUrls(text: string): string[] {\n if (!text || typeof text !== \"string\") return [];\n\n const seen = new Set<string>();\n const out: string[] = [];\n\n // Pass 1: full protocol URLs\n const fullMatches = text.match(URL_IN_TEXT_REGEX) ?? [];\n for (const raw of fullMatches) {\n const url = normalizeUrl(raw);\n if (url && !seen.has(url)) {\n seen.add(url);\n out.push(url);\n }\n }\n\n // Pass 2: bare domain URLs (e.g. github.com/foo)\n const bareMatches = text.match(BARE_URL_REGEX) ?? [];\n for (const raw of bareMatches) {\n const url = normalizeUrl(raw);\n if (url && !seen.has(url)) {\n seen.add(url);\n out.push(url);\n }\n }\n\n return out;\n}\n\nconst SENSITIVE_FIELD_KEYS = new Set([\n \"secret\",\n \"webhooksecret\",\n \"password\",\n \"apikey\",\n \"token\",\n \"accesstoken\",\n \"refreshtoken\",\n \"privatekey\",\n \"authtoken\",\n \"bearertoken\",\n \"clientsecret\",\n]);\n\n/**\n * Recursively redacts sensitive field values from an arbitrary payload before\n * it is passed to a structured logger. Matches field names case-insensitively\n * and ignoring underscores, so `api_key`, `apiKey`, and `API_KEY` all match.\n * Non-sensitive fields are passed through unchanged. Never mutates the input —\n * returns a new value.\n *\n * Intended for structured-log redaction only. Do NOT use as a security\n * boundary for data in motion.\n *\n * @param value - Arbitrary JSON-like payload (query object, config blob, etc.)\n * @returns A new value with sensitive fields replaced by `\"[redacted]\"`.\n */\nexport function redactSensitiveFields(value: unknown): unknown {\n if (value === null || typeof value !== \"object\") return value;\n if (Array.isArray(value)) {\n return value.map((item) => redactSensitiveFields(item));\n }\n const out: Record<string, unknown> = {};\n for (const [key, inner] of Object.entries(value as Record<string, unknown>)) {\n const normalized = key.toLowerCase().replace(/_/g, \"\");\n if (SENSITIVE_FIELD_KEYS.has(normalized)) {\n out[key] = \"[redacted]\";\n } else {\n out[key] = redactSensitiveFields(inner);\n }\n }\n return out;\n}\n"]}
|