@ai-matrx/agents 0.59.176 → 0.59.177

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
@@ -2,17 +2,24 @@
2
2
 
3
3
  ### Unreleased
4
4
 
5
+ - **New `./versions` and `./versions/react` entries: an agent's saved versions — list, compare, restore — moved from the web app (2026-10-21).** `./versions` (pure): `listAgentVersions`, `readAgentVersionSnapshot`, `resolveAgentVersionId`, `promoteAgentVersion` (restore, `agx_promote_version`), `declareContractBreak` over the host's supabase client (`VersionsClient`); `compareAgentDefinitions`, `AGENT_DIFF_OPTIONS`, `promoteFailureMessage`, `computeVersionFetchTargets`, `enrichVersions`, `snapshotToComparable`. `./versions/react`: `AgentDiffViewer` (ports: `enrichment`, `refs` for model/tool identity refs), `buildAgentAdapterRegistry`, `VersionHistoryTimeline` (presentational: the host passes load state, the contract-break write, row actions). New dependency `@ai-matrx/diff`. Consumer action: the web imports these instead of its own copies; Matrx 2 shows them.
6
+
5
7
  - **`ContextRulesChip` closes its compact popover on the first Escape even when a focused control has an open tooltip.** The tooltip dismissal layer previously took that key and left the popover visible. Consumer action: none.
6
8
 
7
9
  - **`useAgentSummary` looks an agent up by server search once per id per catalog (2026-10-19, Board remount law).** An agent tile that woke or remounted searched (`agx_search`) three times each time when the search found nothing; a found, missing or in-flight id is now asked once per tab, and a lookup that failed is forgotten so the next mount asks again. Consumer action: none.
8
10
 
9
11
  - **`toolPriceText` returns null for a zero-cost tool instead of "Free" (2026-10-18, law 14: no "Free").** Positive hints still read "N pts". Consumer action: none (callers already handle null).
10
12
 
11
- ## 0.59.176
13
+ ## 0.59.177
12
14
 
13
15
  UNVERIFIED: this release has no Unreleased entry and the source comparison could not be made (the caller supplied no source comparison). Whether source changed is unknown; consumer action is unknown.
14
16
  Check the package's gitHead on npm against this version's gitHead: `git diff <previous gitHead> <this gitHead> -- apps/shared/matrx-agents/src`.
15
17
 
18
+ ## 0.59.176
19
+
20
+ Automatic changed-only republish (docs/metadata drift since the last published version; verified: `git diff fd6c15b440 ca1c252bee -- apps/shared/matrx-agents/src`
21
+ has no shipped-source changes outside tests, fixtures and docs). No consumer action required.
22
+
16
23
  ## 0.59.175
17
24
 
