@mastra/code-sdk 1.13.1-alpha.0 → 1.14.0-alpha.2
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/agents/credential-resolver.d.ts +26 -22
- package/dist/agents/credential-resolver.d.ts.map +1 -1
- package/dist/agents/credential-resolver.js +54 -34
- package/dist/agents/credential-resolver.js.map +1 -1
- package/dist/agents/mastracode-gateway.d.ts.map +1 -1
- package/dist/agents/mastracode-gateway.js +18 -44
- package/dist/agents/mastracode-gateway.js.map +1 -1
- package/dist/agents/memory.d.ts.map +1 -1
- package/dist/agents/memory.js.map +1 -1
- package/dist/agents/model.d.ts +9 -5
- package/dist/agents/model.d.ts.map +1 -1
- package/dist/agents/model.js +42 -8
- package/dist/agents/model.js.map +1 -1
- package/dist/auth/account-rotation-processor.d.ts +2 -0
- package/dist/auth/account-rotation-processor.d.ts.map +1 -1
- package/dist/auth/account-rotation-processor.js +4 -3
- package/dist/auth/account-rotation-processor.js.map +1 -1
- package/dist/auth/storage.js +1 -1
- package/dist/auth/storage.js.map +1 -1
- package/dist/index.d.ts +14 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -7
- package/dist/index.js.map +1 -1
- package/dist/providers/github-copilot-gateway.d.ts +35 -0
- package/dist/providers/github-copilot-gateway.d.ts.map +1 -0
- package/dist/providers/github-copilot-gateway.js +61 -0
- package/dist/providers/github-copilot-gateway.js.map +1 -0
- package/dist/providers/kimi-coding.d.ts +0 -1
- package/dist/providers/kimi-coding.d.ts.map +1 -1
- package/dist/providers/kimi-coding.js +1 -7
- package/dist/providers/kimi-coding.js.map +1 -1
- package/dist/providers/model-ids.d.ts +18 -0
- package/dist/providers/model-ids.d.ts.map +1 -1
- package/dist/providers/model-ids.js +39 -1
- package/dist/providers/model-ids.js.map +1 -1
- package/dist/providers/provider-thinking.d.ts +5 -0
- package/dist/providers/provider-thinking.d.ts.map +1 -1
- package/dist/providers/provider-thinking.js +32 -2
- package/dist/providers/provider-thinking.js.map +1 -1
- package/dist/providers/thinking-request.d.ts +14 -0
- package/dist/providers/thinking-request.d.ts.map +1 -0
- package/dist/providers/thinking-request.js +90 -0
- package/dist/providers/thinking-request.js.map +1 -0
- package/dist/providers/xai.d.ts +2 -2
- package/dist/providers/xai.d.ts.map +1 -1
- package/dist/providers/xai.js.map +1 -1
- package/dist/schema.d.ts +13 -0
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +2 -0
- package/dist/schema.js.map +1 -1
- package/dist/thinking.d.ts +1 -0
- package/dist/thinking.d.ts.map +1 -1
- package/dist/thinking.js +23 -5
- package/dist/thinking.js.map +1 -1
- package/package.json +10 -10
- package/dist/providers/deepseek-thinking.d.ts +0 -4
- package/dist/providers/deepseek-thinking.d.ts.map +0 -1
- package/dist/providers/deepseek-thinking.js +0 -16
- package/dist/providers/deepseek-thinking.js.map +0 -1
|
@@ -3,56 +3,60 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Locally, model resolution reads the server-global file-backed `AuthStorage`.
|
|
5
5
|
* A deployed web host registers a {@link CredentialStoreProvider} at boot; from
|
|
6
|
-
* then on `resolveModel`
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
6
|
+
* then on `resolveModel` uses the host's trusted execution policy, never mutable
|
|
7
|
+
* session state. Factory scope reads organization credentials only. User scope reads
|
|
8
|
+
* the Factory session owner's credentials only, or the authenticated principal
|
|
9
|
+
* for project-less personal sessions.
|
|
10
10
|
*
|
|
11
11
|
* When no provider is registered (TUI, local web), everything falls through to
|
|
12
12
|
* the existing global behavior unchanged.
|
|
13
13
|
*/
|
|
14
14
|
import type { RequestContext } from '@mastra/core/request-context';
|
|
15
15
|
import type { CredentialStore } from '../auth/types.js';
|
|
16
|
-
|
|
16
|
+
export type CredentialScope = 'factory' | 'user';
|
|
17
|
+
/** The identity and exclusive scope a credential lookup is resolved against. */
|
|
17
18
|
export interface CredentialTenant {
|
|
18
19
|
/** Org tenant; absent for personal accounts (store impls may synthesize one). */
|
|
19
20
|
orgId?: string;
|
|
20
|
-
/** Stable user id
|
|
21
|
+
/** Stable user id used for user-scoped credentials and tenant cache keys. */
|
|
21
22
|
userId: string;
|
|
22
|
-
/**
|
|
23
|
-
|
|
24
|
-
* trusted server code for automated (factory) runs so they ride the org's
|
|
25
|
-
* shared keys first and only fall back to the acting user's credentials.
|
|
26
|
-
*/
|
|
27
|
-
orgFirst?: boolean;
|
|
23
|
+
/** Exclusive credential scope for this request. */
|
|
24
|
+
credentialScope: CredentialScope;
|
|
28
25
|
}
|
|
29
26
|
/**
|
|
30
|
-
* Returns a tenant-scoped {@link CredentialStore}, or `undefined`
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
* authoritative async work inside `getApiKey`.
|
|
27
|
+
* Returns a tenant-scoped {@link CredentialStore}, or `undefined` when tenant
|
|
28
|
+
* storage is unavailable. Must be synchronous — implementations serve from a
|
|
29
|
+
* primed snapshot and do authoritative async work inside `getApiKey`.
|
|
34
30
|
*/
|
|
35
31
|
export type CredentialStoreProvider = (tenant: CredentialTenant) => CredentialStore | undefined;
|
|
32
|
+
export type CredentialTenantResolver = (requestContext: RequestContext) => Promise<CredentialTenant | undefined>;
|
|
36
33
|
/** Register (or clear) the tenant credential store provider. Deployed-web only. */
|
|
37
|
-
export declare function setCredentialStoreProvider(provider: CredentialStoreProvider | undefined): void;
|
|
34
|
+
export declare function setCredentialStoreProvider(provider: CredentialStoreProvider | undefined, resolveTenant?: CredentialTenantResolver): void;
|
|
35
|
+
/** Refresh authority before a fresh model invocation; cloned contexts inherit only an opaque token. */
|
|
36
|
+
export declare function prepareCredentialTenant(requestContext?: RequestContext): Promise<void>;
|
|
37
|
+
export declare function withCredentialTenantPreparation<T>(resolve: (ctx: {
|
|
38
|
+
requestContext: RequestContext;
|
|
39
|
+
}) => T): (ctx: {
|
|
40
|
+
requestContext: RequestContext;
|
|
41
|
+
}) => Promise<T>;
|
|
38
42
|
/**
|
|
39
43
|
* Whether a tenant provider is registered. Used to disable the
|
|
40
44
|
* `loadStoredApiKeysIntoEnv` side-channel in deployed mode — per-tenant
|
|
41
45
|
* credentials must never leak into process-global env vars.
|
|
42
46
|
*/
|
|
43
47
|
export declare function hasCredentialStoreProvider(): boolean;
|
|
48
|
+
export declare function hasCredentialTenantResolver(): boolean;
|
|
49
|
+
export declare function resolveCredentialScope(requestContext?: RequestContext): CredentialScope;
|
|
44
50
|
/**
|
|
45
51
|
* Derive the calling tenant from a request context, if an authenticated web
|
|
46
52
|
* user was stashed on it. Mirrors the web layer's stable-id resolution
|
|
47
53
|
* (`workosId` falling back to the provider `id`).
|
|
48
54
|
*
|
|
49
|
-
*
|
|
50
|
-
* `authenticateToken` returned, so its shape follows the provider: a flat user
|
|
51
|
-
* (WorkOS) or a `{ session, user }` wrapper (better-auth). Reading only the
|
|
52
|
-
* flat shape resolves no tenant at all for the wrapper, which in deployed mode
|
|
53
|
-
* fails closed to an empty credential store.
|
|
55
|
+
* Session state and HTTP-supplied policy values never establish credential authority.
|
|
54
56
|
*/
|
|
55
57
|
export declare function resolveTenantFromRequestContext(requestContext?: RequestContext): CredentialTenant | undefined;
|
|
58
|
+
/** Authenticated principal only, for hosts resolving durable session ownership. */
|
|
59
|
+
export declare function resolveAuthenticatedCredentialTenant(requestContext?: RequestContext): CredentialTenant | undefined;
|
|
56
60
|
/**
|
|
57
61
|
* Resolve the credential store for a request. Local mode returns `undefined`
|
|
58
62
|
* and keeps the global `AuthStorage` behavior. Once deployed web registers a
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"credential-resolver.d.ts","sourceRoot":"","sources":["../../src/agents/credential-resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAExD,
|
|
1
|
+
{"version":3,"file":"credential-resolver.d.ts","sourceRoot":"","sources":["../../src/agents/credential-resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAExD,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,MAAM,CAAC;AAEjD,gFAAgF;AAChF,MAAM,WAAW,gBAAgB;IAC/B,iFAAiF;IACjF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6EAA6E;IAC7E,MAAM,EAAE,MAAM,CAAC;IACf,mDAAmD;IACnD,eAAe,EAAE,eAAe,CAAC;CAClC;AAED;;;;GAIG;AACH,MAAM,MAAM,uBAAuB,GAAG,CAAC,MAAM,EAAE,gBAAgB,KAAK,eAAe,GAAG,SAAS,CAAC;AAEhG,MAAM,MAAM,wBAAwB,GAAG,CAAC,cAAc,EAAE,cAAc,KAAK,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC,CAAC;AAqBjH,mFAAmF;AACnF,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,uBAAuB,GAAG,SAAS,EAC7C,aAAa,CAAC,EAAE,wBAAwB,GACvC,IAAI,CAIN;AAED,uGAAuG;AACvG,wBAAsB,uBAAuB,CAAC,cAAc,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAiB5F;AAED,wBAAgB,+BAA+B,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,GAAG,EAAE;IAAE,cAAc,EAAE,cAAc,CAAA;CAAE,KAAK,CAAC,IAC1F,KAAK;IAAE,cAAc,EAAE,cAAc,CAAA;CAAE,KAAG,OAAO,CAAC,CAAC,CAAC,CAInE;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,IAAI,OAAO,CAEpD;AAED,wBAAgB,2BAA2B,IAAI,OAAO,CAErD;AAkBD,wBAAgB,sBAAsB,CAAC,cAAc,CAAC,EAAE,cAAc,GAAG,eAAe,CAEvF;AAED;;;;;;GAMG;AACH,wBAAgB,+BAA+B,CAAC,cAAc,CAAC,EAAE,cAAc,GAAG,gBAAgB,GAAG,SAAS,CAI7G;AAED,mFAAmF;AACnF,wBAAgB,oCAAoC,CAAC,cAAc,CAAC,EAAE,cAAc,GAAG,gBAAgB,GAAG,SAAS,CAclH;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,cAAc,CAAC,EAAE,cAAc,GAAG,eAAe,GAAG,SAAS,CAsBnG"}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
//#region src/agents/credential-resolver.ts
|
|
2
|
+
const CREDENTIAL_POLICY_KEY = "mastracode__credentialPolicy";
|
|
2
3
|
let credentialStoreProvider;
|
|
4
|
+
let credentialTenantResolver;
|
|
5
|
+
let trustedTenants = /* @__PURE__ */ new WeakMap();
|
|
3
6
|
const unavailableTenantCredentialStore = {
|
|
4
7
|
allowEnvironmentFallback: false,
|
|
5
8
|
reload() {},
|
|
@@ -8,8 +11,34 @@ const unavailableTenantCredentialStore = {
|
|
|
8
11
|
async getApiKey() {}
|
|
9
12
|
};
|
|
10
13
|
/** Register (or clear) the tenant credential store provider. Deployed-web only. */
|
|
11
|
-
function setCredentialStoreProvider(provider) {
|
|
14
|
+
function setCredentialStoreProvider(provider, resolveTenant) {
|
|
12
15
|
credentialStoreProvider = provider;
|
|
16
|
+
credentialTenantResolver = provider ? resolveTenant : void 0;
|
|
17
|
+
trustedTenants = /* @__PURE__ */ new WeakMap();
|
|
18
|
+
}
|
|
19
|
+
/** Refresh authority before a fresh model invocation; cloned contexts inherit only an opaque token. */
|
|
20
|
+
async function prepareCredentialTenant(requestContext) {
|
|
21
|
+
if (!credentialTenantResolver) return;
|
|
22
|
+
if (!requestContext) throw new Error("Tenant model resolution requires a request context.");
|
|
23
|
+
const inheritedToken = requestContext.get(CREDENTIAL_POLICY_KEY);
|
|
24
|
+
const inheritedPolicy = inheritedToken && typeof inheritedToken === "object" ? trustedTenants.get(inheritedToken) : void 0;
|
|
25
|
+
const sourceController = inheritedPolicy?.sourceContext.get("controller");
|
|
26
|
+
const sourceContext = inheritedPolicy && sourceController?.resourceId ? inheritedPolicy.sourceContext : requestContext;
|
|
27
|
+
const token = {};
|
|
28
|
+
requestContext.set(CREDENTIAL_POLICY_KEY, token);
|
|
29
|
+
trustedTenants.set(token, { sourceContext });
|
|
30
|
+
const tenant = await credentialTenantResolver(sourceContext);
|
|
31
|
+
if (!tenant) throw new Error("Tenant model credential policy could not be resolved.");
|
|
32
|
+
trustedTenants.set(token, {
|
|
33
|
+
tenant,
|
|
34
|
+
sourceContext
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
function withCredentialTenantPreparation(resolve) {
|
|
38
|
+
return async (ctx) => {
|
|
39
|
+
await prepareCredentialTenant(ctx.requestContext);
|
|
40
|
+
return resolve(ctx);
|
|
41
|
+
};
|
|
13
42
|
}
|
|
14
43
|
/**
|
|
15
44
|
* Whether a tenant provider is registered. Used to disable the
|
|
@@ -19,47 +48,38 @@ function setCredentialStoreProvider(provider) {
|
|
|
19
48
|
function hasCredentialStoreProvider() {
|
|
20
49
|
return credentialStoreProvider !== void 0;
|
|
21
50
|
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
* `factoryProjectId` into session state (board-run creation) — interactive
|
|
28
|
-
* chat sessions never carry it. Runs on such sessions resolve credentials
|
|
29
|
-
* org > user regardless of who sent the message: a board run continued
|
|
30
|
-
* interactively, or a model switch inside it, is still org work.
|
|
31
|
-
*/
|
|
32
|
-
function isFactorySessionContext(requestContext) {
|
|
33
|
-
const controller = requestContext?.get("controller");
|
|
34
|
-
if (!controller || typeof controller !== "object") return false;
|
|
35
|
-
const factoryProjectId = controller.state?.factoryProjectId;
|
|
36
|
-
return typeof factoryProjectId === "string" && factoryProjectId.length > 0;
|
|
51
|
+
function hasCredentialTenantResolver() {
|
|
52
|
+
return credentialTenantResolver !== void 0;
|
|
53
|
+
}
|
|
54
|
+
function resolveCredentialScope(requestContext) {
|
|
55
|
+
return resolveTenantFromRequestContext(requestContext)?.credentialScope ?? "user";
|
|
37
56
|
}
|
|
38
57
|
/**
|
|
39
58
|
* Derive the calling tenant from a request context, if an authenticated web
|
|
40
59
|
* user was stashed on it. Mirrors the web layer's stable-id resolution
|
|
41
60
|
* (`workosId` falling back to the provider `id`).
|
|
42
61
|
*
|
|
43
|
-
*
|
|
44
|
-
* `authenticateToken` returned, so its shape follows the provider: a flat user
|
|
45
|
-
* (WorkOS) or a `{ session, user }` wrapper (better-auth). Reading only the
|
|
46
|
-
* flat shape resolves no tenant at all for the wrapper, which in deployed mode
|
|
47
|
-
* fails closed to an empty credential store.
|
|
62
|
+
* Session state and HTTP-supplied policy values never establish credential authority.
|
|
48
63
|
*/
|
|
49
64
|
function resolveTenantFromRequestContext(requestContext) {
|
|
65
|
+
if (!credentialTenantResolver) return resolveAuthenticatedCredentialTenant(requestContext);
|
|
66
|
+
const token = requestContext?.get(CREDENTIAL_POLICY_KEY);
|
|
67
|
+
return token && typeof token === "object" ? trustedTenants.get(token)?.tenant : void 0;
|
|
68
|
+
}
|
|
69
|
+
/** Authenticated principal only, for hosts resolving durable session ownership. */
|
|
70
|
+
function resolveAuthenticatedCredentialTenant(requestContext) {
|
|
50
71
|
const raw = requestContext?.get("user");
|
|
51
72
|
if (!raw || typeof raw !== "object") return void 0;
|
|
52
73
|
const wrapped = Boolean(raw.user && typeof raw.user === "object" && raw.session && typeof raw.session === "object");
|
|
53
74
|
const user = wrapped ? raw.user : raw;
|
|
54
|
-
const
|
|
55
|
-
const
|
|
56
|
-
if (typeof
|
|
57
|
-
if (
|
|
58
|
-
const orgFirst = raw.orgFirstCredentials === true || user.orgFirstCredentials === true || isFactorySessionContext(requestContext);
|
|
75
|
+
const principalOrgId = wrapped ? raw.session?.activeOrganizationId : user.organizationId;
|
|
76
|
+
const principalUserId = user.workosId ?? user.id;
|
|
77
|
+
if (typeof principalUserId !== "string" || !principalUserId) return void 0;
|
|
78
|
+
if (principalOrgId !== void 0 && typeof principalOrgId !== "string") return void 0;
|
|
59
79
|
return {
|
|
60
|
-
orgId,
|
|
61
|
-
userId,
|
|
62
|
-
|
|
80
|
+
orgId: principalOrgId,
|
|
81
|
+
userId: principalUserId,
|
|
82
|
+
credentialScope: "user"
|
|
63
83
|
};
|
|
64
84
|
}
|
|
65
85
|
/**
|
|
@@ -74,9 +94,8 @@ function resolveCredentialStore(requestContext) {
|
|
|
74
94
|
if (!tenant) {
|
|
75
95
|
const rawUser = requestContext?.get("user");
|
|
76
96
|
console.warn("[MastraCode] Tenant credential resolution failed closed", {
|
|
77
|
-
reason: rawUser === void 0 ? "missing-user-context" : "
|
|
78
|
-
hasRequestContext: requestContext !== void 0
|
|
79
|
-
factorySession: isFactorySessionContext(requestContext)
|
|
97
|
+
reason: rawUser === void 0 ? "missing-user-context" : "credential-policy-unavailable",
|
|
98
|
+
hasRequestContext: requestContext !== void 0
|
|
80
99
|
});
|
|
81
100
|
return unavailableTenantCredentialStore;
|
|
82
101
|
}
|
|
@@ -85,13 +104,14 @@ function resolveCredentialStore(requestContext) {
|
|
|
85
104
|
console.warn("[MastraCode] Tenant credential resolution failed closed", {
|
|
86
105
|
reason: "credential-store-unavailable",
|
|
87
106
|
hasOrganization: tenant.orgId !== void 0,
|
|
88
|
-
|
|
107
|
+
credentialScope: tenant.credentialScope,
|
|
108
|
+
ownerResolved: tenant.credentialScope === "factory" || tenant.userId !== void 0
|
|
89
109
|
});
|
|
90
110
|
return unavailableTenantCredentialStore;
|
|
91
111
|
}
|
|
92
112
|
return store;
|
|
93
113
|
}
|
|
94
114
|
//#endregion
|
|
95
|
-
export { hasCredentialStoreProvider, resolveCredentialStore, resolveTenantFromRequestContext, setCredentialStoreProvider };
|
|
115
|
+
export { hasCredentialStoreProvider, hasCredentialTenantResolver, prepareCredentialTenant, resolveAuthenticatedCredentialTenant, resolveCredentialScope, resolveCredentialStore, resolveTenantFromRequestContext, setCredentialStoreProvider, withCredentialTenantPreparation };
|
|
96
116
|
|
|
97
117
|
//# sourceMappingURL=credential-resolver.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"credential-resolver.js","names":[],"sources":["../../src/agents/credential-resolver.ts"],"sourcesContent":["/**\n * Per-tenant credential resolution seam for deployed (multi-user) servers.\n *\n * Locally, model resolution reads the server-global file-backed `AuthStorage`.\n * A deployed web host registers a {@link CredentialStoreProvider} at boot; from\n * then on `resolveModel` derives the calling tenant from the request context\n * (the web auth gate stashes the authenticated user under the `user` key) and\n * resolves credentials through the tenant's own store — user credentials over\n * org credentials over server env vars, with OAuth refresh owned by the store.\n *\n * When no provider is registered (TUI, local web), everything falls through to\n * the existing global behavior unchanged.\n */\n\nimport type { RequestContext } from '@mastra/core/request-context';\nimport type { CredentialStore } from '../auth/types.js';\n\n/** The identity a credential lookup is scoped to. */\nexport interface CredentialTenant {\n /** Org tenant; absent for personal accounts (store impls may synthesize one). */\n orgId?: string;\n /** Stable user id from the web auth adapter. */\n userId: string;\n /**\n * Resolve org-shared credentials over the user's personal ones. Set by\n * trusted server code for automated (factory) runs so they ride the org's\n * shared keys first and only fall back to the acting user's credentials.\n */\n orgFirst?: boolean;\n}\n\n/**\n * Returns a tenant-scoped {@link CredentialStore}, or `undefined` to fall back\n * to the global store (e.g. tenant storage temporarily unavailable). Must be\n * synchronous — implementations serve from a primed snapshot and do\n * authoritative async work inside `getApiKey`.\n */\nexport type CredentialStoreProvider = (tenant: CredentialTenant) => CredentialStore | undefined;\n\nlet credentialStoreProvider: CredentialStoreProvider | undefined;\n\nconst unavailableTenantCredentialStore: CredentialStore = {\n allowEnvironmentFallback: false,\n reload() {},\n get() {\n return undefined;\n },\n getStoredApiKey() {\n return undefined;\n },\n async getApiKey() {\n return undefined;\n },\n};\n\n/** Register (or clear) the tenant credential store provider. Deployed-web only. */\nexport function setCredentialStoreProvider(provider: CredentialStoreProvider | undefined): void {\n credentialStoreProvider = provider;\n}\n\n/**\n * Whether a tenant provider is registered. Used to disable the\n * `loadStoredApiKeysIntoEnv` side-channel in deployed mode — per-tenant\n * credentials must never leak into process-global env vars.\n */\nexport function hasCredentialStoreProvider(): boolean {\n return credentialStoreProvider !== undefined;\n}\n\n/** Shape the web auth gate stashes on the request context under `user`. */\ninterface RequestContextUser {\n workosId?: string;\n id?: string;\n organizationId?: string;\n /** Trusted server code marks automated runs to resolve org > user credentials. */\n orgFirstCredentials?: boolean;\n}\n\n/**\n * Session-shaped `authenticateToken` results (better-auth) arrive as a wrapper\n * whose active org lives on the session half rather than on the user.\n */\ninterface RequestContextSession {\n user?: RequestContextUser;\n session?: { activeOrganizationId?: string };\n}\n\n/**\n * Whether the request context belongs to a run on a factory-owned session.\n *\n * The agent controller stamps the session's state onto the request context\n * under `controller`, and only trusted factory server code ever writes\n * `factoryProjectId` into session state (board-run creation) — interactive\n * chat sessions never carry it. Runs on such sessions resolve credentials\n * org > user regardless of who sent the message: a board run continued\n * interactively, or a model switch inside it, is still org work.\n */\nfunction isFactorySessionContext(requestContext?: RequestContext): boolean {\n const controller = requestContext?.get('controller') as { state?: { factoryProjectId?: unknown } } | undefined;\n if (!controller || typeof controller !== 'object') return false;\n const factoryProjectId = controller.state?.factoryProjectId;\n return typeof factoryProjectId === 'string' && factoryProjectId.length > 0;\n}\n\n/**\n * Derive the calling tenant from a request context, if an authenticated web\n * user was stashed on it. Mirrors the web layer's stable-id resolution\n * (`workosId` falling back to the provider `id`).\n *\n * The value under `user` is whatever the active auth provider's\n * `authenticateToken` returned, so its shape follows the provider: a flat user\n * (WorkOS) or a `{ session, user }` wrapper (better-auth). Reading only the\n * flat shape resolves no tenant at all for the wrapper, which in deployed mode\n * fails closed to an empty credential store.\n */\nexport function resolveTenantFromRequestContext(requestContext?: RequestContext): CredentialTenant | undefined {\n const raw = requestContext?.get('user') as (RequestContextUser & RequestContextSession) | undefined;\n if (!raw || typeof raw !== 'object') return undefined;\n\n // Precedence matches `toFactoryAuthUser` in `@mastra/factory`: a wrapper's org\n // comes from the session half only, never from the inner user. The two parsers\n // cannot share code across the package boundary, so they must agree by rule.\n const wrapped = Boolean(raw.user && typeof raw.user === 'object' && raw.session && typeof raw.session === 'object');\n const user = wrapped ? (raw.user as RequestContextUser) : raw;\n const orgId = wrapped ? raw.session?.activeOrganizationId : user.organizationId;\n const userId = user.workosId ?? user.id;\n // The slot holds whatever the provider returned, so the declared string\n // types are hopes, not guarantees. A non-string id must refuse the tenant\n // (fail closed), not flow onward as a mistyped key.\n if (typeof userId !== 'string' || !userId) return undefined;\n if (orgId !== undefined && typeof orgId !== 'string') return undefined;\n // Only an exact `true` flips precedence — anything else keeps user > org.\n // Server code stamps the flag on the stashed value itself, so read it from\n // the top level as well as the unwrapped user (better-auth wrapper shape).\n const orgFirst =\n raw.orgFirstCredentials === true || user.orgFirstCredentials === true || isFactorySessionContext(requestContext);\n return { orgId, userId, ...(orgFirst ? { orgFirst } : {}) };\n}\n\n/**\n * Resolve the credential store for a request. Local mode returns `undefined`\n * and keeps the global `AuthStorage` behavior. Once deployed web registers a\n * provider, missing tenant identity or unavailable tenant storage fails closed\n * through an empty store that also disables process-environment fallback.\n */\nexport function resolveCredentialStore(requestContext?: RequestContext): CredentialStore | undefined {\n if (!credentialStoreProvider) return undefined;\n const tenant = resolveTenantFromRequestContext(requestContext);\n if (!tenant) {\n const rawUser = requestContext?.get('user');\n console.warn('[MastraCode] Tenant credential resolution failed closed', {\n reason: rawUser === undefined ? 'missing-user-context' : 'invalid-principal-shape',\n hasRequestContext: requestContext !== undefined,\n factorySession: isFactorySessionContext(requestContext),\n });\n return unavailableTenantCredentialStore;\n }\n const store = credentialStoreProvider(tenant);\n if (!store) {\n console.warn('[MastraCode] Tenant credential resolution failed closed', {\n reason: 'credential-store-unavailable',\n hasOrganization: tenant.orgId !== undefined,\n orgFirst: tenant.orgFirst === true,\n });\n return unavailableTenantCredentialStore;\n }\n return store;\n}\n"],"mappings":";AAuCA,IAAI;AAEJ,MAAM,mCAAoD;CACxD,0BAA0B;CAC1B,SAAS,CAAC;CACV,MAAM,CAEN;CACA,kBAAkB,CAElB;CACA,MAAM,YAAY,CAElB;AACF;;AAGA,SAAgB,2BAA2B,UAAqD;CAC9F,0BAA0B;AAC5B;;;;;;AAOA,SAAgB,6BAAsC;CACpD,OAAO,4BAA4B,KAAA;AACrC;;;;;;;;;;;AA8BA,SAAS,wBAAwB,gBAA0C;CACzE,MAAM,aAAa,gBAAgB,IAAI,YAAY;CACnD,IAAI,CAAC,cAAc,OAAO,eAAe,UAAU,OAAO;CAC1D,MAAM,mBAAmB,WAAW,OAAO;CAC3C,OAAO,OAAO,qBAAqB,YAAY,iBAAiB,SAAS;AAC3E;;;;;;;;;;;;AAaA,SAAgB,gCAAgC,gBAA+D;CAC7G,MAAM,MAAM,gBAAgB,IAAI,MAAM;CACtC,IAAI,CAAC,OAAO,OAAO,QAAQ,UAAU,OAAO,KAAA;CAK5C,MAAM,UAAU,QAAQ,IAAI,QAAQ,OAAO,IAAI,SAAS,YAAY,IAAI,WAAW,OAAO,IAAI,YAAY,QAAQ;CAClH,MAAM,OAAO,UAAW,IAAI,OAA8B;CAC1D,MAAM,QAAQ,UAAU,IAAI,SAAS,uBAAuB,KAAK;CACjE,MAAM,SAAS,KAAK,YAAY,KAAK;CAIrC,IAAI,OAAO,WAAW,YAAY,CAAC,QAAQ,OAAO,KAAA;CAClD,IAAI,UAAU,KAAA,KAAa,OAAO,UAAU,UAAU,OAAO,KAAA;CAI7D,MAAM,WACJ,IAAI,wBAAwB,QAAQ,KAAK,wBAAwB,QAAQ,wBAAwB,cAAc;CACjH,OAAO;EAAE;EAAO;EAAQ,GAAI,WAAW,EAAE,SAAS,IAAI,CAAC;CAAG;AAC5D;;;;;;;AAQA,SAAgB,uBAAuB,gBAA8D;CACnG,IAAI,CAAC,yBAAyB,OAAO,KAAA;CACrC,MAAM,SAAS,gCAAgC,cAAc;CAC7D,IAAI,CAAC,QAAQ;EACX,MAAM,UAAU,gBAAgB,IAAI,MAAM;EAC1C,QAAQ,KAAK,2DAA2D;GACtE,QAAQ,YAAY,KAAA,IAAY,yBAAyB;GACzD,mBAAmB,mBAAmB,KAAA;GACtC,gBAAgB,wBAAwB,cAAc;EACxD,CAAC;EACD,OAAO;CACT;CACA,MAAM,QAAQ,wBAAwB,MAAM;CAC5C,IAAI,CAAC,OAAO;EACV,QAAQ,KAAK,2DAA2D;GACtE,QAAQ;GACR,iBAAiB,OAAO,UAAU,KAAA;GAClC,UAAU,OAAO,aAAa;EAChC,CAAC;EACD,OAAO;CACT;CACA,OAAO;AACT"}
|
|
1
|
+
{"version":3,"file":"credential-resolver.js","names":[],"sources":["../../src/agents/credential-resolver.ts"],"sourcesContent":["/**\n * Per-tenant credential resolution seam for deployed (multi-user) servers.\n *\n * Locally, model resolution reads the server-global file-backed `AuthStorage`.\n * A deployed web host registers a {@link CredentialStoreProvider} at boot; from\n * then on `resolveModel` uses the host's trusted execution policy, never mutable\n * session state. Factory scope reads organization credentials only. User scope reads\n * the Factory session owner's credentials only, or the authenticated principal\n * for project-less personal sessions.\n *\n * When no provider is registered (TUI, local web), everything falls through to\n * the existing global behavior unchanged.\n */\n\nimport type { RequestContext } from '@mastra/core/request-context';\nimport type { CredentialStore } from '../auth/types.js';\n\nexport type CredentialScope = 'factory' | 'user';\n\n/** The identity and exclusive scope a credential lookup is resolved against. */\nexport interface CredentialTenant {\n /** Org tenant; absent for personal accounts (store impls may synthesize one). */\n orgId?: string;\n /** Stable user id used for user-scoped credentials and tenant cache keys. */\n userId: string;\n /** Exclusive credential scope for this request. */\n credentialScope: CredentialScope;\n}\n\n/**\n * Returns a tenant-scoped {@link CredentialStore}, or `undefined` when tenant\n * storage is unavailable. Must be synchronous — implementations serve from a\n * primed snapshot and do authoritative async work inside `getApiKey`.\n */\nexport type CredentialStoreProvider = (tenant: CredentialTenant) => CredentialStore | undefined;\n\nexport type CredentialTenantResolver = (requestContext: RequestContext) => Promise<CredentialTenant | undefined>;\n\nconst CREDENTIAL_POLICY_KEY = 'mastracode__credentialPolicy';\nlet credentialStoreProvider: CredentialStoreProvider | undefined;\nlet credentialTenantResolver: CredentialTenantResolver | undefined;\nlet trustedTenants = new WeakMap<object, { tenant?: CredentialTenant; sourceContext: RequestContext }>();\n\nconst unavailableTenantCredentialStore: CredentialStore = {\n allowEnvironmentFallback: false,\n reload() {},\n get() {\n return undefined;\n },\n getStoredApiKey() {\n return undefined;\n },\n async getApiKey() {\n return undefined;\n },\n};\n\n/** Register (or clear) the tenant credential store provider. Deployed-web only. */\nexport function setCredentialStoreProvider(\n provider: CredentialStoreProvider | undefined,\n resolveTenant?: CredentialTenantResolver,\n): void {\n credentialStoreProvider = provider;\n credentialTenantResolver = provider ? resolveTenant : undefined;\n trustedTenants = new WeakMap();\n}\n\n/** Refresh authority before a fresh model invocation; cloned contexts inherit only an opaque token. */\nexport async function prepareCredentialTenant(requestContext?: RequestContext): Promise<void> {\n if (!credentialTenantResolver) return;\n if (!requestContext) throw new Error('Tenant model resolution requires a request context.');\n const inheritedToken = requestContext.get(CREDENTIAL_POLICY_KEY);\n const inheritedPolicy =\n inheritedToken && typeof inheritedToken === 'object' ? trustedTenants.get(inheritedToken) : undefined;\n // Subagents and internal memory contexts can strip the controller's thread identity.\n // Keep their billing origin outside those mutable context fields.\n const sourceController = inheritedPolicy?.sourceContext.get('controller') as { resourceId?: string } | undefined;\n const sourceContext =\n inheritedPolicy && sourceController?.resourceId ? inheritedPolicy.sourceContext : requestContext;\n const token = {};\n requestContext.set(CREDENTIAL_POLICY_KEY, token);\n trustedTenants.set(token, { sourceContext });\n const tenant = await credentialTenantResolver(sourceContext);\n if (!tenant) throw new Error('Tenant model credential policy could not be resolved.');\n trustedTenants.set(token, { tenant, sourceContext });\n}\n\nexport function withCredentialTenantPreparation<T>(resolve: (ctx: { requestContext: RequestContext }) => T) {\n return async (ctx: { requestContext: RequestContext }): Promise<T> => {\n await prepareCredentialTenant(ctx.requestContext);\n return resolve(ctx);\n };\n}\n\n/**\n * Whether a tenant provider is registered. Used to disable the\n * `loadStoredApiKeysIntoEnv` side-channel in deployed mode — per-tenant\n * credentials must never leak into process-global env vars.\n */\nexport function hasCredentialStoreProvider(): boolean {\n return credentialStoreProvider !== undefined;\n}\n\nexport function hasCredentialTenantResolver(): boolean {\n return credentialTenantResolver !== undefined;\n}\n\n/** Shape the web auth gate stashes on the request context under `user`. */\ninterface RequestContextUser {\n workosId?: string;\n id?: string;\n organizationId?: string;\n}\n\n/**\n * Session-shaped `authenticateToken` results (better-auth) arrive as a wrapper\n * whose active org lives on the session half rather than on the user.\n */\ninterface RequestContextSession {\n user?: RequestContextUser;\n session?: { activeOrganizationId?: string };\n}\n\nexport function resolveCredentialScope(requestContext?: RequestContext): CredentialScope {\n return resolveTenantFromRequestContext(requestContext)?.credentialScope ?? 'user';\n}\n\n/**\n * Derive the calling tenant from a request context, if an authenticated web\n * user was stashed on it. Mirrors the web layer's stable-id resolution\n * (`workosId` falling back to the provider `id`).\n *\n * Session state and HTTP-supplied policy values never establish credential authority.\n */\nexport function resolveTenantFromRequestContext(requestContext?: RequestContext): CredentialTenant | undefined {\n if (!credentialTenantResolver) return resolveAuthenticatedCredentialTenant(requestContext);\n const token = requestContext?.get(CREDENTIAL_POLICY_KEY);\n return token && typeof token === 'object' ? trustedTenants.get(token)?.tenant : undefined;\n}\n\n/** Authenticated principal only, for hosts resolving durable session ownership. */\nexport function resolveAuthenticatedCredentialTenant(requestContext?: RequestContext): CredentialTenant | undefined {\n const raw = requestContext?.get('user') as (RequestContextUser & RequestContextSession) | undefined;\n if (!raw || typeof raw !== 'object') return undefined;\n\n // Precedence matches `toFactoryAuthUser` in `@mastra/factory`: a wrapper's org\n // comes from the session half only, never from the inner user.\n const wrapped = Boolean(raw.user && typeof raw.user === 'object' && raw.session && typeof raw.session === 'object');\n const user = wrapped ? (raw.user as RequestContextUser) : raw;\n const principalOrgId = wrapped ? raw.session?.activeOrganizationId : user.organizationId;\n const principalUserId = user.workosId ?? user.id;\n if (typeof principalUserId !== 'string' || !principalUserId) return undefined;\n if (principalOrgId !== undefined && typeof principalOrgId !== 'string') return undefined;\n\n return { orgId: principalOrgId, userId: principalUserId, credentialScope: 'user' };\n}\n\n/**\n * Resolve the credential store for a request. Local mode returns `undefined`\n * and keeps the global `AuthStorage` behavior. Once deployed web registers a\n * provider, missing tenant identity or unavailable tenant storage fails closed\n * through an empty store that also disables process-environment fallback.\n */\nexport function resolveCredentialStore(requestContext?: RequestContext): CredentialStore | undefined {\n if (!credentialStoreProvider) return undefined;\n const tenant = resolveTenantFromRequestContext(requestContext);\n if (!tenant) {\n const rawUser = requestContext?.get('user');\n console.warn('[MastraCode] Tenant credential resolution failed closed', {\n reason: rawUser === undefined ? 'missing-user-context' : 'credential-policy-unavailable',\n hasRequestContext: requestContext !== undefined,\n });\n return unavailableTenantCredentialStore;\n }\n const store = credentialStoreProvider(tenant);\n if (!store) {\n console.warn('[MastraCode] Tenant credential resolution failed closed', {\n reason: 'credential-store-unavailable',\n hasOrganization: tenant.orgId !== undefined,\n credentialScope: tenant.credentialScope,\n ownerResolved: tenant.credentialScope === 'factory' || tenant.userId !== undefined,\n });\n return unavailableTenantCredentialStore;\n }\n return store;\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mastracode-gateway.d.ts","sourceRoot":"","sources":["../../src/agents/mastracode-gateway.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAwB,0BAA0B,EAAE,MAAM,+BAA+B,CAAC;AACtG,OAAO,EAGL,kBAAkB,EAGnB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EACV,kBAAkB,EAClB,iBAAiB,EACjB,oBAAoB,EACpB,2BAA2B,EAC3B,cAAc,EACf,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAExD,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,wCAAwC,CAAC;
|
|
1
|
+
{"version":3,"file":"mastracode-gateway.d.ts","sourceRoot":"","sources":["../../src/agents/mastracode-gateway.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
import { getAppDataDir } from "../utils/project.js";
|
|
2
2
|
import { AuthStorage } from "../auth/storage.js";
|
|
3
3
|
import { createGoogleThinkingMiddleware } from "../providers/google-thinking.js";
|
|
4
|
-
import { MASTRA_GATEWAY_PREFIX, OPENAI_PREFIX, normalizeAnthropicModelId, remapOpenAIModelForCodexOAuth, stripMastraGatewayPrefix } from "../providers/model-ids.js";
|
|
4
|
+
import { MASTRA_GATEWAY_PREFIX, OPENAI_PREFIX, getCredentialProviderId, normalizeAnthropicModelId, remapOpenAIModelForCodexOAuth, stripMastraGatewayPrefix } from "../providers/model-ids.js";
|
|
5
5
|
import { THINKING_LEVEL_TO_REASONING_EFFORT, buildOpenAICodexOAuthFetch, createCodexMiddleware, createReasoningEffortMiddleware, getEffectiveThinkingLevel, openaiCodexProvider } from "../providers/openai-codex.js";
|
|
6
6
|
import { getCustomProviderId, loadSettings } from "../onboarding/settings.js";
|
|
7
7
|
import { resolveCustomProviders } from "./custom-provider-source.js";
|
|
8
8
|
import { buildAnthropicOAuthFetch, claudeCodeMiddleware, createAnthropicThinkingMiddleware, createPromptCacheMiddleware, opencodeClaudeMaxProvider } from "../providers/claude-max.js";
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import { ModelRouterLanguageModelWithThinking } from "../providers/provider-thinking.js";
|
|
9
|
+
import { githubCopilotProvider } from "../providers/github-copilot.js";
|
|
10
|
+
import { kimiCodingProvider } from "../providers/kimi-coding.js";
|
|
11
|
+
import { ModelRouterLanguageModelWithThinking, providerThinkingOptions, withThinkingOptionsModel } from "../providers/provider-thinking.js";
|
|
13
12
|
import { xaiProvider } from "../providers/xai.js";
|
|
14
13
|
import { GATEWAY_AUTH_HEADER, MastraGateway, MastraModelGateway, ModelRouterLanguageModel, PROVIDER_REGISTRY } from "@mastra/core/llm";
|
|
15
14
|
import { createOpenAI } from "@ai-sdk/openai";
|
|
@@ -85,15 +84,14 @@ function openaiApiKeyProvider(modelId, apiKey, headers, thinkingLevel) {
|
|
|
85
84
|
middleware: middleware ? [middleware] : []
|
|
86
85
|
});
|
|
87
86
|
}
|
|
88
|
-
function getAuthProviderId(providerId) {
|
|
89
|
-
return providerId === "openai" ? "openai-codex" : providerId;
|
|
90
|
-
}
|
|
91
87
|
function getProviderAuthKey(providerId, credentials = getGlobalAuthStorage()) {
|
|
92
|
-
const authProviderId =
|
|
88
|
+
const authProviderId = getCredentialProviderId(providerId);
|
|
93
89
|
const storedCred = credentials.get(authProviderId);
|
|
94
90
|
if (storedCred?.type === "api_key" && storedCred.key.trim().length > 0) return storedCred.key.trim();
|
|
95
91
|
const dedicatedKey = credentials.getStoredApiKey(authProviderId)?.trim();
|
|
96
92
|
if (dedicatedKey) return dedicatedKey;
|
|
93
|
+
const catalogKey = authProviderId !== providerId ? credentials.getStoredApiKey(providerId)?.trim() : void 0;
|
|
94
|
+
if (catalogKey) return catalogKey;
|
|
97
95
|
if (credentials.allowEnvironmentFallback === false) return void 0;
|
|
98
96
|
return authProviderId === "kimi-for-coding" ? process.env.KIMI_API_KEY?.trim() || void 0 : void 0;
|
|
99
97
|
}
|
|
@@ -209,7 +207,7 @@ var MastraCodeGateway = class MastraCodeGateway extends MastraModelGateway {
|
|
|
209
207
|
apiKey: mastraGatewayApiKey,
|
|
210
208
|
source: "gateway"
|
|
211
209
|
};
|
|
212
|
-
const authProviderId =
|
|
210
|
+
const authProviderId = getCredentialProviderId(request.providerId);
|
|
213
211
|
if (credentials.get(authProviderId)?.type === "oauth") return {
|
|
214
212
|
bearerToken: "oauth",
|
|
215
213
|
source: "gateway"
|
|
@@ -251,6 +249,7 @@ var MastraCodeGateway = class MastraCodeGateway extends MastraModelGateway {
|
|
|
251
249
|
return this.#customProviders ?? resolveCustomProviders() ?? loadSettings(this.#settingsPath).customProviders;
|
|
252
250
|
}
|
|
253
251
|
async fetchProviders() {
|
|
252
|
+
this.#credentials.reload();
|
|
254
253
|
const providers = {};
|
|
255
254
|
for (const provider of this.#getCustomProviders()) {
|
|
256
255
|
const models = provider.models ?? [];
|
|
@@ -264,25 +263,6 @@ var MastraCodeGateway = class MastraCodeGateway extends MastraModelGateway {
|
|
|
264
263
|
models
|
|
265
264
|
};
|
|
266
265
|
}
|
|
267
|
-
providers["kimi-for-coding"] = {
|
|
268
|
-
name: "Kimi For Coding",
|
|
269
|
-
apiKeyEnvVar: "KIMI_API_KEY",
|
|
270
|
-
apiKeyHeader: "Authorization",
|
|
271
|
-
gateway: this.id,
|
|
272
|
-
models: [...KIMI_CODING_MODELS]
|
|
273
|
-
};
|
|
274
|
-
try {
|
|
275
|
-
const copilotModels = await getCopilotModelCatalog({ authStorage: this.#credentials });
|
|
276
|
-
providers["github-copilot"] = {
|
|
277
|
-
name: "GitHub Copilot",
|
|
278
|
-
apiKeyEnvVar: "",
|
|
279
|
-
apiKeyHeader: "Authorization",
|
|
280
|
-
gateway: this.id,
|
|
281
|
-
models: copilotModels.map((model) => model.id)
|
|
282
|
-
};
|
|
283
|
-
} catch (error) {
|
|
284
|
-
console.warn("Failed to load GitHub Copilot model catalog:", error);
|
|
285
|
-
}
|
|
286
266
|
return providers;
|
|
287
267
|
}
|
|
288
268
|
buildUrl(modelId) {
|
|
@@ -341,24 +321,23 @@ var MastraCodeGateway = class MastraCodeGateway extends MastraModelGateway {
|
|
|
341
321
|
const openaiModel = this.#resolveOpenAIModel(args);
|
|
342
322
|
if (openaiModel) return openaiModel;
|
|
343
323
|
}
|
|
344
|
-
if (args.providerId === "xai" && this.#credentials.get("xai")?.type === "oauth") return xaiProvider(args.modelId, {
|
|
324
|
+
if (args.providerId === "xai" && this.#credentials.get("xai")?.type === "oauth") return withThinkingOptionsModel(xaiProvider(args.modelId, {
|
|
345
325
|
headers: args.headers,
|
|
346
326
|
authStorage: this.#credentials
|
|
347
|
-
});
|
|
348
|
-
if (args.providerId === "google") return this.#resolveGoogleModel(args);
|
|
327
|
+
}), providerThinkingOptions(`xai/${args.modelId}`, this.#thinkingLevel));
|
|
349
328
|
if (this.#routeThroughMastraGateway) return this.#mastraGateway.resolveLanguageModel(args);
|
|
350
|
-
if (args.providerId === "
|
|
329
|
+
if (args.providerId === "google") return this.#resolveGoogleModel(args);
|
|
330
|
+
if (args.providerId === "kimi-code-plan-cn" || args.providerId === "kimi-for-coding") return kimiCodingProvider(args.modelId, {
|
|
351
331
|
apiKey: args.apiKey,
|
|
352
332
|
headers: args.headers,
|
|
353
333
|
credentialStore: this.#credentials
|
|
354
334
|
});
|
|
355
335
|
const routedModelId = `${args.providerId}/${args.modelId}`;
|
|
356
|
-
const thinking = args.providerId === "deepseek" ? deepseekThinkingOptions(routedModelId, this.#thinkingLevel) : void 0;
|
|
357
336
|
return new ModelRouterLanguageModelWithThinking({
|
|
358
337
|
id: routedModelId,
|
|
359
338
|
apiKey: args.apiKey,
|
|
360
339
|
headers: args.headers
|
|
361
|
-
},
|
|
340
|
+
}, providerThinkingOptions(routedModelId, this.#thinkingLevel));
|
|
362
341
|
}
|
|
363
342
|
#resolveAnthropicModel(args) {
|
|
364
343
|
const bareModelId = normalizeAnthropicModelId(args.modelId);
|
|
@@ -381,15 +360,10 @@ var MastraCodeGateway = class MastraCodeGateway extends MastraModelGateway {
|
|
|
381
360
|
...thinkingMiddleware ? [thinkingMiddleware] : []
|
|
382
361
|
]
|
|
383
362
|
});
|
|
384
|
-
|
|
363
|
+
return this.#mastraGateway.resolveLanguageModel({
|
|
385
364
|
...args,
|
|
386
365
|
modelId: bareModelId
|
|
387
366
|
});
|
|
388
|
-
if (!thinkingMiddleware) return gatewayModel;
|
|
389
|
-
return wrapLanguageModel({
|
|
390
|
-
model: gatewayModel,
|
|
391
|
-
middleware: [thinkingMiddleware]
|
|
392
|
-
});
|
|
393
367
|
}
|
|
394
368
|
if (storedCred?.type === "oauth") return opencodeClaudeMaxProvider(bareModelId, {
|
|
395
369
|
headers: args.headers,
|
|
@@ -441,15 +415,15 @@ var MastraCodeGateway = class MastraCodeGateway extends MastraModelGateway {
|
|
|
441
415
|
if (apiKey) return openaiApiKeyProvider(args.modelId, apiKey, args.headers, this.#thinkingLevel);
|
|
442
416
|
}
|
|
443
417
|
#resolveGoogleModel(args) {
|
|
444
|
-
const
|
|
418
|
+
const routerModel = new ModelRouterLanguageModel({
|
|
445
419
|
id: `${args.providerId}/${args.modelId}`,
|
|
446
420
|
apiKey: args.apiKey,
|
|
447
421
|
headers: args.headers
|
|
448
422
|
});
|
|
449
423
|
const thinkingMiddleware = createGoogleThinkingMiddleware(args.modelId, this.#thinkingLevel);
|
|
450
|
-
if (!thinkingMiddleware) return
|
|
424
|
+
if (!thinkingMiddleware) return routerModel;
|
|
451
425
|
return wrapLanguageModel({
|
|
452
|
-
model:
|
|
426
|
+
model: routerModel,
|
|
453
427
|
middleware: [thinkingMiddleware]
|
|
454
428
|
});
|
|
455
429
|
}
|