@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 +8 -1
- package/dist/content-transfer/index.cjs +1 -1
- package/dist/content-transfer/index.js +1 -1
- package/dist/content-transfer/react/index.cjs +1 -1
- package/dist/content-transfer/react/index.js +1 -1
- package/dist/mandates/index.cjs +4 -4
- package/dist/mandates/index.d.cts +6 -6
- package/dist/mandates/index.d.ts +6 -6
- package/dist/mandates/index.js +4 -4
- package/dist/versions/index.cjs +231 -0
- package/dist/versions/index.d.cts +158 -0
- package/dist/versions/index.d.ts +158 -0
- package/dist/versions/index.js +208 -0
- package/dist/versions/react/index.cjs +1305 -0
- package/dist/versions/react/index.d.cts +137 -0
- package/dist/versions/react/index.d.ts +137 -0
- package/dist/versions/react/index.js +1302 -0
- package/package.json +23 -2
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
*/
|
package/dist/mandates/index.cjs
CHANGED
|
@@ -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: "
|
|
50
|
+
aidreamRevision: "3265c56d02c86272ed921537d89ca14880b3ded3",
|
|
51
51
|
generatorVersion: "1.0.0",
|
|
52
|
-
packageVersion: "0.59.
|
|
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.
|
|
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.
|
|
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:
|
|
9
|
+
* aidream revision: 3265c56d02c86272ed921537d89ca14880b3ded3
|
|
10
10
|
* generator version: 1.0.0
|
|
11
|
-
* package version: 0.59.
|
|
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: "
|
|
22
|
+
readonly aidreamRevision: "3265c56d02c86272ed921537d89ca14880b3ded3";
|
|
23
23
|
readonly generatorVersion: "1.0.0";
|
|
24
|
-
readonly packageVersion: "0.59.
|
|
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.
|
|
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.
|
|
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";
|
package/dist/mandates/index.d.ts
CHANGED
|
@@ -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:
|
|
9
|
+
* aidream revision: 3265c56d02c86272ed921537d89ca14880b3ded3
|
|
10
10
|
* generator version: 1.0.0
|
|
11
|
-
* package version: 0.59.
|
|
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: "
|
|
22
|
+
readonly aidreamRevision: "3265c56d02c86272ed921537d89ca14880b3ded3";
|
|
23
23
|
readonly generatorVersion: "1.0.0";
|
|
24
|
-
readonly packageVersion: "0.59.
|
|
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.
|
|
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.
|
|
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";
|
package/dist/mandates/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// mandates/keys.generated.ts
|
|
2
2
|
var MANDATE_KEYS_META = {
|
|
3
|
-
aidreamRevision: "
|
|
3
|
+
aidreamRevision: "3265c56d02c86272ed921537d89ca14880b3ded3",
|
|
4
4
|
generatorVersion: "1.0.0",
|
|
5
|
-
packageVersion: "0.59.
|
|
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.
|
|
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.
|
|
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 };
|