@chipmobilesdk/rn-ai
v0.1.1
Published
AI gateway client for ChipMobileSdk-family React Native apps. Streams multimodal (text + image + audio in, text out) AI responses through the platform gateway with per-user rate limiting — apps never talk to Azure OpenAI directly and hold no AI credent
Readme
@chipmobilesdk/rn-ai
AI gateway client for ChipMobileSdk-family React Native apps. Streams multimodal (text + image + audio in, text out) AI responses through the platform gateway with per-user rate limiting — apps never talk to Azure OpenAI directly and hold no AI credentials.
License:
UNLICENSED. Published publicly for use by the owner's applications; no open-source license is granted.
Version:
0.1.0Entrypoint:
@chipmobilesdk/rn-aiNative code: none
Contract: rn-ai-public-api
Gateway API: gateway-api
Behavior config: app-behavior-config
Install
npm install @chipmobilesdk/rn-ai @chipmobilesdk/rn-authPeers: react >=19, react-native >=0.85, @chipmobilesdk/rn-auth >=0.2.0.
Zero runtime dependencies; streaming uses React Native's standard
XMLHttpRequest (no native code, Hermes-compatible, iOS + Android).
Setup
- Add the gateway resource to your rn-auth config:
resources: [
{ key: 'ai-gateway', scopes: ['api://aiapp-gateway/AI.Access'] },
]- Create the client (one per app):
import { createAiClient } from '@chipmobilesdk/rn-ai';
import { auth } from './auth/setup';
export const aiClient = createAiClient({
appId: 'scan-food',
configUrl: 'https://<config-host>/appconfig/config/scan-food.json',
resourceKey: 'ai-gateway',
auth,
// storage: inject a persistent AiConfigCache for offline launches
});- Use the hooks:
import { useAiChat, useAiQuota } from '@chipmobilesdk/rn-ai';
import { aiClient } from './ai/setup';
const { send, cancel, status, text, error, retryAt } = useAiChat(aiClient);
const { quota } = useAiQuota(aiClient);
send({
messages: [{
role: 'user',
content: [
{ type: 'text', text: 'What dish is this? Estimate calories.' },
{ type: 'image', mimeType: 'image/jpeg', dataBase64: photoBase64 },
],
}],
});Runtime behavior
- Config-driven endpoint: resolved lazily on the first quota or chat
request. A fresh cache entry is used immediately; a stale entry is used
immediately and revalidated in the background with its ETag. With no cache,
the first operation waits for the config request. Designated
404/410responses invalidate config and retry against the refreshed endpoint. - Auth: acquires tokens via rn-auth (
requestAccessToken('ai-gateway')); on401, reacquires a token and retries once. - Rate limits:
429surfaces asstatus: 'rate-limited'withretryAt; the SDK never hammers and never enforces limits locally (display only). - Typed errors (
AiError.code):auth-invalid,not-entitled,user-blocked,app-unknown,rate-limited,upstream-busy,payload-too-large,modality-not-allowed,config-unavailable,upstream-error,internal. - Copy keys:
ai.*defaults inaiMessages— map through your i18n.
Public API
Everything is exported from @chipmobilesdk/rn-ai; internal config/,
transport/, core/, react/, and diagnostics/ paths are not public.
- Client:
createAiClient,AiClient,AiClientConfig,TokenProvider - Chat:
ChatRequest,ChatMessage,ContentPart,ChatStreamHandlers,ChatHandle,Usage - Behavior and cache:
AppBehaviorConfig,AiBehaviorState,BehaviorState,AiConfigCache,QuotaSnapshot - React:
useAiChat,useAiQuota,AiChatStatus,UseAiChatResult,UseAiQuotaResult - Diagnostics and copy:
AiError,AiErrorCode,isAiError,aiMessages,aiMessage,AiMessageKey
App responsibilities
- AI disclosure (store policy): user text/images/audio are processed by the platform's AI service. Update your privacy policy, Apple App Privacy, and Google Play Data Safety before shipping, and disclose AI processing in-app (POL-005/006 in the feature spec).
- Camera/microphone permissions for capture UIs are yours; the SDK only accepts already-captured data and adds no permissions.
- Respect
payload-too-large(default cap 10 MB/request) by resizing images and bounding audio length.
Compatibility
React ≥19 · React Native ≥0.85 (Hermes) · iOS + Android · Node ≥22.11 for tooling.
The repository contains src/screens/AiDemoScreen.tsx and its component test.
The current demo sidebar does not expose that screen yet, so it must be wired
into ScreenKey, Sidebar, and ActiveScreen before it is reachable in-app.
Validation
Run from the repository root:
npm run typecheck:ai
npm run pack:ai
npm run validate:ai