@indexnetwork/protocol 11.1.0-rc.457.1 → 11.2.1-rc.459.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 CHANGED
@@ -20,6 +20,30 @@ went 6.7.1 → 8.0.2 with no 7.x in between because the whole 7.x line shipped a
20
20
  prereleases between the two promotions. To track every change, read `rc`; to
21
21
  pin a supported release, use `latest`.
22
22
 
23
+ ## 11.2.1 - 2026-08-11
24
+
25
+ ### Added
26
+
27
+ - Added the guarded historical-quality runtime for single-configuration,
28
+ dual-trigger shared-pool evaluation.
29
+
30
+ ### Fixed
31
+
32
+ - Hardened historical-quality readiness with attested database credentials,
33
+ frozen embedding requests, and fail-closed protected-base refresh gating.
34
+
35
+ ## 10.2.0 - 2026-08-10
36
+
37
+ ### Changed
38
+
39
+ - Refined the canonical V2 historical-quality artifact contract so execution
40
+ completeness is independent of verdict availability: complete filtered
41
+ case/trigger selections are valid descriptive evidence with
42
+ `completeness.complete: true` and
43
+ `measurement.qualityVerdictAvailable: false`; only complete full-corpus,
44
+ full-trigger selections may publish a quality verdict. Legacy and canonical
45
+ parser selection remain unchanged.
46
+
23
47
  ## 10.1.0 - 2026-08-07
24
48
 
25
49
  ### Added
@@ -28,6 +52,12 @@ pin a supported release, use `latest`.
28
52
 
29
53
  ## [Unreleased]
30
54
 
55
+ ### Added
56
+ - Full standalone Hermes capability policy (11.2.0): the `hermes-agent` principal has an explicit six-action MCP/REST policy while the existing `hermes-negotiator` principal remains restricted to its four scheduled negotiation handlers. Both policies default deny and preserve one-shot, generation-fenced negotiation authority.
57
+
58
+ ### Security
59
+ - The Hermes policy never exposes owner credentials, account-security, credential/permission/agent administration, billing, or unclassified tools; connector and owner-native callers receive only nonsecret response projections.
60
+
31
61
  ### Removed
32
62
  - Remove six unsupported shared interface/schema forwarding shims after migrating repository consumers to capability-owned domain and port modules; stable package-root exports remain unchanged.
33
63
  - Remove six unsupported tool-port forwarding shims and the deprecated unused discovery-question mapper; stable package-root exports remain unchanged.
@@ -75,12 +105,19 @@ pin a supported release, use `latest`.
75
105
  - Remove unsupported deprecated source/deep forwarding shims after migrating repository consumers to canonical modules; stable package-root exports are unchanged.
76
106
  - Add a fail-closed isolated provider-free test gate (10.1.1). Tooling-only
77
107
  safety foundation; no runtime or public API behavior changes.
108
+ - For the planned 10.2.0 release, refine the canonical V2 historical-quality
109
+ artifact contract so execution completeness is independent of verdict
110
+ availability: complete filtered case/trigger selections are valid descriptive
111
+ evidence with `completeness.complete: true` and
112
+ `measurement.qualityVerdictAvailable: false`; only complete full-corpus,
113
+ full-trigger selections may publish a quality verdict. Legacy and canonical
114
+ parser selection remain unchanged.
78
115
  - Share capability classification metadata between the existing architecture
79
116
  boundary gate and the protocol atlas generator; allowed dependency directions
80
117
  are unchanged.
81
118
 
82
119
  ### Security
83
- - The Hermes skill contract is restricted to the four negotiator tools, never treats model prose as authority, never forwards secrets or owner-private context, and relies on Index's validated action/consultation and bounded fallback paths. **This branch targets dev/private testing only. Production distribution remains blocked until the Mac owner credential is migrated to Keychain and the plaintext file/directory is removed, hardened runtime and App Sandbox are restored, the app is signed/notarized, and the credential TTL/revocation checklist is verified.**
120
+ - The Hermes skill contract is restricted to the four negotiator tools, never treats model prose as authority, never forwards secrets or owner-private context, and relies on Index's validated action/consultation and bounded fallback paths. **This branch targets dev/private testing only. Production distribution remains blocked until the Mac owner credential is migrated to Keychain and the plaintext file/directory is removed, Developer ID hardened-runtime signing and notarization are complete, and the credential TTL/revocation checklist is verified.**
84
121
 
