@indexnetwork/protocol 8.1.0-rc.421.1 → 8.2.0-rc.423.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 +47 -7
- package/dist/capabilities/opportunities.facade.d.ts +2 -0
- package/dist/capabilities/opportunities.facade.js +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/opportunity/application/opportunity.evaluator.d.ts +20 -6
- package/dist/opportunity/application/opportunity.evaluator.js +102 -45
- package/dist/opportunity/application/opportunity.graph.d.ts +8 -0
- package/dist/opportunity/application/opportunity.graph.js +233 -81
- package/dist/opportunity/discovery.env.d.ts +14 -0
- package/dist/opportunity/discovery.env.js +79 -0
- package/dist/opportunity/domain/opportunity.evidence.d.ts +2 -1
- package/dist/opportunity/domain/opportunity.evidence.js +11 -2
- package/dist/opportunity/domain/opportunity.state.d.ts +4 -2
- package/dist/opportunity/public/index.d.ts +2 -0
- package/dist/opportunity/public/index.js +2 -0
- package/dist/shared/interfaces/database.interface.d.ts +21 -2
- package/dist/shared/interfaces/embedder.interface.d.ts +16 -2
- package/dist/shared/schemas/network-assignment.schema.d.ts +10 -7
- package/dist/shared/schemas/network-assignment.schema.js +4 -1
- package/package.json +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -10,8 +10,45 @@ See [STABILITY.md](./STABILITY.md) for the public-contract and tier definitions.
|
|
|
10
10
|
> itemized. From `2.0.0` onward, keep this file updated as part of every release
|
|
11
11
|
> (bump `package.json` and the `[Unreleased]` section before promoting to `main`).
|
|
12
12
|
|
|
13
|
+
## Release model
|
|
14
|
+
|
|
15
|
+
Every push to `dev` publishes `<package.json version>-rc.<run>.<attempt>` under
|
|
16
|
+
the npm `rc` tag; `latest` moves only when `main` is promoted, and only if that
|
|
17
|
+
exact version is not already on npm. **Stable releases are therefore sparse and
|
|
18
|
+
skip versions on purpose** — most versions only ever exist as an `rc`. `latest`
|
|
19
|
+
went 6.7.1 → 8.0.2 with no 7.x in between because the whole 7.x line shipped as
|
|
20
|
+
prereleases between the two promotions. To track every change, read `rc`; to
|
|
21
|
+
pin a supported release, use `latest`.
|
|
22
|
+
|
|
13
23
|
## [Unreleased]
|
|
14
24
|
|
|
25
|
+
### Added
|
|
26
|
+
- Deterministic fast signal intake (#1307; 8.1.0). `SignalIntakePackGenerator`
|
|
27
|
+
precomputes a per-user intake brief plus round-1 question, and
|
|
28
|
+
`SignalIntakeOrchestrator` drives the funnel as a deterministic state machine
|
|
29
|
+
on flash instead of sequential pro turns, with synthesis speculated during a
|
|
30
|
+
deterministic community picker. New stable exports from the `signals` facade:
|
|
31
|
+
`SignalIntakePackGenerator`, `normalizeIntakePack`, `SignalIntakeOrchestrator`,
|
|
32
|
+
`answerLabel`, `FALLBACK_WHO_QUESTION`, `FALLBACK_BRING_QUESTION`, and the
|
|
33
|
+
`IntakePack` / `IntakePackInput` / `IntakePackQuestion` /
|
|
34
|
+
`IntakePackQuestionOption` / `IntakeAnswer` / `SynthesisInput` /
|
|
35
|
+
`SynthesisResult` types. Minor bump: additive surface only.
|
|
36
|
+
|
|
37
|
+
### Fixed
|
|
38
|
+
- `architecture:cycles` graphs runtime edges only (8.0.3). It counted `import
|
|
39
|
+
type` / `export type` edges, which TypeScript erases, so it reported a
|
|
40
|
+
7-module negotiation/questions cycle that no runtime can observe — penalizing
|
|
41
|
+
the capability-facade pattern of depending on a port *type* instead of an
|
|
42
|
+
implementation. Tooling only; no source or public-surface change. The full
|
|
43
|
+
`architecture:check` suite now passes and runs in CI.
|
|
44
|
+
|
|
45
|
+
## [8.0.2] — 2026-07-30
|
|
46
|
+
|
|
47
|
+
Promoted to npm `latest` on 2026-07-30, carrying the whole 7.6.0 → 8.0.2 line.
|
|
48
|
+
Those intermediate versions were published as `-rc` prereleases from `dev`
|
|
49
|
+
only, so `latest` moved 6.7.1 → 8.0.2 in one step; see **Release model**
|
|
50
|
+
above. Entries below keep the version they were developed under.
|
|
51
|
+
|
|
15
52
|
### Added
|
|
16
53
|
- Configurable negotiator stance `NEGOTIATOR_STANCE` (IND-611; 7.11.0), shipped
|
|
17
54
|
dark. `advocate` (default) | `evaluator` | `skeptic`, resolved by the new
|
|
@@ -39,12 +76,6 @@ See [STABILITY.md](./STABILITY.md) for the public-contract and tier definitions.
|
|
|
39
76
|
with that change; this entry and the regenerated export inventory record it.
|
|
40
77
|
|
|
41
78
|
### Fixed
|
|
42
|
-
- `architecture:cycles` graphs runtime edges only (8.0.3). It counted `import
|
|
43
|
-
type` / `export type` edges, which TypeScript erases, so it reported a
|
|
44
|
-
7-module negotiation/questions cycle that no runtime can observe — penalizing
|
|
45
|
-
the capability-facade pattern of depending on a port *type* instead of an
|
|
46
|
-
implementation. Tooling only; no source or public-surface change. The full
|
|
47
|
-
`architecture:check` suite now passes and runs in CI.
|
|
48
79
|
- Stop force-rewriting an opening-move refusal (IND-611 prerequisite; 7.11.0):
|
|
49
80
|
`negotiation.graph.ts` ran the turn-0 opening force *before* the IND-564
|
|
50
81
|
opening-withdraw guard, so a v2 initiator that judged a match not worth making
|
|
@@ -710,7 +741,16 @@ the matching/opportunity/premise eval harnesses, premise source tracking and
|
|
|
710
741
|
cascade retraction, network-scoped agents, and the agent registry. Reconstructed
|
|
711
742
|
from git history; not itemized.
|
|
712
743
|
|
|
713
|
-
|
|
744
|
+
<!--
|
|
745
|
+
Release tags stopped being created when publishing moved to the automated
|
|
746
|
+
subtree workflow: only v0.2.1 and v0.3.0 still exist in indexnetwork/protocol,
|
|
747
|
+
so every `compare/vX.Y.Z` link below 404s. They are kept for historical intent.
|
|
748
|
+
New entries link to the npm release instead, and [Unreleased] compares the
|
|
749
|
+
branches that actually define it.
|
|
750
|
+
-->
|
|
751
|
+
|
|
752
|
+
[Unreleased]: https://github.com/indexnetwork/protocol/compare/main...dev
|
|
753
|
+
[8.0.2]: https://www.npmjs.com/package/@indexnetwork/protocol/v/8.0.2
|
|
714
754
|
[4.3.0]: https://github.com/indexnetwork/protocol/compare/v4.2.0...v4.3.0
|
|
715
755
|
[4.2.0]: https://github.com/indexnetwork/protocol/compare/v4.1.0...v4.2.0
|
|
716
756
|
[4.1.0]: https://github.com/indexnetwork/protocol/compare/v4.0.0...v4.1.0
|
|
@@ -18,6 +18,8 @@ export { OpportunityPresenter, gatherPresenterContext } from "../opportunity/app
|
|
|
18
18
|
export type { PresenterDatabase } from "../opportunity/application/opportunity.presenter.js";
|
|
19
19
|
export { createOpportunityTools } from "../opportunity/application/opportunity.tools.js";
|
|
20
20
|
export type { OpportunityToolDeps } from "./opportunities.tools.port.js";
|
|
21
|
+
export { discoveryAllowedTypes, discoveryIntentMatchingEnabled, discoveryProfileMatchingEnabled, discoveryProfileSource, resetDiscoveryEnvWarningsForTests, } from "../opportunity/discovery.env.js";
|
|
22
|
+
export type { DiscoveryMatchType, DiscoveryProfileSource } from "../opportunity/discovery.env.js";
|
|
21
23
|
export { PoolDiscriminatorMiner } from "../opportunity/discriminator/discriminator.miner.js";
|
|
22
24
|
export { PoolDiscriminatorAssigner } from "../opportunity/discriminator/discriminator.assigner.js";
|
|
23
25
|
export type { PoolDiscriminatorAssignmentInput, PoolDiscriminatorAssignedAxis } from "../opportunity/discriminator/discriminator.assigner.js";
|
|
@@ -19,6 +19,8 @@ export { OpportunityEvaluator } from "../opportunity/application/opportunity.eva
|
|
|
19
19
|
export { OpportunityPresenter, gatherPresenterContext } from "../opportunity/application/opportunity.presenter.js";
|
|
20
20
|
// ── MCP tool factory ──────────────────────────────────────────────────────────
|
|
21
21
|
export { createOpportunityTools } from "../opportunity/application/opportunity.tools.js";
|
|
22
|
+
// ── Discovery env accessors ───────────────────────────────────────────────────
|
|
23
|
+
export { discoveryAllowedTypes, discoveryIntentMatchingEnabled, discoveryProfileMatchingEnabled, discoveryProfileSource, resetDiscoveryEnvWarningsForTests, } from "../opportunity/discovery.env.js";
|
|
22
24
|
// ── Pool discriminator (Lens A) ───────────────────────────────────────────────
|
|
23
25
|
export { PoolDiscriminatorMiner } from "../opportunity/discriminator/discriminator.miner.js";
|
|
24
26
|
export { PoolDiscriminatorAssigner } from "../opportunity/discriminator/discriminator.assigner.js";
|
package/dist/index.d.ts
CHANGED
|
@@ -89,6 +89,8 @@ export type { PoolDiscriminatorAssignmentInput, PoolDiscriminatorAssignedAxis }
|
|
|
89
89
|
export { runPoolDiscriminatorShadow } from "./capabilities/opportunities.facade.js";
|
|
90
90
|
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, } from "./capabilities/opportunities.facade.js";
|
|
91
91
|
export { poolQuestionsRanking, POOL_RERUN_DEBOUNCE_MS } from "./capabilities/opportunities.facade.js";
|
|
92
|
+
export { discoveryAllowedTypes, discoveryIntentMatchingEnabled, discoveryProfileMatchingEnabled, discoveryProfileSource, resetDiscoveryEnvWarningsForTests, } from "./capabilities/opportunities.facade.js";
|
|
93
|
+
export type { DiscoveryMatchType, DiscoveryProfileSource } from "./capabilities/opportunities.facade.js";
|
|
92
94
|
export { poolQuestionsVisitTrigger, POOL_VISIT_MINING_DEBOUNCE_MS } from "./capabilities/opportunities.facade.js";
|
|
93
95
|
export { buildPoolAdjustment, planPoolAdjustments, mergePoolAdjustment } from "./capabilities/opportunities.facade.js";
|
|
94
96
|
export type { PoolAdjustment, PoolAdjustmentSignal } from "./capabilities/opportunities.facade.js";
|
package/dist/index.js
CHANGED
|
@@ -74,6 +74,8 @@ export { PoolDiscriminatorAssigner } from "./capabilities/opportunities.facade.j
|
|
|
74
74
|
export { runPoolDiscriminatorShadow } from "./capabilities/opportunities.facade.js";
|
|
75
75
|
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, } from "./capabilities/opportunities.facade.js";
|
|
76
76
|
export { poolQuestionsRanking, POOL_RERUN_DEBOUNCE_MS } from "./capabilities/opportunities.facade.js";
|
|
77
|
+
// Discovery env accessors (IND-XXX)
|
|
78
|
+
export { discoveryAllowedTypes, discoveryIntentMatchingEnabled, discoveryProfileMatchingEnabled, discoveryProfileSource, resetDiscoveryEnvWarningsForTests, } from "./capabilities/opportunities.facade.js";
|
|
77
79
|
export { poolQuestionsVisitTrigger, POOL_VISIT_MINING_DEBOUNCE_MS } from "./capabilities/opportunities.facade.js";
|
|
78
80
|
export { buildPoolAdjustment, planPoolAdjustments, mergePoolAdjustment } from "./capabilities/opportunities.facade.js";
|
|
79
81
|
export { synthesizePoolQuestion, selectQuestionDiscriminators, toQuestionDiscriminator, BOTH_MATTER_LABEL } from "./capabilities/opportunities.facade.js";
|
|
@@ -77,7 +77,7 @@ declare const ActorSchema: z.ZodObject<{
|
|
|
77
77
|
intentId: string | null;
|
|
78
78
|
evidenceKey?: string | null | undefined;
|
|
79
79
|
}>;
|
|
80
|
-
declare const
|
|
80
|
+
declare const _OpportunityWithActorsSchema: z.ZodObject<{
|
|
81
81
|
reasoning: z.ZodString;
|
|
82
82
|
score: z.ZodNumber;
|
|
83
83
|
actors: z.ZodArray<z.ZodObject<{
|
|
@@ -116,9 +116,11 @@ declare const OpportunityWithActorsSchema: z.ZodObject<{
|
|
|
116
116
|
}[];
|
|
117
117
|
}>;
|
|
118
118
|
declare const entityBundleResponseFormat: z.ZodObject<{
|
|
119
|
-
|
|
120
|
-
|
|
119
|
+
verdicts: z.ZodArray<z.ZodObject<{
|
|
120
|
+
candidateId: z.ZodString;
|
|
121
|
+
accepted: z.ZodBoolean;
|
|
121
122
|
score: z.ZodNumber;
|
|
123
|
+
reasoning: z.ZodString;
|
|
122
124
|
actors: z.ZodArray<z.ZodObject<{
|
|
123
125
|
userId: z.ZodString;
|
|
124
126
|
role: z.ZodEnum<["agent", "patient", "peer"]>;
|
|
@@ -138,48 +140,60 @@ declare const entityBundleResponseFormat: z.ZodObject<{
|
|
|
138
140
|
}, "strip", z.ZodTypeAny, {
|
|
139
141
|
reasoning: string;
|
|
140
142
|
score: number;
|
|
143
|
+
accepted: boolean;
|
|
141
144
|
actors: {
|
|
142
145
|
userId: string;
|
|
143
146
|
role: "agent" | "patient" | "peer";
|
|
144
147
|
intentId: string | null;
|
|
145
148
|
evidenceKey?: string | null | undefined;
|
|
146
149
|
}[];
|
|
150
|
+
candidateId: string;
|
|
147
151
|
}, {
|
|
148
152
|
reasoning: string;
|
|
149
153
|
score: number;
|
|
154
|
+
accepted: boolean;
|
|
150
155
|
actors: {
|
|
151
156
|
userId: string;
|
|
152
157
|
role: "agent" | "patient" | "peer";
|
|
153
158
|
intentId: string | null;
|
|
154
159
|
evidenceKey?: string | null | undefined;
|
|
155
160
|
}[];
|
|
161
|
+
candidateId: string;
|
|
156
162
|
}>, "many">;
|
|
157
163
|
}, "strip", z.ZodTypeAny, {
|
|
158
|
-
|
|
164
|
+
verdicts: {
|
|
159
165
|
reasoning: string;
|
|
160
166
|
score: number;
|
|
167
|
+
accepted: boolean;
|
|
161
168
|
actors: {
|
|
162
169
|
userId: string;
|
|
163
170
|
role: "agent" | "patient" | "peer";
|
|
164
171
|
intentId: string | null;
|
|
165
172
|
evidenceKey?: string | null | undefined;
|
|
166
173
|
}[];
|
|
174
|
+
candidateId: string;
|
|
167
175
|
}[];
|
|
168
176
|
}, {
|
|
169
|
-
|
|
177
|
+
verdicts: {
|
|
170
178
|
reasoning: string;
|
|
171
179
|
score: number;
|
|
180
|
+
accepted: boolean;
|
|
172
181
|
actors: {
|
|
173
182
|
userId: string;
|
|
174
183
|
role: "agent" | "patient" | "peer";
|
|
175
184
|
intentId: string | null;
|
|
176
185
|
evidenceKey?: string | null | undefined;
|
|
177
186
|
}[];
|
|
187
|
+
candidateId: string;
|
|
178
188
|
}[];
|
|
179
189
|
}>;
|
|
180
190
|
export type EvaluatorActor = z.infer<typeof ActorSchema>;
|
|
181
|
-
export type EvaluatedOpportunityWithActors = z.infer<typeof
|
|
191
|
+
export type EvaluatedOpportunityWithActors = z.infer<typeof _OpportunityWithActorsSchema>;
|
|
182
192
|
export type EvaluatorOutputBundle = z.infer<typeof entityBundleResponseFormat>;
|
|
193
|
+
/** Raised only after both bounded attempts return an incomplete evaluator batch. */
|
|
194
|
+
export declare class EvaluatorIncompleteError extends Error {
|
|
195
|
+
constructor();
|
|
196
|
+
}
|
|
183
197
|
type Opportunity = z.infer<typeof OpportunitySchema>;
|
|
184
198
|
export interface CandidateProfile {
|
|
185
199
|
userId: string;
|
|
@@ -114,17 +114,17 @@ Match patterns to consider:
|
|
|
114
114
|
4. Intents+profile-to-intents+profile: Complementary or reciprocal goals between two or more people.
|
|
115
115
|
|
|
116
116
|
Output:
|
|
117
|
-
- A list of
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
117
|
+
- A list of verdicts with EXACTLY ONE verdict for EVERY candidate entity (never omit a candidate).
|
|
118
|
+
- Each verdict has candidateId (the candidate USER ID), accepted, reasoning, score, and actors.
|
|
119
|
+
- accepted=true verdicts must include exactly the source and that candidate as actors. accepted=false verdicts may use an empty actor list.
|
|
120
|
+
- Rejected candidates still require a verdict: set accepted=false and score below the appropriate threshold.
|
|
121
|
+
- A verdict score is 0-100:
|
|
122
|
+
- 90-100: Must Meet — candidate's PRIMARY role directly matches what the discoverer seeks.
|
|
123
|
+
- 70-89: Should Meet — meaningful overlap on role type AND complementary intent.
|
|
124
|
+
- 50-69: Worth Considering — tangential overlap only.
|
|
125
|
+
- <30: Complementary-role mismatch (candidate cannot fill the discoverer's open argument position), same-side match, or already acquainted.
|
|
126
|
+
- IMPORTANT: Every candidate must be represented once and only once. Do not return an opportunity list and do not omit rejected candidates.
|
|
127
|
+
- Actors in accepted verdicts:
|
|
128
128
|
- userId
|
|
129
129
|
- role: "agent" (can do something for others), "patient" (needs something from others), "peer" (symmetric collaboration)
|
|
130
130
|
- intentId (optional): if the match is intent-driven, the specific intent ID for that user
|
|
@@ -180,14 +180,55 @@ const ActorSchema = z.object({
|
|
|
180
180
|
.describe('If the match is intent-driven, the specific intent ID; null otherwise'),
|
|
181
181
|
evidenceKey: z.string().nullable().optional().describe('Stable evidence key for the matched entity; null if unknown'),
|
|
182
182
|
});
|
|
183
|
-
const
|
|
183
|
+
const _OpportunityWithActorsSchema = z.object({
|
|
184
184
|
reasoning: z.string(),
|
|
185
185
|
score: z.number().min(0).max(100),
|
|
186
186
|
actors: z.array(ActorSchema).min(2).describe('All actors in this opportunity with their roles'),
|
|
187
187
|
});
|
|
188
|
+
const EvaluatorVerdictSchema = z.object({
|
|
189
|
+
candidateId: z.string().describe('The candidate USER ID being evaluated'),
|
|
190
|
+
accepted: z.boolean().describe('Whether this candidate is a qualifying opportunity'),
|
|
191
|
+
score: z.number().min(0).max(100),
|
|
192
|
+
reasoning: z.string(),
|
|
193
|
+
actors: z.array(ActorSchema).describe('Accepted verdicts include source and candidate actors; rejected verdicts may use an empty list'),
|
|
194
|
+
});
|
|
188
195
|
const entityBundleResponseFormat = z.object({
|
|
189
|
-
|
|
196
|
+
verdicts: z.array(EvaluatorVerdictSchema).describe('Exactly one verdict for every candidate entity; include rejected candidates'),
|
|
190
197
|
});
|
|
198
|
+
/** Raised only after both bounded attempts return an incomplete evaluator batch. */
|
|
199
|
+
export class EvaluatorIncompleteError extends Error {
|
|
200
|
+
constructor() {
|
|
201
|
+
super('evaluator-incomplete');
|
|
202
|
+
this.name = 'EvaluatorIncompleteError';
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
function reconcileEvaluatorVerdicts(verdicts, candidateIds, discovererId, introductionMode) {
|
|
206
|
+
const expected = new Set(candidateIds);
|
|
207
|
+
const seen = new Set();
|
|
208
|
+
for (const verdict of verdicts) {
|
|
209
|
+
if (!expected.has(verdict.candidateId) || seen.has(verdict.candidateId)) {
|
|
210
|
+
throw new EvaluatorIncompleteError();
|
|
211
|
+
}
|
|
212
|
+
if (verdict.accepted) {
|
|
213
|
+
const expectedActorIds = introductionMode
|
|
214
|
+
? expected
|
|
215
|
+
: new Set([discovererId, verdict.candidateId]);
|
|
216
|
+
const actorIds = verdict.actors.map((actor) => actor.userId);
|
|
217
|
+
if (actorIds.length !== expectedActorIds.size ||
|
|
218
|
+
new Set(actorIds).size !== expectedActorIds.size ||
|
|
219
|
+
actorIds.some((actorId) => !expectedActorIds.has(actorId))) {
|
|
220
|
+
throw new EvaluatorIncompleteError();
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
seen.add(verdict.candidateId);
|
|
224
|
+
}
|
|
225
|
+
if (seen.size !== expected.size)
|
|
226
|
+
throw new EvaluatorIncompleteError();
|
|
227
|
+
return verdicts;
|
|
228
|
+
}
|
|
229
|
+
function isEvaluatorOutputError(error) {
|
|
230
|
+
return error instanceof z.ZodError || error instanceof EvaluatorIncompleteError;
|
|
231
|
+
}
|
|
191
232
|
export class OpportunityEvaluator {
|
|
192
233
|
constructor(options) {
|
|
193
234
|
this.model = createStructuredModel("opportunityEvaluator", responseFormat, {
|
|
@@ -376,41 +417,57 @@ ${renderOpportunityEvidenceForPrompt(e.evidence ?? [])}`;
|
|
|
376
417
|
new SystemMessage(entityBundleSystemPrompt),
|
|
377
418
|
new HumanMessage(humanContent),
|
|
378
419
|
];
|
|
420
|
+
const candidateIds = input.entities
|
|
421
|
+
.filter((entity) => entity.userId !== input.discovererId)
|
|
422
|
+
.map((entity) => entity.userId);
|
|
423
|
+
if (new Set(candidateIds).size !== candidateIds.length) {
|
|
424
|
+
throw new EvaluatorIncompleteError();
|
|
425
|
+
}
|
|
379
426
|
let parsedTotal = 0;
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
427
|
+
let incompleteReason;
|
|
428
|
+
for (let attempt = 0; attempt < 2; attempt++) {
|
|
429
|
+
try {
|
|
430
|
+
const result = await invokeWithAbortSignal(this.entityBundleModel, messages, options.signal);
|
|
431
|
+
const parsed = entityBundleResponseFormat.parse(result);
|
|
432
|
+
parsedTotal = parsed.verdicts.length;
|
|
433
|
+
const verdicts = reconcileEvaluatorVerdicts(parsed.verdicts, candidateIds, input.discovererId, input.introductionMode ?? false);
|
|
434
|
+
const accepted = verdicts
|
|
435
|
+
.filter((verdict) => verdict.accepted)
|
|
436
|
+
.map((verdict) => ({
|
|
437
|
+
reasoning: stripUuids(verdict.reasoning),
|
|
438
|
+
score: verdict.score,
|
|
439
|
+
actors: verdict.actors,
|
|
440
|
+
}))
|
|
441
|
+
.filter((op) => op.actors.length >= 2);
|
|
442
|
+
// Persistence safety is deterministic and precedes every score/returnAll
|
|
443
|
+
// path. Network/context placement is not typed support provenance, so an
|
|
444
|
+
// unsupported affiliation or presence claim rejects the whole result.
|
|
445
|
+
const claimSafe = accepted.filter((op) => !hasUnsupportedOpportunityClaim(op.reasoning));
|
|
446
|
+
const introGuard = input.introductionMode ? claimSafe.filter((op) => op.actors.length === 2) : claimSafe;
|
|
447
|
+
const filtered = introGuard.filter((op) => op.score >= minScore);
|
|
448
|
+
invokeEntityBundleLog.verbose('Done', {
|
|
449
|
+
total: verdicts.length,
|
|
450
|
+
afterClaimGuard: claimSafe.length,
|
|
451
|
+
afterIntroGuard: introGuard.length,
|
|
452
|
+
accepted: filtered.length,
|
|
453
|
+
returnAll,
|
|
454
|
+
});
|
|
455
|
+
return returnAll ? introGuard : filtered;
|
|
456
|
+
}
|
|
457
|
+
catch (error) {
|
|
458
|
+
if (!isEvaluatorOutputError(error))
|
|
459
|
+
throw error;
|
|
460
|
+
incompleteReason = error instanceof Error ? error.message : 'invalid output';
|
|
385
461
|
}
|
|
386
|
-
parsedTotal = parsed.opportunities.length;
|
|
387
|
-
// Persistence safety is deterministic and precedes every score/returnAll
|
|
388
|
-
// path. Network/context placement is not typed support provenance, so an
|
|
389
|
-
// unsupported affiliation or presence claim rejects the whole result.
|
|
390
|
-
const claimSafe = parsed.opportunities.filter((op) => !hasUnsupportedOpportunityClaim(op.reasoning));
|
|
391
|
-
const introGuard = input.introductionMode
|
|
392
|
-
? claimSafe.filter((op) => op.actors.length === 2)
|
|
393
|
-
: claimSafe;
|
|
394
|
-
const filtered = introGuard.filter((op) => op.score >= minScore);
|
|
395
|
-
invokeEntityBundleLog.verbose('Done', {
|
|
396
|
-
total: parsed.opportunities.length,
|
|
397
|
-
afterClaimGuard: claimSafe.length,
|
|
398
|
-
afterIntroGuard: introGuard.length,
|
|
399
|
-
accepted: filtered.length,
|
|
400
|
-
returnAll,
|
|
401
|
-
});
|
|
402
|
-
return returnAll ? introGuard : filtered;
|
|
403
|
-
}
|
|
404
|
-
catch (llmError) {
|
|
405
|
-
invokeEntityBundleLog.error('Failed', {
|
|
406
|
-
discovererId: input.discovererId,
|
|
407
|
-
totalEntities,
|
|
408
|
-
parsedTotal,
|
|
409
|
-
minScore,
|
|
410
|
-
llmError,
|
|
411
|
-
});
|
|
412
|
-
throw llmError;
|
|
413
462
|
}
|
|
463
|
+
invokeEntityBundleLog.error('Evaluator batch incomplete', {
|
|
464
|
+
discovererId: input.discovererId,
|
|
465
|
+
totalEntities,
|
|
466
|
+
parsedTotal,
|
|
467
|
+
minScore,
|
|
468
|
+
reason: incompleteReason,
|
|
469
|
+
});
|
|
470
|
+
throw new EvaluatorIncompleteError();
|
|
414
471
|
}
|
|
415
472
|
/**
|
|
416
473
|
* Factory method to expose the agent as a LangChain tool.
|
|
@@ -29,6 +29,8 @@ export type OpportunityEvaluatorLike = {
|
|
|
29
29
|
}>>;
|
|
30
30
|
invokeEntityBundle?: (input: EvaluatorInput, options: {
|
|
31
31
|
minScore?: number;
|
|
32
|
+
returnAll?: boolean;
|
|
33
|
+
signal?: AbortSignal;
|
|
32
34
|
}) => Promise<Array<{
|
|
33
35
|
reasoning: string;
|
|
34
36
|
score: number;
|
|
@@ -49,6 +51,12 @@ import { type StampNewbornOpportunitiesFn } from './opportunity.newborn-stamping
|
|
|
49
51
|
export type { QueueOpportunityNotificationFn } from './opportunity.lifecycle.js';
|
|
50
52
|
export type { StampNewbornOpportunitiesFn, StampNewbornOpportunitiesInput } from './opportunity.newborn-stamping.js';
|
|
51
53
|
export { buildPrioritizedNegotiationIntents } from './opportunity.existing-negotiation.js';
|
|
54
|
+
/**
|
|
55
|
+
* Error text can include provider response bodies, URLs, and credentials. Keep
|
|
56
|
+
* observability useful by retaining only a conservative error class at this
|
|
57
|
+
* boundary; detailed errors are intentionally not emitted from graph traces.
|
|
58
|
+
*/
|
|
59
|
+
export declare function safeOpportunityGraphError(_error: unknown): string;
|
|
52
60
|
/** Input shape for the HyDE graph invoke call (query-based embedding). */
|
|
53
61
|
export interface HydeGeneratorInvokeInput {
|
|
54
62
|
sourceType: 'query';
|