@evident-ai/cli 3.6.1-dev.37d1a87 → 3.6.1-dev.409b23d
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -0
- package/dist/index.js +574 -28
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -100,6 +100,26 @@ function clearCredentials() {
|
|
|
100
100
|
credentials.set("byEndpoint", byEndpoint);
|
|
101
101
|
hardenCredentialsPermissions();
|
|
102
102
|
}
|
|
103
|
+
function getManagedInferenceCredential(runnerId) {
|
|
104
|
+
hardenCredentialsPermissions();
|
|
105
|
+
return credentials.get("managedInferenceByEndpoint")?.[credentialsKey()]?.[runnerId];
|
|
106
|
+
}
|
|
107
|
+
function setManagedInferenceCredential(runnerId, credential) {
|
|
108
|
+
const byEndpoint = credentials.get("managedInferenceByEndpoint") ?? {};
|
|
109
|
+
byEndpoint[credentialsKey()] ??= {};
|
|
110
|
+
byEndpoint[credentialsKey()][runnerId] = credential;
|
|
111
|
+
credentials.set("managedInferenceByEndpoint", byEndpoint);
|
|
112
|
+
hardenCredentialsPermissions();
|
|
113
|
+
}
|
|
114
|
+
function clearManagedInferenceCredential(runnerId) {
|
|
115
|
+
const byEndpoint = credentials.get("managedInferenceByEndpoint") ?? {};
|
|
116
|
+
const runners = byEndpoint[credentialsKey()];
|
|
117
|
+
if (!runners || !(runnerId in runners)) return;
|
|
118
|
+
delete runners[runnerId];
|
|
119
|
+
if (Object.keys(runners).length === 0) delete byEndpoint[credentialsKey()];
|
|
120
|
+
credentials.set("managedInferenceByEndpoint", byEndpoint);
|
|
121
|
+
hardenCredentialsPermissions();
|
|
122
|
+
}
|
|
103
123
|
function clearAllCredentials() {
|
|
104
124
|
credentials.clear();
|
|
105
125
|
hardenCredentialsPermissions();
|
|
@@ -119,13 +139,13 @@ function getCliName() {
|
|
|
119
139
|
// src/lib/api.ts
|
|
120
140
|
async function request(path, method, body, headers = {}) {
|
|
121
141
|
const url = `${getApiUrlConfig()}${path}`;
|
|
122
|
-
const
|
|
142
|
+
const requestHeaders2 = {
|
|
123
143
|
"Content-Type": "application/json",
|
|
124
144
|
...headers
|
|
125
145
|
};
|
|
126
146
|
const response = await fetch(url, {
|
|
127
147
|
method,
|
|
128
|
-
headers:
|
|
148
|
+
headers: requestHeaders2,
|
|
129
149
|
body: body ? JSON.stringify(body) : void 0
|
|
130
150
|
});
|
|
131
151
|
if (!response.ok) {
|
|
@@ -1287,6 +1307,102 @@ var TUNNEL_USAGE_REARM_PING_PATH = "/__evident/usage-rearm";
|
|
|
1287
1307
|
var MAX_FILE_PUSH_BYTES = 64 * 1024;
|
|
1288
1308
|
var MAX_FILE_SYNC_DIRECTORIES = 16;
|
|
1289
1309
|
|
|
1310
|
+
// ../../packages/types/src/credential-proxy-native-config.ts
|
|
1311
|
+
var EVIDENT_PROXY_TOKEN_REFERENCE = "{env:EVIDENT_PROXY_TOKEN}";
|
|
1312
|
+
var CLAUDE_PROVIDER = {
|
|
1313
|
+
namespace: "evident-claude",
|
|
1314
|
+
name: "Evident Claude credential proxy",
|
|
1315
|
+
npm: "@ai-sdk/anthropic"
|
|
1316
|
+
};
|
|
1317
|
+
var NATIVE_PROVIDERS = {
|
|
1318
|
+
claude: CLAUDE_PROVIDER,
|
|
1319
|
+
anthropic: CLAUDE_PROVIDER,
|
|
1320
|
+
codex: {
|
|
1321
|
+
namespace: "evident-codex",
|
|
1322
|
+
name: "Evident Codex credential proxy",
|
|
1323
|
+
npm: "@ai-sdk/openai"
|
|
1324
|
+
},
|
|
1325
|
+
openai: {
|
|
1326
|
+
namespace: "evident-openai",
|
|
1327
|
+
name: "Evident OpenAI credential proxy",
|
|
1328
|
+
npm: "@ai-sdk/openai"
|
|
1329
|
+
},
|
|
1330
|
+
kimi: {
|
|
1331
|
+
namespace: "evident-kimi",
|
|
1332
|
+
name: "Evident Kimi credential proxy",
|
|
1333
|
+
npm: "@ai-sdk/openai-compatible",
|
|
1334
|
+
sdkName: "evident-kimi"
|
|
1335
|
+
},
|
|
1336
|
+
antigravity: {
|
|
1337
|
+
namespace: "evident-antigravity",
|
|
1338
|
+
name: "Evident Antigravity credential proxy",
|
|
1339
|
+
npm: "@ai-sdk/openai-compatible",
|
|
1340
|
+
sdkName: "evident-antigravity"
|
|
1341
|
+
},
|
|
1342
|
+
xai: {
|
|
1343
|
+
namespace: "evident-xai",
|
|
1344
|
+
name: "Evident xAI credential proxy",
|
|
1345
|
+
npm: "@ai-sdk/openai-compatible",
|
|
1346
|
+
sdkName: "evident-xai"
|
|
1347
|
+
},
|
|
1348
|
+
mistral: {
|
|
1349
|
+
namespace: "evident-mistral",
|
|
1350
|
+
name: "Evident Mistral credential proxy",
|
|
1351
|
+
npm: "@ai-sdk/openai-compatible",
|
|
1352
|
+
sdkName: "evident-mistral"
|
|
1353
|
+
}
|
|
1354
|
+
};
|
|
1355
|
+
var CREDENTIAL_PROXY_NATIVE_NAMESPACES = [
|
|
1356
|
+
...new Set(Object.values(NATIVE_PROVIDERS).map(({ namespace }) => namespace))
|
|
1357
|
+
];
|
|
1358
|
+
function credentialProxyInferenceUrl(baseUrl) {
|
|
1359
|
+
const trimmed = baseUrl.trim().replace(/\/+$/, "");
|
|
1360
|
+
return /\/v1$/i.test(trimmed) ? trimmed : `${trimmed}/v1`;
|
|
1361
|
+
}
|
|
1362
|
+
function buildCredentialProxyNativeConfig({
|
|
1363
|
+
inferenceBaseUrl,
|
|
1364
|
+
modelDescriptors
|
|
1365
|
+
}) {
|
|
1366
|
+
const baseURL = credentialProxyInferenceUrl(inferenceBaseUrl);
|
|
1367
|
+
const providers = {};
|
|
1368
|
+
const unsupportedProviders = /* @__PURE__ */ new Set();
|
|
1369
|
+
for (const descriptor of modelDescriptors) {
|
|
1370
|
+
const definition = NATIVE_PROVIDERS[descriptor.provider.trim().toLowerCase()];
|
|
1371
|
+
if (!definition) {
|
|
1372
|
+
unsupportedProviders.add(descriptor.provider.trim() || descriptor.provider);
|
|
1373
|
+
continue;
|
|
1374
|
+
}
|
|
1375
|
+
providers[definition.namespace] ??= definition.npm === "@ai-sdk/anthropic" ? {
|
|
1376
|
+
name: definition.name,
|
|
1377
|
+
npm: definition.npm,
|
|
1378
|
+
options: { baseURL, authToken: EVIDENT_PROXY_TOKEN_REFERENCE },
|
|
1379
|
+
models: {}
|
|
1380
|
+
} : definition.npm === "@ai-sdk/openai" ? {
|
|
1381
|
+
name: definition.name,
|
|
1382
|
+
npm: definition.npm,
|
|
1383
|
+
options: { baseURL, apiKey: EVIDENT_PROXY_TOKEN_REFERENCE },
|
|
1384
|
+
models: {}
|
|
1385
|
+
} : {
|
|
1386
|
+
name: definition.name,
|
|
1387
|
+
npm: definition.npm,
|
|
1388
|
+
options: {
|
|
1389
|
+
name: definition.sdkName,
|
|
1390
|
+
baseURL,
|
|
1391
|
+
apiKey: EVIDENT_PROXY_TOKEN_REFERENCE
|
|
1392
|
+
},
|
|
1393
|
+
models: {}
|
|
1394
|
+
};
|
|
1395
|
+
providers[definition.namespace].models[descriptor.id] = { name: descriptor.id };
|
|
1396
|
+
}
|
|
1397
|
+
return {
|
|
1398
|
+
unsupportedProviders: [...unsupportedProviders],
|
|
1399
|
+
config: {
|
|
1400
|
+
$schema: "https://opencode.ai/config.json",
|
|
1401
|
+
provider: providers
|
|
1402
|
+
}
|
|
1403
|
+
};
|
|
1404
|
+
}
|
|
1405
|
+
|
|
1290
1406
|
// ../../packages/types/src/logging/index.ts
|
|
1291
1407
|
var CORRELATION_ID_HEADER = "x-evident-correlation-id";
|
|
1292
1408
|
var FORWARD_FAILURE_REASON_HEADER = "X-Evident-Failure-Reason";
|
|
@@ -1326,7 +1442,7 @@ import ora4 from "ora";
|
|
|
1326
1442
|
import { select as select4 } from "@inquirer/prompts";
|
|
1327
1443
|
|
|
1328
1444
|
// src/lib/telemetry.ts
|
|
1329
|
-
var CLI_VERSION = (true ? "3.6.1-dev.
|
|
1445
|
+
var CLI_VERSION = (true ? "3.6.1-dev.409b23d" : void 0) ?? process.env.npm_package_version ?? "unknown";
|
|
1330
1446
|
function getCliVersion() {
|
|
1331
1447
|
return CLI_VERSION;
|
|
1332
1448
|
}
|
|
@@ -1407,7 +1523,7 @@ async function flushEvents() {
|
|
|
1407
1523
|
const controller = new AbortController();
|
|
1408
1524
|
const timeout = setTimeout(() => controller.abort(), FLUSH_TIMEOUT_MS);
|
|
1409
1525
|
try {
|
|
1410
|
-
const
|
|
1526
|
+
const request3 = {
|
|
1411
1527
|
events,
|
|
1412
1528
|
client_type: "cli",
|
|
1413
1529
|
client_version: CLI_VERSION
|
|
@@ -1418,7 +1534,7 @@ async function flushEvents() {
|
|
|
1418
1534
|
"Content-Type": "application/json",
|
|
1419
1535
|
Authorization: authHeader
|
|
1420
1536
|
},
|
|
1421
|
-
body: JSON.stringify(
|
|
1537
|
+
body: JSON.stringify(request3),
|
|
1422
1538
|
signal: controller.signal
|
|
1423
1539
|
});
|
|
1424
1540
|
if (!response.ok) {
|
|
@@ -3093,6 +3209,52 @@ async function getModelAttachmentCapability(port, model, client) {
|
|
|
3093
3209
|
return null;
|
|
3094
3210
|
}
|
|
3095
3211
|
}
|
|
3212
|
+
async function isPinnedProviderLoaded(port, model, client) {
|
|
3213
|
+
if (client?.version === "v2") return null;
|
|
3214
|
+
const { model: baseModel } = splitModelVariant(model);
|
|
3215
|
+
if (!baseModel) return null;
|
|
3216
|
+
const slash = baseModel.indexOf("/");
|
|
3217
|
+
if (slash <= 0) return null;
|
|
3218
|
+
const providerId = baseModel.slice(0, slash);
|
|
3219
|
+
try {
|
|
3220
|
+
const res = await requestWithClient(port, client, "/config/providers");
|
|
3221
|
+
if (!res.ok) {
|
|
3222
|
+
console.error(
|
|
3223
|
+
`[isPinnedProviderLoaded] GET /config/providers returned HTTP ${res.status} (port ${port})`
|
|
3224
|
+
);
|
|
3225
|
+
return null;
|
|
3226
|
+
}
|
|
3227
|
+
const body = await res.json();
|
|
3228
|
+
if (body === null || typeof body !== "object" || Array.isArray(body)) {
|
|
3229
|
+
console.error(
|
|
3230
|
+
`[isPinnedProviderLoaded] GET /config/providers body was not a plain object (port ${port})`
|
|
3231
|
+
);
|
|
3232
|
+
return null;
|
|
3233
|
+
}
|
|
3234
|
+
const providers = body.providers;
|
|
3235
|
+
if (!Array.isArray(providers)) {
|
|
3236
|
+
console.error(
|
|
3237
|
+
`[isPinnedProviderLoaded] GET /config/providers body had no providers array (port ${port})`
|
|
3238
|
+
);
|
|
3239
|
+
return null;
|
|
3240
|
+
}
|
|
3241
|
+
const providerIds = providers.filter(
|
|
3242
|
+
(provider) => provider !== null && typeof provider === "object" && typeof provider.id === "string"
|
|
3243
|
+
).map((provider) => provider.id);
|
|
3244
|
+
if (providerIds.length === 0) {
|
|
3245
|
+
console.error(
|
|
3246
|
+
`[isPinnedProviderLoaded] GET /config/providers had no provider entries with string ids (port ${port})`
|
|
3247
|
+
);
|
|
3248
|
+
return null;
|
|
3249
|
+
}
|
|
3250
|
+
return providerIds.includes(providerId);
|
|
3251
|
+
} catch (err) {
|
|
3252
|
+
console.error(
|
|
3253
|
+
`[isPinnedProviderLoaded] GET /config/providers failed (port ${port}): ${err instanceof Error ? err.message : String(err)}`
|
|
3254
|
+
);
|
|
3255
|
+
return null;
|
|
3256
|
+
}
|
|
3257
|
+
}
|
|
3096
3258
|
async function buildFileParts(attachments, capable) {
|
|
3097
3259
|
const outcomes = [];
|
|
3098
3260
|
const parts = [];
|
|
@@ -4681,11 +4843,11 @@ function failureMessage(status2) {
|
|
|
4681
4843
|
function isRetryableStatus(status2) {
|
|
4682
4844
|
return CONNECT_KEY_RETRY_STATUSES.includes(status2);
|
|
4683
4845
|
}
|
|
4684
|
-
async function importOneCredential(
|
|
4846
|
+
async function importOneCredential(request3, credential, sleepForRetry, log3) {
|
|
4685
4847
|
const path = `/api/integration/${encodeURIComponent(credential.integrationId)}/connect/key`;
|
|
4686
4848
|
for (let attempt = 1; attempt <= CONNECT_KEY_MAX_ATTEMPTS; attempt += 1) {
|
|
4687
4849
|
try {
|
|
4688
|
-
const response = await
|
|
4850
|
+
const response = await request3(
|
|
4689
4851
|
path,
|
|
4690
4852
|
{
|
|
4691
4853
|
method: "POST",
|
|
@@ -4720,7 +4882,7 @@ async function importOneCredential(request2, credential, sleepForRetry, log3) {
|
|
|
4720
4882
|
throw new Error("OpenCode credential import retry loop did not return");
|
|
4721
4883
|
}
|
|
4722
4884
|
async function importOpenCodeCredentials({
|
|
4723
|
-
request:
|
|
4885
|
+
request: request3,
|
|
4724
4886
|
classified,
|
|
4725
4887
|
connectedIntegrationIds,
|
|
4726
4888
|
sleepForRetry = sleep2,
|
|
@@ -4732,7 +4894,7 @@ async function importOpenCodeCredentials({
|
|
|
4732
4894
|
result.alreadyConnected.push(credential.integrationId);
|
|
4733
4895
|
continue;
|
|
4734
4896
|
}
|
|
4735
|
-
const outcome = await importOneCredential(
|
|
4897
|
+
const outcome = await importOneCredential(request3, credential, sleepForRetry, log3);
|
|
4736
4898
|
if (outcome.ok) result.imported.push(credential.integrationId);
|
|
4737
4899
|
else result.failed.push(outcome.failure);
|
|
4738
4900
|
}
|
|
@@ -4750,7 +4912,7 @@ function parseIntegrationList(value) {
|
|
|
4750
4912
|
return { integrationIds, hasData: value.data.length > 0 };
|
|
4751
4913
|
}
|
|
4752
4914
|
async function getConnectedOpenCodeIntegrationIds({
|
|
4753
|
-
request:
|
|
4915
|
+
request: request3,
|
|
4754
4916
|
directory,
|
|
4755
4917
|
sleepForRetry = sleep2,
|
|
4756
4918
|
log: log3
|
|
@@ -4758,7 +4920,7 @@ async function getConnectedOpenCodeIntegrationIds({
|
|
|
4758
4920
|
const path = `/api/integration?location%5Bdirectory%5D=${encodeURIComponent(directory)}`;
|
|
4759
4921
|
for (let attempt = 1; attempt <= INTEGRATION_LIST_MAX_READS; attempt += 1) {
|
|
4760
4922
|
try {
|
|
4761
|
-
const response = await
|
|
4923
|
+
const response = await request3(path);
|
|
4762
4924
|
const parsed = parseIntegrationList(await response.json());
|
|
4763
4925
|
if (parsed === null) {
|
|
4764
4926
|
log3(
|
|
@@ -4787,7 +4949,7 @@ async function getConnectedOpenCodeIntegrationIds({
|
|
|
4787
4949
|
return null;
|
|
4788
4950
|
}
|
|
4789
4951
|
async function importOpenCodeV2Credentials({
|
|
4790
|
-
request:
|
|
4952
|
+
request: request3,
|
|
4791
4953
|
homeDir,
|
|
4792
4954
|
directory,
|
|
4793
4955
|
sleepForRetry = sleep2,
|
|
@@ -4805,7 +4967,7 @@ async function importOpenCodeV2Credentials({
|
|
|
4805
4967
|
const classified = classifyOpenCodeCredentials(credentials2);
|
|
4806
4968
|
if (classified.importable.length === 0) return emptyResult(classified.unsupported);
|
|
4807
4969
|
const connectedIntegrationIds = await getConnectedOpenCodeIntegrationIds({
|
|
4808
|
-
request:
|
|
4970
|
+
request: request3,
|
|
4809
4971
|
directory,
|
|
4810
4972
|
sleepForRetry,
|
|
4811
4973
|
log: log3
|
|
@@ -4814,7 +4976,7 @@ async function importOpenCodeV2Credentials({
|
|
|
4814
4976
|
return emptyResult(classified.unsupported, "connection-list-unavailable");
|
|
4815
4977
|
}
|
|
4816
4978
|
return importOpenCodeCredentials({
|
|
4817
|
-
request:
|
|
4979
|
+
request: request3,
|
|
4818
4980
|
classified,
|
|
4819
4981
|
connectedIntegrationIds,
|
|
4820
4982
|
sleepForRetry,
|
|
@@ -5505,7 +5667,11 @@ function isSessionDbProvenanceRecord(value) {
|
|
|
5505
5667
|
var OPENCODE2_PACKAGE_SPEC = "@opencode-ai/cli@0.0.0-beta-17823";
|
|
5506
5668
|
|
|
5507
5669
|
// src/lib/opencode/opencode-version-gate.ts
|
|
5508
|
-
var QUEUE_VALIDATED_OPENCODE_VERSIONS = [
|
|
5670
|
+
var QUEUE_VALIDATED_OPENCODE_VERSIONS = [
|
|
5671
|
+
"1.17.11",
|
|
5672
|
+
"1.18.3",
|
|
5673
|
+
"1.18.35"
|
|
5674
|
+
];
|
|
5509
5675
|
function isQueueValidatedVersion(version2) {
|
|
5510
5676
|
if (!version2) return false;
|
|
5511
5677
|
return QUEUE_VALIDATED_OPENCODE_VERSIONS.includes(version2);
|
|
@@ -6550,6 +6716,7 @@ function connectTunnel(options) {
|
|
|
6550
6716
|
}, 3e4);
|
|
6551
6717
|
let relaySilenceTimeout;
|
|
6552
6718
|
let relaySilenceTimedOut = false;
|
|
6719
|
+
let relayConnectionId;
|
|
6553
6720
|
const clearRelaySilenceTimeout = () => {
|
|
6554
6721
|
if (relaySilenceTimeout === void 0) return;
|
|
6555
6722
|
clearTimeout(relaySilenceTimeout);
|
|
@@ -6635,7 +6802,8 @@ function connectTunnel(options) {
|
|
|
6635
6802
|
armRelaySilenceTimeout();
|
|
6636
6803
|
forwarder.setBinaryFramesSupported(message.binary_frames === true);
|
|
6637
6804
|
const connectedAgentId = message.agent_id ?? agentId;
|
|
6638
|
-
|
|
6805
|
+
relayConnectionId = message.connection_id;
|
|
6806
|
+
onConnected?.(connectedAgentId, relayConnectionId);
|
|
6639
6807
|
resolve5({
|
|
6640
6808
|
ws,
|
|
6641
6809
|
close: () => ws.close(1e3, "CLI shutdown")
|
|
@@ -6672,7 +6840,7 @@ function connectTunnel(options) {
|
|
|
6672
6840
|
clearRelaySilenceTimeout();
|
|
6673
6841
|
const reasonStr = (relaySilenceTimedOut ? "no relay heartbeat for 90s \u2014 reconnecting" : void 0) || reason.toString() || upgradeRejection || (code === 1006 ? "abnormal closure" : "No reason provided");
|
|
6674
6842
|
forwarder.abortAll();
|
|
6675
|
-
onDisconnected?.(code, reasonStr);
|
|
6843
|
+
onDisconnected?.(code, reasonStr, relayConnectionId);
|
|
6676
6844
|
});
|
|
6677
6845
|
});
|
|
6678
6846
|
}
|
|
@@ -6735,7 +6903,7 @@ var RunnerConnection = class _RunnerConnection {
|
|
|
6735
6903
|
authHeader: this.opts.getAuthHeader(),
|
|
6736
6904
|
port: this.opts.port,
|
|
6737
6905
|
openCodePassword: this.opts.openCodePassword,
|
|
6738
|
-
onConnected: (agentId) => {
|
|
6906
|
+
onConnected: (agentId, relayConnectionId) => {
|
|
6739
6907
|
const attempt = this.reconnectAttempt + 1;
|
|
6740
6908
|
this.reconnectAttempt = 0;
|
|
6741
6909
|
this.reconnecting = false;
|
|
@@ -6745,13 +6913,17 @@ var RunnerConnection = class _RunnerConnection {
|
|
|
6745
6913
|
this.disconnectedAtMs = null;
|
|
6746
6914
|
events.onConnected(agentId, isReconnect, {
|
|
6747
6915
|
generation: this.generation,
|
|
6916
|
+
relayConnectionId: relayConnectionId ?? null,
|
|
6748
6917
|
attempt,
|
|
6749
6918
|
downtimeMs
|
|
6750
6919
|
});
|
|
6751
6920
|
},
|
|
6752
|
-
onDisconnected: (code, reason) => {
|
|
6921
|
+
onDisconnected: (code, reason, relayConnectionId) => {
|
|
6753
6922
|
this.disconnectedAtMs = this.now();
|
|
6754
|
-
events.onDisconnected(code, reason, {
|
|
6923
|
+
events.onDisconnected(code, reason, {
|
|
6924
|
+
generation: this.generation,
|
|
6925
|
+
relayConnectionId: relayConnectionId ?? null
|
|
6926
|
+
});
|
|
6755
6927
|
const relayRequestedReconnect = code === 1e3 && _RunnerConnection.RELAY_RECONNECT_CLOSE_REASONS.has(reason);
|
|
6756
6928
|
if (this.opts.isRunning() && (code !== 1e3 || relayRequestedReconnect) && !this.reconnecting) {
|
|
6757
6929
|
this.reconnectPromise = this.connectWithRetry(true).catch((err) => {
|
|
@@ -7199,8 +7371,8 @@ import { chmod, mkdir, open as open3, realpath, rename, unlink } from "node:fs/p
|
|
|
7199
7371
|
import { basename as basename2, dirname as dirname6, isAbsolute as isAbsolute2, join as join9, relative as relative2, resolve as resolve3, sep as sep2 } from "node:path";
|
|
7200
7372
|
var FILE_MODE = 384;
|
|
7201
7373
|
var DIRECTORY_MODE = 448;
|
|
7202
|
-
async function writePushedFile(
|
|
7203
|
-
const { requestedPath, content, allowedDirectories, homeDir } =
|
|
7374
|
+
async function writePushedFile(request3) {
|
|
7375
|
+
const { requestedPath, content, allowedDirectories, homeDir } = request3;
|
|
7204
7376
|
const bytes = content.byteLength;
|
|
7205
7377
|
if (allowedDirectories.length === 0) {
|
|
7206
7378
|
return refuse("file_sync_disabled", "File sync is not enabled on this runner.", {
|
|
@@ -8596,6 +8768,47 @@ var ChannelDriver = class _ChannelDriver {
|
|
|
8596
8768
|
agent: message.opencode_agent ?? void 0,
|
|
8597
8769
|
model: message.opencode_model ?? void 0
|
|
8598
8770
|
};
|
|
8771
|
+
const pinnedProviderLoaded = await isPinnedProviderLoaded(
|
|
8772
|
+
this.port,
|
|
8773
|
+
options.model,
|
|
8774
|
+
this.openCodeClient
|
|
8775
|
+
);
|
|
8776
|
+
if (pinnedProviderLoaded === false) {
|
|
8777
|
+
const dispatchedModel = message.opencode_model;
|
|
8778
|
+
const separator = dispatchedModel?.indexOf("/") ?? -1;
|
|
8779
|
+
const hasProviderAndModel = dispatchedModel !== null && separator > 0 && separator < dispatchedModel.length - 1;
|
|
8780
|
+
const providerId = hasProviderAndModel ? dispatchedModel.slice(0, separator) : null;
|
|
8781
|
+
const modelId = hasProviderAndModel ? dispatchedModel.slice(separator + 1) : null;
|
|
8782
|
+
const errorMessage3 = `Provider namespace not loaded on this runner: ${message.opencode_model}. Refused before dispatch; no turn was started.`;
|
|
8783
|
+
this.log({
|
|
8784
|
+
level: "error",
|
|
8785
|
+
message: `Refusing message ${message.id.slice(0, 8)} in conversation ${conv.id.slice(0, 8)}: provider namespace ${providerId ?? "(unknown)"} is not loaded; no turn was started`,
|
|
8786
|
+
conversation_id: conv.id,
|
|
8787
|
+
message_id: message.id
|
|
8788
|
+
});
|
|
8789
|
+
try {
|
|
8790
|
+
await this.markFailed(conv.id, message.id, sessionId, errorMessage3, void 0, {
|
|
8791
|
+
classification: {
|
|
8792
|
+
kind: "model_auth",
|
|
8793
|
+
providerId,
|
|
8794
|
+
modelId,
|
|
8795
|
+
reason: "missing"
|
|
8796
|
+
},
|
|
8797
|
+
errorShape: { name: null, statusCode: null }
|
|
8798
|
+
});
|
|
8799
|
+
this.signalDispatchNotStarted(conv, message, "model_provider_absent");
|
|
8800
|
+
} catch (markErr) {
|
|
8801
|
+
this.log({
|
|
8802
|
+
level: "warn",
|
|
8803
|
+
message: `markFailed PATCH for refused message ${message.id.slice(0, 8)} (conversation ${conv.id.slice(0, 8)}) failed: ${markErr instanceof Error ? markErr.message : String(markErr)}`,
|
|
8804
|
+
conversation_id: conv.id,
|
|
8805
|
+
message_id: message.id
|
|
8806
|
+
});
|
|
8807
|
+
this.signalDispatchNotStarted(conv, message, "failure_unreported");
|
|
8808
|
+
}
|
|
8809
|
+
await this.repairProviderRegistry(conv.id, message.id);
|
|
8810
|
+
break;
|
|
8811
|
+
}
|
|
8599
8812
|
let opencodeMessageId;
|
|
8600
8813
|
let preDispatchUserIds = null;
|
|
8601
8814
|
try {
|
|
@@ -13778,6 +13991,22 @@ async function configureGitHubAccess({ env, log: log3 }) {
|
|
|
13778
13991
|
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
13779
13992
|
import { copyFileSync, existsSync as existsSync2, statSync as statSync6 } from "node:fs";
|
|
13780
13993
|
import { isAbsolute as isAbsolute3, join as join11, resolve as resolve4 } from "node:path";
|
|
13994
|
+
function parseConfigContent(content) {
|
|
13995
|
+
if (!content?.trim()) return {};
|
|
13996
|
+
const parsed = JSON.parse(content);
|
|
13997
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
13998
|
+
throw new Error("OPENCODE_CONFIG_CONTENT must contain a JSON object");
|
|
13999
|
+
}
|
|
14000
|
+
return parsed;
|
|
14001
|
+
}
|
|
14002
|
+
function mergeManagedOpenCodeConfigContent(content, managedProviders) {
|
|
14003
|
+
const config = parseConfigContent(content);
|
|
14004
|
+
const provider = typeof config.provider === "object" && config.provider !== null && !Array.isArray(config.provider) ? { ...config.provider } : {};
|
|
14005
|
+
for (const namespace of CREDENTIAL_PROXY_NATIVE_NAMESPACES) {
|
|
14006
|
+
delete provider[namespace];
|
|
14007
|
+
}
|
|
14008
|
+
return JSON.stringify({ ...config, provider: { ...provider, ...managedProviders } });
|
|
14009
|
+
}
|
|
13781
14010
|
function isFile(filePath) {
|
|
13782
14011
|
return existsSync2(filePath) && statSync6(filePath).isFile();
|
|
13783
14012
|
}
|
|
@@ -14199,6 +14428,255 @@ function createCredentialSync({
|
|
|
14199
14428
|
};
|
|
14200
14429
|
}
|
|
14201
14430
|
|
|
14431
|
+
// src/lib/managed-inference-setup.ts
|
|
14432
|
+
var defaultStore = {
|
|
14433
|
+
get: getManagedInferenceCredential,
|
|
14434
|
+
set: setManagedInferenceCredential,
|
|
14435
|
+
clear: clearManagedInferenceCredential
|
|
14436
|
+
};
|
|
14437
|
+
function endpoint(options, operation) {
|
|
14438
|
+
return `${options.apiUrl}/runners/${options.agentId}/managed-credentials/${operation}`;
|
|
14439
|
+
}
|
|
14440
|
+
function requestHeaders(options) {
|
|
14441
|
+
return { Authorization: options.getAuthHeader(), "Content-Type": "application/json" };
|
|
14442
|
+
}
|
|
14443
|
+
function request2(options) {
|
|
14444
|
+
return withRequestTimeout(options.fetchImpl ?? fetch, REQUEST_TIMEOUT_MS);
|
|
14445
|
+
}
|
|
14446
|
+
function safeFailure(operation, status2) {
|
|
14447
|
+
return status2 === void 0 ? `${operation} could not reach the managed credential service` : `${operation} returned HTTP ${status2}`;
|
|
14448
|
+
}
|
|
14449
|
+
function logTransportFailure(options, operation, error2, authorization) {
|
|
14450
|
+
let detail = error2 instanceof Error ? error2.message : String(error2);
|
|
14451
|
+
const credential = authorization.split(/\s+/, 2)[1];
|
|
14452
|
+
for (const secret of [authorization, credential]) {
|
|
14453
|
+
if (secret) detail = detail.replaceAll(secret, "[redacted]");
|
|
14454
|
+
}
|
|
14455
|
+
options.log(
|
|
14456
|
+
`MANAGED-INFERENCE-TRANSPORT-FAILED: operation=${operation} detail=${redactDiagnosticText(detail)}`,
|
|
14457
|
+
"debug"
|
|
14458
|
+
);
|
|
14459
|
+
}
|
|
14460
|
+
async function responseJson(response) {
|
|
14461
|
+
try {
|
|
14462
|
+
const value = await response.json();
|
|
14463
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
|
|
14464
|
+
} catch (error2) {
|
|
14465
|
+
return null;
|
|
14466
|
+
}
|
|
14467
|
+
}
|
|
14468
|
+
function readSetup(value) {
|
|
14469
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return null;
|
|
14470
|
+
const setup = value;
|
|
14471
|
+
if (typeof setup.runner_id !== "string" || typeof setup.generation !== "string" || typeof setup.status !== "string" || setup.token_id !== null && typeof setup.token_id !== "string" || typeof setup.acknowledged_at !== "string" && setup.acknowledged_at !== null) {
|
|
14472
|
+
return null;
|
|
14473
|
+
}
|
|
14474
|
+
return setup;
|
|
14475
|
+
}
|
|
14476
|
+
function clearLocalSetup(options) {
|
|
14477
|
+
const env = options.env ?? process.env;
|
|
14478
|
+
const store = options.store ?? defaultStore;
|
|
14479
|
+
const stored = store.get(options.agentId);
|
|
14480
|
+
store.clear(options.agentId);
|
|
14481
|
+
const token = env.EVIDENT_PROXY_TOKEN;
|
|
14482
|
+
if (token !== void 0 && token === stored?.token) {
|
|
14483
|
+
delete env.EVIDENT_PROXY_TOKEN;
|
|
14484
|
+
} else if (token !== void 0) {
|
|
14485
|
+
options.log(
|
|
14486
|
+
`MANAGED-INFERENCE-CLEANUP-PRESERVED-EXTERNAL-TOKEN: runner=${options.agentId}`,
|
|
14487
|
+
"debug"
|
|
14488
|
+
);
|
|
14489
|
+
}
|
|
14490
|
+
}
|
|
14491
|
+
async function discoverManagedInferenceSetup(options) {
|
|
14492
|
+
const headers = requestHeaders(options);
|
|
14493
|
+
let response;
|
|
14494
|
+
try {
|
|
14495
|
+
response = await request2(options)(endpoint(options, "current"), {
|
|
14496
|
+
headers
|
|
14497
|
+
});
|
|
14498
|
+
} catch (error2) {
|
|
14499
|
+
logTransportFailure(options, "discovery", error2, headers.Authorization);
|
|
14500
|
+
return { kind: "failed", reason: safeFailure("Managed setup discovery") };
|
|
14501
|
+
}
|
|
14502
|
+
if (response.status === 404) {
|
|
14503
|
+
clearLocalSetup(options);
|
|
14504
|
+
return { kind: "none" };
|
|
14505
|
+
}
|
|
14506
|
+
if (!response.ok) {
|
|
14507
|
+
return { kind: "failed", reason: safeFailure("Managed setup discovery", response.status) };
|
|
14508
|
+
}
|
|
14509
|
+
const body = await responseJson(response);
|
|
14510
|
+
const setup = readSetup(body?.setup);
|
|
14511
|
+
return setup ? { kind: "setup", setup } : { kind: "failed", reason: "Managed setup discovery returned an invalid response" };
|
|
14512
|
+
}
|
|
14513
|
+
async function enrollManagedInferenceSetup(options) {
|
|
14514
|
+
const response = await post(options, "enroll", {});
|
|
14515
|
+
if (!response) {
|
|
14516
|
+
return { kind: "failed", reason: safeFailure("Managed credential enrollment") };
|
|
14517
|
+
}
|
|
14518
|
+
if (response.status === 404) {
|
|
14519
|
+
return { kind: "none" };
|
|
14520
|
+
}
|
|
14521
|
+
const body = await responseJson(response);
|
|
14522
|
+
if (!response.ok) {
|
|
14523
|
+
const serverError = body?.error;
|
|
14524
|
+
return {
|
|
14525
|
+
kind: "failed",
|
|
14526
|
+
reason: typeof serverError === "string" && serverError.trim() ? redactDiagnosticText(serverError).slice(0, 500) : safeFailure("Managed credential enrollment", response.status)
|
|
14527
|
+
};
|
|
14528
|
+
}
|
|
14529
|
+
const setup = readSetup(body?.setup);
|
|
14530
|
+
return setup ? { kind: "setup", setup } : { kind: "failed", reason: "Managed credential enrollment returned an invalid response" };
|
|
14531
|
+
}
|
|
14532
|
+
async function post(options, operation, body) {
|
|
14533
|
+
const headers = requestHeaders(options);
|
|
14534
|
+
try {
|
|
14535
|
+
return await request2(options)(endpoint(options, operation), {
|
|
14536
|
+
method: "POST",
|
|
14537
|
+
headers,
|
|
14538
|
+
body: JSON.stringify(body)
|
|
14539
|
+
});
|
|
14540
|
+
} catch (error2) {
|
|
14541
|
+
logTransportFailure(options, operation, error2, headers.Authorization);
|
|
14542
|
+
return null;
|
|
14543
|
+
}
|
|
14544
|
+
}
|
|
14545
|
+
function applyCredential(options, credential) {
|
|
14546
|
+
const env = options.env ?? process.env;
|
|
14547
|
+
let merged;
|
|
14548
|
+
if (options.autoConfigureCredentialsProxy) {
|
|
14549
|
+
const { config, unsupportedProviders } = buildCredentialProxyNativeConfig({
|
|
14550
|
+
inferenceBaseUrl: credential.inferenceBaseUrl,
|
|
14551
|
+
modelDescriptors: credential.modelDescriptors
|
|
14552
|
+
});
|
|
14553
|
+
if (unsupportedProviders.length > 0 || Object.keys(config.provider).length === 0) {
|
|
14554
|
+
return "Managed setup contains unsupported provider descriptors";
|
|
14555
|
+
}
|
|
14556
|
+
try {
|
|
14557
|
+
merged = mergeManagedOpenCodeConfigContent(env.OPENCODE_CONFIG_CONTENT, config.provider);
|
|
14558
|
+
} catch (error2) {
|
|
14559
|
+
return "OPENCODE_CONFIG_CONTENT is malformed; managed providers were not installed";
|
|
14560
|
+
}
|
|
14561
|
+
}
|
|
14562
|
+
try {
|
|
14563
|
+
(options.store ?? defaultStore).set(options.agentId, credential);
|
|
14564
|
+
} catch (error2) {
|
|
14565
|
+
const detail = (error2 instanceof Error ? error2.message : String(error2)).replaceAll(
|
|
14566
|
+
credential.token,
|
|
14567
|
+
"[redacted]"
|
|
14568
|
+
);
|
|
14569
|
+
options.log(
|
|
14570
|
+
`MANAGED-INFERENCE-STORE-FAILED: runner=${options.agentId} generation=${credential.generation} detail=${redactDiagnosticText(detail)}`,
|
|
14571
|
+
"warn"
|
|
14572
|
+
);
|
|
14573
|
+
return "Managed credentials could not be written to the protected store";
|
|
14574
|
+
}
|
|
14575
|
+
env.EVIDENT_PROXY_TOKEN = credential.token;
|
|
14576
|
+
if (merged !== void 0) env.OPENCODE_CONFIG_CONTENT = merged;
|
|
14577
|
+
return null;
|
|
14578
|
+
}
|
|
14579
|
+
async function reportManagedInferenceApplyFailure(options, failure) {
|
|
14580
|
+
const response = await post(options, "report-failure", {
|
|
14581
|
+
generation: failure.generation,
|
|
14582
|
+
token_id: failure.tokenId
|
|
14583
|
+
});
|
|
14584
|
+
if (!response?.ok) {
|
|
14585
|
+
options.log(
|
|
14586
|
+
`MANAGED-INFERENCE-REPORT-FAILED: runner=${options.agentId} generation=${failure.generation}${response ? ` status=${response.status}` : ""}`,
|
|
14587
|
+
"warn"
|
|
14588
|
+
);
|
|
14589
|
+
}
|
|
14590
|
+
}
|
|
14591
|
+
async function reaffirmStored(options, credential) {
|
|
14592
|
+
const response = await post(options, "reaffirm", {
|
|
14593
|
+
generation: credential.generation,
|
|
14594
|
+
token_id: credential.tokenId
|
|
14595
|
+
});
|
|
14596
|
+
if (!response?.ok) {
|
|
14597
|
+
return {
|
|
14598
|
+
kind: "failed",
|
|
14599
|
+
reason: response?.status === 409 ? "Stored managed credential no longer matches this setup; restart required" : response ? safeFailure("Managed credential reaffirmation", response.status) : safeFailure("Managed credential reaffirmation")
|
|
14600
|
+
};
|
|
14601
|
+
}
|
|
14602
|
+
const body = await responseJson(response);
|
|
14603
|
+
const setup = readSetup(body?.setup);
|
|
14604
|
+
if (!setup || setup.generation !== credential.generation || setup.token_id !== credential.tokenId) {
|
|
14605
|
+
return { kind: "failed", reason: "Managed credential reaffirmation returned a mismatch" };
|
|
14606
|
+
}
|
|
14607
|
+
const failure = applyCredential(options, credential);
|
|
14608
|
+
return failure ? { kind: "failed", reason: failure } : { kind: "ready", generation: credential.generation, tokenId: credential.tokenId };
|
|
14609
|
+
}
|
|
14610
|
+
async function prepareManagedInferenceSetup(options, discovery, health) {
|
|
14611
|
+
if (health.authFailed) {
|
|
14612
|
+
return {
|
|
14613
|
+
kind: "failed",
|
|
14614
|
+
reason: "OpenCode authentication failed; managed credentials were not rotated"
|
|
14615
|
+
};
|
|
14616
|
+
}
|
|
14617
|
+
const stored = (options.store ?? defaultStore).get(options.agentId);
|
|
14618
|
+
if (health.healthy) {
|
|
14619
|
+
if (!stored) {
|
|
14620
|
+
return {
|
|
14621
|
+
kind: "failed",
|
|
14622
|
+
reason: "Managed credentials are missing for the serving OpenCode process; restart required"
|
|
14623
|
+
};
|
|
14624
|
+
}
|
|
14625
|
+
return reaffirmStored(options, stored);
|
|
14626
|
+
}
|
|
14627
|
+
if (discovery.setup.acknowledged_at !== null && stored?.generation === discovery.setup.generation && stored.tokenId === discovery.setup.token_id) {
|
|
14628
|
+
return reaffirmStored(options, stored);
|
|
14629
|
+
}
|
|
14630
|
+
const response = await post(options, "bootstrap", { generation: discovery.setup.generation });
|
|
14631
|
+
if (!response?.ok) {
|
|
14632
|
+
return {
|
|
14633
|
+
kind: "failed",
|
|
14634
|
+
reason: response ? safeFailure("Managed credential bootstrap", response.status) : safeFailure("Managed credential bootstrap")
|
|
14635
|
+
};
|
|
14636
|
+
}
|
|
14637
|
+
const body = await responseJson(response);
|
|
14638
|
+
const setup = readSetup(body?.setup);
|
|
14639
|
+
const token = body?.inference_token;
|
|
14640
|
+
const inferenceBaseUrl = body?.inference_base_url;
|
|
14641
|
+
const modelDescriptors = body?.model_descriptors;
|
|
14642
|
+
if (!setup || setup.generation !== discovery.setup.generation || typeof setup.token_id !== "string" || typeof token !== "string" || typeof inferenceBaseUrl !== "string" || !Array.isArray(modelDescriptors) || !modelDescriptors.every(
|
|
14643
|
+
(descriptor) => typeof descriptor === "object" && descriptor !== null && typeof descriptor.id === "string" && typeof descriptor.provider === "string"
|
|
14644
|
+
)) {
|
|
14645
|
+
return { kind: "failed", reason: "Managed credential bootstrap returned an invalid response" };
|
|
14646
|
+
}
|
|
14647
|
+
const credential = {
|
|
14648
|
+
generation: setup.generation,
|
|
14649
|
+
tokenId: setup.token_id,
|
|
14650
|
+
token,
|
|
14651
|
+
inferenceBaseUrl,
|
|
14652
|
+
modelDescriptors
|
|
14653
|
+
};
|
|
14654
|
+
const failure = applyCredential(options, credential);
|
|
14655
|
+
if (failure) {
|
|
14656
|
+
await reportManagedInferenceApplyFailure(options, credential);
|
|
14657
|
+
return { kind: "failed", reason: failure };
|
|
14658
|
+
}
|
|
14659
|
+
return { kind: "ready", generation: credential.generation, tokenId: credential.tokenId };
|
|
14660
|
+
}
|
|
14661
|
+
async function acknowledgeManagedInferenceSetup(options, preparation) {
|
|
14662
|
+
const response = await post(options, "acknowledge", {
|
|
14663
|
+
generation: preparation.generation,
|
|
14664
|
+
token_id: preparation.tokenId,
|
|
14665
|
+
config_validated: options.autoConfigureCredentialsProxy === true
|
|
14666
|
+
});
|
|
14667
|
+
if (!response?.ok) {
|
|
14668
|
+
throw new Error(
|
|
14669
|
+
response ? safeFailure("Managed credential acknowledgment", response.status) : safeFailure("Managed credential acknowledgment")
|
|
14670
|
+
);
|
|
14671
|
+
}
|
|
14672
|
+
const body = await responseJson(response);
|
|
14673
|
+
const setup = readSetup(body?.setup);
|
|
14674
|
+
if (!setup || setup.generation !== preparation.generation || setup.token_id !== preparation.tokenId) {
|
|
14675
|
+
throw new Error("Managed credential acknowledgment returned a mismatch");
|
|
14676
|
+
}
|
|
14677
|
+
return response.status === 200 && setup.status === "acknowledged" ? "acknowledged" : "pending";
|
|
14678
|
+
}
|
|
14679
|
+
|
|
14202
14680
|
// src/commands/run.ts
|
|
14203
14681
|
var MAX_ACTIVITY_LOG_ENTRIES = 10;
|
|
14204
14682
|
var MAX_DISCONNECT_REASON_LENGTH = 200;
|
|
@@ -15983,6 +16461,44 @@ async function run(options) {
|
|
|
15983
16461
|
for (const warning2 of opencodeVersionWarnings) {
|
|
15984
16462
|
logActivity(state, { type: "info", level: "warn", message: warning2 });
|
|
15985
16463
|
}
|
|
16464
|
+
const managedSetupOptions = {
|
|
16465
|
+
agentId: state.agentId,
|
|
16466
|
+
apiUrl: getApiUrlConfig(),
|
|
16467
|
+
getAuthHeader: () => state.authHeader,
|
|
16468
|
+
autoConfigureCredentialsProxy: options.autoConfigureCredentialsProxy,
|
|
16469
|
+
log: (message, level = "info") => logActivity(state, {
|
|
16470
|
+
type: level === "error" ? "error" : "info",
|
|
16471
|
+
level,
|
|
16472
|
+
...level === "error" ? { error: message } : { message }
|
|
16473
|
+
})
|
|
16474
|
+
};
|
|
16475
|
+
let managedDiscovery = await discoverManagedInferenceSetup(managedSetupOptions);
|
|
16476
|
+
if (managedDiscovery.kind === "none") {
|
|
16477
|
+
managedDiscovery = await enrollManagedInferenceSetup(managedSetupOptions);
|
|
16478
|
+
}
|
|
16479
|
+
let managedPreparation = { kind: "none" };
|
|
16480
|
+
if (managedDiscovery.kind === "failed") {
|
|
16481
|
+
managedPreparation = managedDiscovery;
|
|
16482
|
+
managedSetupOptions.log(`MANAGED-INFERENCE-NOT-READY: ${managedDiscovery.reason}`, "warn");
|
|
16483
|
+
} else if (managedDiscovery.kind === "setup") {
|
|
16484
|
+
const managedHealth = opencodeVersion === "v2" ? await checkOpenCode2Health(state.port) : await checkOpenCodeHealth(state.port);
|
|
16485
|
+
managedPreparation = await prepareManagedInferenceSetup(
|
|
16486
|
+
managedSetupOptions,
|
|
16487
|
+
managedDiscovery,
|
|
16488
|
+
managedHealth
|
|
16489
|
+
);
|
|
16490
|
+
if (managedPreparation.kind === "failed") {
|
|
16491
|
+
managedSetupOptions.log(
|
|
16492
|
+
`MANAGED-INFERENCE-NOT-READY: ${managedPreparation.reason}`,
|
|
16493
|
+
"warn"
|
|
16494
|
+
);
|
|
16495
|
+
} else if (managedPreparation.kind === "ready") {
|
|
16496
|
+
managedSetupOptions.log(
|
|
16497
|
+
`MANAGED-INFERENCE-PREPARED: runner=${state.agentId} generation=${managedPreparation.generation}`,
|
|
16498
|
+
"info"
|
|
16499
|
+
);
|
|
16500
|
+
}
|
|
16501
|
+
}
|
|
15986
16502
|
const { value: maxActiveSessions, warnings: maxActiveSessionsWarnings } = resolveMaxActiveSessions(options, process.env);
|
|
15987
16503
|
for (const warning2 of maxActiveSessionsWarnings) {
|
|
15988
16504
|
logActivity(state, { type: "info", level: "warn", message: warning2 });
|
|
@@ -16077,6 +16593,30 @@ async function run(options) {
|
|
|
16077
16593
|
}
|
|
16078
16594
|
}
|
|
16079
16595
|
state.opencodeConnected = oc.notReadyReason === null;
|
|
16596
|
+
if (managedPreparation.kind === "ready" && oc.notReadyReason === null) {
|
|
16597
|
+
try {
|
|
16598
|
+
const acknowledgement = await acknowledgeManagedInferenceSetup(
|
|
16599
|
+
managedSetupOptions,
|
|
16600
|
+
managedPreparation
|
|
16601
|
+
);
|
|
16602
|
+
if (acknowledgement === "acknowledged") {
|
|
16603
|
+
managedSetupOptions.log(
|
|
16604
|
+
`MANAGED-INFERENCE-ACKNOWLEDGED: runner=${state.agentId} generation=${managedPreparation.generation}`,
|
|
16605
|
+
"info"
|
|
16606
|
+
);
|
|
16607
|
+
} else {
|
|
16608
|
+
managedSetupOptions.log(
|
|
16609
|
+
`MANAGED-INFERENCE-NOT-READY: policy refresh is pending for runner=${state.agentId} generation=${managedPreparation.generation}`,
|
|
16610
|
+
"warn"
|
|
16611
|
+
);
|
|
16612
|
+
}
|
|
16613
|
+
} catch (error2) {
|
|
16614
|
+
managedSetupOptions.log(
|
|
16615
|
+
`MANAGED-INFERENCE-NOT-READY: ${error2 instanceof Error ? error2.message : String(error2)}`,
|
|
16616
|
+
"warn"
|
|
16617
|
+
);
|
|
16618
|
+
}
|
|
16619
|
+
}
|
|
16080
16620
|
const version2 = state.opencodeVersion ? ` (v${state.opencodeVersion})` : "";
|
|
16081
16621
|
ocSpinner?.succeed(`OpenCode running on port ${state.port}${version2}`);
|
|
16082
16622
|
if (!state.interactive && oc.notReadyReason !== null) {
|
|
@@ -16259,7 +16799,7 @@ async function run(options) {
|
|
|
16259
16799
|
onConnected: (agentId, isReconnect, transition) => {
|
|
16260
16800
|
state.connected = true;
|
|
16261
16801
|
state.agentId = agentId;
|
|
16262
|
-
const connectionMessage = isReconnect ? `Tunnel reconnected (runner: ${agentId}, generation: ${transition.generation}, attempt: ${transition.attempt}, offline for ${transition.downtimeMs}ms)` : `Tunnel connected (runner: ${agentId}, generation: ${transition.generation})`;
|
|
16802
|
+
const connectionMessage = isReconnect ? `Tunnel reconnected (runner: ${agentId}, generation: ${transition.generation}, relay connection: ${transition.relayConnectionId ?? "unknown"}, attempt: ${transition.attempt}, offline for ${transition.downtimeMs}ms)` : `Tunnel connected (runner: ${agentId}, generation: ${transition.generation}, relay connection: ${transition.relayConnectionId ?? "unknown"})`;
|
|
16263
16803
|
logActivity(state, {
|
|
16264
16804
|
type: "info",
|
|
16265
16805
|
message: connectionMessage
|
|
@@ -16292,6 +16832,7 @@ async function run(options) {
|
|
|
16292
16832
|
connected: state.opencodeConnected
|
|
16293
16833
|
}),
|
|
16294
16834
|
connection_generation: transition.generation,
|
|
16835
|
+
...transition.relayConnectionId !== null ? { relay_connection_id: transition.relayConnectionId } : {},
|
|
16295
16836
|
...isReconnect && transition.downtimeMs !== null ? {
|
|
16296
16837
|
reconnect_attempt: transition.attempt,
|
|
16297
16838
|
downtime_ms: transition.downtimeMs
|
|
@@ -16322,12 +16863,13 @@ async function run(options) {
|
|
|
16322
16863
|
const safeReason2 = redactDiagnosticText(reason).slice(0, MAX_DISCONNECT_REASON_LENGTH);
|
|
16323
16864
|
logActivity(state, {
|
|
16324
16865
|
type: "info",
|
|
16325
|
-
message: `Tunnel disconnected (generation: ${transition.generation}, code: ${code}, reason: ${safeReason2})`
|
|
16866
|
+
message: `Tunnel disconnected (generation: ${transition.generation}, relay connection: ${transition.relayConnectionId ?? "unknown"}, code: ${code}, reason: ${safeReason2})`
|
|
16326
16867
|
});
|
|
16327
16868
|
emitAgentDisconnected(state.agentId, {
|
|
16328
16869
|
code,
|
|
16329
16870
|
reason: safeReason2,
|
|
16330
|
-
connection_generation: transition.generation
|
|
16871
|
+
connection_generation: transition.generation,
|
|
16872
|
+
...transition.relayConnectionId !== null ? { relay_connection_id: transition.relayConnectionId } : {}
|
|
16331
16873
|
});
|
|
16332
16874
|
if (state.interactive) displayStatus(state);
|
|
16333
16875
|
},
|
|
@@ -16478,9 +17020,9 @@ program.name("evident").description("Run OpenCode locally and connect it to Evid
|
|
|
16478
17020
|
"--endpoint <url>",
|
|
16479
17021
|
"Evident API base URL (default: production; e.g. http://localhost:3001)"
|
|
16480
17022
|
).option("--tunnel <url>", "Tunnel WebSocket URL (default: production; e.g. ws://localhost:8787)").hook("preAction", (thisCommand) => {
|
|
16481
|
-
const { endpoint, tunnel } = thisCommand.opts();
|
|
16482
|
-
if (
|
|
16483
|
-
setEndpoint(
|
|
17023
|
+
const { endpoint: endpoint2, tunnel } = thisCommand.opts();
|
|
17024
|
+
if (endpoint2) {
|
|
17025
|
+
setEndpoint(endpoint2);
|
|
16484
17026
|
}
|
|
16485
17027
|
if (tunnel) {
|
|
16486
17028
|
setTunnelUrl(tunnel);
|
|
@@ -16554,6 +17096,9 @@ program.command("run").description("Connect to Evident and process messages").op
|
|
|
16554
17096
|
).option(
|
|
16555
17097
|
"--opencode-config-overlay <path>",
|
|
16556
17098
|
"Apply this runner-provided OpenCode config before starting OpenCode."
|
|
17099
|
+
).option(
|
|
17100
|
+
"--auto-configure-credentials-proxy",
|
|
17101
|
+
"Install Evident's generated OpenCode providers for the runner's credential pool (off by default)."
|
|
16557
17102
|
).option(
|
|
16558
17103
|
"--credential-sync-marker <path>",
|
|
16559
17104
|
"Own the interval credential sync and write this marker once the shutdown flush has finished, so the runner image's lifecycle hooks can wait on it."
|
|
@@ -16597,6 +17142,7 @@ program.command("run").description("Connect to Evident and process messages").op
|
|
|
16597
17142
|
restoreSessionDb: options.restoreSessionDb,
|
|
16598
17143
|
restoreRunnerCredentials: options.restoreRunnerCredentials,
|
|
16599
17144
|
opencodeConfigOverlay: options.opencodeConfigOverlay,
|
|
17145
|
+
autoConfigureCredentialsProxy: options.autoConfigureCredentialsProxy,
|
|
16600
17146
|
credentialSyncMarker: options.credentialSyncMarker
|
|
16601
17147
|
});
|
|
16602
17148
|
}
|