@yanlinglabs/winter-agent-runtime 0.0.29 → 0.0.30
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/dist/embedded-worker.js +6 -4
- package/dist/embedded.js +6 -4
- package/dist/engine.d.ts +16 -0
- package/dist/{index-jz5d90c6.js → index-51673qbw.js} +151 -120
- package/dist/{index-gmxxtqpe.js → index-9df1q7j4.js} +30 -12
- package/dist/{index-8jgwp1px.js → index-9s68t0pd.js} +170 -11
- package/dist/index-bgeqc7ax.js +52 -0
- package/dist/{index-eyddzcgs.js → index-wsfqsrh5.js} +2 -2
- package/dist/index-z6s3r4xm.js +903 -0
- package/dist/index.js +4 -2
- package/dist/mcp/client.d.ts +20 -1
- package/dist/mcp/lifecycle.d.ts +8 -0
- package/dist/mcp/transports/http.d.ts +10 -1
- package/dist/mcp/transports/sse.d.ts +4 -2
- package/dist/mcp-auth/account.d.ts +33 -0
- package/dist/mcp-auth/config.d.ts +6 -0
- package/dist/mcp-auth/constants.d.ts +30 -0
- package/dist/mcp-auth/discovery.d.ts +72 -0
- package/dist/mcp-auth/engine-wiring.d.ts +52 -0
- package/dist/mcp-auth/errors.d.ts +37 -0
- package/dist/mcp-auth/fetch-policy.d.ts +33 -0
- package/dist/mcp-auth/login.d.ts +59 -0
- package/dist/mcp-auth/records.d.ts +73 -0
- package/dist/mcp-auth/refresh.d.ts +34 -0
- package/dist/mcp-auth/revoke.d.ts +15 -0
- package/dist/mcp-auth/session-provider.d.ts +55 -0
- package/dist/mcp-auth/store.d.ts +85 -0
- package/dist/mcp-auth/test-fixture-as.d.ts +72 -0
- package/dist/mcp-auth.d.ts +14 -0
- package/dist/mcp-auth.js +493 -0
- package/dist/mcp-client.d.ts +12 -2
- package/dist/mcp-client.js +15 -2
- package/dist/production-wiring.d.ts +6 -0
- package/dist/provider/host-credentials.d.ts +48 -0
- package/dist/provider/keychain-store.d.ts +29 -1
- package/dist/provider/session-provider.d.ts +1 -1
- package/dist/store/dialect.d.ts +1 -1
- package/dist/testing.js +5 -3
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +8 -4
package/dist/embedded-worker.js
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
import"./index-
|
|
1
|
+
import"./index-51673qbw.js";
|
|
2
2
|
import {
|
|
3
3
|
liveProcessGroups,
|
|
4
4
|
onProcessGroupChange
|
|
5
|
-
} from "./index-
|
|
5
|
+
} from "./index-9s68t0pd.js";
|
|
6
|
+
import"./index-z6s3r4xm.js";
|
|
7
|
+
import"./index-bgeqc7ax.js";
|
|
6
8
|
import"./index-bef62z3r.js";
|
|
7
|
-
import"./index-
|
|
9
|
+
import"./index-9df1q7j4.js";
|
|
8
10
|
import {
|
|
9
11
|
runEmbeddedSession2
|
|
10
|
-
} from "./index-
|
|
12
|
+
} from "./index-wsfqsrh5.js";
|
|
11
13
|
import {
|
|
12
14
|
Queue
|
|
13
15
|
} from "./index-97t2rmtf.js";
|
package/dist/embedded.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
runEmbeddedSession2
|
|
3
|
-
} from "./index-
|
|
4
|
-
import"./index-
|
|
5
|
-
import"./index-
|
|
3
|
+
} from "./index-wsfqsrh5.js";
|
|
4
|
+
import"./index-9df1q7j4.js";
|
|
5
|
+
import"./index-51673qbw.js";
|
|
6
|
+
import"./index-bgeqc7ax.js";
|
|
6
7
|
import"./index-bef62z3r.js";
|
|
7
|
-
import"./index-
|
|
8
|
+
import"./index-9s68t0pd.js";
|
|
9
|
+
import"./index-z6s3r4xm.js";
|
|
8
10
|
export {
|
|
9
11
|
runEmbeddedSession2 as runEmbeddedSession
|
|
10
12
|
};
|
package/dist/engine.d.ts
CHANGED
|
@@ -12,6 +12,8 @@ import { type StructuredOutputSeam } from "./structured/seam.js";
|
|
|
12
12
|
import { type FileCheckpointSink } from "./checkpoint/seam.js";
|
|
13
13
|
import { type CommandResolver } from "./commands/seam.js";
|
|
14
14
|
import { type McpServerSource } from "./mcp/lifecycle.js";
|
|
15
|
+
import type { McpOAuthStore } from "./mcp-auth/store.js";
|
|
16
|
+
import type { HostCredentialChannel } from "./provider/host-credentials.js";
|
|
15
17
|
import { type ChildHandle } from "./subagents/child-handle.js";
|
|
16
18
|
import { type SourcedRuleEntry } from "./permissions/ruleset.js";
|
|
17
19
|
import { type AutoAuditRecorder, type ClassifierInterface } from "./permissions/auto/engine.js";
|
|
@@ -981,6 +983,20 @@ export interface EngineOptions {
|
|
|
981
983
|
* clone connects freely.
|
|
982
984
|
*/
|
|
983
985
|
extraMcpServerSources?: readonly McpServerSource[];
|
|
986
|
+
/**
|
|
987
|
+
* WS-25 (MCP OAuth): where this session READS its MCP sign-ins -- the session's own Keychain service,
|
|
988
|
+
* supplied by production wiring (`resolveSessionMcpOAuthStore`). Present, every remote (`http`/`sse`)
|
|
989
|
+
* server without a static `Authorization` header connects with a read-only bearer provider that asks
|
|
990
|
+
* the host (`mcp_oauth_refresh`) to refresh. ABSENT -- every direct `runEngine` caller, every unit test --
|
|
991
|
+
* no provider is attached anywhere, the Keychain is never touched, and a 401 is `needs-auth` as before.
|
|
992
|
+
*/
|
|
993
|
+
mcpOAuthStore?: McpOAuthStore;
|
|
994
|
+
/**
|
|
995
|
+
* WS-25 §7: the host-credential channel production wiring built for a host-brokered session
|
|
996
|
+
* (`RuntimeConfig.hostCredentials`). Bound to this run's control bridge the moment it exists, so every
|
|
997
|
+
* `credential_resolve` rides the session's own stdio pipe. Absent: nothing to bind.
|
|
998
|
+
*/
|
|
999
|
+
hostCredentialChannel?: HostCredentialChannel;
|
|
984
1000
|
/**
|
|
985
1001
|
* `system/init.slash_commands`. Produced by `slashCommandNames(resolver, cwd)`, which ALREADY
|
|
986
1002
|
* includes the engine's own `/compact` -- the engine must not prepend it a second time.
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
trackProcessGroup,
|
|
3
3
|
createElicitationAsker2,
|
|
4
|
+
createSessionAuthProvider,
|
|
5
|
+
mcpSignInHint,
|
|
4
6
|
McpConnectError2,
|
|
5
|
-
connectMcpServer2
|
|
6
|
-
|
|
7
|
+
connectMcpServer2,
|
|
8
|
+
insufficientScopeOf,
|
|
9
|
+
classifyMcpAuthFailure
|
|
10
|
+
} from "./index-9s68t0pd.js";
|
|
7
11
|
import {
|
|
8
12
|
promptKey,
|
|
9
13
|
RunJournal,
|
|
@@ -14,6 +18,12 @@ import {
|
|
|
14
18
|
WORKFLOW_WORKER_ARGV_FLAG2,
|
|
15
19
|
WORKFLOW_WORKER_BRIDGE_FLAG2
|
|
16
20
|
} from "./index-bef62z3r.js";
|
|
21
|
+
import {
|
|
22
|
+
keychainAccountName
|
|
23
|
+
} from "./index-z6s3r4xm.js";
|
|
24
|
+
import {
|
|
25
|
+
validateMcpOAuthConfig2
|
|
26
|
+
} from "./index-bgeqc7ax.js";
|
|
17
27
|
import {
|
|
18
28
|
Queue
|
|
19
29
|
} from "./index-97t2rmtf.js";
|
|
@@ -4946,6 +4956,14 @@ function validateServerConfig(raw) {
|
|
|
4946
4956
|
return { ok: false, reason: `MCP server config 'versionNegotiation' must be "legacy", "auto" or { "pin": "<YYYY-MM-DD revision>" }; got ${JSON.stringify(negotiation)}` };
|
|
4947
4957
|
}
|
|
4948
4958
|
}
|
|
4959
|
+
const oauth = raw.oauth;
|
|
4960
|
+
if (oauth !== undefined) {
|
|
4961
|
+
if (type !== "http" && type !== "sse")
|
|
4962
|
+
return { ok: false, reason: "'oauth' applies only to a remote (http/sse) MCP server" };
|
|
4963
|
+
const reason = validateMcpOAuthConfig2(oauth, raw.url);
|
|
4964
|
+
if (reason !== undefined)
|
|
4965
|
+
return { ok: false, reason };
|
|
4966
|
+
}
|
|
4949
4967
|
return { ok: true, config: raw };
|
|
4950
4968
|
}
|
|
4951
4969
|
function resolveMcpServerSources(sources, opts) {
|
|
@@ -5109,6 +5127,24 @@ function toolInfoToDefinition(tool) {
|
|
|
5109
5127
|
...tool._meta !== undefined ? { _meta: tool._meta } : {}
|
|
5110
5128
|
};
|
|
5111
5129
|
}
|
|
5130
|
+
function hasStaticAuthorization(config) {
|
|
5131
|
+
if (config.type !== "http" && config.type !== "sse")
|
|
5132
|
+
return false;
|
|
5133
|
+
return Object.keys(config.headers ?? {}).some((h) => h.toLowerCase() === "authorization");
|
|
5134
|
+
}
|
|
5135
|
+
function sessionAuthFor(name, config, oauth) {
|
|
5136
|
+
if (oauth === undefined || config.type !== "http" && config.type !== "sse" || hasStaticAuthorization(config))
|
|
5137
|
+
return;
|
|
5138
|
+
try {
|
|
5139
|
+
return createSessionAuthProvider({ serverName: name, serverUrl: config.url, oauth });
|
|
5140
|
+
} catch {
|
|
5141
|
+
return;
|
|
5142
|
+
}
|
|
5143
|
+
}
|
|
5144
|
+
function displayScope(scope) {
|
|
5145
|
+
const cleaned = (scope ?? "").replace(/[^A-Za-z0-9:._/ -]/g, "").trim().slice(0, 200);
|
|
5146
|
+
return cleaned === "" ? "unstated" : cleaned;
|
|
5147
|
+
}
|
|
5112
5148
|
function createInMemoryDiscoveryCache() {
|
|
5113
5149
|
const map = new Map;
|
|
5114
5150
|
return {
|
|
@@ -5199,6 +5235,15 @@ function createMcpLifecycle(deps) {
|
|
|
5199
5235
|
});
|
|
5200
5236
|
return { output: capped.text, ...result.isError === true ? { isError: true } : {} };
|
|
5201
5237
|
} catch (err) {
|
|
5238
|
+
const authFailure = classifyMcpAuthFailure(err);
|
|
5239
|
+
if (authFailure === "needs_auth")
|
|
5240
|
+
return { output: `Error: ${markNeedsAuth(slot, slot.client, err)}`, isError: true };
|
|
5241
|
+
if (authFailure === "insufficient_scope") {
|
|
5242
|
+
const challenge = insufficientScopeOf(err);
|
|
5243
|
+
slot.auth?.reportInsufficientScope(challenge?.requiredScope);
|
|
5244
|
+
const hint = deps.oauth?.signInHint(slot.name) ?? "";
|
|
5245
|
+
return { output: `Error: mcp tool call "${toolName}" on server "${slot.name}" needs additional permission the current sign-in does not grant (scope: ${displayScope(challenge?.requiredScope)}). ${hint}`.trim(), isError: true };
|
|
5246
|
+
}
|
|
5202
5247
|
const message = err instanceof Error ? err.message : String(err);
|
|
5203
5248
|
return { output: `Error: mcp tool call "${toolName}" on server "${slot.name}" failed: ${message}`, isError: true };
|
|
5204
5249
|
}
|
|
@@ -5209,6 +5254,18 @@ function createMcpLifecycle(deps) {
|
|
|
5209
5254
|
function isCurrentAttempt(slot, gen) {
|
|
5210
5255
|
return slots.get(slot.name) === slot && slot.gen === gen;
|
|
5211
5256
|
}
|
|
5257
|
+
function markNeedsAuth(slot, failed, err) {
|
|
5258
|
+
const hint = deps.oauth?.signInHint(slot.name) ?? "";
|
|
5259
|
+
const message = err instanceof McpConnectError2 || err instanceof Error && err.name === "McpNeedsAuthError" ? err.message : `MCP server "${slot.name}" needs sign-in (the server answered 401). ${hint}`.trim();
|
|
5260
|
+
if (slots.get(slot.name) !== slot || failed === undefined || slot.client !== failed)
|
|
5261
|
+
return message;
|
|
5262
|
+
slot.gen++;
|
|
5263
|
+
slot.client = undefined;
|
|
5264
|
+
failed.close().catch(() => {});
|
|
5265
|
+
unregisterMcpServerTools(slot.name);
|
|
5266
|
+
setSlotState(slot.name, "needsAuth", { errorCode: "needs_auth", error: message });
|
|
5267
|
+
return `${message} Its tools are unavailable until then.`;
|
|
5268
|
+
}
|
|
5212
5269
|
function beginAttempt(slot) {
|
|
5213
5270
|
return ++slot.gen;
|
|
5214
5271
|
}
|
|
@@ -5241,6 +5298,7 @@ function createMcpLifecycle(deps) {
|
|
|
5241
5298
|
async function connectSlotForReal(slot, gen) {
|
|
5242
5299
|
let connection;
|
|
5243
5300
|
slot.toolListStale = false;
|
|
5301
|
+
const auth = sessionAuthFor(slot.name, slot.config, deps.oauth);
|
|
5244
5302
|
const client = await connectMcpServer2({
|
|
5245
5303
|
name: slot.name,
|
|
5246
5304
|
config: slot.config,
|
|
@@ -5248,7 +5306,8 @@ function createMcpLifecycle(deps) {
|
|
|
5248
5306
|
elicitationAsk: deps.elicitationAsk,
|
|
5249
5307
|
onToolListChanged: onToolListChangedFor(slot, () => connection),
|
|
5250
5308
|
...deps.inProcessServers?.[slot.name] !== undefined ? { inProcessServer: deps.inProcessServers[slot.name] } : {},
|
|
5251
|
-
...deps.cwd !== undefined ? { cwd: deps.cwd } : {}
|
|
5309
|
+
...deps.cwd !== undefined ? { cwd: deps.cwd } : {},
|
|
5310
|
+
...auth !== undefined ? { auth } : {}
|
|
5252
5311
|
});
|
|
5253
5312
|
connection = client;
|
|
5254
5313
|
const tools = await client.listTools();
|
|
@@ -5257,6 +5316,7 @@ function createMcpLifecycle(deps) {
|
|
|
5257
5316
|
return false;
|
|
5258
5317
|
}
|
|
5259
5318
|
slot.client = client;
|
|
5319
|
+
slot.auth = auth;
|
|
5260
5320
|
slot.toolNames = tools.map((t) => t.name);
|
|
5261
5321
|
slot.savedTools = tools;
|
|
5262
5322
|
registerMcpServerTools(slot.name, tools.map(toolInfoToDefinition), {
|
|
@@ -5386,6 +5446,8 @@ function createMcpLifecycle(deps) {
|
|
|
5386
5446
|
setSlotState(name, "connected", { toolNames: slot.toolNames });
|
|
5387
5447
|
return { ok: true, toolNames: slot.toolNames };
|
|
5388
5448
|
} catch (err) {
|
|
5449
|
+
if (classifyMcpAuthFailure(err) === "needs_auth")
|
|
5450
|
+
return { ok: false, reason: markNeedsAuth(slot, client, err) };
|
|
5389
5451
|
const message = err instanceof Error ? err.message : String(err);
|
|
5390
5452
|
return { ok: false, reason: `refreshing server "${name}" failed: ${message}` };
|
|
5391
5453
|
}
|
|
@@ -5462,6 +5524,68 @@ function createMcpLifecycle(deps) {
|
|
|
5462
5524
|
};
|
|
5463
5525
|
}
|
|
5464
5526
|
|
|
5527
|
+
// src/mcp-auth/engine-wiring.ts
|
|
5528
|
+
import { MCP_OAUTH_REFRESH_SUBTYPE, WinterRpcError as WinterRpcError2 } from "@yanlinglabs/winter-agent-sdk";
|
|
5529
|
+
var MCP_OAUTH_HOST_REFRESH_TIMEOUT_MS = 60000;
|
|
5530
|
+
function isAnswer(value) {
|
|
5531
|
+
if (typeof value !== "object" || value === null)
|
|
5532
|
+
return false;
|
|
5533
|
+
const v = value;
|
|
5534
|
+
return v.ok === true || v.ok === false && (v.reason === "needs_auth" || v.reason === "transient");
|
|
5535
|
+
}
|
|
5536
|
+
function createSessionMcpOAuth(opts) {
|
|
5537
|
+
return {
|
|
5538
|
+
store: opts.store,
|
|
5539
|
+
...opts.hostOwnsRefresh === true ? { hostOwnsRefresh: true } : {},
|
|
5540
|
+
signInHint: (serverName) => mcpSignInHint(opts.brand, serverName),
|
|
5541
|
+
askHost: async (request) => {
|
|
5542
|
+
try {
|
|
5543
|
+
const answer = await opts.sender.request(MCP_OAUTH_REFRESH_SUBTYPE, request, { timeoutMs: MCP_OAUTH_HOST_REFRESH_TIMEOUT_MS });
|
|
5544
|
+
return isAnswer(answer) ? answer : { ok: false, reason: "transient" };
|
|
5545
|
+
} catch (err) {
|
|
5546
|
+
if (err instanceof WinterRpcError2 && err.code === "unhandled_subtype")
|
|
5547
|
+
return "unhandled";
|
|
5548
|
+
return { ok: false, reason: "transient" };
|
|
5549
|
+
}
|
|
5550
|
+
}
|
|
5551
|
+
};
|
|
5552
|
+
}
|
|
5553
|
+
function needsAuthServers(states) {
|
|
5554
|
+
return (states ?? []).filter((s) => s.state === "needsAuth").map((s) => s.name).sort();
|
|
5555
|
+
}
|
|
5556
|
+
function needsAuthToolHint(states, toolName, brand) {
|
|
5557
|
+
const server = needsAuthServers(states).find((name) => toolName.startsWith(`mcp__${name}__`));
|
|
5558
|
+
if (server === undefined)
|
|
5559
|
+
return "";
|
|
5560
|
+
return `. The MCP server '${server}' needs sign-in, so its tools are unavailable. ${mcpSignInHint(brand, server)}`;
|
|
5561
|
+
}
|
|
5562
|
+
var SERVER_PLACEHOLDER = "<server>";
|
|
5563
|
+
function displayName(name) {
|
|
5564
|
+
return name.replace(/[^A-Za-z0-9_.:-]/g, "_").slice(0, 64);
|
|
5565
|
+
}
|
|
5566
|
+
registerAttachmentRenderer("mcp_needs_auth", (attachment) => {
|
|
5567
|
+
const servers = Array.isArray(attachment.servers) ? attachment.servers.filter((s) => typeof s === "string").map(displayName) : [];
|
|
5568
|
+
const door = typeof attachment.door === "string" ? attachment.door : "";
|
|
5569
|
+
if (servers.length === 0)
|
|
5570
|
+
return "The MCP servers that needed sign-in are signed in now; their tools are available again.";
|
|
5571
|
+
return `These MCP servers need the user to sign in, so their tools are not available: ${servers.join(", ")}. Do not try to authenticate on the user's behalf. If the user needs one of them, tell them how to sign in: ${door}`;
|
|
5572
|
+
});
|
|
5573
|
+
function lastAnnounced(messages) {
|
|
5574
|
+
let last = [];
|
|
5575
|
+
for (const a of attachmentsIn(messages)) {
|
|
5576
|
+
if (a.type === "mcp_needs_auth" && Array.isArray(a.servers))
|
|
5577
|
+
last = a.servers.filter((s) => typeof s === "string");
|
|
5578
|
+
}
|
|
5579
|
+
return last;
|
|
5580
|
+
}
|
|
5581
|
+
function mcpNeedsAuthAttachment(states, messages, brand) {
|
|
5582
|
+
const now = needsAuthServers(states);
|
|
5583
|
+
const before = lastAnnounced(messages);
|
|
5584
|
+
if (now.length === before.length && now.every((name, i) => name === before[i]))
|
|
5585
|
+
return;
|
|
5586
|
+
return { type: "mcp_needs_auth", servers: now, door: mcpSignInHint(brand, SERVER_PLACEHOLDER) };
|
|
5587
|
+
}
|
|
5588
|
+
|
|
5465
5589
|
// src/subagents/child-handle.ts
|
|
5466
5590
|
var childEngineFactory;
|
|
5467
5591
|
function registerChildEngineFactory(factory) {
|
|
@@ -21788,6 +21912,8 @@ async function runEngineBody(opts, facetDisposers, registerBackgroundShellSweep)
|
|
|
21788
21912
|
extraHookEntries,
|
|
21789
21913
|
subagentHooks,
|
|
21790
21914
|
extraMcpServerSources,
|
|
21915
|
+
mcpOAuthStore,
|
|
21916
|
+
hostCredentialChannel,
|
|
21791
21917
|
initSlashCommands,
|
|
21792
21918
|
initSkills,
|
|
21793
21919
|
initPlugins,
|
|
@@ -21907,6 +22033,7 @@ ${escapeAttributionText(msg.body)}
|
|
|
21907
22033
|
const policyStateStore = new PolicyStateStore({ mode: initialMode, rules: initialRules }, bypassGate);
|
|
21908
22034
|
const permissionHome = homedir();
|
|
21909
22035
|
const bridge = createRpcBridge2(output);
|
|
22036
|
+
hostCredentialChannel?.bind(bridge);
|
|
21910
22037
|
const bridgePromptStage = createBridgePromptStage(bridge);
|
|
21911
22038
|
const realPromptStage = {
|
|
21912
22039
|
async prompt(call, evalCtx, meta) {
|
|
@@ -22763,7 +22890,8 @@ ${escapeAttributionText(msg.body)}
|
|
|
22763
22890
|
envConfig: mcpEnvConfig,
|
|
22764
22891
|
elicitationAsk: createElicitationAsker2(bridge),
|
|
22765
22892
|
reservedServerName: sessionBrand.mcpServerName,
|
|
22766
|
-
cwd: config.cwd
|
|
22893
|
+
cwd: config.cwd,
|
|
22894
|
+
...mcpOAuthStore !== undefined ? { oauth: createSessionMcpOAuth({ store: mcpOAuthStore, sender: bridge, brand: sessionBrand, ...config.hostCredentials === true ? { hostOwnsRefresh: true } : {} }) } : {}
|
|
22767
22895
|
});
|
|
22768
22896
|
await mcpLifecycle.start();
|
|
22769
22897
|
disposeSessionMcpLifecycle = registerSessionMcpLifecycle(sessionStateKey, mcpLifecycle);
|
|
@@ -24108,6 +24236,11 @@ ${escapeAttributionText(msg.body)}
|
|
|
24108
24236
|
const plan = planModeAttachment();
|
|
24109
24237
|
if (plan !== undefined)
|
|
24110
24238
|
produced.push(plan);
|
|
24239
|
+
if (effectiveMcpStateSource !== undefined) {
|
|
24240
|
+
const needsAuth = mcpNeedsAuthAttachment(effectiveMcpStateSource.snapshot(), messages, sessionBrand);
|
|
24241
|
+
if (needsAuth !== undefined)
|
|
24242
|
+
produced.push(needsAuth);
|
|
24243
|
+
}
|
|
24111
24244
|
}
|
|
24112
24245
|
if (phase === "tool-round") {
|
|
24113
24246
|
const attachment = taskNotificationAttachment(notifications.drainFor(config.agentId, { maxPriority: "next" }), {
|
|
@@ -24375,6 +24508,8 @@ ${escapeAttributionText(msg.body)}
|
|
|
24375
24508
|
if (pending !== undefined)
|
|
24376
24509
|
hint = `. The MCP server '${pending.name}' is still connecting. Call WaitForMcpServers to wait for it, then try again.`;
|
|
24377
24510
|
}
|
|
24511
|
+
if (hint === "" && toolName.startsWith("mcp__"))
|
|
24512
|
+
hint = needsAuthToolHint(effectiveMcpStateSource?.snapshot(), toolName, sessionBrand);
|
|
24378
24513
|
return `<tool_use_error>Error: No such tool available: ${toolName}${hint}</tool_use_error>`;
|
|
24379
24514
|
};
|
|
24380
24515
|
const assertMessagesWithinCap = (msgs) => {
|
|
@@ -26367,7 +26502,7 @@ class TranscriptWriter2 {
|
|
|
26367
26502
|
return entries;
|
|
26368
26503
|
}
|
|
26369
26504
|
}
|
|
26370
|
-
var RUNTIME_ENGINE_VERSION2 = "0.0.
|
|
26505
|
+
var RUNTIME_ENGINE_VERSION2 = "0.0.30";
|
|
26371
26506
|
function withPermissionJournal(writer, location) {
|
|
26372
26507
|
return {
|
|
26373
26508
|
transcriptPath: join25(location.winterHome, "projects", location.projectKey, `${location.sessionId}.jsonl`),
|
|
@@ -26506,117 +26641,13 @@ function resolveProductionStoreHome(config, env) {
|
|
|
26506
26641
|
// src/provider/credential-api.ts
|
|
26507
26642
|
import {
|
|
26508
26643
|
ANTHROPIC_CONSOLE_ACCOUNT_ID,
|
|
26509
|
-
CredentialResolutionError
|
|
26644
|
+
CredentialResolutionError,
|
|
26510
26645
|
WinterProviderResolutionError as WinterProviderResolutionError3,
|
|
26511
26646
|
startAnthropicConsoleBrokerLogin,
|
|
26512
26647
|
startCodexLogin,
|
|
26513
26648
|
startXaiLogin
|
|
26514
26649
|
} from "@yanlinglabs/winter-provider-runtime";
|
|
26515
26650
|
|
|
26516
|
-
// src/provider/keychain-store.ts
|
|
26517
|
-
import { CredentialResolutionError, redactRef } from "@yanlinglabs/winter-provider-runtime";
|
|
26518
|
-
import { DEFAULT_KEYCHAIN_SERVICE } from "@yanlinglabs/winter-agent-sdk";
|
|
26519
|
-
function defaultSecretsBackend() {
|
|
26520
|
-
const secrets = globalThis.Bun?.secrets;
|
|
26521
|
-
if (secrets === undefined) {
|
|
26522
|
-
throw new CredentialResolutionError("unsupported", "the Keychain credential store requires Bun.secrets, which is unavailable in this runtime");
|
|
26523
|
-
}
|
|
26524
|
-
return secrets;
|
|
26525
|
-
}
|
|
26526
|
-
function createKeychainCredentialStore(service = DEFAULT_KEYCHAIN_SERVICE, opts = {}) {
|
|
26527
|
-
const backend = () => opts.secrets ?? defaultSecretsBackend();
|
|
26528
|
-
return {
|
|
26529
|
-
async get(ref) {
|
|
26530
|
-
if (ref.kind !== "keychain")
|
|
26531
|
-
return null;
|
|
26532
|
-
let raw;
|
|
26533
|
-
try {
|
|
26534
|
-
raw = await backend().get({ service: ref.service ?? service, name: ref.account });
|
|
26535
|
-
} catch (err) {
|
|
26536
|
-
if (err instanceof CredentialResolutionError)
|
|
26537
|
-
throw err;
|
|
26538
|
-
throw new CredentialResolutionError("io", `keychain lookup failed for ${redactRef(ref)}`);
|
|
26539
|
-
}
|
|
26540
|
-
if (raw === null)
|
|
26541
|
-
return null;
|
|
26542
|
-
let parsed;
|
|
26543
|
-
try {
|
|
26544
|
-
parsed = JSON.parse(raw);
|
|
26545
|
-
} catch {
|
|
26546
|
-
throw new CredentialResolutionError("malformed", `the keychain record for ${redactRef(ref)} is not valid JSON credential material`);
|
|
26547
|
-
}
|
|
26548
|
-
const material = coerceMaterial(parsed);
|
|
26549
|
-
if (material === undefined)
|
|
26550
|
-
throw new CredentialResolutionError("malformed", `the keychain record for ${redactRef(ref)} is not a recognized credential material shape`);
|
|
26551
|
-
return material;
|
|
26552
|
-
},
|
|
26553
|
-
async set(ref, material) {
|
|
26554
|
-
try {
|
|
26555
|
-
await backend().set({ service: ref.service ?? service, name: ref.account, value: JSON.stringify(material) });
|
|
26556
|
-
} catch (err) {
|
|
26557
|
-
if (err instanceof CredentialResolutionError)
|
|
26558
|
-
throw err;
|
|
26559
|
-
throw new CredentialResolutionError("io", `keychain write failed for ${redactRef(ref)}`);
|
|
26560
|
-
}
|
|
26561
|
-
},
|
|
26562
|
-
async delete(ref) {
|
|
26563
|
-
try {
|
|
26564
|
-
await backend().delete({ service: ref.service ?? service, name: ref.account });
|
|
26565
|
-
} catch (err) {
|
|
26566
|
-
if (err instanceof CredentialResolutionError)
|
|
26567
|
-
throw err;
|
|
26568
|
-
throw new CredentialResolutionError("io", `keychain delete failed for ${redactRef(ref)}`);
|
|
26569
|
-
}
|
|
26570
|
-
}
|
|
26571
|
-
};
|
|
26572
|
-
}
|
|
26573
|
-
function createKeychainSecretReader(service = DEFAULT_KEYCHAIN_SERVICE, opts = {}) {
|
|
26574
|
-
const backend = () => opts.secrets ?? defaultSecretsBackend();
|
|
26575
|
-
return async (ref) => {
|
|
26576
|
-
try {
|
|
26577
|
-
return await backend().get({ service: ref.service ?? service, name: ref.account });
|
|
26578
|
-
} catch (err) {
|
|
26579
|
-
if (err instanceof CredentialResolutionError)
|
|
26580
|
-
throw err;
|
|
26581
|
-
throw new CredentialResolutionError("io", `keychain lookup failed for ${redactRef(ref)}`);
|
|
26582
|
-
}
|
|
26583
|
-
};
|
|
26584
|
-
}
|
|
26585
|
-
function keychainAccountName(providerId, accountId) {
|
|
26586
|
-
return `${providerId}:${accountId}`;
|
|
26587
|
-
}
|
|
26588
|
-
var MATERIAL_KINDS = new Set(["api-key", "bearer", "oauth", "aws", "gcp-service-account", "gcp-access-token"]);
|
|
26589
|
-
function coerceMaterial(value) {
|
|
26590
|
-
if (typeof value !== "object" || value === null)
|
|
26591
|
-
return;
|
|
26592
|
-
const v = value;
|
|
26593
|
-
if (typeof v.kind !== "string" || !MATERIAL_KINDS.has(v.kind))
|
|
26594
|
-
return;
|
|
26595
|
-
switch (v.kind) {
|
|
26596
|
-
case "api-key":
|
|
26597
|
-
return typeof v.key === "string" ? { kind: "api-key", key: v.key } : undefined;
|
|
26598
|
-
case "bearer":
|
|
26599
|
-
return typeof v.token === "string" ? { kind: "bearer", token: v.token, ...typeof v.expiresAt === "number" ? { expiresAt: v.expiresAt } : {} } : undefined;
|
|
26600
|
-
case "oauth":
|
|
26601
|
-
return typeof v.accessToken === "string" ? {
|
|
26602
|
-
kind: "oauth",
|
|
26603
|
-
accessToken: v.accessToken,
|
|
26604
|
-
...typeof v.refreshToken === "string" ? { refreshToken: v.refreshToken } : {},
|
|
26605
|
-
...typeof v.expiresAt === "number" ? { expiresAt: v.expiresAt } : {},
|
|
26606
|
-
...typeof v.accountId === "string" ? { accountId: v.accountId } : {},
|
|
26607
|
-
...typeof v.idToken === "string" ? { idToken: v.idToken } : {}
|
|
26608
|
-
} : undefined;
|
|
26609
|
-
case "aws":
|
|
26610
|
-
return typeof v.accessKeyId === "string" && typeof v.secretAccessKey === "string" ? { kind: "aws", accessKeyId: v.accessKeyId, secretAccessKey: v.secretAccessKey, ...typeof v.sessionToken === "string" ? { sessionToken: v.sessionToken } : {} } : undefined;
|
|
26611
|
-
case "gcp-service-account":
|
|
26612
|
-
return typeof v.clientEmail === "string" && typeof v.privateKeyPem === "string" && typeof v.tokenUri === "string" ? { kind: "gcp-service-account", clientEmail: v.clientEmail, privateKeyPem: v.privateKeyPem, tokenUri: v.tokenUri } : undefined;
|
|
26613
|
-
case "gcp-access-token":
|
|
26614
|
-
return typeof v.token === "string" ? { kind: "gcp-access-token", token: v.token } : undefined;
|
|
26615
|
-
default:
|
|
26616
|
-
return;
|
|
26617
|
-
}
|
|
26618
|
-
}
|
|
26619
|
-
|
|
26620
26651
|
// src/provider/selection.ts
|
|
26621
26652
|
import { WinterProviderResolutionError as WinterProviderResolutionError2, createRegistry } from "@yanlinglabs/winter-provider-runtime";
|
|
26622
26653
|
import { DEFAULT_PROVIDER_STALL_TIMEOUT_MS } from "@yanlinglabs/winter-agent-sdk";
|
|
@@ -26829,22 +26860,22 @@ var FORBIDDEN = /[\u0000-\u001f\u007f]/;
|
|
|
26829
26860
|
function assertLocator(locator) {
|
|
26830
26861
|
const { providerId, accountId, service } = locator;
|
|
26831
26862
|
if (typeof providerId !== "string" || providerId.trim().length === 0)
|
|
26832
|
-
throw new
|
|
26863
|
+
throw new CredentialResolutionError("malformed", "a provider credential needs a non-empty providerId");
|
|
26833
26864
|
if (typeof accountId !== "string" || accountId.trim().length === 0)
|
|
26834
|
-
throw new
|
|
26865
|
+
throw new CredentialResolutionError("malformed", `a provider credential for "${providerId}" needs a non-empty accountId`);
|
|
26835
26866
|
if (providerId.includes(":")) {
|
|
26836
|
-
throw new
|
|
26867
|
+
throw new CredentialResolutionError("malformed", `providerId "${providerId}" contains ":", which is the separator in the "<providerId>:<accountId>" keychain account name (R6-10) and would make the record ambiguous`);
|
|
26837
26868
|
}
|
|
26838
26869
|
if (FORBIDDEN.test(providerId) || FORBIDDEN.test(accountId) || service !== undefined && FORBIDDEN.test(service)) {
|
|
26839
|
-
throw new
|
|
26870
|
+
throw new CredentialResolutionError("malformed", `a provider credential locator may not contain control characters (provider "${providerId}")`);
|
|
26840
26871
|
}
|
|
26841
26872
|
if (service !== undefined && service.trim().length === 0)
|
|
26842
|
-
throw new
|
|
26873
|
+
throw new CredentialResolutionError("malformed", `an explicit keychain service for provider "${providerId}" may not be blank; omit it to use the store's default`);
|
|
26843
26874
|
}
|
|
26844
26875
|
function assertMaterial(material, ref) {
|
|
26845
26876
|
const empty = (value) => value === undefined || value.trim().length === 0;
|
|
26846
26877
|
const bad = (field) => {
|
|
26847
|
-
throw new
|
|
26878
|
+
throw new CredentialResolutionError("malformed", `the ${material.kind} credential for ${redactCredentialRef(ref)} has an empty "${field}"; an empty secret is stored happily and then fails as an opaque provider rejection on every request`);
|
|
26848
26879
|
};
|
|
26849
26880
|
switch (material.kind) {
|
|
26850
26881
|
case "api-key":
|
|
@@ -26880,13 +26911,13 @@ function assertMaterial(material, ref) {
|
|
|
26880
26911
|
}
|
|
26881
26912
|
}
|
|
26882
26913
|
function redactedFailure(operation, ref, err) {
|
|
26883
|
-
const code = err instanceof
|
|
26914
|
+
const code = err instanceof CredentialResolutionError ? err.code : "io";
|
|
26884
26915
|
const kind = err instanceof Error ? err.name : typeof err;
|
|
26885
|
-
return new
|
|
26916
|
+
return new CredentialResolutionError(code, `could not ${operation} the credential for ${redactCredentialRef(ref)}: the store failed with a ${kind} (its message is withheld because a store's error text may quote the record)`);
|
|
26886
26917
|
}
|
|
26887
26918
|
function statusFromThrow(err, ref, providerId) {
|
|
26888
26919
|
const locator = redactCredentialRef(ref);
|
|
26889
|
-
if (err instanceof
|
|
26920
|
+
if (err instanceof CredentialResolutionError) {
|
|
26890
26921
|
if (err.code === "malformed")
|
|
26891
26922
|
return { ok: false, code: "invalid", message: `the credential at ${locator} is not valid material for provider "${providerId}"` };
|
|
26892
26923
|
if (err.code === "io")
|
|
@@ -27197,4 +27228,4 @@ function selectClassifierRoute2(config, descriptorOf) {
|
|
|
27197
27228
|
return { kind: "worker-eligible" };
|
|
27198
27229
|
}
|
|
27199
27230
|
|
|
27200
|
-
export { ChildResumeModeIncomparableError, resolveChildResumeMode, ensureDefaultMessagingRuntimeRegistered, buildContinuationChain, AGENT_TOOL_CANONICAL_NAME, computeActiveSlotSet, resolveSlotToProvider, createRpcBridge2, shellWords, escapeRegExpLiteral, validatePermissionRuleString, registerTool2, getRegisteredTool, listRegisteredTools, rebrandStandingServerTools, mcpServerHasRegistrations, onCompaction2, STRUCTURED_OUTPUT_TOOL_NAME, looksLikeCommand, registerChildEngineFactory, matchFileRule, rawToRuleValue, sourceRule, resolveFileRuleAbsolutePath, resolveFileRuleAbsoluteGlobText, resolvesWithinPluginRoot, parseFrontmatter, parseAgentDefinitionFile, allowedAgentTypesFromTools, validateAgentDefinition, WinterPathsError2, sessionTempDir2, ensureTasksDir2, resolveProjectDirName2, buildForkDirectiveText, buildForkInitialMessages,
|
|
27231
|
+
export { ChildResumeModeIncomparableError, resolveChildResumeMode, ensureDefaultMessagingRuntimeRegistered, buildContinuationChain, AGENT_TOOL_CANONICAL_NAME, computeActiveSlotSet, resolveSlotToProvider, createRpcBridge2, shellWords, escapeRegExpLiteral, validatePermissionRuleString, registerTool2, getRegisteredTool, listRegisteredTools, rebrandStandingServerTools, mcpServerHasRegistrations, onCompaction2, STRUCTURED_OUTPUT_TOOL_NAME, looksLikeCommand, capBytes, neutralizeReminderTags, readWhole, readCappedLinesAndBytes, registerAttachmentRenderer, attachmentsIn, registerChildEngineFactory, matchFileRule, rawToRuleValue, sourceRule, resolveFileRuleAbsolutePath, resolveFileRuleAbsoluteGlobText, resolvesWithinPluginRoot, parseFrontmatter, parseAgentDefinitionFile, allowedAgentTypesFromTools, validateAgentDefinition, WinterPathsError2, sessionTempDir2, ensureTasksDir2, resolveProjectDirName2, buildForkDirectiveText, buildForkInitialMessages, gitInstructionsEnabled, isUserInvocable, buildSkillListing, registerPluginAgents, clearPluginAgents, registerSkillSessionRuntime, clearSkillSessionRuntime, buildHookEntriesFromSettings, defaultTrustSource, formatValidationErrors, createSchemaValidatorCache, killAllTaskProcessGroups, runGit, listWorktrees, canonicalAliases, WINTER_CANONICAL_ALIASES, DEFAULT_SKILL_BODY_BYTES, skillNameError, pluginNameError, capBytes2, parseSkillFile, validateSkillsOption, isSkillEnabled, autoSkillPermissionEntries, setHostWorkflowWorkerCommand, listWorkflowsForListing, buildWorkflowSkillPrompt, DEFAULT_CONTEXT_WINDOW_TOKENS2, ProviderTurnError, isProviderTurnError, createContextAccountant2, runEngine2, WINTER_SUMMARY_INSTRUCTION, WINTER_PREFIX_SUMMARY_INSTRUCTION, CARRIED_SUMMARY_NOTE, retainedExchangesNote, buildSummaryInstruction, redactForSummary, summarize, summarizeOverPrefix, recordedProviderSystems2, resetRecordedProviderSystems2, echoProvider2, scriptedProvider2, stubExecutor2, P5_FIXTURE_SKILL_NAME2, P5_WORKFLOW_SCRIPT2, isTestProviderName2, testProviderForNamespace, testProviderByName2, SUBAGENT_CHILD_PROBE_TEXT2, MCP_SDK_TEST_SERVER_NAME2, MCP_SDK_TEST_TOOL_NAME2, BGTASK_TEST_TOOL_NAME2, registerBgTaskTestTool2, ResumeTargetError2, ResumeTruncationError2, findContinueTarget2, findResumeTarget2, toDialectEntries2, truncateAt2, rebuildProviderMessages2, userEntry2, winterMessageIdFor2, assistantEntry2, CLAUDE_COMPACT_SUMMARY_PREAMBLE2, claudeCompactBoundaryEntry2, claudeCompactSummaryEntry2, TranscriptWriterError2, TranscriptWriter2, RUNTIME_ENGINE_VERSION2, childTranscriptSubpath, buildChildTranscriptWriter, listChildAgentIds, resolveEngineSession2, resolveProductionWinterHome2, resolveProductionStoreHome, resolveSessionProvider, redactCredentialRef, createProviderContext, providerCredentialRef2, storeProviderCredential2, deleteProviderCredential2, validateProviderCredential2, CLASSIFIER_TOOL_NAME2, CLASSIFIER_VERDICT_SCHEMA2, CLASSIFIER_NO_VERDICT_REASONS2, DEFAULT_MAX_CONTEXT_CHARS2, CLASSIFIER_SYSTEM_PROMPT2, DEFAULT_CLASSIFIER_TIMEOUT_MS2, createModelClassifier2, selectClassifierRoute2 };
|
|
@@ -15,6 +15,12 @@ import {
|
|
|
15
15
|
mcpServerHasRegistrations,
|
|
16
16
|
STRUCTURED_OUTPUT_TOOL_NAME,
|
|
17
17
|
looksLikeCommand,
|
|
18
|
+
capBytes,
|
|
19
|
+
neutralizeReminderTags,
|
|
20
|
+
readWhole,
|
|
21
|
+
readCappedLinesAndBytes,
|
|
22
|
+
registerAttachmentRenderer,
|
|
23
|
+
attachmentsIn,
|
|
18
24
|
registerChildEngineFactory,
|
|
19
25
|
matchFileRule,
|
|
20
26
|
rawToRuleValue,
|
|
@@ -29,12 +35,6 @@ import {
|
|
|
29
35
|
resolveProjectDirName2,
|
|
30
36
|
buildForkDirectiveText,
|
|
31
37
|
buildForkInitialMessages,
|
|
32
|
-
capBytes,
|
|
33
|
-
neutralizeReminderTags,
|
|
34
|
-
readWhole,
|
|
35
|
-
readCappedLinesAndBytes,
|
|
36
|
-
registerAttachmentRenderer,
|
|
37
|
-
attachmentsIn,
|
|
38
38
|
gitInstructionsEnabled,
|
|
39
39
|
isUserInvocable,
|
|
40
40
|
buildSkillListing,
|
|
@@ -79,15 +79,23 @@ import {
|
|
|
79
79
|
childTranscriptSubpath,
|
|
80
80
|
buildChildTranscriptWriter,
|
|
81
81
|
listChildAgentIds,
|
|
82
|
-
createKeychainCredentialStore,
|
|
83
|
-
createKeychainSecretReader,
|
|
84
82
|
resolveSessionProvider,
|
|
85
83
|
redactCredentialRef,
|
|
86
84
|
createProviderContext,
|
|
87
85
|
providerCredentialRef2,
|
|
88
86
|
createModelClassifier2,
|
|
89
87
|
selectClassifierRoute2
|
|
90
|
-
} from "./index-
|
|
88
|
+
} from "./index-51673qbw.js";
|
|
89
|
+
import {
|
|
90
|
+
createKeychainCredentialStore,
|
|
91
|
+
createKeychainSecretReader,
|
|
92
|
+
createHostCredentialChannel,
|
|
93
|
+
createHostBrokeredCredentialStore,
|
|
94
|
+
createHostBrokeredSecretReader,
|
|
95
|
+
mcpOAuthTestStoreEnvName,
|
|
96
|
+
resolveSessionMcpOAuthStore,
|
|
97
|
+
createHostBrokeredMcpOAuthStore
|
|
98
|
+
} from "./index-z6s3r4xm.js";
|
|
91
99
|
import {
|
|
92
100
|
createInMemoryChannel2
|
|
93
101
|
} from "./index-97t2rmtf.js";
|
|
@@ -1700,8 +1708,8 @@ function apiProviderFor(providerId) {
|
|
|
1700
1708
|
return providerId === undefined ? undefined : API_PROVIDER_BY_PROVIDER_ID[providerId];
|
|
1701
1709
|
}
|
|
1702
1710
|
var DEFAULT_PROVIDER_ACCOUNT_ID = "default";
|
|
1703
|
-
function createProductionCredentialStore(config, env, home) {
|
|
1704
|
-
const keychain = createKeychainCredentialStore(resolveSessionKeychainService(config));
|
|
1711
|
+
function createProductionCredentialStore(config, env, home, keychainMember) {
|
|
1712
|
+
const keychain = keychainMember ?? createKeychainCredentialStore(resolveSessionKeychainService(config));
|
|
1705
1713
|
return createCompositeCredentialStore([
|
|
1706
1714
|
{
|
|
1707
1715
|
...keychain,
|
|
@@ -2201,7 +2209,8 @@ var ALL_TIER_REFUSED_ENV = [
|
|
|
2201
2209
|
storeHomeEnvName(WINTER_BRAND5),
|
|
2202
2210
|
pluginCacheDirEnvName(WINTER_BRAND5),
|
|
2203
2211
|
providerManagedByHostEnvName(WINTER_BRAND5),
|
|
2204
|
-
disableCronEnvName(WINTER_BRAND5)
|
|
2212
|
+
disableCronEnvName(WINTER_BRAND5),
|
|
2213
|
+
mcpOAuthTestStoreEnvName(WINTER_BRAND5)
|
|
2205
2214
|
];
|
|
2206
2215
|
function escapeRegExpLiteral2(literal) {
|
|
2207
2216
|
return literal.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -5469,6 +5478,7 @@ function describeCatalogModel(catalog, model, providerId) {
|
|
|
5469
5478
|
async function buildProductionWiring(opts) {
|
|
5470
5479
|
const { config, env } = opts;
|
|
5471
5480
|
const brand = config.brand ?? WINTER_BRAND15;
|
|
5481
|
+
const mcpOAuthTestStoreFile = env[mcpOAuthTestStoreEnvName(brand)];
|
|
5472
5482
|
const winterHome = opts.winterHome ?? config.winterHome ?? resolveWinterHome2(env, brand);
|
|
5473
5483
|
const storeHomeEnv = env[storeHomeEnvName2(brand)];
|
|
5474
5484
|
const storeHome = config.storeHome ?? (isUnset(storeHomeEnv) ? undefined : storeHomeEnv);
|
|
@@ -5643,9 +5653,15 @@ async function buildProductionWiring(opts) {
|
|
|
5643
5653
|
...skillListingBudgetFraction !== undefined ? { budgetFraction: skillListingBudgetFraction } : {},
|
|
5644
5654
|
...config.contextWindowTokens !== undefined ? { contextWindowTokens: config.contextWindowTokens } : {}
|
|
5645
5655
|
});
|
|
5656
|
+
const hostCredentialChannel = config.hostCredentials === true ? createHostCredentialChannel() : undefined;
|
|
5657
|
+
const hostCredentialOptions = hostCredentialChannel !== undefined ? {
|
|
5658
|
+
credentials: createProductionCredentialStore(config, env, opts.provider?.home ?? env["HOME"] ?? "", createHostBrokeredCredentialStore(hostCredentialChannel)),
|
|
5659
|
+
readKeychainSecret: createHostBrokeredSecretReader(hostCredentialChannel)
|
|
5660
|
+
} : {};
|
|
5646
5661
|
const providerWiring = buildSessionProvider({
|
|
5647
5662
|
config,
|
|
5648
5663
|
env,
|
|
5664
|
+
...hostCredentialOptions,
|
|
5649
5665
|
providerSettings: () => providerSettingsFrom(settingsGetter()),
|
|
5650
5666
|
resolveSlot: (requested, currentModelKey) => resolveSlot(requested, currentModelKey),
|
|
5651
5667
|
advisorModelSetting: () => settingsGetter()?.advisor?.model,
|
|
@@ -5912,6 +5928,8 @@ async function buildProductionWiring(opts) {
|
|
|
5912
5928
|
...pluginWorkflows.length > 0 ? { pluginWorkflows } : {},
|
|
5913
5929
|
...settingSources !== undefined ? { settingSources } : {},
|
|
5914
5930
|
extraMcpServerSources,
|
|
5931
|
+
mcpOAuthStore: hostCredentialChannel !== undefined ? createHostBrokeredMcpOAuthStore(hostCredentialChannel) : resolveSessionMcpOAuthStore({ keychainService: resolveSessionKeychainService(config), testStoreFile: mcpOAuthTestStoreFile }),
|
|
5932
|
+
...hostCredentialChannel !== undefined ? { hostCredentialChannel } : {},
|
|
5915
5933
|
initSlashCommands,
|
|
5916
5934
|
initSkills,
|
|
5917
5935
|
initPlugins,
|