@pellux/goodvibes-sdk 0.18.49 → 0.18.51
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/_internal/errors/index.d.ts +27 -2
- package/dist/_internal/errors/index.d.ts.map +1 -1
- package/dist/_internal/errors/index.js +44 -2
- package/dist/_internal/platform/auth/index.d.ts +4 -0
- package/dist/_internal/platform/auth/index.d.ts.map +1 -0
- package/dist/_internal/platform/auth/index.js +7 -0
- package/dist/_internal/platform/auth/oauth-client.d.ts +45 -0
- package/dist/_internal/platform/auth/oauth-client.d.ts.map +1 -0
- package/dist/_internal/platform/auth/oauth-client.js +45 -0
- package/dist/_internal/platform/auth/oauth-types.d.ts +21 -0
- package/dist/_internal/platform/auth/oauth-types.d.ts.map +1 -0
- package/dist/_internal/platform/auth/oauth-types.js +8 -0
- package/dist/_internal/platform/auth/permission-resolver.d.ts +35 -0
- package/dist/_internal/platform/auth/permission-resolver.d.ts.map +1 -0
- package/dist/_internal/platform/auth/permission-resolver.js +57 -0
- package/dist/_internal/platform/auth/session-manager.d.ts +31 -0
- package/dist/_internal/platform/auth/session-manager.d.ts.map +1 -0
- package/dist/_internal/platform/auth/session-manager.js +44 -0
- package/dist/_internal/platform/auth/token-store.d.ts +23 -0
- package/dist/_internal/platform/auth/token-store.d.ts.map +1 -0
- package/dist/_internal/platform/auth/token-store.js +34 -0
- package/dist/_internal/platform/config/openai-codex-auth.d.ts +1 -1
- package/dist/_internal/platform/config/openai-codex-auth.d.ts.map +1 -1
- package/dist/_internal/platform/config/openai-codex-auth.js +2 -2
- package/dist/_internal/platform/config/subscriptions.d.ts +2 -2
- package/dist/_internal/platform/config/subscriptions.d.ts.map +1 -1
- package/dist/_internal/platform/config/subscriptions.js +2 -2
- package/dist/_internal/platform/core/orchestrator.d.ts +75 -11
- package/dist/_internal/platform/core/orchestrator.d.ts.map +1 -1
- package/dist/_internal/platform/core/orchestrator.js +29 -8
- package/dist/_internal/platform/runtime/auth/crypto-adapter.d.ts +22 -0
- package/dist/_internal/platform/runtime/auth/crypto-adapter.d.ts.map +1 -0
- package/dist/_internal/platform/runtime/auth/crypto-adapter.js +40 -0
- package/dist/_internal/platform/runtime/auth/oauth-core.d.ts +4 -15
- package/dist/_internal/platform/runtime/auth/oauth-core.d.ts.map +1 -1
- package/dist/_internal/platform/runtime/auth/oauth-core.js +13 -8
- package/dist/_internal/platform/version.js +1 -1
- package/dist/_internal/transport-realtime/domain-events.d.ts +26 -0
- package/dist/_internal/transport-realtime/domain-events.d.ts.map +1 -1
- package/dist/_internal/transport-realtime/domain-events.js +63 -0
- package/dist/_internal/transport-realtime/index.d.ts +2 -2
- package/dist/_internal/transport-realtime/index.d.ts.map +1 -1
- package/dist/_internal/transport-realtime/index.js +2 -2
- package/dist/_internal/transport-realtime/runtime-events.d.ts +27 -1
- package/dist/_internal/transport-realtime/runtime-events.d.ts.map +1 -1
- package/dist/_internal/transport-realtime/runtime-events.js +27 -0
- package/dist/auth.d.ts +28 -0
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +6 -0
- package/dist/browser.d.ts +1 -0
- package/dist/browser.d.ts.map +1 -1
- package/dist/browser.js +1 -0
- package/dist/client.d.ts +50 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +2 -0
- package/dist/expo.d.ts +1 -0
- package/dist/expo.d.ts.map +1 -1
- package/dist/expo.js +1 -0
- package/dist/node.d.ts +1 -0
- package/dist/node.d.ts.map +1 -1
- package/dist/node.js +1 -0
- package/dist/oauth.d.ts +26 -0
- package/dist/oauth.d.ts.map +1 -0
- package/dist/oauth.js +24 -0
- package/dist/react-native.d.ts +1 -0
- package/dist/react-native.d.ts.map +1 -1
- package/dist/react-native.js +1 -0
- package/dist/web.d.ts +1 -0
- package/dist/web.d.ts.map +1 -1
- package/dist/web.js +1 -0
- package/package.json +8 -1
|
@@ -17,18 +17,58 @@ interface HookDispatcherLike {
|
|
|
17
17
|
interface LowPrioritySystemMessageSink {
|
|
18
18
|
low(message: string): void;
|
|
19
19
|
}
|
|
20
|
+
/**
|
|
21
|
+
* Options for constructing an {@link Orchestrator}.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```ts
|
|
25
|
+
* const orchestrator = new Orchestrator({
|
|
26
|
+
* conversation,
|
|
27
|
+
* getViewportHeight: () => window.innerHeight,
|
|
28
|
+
* scrollToEnd: (vHeight) => scrollContainer.scrollTo({ top: vHeight }),
|
|
29
|
+
* toolRegistry,
|
|
30
|
+
* permissionManager,
|
|
31
|
+
* getSystemPrompt: () => mySystemPrompt,
|
|
32
|
+
* hookDispatcher,
|
|
33
|
+
* flagManager,
|
|
34
|
+
* requestRender: () => renderFn(),
|
|
35
|
+
* runtimeBus,
|
|
36
|
+
* services: { agentManager, wrfcController },
|
|
37
|
+
* });
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export interface OrchestratorOptions {
|
|
41
|
+
/** Manages the conversation message history. */
|
|
42
|
+
conversation: ConversationManager;
|
|
43
|
+
/** Returns the current viewport height in rows/px for scrolling calculations. */
|
|
44
|
+
getViewportHeight: () => number;
|
|
45
|
+
/** Scrolls the UI to the given viewport height after a turn. */
|
|
46
|
+
scrollToEnd: (vHeight: number) => void;
|
|
47
|
+
/** Registry of all available tools. */
|
|
48
|
+
toolRegistry: ToolRegistry;
|
|
49
|
+
/** Manages tool-use permission grants and denials. */
|
|
50
|
+
permissionManager: PermissionManager;
|
|
51
|
+
/** Returns the current system prompt text. Defaults to `() => ''`. */
|
|
52
|
+
getSystemPrompt?: () => string;
|
|
53
|
+
/** Optional hook dispatcher for lifecycle events. */
|
|
54
|
+
hookDispatcher?: HookDispatcherLike | null;
|
|
55
|
+
/** Optional feature flag manager. */
|
|
56
|
+
flagManager?: FeatureFlagManager | null;
|
|
57
|
+
/** Optional render request callback, called after state changes requiring a redraw. */
|
|
58
|
+
requestRender?: (() => void) | null;
|
|
59
|
+
/** Optional runtime event bus for cross-system event propagation. */
|
|
60
|
+
runtimeBus?: RuntimeEventBus | null;
|
|
61
|
+
/** Required runtime service dependencies. */
|
|
62
|
+
services: {
|
|
63
|
+
readonly agentManager: Pick<AgentManager, 'list' | 'spawn'>;
|
|
64
|
+
readonly wrfcController: Pick<WrfcController, 'listChains'>;
|
|
65
|
+
};
|
|
66
|
+
}
|
|
20
67
|
/**
|
|
21
68
|
* Orchestrator - Manages LLM turn lifecycle with full tool-use loop.
|
|
22
69
|
* Supports multi-turn agent loops: call LLM -> execute tools -> send results -> repeat.
|
|
23
70
|
*/
|
|
24
71
|
export declare class Orchestrator {
|
|
25
|
-
private conversation;
|
|
26
|
-
private getViewportHeight;
|
|
27
|
-
private scrollToEnd;
|
|
28
|
-
private toolRegistry;
|
|
29
|
-
private permissionManager;
|
|
30
|
-
private getSystemPrompt;
|
|
31
|
-
private hookDispatcher;
|
|
32
72
|
isThinking: boolean;
|
|
33
73
|
thinkingFrame: number;
|
|
34
74
|
usage: {
|
|
@@ -113,10 +153,34 @@ export declare class Orchestrator {
|
|
|
113
153
|
private readonly requestRender;
|
|
114
154
|
private systemMessageRouter;
|
|
115
155
|
private readonly followUpRuntime;
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
156
|
+
private conversation;
|
|
157
|
+
private getViewportHeight;
|
|
158
|
+
private scrollToEnd;
|
|
159
|
+
private toolRegistry;
|
|
160
|
+
private permissionManager;
|
|
161
|
+
private getSystemPrompt;
|
|
162
|
+
private hookDispatcher;
|
|
163
|
+
/**
|
|
164
|
+
* Construct an Orchestrator using a named-options object.
|
|
165
|
+
*
|
|
166
|
+
* @example
|
|
167
|
+
* ```ts
|
|
168
|
+
* const orchestrator = new Orchestrator({
|
|
169
|
+
* conversation,
|
|
170
|
+
* getViewportHeight: () => terminalRows,
|
|
171
|
+
* scrollToEnd: (vHeight) => ui.scrollToEnd(vHeight),
|
|
172
|
+
* toolRegistry,
|
|
173
|
+
* permissionManager,
|
|
174
|
+
* getSystemPrompt: () => systemPrompt,
|
|
175
|
+
* hookDispatcher,
|
|
176
|
+
* flagManager,
|
|
177
|
+
* requestRender: () => render(),
|
|
178
|
+
* runtimeBus,
|
|
179
|
+
* services: { agentManager, wrfcController },
|
|
180
|
+
* });
|
|
181
|
+
* ```
|
|
182
|
+
*/
|
|
183
|
+
constructor(options: OrchestratorOptions);
|
|
120
184
|
setCoreServices(services: OrchestratorCoreServices): void;
|
|
121
185
|
/**
|
|
122
186
|
* Attach an AcpManager and register the 'delegate' tool into the ToolRegistry.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../../../../src/_internal/platform/core/orchestrator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAGzD,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAG/D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAG7D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AACnE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAQpD,OAAO,EACL,KAAK,wBAAwB,EAC9B,MAAM,8BAA8B,CAAC;AAEtC,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAK9D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAC9E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAkBlE,OAAO,EASL,KAAK,wBAAwB,EAC9B,MAAM,2BAA2B,CAAC;AAQnC,iFAAiF;AACjF,UAAU,kBAAkB;IAC1B,IAAI,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;CAC7C;AAMD,UAAU,4BAA4B;IACpC,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED
|
|
1
|
+
{"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../../../../src/_internal/platform/core/orchestrator.ts"],"names":[],"mappings":"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"}
|
|
@@ -30,13 +30,6 @@ const THINKING_SPINNER_FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦'
|
|
|
30
30
|
* Supports multi-turn agent loops: call LLM -> execute tools -> send results -> repeat.
|
|
31
31
|
*/
|
|
32
32
|
export class Orchestrator {
|
|
33
|
-
conversation;
|
|
34
|
-
getViewportHeight;
|
|
35
|
-
scrollToEnd;
|
|
36
|
-
toolRegistry;
|
|
37
|
-
permissionManager;
|
|
38
|
-
getSystemPrompt;
|
|
39
|
-
hookDispatcher;
|
|
40
33
|
isThinking = false;
|
|
41
34
|
thinkingFrame = 0;
|
|
42
35
|
usage = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 };
|
|
@@ -113,7 +106,35 @@ export class Orchestrator {
|
|
|
113
106
|
requestRender;
|
|
114
107
|
systemMessageRouter = null;
|
|
115
108
|
followUpRuntime;
|
|
116
|
-
|
|
109
|
+
conversation;
|
|
110
|
+
getViewportHeight;
|
|
111
|
+
scrollToEnd;
|
|
112
|
+
toolRegistry;
|
|
113
|
+
permissionManager;
|
|
114
|
+
getSystemPrompt;
|
|
115
|
+
hookDispatcher;
|
|
116
|
+
/**
|
|
117
|
+
* Construct an Orchestrator using a named-options object.
|
|
118
|
+
*
|
|
119
|
+
* @example
|
|
120
|
+
* ```ts
|
|
121
|
+
* const orchestrator = new Orchestrator({
|
|
122
|
+
* conversation,
|
|
123
|
+
* getViewportHeight: () => terminalRows,
|
|
124
|
+
* scrollToEnd: (vHeight) => ui.scrollToEnd(vHeight),
|
|
125
|
+
* toolRegistry,
|
|
126
|
+
* permissionManager,
|
|
127
|
+
* getSystemPrompt: () => systemPrompt,
|
|
128
|
+
* hookDispatcher,
|
|
129
|
+
* flagManager,
|
|
130
|
+
* requestRender: () => render(),
|
|
131
|
+
* runtimeBus,
|
|
132
|
+
* services: { agentManager, wrfcController },
|
|
133
|
+
* });
|
|
134
|
+
* ```
|
|
135
|
+
*/
|
|
136
|
+
constructor(options) {
|
|
137
|
+
const { conversation, getViewportHeight, scrollToEnd, toolRegistry, permissionManager, getSystemPrompt = () => '', hookDispatcher = null, flagManager = null, requestRender = null, runtimeBus = null, services, } = options;
|
|
117
138
|
this.conversation = conversation;
|
|
118
139
|
this.getViewportHeight = getViewportHeight;
|
|
119
140
|
this.scrollToEnd = scrollToEnd;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Crypto adapter — runtime-neutral interface for PKCE and random-bytes
|
|
3
|
+
* operations used by oauth-core.ts.
|
|
4
|
+
*
|
|
5
|
+
* This file uses the Web Crypto API (globalThis.crypto), which is available
|
|
6
|
+
* in React Native (Hermes / JavaScriptCore), modern browsers, and Node >= 19.
|
|
7
|
+
*
|
|
8
|
+
* API:
|
|
9
|
+
* createSha256Hash(input: string): Promise<string> — returns base64url digest
|
|
10
|
+
* randomBytesBase64url(n: number): string — returns n random bytes as base64url
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Compute SHA-256 of `input` and return the result as a base64url string.
|
|
14
|
+
* Uses Web Crypto API — safe in React Native, browser, and modern Node.
|
|
15
|
+
*/
|
|
16
|
+
export declare function createSha256Hash(input: string): Promise<string>;
|
|
17
|
+
/**
|
|
18
|
+
* Generate `n` cryptographically random bytes and return as base64url.
|
|
19
|
+
* Uses Web Crypto API — safe in React Native, browser, and modern Node.
|
|
20
|
+
*/
|
|
21
|
+
export declare function randomBytesBase64url(n: number): string;
|
|
22
|
+
//# sourceMappingURL=crypto-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crypto-adapter.d.ts","sourceRoot":"","sources":["../../../../../src/_internal/platform/runtime/auth/crypto-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH;;;GAGG;AACH,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAKrE;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAItD"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Crypto adapter — runtime-neutral interface for PKCE and random-bytes
|
|
3
|
+
* operations used by oauth-core.ts.
|
|
4
|
+
*
|
|
5
|
+
* This file uses the Web Crypto API (globalThis.crypto), which is available
|
|
6
|
+
* in React Native (Hermes / JavaScriptCore), modern browsers, and Node >= 19.
|
|
7
|
+
*
|
|
8
|
+
* API:
|
|
9
|
+
* createSha256Hash(input: string): Promise<string> — returns base64url digest
|
|
10
|
+
* randomBytesBase64url(n: number): string — returns n random bytes as base64url
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Compute SHA-256 of `input` and return the result as a base64url string.
|
|
14
|
+
* Uses Web Crypto API — safe in React Native, browser, and modern Node.
|
|
15
|
+
*/
|
|
16
|
+
export async function createSha256Hash(input) {
|
|
17
|
+
const encoder = new TextEncoder();
|
|
18
|
+
const data = encoder.encode(input);
|
|
19
|
+
const hashBuffer = await globalThis.crypto.subtle.digest('SHA-256', data);
|
|
20
|
+
return uint8ArrayToBase64url(new Uint8Array(hashBuffer));
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Generate `n` cryptographically random bytes and return as base64url.
|
|
24
|
+
* Uses Web Crypto API — safe in React Native, browser, and modern Node.
|
|
25
|
+
*/
|
|
26
|
+
export function randomBytesBase64url(n) {
|
|
27
|
+
const bytes = new Uint8Array(n);
|
|
28
|
+
globalThis.crypto.getRandomValues(bytes);
|
|
29
|
+
return uint8ArrayToBase64url(bytes);
|
|
30
|
+
}
|
|
31
|
+
function uint8ArrayToBase64url(bytes) {
|
|
32
|
+
let binary = '';
|
|
33
|
+
for (let i = 0; i < bytes.byteLength; i++) {
|
|
34
|
+
binary += String.fromCharCode(bytes[i]);
|
|
35
|
+
}
|
|
36
|
+
return btoa(binary)
|
|
37
|
+
.replace(/\+/g, '-')
|
|
38
|
+
.replace(/\//g, '_')
|
|
39
|
+
.replace(/=/g, '');
|
|
40
|
+
}
|
|
@@ -1,26 +1,15 @@
|
|
|
1
1
|
import type { OAuthProviderConfig } from '../../config/subscriptions.js';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
readonly state: string;
|
|
5
|
-
readonly verifier: string;
|
|
6
|
-
readonly redirectUri: string;
|
|
7
|
-
}
|
|
8
|
-
export interface OAuthTokenPayload {
|
|
9
|
-
readonly accessToken: string;
|
|
10
|
-
readonly refreshToken?: string;
|
|
11
|
-
readonly tokenType: string;
|
|
12
|
-
readonly expiresAt?: number;
|
|
13
|
-
readonly scopes?: readonly string[];
|
|
14
|
-
}
|
|
2
|
+
import type { OAuthStartState, OAuthTokenPayload } from '../../auth/oauth-types.js';
|
|
3
|
+
export type { OAuthStartState, OAuthTokenPayload } from '../../auth/oauth-types.js';
|
|
15
4
|
export declare function createOAuthState(bytes?: number): string;
|
|
16
5
|
export declare function createPkceVerifier(bytes?: number): string;
|
|
17
|
-
export declare function createPkceChallenge(verifier: string): string
|
|
6
|
+
export declare function createPkceChallenge(verifier: string): Promise<string>;
|
|
18
7
|
export declare function parseOAuthScopes(raw: unknown): readonly string[] | undefined;
|
|
19
8
|
export declare function buildOAuthAuthorizationStart(config: OAuthProviderConfig, input?: {
|
|
20
9
|
readonly state?: string;
|
|
21
10
|
readonly verifier?: string;
|
|
22
11
|
readonly redirectUri?: string;
|
|
23
|
-
}): OAuthStartState
|
|
12
|
+
}): Promise<OAuthStartState>;
|
|
24
13
|
export declare function exchangeOAuthAuthorizationCode(config: OAuthProviderConfig, input: {
|
|
25
14
|
readonly code: string;
|
|
26
15
|
readonly verifier: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oauth-core.d.ts","sourceRoot":"","sources":["../../../../../src/_internal/platform/runtime/auth/oauth-core.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"oauth-core.d.ts","sourceRoot":"","sources":["../../../../../src/_internal/platform/runtime/auth/oauth-core.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AAGzE,OAAO,KAAK,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AACpF,YAAY,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAEpF,wBAAgB,gBAAgB,CAAC,KAAK,SAAK,GAAG,MAAM,CAEnD;AAED,wBAAgB,kBAAkB,CAAC,KAAK,SAAK,GAAG,MAAM,CAErD;AAED,wBAAsB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAE3E;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,OAAO,GAAG,SAAS,MAAM,EAAE,GAAG,SAAS,CAI5E;AAED,wBAAsB,4BAA4B,CAChD,MAAM,EAAE,mBAAmB,EAC3B,KAAK,CAAC,EAAE;IACN,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC/B,GACA,OAAO,CAAC,eAAe,CAAC,CA4B1B;AA4CD,wBAAsB,8BAA8B,CAClD,MAAM,EAAE,mBAAmB,EAC3B,KAAK,EAAE;IACL,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB,GACA,OAAO,CAAC,iBAAiB,CAAC,CAc5B;AAED,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,mBAAmB,EAC3B,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,iBAAiB,CAAC,CAc5B;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAa9E"}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createSha256Hash, randomBytesBase64url } from './crypto-adapter.js';
|
|
2
2
|
export function createOAuthState(bytes = 24) {
|
|
3
|
-
return
|
|
3
|
+
return randomBytesBase64url(bytes);
|
|
4
4
|
}
|
|
5
5
|
export function createPkceVerifier(bytes = 32) {
|
|
6
|
-
return
|
|
6
|
+
return randomBytesBase64url(bytes);
|
|
7
7
|
}
|
|
8
|
-
export function createPkceChallenge(verifier) {
|
|
9
|
-
return
|
|
8
|
+
export async function createPkceChallenge(verifier) {
|
|
9
|
+
return createSha256Hash(verifier);
|
|
10
10
|
}
|
|
11
11
|
export function parseOAuthScopes(raw) {
|
|
12
12
|
if (typeof raw !== 'string')
|
|
@@ -14,7 +14,7 @@ export function parseOAuthScopes(raw) {
|
|
|
14
14
|
const scopes = raw.split(' ').map((value) => value.trim()).filter(Boolean);
|
|
15
15
|
return scopes.length > 0 ? scopes : undefined;
|
|
16
16
|
}
|
|
17
|
-
export function buildOAuthAuthorizationStart(config, input) {
|
|
17
|
+
export async function buildOAuthAuthorizationStart(config, input) {
|
|
18
18
|
const state = input?.state ?? createOAuthState();
|
|
19
19
|
const verifier = input?.verifier ?? createPkceVerifier();
|
|
20
20
|
const redirectUri = input?.redirectUri ?? config.redirectUri;
|
|
@@ -30,7 +30,7 @@ export function buildOAuthAuthorizationStart(config, input) {
|
|
|
30
30
|
url.searchParams.set('audience', config.audience);
|
|
31
31
|
}
|
|
32
32
|
if (config.usePkce ?? true) {
|
|
33
|
-
url.searchParams.set('code_challenge', createPkceChallenge(verifier));
|
|
33
|
+
url.searchParams.set('code_challenge', await createPkceChallenge(verifier));
|
|
34
34
|
url.searchParams.set('code_challenge_method', 'S256');
|
|
35
35
|
}
|
|
36
36
|
for (const [key, value] of Object.entries(config.authParams ?? {})) {
|
|
@@ -109,11 +109,16 @@ export async function refreshOAuthAccessToken(config, refreshToken) {
|
|
|
109
109
|
return exchangeOAuthRequest(config.tokenUrl, config.refreshRequestEncoding ?? config.tokenRequestEncoding ?? 'form', payload);
|
|
110
110
|
}
|
|
111
111
|
export function decodeJwtPayload(token) {
|
|
112
|
+
if (typeof atob !== 'function') {
|
|
113
|
+
throw new Error('decodeJwtPayload requires a global atob(); available in browsers, RN Hermes, and Node >= 16');
|
|
114
|
+
}
|
|
112
115
|
const parts = token.split('.');
|
|
113
116
|
if (parts.length < 2)
|
|
114
117
|
return null;
|
|
115
118
|
try {
|
|
116
|
-
|
|
119
|
+
// atob is universally available (browsers, React Native, modern Node)
|
|
120
|
+
const base64 = (parts[1]).replace(/-/g, '+').replace(/_/g, '/');
|
|
121
|
+
return JSON.parse(atob(base64));
|
|
117
122
|
}
|
|
118
123
|
catch {
|
|
119
124
|
return null;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { readFileSync } from 'node:fs';
|
|
2
2
|
import { join } from 'node:path';
|
|
3
|
-
let version = '0.18.
|
|
3
|
+
let version = '0.18.51';
|
|
4
4
|
try {
|
|
5
5
|
const pkg = JSON.parse(readFileSync(join(import.meta.dir, '..', '..', 'package.json'), 'utf-8'));
|
|
6
6
|
version = pkg.version ?? version;
|
|
@@ -14,5 +14,31 @@ export interface SerializedEventEnvelope<TEvent extends EventLike = EventLike> {
|
|
|
14
14
|
export type DomainEventConnector<TDomain extends string, TEvent extends EventLike = EventLike> = (domain: TDomain, onEnvelope: (envelope: SerializedEventEnvelope<TEvent>) => void) => void | Promise<() => void>;
|
|
15
15
|
export type DomainEvents<TDomain extends string, TEvent extends EventLike = EventLike> = RuntimeEventFeeds<TDomain, TEvent>;
|
|
16
16
|
export declare function createRemoteDomainEvents<TDomain extends string, TEvent extends EventLike = EventLike>(domains: readonly TDomain[], connect: DomainEventConnector<TDomain, TEvent>): DomainEvents<TDomain, TEvent>;
|
|
17
|
+
/**
|
|
18
|
+
* Returns a filtered view of the given domain events object where every
|
|
19
|
+
* callback only fires for events whose envelope `sessionId` equals the
|
|
20
|
+
* supplied value.
|
|
21
|
+
*
|
|
22
|
+
* All domain feeds and the `domain()` accessor are pre-filtered. The
|
|
23
|
+
* `domains` list is preserved unchanged.
|
|
24
|
+
*
|
|
25
|
+
* Unsubscribe handles returned by the filtered feeds propagate correctly
|
|
26
|
+
* to the underlying connection.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* const events = sdk.realtime.viaSse();
|
|
30
|
+
* // Without forSession — manual filter:
|
|
31
|
+
* events.turn.onEnvelope('STREAM_DELTA', (e) => {
|
|
32
|
+
* if (e.sessionId !== mySessionId) return;
|
|
33
|
+
* process.stdout.write(e.payload.content);
|
|
34
|
+
* });
|
|
35
|
+
*
|
|
36
|
+
* // With forSession — no filter needed:
|
|
37
|
+
* const sessionEvents = forSession(events, mySessionId);
|
|
38
|
+
* sessionEvents.turn.onEnvelope('STREAM_DELTA', (e) => {
|
|
39
|
+
* process.stdout.write(e.payload.content);
|
|
40
|
+
* });
|
|
41
|
+
*/
|
|
42
|
+
export declare function forSession<TDomain extends string, TEvent extends EventLike = EventLike>(events: DomainEvents<TDomain, TEvent>, sessionId: string): DomainEvents<TDomain, TEvent>;
|
|
17
43
|
export {};
|
|
18
44
|
//# sourceMappingURL=domain-events.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"domain-events.d.ts","sourceRoot":"","sources":["../../../src/_internal/transport-realtime/domain-events.ts"],"names":[],"mappings":"AAGA,OAAO,EAAkD,KAAK,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAEpH,KAAK,SAAS,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAE3C,MAAM,WAAW,uBAAuB,CAAC,MAAM,SAAS,SAAS,GAAG,SAAS;IAC3E,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,MAAM,oBAAoB,CAC9B,OAAO,SAAS,MAAM,EACtB,MAAM,SAAS,SAAS,GAAG,SAAS,IAClC,CACF,MAAM,EAAE,OAAO,EACf,UAAU,EAAE,CAAC,QAAQ,EAAE,uBAAuB,CAAC,MAAM,CAAC,KAAK,IAAI,KAC5D,IAAI,GAAG,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC;AAEhC,MAAM,MAAM,YAAY,CACtB,OAAO,SAAS,MAAM,EACtB,MAAM,SAAS,SAAS,GAAG,SAAS,IAClC,iBAAiB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;AAmIvC,wBAAgB,wBAAwB,CACtC,OAAO,SAAS,MAAM,EACtB,MAAM,SAAS,SAAS,GAAG,SAAS,EAEpC,OAAO,EAAE,SAAS,OAAO,EAAE,EAC3B,OAAO,EAAE,oBAAoB,CAAC,OAAO,EAAE,MAAM,CAAC,GAC7C,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAK/B"}
|
|
1
|
+
{"version":3,"file":"domain-events.d.ts","sourceRoot":"","sources":["../../../src/_internal/transport-realtime/domain-events.ts"],"names":[],"mappings":"AAGA,OAAO,EAAkD,KAAK,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAEpH,KAAK,SAAS,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAE3C,MAAM,WAAW,uBAAuB,CAAC,MAAM,SAAS,SAAS,GAAG,SAAS;IAC3E,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,MAAM,oBAAoB,CAC9B,OAAO,SAAS,MAAM,EACtB,MAAM,SAAS,SAAS,GAAG,SAAS,IAClC,CACF,MAAM,EAAE,OAAO,EACf,UAAU,EAAE,CAAC,QAAQ,EAAE,uBAAuB,CAAC,MAAM,CAAC,KAAK,IAAI,KAC5D,IAAI,GAAG,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC;AAEhC,MAAM,MAAM,YAAY,CACtB,OAAO,SAAS,MAAM,EACtB,MAAM,SAAS,SAAS,GAAG,SAAS,IAClC,iBAAiB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;AAmIvC,wBAAgB,wBAAwB,CACtC,OAAO,SAAS,MAAM,EACtB,MAAM,SAAS,SAAS,GAAG,SAAS,EAEpC,OAAO,EAAE,SAAS,OAAO,EAAE,EAC3B,OAAO,EAAE,oBAAoB,CAAC,OAAO,EAAE,MAAM,CAAC,GAC7C,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAK/B;AAmCD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,UAAU,CACxB,OAAO,SAAS,MAAM,EACtB,MAAM,SAAS,SAAS,GAAG,SAAS,EAEpC,MAAM,EAAE,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,EACrC,SAAS,EAAE,MAAM,GAChB,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAY/B"}
|
|
@@ -114,3 +114,66 @@ function createRemoteDomainEventFeed(domain, connect) {
|
|
|
114
114
|
export function createRemoteDomainEvents(domains, connect) {
|
|
115
115
|
return createRuntimeEventFeeds(domains, (domain) => createRemoteDomainEventFeed(domain, connect));
|
|
116
116
|
}
|
|
117
|
+
/**
|
|
118
|
+
* Wraps an existing {@link RuntimeEventFeed} and returns a filtered feed whose
|
|
119
|
+
* callbacks only fire for envelopes whose `sessionId` matches the given value.
|
|
120
|
+
*
|
|
121
|
+
* Unsubscribe handles returned by `on` / `onEnvelope` on the filtered feed
|
|
122
|
+
* correctly remove the underlying listener from the original feed.
|
|
123
|
+
*/
|
|
124
|
+
function createFilteredFeed(feed, sessionId) {
|
|
125
|
+
return {
|
|
126
|
+
on(type, listener) {
|
|
127
|
+
return feed.onEnvelope(type, (envelope) => {
|
|
128
|
+
if (envelope.sessionId !== sessionId)
|
|
129
|
+
return;
|
|
130
|
+
listener(envelope.payload);
|
|
131
|
+
});
|
|
132
|
+
},
|
|
133
|
+
onEnvelope(type, listener) {
|
|
134
|
+
return feed.onEnvelope(type, (envelope) => {
|
|
135
|
+
if (envelope.sessionId !== sessionId)
|
|
136
|
+
return;
|
|
137
|
+
listener(envelope);
|
|
138
|
+
});
|
|
139
|
+
},
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Returns a filtered view of the given domain events object where every
|
|
144
|
+
* callback only fires for events whose envelope `sessionId` equals the
|
|
145
|
+
* supplied value.
|
|
146
|
+
*
|
|
147
|
+
* All domain feeds and the `domain()` accessor are pre-filtered. The
|
|
148
|
+
* `domains` list is preserved unchanged.
|
|
149
|
+
*
|
|
150
|
+
* Unsubscribe handles returned by the filtered feeds propagate correctly
|
|
151
|
+
* to the underlying connection.
|
|
152
|
+
*
|
|
153
|
+
* @example
|
|
154
|
+
* const events = sdk.realtime.viaSse();
|
|
155
|
+
* // Without forSession — manual filter:
|
|
156
|
+
* events.turn.onEnvelope('STREAM_DELTA', (e) => {
|
|
157
|
+
* if (e.sessionId !== mySessionId) return;
|
|
158
|
+
* process.stdout.write(e.payload.content);
|
|
159
|
+
* });
|
|
160
|
+
*
|
|
161
|
+
* // With forSession — no filter needed:
|
|
162
|
+
* const sessionEvents = forSession(events, mySessionId);
|
|
163
|
+
* sessionEvents.turn.onEnvelope('STREAM_DELTA', (e) => {
|
|
164
|
+
* process.stdout.write(e.payload.content);
|
|
165
|
+
* });
|
|
166
|
+
*/
|
|
167
|
+
export function forSession(events, sessionId) {
|
|
168
|
+
const filteredFeeds = {};
|
|
169
|
+
for (const domain of events.domains) {
|
|
170
|
+
filteredFeeds[domain] = createFilteredFeed(events[domain], sessionId);
|
|
171
|
+
}
|
|
172
|
+
return Object.freeze({
|
|
173
|
+
...filteredFeeds,
|
|
174
|
+
domains: events.domains,
|
|
175
|
+
domain(d) {
|
|
176
|
+
return filteredFeeds[d];
|
|
177
|
+
},
|
|
178
|
+
});
|
|
179
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export type { DomainEventConnector, DomainEvents, SerializedEventEnvelope, } from './domain-events.js';
|
|
2
|
-
export { createRemoteDomainEvents } from './domain-events.js';
|
|
2
|
+
export { createRemoteDomainEvents, forSession } from './domain-events.js';
|
|
3
3
|
export type { RemoteRuntimeEvents, SerializedRuntimeEnvelope } from './runtime-events.js';
|
|
4
|
-
export { buildEventSourceUrl, buildWebSocketUrl, createEventSourceConnector, createRemoteRuntimeEvents, createWebSocketConnector, } from './runtime-events.js';
|
|
4
|
+
export { buildEventSourceUrl, buildWebSocketUrl, createEventSourceConnector, createRemoteRuntimeEvents, createWebSocketConnector, forSessionRuntime, } from './runtime-events.js';
|
|
5
5
|
export type { RuntimeEventConnectorOptions } from './runtime-events.js';
|
|
6
6
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/_internal/transport-realtime/index.ts"],"names":[],"mappings":"AACA,YAAY,EACV,oBAAoB,EACpB,YAAY,EACZ,uBAAuB,GACxB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/_internal/transport-realtime/index.ts"],"names":[],"mappings":"AACA,YAAY,EACV,oBAAoB,EACpB,YAAY,EACZ,uBAAuB,GACxB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,wBAAwB,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAC1E,YAAY,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AAC1F,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,0BAA0B,EAC1B,yBAAyB,EACzB,wBAAwB,EACxB,iBAAiB,GAClB,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EAAE,4BAA4B,EAAE,MAAM,qBAAqB,CAAC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { createRemoteDomainEvents } from './domain-events.js';
|
|
2
|
-
export { buildEventSourceUrl, buildWebSocketUrl, createEventSourceConnector, createRemoteRuntimeEvents, createWebSocketConnector, } from './runtime-events.js';
|
|
1
|
+
export { createRemoteDomainEvents, forSession } from './domain-events.js';
|
|
2
|
+
export { buildEventSourceUrl, buildWebSocketUrl, createEventSourceConnector, createRemoteRuntimeEvents, createWebSocketConnector, forSessionRuntime, } from './runtime-events.js';
|
|
@@ -7,6 +7,33 @@ type RuntimeEventRecord = {
|
|
|
7
7
|
};
|
|
8
8
|
export type SerializedRuntimeEnvelope<TEvent extends RuntimeEventRecord = RuntimeEventRecord> = SerializedEventEnvelope<TEvent>;
|
|
9
9
|
export type RemoteRuntimeEvents<TEvent extends RuntimeEventRecord = RuntimeEventRecord> = DomainEvents<RuntimeEventDomain, TEvent>;
|
|
10
|
+
/**
|
|
11
|
+
* Returns a filtered view of a {@link RemoteRuntimeEvents} object where every
|
|
12
|
+
* callback only fires for events whose envelope `sessionId` equals the given
|
|
13
|
+
* session identifier.
|
|
14
|
+
*
|
|
15
|
+
* This is a convenience wrapper around {@link forSession} scoped to the
|
|
16
|
+
* canonical runtime-event domains. Use it instead of manually checking
|
|
17
|
+
* `e.sessionId` in every callback.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* const events = sdk.realtime.viaSse();
|
|
21
|
+
* const session = await sdk.operator.sessions.create({ title: 'demo' });
|
|
22
|
+
* const sessionId = session.session.id;
|
|
23
|
+
*
|
|
24
|
+
* // Before forSession — repeated manual guard:
|
|
25
|
+
* events.turn.onEnvelope('STREAM_DELTA', (e) => {
|
|
26
|
+
* if (e.sessionId !== sessionId) return;
|
|
27
|
+
* process.stdout.write(e.payload.content);
|
|
28
|
+
* });
|
|
29
|
+
*
|
|
30
|
+
* // After forSession — clean, session-scoped subscription:
|
|
31
|
+
* const sessionEvents = forSessionRuntime(events, sessionId);
|
|
32
|
+
* sessionEvents.turn.onEnvelope('STREAM_DELTA', (e) => {
|
|
33
|
+
* process.stdout.write(e.payload.content);
|
|
34
|
+
* });
|
|
35
|
+
*/
|
|
36
|
+
export { forSession as forSessionRuntime } from './domain-events.js';
|
|
10
37
|
export interface RuntimeEventConnectorOptions {
|
|
11
38
|
readonly reconnect?: StreamReconnectPolicy;
|
|
12
39
|
readonly onError?: (error: unknown) => void;
|
|
@@ -17,5 +44,4 @@ export declare function buildEventSourceUrl(baseUrl: string, domain: RuntimeEven
|
|
|
17
44
|
export declare function buildWebSocketUrl(baseUrl: string, domains: readonly RuntimeEventDomain[]): string;
|
|
18
45
|
export declare function createEventSourceConnector(baseUrl: string, token: AuthTokenSource, fetchImpl: typeof fetch, options?: RuntimeEventConnectorOptions): DomainEventConnector<RuntimeEventDomain, AnyRuntimeEvent>;
|
|
19
46
|
export declare function createWebSocketConnector(baseUrl: string, token: AuthTokenSource, WebSocketImpl: typeof WebSocket, options?: RuntimeEventConnectorOptions): DomainEventConnector<RuntimeEventDomain, AnyRuntimeEvent>;
|
|
20
|
-
export {};
|
|
21
47
|
//# sourceMappingURL=runtime-events.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime-events.d.ts","sourceRoot":"","sources":["../../../src/_internal/transport-realtime/runtime-events.ts"],"names":[],"mappings":"AAEA,OAAO,EAAyB,KAAK,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AACvF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAC;AAC3E,OAAO,EAAsB,KAAK,iBAAiB,EAAE,KAAK,qBAAqB,EAA6D,MAAM,4BAA4B,CAAC;AAE/K,OAAO,EAEL,KAAK,oBAAoB,EACzB,KAAK,YAAY,EACjB,KAAK,uBAAuB,EAC7B,MAAM,oBAAoB,CAAC;AAE5B,KAAK,kBAAkB,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAEpD,MAAM,MAAM,yBAAyB,CAAC,MAAM,SAAS,kBAAkB,GAAG,kBAAkB,IAC1F,uBAAuB,CAAC,MAAM,CAAC,CAAC;AAElC,MAAM,MAAM,mBAAmB,CAAC,MAAM,SAAS,kBAAkB,GAAG,kBAAkB,IACpF,YAAY,CAAC,kBAAkB,EAAE,MAAM,CAAC,CAAC;AAE3C,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,SAAS,CAAC,EAAE,qBAAqB,CAAC;IAC3C,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CAC7C;AAED,KAAK,eAAe,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,iBAAiB,CAAC;AAErE,wBAAgB,yBAAyB,CAAC,MAAM,SAAS,kBAAkB,GAAG,kBAAkB,EAC9F,OAAO,EAAE,oBAAoB,CAAC,kBAAkB,EAAE,MAAM,CAAC,GACxD,mBAAmB,CAAC,MAAM,CAAC,CAK7B;AAED,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,kBAAkB,GACzB,MAAM,CAIR;AAED,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,SAAS,kBAAkB,EAAE,GACrC,MAAM,CAQR;AAED,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,eAAe,EACtB,SAAS,EAAE,OAAO,KAAK,EACvB,OAAO,GAAE,4BAAiC,GACzC,oBAAoB,CAAC,kBAAkB,EAAE,eAAe,CAAC,CAiB3D;AAED,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,eAAe,EACtB,aAAa,EAAE,OAAO,SAAS,EAC/B,OAAO,GAAE,4BAAiC,GACzC,oBAAoB,CAAC,kBAAkB,EAAE,eAAe,CAAC,CAuF3D"}
|
|
1
|
+
{"version":3,"file":"runtime-events.d.ts","sourceRoot":"","sources":["../../../src/_internal/transport-realtime/runtime-events.ts"],"names":[],"mappings":"AAEA,OAAO,EAAyB,KAAK,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AACvF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAC;AAC3E,OAAO,EAAsB,KAAK,iBAAiB,EAAE,KAAK,qBAAqB,EAA6D,MAAM,4BAA4B,CAAC;AAE/K,OAAO,EAEL,KAAK,oBAAoB,EACzB,KAAK,YAAY,EACjB,KAAK,uBAAuB,EAC7B,MAAM,oBAAoB,CAAC;AAE5B,KAAK,kBAAkB,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAEpD,MAAM,MAAM,yBAAyB,CAAC,MAAM,SAAS,kBAAkB,GAAG,kBAAkB,IAC1F,uBAAuB,CAAC,MAAM,CAAC,CAAC;AAElC,MAAM,MAAM,mBAAmB,CAAC,MAAM,SAAS,kBAAkB,GAAG,kBAAkB,IACpF,YAAY,CAAC,kBAAkB,EAAE,MAAM,CAAC,CAAC;AAE3C;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,OAAO,EAAE,UAAU,IAAI,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAErE,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,SAAS,CAAC,EAAE,qBAAqB,CAAC;IAC3C,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CAC7C;AAED,KAAK,eAAe,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,iBAAiB,CAAC;AAErE,wBAAgB,yBAAyB,CAAC,MAAM,SAAS,kBAAkB,GAAG,kBAAkB,EAC9F,OAAO,EAAE,oBAAoB,CAAC,kBAAkB,EAAE,MAAM,CAAC,GACxD,mBAAmB,CAAC,MAAM,CAAC,CAK7B;AAED,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,kBAAkB,GACzB,MAAM,CAIR;AAED,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,SAAS,kBAAkB,EAAE,GACrC,MAAM,CAQR;AAED,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,eAAe,EACtB,SAAS,EAAE,OAAO,KAAK,EACvB,OAAO,GAAE,4BAAiC,GACzC,oBAAoB,CAAC,kBAAkB,EAAE,eAAe,CAAC,CAiB3D;AAED,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,eAAe,EACtB,aAAa,EAAE,OAAO,SAAS,EAC/B,OAAO,GAAE,4BAAiC,GACzC,oBAAoB,CAAC,kBAAkB,EAAE,eAAe,CAAC,CAuF3D"}
|
|
@@ -4,6 +4,33 @@ import { RUNTIME_EVENT_DOMAINS } from '../contracts/index.js';
|
|
|
4
4
|
import { normalizeAuthToken, openRawServerSentEventStream as openServerSentEventStream } from '../transport-http/index.js';
|
|
5
5
|
import { buildUrl, normalizeBaseUrl } from '../transport-http/index.js';
|
|
6
6
|
import { createRemoteDomainEvents, } from './domain-events.js';
|
|
7
|
+
/**
|
|
8
|
+
* Returns a filtered view of a {@link RemoteRuntimeEvents} object where every
|
|
9
|
+
* callback only fires for events whose envelope `sessionId` equals the given
|
|
10
|
+
* session identifier.
|
|
11
|
+
*
|
|
12
|
+
* This is a convenience wrapper around {@link forSession} scoped to the
|
|
13
|
+
* canonical runtime-event domains. Use it instead of manually checking
|
|
14
|
+
* `e.sessionId` in every callback.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* const events = sdk.realtime.viaSse();
|
|
18
|
+
* const session = await sdk.operator.sessions.create({ title: 'demo' });
|
|
19
|
+
* const sessionId = session.session.id;
|
|
20
|
+
*
|
|
21
|
+
* // Before forSession — repeated manual guard:
|
|
22
|
+
* events.turn.onEnvelope('STREAM_DELTA', (e) => {
|
|
23
|
+
* if (e.sessionId !== sessionId) return;
|
|
24
|
+
* process.stdout.write(e.payload.content);
|
|
25
|
+
* });
|
|
26
|
+
*
|
|
27
|
+
* // After forSession — clean, session-scoped subscription:
|
|
28
|
+
* const sessionEvents = forSessionRuntime(events, sessionId);
|
|
29
|
+
* sessionEvents.turn.onEnvelope('STREAM_DELTA', (e) => {
|
|
30
|
+
* process.stdout.write(e.payload.content);
|
|
31
|
+
* });
|
|
32
|
+
*/
|
|
33
|
+
export { forSession as forSessionRuntime } from './domain-events.js';
|
|
7
34
|
export function createRemoteRuntimeEvents(connect) {
|
|
8
35
|
return createRemoteDomainEvents(RUNTIME_EVENT_DOMAINS, connect);
|
|
9
36
|
}
|
package/dist/auth.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { OperatorMethodInput, OperatorMethodOutput } from './_internal/contracts/index.js';
|
|
2
2
|
import type { AuthTokenResolver } from './_internal/transport-http/index.js';
|
|
3
3
|
import type { OperatorSdk } from './_internal/operator/index.js';
|
|
4
|
+
export { PermissionResolver, SessionManager, TokenStore, } from './_internal/platform/auth/index.js';
|
|
5
|
+
export type { OAuthStartState, OAuthTokenPayload } from './_internal/platform/auth/oauth-types.js';
|
|
4
6
|
export type GoodVibesCurrentAuth = OperatorMethodOutput<'control.auth.current'>;
|
|
5
7
|
export type GoodVibesLoginInput = OperatorMethodInput<'control.auth.login'>;
|
|
6
8
|
export type GoodVibesLoginOutput = OperatorMethodOutput<'control.auth.login'>;
|
|
@@ -16,12 +18,38 @@ export interface BrowserTokenStoreOptions {
|
|
|
16
18
|
export interface GoodVibesAuthLoginOptions {
|
|
17
19
|
readonly persistToken?: boolean;
|
|
18
20
|
}
|
|
21
|
+
/**
|
|
22
|
+
* The combined auth client attached to an SDK instance.
|
|
23
|
+
*
|
|
24
|
+
* This interface aggregates token storage and session management behind a
|
|
25
|
+
* single object for convenience. For focused single-responsibility access,
|
|
26
|
+
* use the split classes exported from this module:
|
|
27
|
+
* - Token persistence: `TokenStore`
|
|
28
|
+
* - Login / session lifecycle: `SessionManager`
|
|
29
|
+
* - OAuth 2.0 flows: `OAuthClient`
|
|
30
|
+
* - Role / scope checks: `PermissionResolver`
|
|
31
|
+
*/
|
|
19
32
|
export interface GoodVibesAuthClient {
|
|
20
33
|
readonly writable: boolean;
|
|
21
34
|
current(): Promise<GoodVibesCurrentAuth>;
|
|
22
35
|
login(input: GoodVibesLoginInput, options?: GoodVibesAuthLoginOptions): Promise<GoodVibesLoginOutput>;
|
|
36
|
+
/**
|
|
37
|
+
* @deprecated Prefer `TokenStore.getToken()` for direct token access.
|
|
38
|
+
* `GoodVibesAuthClient.getToken()` remains supported and delegates to the
|
|
39
|
+
* same underlying store.
|
|
40
|
+
*/
|
|
23
41
|
getToken(): Promise<string | null>;
|
|
42
|
+
/**
|
|
43
|
+
* @deprecated Prefer `TokenStore.setToken()` for direct token mutation.
|
|
44
|
+
* `GoodVibesAuthClient.setToken()` remains supported and delegates to the
|
|
45
|
+
* same underlying store.
|
|
46
|
+
*/
|
|
24
47
|
setToken(token: string | null): Promise<void>;
|
|
48
|
+
/**
|
|
49
|
+
* @deprecated Prefer `TokenStore.clearToken()` for direct token mutation.
|
|
50
|
+
* `GoodVibesAuthClient.clearToken()` remains supported and delegates to the
|
|
51
|
+
* same underlying store.
|
|
52
|
+
*/
|
|
25
53
|
clearToken(): Promise<void>;
|
|
26
54
|
}
|
|
27
55
|
/**
|
package/dist/auth.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,mBAAmB,EACnB,oBAAoB,EACrB,MAAM,gCAAgC,CAAC;AACxC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAC;AAC7E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,mBAAmB,EACnB,oBAAoB,EACrB,MAAM,gCAAgC,CAAC;AACxC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAC;AAC7E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAOjE,OAAO,EACL,kBAAkB,EAClB,cAAc,EACd,UAAU,GACX,MAAM,oCAAoC,CAAC;AAC5C,YAAY,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,0CAA0C,CAAC;AAEnG,MAAM,MAAM,oBAAoB,GAAG,oBAAoB,CAAC,sBAAsB,CAAC,CAAC;AAChF,MAAM,MAAM,mBAAmB,GAAG,mBAAmB,CAAC,oBAAoB,CAAC,CAAC;AAC5E,MAAM,MAAM,oBAAoB,GAAG,oBAAoB,CAAC,oBAAoB,CAAC,CAAC;AAE9E,MAAM,WAAW,mBAAmB;IAClC,QAAQ,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACnC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9C,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7B;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,OAAO,EAAE,SAAS,GAAG,SAAS,GAAG,YAAY,CAAC,CAAC;CACxE;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC;CACjC;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,OAAO,IAAI,OAAO,CAAC,oBAAoB,CAAC,CAAC;IACzC,KAAK,CAAC,KAAK,EAAE,mBAAmB,EAAE,OAAO,CAAC,EAAE,yBAAyB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;IACtG;;;;OAIG;IACH,QAAQ,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACnC;;;;OAIG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9C;;;;OAIG;IACH,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7B;AAYD;;;;;;;;;;;;GAYG;AACH,wBAAgB,sBAAsB,CAAC,YAAY,GAAE,MAAM,GAAG,IAAW,GAAG,mBAAmB,CAa9F;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,GAAE,wBAA6B,GAAG,mBAAmB,CAmBnG;AAwBD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,WAAW,EACrB,UAAU,EAAE,mBAAmB,GAAG,IAAI,EACtC,YAAY,CAAC,EAAE,iBAAiB,GAC/B,mBAAmB,CA0BrB"}
|
package/dist/auth.js
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
import { ConfigurationError } from './_internal/errors/index.js';
|
|
2
|
+
// Re-export focused responsibility classes for consumers who prefer
|
|
3
|
+
// narrower, single-concern APIs over the combined GoodVibesAuthClient facade.
|
|
4
|
+
// NOTE: OAuthClient is intentionally NOT re-exported here. It depends on
|
|
5
|
+
// node:crypto and is not safe in React Native / browser bundles.
|
|
6
|
+
// Use @pellux/goodvibes-sdk/oauth for Node.js consumers who need OAuthClient.
|
|
7
|
+
export { PermissionResolver, SessionManager, TokenStore, } from './_internal/platform/auth/index.js';
|
|
2
8
|
function requireStorage(storage) {
|
|
3
9
|
const resolved = storage ?? globalThis.localStorage;
|
|
4
10
|
if (!resolved) {
|