@indexnetwork/protocol 14.3.2-rc.477.1 → 16.1.1-rc.478.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/CHANGELOG.md +107 -0
- package/IMPLEMENTATION.md +50 -52
- package/STABILITY.md +3 -3
- package/dist/chat/chat.agent.js +2 -2
- package/dist/chat/chat.graph.d.ts +41 -1
- package/dist/chat/chat.graph.js +108 -127
- package/dist/discovery/hyde.frame.d.ts +4 -4
- package/dist/discovery/hyde.graph.d.ts +71 -12
- package/dist/discovery/hyde.graph.js +337 -335
- package/dist/discovery/lens.inferrer.d.ts +6 -6
- package/dist/enrichment/enrichment.graph.d.ts +127 -9
- package/dist/enrichment/enrichment.graph.js +633 -655
- package/dist/enrichment/enrichment.state.d.ts +1 -1
- package/dist/enrichment/enrichment.tools.context-read.d.ts +10 -0
- package/dist/enrichment/enrichment.tools.context-read.js +353 -0
- package/dist/enrichment/enrichment.tools.context-write.d.ts +9 -0
- package/dist/enrichment/enrichment.tools.context-write.js +417 -0
- package/dist/enrichment/enrichment.tools.d.ts +11 -1
- package/dist/enrichment/enrichment.tools.helpers.d.ts +139 -0
- package/dist/enrichment/enrichment.tools.helpers.js +234 -0
- package/dist/enrichment/enrichment.tools.js +16 -975
- package/dist/index.d.ts +27 -48
- package/dist/index.js +17 -27
- package/dist/intents/application/intent.graph.d.ts +71 -67
- package/dist/intents/application/intent.graph.execute.d.ts +59 -0
- package/dist/intents/application/intent.graph.execute.js +301 -0
- package/dist/intents/application/intent.graph.infer.d.ts +44 -0
- package/dist/intents/application/intent.graph.infer.js +97 -0
- package/dist/intents/application/intent.graph.js +96 -888
- package/dist/intents/application/intent.graph.reconcile.d.ts +71 -0
- package/dist/intents/application/intent.graph.reconcile.js +274 -0
- package/dist/intents/application/intent.graph.shared.d.ts +70 -0
- package/dist/intents/application/intent.graph.shared.js +153 -0
- package/dist/intents/domain/intent.state.d.ts +1 -1
- package/dist/maintenance/maintenance.graph.d.ts +66 -3
- package/dist/maintenance/maintenance.graph.js +155 -156
- package/dist/mcp/mcp.authorization-policy.d.ts +24 -28
- package/dist/mcp/mcp.authorization-policy.js +14 -34
- package/dist/mcp/mcp.server.d.ts +3 -3
- package/dist/mcp/mcp.server.js +12 -16
- package/dist/negotiations/application/negotiation.candidates.d.ts +83 -0
- package/dist/negotiations/application/negotiation.candidates.js +162 -0
- package/dist/negotiations/application/negotiation.graph.d.ts +91 -157
- package/dist/negotiations/application/negotiation.graph.finalize.d.ts +5 -0
- package/dist/negotiations/application/negotiation.graph.finalize.js +280 -0
- package/dist/negotiations/application/negotiation.graph.init.d.ts +54 -0
- package/dist/negotiations/application/negotiation.graph.init.js +227 -0
- package/dist/negotiations/application/negotiation.graph.js +69 -1388
- package/dist/negotiations/application/negotiation.graph.screen.d.ts +23 -0
- package/dist/negotiations/application/negotiation.graph.screen.js +108 -0
- package/dist/negotiations/application/negotiation.graph.shared.d.ts +75 -0
- package/dist/negotiations/application/negotiation.graph.shared.js +125 -0
- package/dist/negotiations/application/negotiation.graph.turn.d.ts +105 -0
- package/dist/negotiations/application/negotiation.graph.turn.js +484 -0
- package/dist/negotiations/domain/negotiation.state.d.ts +1 -1
- package/dist/negotiations/domain/negotiation.state.js +0 -1
- package/dist/networks/application/indexer.graph.d.ts +165 -7
- package/dist/networks/application/indexer.graph.js +339 -388
- package/dist/networks/application/indexer.state.d.ts +1 -1
- package/dist/networks/application/membership.graph.d.ts +83 -5
- package/dist/networks/application/membership.graph.js +177 -207
- package/dist/networks/application/network.graph.d.ts +148 -5
- package/dist/networks/application/network.graph.js +249 -278
- package/dist/networks/domain/membership.state.d.ts +1 -1
- package/dist/networks/domain/network.state.d.ts +1 -1
- package/dist/opportunities/application/delivery-card.cache.d.ts +1 -1
- package/dist/opportunities/application/delivery-card.cache.js +2 -2
- package/dist/opportunities/application/index.d.ts +2 -2
- package/dist/opportunities/application/index.js +2 -2
- package/dist/opportunities/application/opportunity.evaluator.js +1 -1
- package/dist/opportunities/application/opportunity.graph.d.ts +686 -473
- package/dist/opportunities/application/opportunity.graph.discovery-strategies.d.ts +109 -0
- package/dist/opportunities/application/opportunity.graph.discovery-strategies.js +451 -0
- package/dist/opportunities/application/opportunity.graph.discovery.d.ts +69 -0
- package/dist/opportunities/application/opportunity.graph.discovery.js +397 -0
- package/dist/opportunities/application/opportunity.graph.evaluation.d.ts +82 -0
- package/dist/opportunities/application/opportunity.graph.evaluation.js +608 -0
- package/dist/opportunities/application/opportunity.graph.js +120 -3690
- package/dist/opportunities/application/opportunity.graph.modes.d.ts +538 -0
- package/dist/opportunities/application/opportunity.graph.modes.js +538 -0
- package/dist/opportunities/application/opportunity.graph.negotiate.d.ts +109 -0
- package/dist/opportunities/application/opportunity.graph.negotiate.js +392 -0
- package/dist/opportunities/application/opportunity.graph.persist-node.d.ts +93 -0
- package/dist/opportunities/application/opportunity.graph.persist-node.js +765 -0
- package/dist/opportunities/application/opportunity.graph.prep.d.ts +150 -0
- package/dist/opportunities/application/opportunity.graph.prep.js +381 -0
- package/dist/opportunities/application/opportunity.graph.shared.d.ts +173 -0
- package/dist/opportunities/application/opportunity.graph.shared.js +199 -0
- package/dist/opportunities/application/opportunity.presentation.d.ts +399 -0
- package/dist/opportunities/application/{opportunity.presenter.js → opportunity.presentation.js} +735 -9
- package/dist/opportunities/application/opportunity.tools.cards.d.ts +152 -0
- package/dist/opportunities/application/opportunity.tools.cards.js +235 -0
- package/dist/opportunities/application/opportunity.tools.d.ts +8 -114
- package/dist/opportunities/application/opportunity.tools.js +28 -711
- package/dist/opportunities/application/opportunity.tools.list.d.ts +10 -0
- package/dist/opportunities/application/opportunity.tools.list.js +493 -0
- package/dist/opportunities/domain/index.d.ts +3 -3
- package/dist/opportunities/domain/index.js +3 -3
- package/dist/opportunities/domain/opportunity.state.d.ts +19 -19
- package/dist/opportunities/index.d.ts +6 -6
- package/dist/opportunities/index.js +4 -4
- package/dist/opportunities/ports/opportunity.tools.port.d.ts +1 -1
- package/dist/opportunities/radar/radar.graph.d.ts +57 -13
- package/dist/opportunities/radar/radar.graph.js +470 -471
- package/dist/premises/premise.graph.d.ts +88 -20
- package/dist/premises/premise.graph.js +207 -218
- package/dist/questions/domain/question.schema.d.ts +40 -40
- package/dist/shared/agent/tool.helpers.d.ts +21 -0
- package/dist/shared/agent/tool.registry.d.ts +4 -3
- package/dist/shared/agent/tool.registry.js +1 -1
- package/dist/shared/interfaces/database.capabilities.d.ts +100 -0
- package/dist/shared/interfaces/database.capabilities.js +7 -0
- package/dist/shared/interfaces/database.entities.d.ts +533 -0
- package/dist/shared/interfaces/database.entities.js +10 -0
- package/dist/shared/interfaces/database.identity-queries.d.ts +294 -0
- package/dist/shared/interfaces/database.identity-queries.js +4 -0
- package/dist/shared/interfaces/database.interface.d.ts +15 -2277
- package/dist/shared/interfaces/database.interface.js +8 -0
- package/dist/shared/interfaces/database.member-queries.d.ts +228 -0
- package/dist/shared/interfaces/database.member-queries.js +4 -0
- package/dist/shared/interfaces/database.negotiation.d.ts +305 -0
- package/dist/shared/interfaces/database.negotiation.js +26 -0
- package/dist/shared/interfaces/database.network-queries.d.ts +277 -0
- package/dist/shared/interfaces/database.network-queries.js +4 -0
- package/dist/shared/interfaces/database.opportunity-queries.d.ts +285 -0
- package/dist/shared/interfaces/database.opportunity-queries.js +4 -0
- package/dist/shared/interfaces/database.port.d.ts +322 -0
- package/dist/shared/interfaces/database.port.js +29 -0
- package/dist/shared/schemas/discovery-question.schema.d.ts +14 -14
- package/dist/shared/schemas/negotiation-digest.schema.d.ts +2 -2
- package/package.json +2 -15
- package/dist/opportunities/application/opportunity.card-presentation.d.ts +0 -44
- package/dist/opportunities/application/opportunity.card-presentation.js +0 -93
- package/dist/opportunities/application/opportunity.presenter.d.ts +0 -156
- package/dist/opportunities/domain/opportunity.presentation-cache.d.ts +0 -5
- package/dist/opportunities/domain/opportunity.presentation-cache.js +0 -11
- package/dist/opportunities/domain/opportunity.presentation.d.ts +0 -76
- package/dist/opportunities/domain/opportunity.presentation.js +0 -516
- package/dist/opportunities/domain/opportunity.safe-presentation.d.ts +0 -104
- package/dist/opportunities/domain/opportunity.safe-presentation.js +0 -102
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Intent graph, stages 2-3: verify inferred signals, then reconcile against what exists.
|
|
3
|
+
*/
|
|
4
|
+
import { VerifiedIntent, type IntentValidationFailure } from "../domain/intent.state.js";
|
|
5
|
+
import type { NormalizedIntentAction } from "./intent.reconciler.js";
|
|
6
|
+
import type { DebugMetaAgent } from "../../agents/index.js";
|
|
7
|
+
import { type IntentGraphDeps, type IntentState } from "./intent.graph.shared.js";
|
|
8
|
+
/**
|
|
9
|
+
* Node 2: Verification (Map-Reduce / Parallel)
|
|
10
|
+
* Verifies each inferred intent in parallel.
|
|
11
|
+
* Phase 4: Can be skipped for delete operations and updates with no new intents.
|
|
12
|
+
*/
|
|
13
|
+
export declare function verificationNode(state: IntentState, deps: IntentGraphDeps): Promise<{
|
|
14
|
+
verifiedIntents: never[];
|
|
15
|
+
agentTimings: never[];
|
|
16
|
+
validationFailures?: undefined;
|
|
17
|
+
trace?: undefined;
|
|
18
|
+
} | {
|
|
19
|
+
verifiedIntents: VerifiedIntent[];
|
|
20
|
+
validationFailures: IntentValidationFailure[];
|
|
21
|
+
agentTimings: DebugMetaAgent[];
|
|
22
|
+
trace: {
|
|
23
|
+
node: string;
|
|
24
|
+
detail: string;
|
|
25
|
+
data: {
|
|
26
|
+
clarity: number;
|
|
27
|
+
authority: number;
|
|
28
|
+
sincerity: number;
|
|
29
|
+
entropy: number | undefined;
|
|
30
|
+
referentialBreadth: "narrow" | "moderate" | "broad" | undefined;
|
|
31
|
+
missingSelectionalConstraints: ("location" | "role" | "outcome" | "timeframe" | "domain" | "concrete_need")[] | undefined;
|
|
32
|
+
specificityWarning: string | undefined;
|
|
33
|
+
classification: "COMMISSIVE" | "DIRECTIVE" | "ASSERTIVE" | "EXPRESSIVE" | "DECLARATION" | "UNKNOWN" | undefined;
|
|
34
|
+
score: number | undefined;
|
|
35
|
+
} | undefined;
|
|
36
|
+
}[];
|
|
37
|
+
}>;
|
|
38
|
+
/**
|
|
39
|
+
* Node 3: Reconciliation
|
|
40
|
+
* Decides on final actions (Create, Update, Expire).
|
|
41
|
+
* Phase 4: Handles delete operations directly without LLM reconciliation.
|
|
42
|
+
*/
|
|
43
|
+
export declare function reconciliationNode(state: IntentState, deps: IntentGraphDeps): Promise<{
|
|
44
|
+
actions: {
|
|
45
|
+
type: "expire";
|
|
46
|
+
id: string;
|
|
47
|
+
reasoning: string;
|
|
48
|
+
}[];
|
|
49
|
+
agentTimings: DebugMetaAgent[];
|
|
50
|
+
trace: {
|
|
51
|
+
node: string;
|
|
52
|
+
detail: string;
|
|
53
|
+
}[];
|
|
54
|
+
validationFailures?: undefined;
|
|
55
|
+
} | {
|
|
56
|
+
actions: NormalizedIntentAction[];
|
|
57
|
+
validationFailures: IntentValidationFailure[];
|
|
58
|
+
agentTimings: DebugMetaAgent[];
|
|
59
|
+
trace: {
|
|
60
|
+
node: string;
|
|
61
|
+
detail: string;
|
|
62
|
+
}[];
|
|
63
|
+
} | {
|
|
64
|
+
actions: NormalizedIntentAction[];
|
|
65
|
+
agentTimings: DebugMetaAgent[];
|
|
66
|
+
trace: {
|
|
67
|
+
node: string;
|
|
68
|
+
detail: string;
|
|
69
|
+
}[];
|
|
70
|
+
validationFailures?: undefined;
|
|
71
|
+
}>;
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Intent graph, stages 2-3: verify inferred signals, then reconcile against what exists.
|
|
3
|
+
*/
|
|
4
|
+
import { timed } from "../../shared/observability/performance.js";
|
|
5
|
+
import { requestContext } from "../../shared/observability/request-context.js";
|
|
6
|
+
import { buildExplicitUpdateActions, enforceIntentActionBoundary, enrichVagueIntentWithContext, getSpecificityWarning, isVague, logger } from "./intent.graph.shared.js";
|
|
7
|
+
/**
|
|
8
|
+
* Node 2: Verification (Map-Reduce / Parallel)
|
|
9
|
+
* Verifies each inferred intent in parallel.
|
|
10
|
+
* Phase 4: Can be skipped for delete operations and updates with no new intents.
|
|
11
|
+
*/
|
|
12
|
+
export async function verificationNode(state, deps) {
|
|
13
|
+
return timed("IntentGraph.verification", async () => {
|
|
14
|
+
const intents = state.inferredIntents;
|
|
15
|
+
logger.verbose("Starting verification", {
|
|
16
|
+
operationMode: state.operationMode,
|
|
17
|
+
intentCount: intents.length
|
|
18
|
+
});
|
|
19
|
+
if (intents.length === 0) {
|
|
20
|
+
logger.verbose("No intents to verify");
|
|
21
|
+
return { verifiedIntents: [], agentTimings: [] };
|
|
22
|
+
}
|
|
23
|
+
logger.verbose('Verifying intents in parallel', { count: intents.length });
|
|
24
|
+
const agentTimingsAccum = [];
|
|
25
|
+
// Parallel Execution
|
|
26
|
+
const verificationResults = await Promise.all(intents.map(async (intent) => {
|
|
27
|
+
try {
|
|
28
|
+
let description = intent.description;
|
|
29
|
+
const _traceEmitterVerifier = requestContext.getStore()?.traceEmitter;
|
|
30
|
+
const verifierStart1 = Date.now();
|
|
31
|
+
_traceEmitterVerifier?.({ type: "agent_start", name: "intent-verifier" });
|
|
32
|
+
let verdict = await deps.verifier.invoke(description, state.userProfile);
|
|
33
|
+
agentTimingsAccum.push({ name: 'intent.verifier', durationMs: Date.now() - verifierStart1 });
|
|
34
|
+
_traceEmitterVerifier?.({ type: "agent_end", name: "intent-verifier", durationMs: Date.now() - verifierStart1, summary: `Verified: ${verdict.classification}` });
|
|
35
|
+
if (isVague(description, verdict.semantic_entropy, verdict.felicity_scores.clarity)) {
|
|
36
|
+
// Role-hint enrichment for vague job intents reads the global
|
|
37
|
+
// user_context paragraph instead of the structured profile fields.
|
|
38
|
+
const roleHintContext = (await deps.database.getUserContext(state.userId, null))?.text ?? '';
|
|
39
|
+
const enrichedDescription = enrichVagueIntentWithContext(description, roleHintContext);
|
|
40
|
+
if (enrichedDescription !== description) {
|
|
41
|
+
logger.verbose("Enriched vague intent using profile context", {
|
|
42
|
+
before: description,
|
|
43
|
+
after: enrichedDescription,
|
|
44
|
+
});
|
|
45
|
+
const _traceEmitterVerifier2 = requestContext.getStore()?.traceEmitter;
|
|
46
|
+
const verifierStart2 = Date.now();
|
|
47
|
+
_traceEmitterVerifier2?.({ type: "agent_start", name: "intent-verifier" });
|
|
48
|
+
const enrichedVerdict = await deps.verifier.invoke(enrichedDescription, state.userProfile);
|
|
49
|
+
agentTimingsAccum.push({ name: 'intent.verifier', durationMs: Date.now() - verifierStart2 });
|
|
50
|
+
_traceEmitterVerifier2?.({ type: "agent_end", name: "intent-verifier", durationMs: Date.now() - verifierStart2, summary: `Verified (enriched): ${enrichedVerdict.classification}` });
|
|
51
|
+
const becameClear = enrichedVerdict.semantic_entropy < verdict.semantic_entropy ||
|
|
52
|
+
enrichedVerdict.felicity_scores.clarity > verdict.felicity_scores.clarity;
|
|
53
|
+
if (becameClear) {
|
|
54
|
+
description = enrichedDescription;
|
|
55
|
+
verdict = enrichedVerdict;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
// Filter Logic: Must be a Commissive, Directive, or Declaration
|
|
60
|
+
const VALID_TYPES = ['COMMISSIVE', 'DIRECTIVE', 'DECLARATION'];
|
|
61
|
+
if (!VALID_TYPES.includes(verdict.classification)) {
|
|
62
|
+
logger.warn('Dropping intent', { description, classification: verdict.classification });
|
|
63
|
+
return {
|
|
64
|
+
failure: {
|
|
65
|
+
category: 'non_actionable',
|
|
66
|
+
classification: verdict.classification,
|
|
67
|
+
referentialBreadth: verdict.referential_breadth,
|
|
68
|
+
message: `Description was classified as ${verdict.classification}, not an actionable goal.`,
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
if (isVague(description, verdict.semantic_entropy, verdict.felicity_scores.clarity)) {
|
|
73
|
+
logger.warn('Dropping vague intent after verification', {
|
|
74
|
+
description,
|
|
75
|
+
entropy: verdict.semantic_entropy,
|
|
76
|
+
clarity: verdict.felicity_scores.clarity,
|
|
77
|
+
});
|
|
78
|
+
return {
|
|
79
|
+
failure: {
|
|
80
|
+
category: 'vague_or_invalid',
|
|
81
|
+
classification: verdict.classification,
|
|
82
|
+
referentialBreadth: verdict.referential_breadth,
|
|
83
|
+
message: 'Description failed clarity or semantic-entropy requirements.',
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
if (state.operationMode === 'create' && verdict.referential_breadth === 'broad') {
|
|
88
|
+
logger.warn('Dropping broad attributive intent before persistence', {
|
|
89
|
+
description,
|
|
90
|
+
referentialBreadth: verdict.referential_breadth,
|
|
91
|
+
missingSelectionalConstraints: verdict.missing_selectional_constraints,
|
|
92
|
+
warning: getSpecificityWarning(verdict),
|
|
93
|
+
});
|
|
94
|
+
return {
|
|
95
|
+
failure: {
|
|
96
|
+
category: 'vague_or_invalid',
|
|
97
|
+
classification: verdict.classification,
|
|
98
|
+
referentialBreadth: verdict.referential_breadth,
|
|
99
|
+
message: getSpecificityWarning(verdict),
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
// Calculate Score
|
|
104
|
+
const score = Math.min(verdict.felicity_scores.authority, verdict.felicity_scores.sincerity, verdict.felicity_scores.clarity);
|
|
105
|
+
// Return enriched intent
|
|
106
|
+
return {
|
|
107
|
+
intent: {
|
|
108
|
+
...intent,
|
|
109
|
+
description,
|
|
110
|
+
verification: verdict,
|
|
111
|
+
score,
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
catch (e) {
|
|
116
|
+
logger.error('Error verifying intent', { description: intent.description, error: e });
|
|
117
|
+
return {
|
|
118
|
+
failure: {
|
|
119
|
+
category: 'verification_failure',
|
|
120
|
+
message: e instanceof Error ? e.message : 'Intent verification failed unexpectedly.',
|
|
121
|
+
},
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
}));
|
|
125
|
+
const verified = verificationResults.flatMap((result) => 'intent' in result ? [result.intent] : []);
|
|
126
|
+
const validationFailures = verificationResults.flatMap((result) => 'failure' in result ? [result.failure] : []);
|
|
127
|
+
logger.verbose(`Verification complete`, {
|
|
128
|
+
passed: verified.length,
|
|
129
|
+
total: intents.length,
|
|
130
|
+
operationMode: state.operationMode
|
|
131
|
+
});
|
|
132
|
+
// Build trace entries with Felicity scores for each verified intent
|
|
133
|
+
const traceEntries = verified.map(v => {
|
|
134
|
+
const fs = v.verification?.felicity_scores;
|
|
135
|
+
const entropy = v.verification?.semantic_entropy;
|
|
136
|
+
const classification = v.verification?.classification;
|
|
137
|
+
const referentialBreadth = v.verification?.referential_breadth;
|
|
138
|
+
return {
|
|
139
|
+
node: "verification",
|
|
140
|
+
detail: `"${v.description.slice(0, 40)}${v.description.length > 40 ? '...' : ''}" → ${classification}${referentialBreadth ? ` (${referentialBreadth} referential breadth)` : ''}`,
|
|
141
|
+
data: fs ? {
|
|
142
|
+
clarity: fs.clarity,
|
|
143
|
+
authority: fs.authority,
|
|
144
|
+
sincerity: fs.sincerity,
|
|
145
|
+
entropy: entropy != null ? Math.round(entropy * 100) / 100 : undefined,
|
|
146
|
+
referentialBreadth,
|
|
147
|
+
missingSelectionalConstraints: v.verification?.missing_selectional_constraints,
|
|
148
|
+
specificityWarning: v.verification?.specificity_warning ?? undefined,
|
|
149
|
+
classification,
|
|
150
|
+
score: v.score,
|
|
151
|
+
} : undefined,
|
|
152
|
+
};
|
|
153
|
+
});
|
|
154
|
+
// Add summary trace if some intents were filtered out
|
|
155
|
+
const dropped = intents.length - verified.length;
|
|
156
|
+
if (dropped > 0) {
|
|
157
|
+
traceEntries.unshift({
|
|
158
|
+
node: "verification",
|
|
159
|
+
detail: `Verified ${verified.length}/${intents.length} (${dropped} filtered as invalid)`,
|
|
160
|
+
data: undefined,
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
else if (verified.length > 0) {
|
|
164
|
+
traceEntries.unshift({
|
|
165
|
+
node: "verification",
|
|
166
|
+
detail: `Verified ${verified.length} intent(s)`,
|
|
167
|
+
data: undefined,
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
return { verifiedIntents: verified, validationFailures, agentTimings: agentTimingsAccum, trace: traceEntries };
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Node 3: Reconciliation
|
|
175
|
+
* Decides on final actions (Create, Update, Expire).
|
|
176
|
+
* Phase 4: Handles delete operations directly without LLM reconciliation.
|
|
177
|
+
*/
|
|
178
|
+
export async function reconciliationNode(state, deps) {
|
|
179
|
+
return timed("IntentGraph.reconciliation", async () => {
|
|
180
|
+
logger.verbose("Starting reconciliation", {
|
|
181
|
+
operationMode: state.operationMode,
|
|
182
|
+
verifiedIntentCount: state.verifiedIntents.length,
|
|
183
|
+
targetIntentIds: state.targetIntentIds
|
|
184
|
+
});
|
|
185
|
+
const agentTimingsAccum = [];
|
|
186
|
+
// Phase 4: Handle delete operations directly
|
|
187
|
+
if (state.operationMode === 'delete') {
|
|
188
|
+
if (!state.targetIntentIds || state.targetIntentIds.length === 0) {
|
|
189
|
+
logger.warn("Delete mode with no target IDs");
|
|
190
|
+
return {
|
|
191
|
+
actions: [],
|
|
192
|
+
agentTimings: agentTimingsAccum,
|
|
193
|
+
trace: [{ node: "reconciler", detail: "Delete mode with no target IDs" }],
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
logger.verbose("Delete mode - generating expire actions", {
|
|
197
|
+
targetIds: state.targetIntentIds
|
|
198
|
+
});
|
|
199
|
+
const actions = state.targetIntentIds.map(id => ({
|
|
200
|
+
type: 'expire',
|
|
201
|
+
id,
|
|
202
|
+
reasoning: 'User requested deletion'
|
|
203
|
+
}));
|
|
204
|
+
return {
|
|
205
|
+
actions,
|
|
206
|
+
agentTimings: agentTimingsAccum,
|
|
207
|
+
trace: [{
|
|
208
|
+
node: "reconciler",
|
|
209
|
+
detail: `Actions: expire=${actions.length}`,
|
|
210
|
+
}],
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
// Standard reconciliation for create/update operations
|
|
214
|
+
const candidates = state.verifiedIntents;
|
|
215
|
+
if (candidates.length === 0) {
|
|
216
|
+
logger.verbose("No verified intents to reconcile");
|
|
217
|
+
return {
|
|
218
|
+
actions: [],
|
|
219
|
+
agentTimings: agentTimingsAccum,
|
|
220
|
+
trace: [{ node: "reconciler", detail: "No intents to reconcile" }],
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
if (state.operationMode === 'update') {
|
|
224
|
+
const explicitUpdate = buildExplicitUpdateActions(state.targetIntentIds, state.activeIntentIds, candidates);
|
|
225
|
+
return {
|
|
226
|
+
actions: explicitUpdate.actions,
|
|
227
|
+
validationFailures: explicitUpdate.failure
|
|
228
|
+
? [...state.validationFailures, explicitUpdate.failure]
|
|
229
|
+
: state.validationFailures,
|
|
230
|
+
agentTimings: agentTimingsAccum,
|
|
231
|
+
trace: [{
|
|
232
|
+
node: 'reconciler',
|
|
233
|
+
detail: explicitUpdate.failure
|
|
234
|
+
? `Explicit update rejected: ${explicitUpdate.failure.category}`
|
|
235
|
+
: `Explicit update bound to target ${state.targetIntentIds?.[0]}`,
|
|
236
|
+
}],
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
// Format candidates for the Reconciler Prompt
|
|
240
|
+
const formattedCandidates = candidates.map(c => `- [${c.type.toUpperCase()}] "${c.description}" (Confidence: ${c.confidence}, Score: ${c.score})\n` +
|
|
241
|
+
` Reasoning: ${c.reasoning}\n` +
|
|
242
|
+
` Verification: ${c.verification?.classification} (Flags: ${c.verification?.flags.join(', ') || 'None'})`).join('\n');
|
|
243
|
+
logger.verbose("Invoking reconciler agent", {
|
|
244
|
+
candidateCount: candidates.length,
|
|
245
|
+
operationMode: state.operationMode
|
|
246
|
+
});
|
|
247
|
+
const _traceEmitterReconciler = requestContext.getStore()?.traceEmitter;
|
|
248
|
+
const reconcilerStart = Date.now();
|
|
249
|
+
_traceEmitterReconciler?.({ type: "agent_start", name: "intent-reconciler" });
|
|
250
|
+
const result = await deps.reconciler.invoke(formattedCandidates, state.activeIntents);
|
|
251
|
+
agentTimingsAccum.push({ name: 'intent.reconciler', durationMs: Date.now() - reconcilerStart });
|
|
252
|
+
_traceEmitterReconciler?.({ type: "agent_end", name: "intent-reconciler", durationMs: Date.now() - reconcilerStart, summary: `Reconciled ${result.actions.length} action(s)` });
|
|
253
|
+
const actions = enforceIntentActionBoundary(state.operationMode, state.targetIntentIds, result.actions);
|
|
254
|
+
logger.verbose("Reconciliation complete", {
|
|
255
|
+
actionCount: actions.length,
|
|
256
|
+
droppedActionCount: result.actions.length - actions.length,
|
|
257
|
+
operationMode: state.operationMode
|
|
258
|
+
});
|
|
259
|
+
// Count actions by type after enforcing the operation boundary.
|
|
260
|
+
const counts = { create: 0, update: 0, expire: 0 };
|
|
261
|
+
for (const a of actions) {
|
|
262
|
+
if (a.type in counts)
|
|
263
|
+
counts[a.type]++;
|
|
264
|
+
}
|
|
265
|
+
return {
|
|
266
|
+
actions,
|
|
267
|
+
agentTimings: agentTimingsAccum,
|
|
268
|
+
trace: [{
|
|
269
|
+
node: "reconciler",
|
|
270
|
+
detail: `Actions: create=${counts.create}, update=${counts.update}, expire=${counts.expire}`,
|
|
271
|
+
}],
|
|
272
|
+
};
|
|
273
|
+
});
|
|
274
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared vocabulary for the intent graph's nodes.
|
|
3
|
+
*
|
|
4
|
+
* The nodes were closures inside `IntentGraphFactory.createGraph()`; they are
|
|
5
|
+
* top-level functions now, each taking an explicit {@link IntentGraphDeps}.
|
|
6
|
+
* This module owns the bag, the logger, and the pure helpers.
|
|
7
|
+
*/
|
|
8
|
+
import { IntentGraphState, VerifiedIntent, type IntentValidationFailure } from "../domain/intent.state.js";
|
|
9
|
+
import { ExplicitIntentInferrer } from "./intent.inferrer.js";
|
|
10
|
+
import { SemanticVerifier } from "./intent.verifier.js";
|
|
11
|
+
import { IntentReconciler } from "./intent.reconciler.js";
|
|
12
|
+
import type { NormalizedIntentAction } from "./intent.reconciler.js";
|
|
13
|
+
import { IntentGraphDatabase } from "../../shared/interfaces/database.interface.js";
|
|
14
|
+
import type { EmbeddingGenerator } from "../../shared/interfaces/embedder.interface.js";
|
|
15
|
+
import type { IntentGraphQueue } from "../../shared/interfaces/queue.interface.js";
|
|
16
|
+
import type { QuestionerEnqueueFn } from "../../questions/index.js";
|
|
17
|
+
/** The graph's channel state, as every node sees it. */
|
|
18
|
+
export type IntentState = typeof IntentGraphState.State;
|
|
19
|
+
/** Everything the intent nodes reach for. Composed once by the factory. */
|
|
20
|
+
export interface IntentGraphDeps {
|
|
21
|
+
database: IntentGraphDatabase;
|
|
22
|
+
embedder?: EmbeddingGenerator;
|
|
23
|
+
intentQueue?: IntentGraphQueue;
|
|
24
|
+
questionerEnqueue?: QuestionerEnqueueFn;
|
|
25
|
+
inferrer: Pick<ExplicitIntentInferrer, 'invoke'>;
|
|
26
|
+
verifier: Pick<SemanticVerifier, 'invoke'>;
|
|
27
|
+
reconciler: Pick<IntentReconciler, 'invoke'>;
|
|
28
|
+
}
|
|
29
|
+
export declare const logger: import("../../shared/observability/log.js").LoggerWithSource;
|
|
30
|
+
/**
|
|
31
|
+
* Enforce write-mode constraints on reconciler output before any action can
|
|
32
|
+
* reach persistence. Update mode is deliberately fail-closed: only updates
|
|
33
|
+
* whose id is one of the caller-provided targets survive.
|
|
34
|
+
*/
|
|
35
|
+
export declare function enforceIntentActionBoundary(operationMode: 'create' | 'update' | 'delete' | 'read' | 'propose', targetIntentIds: string[] | undefined, actions: NormalizedIntentAction[]): NormalizedIntentAction[];
|
|
36
|
+
/**
|
|
37
|
+
* Build the only action permitted for an explicit update. This path is
|
|
38
|
+
* intentionally deterministic: semantic reconciliation may shape create
|
|
39
|
+
* operations, but it may not redirect an update away from its supplied target.
|
|
40
|
+
*/
|
|
41
|
+
export declare function buildExplicitUpdateActions(targetIntentIds: string[] | undefined, activeIntentIds: string[], candidates: VerifiedIntent[]): {
|
|
42
|
+
actions: NormalizedIntentAction[];
|
|
43
|
+
failure?: IntentValidationFailure;
|
|
44
|
+
};
|
|
45
|
+
export declare const MAX_PERMISSIBLE_ENTROPY = 0.75;
|
|
46
|
+
export declare const MIN_CLEAR_INTENT_SCORE = 40;
|
|
47
|
+
export declare const GENERIC_JOB_PHRASE: RegExp;
|
|
48
|
+
export declare const inferRoleFromContextText: (text: string) => string | null;
|
|
49
|
+
/**
|
|
50
|
+
* Derive a job-role qualifier from the user's global user_context paragraph
|
|
51
|
+
* (the identity text that replaced the legacy profile projection). Role is
|
|
52
|
+
* inferred from the free text; the old structured skills/interests extraction
|
|
53
|
+
* is gone with the removed profile fields.
|
|
54
|
+
*/
|
|
55
|
+
export declare const buildJobQualifierFromContext: (contextText: string) => string | null;
|
|
56
|
+
export declare const enrichVagueIntentWithContext: (description: string, userContext: string) => string;
|
|
57
|
+
export declare const isVague: (description: string, entropy: number, clarity: number) => boolean;
|
|
58
|
+
export declare const getSpecificityWarning: (verdict: {
|
|
59
|
+
specificity_warning?: string | null;
|
|
60
|
+
}) => string;
|
|
61
|
+
export declare const toSpeechActType: (classification?: string) => "COMMISSIVE" | "DIRECTIVE" | null;
|
|
62
|
+
/**
|
|
63
|
+
* Factory class to build and compile the Intent Processing Graph.
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Generate a flat embedding for an intent payload, swallowing failures so
|
|
67
|
+
* persistence can continue without an embedding. `intentId` is logging-only
|
|
68
|
+
* (present for updates, absent for creates).
|
|
69
|
+
*/
|
|
70
|
+
export declare function generateIntentEmbedding(deps: IntentGraphDeps, sanitizedPayload: string, intentId?: string): Promise<number[] | undefined>;
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared vocabulary for the intent graph's nodes.
|
|
3
|
+
*
|
|
4
|
+
* The nodes were closures inside `IntentGraphFactory.createGraph()`; they are
|
|
5
|
+
* top-level functions now, each taking an explicit {@link IntentGraphDeps}.
|
|
6
|
+
* This module owns the bag, the logger, and the pure helpers.
|
|
7
|
+
*/
|
|
8
|
+
import { DEFAULT_SPECIFICITY_WARNING } from "../domain/signal.specificity.js";
|
|
9
|
+
import { getAbortSignalConfig } from "../../shared/agent/model-signal.js";
|
|
10
|
+
import { protocolLogger } from "../../shared/observability/protocol.logger.js";
|
|
11
|
+
export const logger = protocolLogger("IntentGraphFactory");
|
|
12
|
+
/**
|
|
13
|
+
* Enforce write-mode constraints on reconciler output before any action can
|
|
14
|
+
* reach persistence. Update mode is deliberately fail-closed: only updates
|
|
15
|
+
* whose id is one of the caller-provided targets survive.
|
|
16
|
+
*/
|
|
17
|
+
export function enforceIntentActionBoundary(operationMode, targetIntentIds, actions) {
|
|
18
|
+
if (operationMode !== 'update')
|
|
19
|
+
return actions;
|
|
20
|
+
const targets = new Set(targetIntentIds ?? []);
|
|
21
|
+
return actions.filter((action) => action.type === 'update' && targets.has(action.id));
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Build the only action permitted for an explicit update. This path is
|
|
25
|
+
* intentionally deterministic: semantic reconciliation may shape create
|
|
26
|
+
* operations, but it may not redirect an update away from its supplied target.
|
|
27
|
+
*/
|
|
28
|
+
export function buildExplicitUpdateActions(targetIntentIds, activeIntentIds, candidates) {
|
|
29
|
+
if (targetIntentIds?.length !== 1 || !activeIntentIds.includes(targetIntentIds[0])) {
|
|
30
|
+
return {
|
|
31
|
+
actions: [],
|
|
32
|
+
failure: {
|
|
33
|
+
category: 'update_target_boundary',
|
|
34
|
+
message: 'Explicit update requires exactly one active intent owned by the caller.',
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
if (candidates.length !== 1) {
|
|
39
|
+
return {
|
|
40
|
+
actions: [],
|
|
41
|
+
failure: {
|
|
42
|
+
category: 'reconciliation_boundary',
|
|
43
|
+
message: 'Explicit update must resolve to exactly one verified intent.',
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
const candidate = candidates[0];
|
|
48
|
+
return {
|
|
49
|
+
actions: [{
|
|
50
|
+
type: 'update',
|
|
51
|
+
id: targetIntentIds[0],
|
|
52
|
+
payload: candidate.description,
|
|
53
|
+
score: candidate.score ?? null,
|
|
54
|
+
reasoning: candidate.reasoning ?? 'Explicit user-confirmed update',
|
|
55
|
+
intentMode: candidate.verification?.referential_anchor ? 'REFERENTIAL' : 'ATTRIBUTIVE',
|
|
56
|
+
}],
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
export const MAX_PERMISSIBLE_ENTROPY = 0.75;
|
|
60
|
+
export const MIN_CLEAR_INTENT_SCORE = 40;
|
|
61
|
+
export const GENERIC_JOB_PHRASE = /\b(?:a|any|some)\s+job\b/i;
|
|
62
|
+
export const inferRoleFromContextText = (text) => {
|
|
63
|
+
const normalized = text.toLowerCase();
|
|
64
|
+
if (/\b(engineer|developer)\b/.test(normalized))
|
|
65
|
+
return "software engineering";
|
|
66
|
+
if (/\b(designer|ux|ui)\b/.test(normalized))
|
|
67
|
+
return "product design";
|
|
68
|
+
if (/\b(marketing|marketer|growth)\b/.test(normalized))
|
|
69
|
+
return "marketing";
|
|
70
|
+
if (/\b(product manager|product)\b/.test(normalized))
|
|
71
|
+
return "product management";
|
|
72
|
+
if (/\b(data scientist|machine learning|ml|ai)\b/.test(normalized))
|
|
73
|
+
return "AI/ML";
|
|
74
|
+
if (/\b(sales|account executive|business development)\b/.test(normalized))
|
|
75
|
+
return "sales";
|
|
76
|
+
return null;
|
|
77
|
+
};
|
|
78
|
+
/**
|
|
79
|
+
* Derive a job-role qualifier from the user's global user_context paragraph
|
|
80
|
+
* (the identity text that replaced the legacy profile projection). Role is
|
|
81
|
+
* inferred from the free text; the old structured skills/interests extraction
|
|
82
|
+
* is gone with the removed profile fields.
|
|
83
|
+
*/
|
|
84
|
+
export const buildJobQualifierFromContext = (contextText) => {
|
|
85
|
+
const roleHint = inferRoleFromContextText(contextText ?? "");
|
|
86
|
+
return roleHint ? `${roleHint} role` : null;
|
|
87
|
+
};
|
|
88
|
+
export const enrichVagueIntentWithContext = (description, userContext) => {
|
|
89
|
+
const trimmed = description?.trim();
|
|
90
|
+
if (!trimmed)
|
|
91
|
+
return description;
|
|
92
|
+
const isGenericJobRequest = GENERIC_JOB_PHRASE.test(trimmed) ||
|
|
93
|
+
/\b(?:find|get|look(?:ing)?\s+for|want)\s+(?:to\s+)?(?:find\s+)?job\b/i.test(trimmed);
|
|
94
|
+
if (!isGenericJobRequest)
|
|
95
|
+
return description;
|
|
96
|
+
const qualifier = buildJobQualifierFromContext(userContext);
|
|
97
|
+
if (!qualifier)
|
|
98
|
+
return description;
|
|
99
|
+
const enriched = trimmed
|
|
100
|
+
.replace(/\ba job\b/i, `a ${qualifier}`)
|
|
101
|
+
.replace(/\bjob\b/i, `${qualifier}`)
|
|
102
|
+
.replace(/\s{2,}/g, " ")
|
|
103
|
+
.trim();
|
|
104
|
+
return enriched.length > 0 ? enriched : description;
|
|
105
|
+
};
|
|
106
|
+
export const isVague = (description, entropy, clarity) => {
|
|
107
|
+
if (GENERIC_JOB_PHRASE.test(description))
|
|
108
|
+
return true;
|
|
109
|
+
if (entropy > MAX_PERMISSIBLE_ENTROPY)
|
|
110
|
+
return true;
|
|
111
|
+
if (clarity < MIN_CLEAR_INTENT_SCORE)
|
|
112
|
+
return true;
|
|
113
|
+
return false;
|
|
114
|
+
};
|
|
115
|
+
export const getSpecificityWarning = (verdict) => {
|
|
116
|
+
const warning = verdict.specificity_warning?.trim();
|
|
117
|
+
return warning && warning.length > 0 ? warning : DEFAULT_SPECIFICITY_WARNING;
|
|
118
|
+
};
|
|
119
|
+
export const toSpeechActType = (classification) => {
|
|
120
|
+
if (classification === "COMMISSIVE" || classification === "DIRECTIVE")
|
|
121
|
+
return classification;
|
|
122
|
+
return null;
|
|
123
|
+
};
|
|
124
|
+
/**
|
|
125
|
+
* Factory class to build and compile the Intent Processing Graph.
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Generate a flat embedding for an intent payload, swallowing failures so
|
|
129
|
+
* persistence can continue without an embedding. `intentId` is logging-only
|
|
130
|
+
* (present for updates, absent for creates).
|
|
131
|
+
*/
|
|
132
|
+
export async function generateIntentEmbedding(deps, sanitizedPayload, intentId) {
|
|
133
|
+
if (!deps.embedder)
|
|
134
|
+
return undefined;
|
|
135
|
+
try {
|
|
136
|
+
const embedding = await deps.embedder.generate(sanitizedPayload, undefined, getAbortSignalConfig());
|
|
137
|
+
const flatEmbedding = Array.isArray(embedding?.[0])
|
|
138
|
+
? embedding[0]
|
|
139
|
+
: embedding;
|
|
140
|
+
logger.verbose("Generated embedding for intent", {
|
|
141
|
+
...(intentId ? { intentId } : {}),
|
|
142
|
+
dimensions: flatEmbedding?.length,
|
|
143
|
+
});
|
|
144
|
+
return flatEmbedding;
|
|
145
|
+
}
|
|
146
|
+
catch (embErr) {
|
|
147
|
+
logger.error("Failed to generate embedding for intent (continuing without)", {
|
|
148
|
+
...(intentId ? { intentId } : {}),
|
|
149
|
+
error: embErr,
|
|
150
|
+
});
|
|
151
|
+
return undefined;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
@@ -82,7 +82,7 @@ export declare const IntentGraphState: import("@langchain/langgraph").Annotation
|
|
|
82
82
|
*
|
|
83
83
|
* Defaults to 'create' for backward compatibility.
|
|
84
84
|
*/
|
|
85
|
-
operationMode: import("@langchain/langgraph").BaseChannel<"
|
|
85
|
+
operationMode: import("@langchain/langgraph").BaseChannel<"update" | "propose" | "create" | "delete" | "read", "update" | "propose" | "create" | "delete" | "read" | import("@langchain/langgraph").OverwriteValue<"update" | "propose" | "create" | "delete" | "read">, unknown>;
|
|
86
86
|
/**
|
|
87
87
|
* For update/delete operations, specifies which intent IDs to target.
|
|
88
88
|
* Optional - used when modifying or removing specific intents.
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { MaintenanceGraphState } from './maintenance.state.js';
|
|
1
2
|
/** Database methods needed by the maintenance graph (includes introducer discovery). */
|
|
2
3
|
export interface MaintenanceGraphDatabase {
|
|
3
4
|
getOpportunitiesForUser(userId: string, options?: {
|
|
@@ -43,14 +44,25 @@ export interface MaintenanceGraphQueue {
|
|
|
43
44
|
jobId?: string;
|
|
44
45
|
}): Promise<unknown>;
|
|
45
46
|
}
|
|
47
|
+
/**
|
|
48
|
+
* Factory for the Maintenance Graph.
|
|
49
|
+
* Accepts database, cache, and queue dependencies via constructor injection.
|
|
50
|
+
*/
|
|
51
|
+
/** The graph's channel state, as every node sees it. */
|
|
52
|
+
export type MaintenanceState = typeof MaintenanceGraphState.State;
|
|
53
|
+
/** Everything the maintenance nodes reach for. */
|
|
54
|
+
export interface MaintenanceGraphDeps {
|
|
55
|
+
database: MaintenanceGraphDatabase;
|
|
56
|
+
cache: MaintenanceGraphCache;
|
|
57
|
+
queue: MaintenanceGraphQueue;
|
|
58
|
+
}
|
|
46
59
|
/**
|
|
47
60
|
* Factory for the Maintenance Graph.
|
|
48
61
|
* Accepts database, cache, and queue dependencies via constructor injection.
|
|
49
62
|
*/
|
|
50
63
|
export declare class MaintenanceGraphFactory {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
private queue;
|
|
64
|
+
/** Resolved dependency bag shared by every node. */
|
|
65
|
+
readonly deps: MaintenanceGraphDeps;
|
|
54
66
|
constructor(database: MaintenanceGraphDatabase, cache: MaintenanceGraphCache, queue: MaintenanceGraphQueue);
|
|
55
67
|
/** Compile and return the maintenance graph. */
|
|
56
68
|
createGraph(): import("@langchain/langgraph").CompiledStateGraph<{
|
|
@@ -174,3 +186,54 @@ export declare class MaintenanceGraphFactory {
|
|
|
174
186
|
logMaintenance: {};
|
|
175
187
|
}, unknown, unknown, []>;
|
|
176
188
|
}
|
|
189
|
+
export declare function loadCurrentRadarNode(state: MaintenanceState, deps: MaintenanceGraphDeps): Promise<{
|
|
190
|
+
error: string;
|
|
191
|
+
currentOpportunities?: undefined;
|
|
192
|
+
expiredCount?: undefined;
|
|
193
|
+
activeIntents?: undefined;
|
|
194
|
+
lastRediscoveryAt?: undefined;
|
|
195
|
+
} | {
|
|
196
|
+
currentOpportunities: {
|
|
197
|
+
[key: string]: unknown;
|
|
198
|
+
id: string;
|
|
199
|
+
actors: Array<{
|
|
200
|
+
userId: string;
|
|
201
|
+
role: string;
|
|
202
|
+
}>;
|
|
203
|
+
status: string;
|
|
204
|
+
}[];
|
|
205
|
+
expiredCount: number;
|
|
206
|
+
activeIntents: {
|
|
207
|
+
id: string;
|
|
208
|
+
payload: string;
|
|
209
|
+
}[];
|
|
210
|
+
lastRediscoveryAt: number | null;
|
|
211
|
+
error?: undefined;
|
|
212
|
+
}>;
|
|
213
|
+
export declare function scoreRadarHealthNode(state: MaintenanceState): Promise<{
|
|
214
|
+
healthResult?: undefined;
|
|
215
|
+
connectorFlowCount?: undefined;
|
|
216
|
+
error?: undefined;
|
|
217
|
+
} | {
|
|
218
|
+
healthResult: import("../opportunities/radar/radar.health.js").RadarHealthResult;
|
|
219
|
+
connectorFlowCount: number;
|
|
220
|
+
error?: undefined;
|
|
221
|
+
} | {
|
|
222
|
+
error: string;
|
|
223
|
+
healthResult?: undefined;
|
|
224
|
+
connectorFlowCount?: undefined;
|
|
225
|
+
}>;
|
|
226
|
+
export declare function shouldRediscover(state: MaintenanceState): string;
|
|
227
|
+
export declare function rediscoverNode(state: MaintenanceState, deps: MaintenanceGraphDeps): Promise<{
|
|
228
|
+
rediscoveryJobsEnqueued: number;
|
|
229
|
+
error?: undefined;
|
|
230
|
+
} | {
|
|
231
|
+
error: string;
|
|
232
|
+
rediscoveryJobsEnqueued?: undefined;
|
|
233
|
+
}>;
|
|
234
|
+
export declare function introducerDiscoveryNode(state: MaintenanceState, deps: MaintenanceGraphDeps): Promise<{
|
|
235
|
+
introducerDiscoveryJobsEnqueued?: undefined;
|
|
236
|
+
} | {
|
|
237
|
+
introducerDiscoveryJobsEnqueued: number;
|
|
238
|
+
}>;
|
|
239
|
+
export declare function logMaintenanceNode(state: MaintenanceState): Promise<{}>;
|