@indexnetwork/protocol 8.3.0-rc.424.1 → 8.4.0-rc.426.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/IMPLEMENTATION.md +2 -2
- package/dist/capabilities/opportunities.facade.d.ts +5 -5
- package/dist/capabilities/opportunities.facade.js +4 -4
- package/dist/index.d.ts +6 -6
- package/dist/index.js +4 -4
- package/dist/maintenance/maintenance.graph.d.ts +9 -9
- package/dist/maintenance/maintenance.graph.js +20 -20
- package/dist/maintenance/maintenance.state.d.ts +5 -5
- package/dist/maintenance/maintenance.state.js +3 -3
- package/dist/opportunity/application/delivery-card.cache.js +1 -1
- package/dist/opportunity/application/index.d.ts +2 -3
- package/dist/opportunity/application/index.js +3 -4
- package/dist/opportunity/application/negotiation-context.loader.d.ts +1 -1
- package/dist/opportunity/application/negotiation-context.loader.js +1 -1
- package/dist/opportunity/application/opportunity.enricher.js +2 -2
- package/dist/opportunity/application/opportunity.presenter.d.ts +15 -15
- package/dist/opportunity/application/opportunity.presenter.js +17 -17
- package/dist/opportunity/application/opportunity.tools.d.ts +1 -1
- package/dist/opportunity/application/opportunity.tools.js +3 -3
- package/dist/opportunity/discriminator/discriminator.adjustments.js +1 -1
- package/dist/opportunity/discriminator/discriminator.env.d.ts +1 -1
- package/dist/opportunity/discriminator/discriminator.env.js +1 -1
- package/dist/opportunity/domain/index.d.ts +3 -3
- package/dist/opportunity/domain/index.js +3 -3
- package/dist/opportunity/domain/opportunity.presentation-cache.d.ts +1 -2
- package/dist/opportunity/domain/opportunity.presentation-cache.js +2 -5
- package/dist/opportunity/domain/opportunity.presentation.d.ts +1 -1
- package/dist/opportunity/domain/opportunity.presentation.js +1 -1
- package/dist/opportunity/domain/opportunity.safe-presentation.d.ts +2 -2
- package/dist/opportunity/domain/opportunity.safe-presentation.js +1 -1
- package/dist/opportunity/domain/opportunity.utils.d.ts +5 -5
- package/dist/opportunity/domain/opportunity.utils.js +8 -8
- package/dist/opportunity/index.d.ts +1 -1
- package/dist/opportunity/index.js +1 -1
- package/dist/opportunity/opportunity.presenter.d.ts +3 -3
- package/dist/opportunity/opportunity.presenter.js +2 -2
- package/dist/opportunity/public/index.d.ts +5 -5
- package/dist/opportunity/public/index.js +6 -6
- package/dist/opportunity/{feed/feed.graph.d.ts → radar/radar.graph.d.ts} +42 -73
- package/dist/opportunity/{feed/feed.graph.js → radar/radar.graph.js} +60 -222
- package/dist/opportunity/{feed/feed.health.d.ts → radar/radar.health.d.ts} +7 -7
- package/dist/opportunity/{feed/feed.health.js → radar/radar.health.js} +8 -8
- package/dist/opportunity/{feed/feed.state.d.ts → radar/radar.state.d.ts} +21 -47
- package/dist/opportunity/{feed/feed.state.js → radar/radar.state.js} +15 -24
- package/dist/shared/agent/tool.helpers.d.ts +1 -1
- package/dist/shared/interfaces/database.interface.d.ts +3 -3
- package/package.json +1 -1
- package/dist/opportunity/feed/feed.categorizer.d.ts +0 -27
- package/dist/opportunity/feed/feed.categorizer.js +0 -168
- package/dist/shared/ui/lucide.icon-catalog.d.ts +0 -21
- package/dist/shared/ui/lucide.icon-catalog.js +0 -100
|
@@ -25,7 +25,7 @@ import { stripUuids, stripIntroducerMentions } from "../domain/opportunity.prese
|
|
|
25
25
|
import { stripUnsupportedOpportunityClaims } from "../domain/opportunity.claim-safety.js";
|
|
26
26
|
import { DEFAULT_EMPTY_FALLBACK_TEXT, DEFAULT_FALLBACK_ACTION, DEFAULT_FALLBACK_HEADLINE, safeFallbackSummary } from "../domain/opportunity.safe-presentation.js";
|
|
27
27
|
const presentLog = protocolLogger("OpportunityPresenter:present");
|
|
28
|
-
const
|
|
28
|
+
const presentCardLog = protocolLogger("OpportunityPresenter:presentCard");
|
|
29
29
|
const LLM_TIMEOUT_MS = 20000;
|
|
30
30
|
const GREETING_DESCRIPTION = "A 2-4 sentence first-person message the viewer could send to the counterpart, in the viewer's voice, referencing what they have in common. Plain prose only — no markdown, no greeting prefix like 'Hey {Name},'. Example body: 'Saw we're both working on regenerative coordination tooling — your post on consent flows resonated. Would love to compare notes if you have time this week.'";
|
|
31
31
|
// ──────────────────────────────────────────────────────────────
|
|
@@ -44,8 +44,8 @@ const PresentationSchema = z.object({
|
|
|
44
44
|
const responseFormat = z.object({
|
|
45
45
|
presentation: PresentationSchema,
|
|
46
46
|
});
|
|
47
|
-
/** LLM-generated fields for
|
|
48
|
-
export const
|
|
47
|
+
/** LLM-generated fields for card presentation (buttons are hardcoded by callers, not LLM-generated). */
|
|
48
|
+
export const CardLLMSchema = z.object({
|
|
49
49
|
headline: z
|
|
50
50
|
.string()
|
|
51
51
|
.describe("Short, compelling headline for this opportunity"),
|
|
@@ -70,7 +70,7 @@ export const HomeCardLLMSchema = z.object({
|
|
|
70
70
|
greeting: z.string().max(500).describe(GREETING_DESCRIPTION),
|
|
71
71
|
});
|
|
72
72
|
const homeCardResponseFormat = z.object({
|
|
73
|
-
presentation:
|
|
73
|
+
presentation: CardLLMSchema,
|
|
74
74
|
});
|
|
75
75
|
// ──────────────────────────────────────────────────────────────
|
|
76
76
|
// SYSTEM PROMPT
|
|
@@ -127,7 +127,7 @@ When INTRODUCTION CONTEXT is provided, this opportunity was explicitly created b
|
|
|
127
127
|
- Suggested action: "Send an intro to connect" or "Start a conversation".
|
|
128
128
|
`;
|
|
129
129
|
const homeCardSystemPrompt = `
|
|
130
|
-
You are an expert at presenting connection opportunities for
|
|
130
|
+
You are an expert at presenting connection opportunities for an opportunity card.
|
|
131
131
|
|
|
132
132
|
Given context about the viewer, the other person, and why they were matched, produce:
|
|
133
133
|
1. headline: one short hook line.
|
|
@@ -307,14 +307,14 @@ Produce headline, personalizedSummary (2-3 sentences in "you" language), suggest
|
|
|
307
307
|
}
|
|
308
308
|
}
|
|
309
309
|
/**
|
|
310
|
-
* Generate LLM-powered
|
|
310
|
+
* Generate LLM-powered card content (headline, body, narrator remark, mutual-intent label).
|
|
311
311
|
* Callers append button labels from opportunity.constants.
|
|
312
312
|
*
|
|
313
313
|
* When `negotiationContext.status === 'negotiating'`, returns a templated
|
|
314
314
|
* chip synchronously without invoking the LLM — the card just reflects
|
|
315
315
|
* "negotiation in progress" at that point.
|
|
316
316
|
*/
|
|
317
|
-
async
|
|
317
|
+
async presentCard(input) {
|
|
318
318
|
if (input.negotiationContext?.status === 'negotiating') {
|
|
319
319
|
return buildNegotiatingChip(input);
|
|
320
320
|
}
|
|
@@ -393,7 +393,7 @@ Produce headline, personalizedSummary, digestSummary, suggestedAction, narratorR
|
|
|
393
393
|
catch (e) {
|
|
394
394
|
const message = e instanceof Error ? e.message : String(e);
|
|
395
395
|
const timeoutReason = message.includes("timed out") ? message : undefined;
|
|
396
|
-
|
|
396
|
+
presentCardLog.warn("LLM failed, returning fallback", {
|
|
397
397
|
event: "presenter_fallback",
|
|
398
398
|
presenter: "home_card",
|
|
399
399
|
reason: timeoutReason ? "timeout" : "parse_error",
|
|
@@ -437,15 +437,15 @@ Produce headline, personalizedSummary, digestSummary, suggestedAction, narratorR
|
|
|
437
437
|
return results;
|
|
438
438
|
}
|
|
439
439
|
/**
|
|
440
|
-
* Process multiple opportunities as
|
|
441
|
-
* Returns full
|
|
440
|
+
* Process multiple opportunities as cards in parallel with bounded concurrency.
|
|
441
|
+
* Returns full card display contracts (headline, body, narrator remark, action labels, mutual-intent label).
|
|
442
442
|
*/
|
|
443
|
-
async
|
|
443
|
+
async presentCardBatch(inputs, options) {
|
|
444
444
|
const concurrency = options?.concurrency ?? 5;
|
|
445
445
|
const results = [];
|
|
446
446
|
for (let i = 0; i < inputs.length; i += concurrency) {
|
|
447
447
|
const chunk = inputs.slice(i, i + concurrency);
|
|
448
|
-
const chunkResults = await Promise.all(chunk.map((inp) => this.
|
|
448
|
+
const chunkResults = await Promise.all(chunk.map((inp) => this.presentCard(inp)));
|
|
449
449
|
results.push(...chunkResults);
|
|
450
450
|
}
|
|
451
451
|
return results;
|
|
@@ -462,7 +462,7 @@ __decorate([
|
|
|
462
462
|
__metadata("design:type", Function),
|
|
463
463
|
__metadata("design:paramtypes", [Object]),
|
|
464
464
|
__metadata("design:returntype", Promise)
|
|
465
|
-
], OpportunityPresenter.prototype, "
|
|
465
|
+
], OpportunityPresenter.prototype, "presentCard", null);
|
|
466
466
|
__decorate([
|
|
467
467
|
Timed(),
|
|
468
468
|
__metadata("design:type", Function),
|
|
@@ -474,12 +474,12 @@ __decorate([
|
|
|
474
474
|
__metadata("design:type", Function),
|
|
475
475
|
__metadata("design:paramtypes", [Array, Object]),
|
|
476
476
|
__metadata("design:returntype", Promise)
|
|
477
|
-
], OpportunityPresenter.prototype, "
|
|
477
|
+
], OpportunityPresenter.prototype, "presentCardBatch", null);
|
|
478
478
|
// ──────────────────────────────────────────────────────────────
|
|
479
479
|
// NEGOTIATION CONTEXT HELPERS
|
|
480
480
|
// ──────────────────────────────────────────────────────────────
|
|
481
481
|
/**
|
|
482
|
-
* Builds a "NEGOTIATION CONTEXT:" block for the
|
|
482
|
+
* Builds a "NEGOTIATION CONTEXT:" block for the card prompt. Returns an
|
|
483
483
|
* empty string when the opportunity has no meaningful negotiation context
|
|
484
484
|
* (draft/latent) or when the opportunity is still negotiating (handled via
|
|
485
485
|
* the templated chip, not the LLM).
|
|
@@ -513,7 +513,7 @@ ${turnLines.length > 0 ? turnLines.map((l) => ` ${l}`).join("\n") : " (no turn
|
|
|
513
513
|
`;
|
|
514
514
|
}
|
|
515
515
|
/**
|
|
516
|
-
* Builds a templated
|
|
516
|
+
* Builds a templated card result for an opportunity whose negotiation
|
|
517
517
|
* is still in progress. Bypasses the LLM so users see a stable "currently
|
|
518
518
|
* negotiating" chip while turns are still being exchanged.
|
|
519
519
|
*/
|
|
@@ -554,7 +554,7 @@ export function summarizeSignalsForPresenter(signals) {
|
|
|
554
554
|
* Gather all context needed for the presenter from the database.
|
|
555
555
|
* Fetches viewer profile, viewer intents, other party profile(s), and index in parallel.
|
|
556
556
|
*
|
|
557
|
-
* @param displayCounterpartUserId - When set (e.g. for
|
|
557
|
+
* @param displayCounterpartUserId - When set (e.g. for a radar card), only this counterpart is included in otherPartyContext so the presenter writes about the person on the card. Omitted for introducer view (card shows both parties).
|
|
558
558
|
*/
|
|
559
559
|
export async function gatherPresenterContext(database, opportunity, viewerId, displayCounterpartUserId) {
|
|
560
560
|
const myActor = opportunity.actors.find((a) => a.userId === viewerId);
|
|
@@ -84,7 +84,7 @@ export declare function attachActionableLinks(card: Record<string, unknown> & {
|
|
|
84
84
|
*
|
|
85
85
|
* Note: narratorChip.text is generated via regex heuristics (narratorRemarkFromReasoning)
|
|
86
86
|
* rather than the OpportunityPresenter LLM. If narrator quality becomes an issue again,
|
|
87
|
-
* consider making this function async and delegating to OpportunityPresenter.
|
|
87
|
+
* consider making this function async and delegating to OpportunityPresenter.presentCard()
|
|
88
88
|
* which already produces a high-quality narratorRemark via LLM (used by the home graph
|
|
89
89
|
* and discovery pipeline). The trade-off is 5-20s latency per card.
|
|
90
90
|
*
|
|
@@ -228,7 +228,7 @@ const CHAT_DISPLAY_LIMIT = 6;
|
|
|
228
228
|
*
|
|
229
229
|
* Note: narratorChip.text is generated via regex heuristics (narratorRemarkFromReasoning)
|
|
230
230
|
* rather than the OpportunityPresenter LLM. If narrator quality becomes an issue again,
|
|
231
|
-
* consider making this function async and delegating to OpportunityPresenter.
|
|
231
|
+
* consider making this function async and delegating to OpportunityPresenter.presentCard()
|
|
232
232
|
* which already produces a high-quality narratorRemark via LLM (used by the home graph
|
|
233
233
|
* and discovery pipeline). The trade-off is 5-20s latency per card.
|
|
234
234
|
*
|
|
@@ -504,7 +504,7 @@ export function createOpportunityTools(defineTool, deps) {
|
|
|
504
504
|
gatherOpportunityPresenterContext(presenterDb, opp, context.userId, counterpartUserId),
|
|
505
505
|
loadNegotiationContext(deps.negotiationDatabase, opp.id, opp.status),
|
|
506
506
|
]);
|
|
507
|
-
const presentation = await presenter.
|
|
507
|
+
const presentation = await presenter.presentCard({
|
|
508
508
|
...ctx,
|
|
509
509
|
opportunityStatus: opp.status,
|
|
510
510
|
...(negotiationContext ? { negotiationContext } : {}),
|
|
@@ -658,7 +658,7 @@ export function createOpportunityTools(defineTool, deps) {
|
|
|
658
658
|
gatherOpportunityPresenterContext(presenterDb, opp, context.userId, counterpartUserId),
|
|
659
659
|
loadNegotiationContext(deps.negotiationDatabase, opp.id, opp.status),
|
|
660
660
|
]);
|
|
661
|
-
const presentation = await presenter.
|
|
661
|
+
const presentation = await presenter.presentCard({
|
|
662
662
|
...ctx,
|
|
663
663
|
opportunityStatus: opp.status,
|
|
664
664
|
...(negotiationContext ? { negotiationContext } : {}),
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* When a user answers a pool_discovery question, every candidate the mining
|
|
5
5
|
* pass assigned to a side gets a multiplicative adjustment written to
|
|
6
|
-
* `opportunities.metadata.poolAdjustments`. The
|
|
6
|
+
* `opportunities.metadata.poolAdjustments`. The radar view (flag-gated) orders
|
|
7
7
|
* by `confidence × Π factor`, floored so demoted candidates stay visible.
|
|
8
8
|
*
|
|
9
9
|
* Invariants:
|
|
@@ -76,7 +76,7 @@ export declare const POOL_QUESTION_PUSH_DAILY_CAP = 2;
|
|
|
76
76
|
/** Ranking mode for pool adjustments (IND-419). */
|
|
77
77
|
export type PoolQuestionsRankingMode = "off" | "on";
|
|
78
78
|
/**
|
|
79
|
-
* Current POOL_QUESTIONS_RANKING (default off). When "on", the
|
|
79
|
+
* Current POOL_QUESTIONS_RANKING (default off). When "on", the radar view
|
|
80
80
|
* orders by adjusted confidence (confidence × Π poolAdjustments.factor,
|
|
81
81
|
* floor {@link POOL_ADJUSTMENT_FLOOR}). Adjustments are WRITTEN regardless of
|
|
82
82
|
* this flag — it only gates whether ordering reads them, so the apply path
|
|
@@ -74,7 +74,7 @@ export const POOL_QUESTION_PUSH_MIN_POOL_SIZE = 8;
|
|
|
74
74
|
/** Maximum claimed proactive pool pushes per recipient per UTC day. */
|
|
75
75
|
export const POOL_QUESTION_PUSH_DAILY_CAP = 2;
|
|
76
76
|
/**
|
|
77
|
-
* Current POOL_QUESTIONS_RANKING (default off). When "on", the
|
|
77
|
+
* Current POOL_QUESTIONS_RANKING (default off). When "on", the radar view
|
|
78
78
|
* orders by adjusted confidence (confidence × Π poolAdjustments.factor,
|
|
79
79
|
* floor {@link POOL_ADJUSTMENT_FLOOR}). Adjustments are WRITTEN regardless of
|
|
80
80
|
* this flag — it only gates whether ordering reads them, so the apply path
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
* - discriminator/ — pool discriminator types, env, scorer, adjustments, question, push
|
|
21
21
|
* - negotiation-evidence/ — evidence types, env, extractor, verifier
|
|
22
22
|
* - outcome/ — outcome types, env, hypotheses
|
|
23
|
-
* -
|
|
23
|
+
* - radar/ — radar state schema, radar health scorer
|
|
24
24
|
*
|
|
25
25
|
* IND-551: canonical domain layer for the opportunities capability.
|
|
26
26
|
*/
|
|
@@ -49,5 +49,5 @@ export { verifyHypotheses } from "../negotiation-evidence/negotiation-evidence.v
|
|
|
49
49
|
export type { OutcomeLabel, OutcomeExample, OutcomeSideSupport, OutcomeHypothesis, OutcomeShadowResult, JoinOutcomeHypothesesInput, } from "../outcome/outcome.types.js";
|
|
50
50
|
export { isOutcomeQuestionsActivated, OUTCOME_MIN_INDEPENDENT_EXAMPLES, OUTCOME_MAX_CANDIDATES, OUTCOME_MAX_PUBLIC_CONTEXT_CHARS, } from "../outcome/outcome.env.js";
|
|
51
51
|
export { joinOutcomeHypotheses } from "../outcome/outcome.hypotheses.js";
|
|
52
|
-
export {
|
|
53
|
-
export type {
|
|
52
|
+
export { computeRadarHealth } from "../radar/radar.health.js";
|
|
53
|
+
export type { RadarHealthResult } from "../radar/radar.health.js";
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
* - discriminator/ — pool discriminator types, env, scorer, adjustments, question, push
|
|
21
21
|
* - negotiation-evidence/ — evidence types, env, extractor, verifier
|
|
22
22
|
* - outcome/ — outcome types, env, hypotheses
|
|
23
|
-
* -
|
|
23
|
+
* - radar/ — radar state schema, radar health scorer
|
|
24
24
|
*
|
|
25
25
|
* IND-551: canonical domain layer for the opportunities capability.
|
|
26
26
|
*/
|
|
@@ -46,5 +46,5 @@ export { extractAllowlistedEvidence } from "../negotiation-evidence/negotiation-
|
|
|
46
46
|
export { verifyHypotheses } from "../negotiation-evidence/negotiation-evidence.verifier.js";
|
|
47
47
|
export { isOutcomeQuestionsActivated, OUTCOME_MIN_INDEPENDENT_EXAMPLES, OUTCOME_MAX_CANDIDATES, OUTCOME_MAX_PUBLIC_CONTEXT_CHARS, } from "../outcome/outcome.env.js";
|
|
48
48
|
export { joinOutcomeHypotheses } from "../outcome/outcome.hypotheses.js";
|
|
49
|
-
//
|
|
50
|
-
export {
|
|
49
|
+
// radar domain
|
|
50
|
+
export { computeRadarHealth } from "../radar/radar.health.js";
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
/** Cache namespace for opportunity presentation copy. Bump to invalidate copy safety changes. */
|
|
2
2
|
export declare const OPPORTUNITY_PRESENTATION_CACHE_VERSION = "v2";
|
|
3
|
-
export declare function
|
|
4
|
-
export declare function buildHomeCategoryPresentationCacheKey(viewerId: string, opportunitySetHash: string): string;
|
|
3
|
+
export declare function buildRadarCardPresentationCacheKey(opportunityId: string, status: string, viewerId: string): string;
|
|
5
4
|
export declare function buildDeliveryCardPresentationCacheKey(opportunityId: string, status: string, viewerId: string): string;
|
|
6
5
|
export declare function buildApiChatCardPresentationCacheKey(opportunityId: string, viewerId: string): string;
|
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
/** Cache namespace for opportunity presentation copy. Bump to invalidate copy safety changes. */
|
|
2
2
|
export const OPPORTUNITY_PRESENTATION_CACHE_VERSION = "v2";
|
|
3
|
-
export function
|
|
4
|
-
return `
|
|
5
|
-
}
|
|
6
|
-
export function buildHomeCategoryPresentationCacheKey(viewerId, opportunitySetHash) {
|
|
7
|
-
return `home:${OPPORTUNITY_PRESENTATION_CACHE_VERSION}:categories:${viewerId}:${opportunitySetHash}`;
|
|
3
|
+
export function buildRadarCardPresentationCacheKey(opportunityId, status, viewerId) {
|
|
4
|
+
return `radar:${OPPORTUNITY_PRESENTATION_CACHE_VERSION}:card:${opportunityId}:${status}:${viewerId}`;
|
|
8
5
|
}
|
|
9
6
|
export function buildDeliveryCardPresentationCacheKey(opportunityId, status, viewerId) {
|
|
10
7
|
return `delivery:${OPPORTUNITY_PRESENTATION_CACHE_VERSION}:card:${opportunityId}:${status}:${viewerId}`;
|
|
@@ -63,7 +63,7 @@ export declare function viewerCentricCardSummary(reasoning: string, counterpartN
|
|
|
63
63
|
* Extracts domain keywords (e.g. "AI", "design", "machine learning") from the
|
|
64
64
|
* reasoning and frames them in a short template like "Shared interest in AI and design."
|
|
65
65
|
*
|
|
66
|
-
* This is a regex-based heuristic — an alternative is OpportunityPresenter.
|
|
66
|
+
* This is a regex-based heuristic — an alternative is OpportunityPresenter.presentCard()
|
|
67
67
|
* which generates narratorRemark via LLM with much higher quality (already used by
|
|
68
68
|
* home.graph.ts and opportunity.discover.ts). See buildMinimalOpportunityCard() in
|
|
69
69
|
* opportunity.tools.ts for the trade-off discussion.
|
|
@@ -318,7 +318,7 @@ const FALLBACK_REMARK = "A potential connection worth exploring.";
|
|
|
318
318
|
* Extracts domain keywords (e.g. "AI", "design", "machine learning") from the
|
|
319
319
|
* reasoning and frames them in a short template like "Shared interest in AI and design."
|
|
320
320
|
*
|
|
321
|
-
* This is a regex-based heuristic — an alternative is OpportunityPresenter.
|
|
321
|
+
* This is a regex-based heuristic — an alternative is OpportunityPresenter.presentCard()
|
|
322
322
|
* which generates narratorRemark via LLM with much higher quality (already used by
|
|
323
323
|
* home.graph.ts and opportunity.discover.ts). See buildMinimalOpportunityCard() in
|
|
324
324
|
* opportunity.tools.ts for the trade-off discussion.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Shared safe-presentation primitive for all user-facing opportunity surfaces.
|
|
3
3
|
*
|
|
4
|
-
* Historically every surface (
|
|
4
|
+
* Historically every surface (radar, list/discover cards, minimal chat
|
|
5
5
|
* cards, notification emails/Telegram, chat context, delivery cards) invented
|
|
6
6
|
* its own fallback chain for the case where genuine LLM presenter output is
|
|
7
7
|
* unavailable — some sliced raw `interpretation.reasoning` with no
|
|
@@ -52,7 +52,7 @@ export interface SafeFallbackOptions {
|
|
|
52
52
|
* @param opts - Per-surface knobs (names for rewrite, max length, empty-text copy).
|
|
53
53
|
*/
|
|
54
54
|
export declare function safeFallbackSummary(rawReasoning: string | null | undefined, opts?: SafeFallbackOptions): string;
|
|
55
|
-
/** Minimal presenter-output shape the primitive inspects (subset of
|
|
55
|
+
/** Minimal presenter-output shape the primitive inspects (subset of CardPresentationResult). */
|
|
56
56
|
export interface SafePresentationCandidate {
|
|
57
57
|
headline?: string;
|
|
58
58
|
personalizedSummary?: string;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Shared safe-presentation primitive for all user-facing opportunity surfaces.
|
|
3
3
|
*
|
|
4
|
-
* Historically every surface (
|
|
4
|
+
* Historically every surface (radar, list/discover cards, minimal chat
|
|
5
5
|
* cards, notification emails/Telegram, chat context, delivery cards) invented
|
|
6
6
|
* its own fallback chain for the case where genuine LLM presenter output is
|
|
7
7
|
* unavailable — some sliced raw `interpretation.reasoning` with no
|
|
@@ -56,7 +56,7 @@ export declare function validateOpportunityActors(actors: Array<{
|
|
|
56
56
|
* viewing an accepted opportunity).
|
|
57
57
|
*
|
|
58
58
|
* The feed graph and debug controller chain both predicates: an opportunity only
|
|
59
|
-
* reaches the
|
|
59
|
+
* reaches the radar view if it passes `canUserSeeOpportunity` first, then
|
|
60
60
|
* `isActionableForViewer`. For `agent with introducer at pending`,
|
|
61
61
|
* `canUserSeeOpportunity` returns false (read gate blocks it), so the opportunity
|
|
62
62
|
* never surfaces even though `isActionableForViewer` Rule 4 would return true in
|
|
@@ -73,7 +73,7 @@ export declare function canUserSeeOpportunity(actors: Array<{
|
|
|
73
73
|
role: string;
|
|
74
74
|
}>, status: string, userId: string): boolean;
|
|
75
75
|
/**
|
|
76
|
-
* Whether an opportunity should appear on the viewer's
|
|
76
|
+
* Whether an opportunity should appear on the viewer's radar (actionable =
|
|
77
77
|
* has a pending action for this user).
|
|
78
78
|
*
|
|
79
79
|
* Rules (see `docs/design/opportunity-status-lifecycle.md`, §3.E):
|
|
@@ -101,8 +101,8 @@ export declare function isActionableForViewer(actors: Array<{
|
|
|
101
101
|
}>, status: string, viewerId: string): boolean;
|
|
102
102
|
/** Feed category for home composition. */
|
|
103
103
|
export type FeedCategory = 'connection' | 'connector-flow' | 'expired';
|
|
104
|
-
/** Soft targets for
|
|
105
|
-
export declare const
|
|
104
|
+
/** Soft targets for radar composition. */
|
|
105
|
+
export declare const RADAR_SOFT_TARGETS: {
|
|
106
106
|
readonly connection: 3;
|
|
107
107
|
readonly connectorFlow: 2;
|
|
108
108
|
readonly expired: 2;
|
|
@@ -123,7 +123,7 @@ export declare function classifyOpportunity(opp: {
|
|
|
123
123
|
status: string;
|
|
124
124
|
}, viewerId: string): FeedCategory;
|
|
125
125
|
/**
|
|
126
|
-
* Select opportunities for the
|
|
126
|
+
* Select opportunities for the radar using soft composition targets.
|
|
127
127
|
* Fills each category up to its target, then redistributes unused slots
|
|
128
128
|
* to categories that have more items available. Preserves input order.
|
|
129
129
|
*
|
|
@@ -85,7 +85,7 @@ export function validateOpportunityActors(actors) {
|
|
|
85
85
|
* viewing an accepted opportunity).
|
|
86
86
|
*
|
|
87
87
|
* The feed graph and debug controller chain both predicates: an opportunity only
|
|
88
|
-
* reaches the
|
|
88
|
+
* reaches the radar view if it passes `canUserSeeOpportunity` first, then
|
|
89
89
|
* `isActionableForViewer`. For `agent with introducer at pending`,
|
|
90
90
|
* `canUserSeeOpportunity` returns false (read gate blocks it), so the opportunity
|
|
91
91
|
* never surfaces even though `isActionableForViewer` Rule 4 would return true in
|
|
@@ -116,7 +116,7 @@ export function canUserSeeOpportunity(actors, status, userId) {
|
|
|
116
116
|
});
|
|
117
117
|
}
|
|
118
118
|
/**
|
|
119
|
-
* Whether an opportunity should appear on the viewer's
|
|
119
|
+
* Whether an opportunity should appear on the viewer's radar (actionable =
|
|
120
120
|
* has a pending action for this user).
|
|
121
121
|
*
|
|
122
122
|
* Rules (see `docs/design/opportunity-status-lifecycle.md`, §3.E):
|
|
@@ -168,8 +168,8 @@ export function isActionableForViewer(actors, status, viewerId) {
|
|
|
168
168
|
return false;
|
|
169
169
|
});
|
|
170
170
|
}
|
|
171
|
-
/** Soft targets for
|
|
172
|
-
export const
|
|
171
|
+
/** Soft targets for radar composition. */
|
|
172
|
+
export const RADAR_SOFT_TARGETS = {
|
|
173
173
|
connection: 3,
|
|
174
174
|
connectorFlow: 2,
|
|
175
175
|
expired: 2,
|
|
@@ -191,7 +191,7 @@ export function classifyOpportunity(opp, viewerId) {
|
|
|
191
191
|
return 'connection';
|
|
192
192
|
}
|
|
193
193
|
/**
|
|
194
|
-
* Select opportunities for the
|
|
194
|
+
* Select opportunities for the radar using soft composition targets.
|
|
195
195
|
* Fills each category up to its target, then redistributes unused slots
|
|
196
196
|
* to categories that have more items available. Preserves input order.
|
|
197
197
|
*
|
|
@@ -210,9 +210,9 @@ export function selectByComposition(opportunities, viewerId) {
|
|
|
210
210
|
buckets[category].push(opp);
|
|
211
211
|
}
|
|
212
212
|
const targets = {
|
|
213
|
-
connection:
|
|
214
|
-
'connector-flow':
|
|
215
|
-
expired:
|
|
213
|
+
connection: RADAR_SOFT_TARGETS.connection,
|
|
214
|
+
'connector-flow': RADAR_SOFT_TARGETS.connectorFlow,
|
|
215
|
+
expired: RADAR_SOFT_TARGETS.expired,
|
|
216
216
|
};
|
|
217
217
|
// First pass: fill each category up to its target
|
|
218
218
|
const selected = {
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
* - discriminator/ — pool question mining, scoring, assignment
|
|
25
25
|
* - negotiation-evidence/ — Lens C evidence extraction and mining
|
|
26
26
|
* - outcome/ — Lens B outcome hypothesis mining
|
|
27
|
-
* -
|
|
27
|
+
* - radar/ — radar graph (flat presenter-card list) and radar health
|
|
28
28
|
*
|
|
29
29
|
* ## Legacy paths (thin inward shims)
|
|
30
30
|
* The following old flat-file paths are preserved as thin re-export shims for
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
* - discriminator/ — pool question mining, scoring, assignment
|
|
25
25
|
* - negotiation-evidence/ — Lens C evidence extraction and mining
|
|
26
26
|
* - outcome/ — Lens B outcome hypothesis mining
|
|
27
|
-
* -
|
|
27
|
+
* - radar/ — radar graph (flat presenter-card list) and radar health
|
|
28
28
|
*
|
|
29
29
|
* ## Legacy paths (thin inward shims)
|
|
30
30
|
* The following old flat-file paths are preserved as thin re-export shims for
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
* Explicit named re-exports are required in addition to export * because
|
|
6
6
|
* some Bun ESM environments do not surface class and function exports
|
|
7
7
|
* through a star re-export chain when the module is loaded indirectly
|
|
8
|
-
* (e.g.
|
|
8
|
+
* (e.g. radar/radar.graph.ts → ../opportunity.presenter.js → application/).
|
|
9
9
|
*/
|
|
10
10
|
export * from "./application/opportunity.presenter.js";
|
|
11
|
-
export { OpportunityPresenter, summarizeSignalsForPresenter, gatherPresenterContext,
|
|
12
|
-
export type { PresenterDatabase, OpportunityPresentationResult,
|
|
11
|
+
export { OpportunityPresenter, summarizeSignalsForPresenter, gatherPresenterContext, CardLLMSchema } from "./application/opportunity.presenter.js";
|
|
12
|
+
export type { PresenterDatabase, OpportunityPresentationResult, CardPresenterInput, CardLLMResult, CardPresentationResult, PresenterInput } from "./application/opportunity.presenter.js";
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
* Explicit named re-exports are required in addition to export * because
|
|
6
6
|
* some Bun ESM environments do not surface class and function exports
|
|
7
7
|
* through a star re-export chain when the module is loaded indirectly
|
|
8
|
-
* (e.g.
|
|
8
|
+
* (e.g. radar/radar.graph.ts → ../opportunity.presenter.js → application/).
|
|
9
9
|
*/
|
|
10
10
|
export * from "./application/opportunity.presenter.js";
|
|
11
11
|
// Value exports that must be explicitly named for Bun ESM shim compatibility.
|
|
12
|
-
export { OpportunityPresenter, summarizeSignalsForPresenter, gatherPresenterContext,
|
|
12
|
+
export { OpportunityPresenter, summarizeSignalsForPresenter, gatherPresenterContext, CardLLMSchema } from "./application/opportunity.presenter.js";
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
export { OpportunityGraphState, } from "../domain/opportunity.state.js";
|
|
11
11
|
export type { SourceProfileData, IndexedIntent, TargetNetwork, CandidateMatch, EvaluatedCandidate, EvaluatedOpportunityActor, EvaluatedOpportunity, OpportunityPersistenceOutcome, OpportunityGraphOptions, } from "../domain/opportunity.state.js";
|
|
12
12
|
export { MINIMAL_MAIN_TEXT_MAX_CHARS, PRIMARY_ACTION_LABEL_INTRODUCER, PRIMARY_ACTION_LABEL_DEFAULT, SECONDARY_ACTION_LABEL, getPrimaryActionLabel, } from "../domain/opportunity.labels.js";
|
|
13
|
-
export { deriveRolesFromCorpus, validateOpportunityActors, canUserSeeOpportunity, isActionableForViewer, classifyOpportunity, selectByComposition, deduplicateByPerson, selectDigestCandidates,
|
|
13
|
+
export { deriveRolesFromCorpus, validateOpportunityActors, canUserSeeOpportunity, isActionableForViewer, classifyOpportunity, selectByComposition, deduplicateByPerson, selectDigestCandidates, RADAR_SOFT_TARGETS, DIGEST_REDELIVERY_COOLDOWN_DAYS, } from "../domain/opportunity.utils.js";
|
|
14
14
|
export type { OpportunityActorRole, DerivedRoles, FeedCategory, DigestDeliveredRow, } from "../domain/opportunity.utils.js";
|
|
15
15
|
export { normalizeOpportunityActorIntent, resolveOpportunityActorIntent, normalizeOpportunityActors, normalizeCreateOpportunityActorIntents, } from "../domain/opportunity.actor.js";
|
|
16
16
|
export { buildCandidateEvidence, mergeOpportunityEvidence, withCandidateEvidence, withMatchedStrategies, renderOpportunityEvidenceForPrompt, } from "../domain/opportunity.evidence.js";
|
|
@@ -19,7 +19,7 @@ export { hasUnsupportedOpportunityClaim, isUnsupportedOpportunityClaimSentence,
|
|
|
19
19
|
export { presentOpportunity, stripUuids, truncateAtBoundary, viewerCentricCardSummary, narratorRemarkFromReasoning, stripIntroducerMentions, } from "../domain/opportunity.presentation.js";
|
|
20
20
|
export type { OpportunityPresentation, UserInfo, } from "../domain/opportunity.presentation.js";
|
|
21
21
|
export { safeFallbackSummary, SAFE_FALLBACK_MAX_CHARS, DEFAULT_EMPTY_FALLBACK_TEXT, } from "../domain/opportunity.safe-presentation.js";
|
|
22
|
-
export { OPPORTUNITY_PRESENTATION_CACHE_VERSION,
|
|
22
|
+
export { OPPORTUNITY_PRESENTATION_CACHE_VERSION, buildRadarCardPresentationCacheKey, buildDeliveryCardPresentationCacheKey, buildApiChatCardPresentationCacheKey, } from "../domain/opportunity.presentation-cache.js";
|
|
23
23
|
export { buildDiscoverySummary, toDiscoveryNegotiation, } from "../domain/negotiation-summary.builder.js";
|
|
24
24
|
export type { NegotiationResolution } from "../domain/negotiation-summary.builder.js";
|
|
25
25
|
export type { PoolCandidate, DiscriminatorMiningInput, MinedDiscriminator, ScoredDiscriminator, DiscriminatorShadowResult, } from "../discriminator/discriminator.types.js";
|
|
@@ -34,8 +34,8 @@ export type { RawEvidenceTurn, RawEvidenceOutcome, RawEvidenceOwnerAnswer, RawEv
|
|
|
34
34
|
export { negotiationEvidenceQuestionsMode, NEGOTIATION_EVIDENCE_MAX_OPPORTUNITIES, } from "../negotiation-evidence/negotiation-evidence.env.js";
|
|
35
35
|
export type { OutcomeLabel, OutcomeExample, OutcomeShadowResult, } from "../outcome/outcome.types.js";
|
|
36
36
|
export { isOutcomeQuestionsActivated, OUTCOME_MIN_INDEPENDENT_EXAMPLES, OUTCOME_MAX_CANDIDATES, OUTCOME_MAX_PUBLIC_CONTEXT_CHARS, } from "../outcome/outcome.env.js";
|
|
37
|
-
export {
|
|
38
|
-
export type {
|
|
37
|
+
export { computeRadarHealth } from "../radar/radar.health.js";
|
|
38
|
+
export type { RadarHealthInput } from "../radar/radar.health.js";
|
|
39
39
|
export { isIntroducerDiscoveryEnabled } from "../application/opportunity.introducer-feature.js";
|
|
40
40
|
export { OpportunityGraphFactory } from "../application/opportunity.graph.js";
|
|
41
41
|
export type { StampNewbornOpportunitiesFn, StampNewbornOpportunitiesInput, } from "../application/opportunity.newborn-stamping.js";
|
|
@@ -55,6 +55,6 @@ export { runPoolDiscriminatorShadow } from "../discriminator/discriminator.shado
|
|
|
55
55
|
export { NegotiationEvidenceMiner } from "../negotiation-evidence/negotiation-evidence.miner.js";
|
|
56
56
|
export { runNegotiationEvidenceShadow } from "../negotiation-evidence/negotiation-evidence.shadow.js";
|
|
57
57
|
export { runOutcomeShadow } from "../outcome/outcome.shadow.js";
|
|
58
|
-
export {
|
|
58
|
+
export { RadarGraphFactory } from "../radar/radar.graph.js";
|
|
59
59
|
export { createOpportunityTools } from "../application/opportunity.tools.js";
|
|
60
60
|
export type { OpportunityToolDeps } from "../ports/index.js";
|
|
@@ -12,13 +12,13 @@ export {
|
|
|
12
12
|
// state
|
|
13
13
|
OpportunityGraphState, } from "../domain/opportunity.state.js";
|
|
14
14
|
export { MINIMAL_MAIN_TEXT_MAX_CHARS, PRIMARY_ACTION_LABEL_INTRODUCER, PRIMARY_ACTION_LABEL_DEFAULT, SECONDARY_ACTION_LABEL, getPrimaryActionLabel, } from "../domain/opportunity.labels.js";
|
|
15
|
-
export { deriveRolesFromCorpus, validateOpportunityActors, canUserSeeOpportunity, isActionableForViewer, classifyOpportunity, selectByComposition, deduplicateByPerson, selectDigestCandidates,
|
|
15
|
+
export { deriveRolesFromCorpus, validateOpportunityActors, canUserSeeOpportunity, isActionableForViewer, classifyOpportunity, selectByComposition, deduplicateByPerson, selectDigestCandidates, RADAR_SOFT_TARGETS, DIGEST_REDELIVERY_COOLDOWN_DAYS, } from "../domain/opportunity.utils.js";
|
|
16
16
|
export { normalizeOpportunityActorIntent, resolveOpportunityActorIntent, normalizeOpportunityActors, normalizeCreateOpportunityActorIntents, } from "../domain/opportunity.actor.js";
|
|
17
17
|
export { buildCandidateEvidence, mergeOpportunityEvidence, withCandidateEvidence, withMatchedStrategies, renderOpportunityEvidenceForPrompt, } from "../domain/opportunity.evidence.js";
|
|
18
18
|
export { hasUnsupportedOpportunityClaim, isUnsupportedOpportunityClaimSentence, stripUnsupportedOpportunityClaims, } from "../domain/opportunity.claim-safety.js";
|
|
19
19
|
export { presentOpportunity, stripUuids, truncateAtBoundary, viewerCentricCardSummary, narratorRemarkFromReasoning, stripIntroducerMentions, } from "../domain/opportunity.presentation.js";
|
|
20
20
|
export { safeFallbackSummary, SAFE_FALLBACK_MAX_CHARS, DEFAULT_EMPTY_FALLBACK_TEXT, } from "../domain/opportunity.safe-presentation.js";
|
|
21
|
-
export { OPPORTUNITY_PRESENTATION_CACHE_VERSION,
|
|
21
|
+
export { OPPORTUNITY_PRESENTATION_CACHE_VERSION, buildRadarCardPresentationCacheKey, buildDeliveryCardPresentationCacheKey, buildApiChatCardPresentationCacheKey, } from "../domain/opportunity.presentation-cache.js";
|
|
22
22
|
export { buildDiscoverySummary, toDiscoveryNegotiation, } from "../domain/negotiation-summary.builder.js";
|
|
23
23
|
export { poolQuestionsMiningMode, poolQuestionsMode, poolQuestionsPushMode, poolQuestionsStampNewborn, POOL_DISCRIMINATOR_MIN_POOL_SIZE, POOL_DISCRIMINATOR_MAX_CANDIDATES, POOL_DISCRIMINATOR_MAX_PUBLIC_CONTEXT_CHARS, POOL_QUESTION_MIN_VOI, POOL_QUESTION_MAX_PENDING_PER_INTENT, poolQuestionsRanking, POOL_RERUN_DEBOUNCE_MS, poolQuestionsVisitTrigger, POOL_VISIT_MINING_DEBOUNCE_MS, } from "../discriminator/discriminator.env.js";
|
|
24
24
|
// discovery env accessors
|
|
@@ -28,8 +28,8 @@ export { synthesizePoolQuestion, selectQuestionDiscriminators, toQuestionDiscrim
|
|
|
28
28
|
export { poolQuestionCycleKey, buildPoolQuestionPushMessage, } from "../discriminator/discriminator.push.js";
|
|
29
29
|
export { negotiationEvidenceQuestionsMode, NEGOTIATION_EVIDENCE_MAX_OPPORTUNITIES, } from "../negotiation-evidence/negotiation-evidence.env.js";
|
|
30
30
|
export { isOutcomeQuestionsActivated, OUTCOME_MIN_INDEPENDENT_EXAMPLES, OUTCOME_MAX_CANDIDATES, OUTCOME_MAX_PUBLIC_CONTEXT_CHARS, } from "../outcome/outcome.env.js";
|
|
31
|
-
//
|
|
32
|
-
export {
|
|
31
|
+
// radar domain
|
|
32
|
+
export { computeRadarHealth } from "../radar/radar.health.js";
|
|
33
33
|
// ── Application exports ───────────────────────────────────────────────────────
|
|
34
34
|
export { isIntroducerDiscoveryEnabled } from "../application/opportunity.introducer-feature.js";
|
|
35
35
|
export { OpportunityGraphFactory } from "../application/opportunity.graph.js";
|
|
@@ -48,7 +48,7 @@ export { NegotiationEvidenceMiner } from "../negotiation-evidence/negotiation-ev
|
|
|
48
48
|
export { runNegotiationEvidenceShadow } from "../negotiation-evidence/negotiation-evidence.shadow.js";
|
|
49
49
|
// outcome application
|
|
50
50
|
export { runOutcomeShadow } from "../outcome/outcome.shadow.js";
|
|
51
|
-
//
|
|
52
|
-
export {
|
|
51
|
+
// radar application
|
|
52
|
+
export { RadarGraphFactory } from "../radar/radar.graph.js";
|
|
53
53
|
// ── Tools ────────────────────────────────────────────────────────────────────
|
|
54
54
|
export { createOpportunityTools } from "../application/opportunity.tools.js";
|