@indexnetwork/protocol 66.0.0-rc.646.1 → 66.0.0-rc.650.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/README.md +27 -34
- package/dist/internal/intents/intent.preparer.d.ts +1 -0
- package/dist/internal/intents/intent.preparer.js +9 -18
- package/dist/internal/opportunities/opportunity.presentation.js +3 -2
- package/dist/internal/shared/agent/model.config.d.ts +2 -2
- package/dist/internal/shared/agent/model.config.js +2 -2
- package/dist/internal/shared/agent/model.resolver.d.ts +2 -2
- package/dist/internal/shared/agent/model.resolver.js +2 -2
- package/dist/protocol/protocol.prompt.d.ts +1 -1
- package/dist/protocol/protocol.prompt.js +6 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -31,8 +31,8 @@ flowchart LR
|
|
|
31
31
|
|
|
32
32
|
Scope --> CandidateGeneration[Candidate generation]
|
|
33
33
|
CandidateGeneration --> Evaluation[Evaluation]
|
|
34
|
-
Evaluation -->|plausible but uncertain| Opportunity[
|
|
35
|
-
Evaluation -->|clear fit| Opportunity[
|
|
34
|
+
Evaluation -->|plausible but uncertain| Opportunity[Negotiating opportunity]
|
|
35
|
+
Evaluation -->|clear fit| Opportunity[Pending opportunity]
|
|
36
36
|
Opportunity -->|needs agent clarification| Negotiation[Bounded negotiation]
|
|
37
37
|
Negotiation -->|fit established| Opportunity
|
|
38
38
|
Negotiation -->|human judgment required| Questions[Structured questions]
|
|
@@ -238,11 +238,11 @@ Opportunity states are participant-facing as follows:
|
|
|
238
238
|
|
|
239
239
|
| State | Participant-facing term | Meaning |
|
|
240
240
|
|---|---|---|
|
|
241
|
-
| **
|
|
242
|
-
| **
|
|
243
|
-
| **
|
|
244
|
-
| **
|
|
245
|
-
| **
|
|
241
|
+
| **negotiating** | Agents talking | The agents are negotiating whether the fit holds. |
|
|
242
|
+
| **pending** | Waiting on you | The agents agreed and the participants decide. A participant who already accepted sees Chat open: the first accept opens the conversation, and the status stays pending until every participant has accepted. |
|
|
243
|
+
| **accepted** | Connected | Every participant accepted. |
|
|
244
|
+
| **rejected** | Passed | An agent declined or a participant rejected the opportunity. |
|
|
245
|
+
| **expired** | Expired | An intent was archived. |
|
|
246
246
|
|
|
247
247
|
A conforming agent MUST NOT present a received opportunity as **Connected** without explicit approval from the receiving participant. The reference implementation enforces actor authorization and valid source statuses for acceptance, while current-approval capture is handled by the agent or user-interface flow invoking the transition.
|
|
248
248
|
|
|
@@ -250,33 +250,26 @@ A conforming agent MUST NOT present a received opportunity as **Connected** with
|
|
|
250
250
|
|
|
251
251
|
```mermaid
|
|
252
252
|
stateDiagram-v2
|
|
253
|
-
[*] -->
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
Only visible under role and scope rules.
|
|
253
|
+
[*] --> negotiating: agent opens it
|
|
254
|
+
negotiating --> pending: agents agree
|
|
255
|
+
negotiating --> rejected: agent declines
|
|
256
|
+
negotiating --> expired: intent archived
|
|
257
|
+
|
|
258
|
+
pending --> accepted: every participant accepts
|
|
259
|
+
pending --> rejected: participant rejects
|
|
260
|
+
pending --> expired: intent archived
|
|
261
|
+
|
|
262
|
+
accepted --> [*]
|
|
263
|
+
rejected --> [*]
|
|
264
|
+
expired --> [*]
|
|
265
|
+
|
|
266
|
+
note right of pending
|
|
267
|
+
Waiting on the participants.
|
|
268
|
+
The first accept opens the chat.
|
|
270
269
|
end note
|
|
271
270
|
|
|
272
|
-
note right of
|
|
273
|
-
|
|
274
|
-
Acceptance requires participant approval.
|
|
275
|
-
end note
|
|
276
|
-
|
|
277
|
-
note right of Connected
|
|
278
|
-
Relationship boundary crossed.
|
|
279
|
-
Conversation or introduction may proceed.
|
|
271
|
+
note right of accepted
|
|
272
|
+
Every participant accepted.
|
|
280
273
|
end note
|
|
281
274
|
```
|
|
282
275
|
|
|
@@ -300,11 +293,11 @@ sequenceDiagram
|
|
|
300
293
|
PR->>PR: Generate candidates inside scope
|
|
301
294
|
PR->>PR: Evaluate role fit and constraints
|
|
302
295
|
alt Fit is clear
|
|
303
|
-
PR-->>A:
|
|
296
|
+
PR-->>A: Pending opportunity with explanation
|
|
304
297
|
else Fit is uncertain
|
|
305
298
|
PR->>N: Start bounded negotiation
|
|
306
299
|
N-->>PR: Propose, counter, accept, reject, or question
|
|
307
|
-
PR-->>A:
|
|
300
|
+
PR-->>A: Pending opportunity or structured question
|
|
308
301
|
end
|
|
309
302
|
A->>P: Explain strongest reason and ask for approval
|
|
310
303
|
P-->>A: Approve, decline, or refine intent
|
|
@@ -49,4 +49,5 @@ export declare class IntentPreparer {
|
|
|
49
49
|
* @throws When rewriting, verification, or recovery generation fails; callers must retain the input for retry.
|
|
50
50
|
*/
|
|
51
51
|
invoke(input: PrepareInput, profileContext?: string): Promise<PrepareResult>;
|
|
52
|
+
private recoveryForm;
|
|
52
53
|
}
|
|
@@ -58,30 +58,21 @@ export class IntentPreparer {
|
|
|
58
58
|
]);
|
|
59
59
|
payload = payloadSchema.parse(result).payload;
|
|
60
60
|
}
|
|
61
|
+
// The form starts with verification: it only needs the draft, so a failed draft doesn't wait for it twice.
|
|
62
|
+
const recovery = this.recoveryForm(payload, answers);
|
|
63
|
+
recovery.catch(() => { }); // Unused when the draft is ready, or when verification throws first.
|
|
61
64
|
const verdict = await this.verifier.invoke(payload, profileContext);
|
|
62
65
|
const failure = admissionFailure(payload, verdict);
|
|
63
66
|
if (!failure)
|
|
64
67
|
return { status: "ready", payload, metadata: semanticMetadata(verdict) };
|
|
68
|
+
return { status: "needs_revision", payload, feedback: failure.message, recovery: await recovery };
|
|
69
|
+
}
|
|
70
|
+
async recoveryForm(payload, answers) {
|
|
65
71
|
const model = createStructuredModel("intentClarifier", recoverySchema, { name: "intent_recovery" });
|
|
66
72
|
const result = await invokeWithAbortSignal(model, [
|
|
67
|
-
new SystemMessage("Build one recovery form that helps the person concretize their intent. Return 2-6 fields. Each field needs a draft-specific label, a kind (single, multi, or text), and for single/multi 2-5 concrete options anchored to the draft. Text fields need a placeholder. Never re-ask what the draft or answers already settle. Options must be matchable and specific. Do not expose scores, classifications, JSON, or internal vocabulary."),
|
|
68
|
-
new HumanMessage(JSON.stringify({
|
|
69
|
-
payload,
|
|
70
|
-
answers,
|
|
71
|
-
feedback: failure.message,
|
|
72
|
-
category: failure.category,
|
|
73
|
-
classification: verdict.classification,
|
|
74
|
-
clarity: verdict.felicity_scores.clarity,
|
|
75
|
-
entropy: verdict.semantic_entropy,
|
|
76
|
-
referentialBreadth: verdict.referential_breadth,
|
|
77
|
-
missingConstraints: verdict.missing_selectional_constraints,
|
|
78
|
-
})),
|
|
73
|
+
new SystemMessage("Build one recovery form that helps the person concretize their intent. Assume the draft is too broad to match anyone yet: ask for whatever is missing among role, outcome, location, timeframe, domain, and concrete need. Return 2-6 fields. Each field needs a draft-specific label, a kind (single, multi, or text), and for single/multi 2-5 concrete options anchored to the draft. Text fields need a placeholder. Never re-ask what the draft or answers already settle. Options must be matchable and specific. Do not expose scores, classifications, JSON, or internal vocabulary."),
|
|
74
|
+
new HumanMessage(JSON.stringify({ payload, answers })),
|
|
79
75
|
]);
|
|
80
|
-
return
|
|
81
|
-
status: "needs_revision",
|
|
82
|
-
payload,
|
|
83
|
-
feedback: failure.message,
|
|
84
|
-
recovery: parseRecoveryFields(recoverySchema.parse(result)),
|
|
85
|
-
};
|
|
76
|
+
return parseRecoveryFields(recoverySchema.parse(result));
|
|
86
77
|
}
|
|
87
78
|
}
|
|
@@ -145,8 +145,9 @@ Rules:
|
|
|
145
145
|
**Negotiation-grounded explanations (ONLY when NEGOTIATION CONTEXT is provided):**
|
|
146
146
|
When NEGOTIATION CONTEXT is provided, this opportunity passed through an agent-to-agent negotiation. Use the transcript to ground your explanation in the concrete reasoning the agents exchanged.
|
|
147
147
|
- Personalize the summary with *why* the negotiation produced this match — reference the roles the agents agreed on, the specific concerns raised, and how they were resolved.
|
|
148
|
-
- For status "
|
|
149
|
-
- For status "
|
|
148
|
+
- For status "pending": the agents agreed and the viewer decides; the card should confidently explain *why* they agreed.
|
|
149
|
+
- For status "accepted": both people said yes; the card should explain *why* the agents agreed.
|
|
150
|
+
- For status "rejected": say who ended it. If the negotiation says one agent declined, the agents did; otherwise a person passed. The card should explain the reason briefly so the user understands — not dwell on it.
|
|
150
151
|
- Do NOT invent turn content. Only reference what is in the NEGOTIATION CONTEXT block.
|
|
151
152
|
|
|
152
153
|
`;
|
|
@@ -37,10 +37,10 @@ declare function getBaseModelConfig(config?: ModelConfig): { [Agent in "intentIn
|
|
|
37
37
|
readonly model: "google/gemini-3.7-flash";
|
|
38
38
|
};
|
|
39
39
|
readonly intentVerifier: {
|
|
40
|
-
readonly model: "google/gemini-
|
|
40
|
+
readonly model: "google/gemini-2.5-flash";
|
|
41
41
|
};
|
|
42
42
|
readonly intentClarifier: {
|
|
43
|
-
readonly model: "google/gemini-
|
|
43
|
+
readonly model: "google/gemini-2.5-flash";
|
|
44
44
|
};
|
|
45
45
|
readonly profileGenerator: {
|
|
46
46
|
readonly model: "google/gemini-3.7-flash";
|
|
@@ -5,8 +5,8 @@ const GEMINI_3_7_FLASH_MODEL = "google/gemini-3.7-flash";
|
|
|
5
5
|
function getBaseModelConfig(config) {
|
|
6
6
|
const settings = {
|
|
7
7
|
intentInferrer: { model: "google/gemini-3.7-flash" },
|
|
8
|
-
intentVerifier: { model: "google/gemini-
|
|
9
|
-
intentClarifier: { model: "google/gemini-
|
|
8
|
+
intentVerifier: { model: "google/gemini-2.5-flash" },
|
|
9
|
+
intentClarifier: { model: "google/gemini-2.5-flash" },
|
|
10
10
|
profileGenerator: { model: "google/gemini-3.7-flash" },
|
|
11
11
|
opportunityPresenter: { model: "google/gemini-3.7-flash" },
|
|
12
12
|
negotiator: { model: "google/gemini-3.7-flash" },
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
*/
|
|
8
8
|
export declare const CANONICAL_AGENT_MODEL_DEFAULTS: Readonly<{
|
|
9
9
|
readonly intentInferrer: "google/gemini-3.7-flash";
|
|
10
|
-
readonly intentVerifier: "google/gemini-
|
|
11
|
-
readonly intentClarifier: "google/gemini-
|
|
10
|
+
readonly intentVerifier: "google/gemini-2.5-flash";
|
|
11
|
+
readonly intentClarifier: "google/gemini-2.5-flash";
|
|
12
12
|
readonly profileGenerator: "google/gemini-3.7-flash";
|
|
13
13
|
readonly opportunityPresenter: "google/gemini-3.7-flash";
|
|
14
14
|
readonly negotiator: "google/gemini-3.7-flash";
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
*/
|
|
8
8
|
export const CANONICAL_AGENT_MODEL_DEFAULTS = Object.freeze({
|
|
9
9
|
intentInferrer: "google/gemini-3.7-flash",
|
|
10
|
-
intentVerifier: "google/gemini-
|
|
11
|
-
intentClarifier: "google/gemini-
|
|
10
|
+
intentVerifier: "google/gemini-2.5-flash",
|
|
11
|
+
intentClarifier: "google/gemini-2.5-flash",
|
|
12
12
|
profileGenerator: "google/gemini-3.7-flash",
|
|
13
13
|
opportunityPresenter: "google/gemini-3.7-flash",
|
|
14
14
|
negotiator: "google/gemini-3.7-flash",
|
|
@@ -5,7 +5,7 @@ export declare const NEGOTIATION_GUIDANCE = "You participate in the Index protoc
|
|
|
5
5
|
export declare const CANONICAL_GUIDANCE_TOPICS: readonly ["identity-context", "intents", "communities-networks", "opportunities", "negotiations", "workflows"];
|
|
6
6
|
export type CanonicalGuidanceTopic = (typeof CANONICAL_GUIDANCE_TOPICS)[number];
|
|
7
7
|
/** Summary served when GET /api/docs has no topic. */
|
|
8
|
-
export declare const CANONICAL_GUIDANCE_SUMMARY = "# Index Network Protocol\n\nIndex Network is a private, intent-driven discovery protocol. Users express intents, agents find matches within shared networks, and decisions proceed through clear gates.\n\n## Core Concepts\n\n**Identity & Context** \u2014 Account and presentation metadata plus scoped runtime state (networks, intents, stage).\n\n**Intents** \u2014 What users seek (intents, opportunities). Drive semantic matching.\n\n**Communities & Networks** \u2014 Private groups where members share intents and discover connections via shared membership.\n\n**Opportunities** \u2014 Discovered matches between users. Matches
|
|
8
|
+
export declare const CANONICAL_GUIDANCE_SUMMARY = "# Index Network Protocol\n\nIndex Network is a private, intent-driven discovery protocol. Users express intents, agents find matches within shared networks, and decisions proceed through clear gates.\n\n## Core Concepts\n\n**Identity & Context** \u2014 Account and presentation metadata plus scoped runtime state (networks, intents, stage).\n\n**Intents** \u2014 What users seek (intents, opportunities). Drive semantic matching.\n\n**Communities & Networks** \u2014 Private groups where members share intents and discover connections via shared membership.\n\n**Opportunities** \u2014 Discovered matches between users. Matches start negotiating; agreement advances to pending owner review, then accepted/rejected/expired.\n\n**Negotiations** \u2014 Agents coordinate, users approve. **A2A acceptance is not owner approval.** These are separate gates.\n\n**Workflows** \u2014 H2A (users express intents \u2192 agents discover) and A2A (agents coordinate) over the REST API. External agents use the Index CLI; the personal-agent runtime stays on the server. Human conversations are available through the conversation routes and commands.\n\n## Command interface\n\nUse the Index CLI with an explicit API origin: index --api-url <origin> ... --json.\nAuthenticate with browser login or one environment credential: INDEX_SESSION_TOKEN (Bearer) or INDEX_API_KEY (x-api-key). Keys do not bypass owner-session requirements.\nEvery capability is a named resource: /api/intents, /api/networks, /api/opportunities, /api/negotiations, /api/conversations, /api/scrape, /api/docs. The user's event stream is GET /api/events.\nUse the workflows topic for the resource routes and their CLI commands.\n\n## Canonical Topics\n\nRefer to these for detailed entity facts and lifecycle:\n\n- **identity-context** \u2014 Presentation identity, context scoping, matching inputs\n- **intents** \u2014 Intent inference, classification\n- **communities-networks** \u2014 Membership and explicit intent sharing\n- **opportunities** \u2014 Discovery, roles, reasoning\n- **negotiations** \u2014 Owner approval vs A2A, acceptance gates\n- **workflows** \u2014 H2A and A2A request sequences";
|
|
9
9
|
/**
|
|
10
10
|
* Detailed canonical topic content for GET /api/docs.
|
|
11
11
|
* Indexed by topic name; each contains current entity, capability, and lifecycle facts.
|
|
@@ -30,7 +30,7 @@ Index Network is a private, intent-driven discovery protocol. Users express inte
|
|
|
30
30
|
|
|
31
31
|
**Communities & Networks** — Private groups where members share intents and discover connections via shared membership.
|
|
32
32
|
|
|
33
|
-
**Opportunities** — Discovered matches between users. Matches
|
|
33
|
+
**Opportunities** — Discovered matches between users. Matches start negotiating; agreement advances to pending owner review, then accepted/rejected/expired.
|
|
34
34
|
|
|
35
35
|
**Negotiations** — Agents coordinate, users approve. **A2A acceptance is not owner approval.** These are separate gates.
|
|
36
36
|
|
|
@@ -131,16 +131,15 @@ Discovery is networked — it only finds matches within shared networks. This pr
|
|
|
131
131
|
**Opportunity** is a discovered connection between two or more users based on complementary intents and shared network membership. Each opportunity has:
|
|
132
132
|
- Parties (the people being connected)
|
|
133
133
|
- Roles (party)
|
|
134
|
-
- Status (
|
|
134
|
+
- Status (negotiating → pending owner review → accepted/rejected/expired)
|
|
135
135
|
- Match reasoning (why they're a good fit)
|
|
136
136
|
- Confidence score (0-1 from evaluation)
|
|
137
137
|
|
|
138
138
|
### Opportunity Lifecycle
|
|
139
|
-
1. **
|
|
140
|
-
2. **
|
|
141
|
-
3. **
|
|
142
|
-
4. **
|
|
143
|
-
5. **Rejected** or **Expired**: The opportunity no longer advances automatically.
|
|
139
|
+
1. **Negotiating**: Agents exchange structured turns under the negotiation rules.
|
|
140
|
+
2. **Pending**: Agent agreement recommends a connection for separate owner review. An owner's accept opens their chat right away; the status stays pending until every participant has accepted.
|
|
141
|
+
3. **Accepted**: Every participant has accepted.
|
|
142
|
+
4. **Rejected** or **Expired**: The opportunity no longer advances automatically. Expired means an intent was archived.
|
|
144
143
|
|
|
145
144
|
### Background Matching
|
|
146
145
|
Approved intents are evaluated in the background. GET /api/opportunities only reviews persisted opportunities; it does not start matching.
|