@chipmobilesdk/rn-ai 0.4.0 → 0.5.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/CHANGELOG.md +120 -0
- package/README.md +5 -2
- package/lib/commonjs/config/behaviorConfig.js +283 -0
- package/lib/commonjs/config/behaviorConfig.js.map +1 -0
- package/lib/commonjs/contract/gateway.js +60 -0
- package/lib/commonjs/contract/gateway.js.map +1 -0
- package/lib/commonjs/core/aiClient.js +330 -0
- package/lib/commonjs/core/aiClient.js.map +1 -0
- package/lib/commonjs/core/quotaRequest.js +105 -0
- package/lib/commonjs/core/quotaRequest.js.map +1 -0
- package/lib/commonjs/diagnostics/errors.js +108 -0
- package/lib/commonjs/diagnostics/errors.js.map +1 -0
- package/lib/commonjs/diagnostics/messageKeys.js +68 -0
- package/lib/commonjs/diagnostics/messageKeys.js.map +1 -0
- package/lib/commonjs/index.js +102 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/package.json +1 -0
- package/lib/commonjs/react/hooks.js +170 -0
- package/lib/commonjs/react/hooks.js.map +1 -0
- package/lib/commonjs/transport/sseClient.js +151 -0
- package/lib/commonjs/transport/sseClient.js.map +1 -0
- package/lib/commonjs/transport/timeouts.js +46 -0
- package/lib/commonjs/transport/timeouts.js.map +1 -0
- package/lib/module/config/behaviorConfig.js +275 -0
- package/lib/module/config/behaviorConfig.js.map +1 -0
- package/lib/module/contract/gateway.js +56 -0
- package/lib/module/contract/gateway.js.map +1 -0
- package/lib/module/core/aiClient.js +327 -0
- package/lib/module/core/aiClient.js.map +1 -0
- package/lib/module/core/quotaRequest.js +102 -0
- package/lib/module/core/quotaRequest.js.map +1 -0
- package/lib/module/diagnostics/errors.js +99 -0
- package/lib/module/diagnostics/errors.js.map +1 -0
- package/lib/module/diagnostics/messageKeys.js +61 -0
- package/lib/module/diagnostics/messageKeys.js.map +1 -0
- package/lib/module/index.js +19 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/react/hooks.js +164 -0
- package/lib/module/react/hooks.js.map +1 -0
- package/lib/module/transport/sseClient.js +146 -0
- package/lib/module/transport/sseClient.js.map +1 -0
- package/lib/module/transport/timeouts.js +41 -0
- package/lib/module/transport/timeouts.js.map +1 -0
- package/lib/typescript/commonjs/config/behaviorConfig.d.ts +119 -0
- package/lib/typescript/commonjs/config/behaviorConfig.d.ts.map +1 -0
- package/lib/typescript/commonjs/contract/gateway.d.ts +64 -0
- package/lib/typescript/commonjs/contract/gateway.d.ts.map +1 -0
- package/lib/typescript/commonjs/core/aiClient.d.ts +104 -0
- package/lib/typescript/commonjs/core/aiClient.d.ts.map +1 -0
- package/lib/typescript/commonjs/core/quotaRequest.d.ts +45 -0
- package/lib/typescript/commonjs/core/quotaRequest.d.ts.map +1 -0
- package/lib/typescript/commonjs/diagnostics/errors.d.ts +38 -0
- package/lib/typescript/commonjs/diagnostics/errors.d.ts.map +1 -0
- package/lib/typescript/commonjs/diagnostics/messageKeys.d.ts +46 -0
- package/lib/typescript/commonjs/diagnostics/messageKeys.d.ts.map +1 -0
- package/lib/typescript/commonjs/index.d.ts +21 -0
- package/lib/typescript/commonjs/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/package.json +1 -0
- package/lib/typescript/commonjs/react/hooks.d.ts +37 -0
- package/lib/typescript/commonjs/react/hooks.d.ts.map +1 -0
- package/lib/typescript/commonjs/transport/sseClient.d.ts +57 -0
- package/lib/typescript/commonjs/transport/sseClient.d.ts.map +1 -0
- package/lib/typescript/commonjs/transport/timeouts.d.ts +28 -0
- package/lib/typescript/commonjs/transport/timeouts.d.ts.map +1 -0
- package/lib/typescript/module/config/behaviorConfig.d.ts +119 -0
- package/lib/typescript/module/config/behaviorConfig.d.ts.map +1 -0
- package/lib/typescript/module/contract/gateway.d.ts +64 -0
- package/lib/typescript/module/contract/gateway.d.ts.map +1 -0
- package/lib/typescript/module/core/aiClient.d.ts +104 -0
- package/lib/typescript/module/core/aiClient.d.ts.map +1 -0
- package/lib/typescript/module/core/quotaRequest.d.ts +45 -0
- package/lib/typescript/module/core/quotaRequest.d.ts.map +1 -0
- package/lib/typescript/module/diagnostics/errors.d.ts +38 -0
- package/lib/typescript/module/diagnostics/errors.d.ts.map +1 -0
- package/lib/typescript/module/diagnostics/messageKeys.d.ts +46 -0
- package/lib/typescript/module/diagnostics/messageKeys.d.ts.map +1 -0
- package/lib/typescript/module/index.d.ts +21 -0
- package/lib/typescript/module/index.d.ts.map +1 -0
- package/lib/typescript/module/package.json +1 -0
- package/lib/typescript/module/react/hooks.d.ts +37 -0
- package/lib/typescript/module/react/hooks.d.ts.map +1 -0
- package/lib/typescript/module/transport/sseClient.d.ts +57 -0
- package/lib/typescript/module/transport/sseClient.d.ts.map +1 -0
- package/lib/typescript/module/transport/timeouts.d.ts +28 -0
- package/lib/typescript/module/transport/timeouts.d.ts.map +1 -0
- package/package.json +40 -12
- package/skills/sdk-rn-ai/SKILL.md +8 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @chipmobilesdk/rn-ai — AI gateway client for ChipMobileSdk-family React
|
|
3
|
+
* Native apps (feature 005). Single public entrypoint (LIB-003); modules
|
|
4
|
+
* under `config/`, `transport/`, `core/`, `react/`, and `diagnostics/` are
|
|
5
|
+
* private. Contract: specs/005-azure-ai-gateway/contracts/rn-ai-public-api.md
|
|
6
|
+
*/
|
|
7
|
+
export { createAiClient } from './core/aiClient';
|
|
8
|
+
export type { AiClient, AiClientConfig, AiBehaviorState, TokenProvider, AccessTokenRequestOptions, ChatRequest, ChatMessage, ContentPart, ChatStreamHandlers, ChatHandle, Usage, QuotaSnapshot, } from './core/aiClient';
|
|
9
|
+
export type { AppBehaviorConfig, AiConfigCache, BehaviorState } from './config/behaviorConfig';
|
|
10
|
+
export { configCacheFromKeyValue, SUPPORTED_SCHEMA_VERSION } from './config/behaviorConfig';
|
|
11
|
+
export type { GatewayErrorCode, GatewayErrorBody, GatewayQuota, GatewayStreamEvent, GatewayUsage, QuotaHeaderName, QuotaHeaderNames, } from './contract/gateway';
|
|
12
|
+
export { GATEWAY_ERROR_STATUS, QUOTA_HEADERS, SSE_DONE_SENTINEL } from './contract/gateway';
|
|
13
|
+
export type { AiTimeouts } from './transport/timeouts';
|
|
14
|
+
export type { SseRequest, SseHandlers, SseHandle, SseResponseInfo, StreamTransport, } from './transport/sseClient';
|
|
15
|
+
export { useAiBehaviorState, useAiChat, useAiQuota } from './react/hooks';
|
|
16
|
+
export type { AiChatStatus, UseAiChatOptions, UseAiChatResult, UseAiQuotaResult, } from './react/hooks';
|
|
17
|
+
export { AiError, isAiError } from './diagnostics/errors';
|
|
18
|
+
export type { AiErrorCode } from './diagnostics/errors';
|
|
19
|
+
export { aiMessage, aiMessageSet, aiMessages, messageKeyForError } from './diagnostics/messageKeys';
|
|
20
|
+
export type { AiMessageKey } from './diagnostics/messageKeys';
|
|
21
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,YAAY,EACX,QAAQ,EACR,cAAc,EACd,eAAe,EACf,aAAa,EACb,yBAAyB,EACzB,WAAW,EACX,WAAW,EACX,WAAW,EACX,kBAAkB,EAClB,UAAU,EACV,KAAK,EACL,aAAa,GACb,MAAM,iBAAiB,CAAC;AAEzB,YAAY,EAAE,iBAAiB,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAC/F,OAAO,EAAE,uBAAuB,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AAI5F,YAAY,EACX,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,EACZ,kBAAkB,EAClB,YAAY,EACZ,eAAe,EACf,gBAAgB,GAChB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,oBAAoB,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAE5F,YAAY,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvD,YAAY,EACX,UAAU,EACV,WAAW,EACX,SAAS,EACT,eAAe,EACf,eAAe,GACf,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC1E,YAAY,EACX,YAAY,EACZ,gBAAgB,EAChB,eAAe,EACf,gBAAgB,GAChB,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAC1D,YAAY,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AACpG,YAAY,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"type":"commonjs"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { AiBehaviorState, AiClient, ChatRequest, QuotaSnapshot } from '../core/aiClient';
|
|
2
|
+
import type { AiError } from '../diagnostics/errors';
|
|
3
|
+
export type AiChatStatus = 'idle' | 'loading' | 'streaming' | 'done' | 'error' | 'rate-limited';
|
|
4
|
+
export interface UseAiChatResult {
|
|
5
|
+
send(request: ChatRequest): void;
|
|
6
|
+
cancel(): void;
|
|
7
|
+
status: AiChatStatus;
|
|
8
|
+
/** Accumulated streamed text, flushed on an interval rather than per token. */
|
|
9
|
+
text: string;
|
|
10
|
+
error?: AiError;
|
|
11
|
+
retryAt?: Date;
|
|
12
|
+
quota?: QuotaSnapshot;
|
|
13
|
+
}
|
|
14
|
+
export interface UseAiChatOptions {
|
|
15
|
+
/**
|
|
16
|
+
* How often the accumulated text reaches the screen, in milliseconds.
|
|
17
|
+
*
|
|
18
|
+
* A model streams 30–100 tokens a second, and a render per token is 30–100
|
|
19
|
+
* renders of the whole transcript a second on the JS thread (PERF-12). At the
|
|
20
|
+
* default a long answer costs about 20 renders a second instead, and the last
|
|
21
|
+
* tokens are always flushed with the terminal state. `0` renders per token.
|
|
22
|
+
*/
|
|
23
|
+
flushIntervalMs?: number;
|
|
24
|
+
}
|
|
25
|
+
export declare function useAiChat(client: AiClient, options?: UseAiChatOptions): UseAiChatResult;
|
|
26
|
+
export interface UseAiQuotaResult {
|
|
27
|
+
quota?: QuotaSnapshot;
|
|
28
|
+
status: 'loading' | 'ready' | 'error';
|
|
29
|
+
refresh(): void;
|
|
30
|
+
}
|
|
31
|
+
export declare function useAiQuota(client: AiClient): UseAiQuotaResult;
|
|
32
|
+
/**
|
|
33
|
+
* The client's behavior state (config source and whether AI is enabled), live:
|
|
34
|
+
* re-renders when the kill switch flips or the config state moves (AI-09).
|
|
35
|
+
*/
|
|
36
|
+
export declare function useAiBehaviorState(client: AiClient): AiBehaviorState;
|
|
37
|
+
//# sourceMappingURL=hooks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../../../src/react/hooks.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACX,eAAe,EACf,QAAQ,EAER,WAAW,EACX,aAAa,EACb,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAErD,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,SAAS,GAAG,WAAW,GAAG,MAAM,GAAG,OAAO,GAAG,cAAc,CAAC;AAEhG,MAAM,WAAW,eAAe;IAC/B,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,CAAC;IACjC,MAAM,IAAI,IAAI,CAAC;IACf,MAAM,EAAE,YAAY,CAAC;IACrB,+EAA+E;IAC/E,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,IAAI,CAAC;IACf,KAAK,CAAC,EAAE,aAAa,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAChC;;;;;;;OAOG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;CACzB;AAID,wBAAgB,SAAS,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAE,gBAAqB,GAAG,eAAe,CA2G3F;AAED,MAAM,WAAW,gBAAgB;IAChC,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,MAAM,EAAE,SAAS,GAAG,OAAO,GAAG,OAAO,CAAC;IACtC,OAAO,IAAI,IAAI,CAAC;CAChB;AAgBD,wBAAgB,UAAU,CAAC,MAAM,EAAE,QAAQ,GAAG,gBAAgB,CAqC7D;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,QAAQ,GAAG,eAAe,CAEpE"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal SSE reader over XMLHttpRequest (research R2).
|
|
3
|
+
*
|
|
4
|
+
* React Native's fetch does not reliably expose ReadableStream on Hermes, so
|
|
5
|
+
* we use XHR incremental text delivery (readyState LOADING + onprogress) —
|
|
6
|
+
* the same mechanism community SSE libraries use — with zero dependencies.
|
|
7
|
+
* The gateway never compresses SSE responses (contract), which keeps
|
|
8
|
+
* incremental delivery intact on both platforms.
|
|
9
|
+
*/
|
|
10
|
+
export interface SseRequest {
|
|
11
|
+
url: string;
|
|
12
|
+
method?: 'GET' | 'POST';
|
|
13
|
+
headers?: Record<string, string>;
|
|
14
|
+
/** JSON string body for POST requests. */
|
|
15
|
+
body?: string;
|
|
16
|
+
/** Hard limit on the whole request. Rarely right for a stream; prefer the two below. */
|
|
17
|
+
timeoutMs?: number;
|
|
18
|
+
/** Fails with `onError(0, 'timeout')` if response headers have not arrived by then. */
|
|
19
|
+
connectTimeoutMs?: number;
|
|
20
|
+
/** Fails with `onError(0, 'timeout')` when no chunk arrives for this long. Reset per chunk. */
|
|
21
|
+
idleTimeoutMs?: number;
|
|
22
|
+
}
|
|
23
|
+
/** What the response said besides its body. Absent for a failure with no response. */
|
|
24
|
+
export interface SseResponseInfo {
|
|
25
|
+
/** A response header, or null. `Retry-After` is the one this package reads. */
|
|
26
|
+
getHeader(name: string): string | null;
|
|
27
|
+
}
|
|
28
|
+
export interface SseHandlers {
|
|
29
|
+
/** One call per `data:` event payload (raw string, already de-framed). */
|
|
30
|
+
onData(payload: string): void;
|
|
31
|
+
/** Stream closed normally (transport level; `[DONE]` handling is the caller's). */
|
|
32
|
+
onEnd(): void;
|
|
33
|
+
/** Transport or HTTP error. `status` is 0 for network failures. */
|
|
34
|
+
onError(status: number, bodyText: string, response?: SseResponseInfo): void;
|
|
35
|
+
}
|
|
36
|
+
export interface SseHandle {
|
|
37
|
+
cancel(): void;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* The transport port: how this package makes a streaming request.
|
|
41
|
+
*
|
|
42
|
+
* A published port rather than `typeof requestSse`, so the default reader's
|
|
43
|
+
* own signature is not part of the public API (AI-18): an app may inject its
|
|
44
|
+
* own transport, and this package may change how `requestSse` is written
|
|
45
|
+
* without that being a breaking change.
|
|
46
|
+
*/
|
|
47
|
+
export type StreamTransport = (request: SseRequest, handlers: SseHandlers) => SseHandle;
|
|
48
|
+
/**
|
|
49
|
+
* Parse complete `data:` events out of `text` starting at `fromIndex`.
|
|
50
|
+
*
|
|
51
|
+
* Both line endings are accepted. A proxy that normalises to CRLF — an API
|
|
52
|
+
* gateway or a corporate middlebox — used to make every event invisible until
|
|
53
|
+
* the stream closed, because only `\n\n` counted as a separator (AI-22).
|
|
54
|
+
*/
|
|
55
|
+
export declare function drainSseEvents(text: string, fromIndex: number, emit: (payload: string) => void): number;
|
|
56
|
+
export declare function requestSse(request: SseRequest, handlers: SseHandlers): SseHandle;
|
|
57
|
+
//# sourceMappingURL=sseClient.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sseClient.d.ts","sourceRoot":"","sources":["../../../../src/transport/sseClient.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,WAAW,UAAU;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,0CAA0C;IAC1C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,wFAAwF;IACxF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uFAAuF;IACvF,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,+FAA+F;IAC/F,aAAa,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,sFAAsF;AACtF,MAAM,WAAW,eAAe;IAC/B,+EAA+E;IAC/E,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;CACvC;AAED,MAAM,WAAW,WAAW;IAC3B,0EAA0E;IAC1E,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,mFAAmF;IACnF,KAAK,IAAI,IAAI,CAAC;IACd,mEAAmE;IACnE,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;CAC5E;AAED,MAAM,WAAW,SAAS;IACzB,MAAM,IAAI,IAAI,CAAC;CACf;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,WAAW,KAAK,SAAS,CAAC;AAExF;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC7B,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GAC7B,MAAM,CAiBR;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,WAAW,GAAG,SAAS,CA0GhF"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Time limits for every network call the client makes (AI-04).
|
|
3
|
+
*
|
|
4
|
+
* Without them a stalled mobile connection left `useAiChat` in `loading` or
|
|
5
|
+
* `streaming`, and `useAiQuota` in `loading`, until the user gave up.
|
|
6
|
+
*/
|
|
7
|
+
export interface AiTimeouts {
|
|
8
|
+
/** Request sent → response headers received, for the chat stream. */
|
|
9
|
+
connectMs: number;
|
|
10
|
+
/** Longest silence allowed between two chunks of the chat stream. */
|
|
11
|
+
idleMs: number;
|
|
12
|
+
/** Behavior-config fetch, including reading the body. */
|
|
13
|
+
configMs: number;
|
|
14
|
+
/** Quota fetch, including reading the body. */
|
|
15
|
+
quotaMs: number;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* The gateway sends headers only once the model has answered, so `connectMs`
|
|
19
|
+
* also covers time to first token on a large image prompt.
|
|
20
|
+
*/
|
|
21
|
+
export declare const DEFAULT_AI_TIMEOUTS: AiTimeouts;
|
|
22
|
+
/**
|
|
23
|
+
* Runs `run` with an abort signal and rejects with `onTimeout()` after `ms`.
|
|
24
|
+
* The race matters as much as the signal: an injected `fetchFn` (or an old
|
|
25
|
+
* polyfill) may ignore the signal entirely.
|
|
26
|
+
*/
|
|
27
|
+
export declare function withTimeout<T>(ms: number, run: (signal: AbortSignal | undefined) => Promise<T>, onTimeout: () => Error): Promise<T>;
|
|
28
|
+
//# sourceMappingURL=timeouts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"timeouts.d.ts","sourceRoot":"","sources":["../../../../src/transport/timeouts.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,UAAU;IAC1B,qEAAqE;IACrE,SAAS,EAAE,MAAM,CAAC;IAClB,qEAAqE;IACrE,MAAM,EAAE,MAAM,CAAC;IACf,yDAAyD;IACzD,QAAQ,EAAE,MAAM,CAAC;IACjB,+CAA+C;IAC/C,OAAO,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,eAAO,MAAM,mBAAmB,EAAE,UAKjC,CAAC;AAEF;;;;GAIG;AACH,wBAAsB,WAAW,CAAC,CAAC,EAClC,EAAE,EAAE,MAAM,EACV,GAAG,EAAE,CAAC,MAAM,EAAE,WAAW,GAAG,SAAS,KAAK,OAAO,CAAC,CAAC,CAAC,EACpD,SAAS,EAAE,MAAM,KAAK,GACpB,OAAO,CAAC,CAAC,CAAC,CAcZ"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { type KeyValuePort } from '@chipmobilesdk/rn-core';
|
|
2
|
+
/** App behavior configuration (contracts/app-behavior-config.md). */
|
|
3
|
+
export interface AppBehaviorConfig {
|
|
4
|
+
schemaVersion: number;
|
|
5
|
+
appId: string;
|
|
6
|
+
configVersion: number;
|
|
7
|
+
refreshTtlSeconds: number;
|
|
8
|
+
api: {
|
|
9
|
+
baseUrl: string;
|
|
10
|
+
scopes: string[];
|
|
11
|
+
supportsStreaming: boolean;
|
|
12
|
+
};
|
|
13
|
+
limitsDisplay?: {
|
|
14
|
+
requestsPerDay?: number;
|
|
15
|
+
tokensPerDay?: number;
|
|
16
|
+
};
|
|
17
|
+
recovery: {
|
|
18
|
+
reloadOnHttpStatus: number[];
|
|
19
|
+
maxSilentRetries: number;
|
|
20
|
+
retryBackoffMs: number[];
|
|
21
|
+
};
|
|
22
|
+
features: {
|
|
23
|
+
aiEnabled: boolean;
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
/** Persistence port; default is in-memory (inject a durable store for offline launch). */
|
|
27
|
+
export interface AiConfigCache {
|
|
28
|
+
get(key: string): Promise<string | null>;
|
|
29
|
+
set(key: string, value: string): Promise<void>;
|
|
30
|
+
}
|
|
31
|
+
export declare class MemoryConfigCache implements AiConfigCache {
|
|
32
|
+
private map;
|
|
33
|
+
get(key: string): Promise<string | null>;
|
|
34
|
+
set(key: string, value: string): Promise<void>;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* An `AiConfigCache` over rn-core's synchronous `KeyValuePort` (AI-10).
|
|
38
|
+
*
|
|
39
|
+
* Without a durable cache every launch waits for the network before the first
|
|
40
|
+
* chat, which is exactly what the cache-first design exists to avoid. Open the
|
|
41
|
+
* port the way the app opens its other durable state, for example
|
|
42
|
+
* `openDurable(() => createMMKV({ id: 'app' }))`.
|
|
43
|
+
*/
|
|
44
|
+
export declare function configCacheFromKeyValue(port: KeyValuePort): AiConfigCache;
|
|
45
|
+
export type BehaviorState = 'unloaded' | 'ready-network' | 'ready-cache' | 'unavailable';
|
|
46
|
+
/** The newest document layout this release understands. */
|
|
47
|
+
export declare const SUPPORTED_SCHEMA_VERSION = 1;
|
|
48
|
+
/** https, or http on a development machine: a bearer token travels to this host. */
|
|
49
|
+
export declare function isTrustedUrl(url: string): boolean;
|
|
50
|
+
export interface ParseBehaviorConfigOptions {
|
|
51
|
+
/** The app this document must be for; a document for another app is refused. */
|
|
52
|
+
expectedAppId?: string;
|
|
53
|
+
/** Hosts `api.baseUrl` may name. Any host is accepted when omitted. */
|
|
54
|
+
allowedHosts?: readonly string[];
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Parse + validate; unknown fields ignored (forward compatibility).
|
|
58
|
+
*
|
|
59
|
+
* Every field this package acts on is checked here, because the document is
|
|
60
|
+
* remote and the alternative is a TypeError inside an XHR callback, a revalidate
|
|
61
|
+
* on every single request, or a bearer token sent to a host nobody vetted
|
|
62
|
+
* (AI-06, AI-07).
|
|
63
|
+
*/
|
|
64
|
+
export declare function parseBehaviorConfig(json: string, options?: ParseBehaviorConfigOptions): AppBehaviorConfig;
|
|
65
|
+
export interface BehaviorConfigDeps {
|
|
66
|
+
configUrl: string;
|
|
67
|
+
appId: string;
|
|
68
|
+
cache?: AiConfigCache;
|
|
69
|
+
fetchFn?: typeof fetch;
|
|
70
|
+
now?: () => number;
|
|
71
|
+
/** Limit on one config fetch, body included. Defaults to 10 s. */
|
|
72
|
+
timeoutMs?: number;
|
|
73
|
+
/** Hosts the document's `api.baseUrl` may name. */
|
|
74
|
+
allowedHosts?: readonly string[];
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Cache-first behavior config (FR-018): launch never blocks on the network;
|
|
78
|
+
* TTL revalidation uses ETag; designated errors force a reload.
|
|
79
|
+
*/
|
|
80
|
+
export declare class BehaviorConfigManager {
|
|
81
|
+
private deps;
|
|
82
|
+
private cacheKey;
|
|
83
|
+
private cache;
|
|
84
|
+
private fetchFn;
|
|
85
|
+
private now;
|
|
86
|
+
private current?;
|
|
87
|
+
/**
|
|
88
|
+
* One cache read and one network fetch at a time (AI-08): a cold start makes a
|
|
89
|
+
* chat and a quota call together, and each used to fetch the config itself.
|
|
90
|
+
*/
|
|
91
|
+
private readonly cacheRead;
|
|
92
|
+
private readonly networkFetch;
|
|
93
|
+
private currentState;
|
|
94
|
+
private readonly stateListeners;
|
|
95
|
+
/** Where the config came from, or why there is none. */
|
|
96
|
+
get state(): BehaviorState;
|
|
97
|
+
/** Called whenever `state` changes (AI-09). */
|
|
98
|
+
subscribe(listener: () => void): () => void;
|
|
99
|
+
private setState;
|
|
100
|
+
constructor(deps: BehaviorConfigDeps);
|
|
101
|
+
private parse;
|
|
102
|
+
private isFresh;
|
|
103
|
+
private loadFromCache;
|
|
104
|
+
private readCache;
|
|
105
|
+
private fetchNetwork;
|
|
106
|
+
/** One attempt; `conditional` sends the stored ETag when there is one. */
|
|
107
|
+
private fetchOnce;
|
|
108
|
+
private fetchFromNetwork;
|
|
109
|
+
private persist;
|
|
110
|
+
/**
|
|
111
|
+
* Cache-first read. Fresh cache returns immediately; stale cache returns
|
|
112
|
+
* immediately too while a background revalidation runs; no cache at all
|
|
113
|
+
* falls through to the network (or `config-unavailable`).
|
|
114
|
+
*/
|
|
115
|
+
getConfig(options?: {
|
|
116
|
+
forceReload?: boolean;
|
|
117
|
+
}): Promise<AppBehaviorConfig>;
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=behaviorConfig.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"behaviorConfig.d.ts","sourceRoot":"","sources":["../../../../src/config/behaviorConfig.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The gateway↔client contract: error codes, quota headers, stream events.
|
|
3
|
+
*
|
|
4
|
+
* One definition, imported by both sides (GW-13). The gateway's own codes and
|
|
5
|
+
* the client's map of them were two hand-maintained lists, and they had already
|
|
6
|
+
* drifted: `BAD_REQUEST`, `ENDPOINT_RETIRED` and `INTERNAL` existed on the
|
|
7
|
+
* server and were unknown to the client, which fell back to a guess from the
|
|
8
|
+
* status. Adding a code now fails to compile on whichever side has not handled
|
|
9
|
+
* it.
|
|
10
|
+
*
|
|
11
|
+
* Types and plain constants only, and no import of anything: the gateway runs
|
|
12
|
+
* on Node and imports this file for its types alone.
|
|
13
|
+
*/
|
|
14
|
+
/** Every error the gateway answers with (`error.code` in the body). */
|
|
15
|
+
export type GatewayErrorCode = 'BAD_REQUEST' | 'AUTH_INVALID' | 'NOT_ENTITLED' | 'USER_BLOCKED' | 'APP_UNKNOWN' | 'ENDPOINT_RETIRED' | 'PAYLOAD_TOO_LARGE' | 'MODALITY_NOT_ALLOWED' | 'RATE_LIMITED' | 'UPSTREAM_BUSY' | 'UPSTREAM_ERROR' | 'INTERNAL';
|
|
16
|
+
/** The HTTP status each code is sent with. */
|
|
17
|
+
export declare const GATEWAY_ERROR_STATUS: Readonly<Record<GatewayErrorCode, number>>;
|
|
18
|
+
/** The error body. `message` is safe to log; it never carries upstream detail. */
|
|
19
|
+
export interface GatewayErrorBody {
|
|
20
|
+
error: {
|
|
21
|
+
code: GatewayErrorCode;
|
|
22
|
+
message: string;
|
|
23
|
+
retryAfterSeconds?: number;
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
/** The quota headers, by name. A rename here breaks both sides' compile. */
|
|
27
|
+
export declare const QUOTA_HEADERS: {
|
|
28
|
+
readonly minuteRemaining: "X-Quota-Minute-Remaining";
|
|
29
|
+
readonly dayRemaining: "X-Quota-Day-Remaining";
|
|
30
|
+
readonly dayTokensRemaining: "X-Quota-Day-Tokens-Remaining";
|
|
31
|
+
};
|
|
32
|
+
/** The names field by field, so a side declaring its own literals is checked exactly. */
|
|
33
|
+
export type QuotaHeaderNames = typeof QUOTA_HEADERS;
|
|
34
|
+
export type QuotaHeaderName = QuotaHeaderNames[keyof QuotaHeaderNames];
|
|
35
|
+
/** What is left of an app's allowance, as the gateway reports it. */
|
|
36
|
+
export interface GatewayQuota {
|
|
37
|
+
minuteRemaining: number;
|
|
38
|
+
dayRemaining: number;
|
|
39
|
+
dayTokensRemaining: number;
|
|
40
|
+
}
|
|
41
|
+
/** What one answer cost. */
|
|
42
|
+
export interface GatewayUsage {
|
|
43
|
+
promptTokens: number;
|
|
44
|
+
completionTokens: number;
|
|
45
|
+
totalTokens: number;
|
|
46
|
+
}
|
|
47
|
+
/** The `data:` payloads of a chat stream, before the `[DONE]` sentinel. */
|
|
48
|
+
export type GatewayStreamEvent = {
|
|
49
|
+
type: 'delta';
|
|
50
|
+
text: string;
|
|
51
|
+
} | {
|
|
52
|
+
type: 'done';
|
|
53
|
+
usage: GatewayUsage;
|
|
54
|
+
quota?: GatewayQuota;
|
|
55
|
+
} | {
|
|
56
|
+
type: 'error';
|
|
57
|
+
code: GatewayErrorCode;
|
|
58
|
+
};
|
|
59
|
+
/** The last `data:` line of a stream that completed. */
|
|
60
|
+
export declare const SSE_DONE_SENTINEL = "[DONE]";
|
|
61
|
+
export type SseDoneSentinel = typeof SSE_DONE_SENTINEL;
|
|
62
|
+
/** The `Retry-After` header, which a 429 always carries. */
|
|
63
|
+
export declare const RETRY_AFTER_HEADER = "Retry-After";
|
|
64
|
+
//# sourceMappingURL=gateway.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gateway.d.ts","sourceRoot":"","sources":["../../../../src/contract/gateway.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,uEAAuE;AACvE,MAAM,MAAM,gBAAgB,GACzB,aAAa,GACb,cAAc,GACd,cAAc,GACd,cAAc,GACd,aAAa,GACb,kBAAkB,GAClB,mBAAmB,GACnB,sBAAsB,GACtB,cAAc,GACd,eAAe,GACf,gBAAgB,GAChB,UAAU,CAAC;AAEd,8CAA8C;AAC9C,eAAO,MAAM,oBAAoB,EAAE,QAAQ,CAAC,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAa3E,CAAC;AAEF,kFAAkF;AAClF,MAAM,WAAW,gBAAgB;IAChC,KAAK,EAAE;QACN,IAAI,EAAE,gBAAgB,CAAC;QACvB,OAAO,EAAE,MAAM,CAAC;QAChB,iBAAiB,CAAC,EAAE,MAAM,CAAC;KAC3B,CAAC;CACF;AAED,4EAA4E;AAC5E,eAAO,MAAM,aAAa;;;;CAIhB,CAAC;AAEX,yFAAyF;AACzF,MAAM,MAAM,gBAAgB,GAAG,OAAO,aAAa,CAAC;AACpD,MAAM,MAAM,eAAe,GAAG,gBAAgB,CAAC,MAAM,gBAAgB,CAAC,CAAC;AAEvE,qEAAqE;AACrE,MAAM,WAAW,YAAY;IAC5B,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,EAAE,MAAM,CAAC;CAC3B;AAED,4BAA4B;AAC5B,MAAM,WAAW,YAAY;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;CACpB;AAED,2EAA2E;AAC3E,MAAM,MAAM,kBAAkB,GAC3B;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC/B;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,YAAY,CAAC;IAAC,KAAK,CAAC,EAAE,YAAY,CAAA;CAAE,GAC3D;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,gBAAgB,CAAA;CAAE,CAAC;AAE7C,wDAAwD;AACxD,eAAO,MAAM,iBAAiB,WAAW,CAAC;AAC1C,MAAM,MAAM,eAAe,GAAG,OAAO,iBAAiB,CAAC;AAEvD,4DAA4D;AAC5D,eAAO,MAAM,kBAAkB,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { type Scheduler } from '@chipmobilesdk/rn-core';
|
|
2
|
+
import { type AiConfigCache, type BehaviorState } from '../config/behaviorConfig.js';
|
|
3
|
+
import { type GatewayQuota, type GatewayUsage } from '../contract/gateway.js';
|
|
4
|
+
import { AiError } from '../diagnostics/errors.js';
|
|
5
|
+
import { type StreamTransport } from '../transport/sseClient.js';
|
|
6
|
+
import { type AiTimeouts } from '../transport/timeouts.js';
|
|
7
|
+
export interface AccessTokenRequestOptions {
|
|
8
|
+
/**
|
|
9
|
+
* Skip the cached token and ask the provider for a new one. Set after a 401:
|
|
10
|
+
* the cached token is valid by the clock and refused by the server, so asking
|
|
11
|
+
* again without this re-sends the token that was just rejected (AI-01).
|
|
12
|
+
*/
|
|
13
|
+
forceRefresh?: boolean;
|
|
14
|
+
}
|
|
15
|
+
/** Minimal slice of the rn-auth `Auth` controller the client needs. */
|
|
16
|
+
export interface TokenProvider {
|
|
17
|
+
requestAccessToken(resourceKey: string, options?: AccessTokenRequestOptions): Promise<{
|
|
18
|
+
status: string;
|
|
19
|
+
token?: string;
|
|
20
|
+
errorCode?: string;
|
|
21
|
+
}>;
|
|
22
|
+
}
|
|
23
|
+
export type ContentPart = {
|
|
24
|
+
type: 'text';
|
|
25
|
+
text: string;
|
|
26
|
+
} | {
|
|
27
|
+
type: 'image';
|
|
28
|
+
mimeType: string;
|
|
29
|
+
dataBase64: string;
|
|
30
|
+
} | {
|
|
31
|
+
type: 'audio';
|
|
32
|
+
format: 'wav' | 'mp3';
|
|
33
|
+
dataBase64: string;
|
|
34
|
+
};
|
|
35
|
+
export interface ChatMessage {
|
|
36
|
+
role: 'system' | 'user' | 'assistant';
|
|
37
|
+
content: ContentPart[];
|
|
38
|
+
}
|
|
39
|
+
export interface ChatRequest {
|
|
40
|
+
messages: ChatMessage[];
|
|
41
|
+
options?: {
|
|
42
|
+
temperature?: number;
|
|
43
|
+
maxOutputTokens?: number;
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
/** What one answer cost, as the gateway reports it. */
|
|
47
|
+
export type Usage = GatewayUsage;
|
|
48
|
+
/** What is left of the app's allowance. */
|
|
49
|
+
export type QuotaSnapshot = GatewayQuota;
|
|
50
|
+
export interface ChatStreamHandlers {
|
|
51
|
+
onDelta(text: string): void;
|
|
52
|
+
onDone(result: {
|
|
53
|
+
usage: Usage;
|
|
54
|
+
quota?: QuotaSnapshot;
|
|
55
|
+
}): void;
|
|
56
|
+
onError(error: AiError): void;
|
|
57
|
+
}
|
|
58
|
+
export interface ChatHandle {
|
|
59
|
+
cancel(): void;
|
|
60
|
+
}
|
|
61
|
+
export interface AiBehaviorState {
|
|
62
|
+
config: BehaviorState;
|
|
63
|
+
aiEnabled: boolean;
|
|
64
|
+
}
|
|
65
|
+
export interface AiClientConfig {
|
|
66
|
+
appId: string;
|
|
67
|
+
configUrl: string;
|
|
68
|
+
auth: TokenProvider;
|
|
69
|
+
/** rn-auth resource key configured for the gateway API scope. */
|
|
70
|
+
resourceKey?: string;
|
|
71
|
+
storage?: AiConfigCache;
|
|
72
|
+
fetchFn?: typeof fetch;
|
|
73
|
+
/** The streaming transport. Injected in tests, or to replace the XHR reader. */
|
|
74
|
+
transport?: StreamTransport;
|
|
75
|
+
/** Overrides for the network time limits; see `AiTimeouts` for the defaults. */
|
|
76
|
+
timeouts?: Partial<AiTimeouts>;
|
|
77
|
+
/** Test seam: how the backoff before a silent retry is waited out. */
|
|
78
|
+
scheduler?: Scheduler;
|
|
79
|
+
/**
|
|
80
|
+
* Hosts the remote config's `api.baseUrl` may name. A config document decides
|
|
81
|
+
* where this client sends its bearer token, so an app with a fixed deployment
|
|
82
|
+
* can pin it (AI-07).
|
|
83
|
+
*/
|
|
84
|
+
allowedHosts?: readonly string[];
|
|
85
|
+
}
|
|
86
|
+
export interface AiClient {
|
|
87
|
+
chat(request: ChatRequest, handlers: ChatStreamHandlers): ChatHandle;
|
|
88
|
+
getQuota(): Promise<QuotaSnapshot>;
|
|
89
|
+
/**
|
|
90
|
+
* The last quota this client saw, from a chat's `done` event or `getQuota`.
|
|
91
|
+
* Optional so an app's own `AiClient` keeps compiling.
|
|
92
|
+
*/
|
|
93
|
+
lastQuota?(): QuotaSnapshot | undefined;
|
|
94
|
+
/** The current behavior state; the same object until it changes. */
|
|
95
|
+
getBehaviorState(): AiBehaviorState;
|
|
96
|
+
/**
|
|
97
|
+
* Called whenever the behavior state or the last quota changes (AI-09, AI-13);
|
|
98
|
+
* returns the unsubscribe. Optional so an app's own `AiClient` keeps compiling.
|
|
99
|
+
*/
|
|
100
|
+
subscribe?(listener: () => void): () => void;
|
|
101
|
+
reloadConfig(): Promise<void>;
|
|
102
|
+
}
|
|
103
|
+
export declare function createAiClient(clientConfig: AiClientConfig): AiClient;
|
|
104
|
+
//# sourceMappingURL=aiClient.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aiClient.d.ts","sourceRoot":"","sources":["../../../../src/core/aiClient.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The quota request, and the recovery it shares with a chat (AI-13).
|
|
3
|
+
*
|
|
4
|
+
* `getQuota` used to be the one call with no recovery at all: a gateway that
|
|
5
|
+
* had moved answered 404 for quota while chats silently re-routed, so the
|
|
6
|
+
* figure on screen failed while the feature worked. It now goes through the
|
|
7
|
+
* same `recover` the chat stream does — a designated status reloads the
|
|
8
|
+
* configuration and retries, a 401 retries once with a token the provider had
|
|
9
|
+
* to fetch again.
|
|
10
|
+
*/
|
|
11
|
+
import type { AppBehaviorConfig } from '../config/behaviorConfig.js';
|
|
12
|
+
import { AiError } from '../diagnostics/errors.js';
|
|
13
|
+
import { type AiTimeouts } from '../transport/timeouts.js';
|
|
14
|
+
/** Where the quota request is in its recovery, shared with the chat path. */
|
|
15
|
+
export interface RecoveryState {
|
|
16
|
+
configReloads: number;
|
|
17
|
+
authRetries: number;
|
|
18
|
+
}
|
|
19
|
+
export interface QuotaRequestDeps {
|
|
20
|
+
fetchFn: typeof fetch;
|
|
21
|
+
timeouts: AiTimeouts;
|
|
22
|
+
acquire: (options?: {
|
|
23
|
+
forceRefresh?: boolean;
|
|
24
|
+
}) => Promise<{
|
|
25
|
+
config: AppBehaviorConfig;
|
|
26
|
+
token: string;
|
|
27
|
+
}>;
|
|
28
|
+
endpoint: (config: AppBehaviorConfig, path: 'chat' | 'quota') => string;
|
|
29
|
+
asQuota: (value: unknown) => QuotaSnapshot | undefined;
|
|
30
|
+
recover: (status: number, bodyText: string, state: RecoveryState, context: {
|
|
31
|
+
getHeader?: (name: string) => string | null;
|
|
32
|
+
}, retry: (next: RecoveryState) => void, onFailure: (error: unknown) => void, onGiveUp: (error: AiError) => void) => void;
|
|
33
|
+
report: (error: AiError) => void;
|
|
34
|
+
setQuota: (next: QuotaSnapshot | undefined) => void;
|
|
35
|
+
}
|
|
36
|
+
/** What is left of the app's allowance. */
|
|
37
|
+
export type QuotaSnapshot = {
|
|
38
|
+
minuteRemaining: number;
|
|
39
|
+
dayRemaining: number;
|
|
40
|
+
dayTokensRemaining: number;
|
|
41
|
+
};
|
|
42
|
+
export declare function createQuotaRequest(deps: QuotaRequestDeps): {
|
|
43
|
+
getQuota: () => Promise<QuotaSnapshot>;
|
|
44
|
+
};
|
|
45
|
+
//# sourceMappingURL=quotaRequest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quotaRequest.d.ts","sourceRoot":"","sources":["../../../../src/core/quotaRequest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA0B,CAAC;AAClE,OAAO,EAAE,OAAO,EAAE,MAAM,0BAAuB,CAAC;AAChD,OAAO,EAAe,KAAK,UAAU,EAAE,MAAM,0BAAuB,CAAC;AAErE,6EAA6E;AAC7E,MAAM,WAAW,aAAa;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB;IAChC,OAAO,EAAE,OAAO,KAAK,CAAC;IACtB,QAAQ,EAAE,UAAU,CAAC;IACrB,OAAO,EAAE,CAAC,OAAO,CAAC,EAAE;QAAE,YAAY,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,OAAO,CAAC;QAC1D,MAAM,EAAE,iBAAiB,CAAC;QAC1B,KAAK,EAAE,MAAM,CAAC;KACd,CAAC,CAAC;IACH,QAAQ,EAAE,CAAC,MAAM,EAAE,iBAAiB,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,KAAK,MAAM,CAAC;IACxE,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,aAAa,GAAG,SAAS,CAAC;IACvD,OAAO,EAAE,CACR,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,aAAa,EACpB,OAAO,EAAE;QAAE,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAA;KAAE,EACxD,KAAK,EAAE,CAAC,IAAI,EAAE,aAAa,KAAK,IAAI,EACpC,SAAS,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,EACnC,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,KAC9B,IAAI,CAAC;IACV,MAAM,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACjC,QAAQ,EAAE,CAAC,IAAI,EAAE,aAAa,GAAG,SAAS,KAAK,IAAI,CAAC;CACpD;AAED,2CAA2C;AAC3C,MAAM,MAAM,aAAa,GAAG;IAC3B,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,gBAAgB;oBAI7B,OAAO,CAAC,aAAa,CAAC;EAuEjD"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/** Typed client errors (contracts/rn-ai-public-api.md). */
|
|
2
|
+
import { SdkError } from '@chipmobilesdk/rn-core';
|
|
3
|
+
export type AiErrorCode = 'auth-invalid'
|
|
4
|
+
/** The session itself ended: the user has to sign in again. */
|
|
5
|
+
| 'session-expired' | 'not-entitled' | 'user-blocked' | 'app-unknown' | 'rate-limited' | 'upstream-busy' | 'payload-too-large' | 'modality-not-allowed' | 'config-unavailable'
|
|
6
|
+
/** The request never reached the gateway: no connection, a timeout, a dropped stream. */
|
|
7
|
+
| 'network' | 'upstream-error' | 'internal';
|
|
8
|
+
export interface AiErrorOptions {
|
|
9
|
+
retryAfterSeconds?: number | undefined;
|
|
10
|
+
/** Whether retrying can succeed. Defaults by code; see `RETRYABLE_BY_DEFAULT`. */
|
|
11
|
+
retryable?: boolean | undefined;
|
|
12
|
+
/** @deprecated Use `retryable`; accepted as its alias. */
|
|
13
|
+
recoverable?: boolean | undefined;
|
|
14
|
+
/**
|
|
15
|
+
* The code the layer underneath reported — an rn-auth `AuthErrorCode`, or the
|
|
16
|
+
* gateway's own code. Kept so a screen can say *why* rather than only *what*.
|
|
17
|
+
*/
|
|
18
|
+
cause?: string | undefined;
|
|
19
|
+
}
|
|
20
|
+
/** The package's error; an `SdkError` (`@chipmobilesdk/rn-core`) with `pkg: 'rn-ai'`. */
|
|
21
|
+
export declare class AiError extends SdkError<AiErrorCode> {
|
|
22
|
+
readonly retryAfterSeconds?: number | undefined;
|
|
23
|
+
/** The underlying code, when one layer down had a name for the failure. */
|
|
24
|
+
readonly cause?: string | undefined;
|
|
25
|
+
constructor(code: AiErrorCode, message: string, options?: AiErrorOptions);
|
|
26
|
+
/** @deprecated Use `retryable`, the name every SDK package shares. */
|
|
27
|
+
get recoverable(): boolean;
|
|
28
|
+
}
|
|
29
|
+
export declare function isAiError(value: unknown): value is AiError;
|
|
30
|
+
/** `Retry-After` in seconds, from either form the header may take. */
|
|
31
|
+
export declare function parseRetryAfter(value: string | null | undefined): number | undefined;
|
|
32
|
+
export interface HttpErrorContext {
|
|
33
|
+
/** The response headers, when the transport can read them. */
|
|
34
|
+
getHeader?: (name: string) => string | null | undefined;
|
|
35
|
+
}
|
|
36
|
+
/** Map a gateway error response (status + JSON body) to a typed AiError. */
|
|
37
|
+
export declare function errorFromHttp(status: number, bodyText: string, context?: HttpErrorContext): AiError;
|
|
38
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../../src/diagnostics/errors.ts"],"names":[],"mappings":"AAAA,2DAA2D;AAC3D,OAAO,EAAE,QAAQ,EAAkB,MAAM,wBAAwB,CAAC;AAQlE,MAAM,MAAM,WAAW,GACpB,cAAc;AAChB,+DAA+D;GAC7D,iBAAiB,GACjB,cAAc,GACd,cAAc,GACd,aAAa,GACb,cAAc,GACd,eAAe,GACf,mBAAmB,GACnB,sBAAsB,GACtB,oBAAoB;AACtB,yFAAyF;GACvF,SAAS,GACT,gBAAgB,GAChB,UAAU,CAAC;AAEd,MAAM,WAAW,cAAc;IAC9B,iBAAiB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,kFAAkF;IAClF,SAAS,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAChC,0DAA0D;IAC1D,WAAW,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAClC;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC3B;AASD,yFAAyF;AACzF,qBAAa,OAAQ,SAAQ,QAAQ,CAAC,WAAW,CAAC;IACjD,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChD,2EAA2E;IAC3E,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;gBAExB,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,cAAmB;IAU5E,sEAAsE;IACtE,IAAI,WAAW,IAAI,OAAO,CAEzB;CACD;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,OAAO,CAE1D;AA0BD,sEAAsE;AACtE,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAapF;AAED,MAAM,WAAW,gBAAgB;IAChC,8DAA8D;IAC9D,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;CACxD;AAED,4EAA4E;AAC5E,wBAAgB,aAAa,CAC5B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,gBAAqB,GAC5B,OAAO,CA4BT"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { AiError } from './errors.js';
|
|
2
|
+
export declare const aiMessageSet: import("@chipmobilesdk/rn-core").MessageSet<{
|
|
3
|
+
'ai.state.loading': string;
|
|
4
|
+
'ai.state.streaming': string;
|
|
5
|
+
'ai.input.placeholder': string;
|
|
6
|
+
'ai.action.send': string;
|
|
7
|
+
'ai.action.cancel': string;
|
|
8
|
+
'ai.action.retry': string;
|
|
9
|
+
'ai.action.retryAt': string;
|
|
10
|
+
'ai.quota.remaining': string;
|
|
11
|
+
'ai.error.rateLimited': string;
|
|
12
|
+
'ai.error.premiumRequired': string;
|
|
13
|
+
'ai.error.blocked': string;
|
|
14
|
+
'ai.error.payloadTooLarge': string;
|
|
15
|
+
'ai.error.modality': string;
|
|
16
|
+
'ai.error.busy': string;
|
|
17
|
+
'ai.error.unavailable': string;
|
|
18
|
+
'ai.error.signIn': string;
|
|
19
|
+
'ai.error.offline': string;
|
|
20
|
+
'ai.error.generic': string;
|
|
21
|
+
}, Record<never, string>>;
|
|
22
|
+
export declare const aiMessages: Readonly<{
|
|
23
|
+
'ai.state.loading': string;
|
|
24
|
+
'ai.state.streaming': string;
|
|
25
|
+
'ai.input.placeholder': string;
|
|
26
|
+
'ai.action.send': string;
|
|
27
|
+
'ai.action.cancel': string;
|
|
28
|
+
'ai.action.retry': string;
|
|
29
|
+
'ai.action.retryAt': string;
|
|
30
|
+
'ai.quota.remaining': string;
|
|
31
|
+
'ai.error.rateLimited': string;
|
|
32
|
+
'ai.error.premiumRequired': string;
|
|
33
|
+
'ai.error.blocked': string;
|
|
34
|
+
'ai.error.payloadTooLarge': string;
|
|
35
|
+
'ai.error.modality': string;
|
|
36
|
+
'ai.error.busy': string;
|
|
37
|
+
'ai.error.unavailable': string;
|
|
38
|
+
'ai.error.signIn': string;
|
|
39
|
+
'ai.error.offline': string;
|
|
40
|
+
'ai.error.generic': string;
|
|
41
|
+
} & Record<never, string>>;
|
|
42
|
+
export type AiMessageKey = keyof typeof aiMessages;
|
|
43
|
+
export declare function aiMessage(key: AiMessageKey): string;
|
|
44
|
+
/** The message key to show a user for an error. */
|
|
45
|
+
export declare function messageKeyForError(error: AiError): AiMessageKey;
|
|
46
|
+
//# sourceMappingURL=messageKeys.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messageKeys.d.ts","sourceRoot":"","sources":["../../../../src/diagnostics/messageKeys.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAU,CAAC;AAExC,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;yBAsBvB,CAAC;AAEH,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;0BAAwB,CAAC;AAEhD,MAAM,MAAM,YAAY,GAAG,MAAM,OAAO,UAAU,CAAC;AAEnD,wBAAgB,SAAS,CAAC,GAAG,EAAE,YAAY,GAAG,MAAM,CAEnD;AAsBD,mDAAmD;AACnD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,YAAY,CAE/D"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @chipmobilesdk/rn-ai — AI gateway client for ChipMobileSdk-family React
|
|
3
|
+
* Native apps (feature 005). Single public entrypoint (LIB-003); modules
|
|
4
|
+
* under `config/`, `transport/`, `core/`, `react/`, and `diagnostics/` are
|
|
5
|
+
* private. Contract: specs/005-azure-ai-gateway/contracts/rn-ai-public-api.md
|
|
6
|
+
*/
|
|
7
|
+
export { createAiClient } from './core/aiClient.js';
|
|
8
|
+
export type { AiClient, AiClientConfig, AiBehaviorState, TokenProvider, AccessTokenRequestOptions, ChatRequest, ChatMessage, ContentPart, ChatStreamHandlers, ChatHandle, Usage, QuotaSnapshot, } from './core/aiClient.js';
|
|
9
|
+
export type { AppBehaviorConfig, AiConfigCache, BehaviorState } from './config/behaviorConfig.js';
|
|
10
|
+
export { configCacheFromKeyValue, SUPPORTED_SCHEMA_VERSION } from './config/behaviorConfig.js';
|
|
11
|
+
export type { GatewayErrorCode, GatewayErrorBody, GatewayQuota, GatewayStreamEvent, GatewayUsage, QuotaHeaderName, QuotaHeaderNames, } from './contract/gateway.js';
|
|
12
|
+
export { GATEWAY_ERROR_STATUS, QUOTA_HEADERS, SSE_DONE_SENTINEL } from './contract/gateway.js';
|
|
13
|
+
export type { AiTimeouts } from './transport/timeouts.js';
|
|
14
|
+
export type { SseRequest, SseHandlers, SseHandle, SseResponseInfo, StreamTransport, } from './transport/sseClient.js';
|
|
15
|
+
export { useAiBehaviorState, useAiChat, useAiQuota } from './react/hooks.js';
|
|
16
|
+
export type { AiChatStatus, UseAiChatOptions, UseAiChatResult, UseAiQuotaResult, } from './react/hooks.js';
|
|
17
|
+
export { AiError, isAiError } from './diagnostics/errors.js';
|
|
18
|
+
export type { AiErrorCode } from './diagnostics/errors.js';
|
|
19
|
+
export { aiMessage, aiMessageSet, aiMessages, messageKeyForError } from './diagnostics/messageKeys.js';
|
|
20
|
+
export type { AiMessageKey } from './diagnostics/messageKeys.js';
|
|
21
|
+
//# sourceMappingURL=index.d.ts.map
|