@theokit/agents 4.7.0 → 4.9.0
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/auth.d.ts +10 -0
- package/dist/auth.js +48 -11
- package/dist/auth.js.map +1 -1
- package/dist/{bridge-entry-Ddu3Ug_3.d.ts → bridge-entry-BmPk3TPf.d.ts} +2 -8
- package/dist/bridge.d.ts +1 -1
- package/dist/bridge.js +1 -1
- package/dist/{chunk-LIRSFEEJ.js → chunk-ZQKR6XQS.js} +9 -3
- package/dist/chunk-ZQKR6XQS.js.map +1 -0
- package/dist/index.d.ts +18 -4
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-LIRSFEEJ.js.map +0 -1
package/dist/auth.d.ts
CHANGED
|
@@ -31,6 +31,16 @@ declare class AuthProvider {
|
|
|
31
31
|
* thread through. Returns the fresh `ResolvedCredential` — never logs the rotated token.
|
|
32
32
|
*/
|
|
33
33
|
ensureFresh(resolved: ResolvedCredential, deps: EnsureFreshHttpDeps, env?: Record<string, string | undefined>): Promise<ResolvedCredential>;
|
|
34
|
+
/** Refresh em voo por caminho de store — a chave é o arquivo, não a instância. */
|
|
35
|
+
private static readonly refreshEmVoo;
|
|
36
|
+
/**
|
|
37
|
+
* O refresh propriamente dito, serializado entre PROCESSOS e com re-leitura.
|
|
38
|
+
*
|
|
39
|
+
* A re-leitura não é detalhe: sem ela o lock apenas serializa, e o segundo processo decide com o
|
|
40
|
+
* estado que leu ANTES de esperar — refrescando de novo e invalidando o token que o primeiro acabou
|
|
41
|
+
* de gravar. É o double-checked locking clássico, e é o que o teste de dois processos pega.
|
|
42
|
+
*/
|
|
43
|
+
private refrescarSobLock;
|
|
34
44
|
/**
|
|
35
45
|
* Run the headless OpenAI device-login flow. Delegates to `openaiDeviceLogin` (which JWT-extracts the
|
|
36
46
|
* account id). `deviceConfig` is passed per-call because it is a distinct endpoint set from the
|
package/dist/auth.js
CHANGED
|
@@ -3,8 +3,9 @@ import {
|
|
|
3
3
|
} from "./chunk-7QVYU63E.js";
|
|
4
4
|
|
|
5
5
|
// src/auth/auth-provider.ts
|
|
6
|
-
import { ensureFreshCredential, openaiDeviceLogin, persistOAuthTokens } from "@theokit/sdk/auth";
|
|
7
|
-
|
|
6
|
+
import { authFilePath, ensureFreshCredential, openaiDeviceLogin, persistOAuthTokens, readStoredOAuth } from "@theokit/sdk/auth";
|
|
7
|
+
import { withFileLock } from "@theokit/sdk/persistence";
|
|
8
|
+
var AuthProvider = class _AuthProvider {
|
|
8
9
|
static {
|
|
9
10
|
__name(this, "AuthProvider");
|
|
10
11
|
}
|
|
@@ -19,12 +20,48 @@ var AuthProvider = class {
|
|
|
19
20
|
* `config` + `store`; `env` (for reading the store's env overrides) + the `{ fetch, now }` HTTP deps
|
|
20
21
|
* thread through. Returns the fresh `ResolvedCredential` — never logs the rotated token.
|
|
21
22
|
*/
|
|
22
|
-
ensureFresh(resolved, deps, env) {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
23
|
+
async ensureFresh(resolved, deps, env) {
|
|
24
|
+
if (resolved.kind !== "oauth") {
|
|
25
|
+
return ensureFreshCredential(resolved, {
|
|
26
|
+
config: this.config,
|
|
27
|
+
store: this.store,
|
|
28
|
+
env
|
|
29
|
+
}, deps);
|
|
30
|
+
}
|
|
31
|
+
const caminho = authFilePath(this.store, env);
|
|
32
|
+
const emVoo = _AuthProvider.refreshEmVoo.get(caminho);
|
|
33
|
+
if (emVoo !== void 0) return emVoo;
|
|
34
|
+
const promessa = this.refrescarSobLock(caminho, resolved, deps, env);
|
|
35
|
+
_AuthProvider.refreshEmVoo.set(caminho, promessa);
|
|
36
|
+
try {
|
|
37
|
+
return await promessa;
|
|
38
|
+
} finally {
|
|
39
|
+
_AuthProvider.refreshEmVoo.delete(caminho);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/** Refresh em voo por caminho de store — a chave é o arquivo, não a instância. */
|
|
43
|
+
static refreshEmVoo = /* @__PURE__ */ new Map();
|
|
44
|
+
/**
|
|
45
|
+
* O refresh propriamente dito, serializado entre PROCESSOS e com re-leitura.
|
|
46
|
+
*
|
|
47
|
+
* A re-leitura não é detalhe: sem ela o lock apenas serializa, e o segundo processo decide com o
|
|
48
|
+
* estado que leu ANTES de esperar — refrescando de novo e invalidando o token que o primeiro acabou
|
|
49
|
+
* de gravar. É o double-checked locking clássico, e é o que o teste de dois processos pega.
|
|
50
|
+
*/
|
|
51
|
+
refrescarSobLock(caminho, resolved, deps, env) {
|
|
52
|
+
return withFileLock(caminho, async () => {
|
|
53
|
+
const doDisco = readStoredOAuth(this.store, env);
|
|
54
|
+
const atual = doDisco !== void 0 ? {
|
|
55
|
+
...resolved,
|
|
56
|
+
apiKey: doDisco.access,
|
|
57
|
+
expiresAt: doDisco.expires
|
|
58
|
+
} : resolved;
|
|
59
|
+
return await ensureFreshCredential(atual, {
|
|
60
|
+
config: this.config,
|
|
61
|
+
store: this.store,
|
|
62
|
+
env
|
|
63
|
+
}, deps);
|
|
64
|
+
});
|
|
28
65
|
}
|
|
29
66
|
/**
|
|
30
67
|
* Run the headless OpenAI device-login flow. Delegates to `openaiDeviceLogin` (which JWT-extracts the
|
|
@@ -44,14 +81,14 @@ var AuthProvider = class {
|
|
|
44
81
|
};
|
|
45
82
|
|
|
46
83
|
// src/auth-entry.ts
|
|
47
|
-
import { authFilePath, CredentialError, credentialHome, readAuthFile, readStoredOAuth, writeCredential } from "@theokit/sdk/auth";
|
|
84
|
+
import { authFilePath as authFilePath2, CredentialError, credentialHome, readAuthFile, readStoredOAuth as readStoredOAuth2, writeCredential } from "@theokit/sdk/auth";
|
|
48
85
|
export {
|
|
49
86
|
AuthProvider,
|
|
50
87
|
CredentialError,
|
|
51
|
-
authFilePath,
|
|
88
|
+
authFilePath2 as authFilePath,
|
|
52
89
|
credentialHome,
|
|
53
90
|
readAuthFile,
|
|
54
|
-
readStoredOAuth,
|
|
91
|
+
readStoredOAuth2 as readStoredOAuth,
|
|
55
92
|
writeCredential
|
|
56
93
|
};
|
|
57
94
|
//# sourceMappingURL=auth.js.map
|
package/dist/auth.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/auth/auth-provider.ts","../src/auth-entry.ts"],"sourcesContent":["import { ensureFreshCredential, openaiDeviceLogin, persistOAuthTokens } from '@theokit/sdk/auth'\nimport type {\n CredentialStoreConfig,\n OAuthProviderConfig,\n OAuthTokens,\n OpenAIDeviceConfig,\n ResolvedCredential,\n} from '@theokit/sdk/auth'\n\n/**\n * M60 — `AuthProvider`, the OO contract that unifies the SDK's free OAuth-lifecycle functions\n * (`openaiDeviceLogin` → `persistOAuthTokens` → `ensureFreshCredential`). Those are stateful across a\n * SHARED `config` (`OAuthProviderConfig`) + `store` (`CredentialStoreConfig`); this class holds that\n * state so a consumer authors `new AuthProvider(config, store).persist(...)` / `.ensureFresh(...)`\n * instead of threading `config`/`store` through every call — the `SDK → Theokit → AgentBuilder`\n * boundary applied to the auth domain (ENRICH, per blueprint D2: auth carries orchestration + state).\n *\n * It DELEGATES, never reimplements (parsimony Rung 9): each method forwards verbatim to the SDK\n * function, so login → persist → refresh produces byte-identical state to calling the SDK directly.\n *\n * SECRET-SAFETY (hard rule): this class NEVER logs, stringifies, or otherwise surfaces token material.\n * Methods return exactly what the SDK returns and add no observability — a token is data that flows\n * through, never something this layer emits. The parity/secret tests pin both properties.\n */\n\n/** The HTTP deps of `ensureFreshCredential` (`{ fetch, now }`) — typed off the SDK to avoid drift. */\ntype EnsureFreshHttpDeps = Parameters<typeof ensureFreshCredential>[2]\n/** The device-flow deps + prompt hook of `openaiDeviceLogin` — typed off the SDK. */\ntype DeviceLoginDeps = Parameters<typeof openaiDeviceLogin>[1]\ntype DeviceLoginHooks = Parameters<typeof openaiDeviceLogin>[2]\n\nexport class AuthProvider {\n constructor(\n private readonly config: OAuthProviderConfig,\n private readonly store: CredentialStoreConfig,\n ) {}\n\n /**\n * Refresh a resolved credential if stale. Delegates to `ensureFreshCredential` with the held\n * `config` + `store`; `env` (for reading the store's env overrides) + the `{ fetch, now }` HTTP deps\n * thread through. Returns the fresh `ResolvedCredential` — never logs the rotated token.\n */\n ensureFresh(\n resolved: ResolvedCredential,\n deps: EnsureFreshHttpDeps,\n env?: Record<string, string | undefined>,\n ): Promise<ResolvedCredential> {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -- `CredentialStoreConfig` (SDK `/auth` subpath) resolves under tsc (root typecheck is clean) but eslint's type-aware project reads `this.store` as error-typed; the assignment is type-safe per tsc.\n return ensureFreshCredential(resolved, { config: this.config, store: this.store, env }, deps)\n }\n\n /**\n * Run the headless OpenAI device-login flow. Delegates to `openaiDeviceLogin` (which JWT-extracts the\n * account id). `deviceConfig` is passed per-call because it is a distinct endpoint set from the\n * refresh `config`. Returns `OAuthTokens` — the caller persists them via {@link AuthProvider.persist}.\n */\n deviceLogin(\n deviceConfig: OpenAIDeviceConfig,\n deps: DeviceLoginDeps,\n hooks: DeviceLoginHooks,\n ): Promise<OAuthTokens> {\n return openaiDeviceLogin(deviceConfig, deps, hooks)\n }\n\n /**\n * Persist freshly-obtained tokens through the held `store`. Delegates to `persistOAuthTokens` and\n * returns the credential-file path (never the token). `env` selects the store's home override.\n */\n persist(provider: string, tokens: OAuthTokens, env?: Record<string, string | undefined>): string {\n return persistOAuthTokens(provider, tokens, this.store, env)\n }\n}\n","// M60 — `@theokit/agents/auth`: the OO auth contract. `AuthProvider` (ENRICH — it holds the shared\n// `config`+`store` state and delegates to the SDK's free OAuth-lifecycle functions), plus the auth\n// domain's types re-exported so a consumer types the whole surface from the Theokit layer, never\n// reaching back to `@theokit/sdk/auth`.\nexport { AuthProvider } from './auth/auth-provider.js'\n\n// M73 — \"enriquecer nunca reduz\". A mecânica de store do SDK atravessa como PASS-THROUGH PURO.\n//\n// Antes disto, este subpath exportava 1 valor e 6 tipos enquanto `@theokit/sdk/auth` exportava 19\n// símbolos: nenhuma função atravessava. Como o consumidor tem regra INQUEBRÁVEL de nunca importar\n// `@theokit/sdk*` direto, **reimplementar era a única saída legal** — e o agent-builder reescreveu\n// seis destes nomes, ~120 linhas de mecânica duplicada. A lacuna era daqui, não indisciplina de lá.\n//\n// PURO, e não wrapper (parsimony Rung 9): estas são funções de I/O sem estado a segurar. A camada\n// enriquece onde há orquestração — é o que `AuthProvider` faz com o par `config`+`store`. Envolver\n// isto acrescentaria indireção sem nada dentro, e **quebraria `instanceof`**: o consumidor faz\n// `err instanceof CredentialError`, o que só vale enquanto a classe for a MESMA referência do SDK.\n// `tests/unit/auth-parity.test.ts` trava essa identidade com `toBe`.\n//\n// `resolveCredential` NÃO atravessa, de propósito: o SDK e o agent-builder têm funções DIFERENTES com\n// esse nome (sync vs async, lança vs `undefined`, lê env vs não lê, infere provider vs recusa), e o\n// próprio SDK declara que a precedência de env, a inferência por prefixo e o provider declarado são\n// app policy do consumidor (`internal/auth/credential-store.ts`). Expor os dois no mesmo escopo seria\n// convite a importar o errado, com falha silenciosa.\nexport {\n authFilePath,\n CredentialError,\n credentialHome,\n readAuthFile,\n readStoredOAuth,\n writeCredential,\n} from '@theokit/sdk/auth'\nexport type { ResolveCredentialOptions } from '@theokit/sdk/auth'\nexport type {\n CredentialStoreConfig,\n DeviceDeps,\n OAuthProviderConfig,\n OAuthTokens,\n OpenAIDeviceConfig,\n ResolvedCredential,\n} from '@theokit/sdk/auth'\n"],"mappings":";;;;;AAAA,SAASA,uBAAuBC,mBAAmBC,0BAA0B;AA+BtE,IAAMC,eAAN,MAAMA;EA/Bb,OA+BaA;;;;;EACX,YACmBC,QACAC,OACjB;SAFiBD,SAAAA;SACAC,QAAAA;EAChB;;;;;;EAOHC,YACEC,UACAC,MACAC,KAC6B;AAE7B,WAAOC,sBAAsBH,UAAU;MAAEH,QAAQ,KAAKA;MAAQC,OAAO,KAAKA;MAAOI;IAAI,GAAGD,IAAAA;EAC1F;;;;;;EAOAG,YACEC,cACAJ,MACAK,OACsB;AACtB,WAAOC,kBAAkBF,cAAcJ,MAAMK,KAAAA;EAC/C;;;;;EAMAE,QAAQC,UAAkBC,QAAqBR,KAAkD;AAC/F,WAAOS,mBAAmBF,UAAUC,QAAQ,KAAKZ,OAAOI,GAAAA;EAC1D;AACF;;;AC/CA,SACEU,cACAC,iBACAC,gBACAC,cACAC,iBACAC,uBACK;","names":["ensureFreshCredential","openaiDeviceLogin","persistOAuthTokens","AuthProvider","config","store","ensureFresh","resolved","deps","env","ensureFreshCredential","deviceLogin","deviceConfig","hooks","openaiDeviceLogin","persist","provider","tokens","persistOAuthTokens","authFilePath","CredentialError","credentialHome","readAuthFile","readStoredOAuth","writeCredential"]}
|
|
1
|
+
{"version":3,"sources":["../src/auth/auth-provider.ts","../src/auth-entry.ts"],"sourcesContent":["import {\n authFilePath,\n ensureFreshCredential,\n openaiDeviceLogin,\n persistOAuthTokens,\n readStoredOAuth,\n} from '@theokit/sdk/auth'\nimport type {\n CredentialStoreConfig,\n OAuthProviderConfig,\n OAuthTokens,\n OpenAIDeviceConfig,\n ResolvedCredential,\n} from '@theokit/sdk/auth'\nimport { withFileLock } from '@theokit/sdk/persistence'\n\n/**\n * M60 — `AuthProvider`, the OO contract that unifies the SDK's free OAuth-lifecycle functions\n * (`openaiDeviceLogin` → `persistOAuthTokens` → `ensureFreshCredential`). Those are stateful across a\n * SHARED `config` (`OAuthProviderConfig`) + `store` (`CredentialStoreConfig`); this class holds that\n * state so a consumer authors `new AuthProvider(config, store).persist(...)` / `.ensureFresh(...)`\n * instead of threading `config`/`store` through every call — the `SDK → Theokit → AgentBuilder`\n * boundary applied to the auth domain (ENRICH, per blueprint D2: auth carries orchestration + state).\n *\n * It DELEGATES, never reimplements (parsimony Rung 9): each method forwards verbatim to the SDK\n * function, so login → persist → refresh produces byte-identical state to calling the SDK directly.\n *\n * SECRET-SAFETY (hard rule): this class NEVER logs, stringifies, or otherwise surfaces token material.\n * Methods return exactly what the SDK returns and add no observability — a token is data that flows\n * through, never something this layer emits. The parity/secret tests pin both properties.\n */\n\n/** The HTTP deps of `ensureFreshCredential` (`{ fetch, now }`) — typed off the SDK to avoid drift. */\ntype EnsureFreshHttpDeps = Parameters<typeof ensureFreshCredential>[2]\n/** The device-flow deps + prompt hook of `openaiDeviceLogin` — typed off the SDK. */\ntype DeviceLoginDeps = Parameters<typeof openaiDeviceLogin>[1]\ntype DeviceLoginHooks = Parameters<typeof openaiDeviceLogin>[2]\n\n/**\n * Falha de refresh, classificada — porque a decisão de tentar de novo depende da classe, não do texto.\n *\n * M74: repetir um `invalid_grant` não é resiliência, é ruído. O refresh token foi revogado e nenhuma\n * tentativa muda isso; o usuário que revogou o login espera três backoffs para ler uma mensagem que já\n * era conhecida na primeira resposta. Rede e 5xx são o oposto: quase sempre passam na segunda.\n *\n * SECRET-SAFETY: a mensagem nunca carrega material de token — só a classe e o motivo.\n */\nexport class RefreshFailure extends Error {\n constructor(\n message: string,\n /** `true` ⇒ vale tentar de novo com backoff. `false` ⇒ terminal, falha na primeira. */\n readonly transitorio: boolean,\n ) {\n super(message)\n this.name = 'RefreshFailure'\n }\n}\n\n/**\n * O que conta como transitório. Lista NOMEADA de propósito: é decisão de produto que envelhece, e\n * espalhá-la em `if` faz cada sítio envelhecer sozinho.\n */\nconst MOTIVOS_TRANSITORIOS = [\n 'ETIMEDOUT',\n 'ECONNRESET',\n 'ECONNREFUSED',\n 'EAI_AGAIN',\n 'ENOTFOUND',\n 'AbortError',\n]\n\n/** Classifica uma falha de refresh. `invalid_grant` é terminal; rede e 5xx são transitórios. */\nexport function classificarFalhaDeRefresh(err: unknown): RefreshFailure {\n const texto = err instanceof Error ? `${err.name}: ${err.message}` : String(err)\n if (/invalid_grant|invalid_request|unauthorized_client/i.test(texto)) {\n return new RefreshFailure(\n 'o refresh token não é mais válido — refaça o login. Tentar de novo não muda o resultado.',\n false,\n )\n }\n const transitorio =\n MOTIVOS_TRANSITORIOS.some((m) => texto.includes(m)) ||\n /\\b(5\\d{2})\\b|timeout|network/i.test(texto)\n return new RefreshFailure(\n transitorio ? 'falha transitória ao refrescar a credencial' : 'falha ao refrescar a credencial',\n transitorio,\n )\n}\n\n/** Espera com jitter: backoff exponencial ±25%, para dois processos não retentarem em uníssono. */\nexport function esperaComJitter(tentativa: number, baseMs = 200, aleatorio = Math.random): number {\n const base = baseMs * 2 ** tentativa\n return Math.round(base * (0.75 + aleatorio() * 0.5))\n}\n\nexport class AuthProvider {\n constructor(\n private readonly config: OAuthProviderConfig,\n private readonly store: CredentialStoreConfig,\n ) {}\n\n /**\n * Refresh a resolved credential if stale. Delegates to `ensureFreshCredential` with the held\n * `config` + `store`; `env` (for reading the store's env overrides) + the `{ fetch, now }` HTTP deps\n * thread through. Returns the fresh `ResolvedCredential` — never logs the rotated token.\n */\n async ensureFresh(\n resolved: ResolvedCredential,\n deps: EnsureFreshHttpDeps,\n env?: Record<string, string | undefined>,\n ): Promise<ResolvedCredential> {\n if (resolved.kind !== 'oauth') {\n // Chave de API não expira: nenhum lock, nenhuma releitura, nenhum I/O. Manter o caminho quente\n // livre é o que torna o resolvedor por-run barato (M74, Risco 1).\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -- `CredentialStoreConfig` do subpath /auth resolve sob tsc; o projeto type-aware do eslint o lê como error-typed.\n return ensureFreshCredential(resolved, { config: this.config, store: this.store, env }, deps)\n }\n\n const caminho: string = authFilePath(this.store, env)\n\n // SINGLE-FLIGHT in-process, ANTES do lock (M74, EC-2 do edge-case review).\n //\n // `withFileLock` (proper-lockfile) NÃO é reentrante: se uma run começar de dentro de um contexto\n // que já segura o lock — uma run aninhada, ou um time disparando membros enquanto o pai refresca —\n // a segunda aquisição espera até o timeout e o sintoma é \"a run travou\", sem erro nenhum. Com o\n // resolvedor por-run do M74 isso deixa de ser hipotético: `ensureFresh` passa a ser chamado de\n // dentro do stream. A promise em voo faz a reentrância resolver por composição, não por lock.\n const emVoo = AuthProvider.refreshEmVoo.get(caminho)\n if (emVoo !== undefined) return emVoo\n\n const promessa = this.refrescarSobLock(caminho, resolved, deps, env)\n AuthProvider.refreshEmVoo.set(caminho, promessa)\n try {\n return await promessa\n } finally {\n AuthProvider.refreshEmVoo.delete(caminho)\n }\n }\n\n /** Refresh em voo por caminho de store — a chave é o arquivo, não a instância. */\n private static readonly refreshEmVoo = new Map<string, Promise<ResolvedCredential>>()\n\n /**\n * O refresh propriamente dito, serializado entre PROCESSOS e com re-leitura.\n *\n * A re-leitura não é detalhe: sem ela o lock apenas serializa, e o segundo processo decide com o\n * estado que leu ANTES de esperar — refrescando de novo e invalidando o token que o primeiro acabou\n * de gravar. É o double-checked locking clássico, e é o que o teste de dois processos pega.\n */\n private refrescarSobLock(\n caminho: string,\n resolved: ResolvedCredential,\n deps: EnsureFreshHttpDeps,\n env?: Record<string, string | undefined>,\n ): Promise<ResolvedCredential> {\n /* eslint-disable @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access -- os subpaths `/auth` e `/persistence` do SDK resolvem sob tsc (typecheck da raiz limpo); o projeto type-aware do eslint os lê como error-typed. Mesma nota que este arquivo já carregava para `CredentialStoreConfig`. */\n return withFileLock(caminho, async () => {\n // RE-LEITURA depois de adquirir o lock: outro processo pode ter refrescado enquanto esperávamos.\n const doDisco = readStoredOAuth(this.store, env)\n const atual =\n doDisco !== undefined\n ? { ...resolved, apiKey: doDisco.access, expiresAt: doDisco.expires }\n : resolved\n return await ensureFreshCredential(\n atual,\n { config: this.config, store: this.store, env },\n deps,\n )\n }) as Promise<ResolvedCredential>\n /* eslint-enable @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access */\n }\n\n /**\n * Run the headless OpenAI device-login flow. Delegates to `openaiDeviceLogin` (which JWT-extracts the\n * account id). `deviceConfig` is passed per-call because it is a distinct endpoint set from the\n * refresh `config`. Returns `OAuthTokens` — the caller persists them via {@link AuthProvider.persist}.\n */\n deviceLogin(\n deviceConfig: OpenAIDeviceConfig,\n deps: DeviceLoginDeps,\n hooks: DeviceLoginHooks,\n ): Promise<OAuthTokens> {\n return openaiDeviceLogin(deviceConfig, deps, hooks)\n }\n\n /**\n * Persist freshly-obtained tokens through the held `store`. Delegates to `persistOAuthTokens` and\n * returns the credential-file path (never the token). `env` selects the store's home override.\n */\n persist(provider: string, tokens: OAuthTokens, env?: Record<string, string | undefined>): string {\n return persistOAuthTokens(provider, tokens, this.store, env)\n }\n}\n","// M60 — `@theokit/agents/auth`: the OO auth contract. `AuthProvider` (ENRICH — it holds the shared\n// `config`+`store` state and delegates to the SDK's free OAuth-lifecycle functions), plus the auth\n// domain's types re-exported so a consumer types the whole surface from the Theokit layer, never\n// reaching back to `@theokit/sdk/auth`.\nexport { AuthProvider } from './auth/auth-provider.js'\n\n// M73 — \"enriquecer nunca reduz\". A mecânica de store do SDK atravessa como PASS-THROUGH PURO.\n//\n// Antes disto, este subpath exportava 1 valor e 6 tipos enquanto `@theokit/sdk/auth` exportava 19\n// símbolos: nenhuma função atravessava. Como o consumidor tem regra INQUEBRÁVEL de nunca importar\n// `@theokit/sdk*` direto, **reimplementar era a única saída legal** — e o agent-builder reescreveu\n// seis destes nomes, ~120 linhas de mecânica duplicada. A lacuna era daqui, não indisciplina de lá.\n//\n// PURO, e não wrapper (parsimony Rung 9): estas são funções de I/O sem estado a segurar. A camada\n// enriquece onde há orquestração — é o que `AuthProvider` faz com o par `config`+`store`. Envolver\n// isto acrescentaria indireção sem nada dentro, e **quebraria `instanceof`**: o consumidor faz\n// `err instanceof CredentialError`, o que só vale enquanto a classe for a MESMA referência do SDK.\n// `tests/unit/auth-parity.test.ts` trava essa identidade com `toBe`.\n//\n// `resolveCredential` NÃO atravessa, de propósito: o SDK e o agent-builder têm funções DIFERENTES com\n// esse nome (sync vs async, lança vs `undefined`, lê env vs não lê, infere provider vs recusa), e o\n// próprio SDK declara que a precedência de env, a inferência por prefixo e o provider declarado são\n// app policy do consumidor (`internal/auth/credential-store.ts`). Expor os dois no mesmo escopo seria\n// convite a importar o errado, com falha silenciosa.\nexport {\n authFilePath,\n CredentialError,\n credentialHome,\n readAuthFile,\n readStoredOAuth,\n writeCredential,\n} from '@theokit/sdk/auth'\nexport type { ResolveCredentialOptions } from '@theokit/sdk/auth'\nexport type {\n CredentialStoreConfig,\n DeviceDeps,\n OAuthProviderConfig,\n OAuthTokens,\n OpenAIDeviceConfig,\n ResolvedCredential,\n} from '@theokit/sdk/auth'\n"],"mappings":";;;;;AAAA,SACEA,cACAC,uBACAC,mBACAC,oBACAC,uBACK;AAQP,SAASC,oBAAoB;AAiFtB,IAAMC,eAAN,MAAMA,cAAAA;EA/Fb,OA+FaA;;;;;EACX,YACmBC,QACAC,OACjB;SAFiBD,SAAAA;SACAC,QAAAA;EAChB;;;;;;EAOH,MAAMC,YACJC,UACAC,MACAC,KAC6B;AAC7B,QAAIF,SAASG,SAAS,SAAS;AAI7B,aAAOC,sBAAsBJ,UAAU;QAAEH,QAAQ,KAAKA;QAAQC,OAAO,KAAKA;QAAOI;MAAI,GAAGD,IAAAA;IAC1F;AAEA,UAAMI,UAAkBC,aAAa,KAAKR,OAAOI,GAAAA;AASjD,UAAMK,QAAQX,cAAaY,aAAaC,IAAIJ,OAAAA;AAC5C,QAAIE,UAAUG,OAAW,QAAOH;AAEhC,UAAMI,WAAW,KAAKC,iBAAiBP,SAASL,UAAUC,MAAMC,GAAAA;AAChEN,kBAAaY,aAAaK,IAAIR,SAASM,QAAAA;AACvC,QAAI;AACF,aAAO,MAAMA;IACf,UAAA;AACEf,oBAAaY,aAAaM,OAAOT,OAAAA;IACnC;EACF;;EAGA,OAAwBG,eAAe,oBAAIO,IAAAA;;;;;;;;EASnCH,iBACNP,SACAL,UACAC,MACAC,KAC6B;AAE7B,WAAOc,aAAaX,SAAS,YAAA;AAE3B,YAAMY,UAAUC,gBAAgB,KAAKpB,OAAOI,GAAAA;AAC5C,YAAMiB,QACJF,YAAYP,SACR;QAAE,GAAGV;QAAUoB,QAAQH,QAAQI;QAAQC,WAAWL,QAAQM;MAAQ,IAClEvB;AACN,aAAO,MAAMI,sBACXe,OACA;QAAEtB,QAAQ,KAAKA;QAAQC,OAAO,KAAKA;QAAOI;MAAI,GAC9CD,IAAAA;IAEJ,CAAA;EAEF;;;;;;EAOAuB,YACEC,cACAxB,MACAyB,OACsB;AACtB,WAAOC,kBAAkBF,cAAcxB,MAAMyB,KAAAA;EAC/C;;;;;EAMAE,QAAQC,UAAkBC,QAAqB5B,KAAkD;AAC/F,WAAO6B,mBAAmBF,UAAUC,QAAQ,KAAKhC,OAAOI,GAAAA;EAC1D;AACF;;;ACxKA,SACE8B,gBAAAA,eACAC,iBACAC,gBACAC,cACAC,mBAAAA,kBACAC,uBACK;","names":["authFilePath","ensureFreshCredential","openaiDeviceLogin","persistOAuthTokens","readStoredOAuth","withFileLock","AuthProvider","config","store","ensureFresh","resolved","deps","env","kind","ensureFreshCredential","caminho","authFilePath","emVoo","refreshEmVoo","get","undefined","promessa","refrescarSobLock","set","delete","Map","withFileLock","doDisco","readStoredOAuth","atual","apiKey","access","expiresAt","expires","deviceLogin","deviceConfig","hooks","openaiDeviceLogin","persist","provider","tokens","persistOAuthTokens","authFilePath","CredentialError","credentialHome","readAuthFile","readStoredOAuth","writeCredential"]}
|
|
@@ -938,13 +938,7 @@ interface RuntimeOverrides {
|
|
|
938
938
|
*/
|
|
939
939
|
sdkTools?: readonly CustomTool[];
|
|
940
940
|
}
|
|
941
|
-
|
|
942
|
-
* Creates an agent stream factory using @theokit/sdk as the runtime.
|
|
943
|
-
*
|
|
944
|
-
* Returns a function that, given a message + sessionId, yields TheoKit
|
|
945
|
-
* AgentStreamEvent via the SDK's Agent.create() + Run.stream() pipeline.
|
|
946
|
-
*/
|
|
947
|
-
declare function createSdkAgentStream(compiled: CompiledAgentOptions, compiledTools: CompiledTool[], apiKey: string, overrides?: RuntimeOverrides): ((message: string, sessionId: string, factoryOpts?: {
|
|
941
|
+
declare function createSdkAgentStream(compiled: CompiledAgentOptions, compiledTools: CompiledTool[], apiKey: string | (() => string | Promise<string>), overrides?: RuntimeOverrides): ((message: string, sessionId: string, factoryOpts?: {
|
|
948
942
|
disableTools?: boolean;
|
|
949
943
|
}) => AsyncIterable<StreamEvent>) & {
|
|
950
944
|
resolvedModel: string;
|
|
@@ -973,7 +967,7 @@ interface SdkAgentHandle {
|
|
|
973
967
|
* surface (e.g. the ACP client) owns approval. Tools still execute; they are simply not HITL-gated here.
|
|
974
968
|
*/
|
|
975
969
|
declare function toAgentFactory(def: AgentDefinition, opts: {
|
|
976
|
-
apiKey: string;
|
|
970
|
+
apiKey: string | (() => string | Promise<string>);
|
|
977
971
|
overrides?: RuntimeOverrides;
|
|
978
972
|
}): (sessionId: string) => Promise<SdkAgentHandle>;
|
|
979
973
|
|
package/dist/bridge.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { g as AGENT_BRAND, h as AfterToolCallContext, i as AgentBuilder, j as AgentDefinition, k as AgentDefinitionError, l as AgentExecutionContext, m as AgentManifest, f as AgentManifestEntry, n as AgentManifestSource, o as AgentManifestTool, q as AgentRoute, r as AgentRouteContext, s as AgentRunInfo, t as AgentStreamEvent, u as AgentTurnMetadata, v as AgentsPluginOptions, w as ApiErrorContext, x as ApiErrorDecision, y as ApiErrorPolicy, z as ApprovalRequiredEvent, B as ArtifactChunkEvent, E as ArtifactStartEvent, F as BackgroundDelegation, I as BeforeToolCallContext, J as BudgetExceededError, N as CheckpointSavedEvent, C as CompiledAgentOptions, O as CompiledContextWindow, a as CompiledTool, P as ContextualTool, V as DefineAgentConfig, W as DelegateFn, X as DelegateOptions, Y as DelegationError, D as DelegationResult, Z as DoneEvent, _ as ErrorEvent, $ as FileEditEvent, a5 as InferAgentInput, a6 as InferAgentToolNames, a7 as IterationEvent, a8 as LLMCallContext, ad as McpApprovalSpec, ae as McpRegistryConfig, af as McpRequestContext, ag as McpSelection, ah as PartialToolCallEvent, aj as ProcessInputContext, an as RunStartedEvent, ao as ScoreVerdict, ap as ScoredDelegation, aq as Scorer, ar as SdkAgentHandle, as as SdkMessage, at as Segment, aw as StateUpdateEvent, S as StreamEvent, ax as TextDeltaEvent, ay as ThinkingEvent, aA as ToolCallEvent, aB as ToolCallVeto, aC as ToolHooks, aD as ToolHooksPlugin, aE as ToolResultEvent, aF as ToolWalkResult, aH as ToolboxWalkResult, aI as agentsPlugin, aJ as buildModelSelection, aK as compileAgentDefinition, aL as compileAgentModule, aM as compileContextWindow, aN as compileProjectContext, aO as compileSkills, aP as compileTools, aQ as createAgentExecutionContext, aR as createApiErrorHandler, aS as createSdkAgentStream, aT as createThinkTagExtractor, aU as createToolHooksPlugin, aV as delegate, aW as delegateBackground, aX as delegateWithScoring, aY as extractThinkTagStream, aZ as generateAgentManifest, a_ as generateAgentRoutes, a$ as isAgentContext, b0 as isAgentDefinition, b1 as isApprovalRequired, b2 as isDone, b3 as isError, b4 as isPartialToolCall, b5 as isTextDelta, b6 as isToolCall, b7 as isToolResult, ba as mcpRegistry, bb as mcpToolApprovals, bd as presentUIMessageStream, be as projectContextMetadataOnlyKnobs, bi as resolveMcpServers, bj as runWithApiErrorHandling, bk as streamAgentResponse, bl as streamAgentUIMessages, bm as toAgentFactory, bn as translateSdkEvent } from './bridge-entry-
|
|
1
|
+
export { g as AGENT_BRAND, h as AfterToolCallContext, i as AgentBuilder, j as AgentDefinition, k as AgentDefinitionError, l as AgentExecutionContext, m as AgentManifest, f as AgentManifestEntry, n as AgentManifestSource, o as AgentManifestTool, q as AgentRoute, r as AgentRouteContext, s as AgentRunInfo, t as AgentStreamEvent, u as AgentTurnMetadata, v as AgentsPluginOptions, w as ApiErrorContext, x as ApiErrorDecision, y as ApiErrorPolicy, z as ApprovalRequiredEvent, B as ArtifactChunkEvent, E as ArtifactStartEvent, F as BackgroundDelegation, I as BeforeToolCallContext, J as BudgetExceededError, N as CheckpointSavedEvent, C as CompiledAgentOptions, O as CompiledContextWindow, a as CompiledTool, P as ContextualTool, V as DefineAgentConfig, W as DelegateFn, X as DelegateOptions, Y as DelegationError, D as DelegationResult, Z as DoneEvent, _ as ErrorEvent, $ as FileEditEvent, a5 as InferAgentInput, a6 as InferAgentToolNames, a7 as IterationEvent, a8 as LLMCallContext, ad as McpApprovalSpec, ae as McpRegistryConfig, af as McpRequestContext, ag as McpSelection, ah as PartialToolCallEvent, aj as ProcessInputContext, an as RunStartedEvent, ao as ScoreVerdict, ap as ScoredDelegation, aq as Scorer, ar as SdkAgentHandle, as as SdkMessage, at as Segment, aw as StateUpdateEvent, S as StreamEvent, ax as TextDeltaEvent, ay as ThinkingEvent, aA as ToolCallEvent, aB as ToolCallVeto, aC as ToolHooks, aD as ToolHooksPlugin, aE as ToolResultEvent, aF as ToolWalkResult, aH as ToolboxWalkResult, aI as agentsPlugin, aJ as buildModelSelection, aK as compileAgentDefinition, aL as compileAgentModule, aM as compileContextWindow, aN as compileProjectContext, aO as compileSkills, aP as compileTools, aQ as createAgentExecutionContext, aR as createApiErrorHandler, aS as createSdkAgentStream, aT as createThinkTagExtractor, aU as createToolHooksPlugin, aV as delegate, aW as delegateBackground, aX as delegateWithScoring, aY as extractThinkTagStream, aZ as generateAgentManifest, a_ as generateAgentRoutes, a$ as isAgentContext, b0 as isAgentDefinition, b1 as isApprovalRequired, b2 as isDone, b3 as isError, b4 as isPartialToolCall, b5 as isTextDelta, b6 as isToolCall, b7 as isToolResult, ba as mcpRegistry, bb as mcpToolApprovals, bd as presentUIMessageStream, be as projectContextMetadataOnlyKnobs, bi as resolveMcpServers, bj as runWithApiErrorHandling, bk as streamAgentResponse, bl as streamAgentUIMessages, bm as toAgentFactory, bn as translateSdkEvent } from './bridge-entry-BmPk3TPf.js';
|
|
2
2
|
import '@theokit/http';
|
|
3
3
|
import '@theokit/sdk';
|
|
4
4
|
import 'zod';
|
package/dist/bridge.js
CHANGED
|
@@ -1164,6 +1164,10 @@ function buildSdkTools(compiledTools, defineTool, extraSdkTools = [], runContext
|
|
|
1164
1164
|
];
|
|
1165
1165
|
}
|
|
1166
1166
|
__name(buildSdkTools, "buildSdkTools");
|
|
1167
|
+
async function resolverApiKey(k) {
|
|
1168
|
+
return typeof k === "function" ? await k() : k;
|
|
1169
|
+
}
|
|
1170
|
+
__name(resolverApiKey, "resolverApiKey");
|
|
1167
1171
|
function createSdkAgentStream(compiled, compiledTools, apiKey, overrides = {}) {
|
|
1168
1172
|
const model = overrides.model ?? compiled.model ?? "openai/gpt-4o-mini";
|
|
1169
1173
|
const reasoningEffort = overrides.reasoningEffort ?? compiled.reasoningEffort;
|
|
@@ -1201,8 +1205,9 @@ function createSdkAgentStream(compiled, compiledTools, apiKey, overrides = {}) {
|
|
|
1201
1205
|
keys: runContext !== void 0 ? Object.keys(runContext) : []
|
|
1202
1206
|
});
|
|
1203
1207
|
try {
|
|
1208
|
+
const apiKeyResolvida = await resolverApiKey(apiKey);
|
|
1204
1209
|
yield* streamSdkAgent(rt, compiled, sdkTools, {
|
|
1205
|
-
apiKey,
|
|
1210
|
+
apiKey: apiKeyResolvida,
|
|
1206
1211
|
model,
|
|
1207
1212
|
reasoningEffort,
|
|
1208
1213
|
overrides,
|
|
@@ -1310,8 +1315,9 @@ function toAgentFactory(def, opts) {
|
|
|
1310
1315
|
baseDir: overrides.baseDir
|
|
1311
1316
|
};
|
|
1312
1317
|
const extra = buildExtraCreateOptions(overrides, compiled);
|
|
1318
|
+
const apiKeyResolvida = await resolverApiKey(opts.apiKey);
|
|
1313
1319
|
const agent = await rt.Agent.getOrCreate(sessionId, {
|
|
1314
|
-
apiKey:
|
|
1320
|
+
apiKey: apiKeyResolvida,
|
|
1315
1321
|
model: buildModelSelection(model, reasoningEffort),
|
|
1316
1322
|
tools: sdkTools,
|
|
1317
1323
|
...m8,
|
|
@@ -3505,4 +3511,4 @@ export {
|
|
|
3505
3511
|
generateAgentManifest,
|
|
3506
3512
|
agentsPlugin
|
|
3507
3513
|
};
|
|
3508
|
-
//# sourceMappingURL=chunk-
|
|
3514
|
+
//# sourceMappingURL=chunk-ZQKR6XQS.js.map
|