@ouro.bot/cli 0.1.0-alpha.345 → 0.1.0-alpha.346
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.json
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"_note": "This changelog is maintained as part of the PR/version-bump workflow. Agent-curated, not auto-generated. Agents read this file directly via read_file to understand what changed between versions.",
|
|
3
3
|
"versions": [
|
|
4
|
+
{
|
|
5
|
+
"version": "0.1.0-alpha.346",
|
|
6
|
+
"changes": [
|
|
7
|
+
"Effective provider bindings now have a shared resolver primitive that reads machine-local `state/providers.json`, summarizes machine-wide credential provenance from `~/.agentsecrets/providers.json` without exposing secrets, maps legacy facing names to lane names, and marks readiness stale when provider/model or credential revisions change."
|
|
8
|
+
]
|
|
9
|
+
},
|
|
4
10
|
{
|
|
5
11
|
"version": "0.1.0-alpha.345",
|
|
6
12
|
"changes": [
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.normalizeProviderLane = normalizeProviderLane;
|
|
4
|
+
exports.resolveEffectiveProviderBinding = resolveEffectiveProviderBinding;
|
|
5
|
+
const runtime_1 = require("../nerves/runtime");
|
|
6
|
+
const provider_credential_pool_1 = require("./provider-credential-pool");
|
|
7
|
+
const provider_state_1 = require("./provider-state");
|
|
8
|
+
function legacyLaneWarning(selector, lane) {
|
|
9
|
+
return {
|
|
10
|
+
code: "legacy-lane-selector",
|
|
11
|
+
message: `${selector} is legacy provider wording; using ${lane} lane`,
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
function normalizeProviderLane(selector) {
|
|
15
|
+
switch (selector) {
|
|
16
|
+
case "outward":
|
|
17
|
+
return { lane: "outward", warnings: [] };
|
|
18
|
+
case "inner":
|
|
19
|
+
return { lane: "inner", warnings: [] };
|
|
20
|
+
case "human":
|
|
21
|
+
case "humanFacing":
|
|
22
|
+
return { lane: "outward", warnings: [legacyLaneWarning(selector, "outward")] };
|
|
23
|
+
case "agent":
|
|
24
|
+
case "agentFacing":
|
|
25
|
+
return { lane: "inner", warnings: [legacyLaneWarning(selector, "inner")] };
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function buildUseRepair(agentName, lane, force = false) {
|
|
29
|
+
return {
|
|
30
|
+
command: `ouro use --agent ${agentName} --lane ${lane} --provider <provider> --model <model>${force ? " --force" : ""}`,
|
|
31
|
+
message: force
|
|
32
|
+
? `Rewrite this machine's ${lane} provider binding for ${agentName}.`
|
|
33
|
+
: `Choose the provider/model this machine should use for ${agentName}'s ${lane} lane.`,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
function buildAuthRepair(agentName, provider) {
|
|
37
|
+
return {
|
|
38
|
+
command: `ouro auth --agent ${agentName} --provider ${provider}`,
|
|
39
|
+
message: `Authenticate ${provider} once for this machine's shared credential pool.`,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
function missingProviderStateWarning(agentName) {
|
|
43
|
+
return {
|
|
44
|
+
code: "provider-state-missing",
|
|
45
|
+
message: `No local provider binding exists for ${agentName} on this machine.`,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function invalidProviderStateWarning(agentName) {
|
|
49
|
+
return {
|
|
50
|
+
code: "provider-state-invalid",
|
|
51
|
+
message: `Local provider binding state for ${agentName} is invalid.`,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
function missingCredentialWarning(provider) {
|
|
55
|
+
return {
|
|
56
|
+
code: "credential-missing",
|
|
57
|
+
message: `${provider} has no credential record in the machine credential pool.`,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
function invalidCredentialPoolWarning(provider) {
|
|
61
|
+
return {
|
|
62
|
+
code: "credential-pool-invalid",
|
|
63
|
+
message: `${provider} cannot read credentials because the machine credential pool is invalid.`,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
function presentCredential(record) {
|
|
67
|
+
return {
|
|
68
|
+
status: "present",
|
|
69
|
+
provider: record.provider,
|
|
70
|
+
revision: record.revision,
|
|
71
|
+
source: record.provenance.source,
|
|
72
|
+
contributedByAgent: record.provenance.contributedByAgent,
|
|
73
|
+
updatedAt: record.updatedAt,
|
|
74
|
+
credentialFields: Object.keys(record.credentials).sort(),
|
|
75
|
+
configFields: Object.keys(record.config).sort(),
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
function resolveCredential(poolResult, provider, agentName) {
|
|
79
|
+
if (poolResult.ok) {
|
|
80
|
+
const record = poolResult.pool.providers[provider];
|
|
81
|
+
if (record)
|
|
82
|
+
return { credential: presentCredential(record), warnings: [] };
|
|
83
|
+
return {
|
|
84
|
+
credential: {
|
|
85
|
+
status: "missing",
|
|
86
|
+
provider,
|
|
87
|
+
poolPath: poolResult.poolPath,
|
|
88
|
+
repair: buildAuthRepair(agentName, provider),
|
|
89
|
+
},
|
|
90
|
+
warnings: [missingCredentialWarning(provider)],
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
if (poolResult.reason === "invalid") {
|
|
94
|
+
return {
|
|
95
|
+
credential: {
|
|
96
|
+
status: "invalid-pool",
|
|
97
|
+
provider,
|
|
98
|
+
poolPath: poolResult.poolPath,
|
|
99
|
+
error: poolResult.error,
|
|
100
|
+
repair: buildAuthRepair(agentName, provider),
|
|
101
|
+
},
|
|
102
|
+
warnings: [invalidCredentialPoolWarning(provider)],
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
return {
|
|
106
|
+
credential: {
|
|
107
|
+
status: "missing",
|
|
108
|
+
provider,
|
|
109
|
+
poolPath: poolResult.poolPath,
|
|
110
|
+
repair: buildAuthRepair(agentName, provider),
|
|
111
|
+
},
|
|
112
|
+
warnings: [missingCredentialWarning(provider)],
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
function readinessFromState(readiness) {
|
|
116
|
+
return {
|
|
117
|
+
status: readiness.status,
|
|
118
|
+
checkedAt: readiness.checkedAt,
|
|
119
|
+
credentialRevision: readiness.credentialRevision,
|
|
120
|
+
error: readiness.error,
|
|
121
|
+
attempts: readiness.attempts,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
function staleReadiness(readiness, reason) {
|
|
125
|
+
return {
|
|
126
|
+
...readinessFromState(readiness),
|
|
127
|
+
status: "stale",
|
|
128
|
+
previousStatus: readiness.status,
|
|
129
|
+
reason,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
function resolveReadiness(input) {
|
|
133
|
+
if (!input.readiness) {
|
|
134
|
+
if (input.credential.status === "missing") {
|
|
135
|
+
return { readiness: { status: "unknown", reason: "credential-missing" }, warnings: [] };
|
|
136
|
+
}
|
|
137
|
+
if (input.credential.status === "invalid-pool") {
|
|
138
|
+
return { readiness: { status: "unknown", reason: "credential-pool-invalid" }, warnings: [] };
|
|
139
|
+
}
|
|
140
|
+
return { readiness: { status: "unknown" }, warnings: [] };
|
|
141
|
+
}
|
|
142
|
+
if (input.readiness.provider !== input.provider || input.readiness.model !== input.model) {
|
|
143
|
+
return {
|
|
144
|
+
readiness: staleReadiness(input.readiness, "provider-model-changed"),
|
|
145
|
+
warnings: [{
|
|
146
|
+
code: "readiness-stale",
|
|
147
|
+
message: `${input.provider}/${input.model} readiness is stale because the last check was for ${input.readiness.provider}/${input.readiness.model}.`,
|
|
148
|
+
}],
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
if (input.credential.status === "present"
|
|
152
|
+
&& input.readiness.credentialRevision !== undefined
|
|
153
|
+
&& input.readiness.credentialRevision !== input.credential.revision) {
|
|
154
|
+
return {
|
|
155
|
+
readiness: staleReadiness(input.readiness, "credential-revision-changed"),
|
|
156
|
+
warnings: [{
|
|
157
|
+
code: "readiness-stale",
|
|
158
|
+
message: `${input.provider}/${input.model} readiness is stale because credential revision changed from ${input.readiness.credentialRevision} to ${input.credential.revision}.`,
|
|
159
|
+
}],
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
if (input.credential.status === "missing") {
|
|
163
|
+
return {
|
|
164
|
+
readiness: staleReadiness(input.readiness, "credential-missing"),
|
|
165
|
+
warnings: [],
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
if (input.credential.status === "invalid-pool") {
|
|
169
|
+
return {
|
|
170
|
+
readiness: staleReadiness(input.readiness, "credential-pool-invalid"),
|
|
171
|
+
warnings: [],
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
return { readiness: readinessFromState(input.readiness), warnings: [] };
|
|
175
|
+
}
|
|
176
|
+
function resolveEffectiveProviderBinding(input) {
|
|
177
|
+
const laneResolution = normalizeProviderLane(input.lane);
|
|
178
|
+
const stateResult = (0, provider_state_1.readProviderState)(input.agentRoot);
|
|
179
|
+
if (!stateResult.ok) {
|
|
180
|
+
const reason = stateResult.reason === "missing" ? "provider-state-missing" : "provider-state-invalid";
|
|
181
|
+
const stateWarning = stateResult.reason === "missing"
|
|
182
|
+
? missingProviderStateWarning(input.agentName)
|
|
183
|
+
: invalidProviderStateWarning(input.agentName);
|
|
184
|
+
const result = {
|
|
185
|
+
ok: false,
|
|
186
|
+
lane: laneResolution.lane,
|
|
187
|
+
reason,
|
|
188
|
+
statePath: stateResult.statePath,
|
|
189
|
+
warnings: [...laneResolution.warnings, stateWarning],
|
|
190
|
+
repair: buildUseRepair(input.agentName, laneResolution.lane, stateResult.reason === "invalid"),
|
|
191
|
+
};
|
|
192
|
+
(0, runtime_1.emitNervesEvent)({
|
|
193
|
+
component: "config/identity",
|
|
194
|
+
event: "config.provider_binding_resolution_failed",
|
|
195
|
+
message: "provider binding resolution failed",
|
|
196
|
+
meta: { agentName: input.agentName, lane: laneResolution.lane, reason },
|
|
197
|
+
});
|
|
198
|
+
return result;
|
|
199
|
+
}
|
|
200
|
+
const laneBinding = stateResult.state.lanes[laneResolution.lane];
|
|
201
|
+
const poolResult = (0, provider_credential_pool_1.readProviderCredentialPool)(input.homeDir);
|
|
202
|
+
const credentialResult = resolveCredential(poolResult, laneBinding.provider, input.agentName);
|
|
203
|
+
const readinessResult = resolveReadiness({
|
|
204
|
+
provider: laneBinding.provider,
|
|
205
|
+
model: laneBinding.model,
|
|
206
|
+
readiness: stateResult.state.readiness[laneResolution.lane],
|
|
207
|
+
credential: credentialResult.credential,
|
|
208
|
+
});
|
|
209
|
+
const warnings = [
|
|
210
|
+
...laneResolution.warnings,
|
|
211
|
+
...credentialResult.warnings,
|
|
212
|
+
...readinessResult.warnings,
|
|
213
|
+
];
|
|
214
|
+
const binding = {
|
|
215
|
+
lane: laneResolution.lane,
|
|
216
|
+
provider: laneBinding.provider,
|
|
217
|
+
model: laneBinding.model,
|
|
218
|
+
source: laneBinding.source,
|
|
219
|
+
machineId: stateResult.state.machineId,
|
|
220
|
+
statePath: stateResult.statePath,
|
|
221
|
+
credential: credentialResult.credential,
|
|
222
|
+
readiness: readinessResult.readiness,
|
|
223
|
+
warnings,
|
|
224
|
+
};
|
|
225
|
+
(0, runtime_1.emitNervesEvent)({
|
|
226
|
+
component: "config/identity",
|
|
227
|
+
event: "config.provider_binding_resolved",
|
|
228
|
+
message: "resolved effective provider binding",
|
|
229
|
+
meta: {
|
|
230
|
+
agentName: input.agentName,
|
|
231
|
+
lane: binding.lane,
|
|
232
|
+
provider: binding.provider,
|
|
233
|
+
model: binding.model,
|
|
234
|
+
credentialStatus: binding.credential.status,
|
|
235
|
+
readinessStatus: binding.readiness.status,
|
|
236
|
+
warningCount: warnings.length,
|
|
237
|
+
},
|
|
238
|
+
});
|
|
239
|
+
return { ok: true, binding };
|
|
240
|
+
}
|