85
122
  ### Fixed
86
123
  - Add an independent complete-payload golden digest and stronger audit/report leak
@@ -25,6 +25,12 @@ export type McpToolPermissionMap = ReadonlyMap<string, McpToolPermissionRequirem
25
25
  * Runtime-validates a capability-owned tool-to-permission mapping.
26
26
  */
27
27
  export declare function defineMcpToolPermissionMap(mapping: Readonly<Record<string, McpToolPermissionRequirement>>): McpToolPermissionMap;
28
+ /**
29
+ * Exact full-standalone Hermes MCP surface. Every admitted tool maps to one
30
+ * canonical action; absence is denial, including human-only, deletion,
31
+ * permission-management, agent-administration, and retired aliases.
32
+ */
33
+ export declare const HERMES_AGENT_MCP_TOOL_PERMISSIONS: McpToolPermissionMap;
28
34
  export declare const McpToolAccessRuleSchema: z.ZodEffects<z.ZodObject<{
29
35
  access: z.ZodEnum<["permission", "authenticated", "human_only", "agent_admin", "informational", "delivery_only", "removed"]>;
30
36
  actions: z.ZodOptional<z.ZodArray<z.ZodEnum<["manage:identity", "manage:premises", "manage:intents", "manage:networks", "manage:opportunities", "manage:negotiations"]>, "many">>;
@@ -113,10 +119,10 @@ export declare const McpPolicyAgentSnapshotSchema: z.ZodObject<{
113
119
  }[];
114
120
  }>;
115
121
  export type McpPolicyAgentSnapshot = z.infer<typeof McpPolicyAgentSnapshotSchema>;
116
- export declare const McpPrincipalProfileSchema: z.ZodEnum<["session_human", "onboarding_human", "enrollment_key", "unregistered_key", "registered_global_agent", "registered_network_agent", "delivery_agent", "invalid_agent"]>;
122
+ export declare const McpPrincipalProfileSchema: z.ZodEnum<["session_human", "onboarding_human", "enrollment_key", "unregistered_key", "registered_global_agent", "registered_network_agent", "hermes_agent", "delivery_agent", "invalid_agent"]>;
117
123
  export type McpPrincipalProfile = z.infer<typeof McpPrincipalProfileSchema>;