18
25
  Automatic changed-only republish (docs/metadata drift since the last published version; verified: `git diff a1c540b807 fd6c15b440 -- apps/shared/matrx-agents/src`
@@ -703,7 +703,7 @@ var MANDATE_KEYS = {
703
703
  */
704
704
  brand_discovery__offering_roles: "brand_discovery.offering_roles",
705
705
  /**
706
- * @deprecated retiring since 0.59.176 — no longer declared in
706
+ * @deprecated retiring since 0.59.177 — no longer declared in
707
707
  * aidream. It leaves this union once no snapshot within the last
708
708
  * 3 published versions still carries it as active.
709
709
  */
@@ -680,7 +680,7 @@ var MANDATE_KEYS = {
680
680
  */
681
681
  brand_discovery__offering_roles: "brand_discovery.offering_roles",
682
682
  /**
683
- * @deprecated retiring since 0.59.176 — no longer declared in
683
+ * @deprecated retiring since 0.59.177 — no longer declared in
684
684
  * aidream. It leaves this union once no snapshot within the last
685
685
  * 3 published versions still carries it as active.
686
686
  */
@@ -656,7 +656,7 @@ var MANDATE_KEYS = {
656
656
  */
657
657
  brand_discovery__offering_roles: "brand_discovery.offering_roles",
658
658
  /**
659
- * @deprecated retiring since 0.59.176 — no longer declared in
659
+ * @deprecated retiring since 0.59.177 — no longer declared in
660
660
  * aidream. It leaves this union once no snapshot within the last
661
661
  * 3 published versions still carries it as active.
662
662
  */
@@ -628,7 +628,7 @@ var MANDATE_KEYS = {
628
628
  */
629
629
  brand_discovery__offering_roles: "brand_discovery.offering_roles",
630
630
  /**
631
- * @deprecated retiring since 0.59.176 — no longer declared in
631
+ * @deprecated retiring since 0.59.177 — no longer declared in
632
632
  * aidream. It leaves this union once no snapshot within the last
633
633
  * 3 published versions still carries it as active.
634
634
  */
@@ -47,9 +47,9 @@ module.exports = __toCommonJS(mandates_exports);
47
47
 
48
48
  // mandates/keys.generated.ts
49
49
  var MANDATE_KEYS_META = {
50
- aidreamRevision: "ca1c252beec48565c47288b33e1adbdffbd816a3",
50
+ aidreamRevision: "3265c56d02c86272ed921537d89ca14880b3ded3",
51
51
  generatorVersion: "1.0.0",
52
- packageVersion: "0.59.176",
52
+ packageVersion: "0.59.177",
53
53
  retireWindow: 3
54
54
  };
55
55
  var MANDATE_KEYS = {
@@ -666,7 +666,7 @@ var MANDATE_KEYS = {
666
666
  */
667
667
  brand_discovery__offering_roles: "brand_discovery.offering_roles",
668
668
  /**
669
- * @deprecated retiring since 0.59.176 — no longer declared in
669
+ * @deprecated retiring since 0.59.177 — no longer declared in
670
670
  * aidream. It leaves this union once no snapshot within the last
671
671
  * 3 published versions still carries it as active.
672
672
  */
@@ -693,7 +693,7 @@ var MANDATE_KEYS = {
693
693
  var ALL_MANDATE_KEYS = Object.values(MANDATE_KEYS);
694
694
  var RETIRING_MANDATE_KEYS = {
695
695
  "brand_discovery.offering_roles": "0.59.0",
696
- "coding_session.managed_translation_reference": "0.59.176",
696
+ "coding_session.managed_translation_reference": "0.59.177",
697
697
  "pdf.content_cleaner": "0.59.0",
698
698
  "sms.owner_beta": "0.59.0",
699
699
  "voice.owner_beta": "0.59.0"
@@ -6,9 +6,9 @@
6
6
  * from the IN-PROCESS mandate declarations — the same `declared_mandates()` the
7
7
  * boot sync writes to the database from. There is no hand list anywhere.
8
8
  *
9
- * aidream revision: ca1c252beec48565c47288b33e1adbdffbd816a3
9
+ * aidream revision: 3265c56d02c86272ed921537d89ca14880b3ded3
10
10
  * generator version: 1.0.0
11
- * package version: 0.59.176
11
+ * package version: 0.59.177
12
12
  * active keys: 606
13
13
  * retiring keys: 5
14
14
  *
@@ -19,9 +19,9 @@
19
19
  */
20
20
  /** Where this module came from — surfaced so a report can name the exact build. */
21
21
  declare const MANDATE_KEYS_META: {
22
- readonly aidreamRevision: "ca1c252beec48565c47288b33e1adbdffbd816a3";
22
+ readonly aidreamRevision: "3265c56d02c86272ed921537d89ca14880b3ded3";
23
23
  readonly generatorVersion: "1.0.0";
24
- readonly packageVersion: "0.59.176";
24
+ readonly packageVersion: "0.59.177";
25
25
  readonly retireWindow: 3;
26
26
  };
27
27
  /** Every declared mandate key, by THE IDENTIFIER RULE. */
@@ -639,7 +639,7 @@ declare const MANDATE_KEYS: {
639
639
  */
640
640
  readonly brand_discovery__offering_roles: "brand_discovery.offering_roles";
641
641
  /**
642
- * @deprecated retiring since 0.59.176 — no longer declared in
642
+ * @deprecated retiring since 0.59.177 — no longer declared in
643
643
  * aidream. It leaves this union once no snapshot within the last
644
644
  * 3 published versions still carries it as active.
645
645
  */
@@ -670,7 +670,7 @@ declare const ALL_MANDATE_KEYS: readonly MandateKey[];
670
670
  /** Keys still in the union but no longer declared (two-phase retire, phase 1). */
671
671
  declare const RETIRING_MANDATE_KEYS: {
672
672
  readonly "brand_discovery.offering_roles": "0.59.0";
673
- readonly "coding_session.managed_translation_reference": "0.59.176";
673
+ readonly "coding_session.managed_translation_reference": "0.59.177";
674
674
  readonly "pdf.content_cleaner": "0.59.0";
675
675
  readonly "sms.owner_beta": "0.59.0";
676
676
  readonly "voice.owner_beta": "0.59.0";
@@ -6,9 +6,9 @@
6
6
  * from the IN-PROCESS mandate declarations — the same `declared_mandates()` the
7
7
  * boot sync writes to the database from. There is no hand list anywhere.
8
8
  *
9
- * aidream revision: ca1c252beec48565c47288b33e1adbdffbd816a3
9
+ * aidream revision: 3265c56d02c86272ed921537d89ca14880b3ded3
10
10
  * generator version: 1.0.0
11
- * package version: 0.59.176
11
+ * package version: 0.59.177
12
12
  * active keys: 606
13
13
  * retiring keys: 5
14
14
  *
@@ -19,9 +19,9 @@
19
19
  */
20
20
  /** Where this module came from — surfaced so a report can name the exact build. */
21
21
  declare const MANDATE_KEYS_META: {
22
- readonly aidreamRevision: "ca1c252beec48565c47288b33e1adbdffbd816a3";
22
+ readonly aidreamRevision: "3265c56d02c86272ed921537d89ca14880b3ded3";
23
23
  readonly generatorVersion: "1.0.0";
24
- readonly packageVersion: "0.59.176";
24
+ readonly packageVersion: "0.59.177";
25
25
  readonly retireWindow: 3;
26
26
  };
27
27
  /** Every declared mandate key, by THE IDENTIFIER RULE. */
@@ -639,7 +639,7 @@ declare const MANDATE_KEYS: {
639
639
  */
640
640
  readonly brand_discovery__offering_roles: "brand_discovery.offering_roles";
641
641
  /**
642
- * @deprecated retiring since 0.59.176 — no longer declared in
642
+ * @deprecated retiring since 0.59.177 — no longer declared in
643
643
  * aidream. It leaves this union once no snapshot within the last
644
644
  * 3 published versions still carries it as active.
645
645
  */
@@ -670,7 +670,7 @@ declare const ALL_MANDATE_KEYS: readonly MandateKey[];
670
670
  /** Keys still in the union but no longer declared (two-phase retire, phase 1). */
671
671
  declare const RETIRING_MANDATE_KEYS: {
672
672
  readonly "brand_discovery.offering_roles": "0.59.0";
673
- readonly "coding_session.managed_translation_reference": "0.59.176";
673
+ readonly "coding_session.managed_translation_reference": "0.59.177";
674
674
  readonly "pdf.content_cleaner": "0.59.0";
675
675
  readonly "sms.owner_beta": "0.59.0";
676
676
  readonly "voice.owner_beta": "0.59.0";
@@ -1,8 +1,8 @@
1
1
  // mandates/keys.generated.ts
2
2
  var MANDATE_KEYS_META = {
3
- aidreamRevision: "ca1c252beec48565c47288b33e1adbdffbd816a3",
3
+ aidreamRevision: "3265c56d02c86272ed921537d89ca14880b3ded3",
4
4
  generatorVersion: "1.0.0",
5
- packageVersion: "0.59.176",
5
+ packageVersion: "0.59.177",
6
6
  retireWindow: 3
7
7
  };
8
8
  var MANDATE_KEYS = {
@@ -619,7 +619,7 @@ var MANDATE_KEYS = {
619
619
  */
620
620
  brand_discovery__offering_roles: "brand_discovery.offering_roles",
621
621
  /**
622
- * @deprecated retiring since 0.59.176 — no longer declared in
622
+ * @deprecated retiring since 0.59.177 — no longer declared in
623
623
  * aidream. It leaves this union once no snapshot within the last
624
624
  * 3 published versions still carries it as active.
625
625
  */
@@ -646,7 +646,7 @@ var MANDATE_KEYS = {
646
646
  var ALL_MANDATE_KEYS = Object.values(MANDATE_KEYS);
647
647
  var RETIRING_MANDATE_KEYS = {
648
648
  "brand_discovery.offering_roles": "0.59.0",
649
- "coding_session.managed_translation_reference": "0.59.176",
649
+ "coding_session.managed_translation_reference": "0.59.177",
650
650
  "pdf.content_cleaner": "0.59.0",
651
651
  "sms.owner_beta": "0.59.0",
652
652
  "voice.owner_beta": "0.59.0"
@@ -0,0 +1,231 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // versions/index.ts
21
+ var versions_exports = {};
22
+ __export(versions_exports, {
23
+ AGENT_DIFF_OPTIONS: () => AGENT_DIFF_OPTIONS,
24
+ AGENT_EXCLUDE_PATHS: () => AGENT_EXCLUDE_PATHS,
25
+ AGENT_IDENTITY_KEYS: () => AGENT_IDENTITY_KEYS,
26
+ AgentVersionsError: () => AgentVersionsError,
27
+ compareAgentDefinitions: () => compareAgentDefinitions,
28
+ computeVersionFetchTargets: () => computeVersionFetchTargets,
29
+ declareContractBreak: () => declareContractBreak,
30
+ enrichVersions: () => enrichVersions,
31
+ listAgentVersions: () => listAgentVersions,
32
+ promoteAgentVersion: () => promoteAgentVersion,
33
+ promoteFailureMessage: () => promoteFailureMessage,
34
+ readAgentVersionSnapshot: () => readAgentVersionSnapshot,
35
+ resolveAgentVersionId: () => resolveAgentVersionId,
36
+ snapshotToComparable: () => snapshotToComparable
37
+ });
38
+ module.exports = __toCommonJS(versions_exports);
39
+
40
+ // versions/constants.ts
41
+ var AGENT_EXCLUDE_PATHS = /* @__PURE__ */ new Set([
42
+ "id",
43
+ "userId",
44
+ "organizationId",
45
+ "taskId",
46
+ "createdAt",
47
+ "updatedAt",
48
+ "isVersion",
49
+ "parentAgentId",
50
+ "sourceAgentId",
51
+ "sourceSnapshotAt",
52
+ // Lineage and record bookkeeping: who made the row and which version it was
53
+ // copied from never change what the agent does, so a copy never "differs" here.
54
+ "sourceVersion",
55
+ "followsSource",
56
+ "createdBy",
57
+ "runCounts",
58
+ "isOwner",
59
+ "accessLevel",
60
+ "sharedByEmail",
61
+ "agentType",
62
+ "version",
63
+ "changeNote",
64
+ "changedAt"
65
+ ]);
66
+ var AGENT_IDENTITY_KEYS = {
67
+ variableDefinitions: "name",
68
+ contextPolicies: "key",
69
+ customTools: "name"
70
+ };
71
+ var AGENT_DIFF_OPTIONS = {
72
+ excludePaths: AGENT_EXCLUDE_PATHS,
73
+ identityKeys: AGENT_IDENTITY_KEYS,
74
+ // Output-schema property order is authored behavior: model providers often
75
+ // emit fields in schema order, so a reorder must be visible in version diffs.
76
+ orderSensitiveObjectPaths: /* @__PURE__ */ new Set(["outputSchema"]),
77
+ // Agent configuration is executable data. `_`/`__` keys (especially
78
+ // output-schema `__kind`) are contract fields, never hidden metadata.
79
+ skipUnderscorePrefix: false
80
+ };
81
+
82
+ // versions/compare.ts
83
+ var import_structural = require("@ai-matrx/diff/structural");
84
+ var AGENT_PROFILE_FIELDS = /* @__PURE__ */ new Set(["name", "description", "category", "tags"]);
85
+ var AGENT_LOCAL_STATE_FIELDS = /* @__PURE__ */ new Set([
86
+ "isActive",
87
+ "isArchived",
88
+ "isFavorite"
89
+ ]);
90
+ function toComparableAgentRecord(agent) {
91
+ return Object.fromEntries(
92
+ Object.entries(agent).filter(([key]) => !key.startsWith("_"))
93
+ );
94
+ }
95
+ function compareAgentDefinitions(systemAgent, personalAgent) {
96
+ const systemRecord = toComparableAgentRecord(systemAgent);
97
+ const personalRecord = toComparableAgentRecord(personalAgent);
98
+ const diffResult = (0, import_structural.computeDiff)(
99
+ systemRecord,
100
+ personalRecord,
101
+ AGENT_DIFF_OPTIONS
102
+ );
103
+ const changedFields = diffResult.root.filter(
104
+ (node) => node.changeType !== "unchanged"
105
+ );
106
+ const profileFields = changedFields.filter(
107
+ (node) => AGENT_PROFILE_FIELDS.has(node.key)
108
+ );
109
+ const localStateFields = changedFields.filter(
110
+ (node) => AGENT_LOCAL_STATE_FIELDS.has(node.key)
111
+ );
112
+ const behaviorFields = changedFields.filter(
113
+ (node) => !AGENT_PROFILE_FIELDS.has(node.key) && !AGENT_LOCAL_STATE_FIELDS.has(node.key)
114
+ );
115
+ return {
116
+ diffResult,
117
+ changedFields,
118
+ behaviorFields,
119
+ profileFields,
120
+ localStateFields,
121
+ behaviorMatches: behaviorFields.length === 0,
122
+ comparedConfigurationMatches: !diffResult.hasChanges
123
+ };
124
+ }
125
+
126
+ // versions/promote-failure-message.ts
127
+ var GENERIC = "Failed to promote version";
128
+ function promoteFailureMessage(err) {
129
+ const raw = err instanceof Error ? err.message : err && typeof err === "object" && "message" in err ? String(err.message ?? "") : typeof err === "string" ? err : "";
130
+ const reason = raw.trim();
131
+ return reason ? `${GENERIC}: ${reason}` : GENERIC;
132
+ }
133
+
134
+ // versions/enrich.ts
135
+ var import_structural2 = require("@ai-matrx/diff/structural");
136
+ function computeVersionFetchTargets(versions) {
137
+ if (versions.length === 0) return [];
138
+ const sorted = [...versions].sort((a, b) => b.version_number - a.version_number);
139
+ const targets = /* @__PURE__ */ new Set();
140
+ for (const v of sorted.slice(0, 10)) targets.add(v.version_number);
141
+ if (sorted.length <= 10) return [...targets];
142
+ targets.add(sorted[sorted.length - 1].version_number);
143
+ const remaining = sorted.slice(10, -1);
144
+ if (remaining.length > 0) {
145
+ const step = Math.max(1, Math.floor(remaining.length / Math.ceil(remaining.length / 10)));
146
+ for (let i = 0; i < remaining.length; i += step) targets.add(remaining[i].version_number);
147
+ }
148
+ return [...targets];
149
+ }
150
+ function enrichVersions(versions, snapshotOf) {
151
+ const sorted = [...versions].sort((a, b) => b.version_number - a.version_number);
152
+ return sorted.map((v, i) => {
153
+ const snapshot = snapshotOf(v.version_number);
154
+ const prev = sorted[i + 1];
155
+ const prevSnapshot = prev ? snapshotOf(prev.version_number) : void 0;
156
+ let diffSummary;
157
+ if (snapshot && prevSnapshot) {
158
+ diffSummary = (0, import_structural2.computeDiff)(
159
+ prevSnapshot,
160
+ snapshot,
161
+ AGENT_DIFF_OPTIONS
162
+ );
163
+ }
164
+ return { ...v, snapshotLoaded: !!snapshot, ...diffSummary ? { diffSummary } : {} };
165
+ });
166
+ }
167
+ var camel = (key) => key.replace(/_([a-z0-9])/g, (_, c) => c.toUpperCase());
168
+ function snapshotToComparable(row) {
169
+ const out = {};
170
+ for (const [key, value] of Object.entries(row)) {
171
+ const name = key === "version_number" ? "version" : camel(key);
172
+ out[name] = value;
173
+ }
174
+ return out;
175
+ }
176
+
177
+ // versions/data.ts
178
+ var AgentVersionsError = class extends Error {
179
+ code;
180
+ detail;
181
+ hint;
182
+ constructor(error) {
183
+ super(error.message || "The agent's versions could not be read and the database gave no reason.");
184
+ this.name = "AgentVersionsError";
185
+ this.code = error.code ?? null;
186
+ this.detail = error.details ?? null;
187
+ this.hint = error.hint ?? null;
188
+ }
189
+ };
190
+ async function listAgentVersions(client, query) {
191
+ const { data, error } = await client.rpc("agx_get_version_history", {
192
+ p_agent_id: query.agentId,
193
+ p_limit: query.limit ?? 50,
194
+ p_offset: query.offset ?? 0
195
+ });
196
+ if (error) throw new AgentVersionsError(error);
197
+ return Array.isArray(data) ? data : [];
198
+ }
199
+ async function readAgentVersionSnapshot(client, query) {
200
+ const { data, error } = await client.rpc("agx_get_version_snapshot", {
201
+ p_agent_id: query.agentId,
202
+ p_version_number: query.version
203
+ });
204
+ if (error) throw new AgentVersionsError(error);
205
+ const raw = Array.isArray(data) ? data[0] : data;
206
+ return raw && typeof raw === "object" ? raw : null;
207
+ }
208
+ async function resolveAgentVersionId(client, versionId) {
209
+ const { data, error } = await client.schema("agent").from("definition_version").select("id, agent_id, version_number, name").eq("id", versionId).maybeSingle();
210
+ if (error) throw new AgentVersionsError(error);
211
+ if (!data) return null;
212
+ const row = data;
213
+ return { versionId: row.id, agentId: row.agent_id, versionNumber: row.version_number, agentName: row.name };
214
+ }
215
+ async function promoteAgentVersion(client, query) {
216
+ const { data, error } = await client.rpc("agx_promote_version", {
217
+ p_agent_id: query.agentId,
218
+ p_version_number: query.version
219
+ });
220
+ if (error) throw new AgentVersionsError(error);
221
+ const result = data ?? {};
222
+ return { ...result, success: result.success === true };
223
+ }
224
+ async function declareContractBreak(client, query) {
225
+ const { error } = await client.rpc("agx_declare_contract_break", {
226
+ p_agent_id: query.agentId,
227
+ p_version_number: query.version,
228
+ p_kind: query.kind ?? void 0
229
+ });
230
+ if (error) throw new AgentVersionsError(error);
231
+ }
@@ -0,0 +1,158 @@
1
+ import { DiffOptions, DiffResult, DiffNode } from '@ai-matrx/diff/structural';
2
+
3
+ /** Internal/runtime fields that should never appear in diffs */
4
+ declare const AGENT_EXCLUDE_PATHS: Set<string>;
5
+ /** Identity keys for array matching — prevents false diffs when items shift position */
6
+ declare const AGENT_IDENTITY_KEYS: Record<string, string>;
7
+ declare const AGENT_DIFF_OPTIONS: DiffOptions;
8
+
9
+ /**
10
+ * Any agent record the diff can compare: the web's Redux `AgentDefinition`, a version snapshot
11
+ * mapped by `snapshotToComparable`, or a fixture. Only top-level keys matter to the comparison.
12
+ */
13
+ type ComparableAgent = object;
14
+ interface AgentDefinitionComparison {
15
+ diffResult: DiffResult;
16
+ changedFields: DiffNode[];
17
+ behaviorFields: DiffNode[];
18
+ profileFields: DiffNode[];
19
+ localStateFields: DiffNode[];
20
+ behaviorMatches: boolean;
21
+ comparedConfigurationMatches: boolean;
22
+ }
23
+ /**
24
+ * Compare two live agents through the same exclusions and identity rules as
25
+ * the canonical AgentDiffViewer, while separating behavior from expected
26
+ * personal-copy profile differences.
27
+ */
28
+ declare function compareAgentDefinitions(systemAgent: ComparableAgent, personalAgent: ComparableAgent): AgentDefinitionComparison;
29
+
30
+ declare function promoteFailureMessage(err: unknown): string;
31
+
32
+ /** One row of `agx_get_version_history`: a saved version of an agent (newest first). */
33
+ interface AgentVersionHistoryEntry {
34
+ version_id: string;
35
+ version_number: number;
36
+ name: string;
37
+ changed_at: string;
38
+ change_note: string | null;
39
+ contract_change: string | null;
40
+ contract_break_declared: string | null;
41
+ input_contract_hash: string | null;
42
+ output_contract_hash: string | null;
43
+ }
44
+ /** A version id resolved to its agent and number (`agent.definition_version`). */
45
+ interface AgentVersionLookup {
46
+ versionId: string;
47
+ agentId: string;
48
+ versionNumber: number;
49
+ agentName: string | null;
50
+ }
51
+ /** What `agx_promote_version` answers. */
52
+ interface PromoteVersionResult {
53
+ success: boolean;
54
+ error?: string;
55
+ promoted_version?: number;
56
+ agent_id?: string;
57
+ }
58
+ /** A contract break a person declares on a version (null clears the declaration). */
59
+ type ContractBreakKind = "input" | "output" | "both";
60
+ /** A history entry with what changed since the version before it, once both snapshots were read. */
61
+ interface EnrichedVersion extends AgentVersionHistoryEntry {
62
+ diffSummary?: DiffResult;
63
+ snapshotLoaded: boolean;
64
+ }
65
+ /** The load state the version timeline renders (the host owns where snapshots are kept). */
66
+ interface VersionHistoryLoad {
67
+ enrichedVersions: EnrichedVersion[];
68
+ loading: boolean;
69
+ progress: {
70
+ fetched: number;
71
+ total: number;
72
+ };
73
+ /** Versions whose snapshot read failed — never invisible. */
74
+ failedVersions: number[];
75
+ failureReason: string | null;
76
+ fetchEnrichedHistory: () => void | Promise<void>;
77
+ /** Read the named versions' snapshots (the timeline's Load on a gap). */
78
+ fetchGap: (versionNumbers: number[]) => void | Promise<void>;
79
+ }
80
+
81
+ /**
82
+ * The versions a "Load Full History" reads: the 10 newest, the oldest, and about every 10th in
83
+ * between — enough to say what changed across a long history without reading every snapshot.
84
+ */
85
+ declare function computeVersionFetchTargets(versions: readonly Pick<AgentVersionHistoryEntry, "version_number">[]): number[];
86
+ /**
87
+ * Each version (newest first) with `snapshotLoaded` and, when it and the version before it were
88
+ * both read, the diff between them. `snapshotOf` answers the host's stored snapshot or undefined.
89
+ */
90
+ declare function enrichVersions<V extends AgentVersionHistoryEntry>(versions: readonly V[], snapshotOf: (versionNumber: number) => ComparableAgent | undefined): (V & EnrichedVersion)[];
91
+ /**
92
+ * A raw `agx_get_version_snapshot` row in the agent-definition key names the diff adapters read
93
+ * (`model_id` → `modelId`, `variable_definitions` → `variableDefinitions`, …). Top-level keys only;
94
+ * values pass through untouched, so both sides of a comparison made this way read alike. A host
95
+ * with its own parsed agent records (the web's Redux store) compares those instead.
96
+ */
97
+ declare function snapshotToComparable(row: Record<string, unknown>): Record<string, unknown>;
98
+
99
+ /** The database's refusal, as supabase-js reports it. */
100
+ interface VersionsDbError {
101
+ message: string;
102
+ code?: string | null;
103
+ details?: string | null;
104
+ hint?: string | null;
105
+ }
106
+ type Answer = PromiseLike<{
107
+ data: unknown;
108
+ error: VersionsDbError | null;
109
+ }>;
110
+ /** The calls these reads make: a supabase-js client fits it as is. */
111
+ interface VersionsClient {
112
+ rpc(fn: string, args: Record<string, unknown>): Answer;
113
+ schema(name: "agent"): {
114
+ from(table: "definition_version"): {
115
+ select(columns: string): {
116
+ eq(column: string, value: string): {
117
+ maybeSingle(): Answer;
118
+ };
119
+ };
120
+ };
121
+ };
122
+ }
123
+ /** A refused or failed read, carrying the database's own sentence. */
124
+ declare class AgentVersionsError extends Error {
125
+ readonly code: string | null;
126
+ readonly detail: string | null;
127
+ readonly hint: string | null;
128
+ constructor(error: VersionsDbError);
129
+ }
130
+ /** One page of an agent's saved versions, newest first. */
131
+ declare function listAgentVersions(client: VersionsClient, query: {
132
+ agentId: string;
133
+ limit?: number;
134
+ offset?: number;
135
+ }): Promise<AgentVersionHistoryEntry[]>;
136
+ /** The raw snapshot row of one version (null: the database has no such version for this agent). */
137
+ declare function readAgentVersionSnapshot(client: VersionsClient, query: {
138
+ agentId: string;
139
+ version: number;
140
+ }): Promise<Record<string, unknown> | null>;
141
+ /** An immutable version id → its agent and number. RLS on agent.definition_version is the boundary. */
142
+ declare function resolveAgentVersionId(client: VersionsClient, versionId: string): Promise<AgentVersionLookup | null>;
143
+ /**
144
+ * Restore: make a past version the agent's current definition (`agx_promote_version`). A refusal
145
+ * throws with the database's sentence — show it with `promoteFailureMessage`.
146
+ */
147
+ declare function promoteAgentVersion(client: VersionsClient, query: {
148
+ agentId: string;
149
+ version: number;
150
+ }): Promise<PromoteVersionResult>;
151
+ /** Declare (or clear, with null) a contract break the hashes cannot see. */
152
+ declare function declareContractBreak(client: VersionsClient, query: {
153
+ agentId: string;
154
+ version: number;
155
+ kind: ContractBreakKind | null;
156
+ }): Promise<void>;
157
+
158
+ export { AGENT_DIFF_OPTIONS, AGENT_EXCLUDE_PATHS, AGENT_IDENTITY_KEYS, type AgentDefinitionComparison, type AgentVersionHistoryEntry, type AgentVersionLookup, AgentVersionsError, type ComparableAgent, type ContractBreakKind, type EnrichedVersion, type PromoteVersionResult, type VersionHistoryLoad, type VersionsClient, type VersionsDbError, compareAgentDefinitions, computeVersionFetchTargets, declareContractBreak, enrichVersions, listAgentVersions, promoteAgentVersion, promoteFailureMessage, readAgentVersionSnapshot, resolveAgentVersionId, snapshotToComparable };