118
124
  export declare const McpCapabilitySubjectSchema: z.ZodObject<{
119
- profile: z.ZodEnum<["session_human", "onboarding_human", "enrollment_key", "unregistered_key", "registered_global_agent", "registered_network_agent", "delivery_agent", "invalid_agent"]>;
125
+ profile: z.ZodEnum<["session_human", "onboarding_human", "enrollment_key", "unregistered_key", "registered_global_agent", "registered_network_agent", "hermes_agent", "delivery_agent", "invalid_agent"]>;
120
126
  userId: z.ZodString;
121
127
  agentId: z.ZodOptional<z.ZodString>;
122
128
  agentType: z.ZodOptional<z.ZodEnum<["personal", "external", "system"]>>;
@@ -125,7 +131,7 @@ export declare const McpCapabilitySubjectSchema: z.ZodObject<{
125
131
  permissions: z.ZodArray<z.ZodEnum<["manage:identity", "manage:premises", "manage:intents", "manage:networks", "manage:opportunities", "manage:negotiations"]>, "many">;
126
132
  }, "strict", z.ZodTypeAny, {
127
133
  userId: string;
128
- profile: "session_human" | "onboarding_human" | "enrollment_key" | "unregistered_key" | "registered_global_agent" | "registered_network_agent" | "delivery_agent" | "invalid_agent";
134
+ profile: "session_human" | "onboarding_human" | "enrollment_key" | "unregistered_key" | "registered_global_agent" | "registered_network_agent" | "hermes_agent" | "delivery_agent" | "invalid_agent";
129
135
  permissions: ("manage:negotiations" | "manage:intents" | "manage:opportunities" | "manage:identity" | "manage:premises" | "manage:networks")[];
130
136
  networkScopeId: string | null;
131
137
  isOnboarding: boolean;
@@ -133,7 +139,7 @@ export declare const McpCapabilitySubjectSchema: z.ZodObject<{
133
139
  agentType?: "system" | "personal" | "external" | undefined;
134
140
  }, {
135
141
  userId: string;
136
- profile: "session_human" | "onboarding_human" | "enrollment_key" | "unregistered_key" | "registered_global_agent" | "registered_network_agent" | "delivery_agent" | "invalid_agent";
142
+ profile: "session_human" | "onboarding_human" | "enrollment_key" | "unregistered_key" | "registered_global_agent" | "registered_network_agent" | "hermes_agent" | "delivery_agent" | "invalid_agent";
137
143
  permissions: ("manage:negotiations" | "manage:intents" | "manage:opportunities" | "manage:identity" | "manage:premises" | "manage:networks")[];
138
144
  networkScopeId: string | null;
139
145
  isOnboarding: boolean;
@@ -26,6 +26,44 @@ export function defineMcpToolPermissionMap(mapping) {
26
26
  const parsed = McpToolPermissionMapSchema.parse(mapping);
27
27
  return new Map(Object.entries(parsed));
28
28
  }
29
+ /**
30
+ * Exact full-standalone Hermes MCP surface. Every admitted tool maps to one
31
+ * canonical action; absence is denial, including human-only, deletion,
32
+ * permission-management, agent-administration, and retired aliases.
33
+ */
34
+ export const HERMES_AGENT_MCP_TOOL_PERMISSIONS = defineMcpToolPermissionMap({
35
+ read_user_contexts: { action: 'manage:identity', reach: 'principal' },
36
+ preview_user_context: { action: 'manage:identity', reach: 'principal' },
37
+ confirm_user_context: { action: 'manage:identity', reach: 'principal' },
38
+ create_user_context: { action: 'manage:identity', reach: 'principal' },
39
+ update_user_context: { action: 'manage:identity', reach: 'principal' },
40
+ get_enrichment_run: { action: 'manage:identity', reach: 'principal' },
41
+ cancel_enrichment_run: { action: 'manage:identity', reach: 'principal' },
42
+ read_intents: { action: 'manage:intents', reach: 'network' },
43
+ search_intents: { action: 'manage:intents', reach: 'network' },
44
+ create_intent: { action: 'manage:intents', reach: 'network' },
45
+ update_intent: { action: 'manage:intents', reach: 'network' },
46
+ read_intent_indexes: { action: 'manage:intents', reach: 'network' },
47
+ create_intent_index: { action: 'manage:intents', reach: 'network' },
48
+ list_negotiations: { action: 'manage:negotiations', reach: 'network' },
49
+ get_negotiation: { action: 'manage:negotiations', reach: 'network' },
50
+ respond_to_negotiation: { action: 'manage:negotiations', reach: 'network' },
51
+ read_networks: { action: 'manage:networks', reach: 'network' },
52
+ read_network_memberships: { action: 'manage:networks', reach: 'network' },
53
+ create_network: { action: 'manage:networks', reach: 'network' },
54
+ update_network: { action: 'manage:networks', reach: 'network' },
55
+ create_network_membership: { action: 'manage:networks', reach: 'network' },
56
+ list_opportunities: { action: 'manage:opportunities', reach: 'network' },
57
+ update_opportunity: { action: 'manage:opportunities', reach: 'network' },
58
+ confirm_opportunity_delivery: { action: 'manage:opportunities', reach: 'network' },
59
+ read_premises: { action: 'manage:premises', reach: 'principal' },
60
+ create_premise: { action: 'manage:premises', reach: 'principal' },
61
+ update_premise: { action: 'manage:premises', reach: 'principal' },
62
+ retract_premise: { action: 'manage:premises', reach: 'principal' },
63
+ read_pending_questions: { action: 'manage:identity', reach: 'principal' },
64
+ read_activity_summary: { action: 'manage:identity', reach: 'principal' },
65
+ read_docs: { action: 'manage:identity', reach: 'principal' },
66
+ });
29
67
  export const McpToolAccessRuleSchema = z.object({
30
68
  access: z.enum([
31
69
  'permission',
@@ -216,6 +254,7 @@ export const McpPrincipalProfileSchema = z.enum([
216
254
  'unregistered_key',
217
255
  'registered_global_agent',
218
256
  'registered_network_agent',
257
+ 'hermes_agent',
219
258
  'delivery_agent',
220
259
  'invalid_agent',
221
260
  ]);
@@ -331,11 +370,13 @@ export function resolveMcpCapabilitySubject(input) {
331
370
  });
332
371
  }
333
372
  const agent = parsedAgent.data;
334
- const profile = identity.isDeliveryAgent === true
335
- ? 'delivery_agent'
336
- : identity.networkScopeId
337
- ? 'registered_network_agent'
338
- : 'registered_global_agent';
373
+ const profile = identity.isHermesAgent === true
374
+ ? 'hermes_agent'
375
+ : identity.isDeliveryAgent === true
376
+ ? 'delivery_agent'
377
+ : identity.networkScopeId
378
+ ? 'registered_network_agent'
379
+ : 'registered_global_agent';
339
380
  return McpCapabilitySubjectSchema.parse({
340
381
  profile,
341
382
  userId: identity.userId,
@@ -437,6 +478,24 @@ export class McpCapabilityPolicy {
437
478
  if (subject.isOnboarding && !ONBOARDING_ALLOWED.has(toolName)) {
438
479
  return { allowed: false, reason: 'onboarding_required', reach: rule.reach };
439
480
  }
481
+ if (subject.profile === 'hermes_agent') {
482
+ const requirement = HERMES_AGENT_MCP_TOOL_PERMISSIONS.get(toolName);
483
+ if (!requirement)
484
+ return { allowed: false, reason: 'tool_unclassified' };
485
+ return subject.permissions.includes(requirement.action)
486
+ ? {
487
+ allowed: true,
488
+ reason: 'permission_granted',
489
+ reach: requirement.reach,
490
+ requiredPermissions: [requirement.action],
491
+ }
492
+ : {
493
+ allowed: false,
494
+ reason: 'permission_missing',
495
+ reach: requirement.reach,
496
+ requiredPermissions: [requirement.action],
497
+ };
498
+ }
440
499
  if (rule.access === 'delivery_only') {
441
500
  return subject.profile === 'delivery_agent'
442
501
  ? { allowed: true, reason: 'delivery', reach: rule.reach }
@@ -31,8 +31,8 @@ export interface ModelConfig {
31
31
  /** Override the chat reasoning effort. Falls back to CHAT_REASONING_EFFORT env var. */
32
32
  chatReasoningEffort?: 'minimal' | 'low' | 'medium' | 'high' | 'xhigh';
33
33
  }
34
- /** Per-agent model settings before any eval-only override is applied. */
35
- declare function getBaseModelConfig(config?: ModelConfig): {
34
+ /** Per-agent model settings before canonical assignments are applied. */
35
+ declare function getBaseModelConfig(config?: ModelConfig): { [Agent in "intentInferrer" | "intentIndexer" | "intentVerifier" | "intentReconciler" | "intentClarifier" | "profileGenerator" | "hydeGenerator" | "hydeValidator" | "lensInferrer" | "opportunityEvaluator" | "opportunityPresenter" | "negotiator" | "negotiationScreener" | "negotiationReflector" | "homeCategorizer" | "suggestionGenerator" | "chatTitleGenerator" | "negotiationInsights" | "chatContextSummarizer" | "questioner" | "signalIntakePack" | "negotiationSummarizer" | "poolDiscriminatorMiner" | "poolDiscriminatorAssigner" | "negotiationEvidenceMiner" | "inviteGenerator" | "premiseAnalyzer" | "premiseDecomposer" | "premiseIndexer" | "userContextGenerator" | "networkRecommender" | "interruptClassifier" | "chat"]: Omit<{
36
36
  readonly intentInferrer: {
37
37
  readonly model: "google/gemini-2.5-flash";
38
38
  };
@@ -164,14 +164,16 @@ declare function getBaseModelConfig(config?: ModelConfig): {
164
164
  readonly maxTokens: 16;
165
165
  };
166
166
  readonly chat: {
167
- readonly model: string;
167
+ readonly model: "google/gemini-3-pro-preview";
168
168
  readonly maxTokens: 8192;
169
169
  readonly reasoning: {
170
170
  readonly effort: NonNullable<ModelSettings["reasoning"]>["effort"];
171
171
  readonly exclude: true;
172
172
  };
173
173
  };
174
- };
174
+ }[Agent], "model"> & {
175
+ model: string;
176
+ }; };
175
177
  /** Key identifying one of the per-agent model configurations. */
176
178
  export type ModelAgent = keyof ReturnType<typeof getBaseModelConfig>;
177
179
  /**
@@ -1,50 +1,8 @@
1
1
  import { ChatOpenAI } from "@langchain/openai";
2
- /**
3
- * Eval-only per-agent model overrides, e.g.
4
- * `EVAL_MODEL_OVERRIDES={"opportunityEvaluator":"anthropic/claude-sonnet-4"}`.
5
- *
6
- * Read on every call (no caching) to match the surrounding env convention, and
7
- * ignored entirely in production so a deployed process can never be repointed at
8
- * another model by an environment variable. A malformed value or an unknown agent
9
- * key throws: a typo must not silently produce a run that measured the default.
10
- */
11
- function readModelOverrides(agentKeys) {
12
- if (process.env.NODE_ENV === "production")
13
- return {};
14
- const raw = process.env.EVAL_MODEL_OVERRIDES?.trim();
15
- if (!raw)
16
- return {};
17
- let parsed;
18
- try {
19
- parsed = JSON.parse(raw);
20
- }
21
- catch (err) {
22
- // `new Error(msg, { cause })` needs lib ES2022; this package targets ES2020,
23
- // so the cause is attached after construction (same pattern as elsewhere in src).
24
- const wrapped = new Error(`EVAL_MODEL_OVERRIDES is not valid JSON: ${raw}`);
25
- wrapped.cause = err;
26
- throw wrapped;
27
- }
28
- if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
29
- throw new Error("EVAL_MODEL_OVERRIDES must be a JSON object of agent -> model id");
30
- }
31
- const overrides = {};
32
- for (const [agent, model] of Object.entries(parsed)) {
33
- if (!agentKeys.includes(agent)) {
34
- throw new Error(`EVAL_MODEL_OVERRIDES names an unknown agent "${agent}". Known agents: ${agentKeys.join(", ")}`);
35
- }
36
- if (typeof model !== "string" || model.trim() === "") {
37
- throw new Error(`EVAL_MODEL_OVERRIDES value for "${agent}" must be a non-empty model id string`);
38
- }
39
- // Store trimmed: surrounding whitespace in the JSON value would otherwise be
40
- // sent verbatim to OpenRouter as part of the model id.
41
- overrides[agent] = model.trim();
42
- }
43
- return overrides;
44
- }
45
- /** Per-agent model settings before any eval-only override is applied. */
2
+ import { resolveCanonicalAllAgentModels } from "./model.resolver.js";
3
+ /** Per-agent model settings before canonical assignments are applied. */
46
4
  function getBaseModelConfig(config) {
47
- return {
5
+ const settings = {
48
6
  intentInferrer: { model: "google/gemini-2.5-flash" },
49
7
  intentIndexer: { model: "google/gemini-2.5-flash" },
50
8
  intentVerifier: { model: "google/gemini-2.5-flash" },
@@ -78,7 +36,7 @@ function getBaseModelConfig(config) {
78
36
  networkRecommender: { model: "google/gemini-2.5-flash", temperature: 0.2, maxTokens: 512 },
79
37
  interruptClassifier: { model: "google/gemini-2.5-flash", temperature: 0.0, maxTokens: 16 },
80
38
  chat: {
81
- model: config?.chatModel ?? process.env.CHAT_MODEL ?? "google/gemini-3-pro-preview",
39
+ model: "google/gemini-3-pro-preview",
82
40
  maxTokens: 8192,
83
41
  reasoning: {
84
42
  effort: (config?.chatReasoningEffort ?? process.env.CHAT_REASONING_EFFORT ?? "low"),
@@ -86,22 +44,15 @@ function getBaseModelConfig(config) {
86
44
  },
87
45
  },
88
46
  };
47
+ const assignments = resolveCanonicalAllAgentModels({
48
+ CHAT_MODEL: config?.chatModel ?? process.env.CHAT_MODEL,
49
+ EVAL_MODEL_OVERRIDES: process.env.EVAL_MODEL_OVERRIDES,
50
+ }, { applyEvalOverrides: process.env.NODE_ENV !== "production" });
51
+ return Object.fromEntries(Object.entries(settings).map(([agent, value]) => [agent, { ...value, model: assignments[agent] }]));
89
52
  }
90
- /**
91
- * Per-agent model settings, with `EVAL_MODEL_OVERRIDES` applied when present.
92
- * Only the model id is overridable: temperature, token limits and reasoning
93
- * effort stay fixed so an eval measures a model swap and nothing else.
94
- */
53
+ /** Canonical assignments preserve sampling, token, and reasoning settings. */
95
54
  function getModelConfig(config) {
96
- const base = getBaseModelConfig(config);
97
- const overrides = readModelOverrides(Object.keys(base));
98
- if (Object.keys(overrides).length === 0)
99
- return base;
100
- const merged = Object.fromEntries(Object.entries(base).map(([agent, settings]) => {
101
- const model = overrides[agent];
102
- return [agent, model ? { ...settings, model } : settings];
103
- }));
104
- return merged;
55
+ return getBaseModelConfig(config);
105
56
  }
106
57
  /**
107
58
  * Returns the model name string for the given agent key.
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Canonical model-assignment authority for every protocol agent.
3
+ *
4
+ * The resolver is pure: callers provide the complete environment projection it
5
+ * may read. Historical eval planning uses the returned all-agent map so an
6
+ * unmentioned agent cannot drift behind an implicit runtime default.
7
+ */
8
+ export declare const CANONICAL_AGENT_MODEL_DEFAULTS: Readonly<{
9
+ readonly intentInferrer: "google/gemini-2.5-flash";
10
+ readonly intentIndexer: "google/gemini-2.5-flash";
11
+ readonly intentVerifier: "google/gemini-2.5-flash";
12
+ readonly intentReconciler: "google/gemini-2.5-flash";
13
+ readonly intentClarifier: "google/gemini-2.5-flash";
14
+ readonly profileGenerator: "google/gemini-2.5-flash";
15
+ readonly hydeGenerator: "google/gemini-2.5-flash";
16
+ readonly hydeValidator: "google/gemini-2.5-flash";
17
+ readonly lensInferrer: "google/gemini-2.5-flash";
18
+ readonly opportunityEvaluator: "google/gemini-2.5-flash";
19
+ readonly opportunityPresenter: "google/gemini-2.5-flash";
20
+ readonly negotiator: "google/gemini-2.5-flash";
21
+ readonly negotiationScreener: "google/gemini-2.5-flash";
22
+ readonly negotiationReflector: "google/gemini-2.5-flash";
23
+ readonly homeCategorizer: "google/gemini-2.5-flash";
24
+ readonly suggestionGenerator: "google/gemini-2.5-flash";
25
+ readonly chatTitleGenerator: "google/gemini-2.5-flash";
26
+ readonly negotiationInsights: "google/gemini-2.5-flash";
27
+ readonly chatContextSummarizer: "google/gemini-2.5-flash";
28
+ readonly questioner: "google/gemini-2.5-flash";
29
+ readonly signalIntakePack: "google/gemini-2.5-flash";
30
+ readonly negotiationSummarizer: "google/gemini-2.5-flash";
31
+ readonly poolDiscriminatorMiner: "google/gemini-2.5-flash";
32
+ readonly poolDiscriminatorAssigner: "google/gemini-2.5-flash";
33
+ readonly negotiationEvidenceMiner: "google/gemini-2.5-flash";
34
+ readonly inviteGenerator: "google/gemini-2.5-flash";
35
+ readonly premiseAnalyzer: "google/gemini-2.5-flash";
36
+ readonly premiseDecomposer: "google/gemini-2.5-flash";
37
+ readonly premiseIndexer: "google/gemini-2.5-flash";
38
+ readonly userContextGenerator: "google/gemini-2.5-flash";
39
+ readonly networkRecommender: "google/gemini-2.5-flash";
40
+ readonly interruptClassifier: "google/gemini-2.5-flash";
41
+ readonly chat: "google/gemini-3-pro-preview";
42
+ }>;
43
+ export type CanonicalModelAgent = keyof typeof CANONICAL_AGENT_MODEL_DEFAULTS;
44
+ export type CanonicalAllAgentModels = Readonly<Record<CanonicalModelAgent, string>>;
45
+ export declare const CANONICAL_MODEL_AGENTS: readonly ("intentInferrer" | "intentIndexer" | "intentVerifier" | "intentReconciler" | "intentClarifier" | "profileGenerator" | "hydeGenerator" | "hydeValidator" | "lensInferrer" | "opportunityEvaluator" | "opportunityPresenter" | "negotiator" | "negotiationScreener" | "negotiationReflector" | "homeCategorizer" | "suggestionGenerator" | "chatTitleGenerator" | "negotiationInsights" | "chatContextSummarizer" | "questioner" | "signalIntakePack" | "negotiationSummarizer" | "poolDiscriminatorMiner" | "poolDiscriminatorAssigner" | "negotiationEvidenceMiner" | "inviteGenerator" | "premiseAnalyzer" | "premiseDecomposer" | "premiseIndexer" | "userContextGenerator" | "networkRecommender" | "interruptClassifier" | "chat")[];
46
+ export declare function resolveCanonicalAllAgentModels(environment: Readonly<Record<string, string | undefined>>, options?: {
47
+ applyEvalOverrides?: boolean;
48
+ }): CanonicalAllAgentModels;
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Canonical model-assignment authority for every protocol agent.
3
+ *
4
+ * The resolver is pure: callers provide the complete environment projection it
5
+ * may read. Historical eval planning uses the returned all-agent map so an
6
+ * unmentioned agent cannot drift behind an implicit runtime default.
7
+ */
8
+ export const CANONICAL_AGENT_MODEL_DEFAULTS = Object.freeze({
9
+ intentInferrer: "google/gemini-2.5-flash",
10
+ intentIndexer: "google/gemini-2.5-flash",
11
+ intentVerifier: "google/gemini-2.5-flash",
12
+ intentReconciler: "google/gemini-2.5-flash",
13
+ intentClarifier: "google/gemini-2.5-flash",
14
+ profileGenerator: "google/gemini-2.5-flash",
15
+ hydeGenerator: "google/gemini-2.5-flash",
16
+ hydeValidator: "google/gemini-2.5-flash",
17
+ lensInferrer: "google/gemini-2.5-flash",
18
+ opportunityEvaluator: "google/gemini-2.5-flash",
19
+ opportunityPresenter: "google/gemini-2.5-flash",
20
+ negotiator: "google/gemini-2.5-flash",
21
+ negotiationScreener: "google/gemini-2.5-flash",
22
+ negotiationReflector: "google/gemini-2.5-flash",
23
+ homeCategorizer: "google/gemini-2.5-flash",
24
+ suggestionGenerator: "google/gemini-2.5-flash",
25
+ chatTitleGenerator: "google/gemini-2.5-flash",
26
+ negotiationInsights: "google/gemini-2.5-flash",
27
+ chatContextSummarizer: "google/gemini-2.5-flash",
28
+ questioner: "google/gemini-2.5-flash",
29
+ signalIntakePack: "google/gemini-2.5-flash",
30
+ negotiationSummarizer: "google/gemini-2.5-flash",
31
+ poolDiscriminatorMiner: "google/gemini-2.5-flash",
32
+ poolDiscriminatorAssigner: "google/gemini-2.5-flash",
33
+ negotiationEvidenceMiner: "google/gemini-2.5-flash",
34
+ inviteGenerator: "google/gemini-2.5-flash",
35
+ premiseAnalyzer: "google/gemini-2.5-flash",
36
+ premiseDecomposer: "google/gemini-2.5-flash",
37
+ premiseIndexer: "google/gemini-2.5-flash",
38
+ userContextGenerator: "google/gemini-2.5-flash",
39
+ networkRecommender: "google/gemini-2.5-flash",
40
+ interruptClassifier: "google/gemini-2.5-flash",
41
+ chat: "google/gemini-3-pro-preview",
42
+ });
43
+ export const CANONICAL_MODEL_AGENTS = Object.freeze(Object.keys(CANONICAL_AGENT_MODEL_DEFAULTS));
44
+ function parseOverrides(raw) {
45
+ if (raw?.trim() === undefined || raw.trim() === "")
46
+ return {};
47
+ let parsed;
48
+ try {
49
+ parsed = JSON.parse(raw);
50
+ }
51
+ catch {
52
+ throw new Error("EVAL_MODEL_OVERRIDES is not valid JSON");
53
+ }
54
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
55
+ throw new Error("EVAL_MODEL_OVERRIDES must be a JSON object of agent -> model id");
56
+ }
57
+ const overrides = {};
58
+ for (const [agent, model] of Object.entries(parsed)) {
59
+ if (!CANONICAL_MODEL_AGENTS.includes(agent)) {
60
+ throw new Error(`EVAL_MODEL_OVERRIDES names an unknown agent "${agent}". Known agents: ${CANONICAL_MODEL_AGENTS.join(", ")}`);
61
+ }
62
+ if (typeof model !== "string" || model.trim() === "") {
63
+ throw new Error(`EVAL_MODEL_OVERRIDES value for "${agent}" must be a non-empty model id string`);
64
+ }
65
+ overrides[agent] = model.trim();
66
+ }
67
+ return overrides;
68
+ }
69
+ export function resolveCanonicalAllAgentModels(environment, options = {}) {
70
+ const models = { ...CANONICAL_AGENT_MODEL_DEFAULTS };
71
+ const chatModel = environment.CHAT_MODEL?.trim();
72
+ if (chatModel)
73
+ models.chat = chatModel;
74
+ if (options.applyEvalOverrides !== false) {
75
+ Object.assign(models, parseOverrides(environment.EVAL_MODEL_OVERRIDES));
76
+ }
77
+ return Object.freeze(models);
78
+ }
@@ -48,6 +48,8 @@ export declare const McpResolvedIdentitySchema: z.ZodEffects<z.ZodObject<{
48
48
  isSessionAuth: z.ZodOptional<z.ZodBoolean>;
49
49
  enrollmentCapable: z.ZodOptional<z.ZodBoolean>;
50
50
  isDeliveryAgent: z.ZodOptional<z.ZodBoolean>;
51
+ /** Host-authenticated marker for the dedicated full standalone Hermes audience. */
52
+ isHermesAgent: z.ZodOptional<z.ZodBoolean>;
51
53
  networkScopeId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
52
54
  }, "strict", z.ZodTypeAny, {
53
55
  userId: string;
@@ -56,6 +58,7 @@ export declare const McpResolvedIdentitySchema: z.ZodEffects<z.ZodObject<{
56
58
  enrollmentCapable?: boolean | undefined;
57
59
  isDeliveryAgent?: boolean | undefined;
58
60
  isSessionAuth?: boolean | undefined;
61
+ isHermesAgent?: boolean | undefined;
59
62
  }, {
60
63
  userId: string;
61
64
  agentId?: string | undefined;
@@ -63,6 +66,7 @@ export declare const McpResolvedIdentitySchema: z.ZodEffects<z.ZodObject<{
63
66
  enrollmentCapable?: boolean | undefined;
64
67
  isDeliveryAgent?: boolean | undefined;
65
68
  isSessionAuth?: boolean | undefined;
69
+ isHermesAgent?: boolean | undefined;
66
70
  }>, {
67
71
  userId: string;
68
72
  agentId?: string | undefined;
@@ -70,6 +74,7 @@ export declare const McpResolvedIdentitySchema: z.ZodEffects<z.ZodObject<{
70
74
  enrollmentCapable?: boolean | undefined;
71
75
  isDeliveryAgent?: boolean | undefined;
72
76
  isSessionAuth?: boolean | undefined;
77
+ isHermesAgent?: boolean | undefined;
73
78
  }, {
74
79
  userId: string;
75
80
  agentId?: string | undefined;
@@ -77,5 +82,6 @@ export declare const McpResolvedIdentitySchema: z.ZodEffects<z.ZodObject<{
77
82
  enrollmentCapable?: boolean | undefined;
78
83
  isDeliveryAgent?: boolean | undefined;
79
84
  isSessionAuth?: boolean | undefined;
85
+ isHermesAgent?: boolean | undefined;
80
86
  }>;
81
87
  export type McpResolvedIdentity = z.infer<typeof McpResolvedIdentitySchema>;
@@ -28,6 +28,8 @@ export const McpResolvedIdentitySchema = z.object({
28
28
  isSessionAuth: z.boolean().optional(),
29
29
  enrollmentCapable: z.boolean().optional(),
30
30
  isDeliveryAgent: z.boolean().optional(),
31
+ /** Host-authenticated marker for the dedicated full standalone Hermes audience. */
32
+ isHermesAgent: z.boolean().optional(),
31
33
  networkScopeId: z.string().min(1).nullable().optional(),
32
34
  }).strict().superRefine((identity, ctx) => {
33
35
  if (identity.isSessionAuth === true && identity.agentId) {
@@ -44,4 +46,11 @@ export const McpResolvedIdentitySchema = z.object({
44
46
  message: 'Delivery-agent designation requires an agent ID.',
45
47
  });
46
48
  }
49
+ if (identity.isHermesAgent === true && !identity.agentId) {
50
+ ctx.addIssue({
51
+ code: z.ZodIssueCode.custom,
52
+ path: ['isHermesAgent'],
53
+ message: 'Hermes-agent designation requires an agent ID.',
54
+ });
55
+ }
47
56
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@indexnetwork/protocol",
3
- "version": "11.1.0-rc.457.1",
3
+ "version": "11.2.1-rc.459.1",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",