@amaster.ai/client 1.1.0-beta.50 → 1.1.0-beta.52

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/index.cjs CHANGED
@@ -131,7 +131,8 @@ function createClient(options) {
131
131
  getAccessToken: () => auth.getAccessToken()
132
132
  });
133
133
  const asrHttp = asrClient.createASRHttpClient({
134
- getAccessToken: () => auth.getAccessToken()
134
+ getAccessToken: () => auth.getAccessToken(),
135
+ http: authenticatedHttpClient
135
136
  });
136
137
  const tts = ttsClient.createTTSClient({
137
138
  getAccessToken: () => auth.getAccessToken()
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/client.ts"],"names":["createHttpClient","createAuthClient","createEntityClient","createBpmClient","createWorkflowClient","functionClient","createFunctionClient","createCopilotClient","createS3Client","createASRClient","createASRHttpClient","createTTSClient"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * ============================================================================\n * @amaster.ai/client - Unified Amaster Client\n * ============================================================================\n *\n * Supabase-inspired unified API client for the Amaster platform\n *\n * Features:\n * - Single client instance for all services (auth, entity, bpm, workflow)\n * - Automatic token management and refresh\n * - Auto-attach authentication to all requests\n * - Centralized error handling\n *\n * @example\n * ```typescript\n * // With explicit baseURL\n * const client = createClient({\n * baseURL: 'https://api.amaster.ai',\n * onUnauthorized: () => window.location.href = '/login'\n * });\n *\n * // Auto-detect baseURL from env (Taro/Mini-program)\n * const client = createClient({\n * onUnauthorized: () => window.location.href = '/login'\n * });\n *\n * // Login\n * await client.auth.login({ email, password });\n *\n * // All subsequent requests automatically include auth token\n * await client.entity.list('default', 'users');\n * await client.bpm.startProcess({ processKey: 'approval' });\n * ```\n */\n\nimport { createAuthClient, type AuthClient } from \"@amaster.ai/auth-client\";\nimport { createEntityClient, type EntityClient } from \"@amaster.ai/entity-client\";\nimport { createBpmClient, type BpmClient } from \"@amaster.ai/bpm-client\";\nimport { createWorkflowClient, type WorkflowClient } from \"@amaster.ai/workflow-client\";\nimport {\n createASRClient,\n createASRHttpClient,\n type ASRClientConfig,\n type ASRClient,\n type ASRHttpClientConfig,\n type ASRHttpClient,\n} from \"@amaster.ai/asr-client\";\nimport { createCopilotClient, type CopilotClient } from \"@amaster.ai/copilot-client\";\nimport { createFunctionClient, type FunctionClient } from \"@amaster.ai/function-client\";\nimport { createTTSClient, TTSClientConfig, type TTSClient } from \"@amaster.ai/tts-client\";\nimport { createS3Client, type S3Client } from \"@amaster.ai/s3-client\";\nimport {\n createHttpClient,\n type HttpClient,\n type RequestConfig,\n type ClientResult,\n} from \"@amaster.ai/http-client\";\nimport type { AmasterClient, AmasterClientOptions } from \"./types\";\n\n/**\n * Create a unified Amaster client instance\n *\n * This function creates a single client that provides access to all Amaster services:\n * - Authentication (login, register, logout)\n * - Entity CRUD operations\n * - BPM (Business Process Management)\n * - Workflow execution\n *\n * All sub-clients automatically share the same HTTP client and authentication state,\n * ensuring that tokens are consistently attached to all requests.\n *\n * @param options - Client configuration options\n * @returns A unified Amaster client instance\n *\n * @example\n * ```typescript\n * // Basic usage with explicit baseURL\n * const client = createClient({\n * baseURL: 'https://api.amaster.ai'\n * });\n *\n * // Auto-detect baseURL (for Taro/Mini-program or dev proxy)\n * const client = createClient({});\n *\n * // With authentication callbacks\n * const client = createClient({\n * baseURL: 'https://api.amaster.ai',\n * onUnauthorized: () => {\n * // Redirect to login or show auth modal\n * window.location.href = '/login';\n * },\n * onTokenExpired: () => {\n * console.log('Token expired, refreshing...');\n * }\n * });\n *\n * // Login\n * await client.auth.login({\n * email: 'user@example.com',\n * password: 'password123'\n * });\n *\n * // Now all requests automatically include the auth token\n * const users = await client.entity.list('default', 'users');\n * const tasks = await client.bpm.getMyTasks();\n * ```\n */\nexport function createClient(options: AmasterClientOptions): AmasterClient {\n const {\n baseURL,\n headers = {},\n onUnauthorized,\n onTokenExpired,\n autoHandleOAuthCallback,\n } = options;\n\n // Create the base HTTP client\n const baseHttpClient = createHttpClient({\n baseURL,\n headers,\n });\n\n // Create the auth client first (it manages its own HTTP client internally)\n const auth: AuthClient = createAuthClient({\n baseURL,\n headers,\n onTokenExpired,\n onUnauthorized,\n autoHandleOAuthCallback,\n });\n\n // Create a wrapper HTTP client that automatically adds the auth token\n const createAuthenticatedHttpClient = (): HttpClient => {\n // Track if we're currently refreshing to avoid multiple simultaneous refreshes\n let isRefreshing = false;\n let refreshPromise: Promise<boolean> | null = null;\n\n /**\n * Check if 401 error is due to token expiration\n * Traefik JWT plugin returns plain text like \"Jwt is expired\" or \"Token is expired\"\n */\n function isTokenExpired(result: ClientResult<unknown>): boolean {\n if (result.status !== 401) return false;\n\n // Check error message (could be from backend JSON response)\n if (result.error?.message && /expired/i.test(result.error.message)) {\n return true;\n }\n\n // Check error details (traefik returns plain text in details)\n if (result.error?.details) {\n const details = result.error.details;\n if (typeof details === \"string\" && /expired/i.test(details)) {\n return true;\n }\n // Also check if details is an object with message field\n if (typeof details === \"object\" && details !== null) {\n const detailsObj = details as Record<string, unknown>;\n if (typeof detailsObj.message === \"string\" && /expired/i.test(detailsObj.message)) {\n return true;\n }\n }\n }\n\n // Check raw data (could be plain text from traefik)\n if (typeof result.data === \"string\" && /expired/i.test(result.data)) {\n return true;\n }\n\n // If we have a token but got 401, assume it might be expired\n return !!auth.getAccessToken();\n }\n\n return {\n async request<T>(config: RequestConfig): Promise<ClientResult<T>> {\n // Get the current token from auth client\n const token = auth.getAccessToken();\n\n // Merge Authorization header with existing headers\n const authHeaders = token ? { Authorization: `Bearer ${token}` } : {};\n const mergedConfig: RequestConfig = {\n ...config,\n headers: {\n ...config.headers,\n ...authHeaders,\n },\n };\n\n // Make the request with the updated config\n let result = await baseHttpClient.request<T>(mergedConfig);\n\n // Handle 401 errors with automatic token refresh\n if (result.status === 401 && isTokenExpired(result)) {\n // Attempt to refresh token\n if (!isRefreshing) {\n isRefreshing = true;\n refreshPromise = (async () => {\n try {\n const refreshResult = await auth.refreshToken();\n return !!refreshResult.data;\n } finally {\n isRefreshing = false;\n refreshPromise = null;\n }\n })();\n }\n\n const refreshed = await refreshPromise;\n\n if (refreshed) {\n // Retry with new token\n const newToken = auth.getAccessToken();\n result = await baseHttpClient.request<T>({\n ...config,\n headers: {\n ...config.headers,\n ...(newToken ? { Authorization: `Bearer ${newToken}` } : {}),\n },\n });\n }\n }\n\n // Trigger unauthorized if still 401\n if (result.status === 401 && onUnauthorized) {\n onUnauthorized();\n }\n\n return result;\n },\n };\n };\n\n const authenticatedHttpClient = createAuthenticatedHttpClient();\n\n let cachedUserUid: string | null = null;\n\n auth.on(\"login\", (user: { uid?: string }) => {\n cachedUserUid = user?.uid ?? null;\n });\n auth.on(\"logout\", () => {\n cachedUserUid = null;\n });\n\n if (auth.isAuthenticated()) {\n auth\n .getMe()\n .then((result) => {\n if (result.data?.uid) {\n cachedUserUid = result.data.uid;\n }\n })\n .catch(() => {});\n }\n\n // Create other clients using the authenticated HTTP client\n const entity: EntityClient = createEntityClient(authenticatedHttpClient);\n const bpm: BpmClient = createBpmClient(authenticatedHttpClient);\n const workflow: WorkflowClient = createWorkflowClient(authenticatedHttpClient);\n const functionClient: FunctionClient = createFunctionClient(authenticatedHttpClient);\n const copilot: CopilotClient = createCopilotClient(\n authenticatedHttpClient,\n baseURL,\n () => auth.getAccessToken(),\n () => cachedUserUid\n );\n const s3: S3Client = createS3Client(authenticatedHttpClient);\n\n // ASR and TTS clients use WebSocket, pass token getter for authentication\n // Token can be appended to WebSocket URL as query parameter\n const asr: (config: ASRClientConfig) => ASRClient = createASRClient({\n getAccessToken: () => auth.getAccessToken(),\n });\n const asrHttp: (config: ASRHttpClientConfig) => ASRHttpClient = createASRHttpClient({\n getAccessToken: () => auth.getAccessToken(),\n });\n const tts: (config: TTSClientConfig) => TTSClient = createTTSClient({\n getAccessToken: () => auth.getAccessToken(),\n });\n\n // Return unified client interface\n const client: AmasterClient = {\n auth,\n entity,\n bpm,\n workflow,\n asr,\n asrHttp,\n copilot,\n function: functionClient,\n tts,\n s3,\n http: authenticatedHttpClient,\n\n // Expose token management methods from auth client\n isAuthenticated: () => auth.isAuthenticated(),\n getAccessToken: () => auth.getAccessToken(),\n setAccessToken: (token: string) => auth.setAccessToken(token),\n clearAuth: () => auth.clearAuth(),\n };\n\n return client;\n}\n"]}
1
+ {"version":3,"sources":["../src/client.ts"],"names":["createHttpClient","createAuthClient","createEntityClient","createBpmClient","createWorkflowClient","functionClient","createFunctionClient","createCopilotClient","createS3Client","createASRClient","createASRHttpClient","createTTSClient"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * ============================================================================\n * @amaster.ai/client - Unified Amaster Client\n * ============================================================================\n *\n * Supabase-inspired unified API client for the Amaster platform\n *\n * Features:\n * - Single client instance for all services (auth, entity, bpm, workflow)\n * - Automatic token management and refresh\n * - Auto-attach authentication to all requests\n * - Centralized error handling\n *\n * @example\n * ```typescript\n * // With explicit baseURL\n * const client = createClient({\n * baseURL: 'https://api.amaster.ai',\n * onUnauthorized: () => window.location.href = '/login'\n * });\n *\n * // Auto-detect baseURL from env (Taro/Mini-program)\n * const client = createClient({\n * onUnauthorized: () => window.location.href = '/login'\n * });\n *\n * // Login\n * await client.auth.login({ email, password });\n *\n * // All subsequent requests automatically include auth token\n * await client.entity.list('default', 'users');\n * await client.bpm.startProcess({ processKey: 'approval' });\n * ```\n */\n\nimport { createAuthClient, type AuthClient } from \"@amaster.ai/auth-client\";\nimport { createEntityClient, type EntityClient } from \"@amaster.ai/entity-client\";\nimport { createBpmClient, type BpmClient } from \"@amaster.ai/bpm-client\";\nimport { createWorkflowClient, type WorkflowClient } from \"@amaster.ai/workflow-client\";\nimport {\n createASRClient,\n createASRHttpClient,\n type ASRClientConfig,\n type ASRClient,\n type ASRHttpClientConfig,\n type ASRHttpClient,\n} from \"@amaster.ai/asr-client\";\nimport { createCopilotClient, type CopilotClient } from \"@amaster.ai/copilot-client\";\nimport { createFunctionClient, type FunctionClient } from \"@amaster.ai/function-client\";\nimport { createTTSClient, TTSClientConfig, type TTSClient } from \"@amaster.ai/tts-client\";\nimport { createS3Client, type S3Client } from \"@amaster.ai/s3-client\";\nimport {\n createHttpClient,\n type HttpClient,\n type RequestConfig,\n type ClientResult,\n} from \"@amaster.ai/http-client\";\nimport type { AmasterClient, AmasterClientOptions } from \"./types\";\n\n/**\n * Create a unified Amaster client instance\n *\n * This function creates a single client that provides access to all Amaster services:\n * - Authentication (login, register, logout)\n * - Entity CRUD operations\n * - BPM (Business Process Management)\n * - Workflow execution\n *\n * All sub-clients automatically share the same HTTP client and authentication state,\n * ensuring that tokens are consistently attached to all requests.\n *\n * @param options - Client configuration options\n * @returns A unified Amaster client instance\n *\n * @example\n * ```typescript\n * // Basic usage with explicit baseURL\n * const client = createClient({\n * baseURL: 'https://api.amaster.ai'\n * });\n *\n * // Auto-detect baseURL (for Taro/Mini-program or dev proxy)\n * const client = createClient({});\n *\n * // With authentication callbacks\n * const client = createClient({\n * baseURL: 'https://api.amaster.ai',\n * onUnauthorized: () => {\n * // Redirect to login or show auth modal\n * window.location.href = '/login';\n * },\n * onTokenExpired: () => {\n * console.log('Token expired, refreshing...');\n * }\n * });\n *\n * // Login\n * await client.auth.login({\n * email: 'user@example.com',\n * password: 'password123'\n * });\n *\n * // Now all requests automatically include the auth token\n * const users = await client.entity.list('default', 'users');\n * const tasks = await client.bpm.getMyTasks();\n * ```\n */\nexport function createClient(options: AmasterClientOptions): AmasterClient {\n const {\n baseURL,\n headers = {},\n onUnauthorized,\n onTokenExpired,\n autoHandleOAuthCallback,\n } = options;\n\n // Create the base HTTP client\n const baseHttpClient = createHttpClient({\n baseURL,\n headers,\n });\n\n // Create the auth client first (it manages its own HTTP client internally)\n const auth: AuthClient = createAuthClient({\n baseURL,\n headers,\n onTokenExpired,\n onUnauthorized,\n autoHandleOAuthCallback,\n });\n\n // Create a wrapper HTTP client that automatically adds the auth token\n const createAuthenticatedHttpClient = (): HttpClient => {\n // Track if we're currently refreshing to avoid multiple simultaneous refreshes\n let isRefreshing = false;\n let refreshPromise: Promise<boolean> | null = null;\n\n /**\n * Check if 401 error is due to token expiration\n * Traefik JWT plugin returns plain text like \"Jwt is expired\" or \"Token is expired\"\n */\n function isTokenExpired(result: ClientResult<unknown>): boolean {\n if (result.status !== 401) return false;\n\n // Check error message (could be from backend JSON response)\n if (result.error?.message && /expired/i.test(result.error.message)) {\n return true;\n }\n\n // Check error details (traefik returns plain text in details)\n if (result.error?.details) {\n const details = result.error.details;\n if (typeof details === \"string\" && /expired/i.test(details)) {\n return true;\n }\n // Also check if details is an object with message field\n if (typeof details === \"object\" && details !== null) {\n const detailsObj = details as Record<string, unknown>;\n if (typeof detailsObj.message === \"string\" && /expired/i.test(detailsObj.message)) {\n return true;\n }\n }\n }\n\n // Check raw data (could be plain text from traefik)\n if (typeof result.data === \"string\" && /expired/i.test(result.data)) {\n return true;\n }\n\n // If we have a token but got 401, assume it might be expired\n return !!auth.getAccessToken();\n }\n\n return {\n async request<T>(config: RequestConfig): Promise<ClientResult<T>> {\n // Get the current token from auth client\n const token = auth.getAccessToken();\n\n // Merge Authorization header with existing headers\n const authHeaders = token ? { Authorization: `Bearer ${token}` } : {};\n const mergedConfig: RequestConfig = {\n ...config,\n headers: {\n ...config.headers,\n ...authHeaders,\n },\n };\n\n // Make the request with the updated config\n let result = await baseHttpClient.request<T>(mergedConfig);\n\n // Handle 401 errors with automatic token refresh\n if (result.status === 401 && isTokenExpired(result)) {\n // Attempt to refresh token\n if (!isRefreshing) {\n isRefreshing = true;\n refreshPromise = (async () => {\n try {\n const refreshResult = await auth.refreshToken();\n return !!refreshResult.data;\n } finally {\n isRefreshing = false;\n refreshPromise = null;\n }\n })();\n }\n\n const refreshed = await refreshPromise;\n\n if (refreshed) {\n // Retry with new token\n const newToken = auth.getAccessToken();\n result = await baseHttpClient.request<T>({\n ...config,\n headers: {\n ...config.headers,\n ...(newToken ? { Authorization: `Bearer ${newToken}` } : {}),\n },\n });\n }\n }\n\n // Trigger unauthorized if still 401\n if (result.status === 401 && onUnauthorized) {\n onUnauthorized();\n }\n\n return result;\n },\n };\n };\n\n const authenticatedHttpClient = createAuthenticatedHttpClient();\n\n let cachedUserUid: string | null = null;\n\n auth.on(\"login\", (user: { uid?: string }) => {\n cachedUserUid = user?.uid ?? null;\n });\n auth.on(\"logout\", () => {\n cachedUserUid = null;\n });\n\n if (auth.isAuthenticated()) {\n auth\n .getMe()\n .then((result) => {\n if (result.data?.uid) {\n cachedUserUid = result.data.uid;\n }\n })\n .catch(() => {});\n }\n\n // Create other clients using the authenticated HTTP client\n const entity: EntityClient = createEntityClient(authenticatedHttpClient);\n const bpm: BpmClient = createBpmClient(authenticatedHttpClient);\n const workflow: WorkflowClient = createWorkflowClient(authenticatedHttpClient);\n const functionClient: FunctionClient = createFunctionClient(authenticatedHttpClient);\n const copilot: CopilotClient = createCopilotClient(\n authenticatedHttpClient,\n baseURL,\n () => auth.getAccessToken(),\n () => cachedUserUid\n );\n const s3: S3Client = createS3Client(authenticatedHttpClient);\n\n // ASR and TTS clients use WebSocket, pass token getter for authentication\n // Token can be appended to WebSocket URL as query parameter\n const asr: (config: ASRClientConfig) => ASRClient = createASRClient({\n getAccessToken: () => auth.getAccessToken(),\n });\n const asrHttp: (config: ASRHttpClientConfig) => ASRHttpClient = createASRHttpClient({\n getAccessToken: () => auth.getAccessToken(),\n http: authenticatedHttpClient,\n });\n const tts: (config: TTSClientConfig) => TTSClient = createTTSClient({\n getAccessToken: () => auth.getAccessToken(),\n });\n\n // Return unified client interface\n const client: AmasterClient = {\n auth,\n entity,\n bpm,\n workflow,\n asr,\n asrHttp,\n copilot,\n function: functionClient,\n tts,\n s3,\n http: authenticatedHttpClient,\n\n // Expose token management methods from auth client\n isAuthenticated: () => auth.isAuthenticated(),\n getAccessToken: () => auth.getAccessToken(),\n setAccessToken: (token: string) => auth.setAccessToken(token),\n clearAuth: () => auth.clearAuth(),\n };\n\n return client;\n}\n"]}
package/dist/index.d.cts CHANGED
@@ -7,7 +7,7 @@ export { ActivityInstanceTree, CamundaVariable, HistoryActivityInstance, History
7
7
  import { WorkflowClient } from '@amaster.ai/workflow-client';
8
8
  export { WorkflowFile, WorkflowInputValue, WorkflowRunRequest, WorkflowRunResponse } from '@amaster.ai/workflow-client';
9
9
  import { ASRClientConfig, ASRClient, ASRHttpClientConfig, ASRHttpClient } from '@amaster.ai/asr-client';
10
- export { ASRClient, ASRClientConfig, ASRHttpClient, ASRHttpClientConfig } from '@amaster.ai/asr-client';
10
+ export { ASRClient, ASRClientConfig, ASRHttpClient, ASRHttpClientConfig, ASRLanguage } from '@amaster.ai/asr-client';
11
11
  import { CopilotClient } from '@amaster.ai/copilot-client';
12
12
  export { ChatMessage, ChatOptions, CopilotClient, FileContent, ImageContent, MessageContent, TextContent } from '@amaster.ai/copilot-client';
13
13
  import { FunctionClient } from '@amaster.ai/function-client';
package/dist/index.d.ts CHANGED
@@ -7,7 +7,7 @@ export { ActivityInstanceTree, CamundaVariable, HistoryActivityInstance, History
7
7
  import { WorkflowClient } from '@amaster.ai/workflow-client';
8
8
  export { WorkflowFile, WorkflowInputValue, WorkflowRunRequest, WorkflowRunResponse } from '@amaster.ai/workflow-client';
9
9
  import { ASRClientConfig, ASRClient, ASRHttpClientConfig, ASRHttpClient } from '@amaster.ai/asr-client';
10
- export { ASRClient, ASRClientConfig, ASRHttpClient, ASRHttpClientConfig } from '@amaster.ai/asr-client';
10
+ export { ASRClient, ASRClientConfig, ASRHttpClient, ASRHttpClientConfig, ASRLanguage } from '@amaster.ai/asr-client';
11
11
  import { CopilotClient } from '@amaster.ai/copilot-client';
12
12
  export { ChatMessage, ChatOptions, CopilotClient, FileContent, ImageContent, MessageContent, TextContent } from '@amaster.ai/copilot-client';
13
13
  import { FunctionClient } from '@amaster.ai/function-client';
package/dist/index.js CHANGED
@@ -129,7 +129,8 @@ function createClient(options) {
129
129
  getAccessToken: () => auth.getAccessToken()
130
130
  });
131
131
  const asrHttp = createASRHttpClient({
132
- getAccessToken: () => auth.getAccessToken()
132
+ getAccessToken: () => auth.getAccessToken(),
133
+ http: authenticatedHttpClient
133
134
  });
134
135
  const tts = createTTSClient({
135
136
  getAccessToken: () => auth.getAccessToken()
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/client.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * ============================================================================\n * @amaster.ai/client - Unified Amaster Client\n * ============================================================================\n *\n * Supabase-inspired unified API client for the Amaster platform\n *\n * Features:\n * - Single client instance for all services (auth, entity, bpm, workflow)\n * - Automatic token management and refresh\n * - Auto-attach authentication to all requests\n * - Centralized error handling\n *\n * @example\n * ```typescript\n * // With explicit baseURL\n * const client = createClient({\n * baseURL: 'https://api.amaster.ai',\n * onUnauthorized: () => window.location.href = '/login'\n * });\n *\n * // Auto-detect baseURL from env (Taro/Mini-program)\n * const client = createClient({\n * onUnauthorized: () => window.location.href = '/login'\n * });\n *\n * // Login\n * await client.auth.login({ email, password });\n *\n * // All subsequent requests automatically include auth token\n * await client.entity.list('default', 'users');\n * await client.bpm.startProcess({ processKey: 'approval' });\n * ```\n */\n\nimport { createAuthClient, type AuthClient } from \"@amaster.ai/auth-client\";\nimport { createEntityClient, type EntityClient } from \"@amaster.ai/entity-client\";\nimport { createBpmClient, type BpmClient } from \"@amaster.ai/bpm-client\";\nimport { createWorkflowClient, type WorkflowClient } from \"@amaster.ai/workflow-client\";\nimport {\n createASRClient,\n createASRHttpClient,\n type ASRClientConfig,\n type ASRClient,\n type ASRHttpClientConfig,\n type ASRHttpClient,\n} from \"@amaster.ai/asr-client\";\nimport { createCopilotClient, type CopilotClient } from \"@amaster.ai/copilot-client\";\nimport { createFunctionClient, type FunctionClient } from \"@amaster.ai/function-client\";\nimport { createTTSClient, TTSClientConfig, type TTSClient } from \"@amaster.ai/tts-client\";\nimport { createS3Client, type S3Client } from \"@amaster.ai/s3-client\";\nimport {\n createHttpClient,\n type HttpClient,\n type RequestConfig,\n type ClientResult,\n} from \"@amaster.ai/http-client\";\nimport type { AmasterClient, AmasterClientOptions } from \"./types\";\n\n/**\n * Create a unified Amaster client instance\n *\n * This function creates a single client that provides access to all Amaster services:\n * - Authentication (login, register, logout)\n * - Entity CRUD operations\n * - BPM (Business Process Management)\n * - Workflow execution\n *\n * All sub-clients automatically share the same HTTP client and authentication state,\n * ensuring that tokens are consistently attached to all requests.\n *\n * @param options - Client configuration options\n * @returns A unified Amaster client instance\n *\n * @example\n * ```typescript\n * // Basic usage with explicit baseURL\n * const client = createClient({\n * baseURL: 'https://api.amaster.ai'\n * });\n *\n * // Auto-detect baseURL (for Taro/Mini-program or dev proxy)\n * const client = createClient({});\n *\n * // With authentication callbacks\n * const client = createClient({\n * baseURL: 'https://api.amaster.ai',\n * onUnauthorized: () => {\n * // Redirect to login or show auth modal\n * window.location.href = '/login';\n * },\n * onTokenExpired: () => {\n * console.log('Token expired, refreshing...');\n * }\n * });\n *\n * // Login\n * await client.auth.login({\n * email: 'user@example.com',\n * password: 'password123'\n * });\n *\n * // Now all requests automatically include the auth token\n * const users = await client.entity.list('default', 'users');\n * const tasks = await client.bpm.getMyTasks();\n * ```\n */\nexport function createClient(options: AmasterClientOptions): AmasterClient {\n const {\n baseURL,\n headers = {},\n onUnauthorized,\n onTokenExpired,\n autoHandleOAuthCallback,\n } = options;\n\n // Create the base HTTP client\n const baseHttpClient = createHttpClient({\n baseURL,\n headers,\n });\n\n // Create the auth client first (it manages its own HTTP client internally)\n const auth: AuthClient = createAuthClient({\n baseURL,\n headers,\n onTokenExpired,\n onUnauthorized,\n autoHandleOAuthCallback,\n });\n\n // Create a wrapper HTTP client that automatically adds the auth token\n const createAuthenticatedHttpClient = (): HttpClient => {\n // Track if we're currently refreshing to avoid multiple simultaneous refreshes\n let isRefreshing = false;\n let refreshPromise: Promise<boolean> | null = null;\n\n /**\n * Check if 401 error is due to token expiration\n * Traefik JWT plugin returns plain text like \"Jwt is expired\" or \"Token is expired\"\n */\n function isTokenExpired(result: ClientResult<unknown>): boolean {\n if (result.status !== 401) return false;\n\n // Check error message (could be from backend JSON response)\n if (result.error?.message && /expired/i.test(result.error.message)) {\n return true;\n }\n\n // Check error details (traefik returns plain text in details)\n if (result.error?.details) {\n const details = result.error.details;\n if (typeof details === \"string\" && /expired/i.test(details)) {\n return true;\n }\n // Also check if details is an object with message field\n if (typeof details === \"object\" && details !== null) {\n const detailsObj = details as Record<string, unknown>;\n if (typeof detailsObj.message === \"string\" && /expired/i.test(detailsObj.message)) {\n return true;\n }\n }\n }\n\n // Check raw data (could be plain text from traefik)\n if (typeof result.data === \"string\" && /expired/i.test(result.data)) {\n return true;\n }\n\n // If we have a token but got 401, assume it might be expired\n return !!auth.getAccessToken();\n }\n\n return {\n async request<T>(config: RequestConfig): Promise<ClientResult<T>> {\n // Get the current token from auth client\n const token = auth.getAccessToken();\n\n // Merge Authorization header with existing headers\n const authHeaders = token ? { Authorization: `Bearer ${token}` } : {};\n const mergedConfig: RequestConfig = {\n ...config,\n headers: {\n ...config.headers,\n ...authHeaders,\n },\n };\n\n // Make the request with the updated config\n let result = await baseHttpClient.request<T>(mergedConfig);\n\n // Handle 401 errors with automatic token refresh\n if (result.status === 401 && isTokenExpired(result)) {\n // Attempt to refresh token\n if (!isRefreshing) {\n isRefreshing = true;\n refreshPromise = (async () => {\n try {\n const refreshResult = await auth.refreshToken();\n return !!refreshResult.data;\n } finally {\n isRefreshing = false;\n refreshPromise = null;\n }\n })();\n }\n\n const refreshed = await refreshPromise;\n\n if (refreshed) {\n // Retry with new token\n const newToken = auth.getAccessToken();\n result = await baseHttpClient.request<T>({\n ...config,\n headers: {\n ...config.headers,\n ...(newToken ? { Authorization: `Bearer ${newToken}` } : {}),\n },\n });\n }\n }\n\n // Trigger unauthorized if still 401\n if (result.status === 401 && onUnauthorized) {\n onUnauthorized();\n }\n\n return result;\n },\n };\n };\n\n const authenticatedHttpClient = createAuthenticatedHttpClient();\n\n let cachedUserUid: string | null = null;\n\n auth.on(\"login\", (user: { uid?: string }) => {\n cachedUserUid = user?.uid ?? null;\n });\n auth.on(\"logout\", () => {\n cachedUserUid = null;\n });\n\n if (auth.isAuthenticated()) {\n auth\n .getMe()\n .then((result) => {\n if (result.data?.uid) {\n cachedUserUid = result.data.uid;\n }\n })\n .catch(() => {});\n }\n\n // Create other clients using the authenticated HTTP client\n const entity: EntityClient = createEntityClient(authenticatedHttpClient);\n const bpm: BpmClient = createBpmClient(authenticatedHttpClient);\n const workflow: WorkflowClient = createWorkflowClient(authenticatedHttpClient);\n const functionClient: FunctionClient = createFunctionClient(authenticatedHttpClient);\n const copilot: CopilotClient = createCopilotClient(\n authenticatedHttpClient,\n baseURL,\n () => auth.getAccessToken(),\n () => cachedUserUid\n );\n const s3: S3Client = createS3Client(authenticatedHttpClient);\n\n // ASR and TTS clients use WebSocket, pass token getter for authentication\n // Token can be appended to WebSocket URL as query parameter\n const asr: (config: ASRClientConfig) => ASRClient = createASRClient({\n getAccessToken: () => auth.getAccessToken(),\n });\n const asrHttp: (config: ASRHttpClientConfig) => ASRHttpClient = createASRHttpClient({\n getAccessToken: () => auth.getAccessToken(),\n });\n const tts: (config: TTSClientConfig) => TTSClient = createTTSClient({\n getAccessToken: () => auth.getAccessToken(),\n });\n\n // Return unified client interface\n const client: AmasterClient = {\n auth,\n entity,\n bpm,\n workflow,\n asr,\n asrHttp,\n copilot,\n function: functionClient,\n tts,\n s3,\n http: authenticatedHttpClient,\n\n // Expose token management methods from auth client\n isAuthenticated: () => auth.isAuthenticated(),\n getAccessToken: () => auth.getAccessToken(),\n setAccessToken: (token: string) => auth.setAccessToken(token),\n clearAuth: () => auth.clearAuth(),\n };\n\n return client;\n}\n"]}
1
+ {"version":3,"sources":["../src/client.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * ============================================================================\n * @amaster.ai/client - Unified Amaster Client\n * ============================================================================\n *\n * Supabase-inspired unified API client for the Amaster platform\n *\n * Features:\n * - Single client instance for all services (auth, entity, bpm, workflow)\n * - Automatic token management and refresh\n * - Auto-attach authentication to all requests\n * - Centralized error handling\n *\n * @example\n * ```typescript\n * // With explicit baseURL\n * const client = createClient({\n * baseURL: 'https://api.amaster.ai',\n * onUnauthorized: () => window.location.href = '/login'\n * });\n *\n * // Auto-detect baseURL from env (Taro/Mini-program)\n * const client = createClient({\n * onUnauthorized: () => window.location.href = '/login'\n * });\n *\n * // Login\n * await client.auth.login({ email, password });\n *\n * // All subsequent requests automatically include auth token\n * await client.entity.list('default', 'users');\n * await client.bpm.startProcess({ processKey: 'approval' });\n * ```\n */\n\nimport { createAuthClient, type AuthClient } from \"@amaster.ai/auth-client\";\nimport { createEntityClient, type EntityClient } from \"@amaster.ai/entity-client\";\nimport { createBpmClient, type BpmClient } from \"@amaster.ai/bpm-client\";\nimport { createWorkflowClient, type WorkflowClient } from \"@amaster.ai/workflow-client\";\nimport {\n createASRClient,\n createASRHttpClient,\n type ASRClientConfig,\n type ASRClient,\n type ASRHttpClientConfig,\n type ASRHttpClient,\n} from \"@amaster.ai/asr-client\";\nimport { createCopilotClient, type CopilotClient } from \"@amaster.ai/copilot-client\";\nimport { createFunctionClient, type FunctionClient } from \"@amaster.ai/function-client\";\nimport { createTTSClient, TTSClientConfig, type TTSClient } from \"@amaster.ai/tts-client\";\nimport { createS3Client, type S3Client } from \"@amaster.ai/s3-client\";\nimport {\n createHttpClient,\n type HttpClient,\n type RequestConfig,\n type ClientResult,\n} from \"@amaster.ai/http-client\";\nimport type { AmasterClient, AmasterClientOptions } from \"./types\";\n\n/**\n * Create a unified Amaster client instance\n *\n * This function creates a single client that provides access to all Amaster services:\n * - Authentication (login, register, logout)\n * - Entity CRUD operations\n * - BPM (Business Process Management)\n * - Workflow execution\n *\n * All sub-clients automatically share the same HTTP client and authentication state,\n * ensuring that tokens are consistently attached to all requests.\n *\n * @param options - Client configuration options\n * @returns A unified Amaster client instance\n *\n * @example\n * ```typescript\n * // Basic usage with explicit baseURL\n * const client = createClient({\n * baseURL: 'https://api.amaster.ai'\n * });\n *\n * // Auto-detect baseURL (for Taro/Mini-program or dev proxy)\n * const client = createClient({});\n *\n * // With authentication callbacks\n * const client = createClient({\n * baseURL: 'https://api.amaster.ai',\n * onUnauthorized: () => {\n * // Redirect to login or show auth modal\n * window.location.href = '/login';\n * },\n * onTokenExpired: () => {\n * console.log('Token expired, refreshing...');\n * }\n * });\n *\n * // Login\n * await client.auth.login({\n * email: 'user@example.com',\n * password: 'password123'\n * });\n *\n * // Now all requests automatically include the auth token\n * const users = await client.entity.list('default', 'users');\n * const tasks = await client.bpm.getMyTasks();\n * ```\n */\nexport function createClient(options: AmasterClientOptions): AmasterClient {\n const {\n baseURL,\n headers = {},\n onUnauthorized,\n onTokenExpired,\n autoHandleOAuthCallback,\n } = options;\n\n // Create the base HTTP client\n const baseHttpClient = createHttpClient({\n baseURL,\n headers,\n });\n\n // Create the auth client first (it manages its own HTTP client internally)\n const auth: AuthClient = createAuthClient({\n baseURL,\n headers,\n onTokenExpired,\n onUnauthorized,\n autoHandleOAuthCallback,\n });\n\n // Create a wrapper HTTP client that automatically adds the auth token\n const createAuthenticatedHttpClient = (): HttpClient => {\n // Track if we're currently refreshing to avoid multiple simultaneous refreshes\n let isRefreshing = false;\n let refreshPromise: Promise<boolean> | null = null;\n\n /**\n * Check if 401 error is due to token expiration\n * Traefik JWT plugin returns plain text like \"Jwt is expired\" or \"Token is expired\"\n */\n function isTokenExpired(result: ClientResult<unknown>): boolean {\n if (result.status !== 401) return false;\n\n // Check error message (could be from backend JSON response)\n if (result.error?.message && /expired/i.test(result.error.message)) {\n return true;\n }\n\n // Check error details (traefik returns plain text in details)\n if (result.error?.details) {\n const details = result.error.details;\n if (typeof details === \"string\" && /expired/i.test(details)) {\n return true;\n }\n // Also check if details is an object with message field\n if (typeof details === \"object\" && details !== null) {\n const detailsObj = details as Record<string, unknown>;\n if (typeof detailsObj.message === \"string\" && /expired/i.test(detailsObj.message)) {\n return true;\n }\n }\n }\n\n // Check raw data (could be plain text from traefik)\n if (typeof result.data === \"string\" && /expired/i.test(result.data)) {\n return true;\n }\n\n // If we have a token but got 401, assume it might be expired\n return !!auth.getAccessToken();\n }\n\n return {\n async request<T>(config: RequestConfig): Promise<ClientResult<T>> {\n // Get the current token from auth client\n const token = auth.getAccessToken();\n\n // Merge Authorization header with existing headers\n const authHeaders = token ? { Authorization: `Bearer ${token}` } : {};\n const mergedConfig: RequestConfig = {\n ...config,\n headers: {\n ...config.headers,\n ...authHeaders,\n },\n };\n\n // Make the request with the updated config\n let result = await baseHttpClient.request<T>(mergedConfig);\n\n // Handle 401 errors with automatic token refresh\n if (result.status === 401 && isTokenExpired(result)) {\n // Attempt to refresh token\n if (!isRefreshing) {\n isRefreshing = true;\n refreshPromise = (async () => {\n try {\n const refreshResult = await auth.refreshToken();\n return !!refreshResult.data;\n } finally {\n isRefreshing = false;\n refreshPromise = null;\n }\n })();\n }\n\n const refreshed = await refreshPromise;\n\n if (refreshed) {\n // Retry with new token\n const newToken = auth.getAccessToken();\n result = await baseHttpClient.request<T>({\n ...config,\n headers: {\n ...config.headers,\n ...(newToken ? { Authorization: `Bearer ${newToken}` } : {}),\n },\n });\n }\n }\n\n // Trigger unauthorized if still 401\n if (result.status === 401 && onUnauthorized) {\n onUnauthorized();\n }\n\n return result;\n },\n };\n };\n\n const authenticatedHttpClient = createAuthenticatedHttpClient();\n\n let cachedUserUid: string | null = null;\n\n auth.on(\"login\", (user: { uid?: string }) => {\n cachedUserUid = user?.uid ?? null;\n });\n auth.on(\"logout\", () => {\n cachedUserUid = null;\n });\n\n if (auth.isAuthenticated()) {\n auth\n .getMe()\n .then((result) => {\n if (result.data?.uid) {\n cachedUserUid = result.data.uid;\n }\n })\n .catch(() => {});\n }\n\n // Create other clients using the authenticated HTTP client\n const entity: EntityClient = createEntityClient(authenticatedHttpClient);\n const bpm: BpmClient = createBpmClient(authenticatedHttpClient);\n const workflow: WorkflowClient = createWorkflowClient(authenticatedHttpClient);\n const functionClient: FunctionClient = createFunctionClient(authenticatedHttpClient);\n const copilot: CopilotClient = createCopilotClient(\n authenticatedHttpClient,\n baseURL,\n () => auth.getAccessToken(),\n () => cachedUserUid\n );\n const s3: S3Client = createS3Client(authenticatedHttpClient);\n\n // ASR and TTS clients use WebSocket, pass token getter for authentication\n // Token can be appended to WebSocket URL as query parameter\n const asr: (config: ASRClientConfig) => ASRClient = createASRClient({\n getAccessToken: () => auth.getAccessToken(),\n });\n const asrHttp: (config: ASRHttpClientConfig) => ASRHttpClient = createASRHttpClient({\n getAccessToken: () => auth.getAccessToken(),\n http: authenticatedHttpClient,\n });\n const tts: (config: TTSClientConfig) => TTSClient = createTTSClient({\n getAccessToken: () => auth.getAccessToken(),\n });\n\n // Return unified client interface\n const client: AmasterClient = {\n auth,\n entity,\n bpm,\n workflow,\n asr,\n asrHttp,\n copilot,\n function: functionClient,\n tts,\n s3,\n http: authenticatedHttpClient,\n\n // Expose token management methods from auth client\n isAuthenticated: () => auth.isAuthenticated(),\n getAccessToken: () => auth.getAccessToken(),\n setAccessToken: (token: string) => auth.setAccessToken(token),\n clearAuth: () => auth.clearAuth(),\n };\n\n return client;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@amaster.ai/client",
3
- "version": "1.1.0-beta.50",
3
+ "version": "1.1.0-beta.52",
4
4
  "description": "Unified API client for Amaster platform - All services in one package",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -72,16 +72,16 @@
72
72
  "registry": "https://registry.npmjs.org/"
73
73
  },
74
74
  "dependencies": {
75
- "@amaster.ai/asr-client": "1.1.0-beta.50",
76
- "@amaster.ai/copilot-client": "1.1.0-beta.50",
77
- "@amaster.ai/auth-client": "1.1.0-beta.50",
78
- "@amaster.ai/entity-client": "1.1.0-beta.50",
79
- "@amaster.ai/function-client": "1.1.0-beta.50",
80
- "@amaster.ai/http-client": "1.1.0-beta.50",
81
- "@amaster.ai/s3-client": "1.1.0-beta.50",
82
- "@amaster.ai/bpm-client": "1.1.0-beta.50",
83
- "@amaster.ai/tts-client": "1.1.0-beta.50",
84
- "@amaster.ai/workflow-client": "1.1.0-beta.50"
75
+ "@amaster.ai/asr-client": "1.1.0-beta.52",
76
+ "@amaster.ai/auth-client": "1.1.0-beta.52",
77
+ "@amaster.ai/copilot-client": "1.1.0-beta.52",
78
+ "@amaster.ai/bpm-client": "1.1.0-beta.52",
79
+ "@amaster.ai/entity-client": "1.1.0-beta.52",
80
+ "@amaster.ai/function-client": "1.1.0-beta.52",
81
+ "@amaster.ai/http-client": "1.1.0-beta.52",
82
+ "@amaster.ai/s3-client": "1.1.0-beta.52",
83
+ "@amaster.ai/tts-client": "1.1.0-beta.52",
84
+ "@amaster.ai/workflow-client": "1.1.0-beta.52"
85
85
  },
86
86
  "peerDependencies": {
87
87
  "axios": "^1.11.0"
package/types/asr.d.ts CHANGED
@@ -1,114 +1,325 @@
1
+ import type{ HttpClient } from "./http";
1
2
  /**
2
- * * Real-time speech recognition using WebSocket connection.
3
- *
4
- * @module asr
5
- */
6
-
7
- /**
8
- * ASR Client Configuration
3
+ * ASR Realtime WebSocket Client for Qwen-ASR Realtime API
4
+ *
5
+ * WebSocket-based real-time speech recognition for streaming transcription.
6
+ * Follows the Qwen-ASR Realtime API protocol with proper event handling.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * const asrClient = client.asr({
11
+ * language: "zh",
12
+ * enableVAD: true,
13
+ * onReady() {
14
+ * console.log("ASR connected");
15
+ * },
16
+ * onTranscript(text, isFinal) {
17
+ * console.log(isFinal ? "[Final]" : "[Interim]", text);
18
+ * },
19
+ * onError(err) {
20
+ * console.error("ASR error:", err);
21
+ * },
22
+ * });
9
23
  *
24
+ * await asrClient.connect();
25
+ * await asrClient.startRecording();
26
+ * // ... stop ...
27
+ * await asrClient.stopRecording();
28
+ * await asrClient.close();
29
+ * ```
10
30
  */
31
+ export type ASRLanguage =
32
+ | "zh"
33
+ | "yue"
34
+ | "en"
35
+ | "ja"
36
+ | "de"
37
+ | "ko"
38
+ | "ru"
39
+ | "fr"
40
+ | "pt"
41
+ | "ar"
42
+ | "it"
43
+ | "es"
44
+ | "hi"
45
+ | "id"
46
+ | "th"
47
+ | "tr"
48
+ | "uk"
49
+ | "vi"
50
+ | "cs"
51
+ | "da"
52
+ | "fil"
53
+ | "fi"
54
+ | "is"
55
+ | "ms"
56
+ | "no"
57
+ | "pl"
58
+ | "sv";
59
+ export type ClientEventType =
60
+ | "session.update"
61
+ | "input_audio_buffer.append"
62
+ | "input_audio_buffer.commit"
63
+ | "session.finish";
64
+ export type ServerEventType =
65
+ | "session.created"
66
+ | "session.updated"
67
+ | "input_audio_buffer.speech_started"
68
+ | "input_audio_buffer.speech_stopped"
69
+ | "input_audio_buffer.committed"
70
+ | "conversation.item.input_audio_transcription.text"
71
+ | "conversation.item.input_audio_transcription.completed"
72
+ | "session.finished"
73
+ | "error";
74
+ export interface BaseEvent {
75
+ event_id: string;
76
+ type: ClientEventType | ServerEventType;
77
+ }
78
+ export interface SessionUpdateEvent extends BaseEvent {
79
+ type: "session.update";
80
+ session: SessionConfig;
81
+ }
82
+ export interface InputAudioBufferAppendEvent extends BaseEvent {
83
+ type: "input_audio_buffer.append";
84
+ audio: string;
85
+ }
86
+ export interface InputAudioBufferCommitEvent extends BaseEvent {
87
+ type: "input_audio_buffer.commit";
88
+ }
89
+ export interface SessionFinishEvent extends BaseEvent {
90
+ type: "session.finish";
91
+ }
92
+ type ClientEvent =
93
+ | SessionUpdateEvent
94
+ | InputAudioBufferAppendEvent
95
+ | InputAudioBufferCommitEvent
96
+ | SessionFinishEvent;
97
+ export interface SessionCreatedEvent extends BaseEvent {
98
+ type: "session.created";
99
+ session: {
100
+ id: string;
101
+ };
102
+ }
103
+ export interface SessionUpdatedEvent extends BaseEvent {
104
+ type: "session.updated";
105
+ session: SessionConfig;
106
+ }
107
+ export interface SpeechStartedEvent extends BaseEvent {
108
+ type: "input_audio_buffer.speech_started";
109
+ }
110
+ export interface SpeechStoppedEvent extends BaseEvent {
111
+ type: "input_audio_buffer.speech_stopped";
112
+ }
113
+ export interface InputAudioBufferCommittedEvent extends BaseEvent {
114
+ type: "input_audio_buffer.committed";
115
+ }
116
+ export interface TranscriptionTextEvent extends BaseEvent {
117
+ type: "conversation.item.input_audio_transcription.text";
118
+ text?: string;
119
+ stash?: string;
120
+ transcript?: string;
121
+ }
122
+ export interface TranscriptionCompletedEvent extends BaseEvent {
123
+ type: "conversation.item.input_audio_transcription.completed";
124
+ text?: string;
125
+ transcript?: string;
126
+ }
127
+ export interface SessionFinishedEvent extends BaseEvent {
128
+ type: "session.finished";
129
+ }
130
+ export interface ErrorEvent extends BaseEvent {
131
+ type: "error";
132
+ error: {
133
+ message: string;
134
+ code?: string;
135
+ };
136
+ }
137
+ export type ServerEvent =
138
+ | SessionCreatedEvent
139
+ | SessionUpdatedEvent
140
+ | SpeechStartedEvent
141
+ | SpeechStoppedEvent
142
+ | InputAudioBufferCommittedEvent
143
+ | TranscriptionTextEvent
144
+ | TranscriptionCompletedEvent
145
+ | SessionFinishedEvent
146
+ | ErrorEvent;
147
+ export interface TurnDetectionConfig {
148
+ type: "server_vad";
149
+ /** VAD检测阈值,推荐设为 0.0,默认值 0.2,范围 [-1, 1] */
150
+ threshold?: number;
151
+ /** VAD断句检测阈值(ms),推荐设为 400,默认值 800,范围 [200, 6000] */
152
+ silence_duration_ms?: number;
153
+ }
154
+ export interface InputAudioTranscriptionConfig {
155
+ language?: ASRLanguage;
156
+ }
157
+ export interface SessionConfig {
158
+ input_audio_format?: "pcm" | "opus";
159
+ sample_rate?: 16000 | 8000;
160
+ input_audio_transcription?: InputAudioTranscriptionConfig;
161
+ turn_detection?: TurnDetectionConfig | null;
162
+ }
11
163
  export interface ASRClientConfig {
12
- /** Audio format, default 'pcm16' */
13
- audioFormat?: "pcm16" | "g711a" | "g711u";
14
-
15
- /** Sample rate, default 16000 */
16
- sampleRate?: number;
17
-
18
- /** Called when connection is ready */
164
+ /**
165
+ * Audio format
166
+ * @default "pcm"
167
+ */
168
+ audioFormat?: "pcm" | "opus";
169
+ /**
170
+ * Sample rate in Hz
171
+ * @default 16000
172
+ * @description 支持 16000 和 8000。设置为 8000 时,服务端会先升采样到16000Hz再进行识别,可能引入微小延迟。
173
+ */
174
+ sampleRate?: 16000 | 8000;
175
+ /**
176
+ * Audio source language
177
+ * @default "zh"
178
+ * @description 支持多种语言,包括 zh(中文)、yue(粤语)、en(英文)、ja(日语)等
179
+ */
180
+ language?: ASRLanguage;
181
+ /**
182
+ * Enable VAD (Voice Activity Detection) mode
183
+ * @default true
184
+ * @description true = VAD模式(服务端自动检测语音开始/结束),false = Manual模式(客户端手动控制)
185
+ */
186
+ enableVAD?: boolean;
187
+ /**
188
+ * VAD detection threshold
189
+ * @default 0.2
190
+ * @description 推荐设为 0.0。取值范围 [-1, 1]。较低的阈值会提高 VAD 的灵敏度。
191
+ */
192
+ vadThreshold?: number;
193
+ /**
194
+ * VAD silence duration threshold in milliseconds
195
+ * @default 800
196
+ * @description 推荐设为 400。取值范围 [200, 6000]。静音持续时长超过该阈值将被认为是语句结束。
197
+ */
198
+ vadSilenceDurationMs?: number;
199
+ /**
200
+ * Get access token for WebSocket authentication
201
+ */
202
+ getAccessToken?: () => string | null;
203
+ /**
204
+ * Called when connection is ready (session.created received and session.update sent)
205
+ */
19
206
  onReady?: () => void;
20
-
21
- /** Called when speech is detected */
207
+ /**
208
+ * Called when speech is detected (VAD mode only)
209
+ */
22
210
  onSpeechStart?: () => void;
23
-
24
- /** Called when speech stops */
211
+ /**
212
+ * Called when speech stops (VAD mode only)
213
+ */
25
214
  onSpeechEnd?: () => void;
26
-
27
- /**
215
+ /**
28
216
  * Called on transcript result
29
- * @param text - Recognized text
217
+ * @param text - Transcribed text
30
218
  * @param isFinal - Whether this is the final result
31
219
  */
32
220
  onTranscript?: (text: string, isFinal: boolean) => void;
33
-
34
- /** Called on error */
221
+ /**
222
+ * Called when audio buffer is committed (non-VAD mode only)
223
+ */
224
+ onAudioBufferCommitted?: () => void;
225
+ /**
226
+ * Called when session is finished
227
+ */
228
+ onSessionFinished?: () => void;
229
+ /**
230
+ * Called on error
231
+ */
35
232
  onError?: (error: Error) => void;
36
-
37
- /** Called on connection close */
233
+ /**
234
+ * Called on close
235
+ */
38
236
  onClose?: () => void;
39
237
  }
40
-
41
- /**
42
- * ASR (Automatic Speech Recognition) Client API
43
- *
44
- * Provides real-time speech-to-text conversion via WebSocket.
45
- *
46
- * @since 1.0.0
47
- */
48
- export interface ASRClientAPI {
238
+ export interface ASRClient {
239
+ /** Connect to ASR service and establish session */
240
+ connect(): Promise<void>;
241
+ /** Start recording from microphone */
242
+ startRecording(): Promise<void>;
49
243
  /**
50
- * Connect to ASR service
51
- *
52
- * Establishes WebSocket connection to the speech recognition service.
53
- *
54
- * @returns Promise that resolves when connected
55
- *
244
+ * Stop recording
245
+ * @description In non-VAD mode, this triggers recognition by sending input_audio_buffer.commit
56
246
  */
57
- connect(): Promise<void>;
58
-
247
+ stopRecording(): Promise<void>;
59
248
  /**
60
- * Start recording from microphone
61
- *
62
- * Begins capturing audio from the user's microphone and sends it to the ASR service.
63
- * Requires microphone permission from the user.
64
- *
65
- * @returns Promise that resolves when recording starts
66
- *
249
+ * Close connection gracefully
250
+ * @description Sends session.finish and waits for session.finished before closing
67
251
  */
68
- startRecording(): Promise<void>;
252
+ close(): Promise<void>;
253
+ /**
254
+ * Check if currently recording
255
+ */
256
+ isRecording(): boolean;
257
+ /**
258
+ * Check if connected to server
259
+ */
260
+ isConnected(): boolean;
261
+ }
262
+ declare const _default$1: (
263
+ authConfig: Pick<ASRClientConfig, "getAccessToken">
264
+ ) => (config: ASRClientConfig) => ASRClient;
69
265
 
266
+ export interface Recorder {
267
+ /** Start recording */
268
+ start(): Promise<void>;
70
269
  /**
71
- * Stop recording
72
- *
73
- * Stops capturing audio from the microphone but keeps the WebSocket connection open.
270
+ * Stop recording and get base64-encoded WAV audio data. You can use this data to call the ASR API.
74
271
  *
272
+ * @returns Base64-encoded WAV audio data
75
273
  */
76
- stopRecording(): void;
274
+ stop(): Promise<void>;
275
+ }
77
276
 
277
+ export interface RecorderOptions {
278
+ /** Called when recording starts */
279
+ onStart?: () => void;
78
280
  /**
79
- * Close connection
80
- *
81
- * Closes the WebSocket connection and releases resources.
281
+ * Called when recording stops, with base64-encoded WAV audio data. You can use this data to call the ASR API.
82
282
  *
283
+ * @param base64 - Base64-encoded WAV audio data
284
+ * @returns void
83
285
  */
84
- close(): void;
286
+ onStop?: (base64: string) => void;
287
+ onError?: (error: Error) => void;
85
288
  }
86
289
 
290
+ export type ASRHttpStatus = "idle" | "recording" | "recognizing";
291
+
87
292
  export interface ASRHttpClientConfig {
88
- /** Get access token */
89
- getAccessToken?(): string | null;
90
- /** Language, default 'zh' */
91
- language?: string;
92
- /** Sample rate, default 16000 */
93
- sampleRate?: number;
94
- /** Called when recording starts */
95
- onRecordingStart?: () => void;
96
- /** Called when recording stops */
97
- onRecordingStop?: () => void;
98
- /** Called with recognition result */
99
- onResult?: (text: string) => void;
100
- /** Called on error */
101
- onError?: (error: Error) => void;
293
+ /** Get access token */
294
+ http?: HttpClient;
295
+ /** Get access token */
296
+ getAccessToken?(): string | null;
297
+ /** Create custom recorder */
298
+ createRecorder?(options?: RecorderOptions): Promise<Recorder>;
299
+ /** Language, default 'zh' */
300
+ language?: string;
301
+ /** Sample rate, default 16000 */
302
+ sampleRate?: number;
303
+ /** Called when recording starts */
304
+ onRecordingStart?: () => void;
305
+ /** Called when recording stops */
306
+ onRecordingStop?: () => void;
307
+ /** Called with recognition result */
308
+ onResult?: (text: string) => void;
309
+ /** Called on error */
310
+ onError?: (error: Error) => void;
311
+ /** Called when status changes */
312
+ onStatusChange?: (status: ASRHttpStatus) => void;
102
313
  }
103
314
  export interface ASRHttpClient {
104
- /** Start recording (press-to-talk) */
105
- startRecording(): Promise<void>;
106
- /** Stop recording and get result */
107
- stopRecording(): Promise<string>;
108
- /** Record for specific duration then recognize */
109
- recordAndRecognize(durationMs: number): Promise<string>;
110
- /** Recognize audio file (File or Blob) */
111
- recognizeFile(file: File | Blob): Promise<string>;
112
- /** Recognize audio from URL */
113
- recognizeUrl(audioUrl: string): Promise<string>;
114
- }
315
+ /** Start recording (press-to-talk) */
316
+ startRecording(): Promise<void>;
317
+ /** Stop recording and get result */
318
+ stopRecording(): Promise<string>;
319
+ /** Record for specific duration then recognize */
320
+ recordAndRecognize(durationMs: number): Promise<string>;
321
+ /** Recognize audio file (File or Blob) */
322
+ recognizeFile(file: File | Blob): Promise<string>;
323
+ /** Recognize audio from URL */
324
+ recognizeUrl(audioUrl: string): Promise<string>;
325
+ }
@@ -0,0 +1,95 @@
1
+ import { AxiosRequestConfig, AxiosInstance } from 'axios';
2
+
3
+ type ClientError = {
4
+ message: string;
5
+ status?: number;
6
+ code?: string;
7
+ details?: unknown;
8
+ };
9
+ type ClientResult<T> = {
10
+ data: T | null;
11
+ error: ClientError | null;
12
+ status: number;
13
+ };
14
+ type RequestConfig = AxiosRequestConfig & {
15
+ url: string;
16
+ method: NonNullable<AxiosRequestConfig["method"]> | string;
17
+ };
18
+ type AdapterResponse = {
19
+ status: number;
20
+ data: unknown;
21
+ headers?: unknown;
22
+ };
23
+ type HttpAdapter = (_config: RequestConfig) => Promise<AdapterResponse>;
24
+ type HttpClientOptions = {
25
+ /**
26
+ * HTTP adapter to use:
27
+ * - undefined: auto-detect (taro if mini-program APIs exist, otherwise axios)
28
+ * - "taro": force mini-program request (wx/tt/my/...) or global Taro.request
29
+ * - "axios": force axios
30
+ * - AxiosInstance: use provided axios instance
31
+ * - function: custom adapter
32
+ */
33
+ adapter?: "taro" | "axios" | AxiosInstance | HttpAdapter;
34
+ /**
35
+ * Base URL to prefix when `config.url` is relative (e.g. "/api/...").
36
+ *
37
+ * If not provided:
38
+ * - Taro/mini-program: auto-reads from process.env.TARO_APP_API_BASE_URL or process.env.VITE_API_BASE_URL
39
+ * - H5/Browser: no baseURL (expects dev proxy or absolute URLs)
40
+ */
41
+ baseURL?: string;
42
+ /** Default headers merged into each request */
43
+ headers?: Record<string, string>;
44
+ /**
45
+ * Custom response transform function to extract/modify data from backend response
46
+ * If not provided, uses default transform logic for { status: 0/1, data: {...} }
47
+ *
48
+ * Similar to axios's transformResponse option
49
+ *
50
+ * @example
51
+ * ```typescript
52
+ * // For backend that returns: { statusCode: 200, data: {...} }
53
+ * const client = createHttpClient({
54
+ * transformResponse: (response) => {
55
+ * if (response && typeof response === 'object' && 'data' in response) {
56
+ * return response.data;
57
+ * }
58
+ * return response;
59
+ * }
60
+ * });
61
+ * ```
62
+ */
63
+ transformResponse?: <T>(responseData: unknown) => T;
64
+ /**
65
+ * Whether to log errors to console (default: true)
66
+ * Set to false to disable automatic error logging
67
+ */
68
+ logErrors?: boolean;
69
+ };
70
+ type HttpClient = {
71
+ request<T>(_config: RequestConfig): Promise<ClientResult<T>>;
72
+ };
73
+ /**
74
+ * Create an HTTP client instance
75
+ *
76
+ * @param axiosInstance - Optional axios instance to use (defaults to a basic axios instance)
77
+ * @returns HttpClient with request method
78
+ *
79
+ * @example
80
+ * ```typescript
81
+ * import axios from "axios";
82
+ * import { createHttpClient } from "@amaster.ai/http-client";
83
+ *
84
+ * const instance = axios.create({ baseURL: "https://api.example.com" });
85
+ * const client = createHttpClient(instance);
86
+ *
87
+ * const result = await client.request({
88
+ * url: "/users",
89
+ * method: "get",
90
+ * });
91
+ * ```
92
+ */
93
+ declare function createHttpClient(axiosInstanceOrOptions?: AxiosInstance | HttpClientOptions): HttpClient;
94
+
95
+ export { type AdapterResponse, type ClientError, type ClientResult, type HttpAdapter, type HttpClient, type HttpClientOptions, type RequestConfig, createHttpClient };
package/types/index.d.ts CHANGED
@@ -1,40 +1,40 @@
1
1
  /**
2
2
  * * A Supabase-inspired unified client for the Amaster platform.
3
- *
3
+ *
4
4
  * ## Features
5
5
  * - Single client instance for all services (auth, entity, bpm, workflow)
6
6
  * - Automatic token management and refresh
7
7
  * - Auto-attach authentication to all requests
8
8
  * - Centralized error handling
9
- *
9
+ *
10
10
  * ## Quick Start
11
11
  * ```typescript
12
12
  * import { createClient } from '@amaster.ai/client';
13
- *
13
+ *
14
14
  * const client = createClient({
15
15
  * baseURL: 'https://api.amaster.ai',
16
16
  * onUnauthorized: () => window.location.href = '/login'
17
17
  * });
18
- *
18
+ *
19
19
  * // Login
20
20
  * await client.auth.login({ email, password });
21
- *
21
+ *
22
22
  * // All subsequent requests automatically include auth token
23
23
  * await client.entity.list('default', 'users');
24
24
  * await client.bpm.startProcess('approval', {});
25
25
  * ```
26
- *
26
+ *
27
27
  * ## Module Documentation
28
28
  * For detailed API documentation, see individual module type definitions:
29
29
  * - **Authentication**: {@link ./auth/index.d.ts} (split into user, password-auth, code-auth, oauth, permissions, profile)
30
30
  * - **Entity Operations**: {@link ./entity.d.ts}
31
31
  * - **BPM (Business Process)**: {@link ./bpm.d.ts}
32
32
  * - **Workflow Execution**: {@link ./workflow.d.ts}
33
- *
33
+ *
34
34
  * ## AI-Friendly Type Structure
35
35
  * This package provides modular type definitions optimized for AI tools and large language models.
36
36
  * Types are split into focused modules that can be loaded on-demand:
37
- *
37
+ *
38
38
  * **Authentication Types** (70-88% token savings):
39
39
  * - `@amaster.ai/client/auth/user` - User types (100 lines)
40
40
  * - `@amaster.ai/client/auth/password-auth` - Login/register (200 lines)
@@ -44,15 +44,16 @@
44
44
  * - `@amaster.ai/client/auth/profile` - Profile management (100 lines)
45
45
  * */
46
46
 
47
- import type { AuthClientAPI } from './auth/index';
48
- import type { EntityClientAPI } from './entity';
49
- import type { BpmClientAPI } from './bpm';
50
- import type { WorkflowClientAPI } from './workflow';
51
- import type { ASRClientAPI } from './asr';
52
- import type { CopilotClientAPI } from './copilot';
53
- import type { FunctionClientAPI } from './function';
54
- import type { TTSClientAPI } from './tts';
55
- import type { S3ClientAPI } from './s3';
47
+ import type { AuthClientAPI } from "./auth/index";
48
+ import type { EntityClientAPI } from "./entity";
49
+ import type { BpmClientAPI } from "./bpm";
50
+ import type { WorkflowClientAPI } from "./workflow";
51
+ import type { ASRClientConfig, ASRClient, ASRHttpClientConfig, ASRHttpClient } from "./asr";
52
+ import type { CopilotClientAPI } from "./copilot";
53
+ import type { FunctionClientAPI } from "./function";
54
+ import type { TTSClientAPI } from "./tts";
55
+ import type { S3ClientAPI } from "./s3";
56
+ import type { HttpClient } from "./http";
56
57
 
57
58
  /**
58
59
  * Configuration options for creating an Amaster client
@@ -67,7 +68,7 @@ export interface AmasterClientOptions {
67
68
 
68
69
  /**
69
70
  * Optional custom headers to include in ALL requests
70
- *
71
+ *
71
72
  * These headers will be merged with authentication headers.
72
73
  * Useful for tenant IDs, API keys, or application metadata.
73
74
  *
@@ -76,7 +77,7 @@ export interface AmasterClientOptions {
76
77
 
77
78
  /**
78
79
  * Callback triggered when a 401 Unauthorized response is received
79
- *
80
+ *
80
81
  * Use this to redirect to login page or show authentication modal.
81
82
  * This callback is invoked BEFORE the request promise rejects.
82
83
  *
@@ -85,7 +86,7 @@ export interface AmasterClientOptions {
85
86
 
86
87
  /**
87
88
  * Callback triggered when the access token expires
88
- *
89
+ *
89
90
  * Note: Token refresh is handled automatically by the client.
90
91
  * This callback is for additional actions like logging or analytics.
91
92
  *
@@ -94,31 +95,31 @@ export interface AmasterClientOptions {
94
95
 
95
96
  /**
96
97
  * Enable automatic token refresh (default: true)
97
- *
98
+ *
98
99
  * When enabled, tokens are automatically refreshed before expiry.
99
- *
100
+ *
100
101
  * @default true
101
102
  */
102
103
  autoRefresh?: boolean;
103
104
 
104
105
  /**
105
106
  * Token refresh threshold in seconds (default: 300)
106
- *
107
+ *
107
108
  * Tokens will be refreshed this many seconds before expiry.
108
109
  * For example, if set to 300 (5 minutes), a token expiring at
109
110
  * 10:00:00 will be refreshed at 9:55:00.
110
- *
111
+ *
111
112
  * @default 300
112
113
  */
113
114
  refreshThreshold?: number;
114
115
 
115
116
  /**
116
117
  * Auto-handle OAuth callback on page load (default: true)
117
- *
118
+ *
118
119
  * Automatically detects and processes `#access_token` in URL hash,
119
120
  * then clears the hash for security. Set to `false` to manually
120
121
  * call `client.auth.handleOAuthCallback()`.
121
- *
122
+ *
122
123
  * @default true
123
124
  */
124
125
  autoHandleOAuthCallback?: boolean;
@@ -126,16 +127,16 @@ export interface AmasterClientOptions {
126
127
 
127
128
  /**
128
129
  * Unified Amaster Client interface
129
- *
130
+ *
130
131
  * This is the main client object returned by `createClient()`.
131
132
  * It provides access to all Amaster services through a unified interface.
132
- *
133
+ *
133
134
  * ## Core Modules
134
135
  * - {@link auth} - Authentication and user management
135
136
  * - {@link entity} - CRUD operations for entities
136
137
  * - {@link bpm} - Business process management
137
138
  * - {@link workflow} - Workflow execution
138
- *
139
+ *
139
140
  * ## Token Management
140
141
  * - {@link isAuthenticated} - Check if user is authenticated
141
142
  * - {@link getAccessToken} - Get current access token
@@ -146,9 +147,9 @@ export interface AmasterClientOptions {
146
147
  export interface AmasterClient {
147
148
  /**
148
149
  * Authentication module
149
- *
150
+ *
150
151
  * Provides methods for user authentication, registration, and management.
151
- *
152
+ *
152
153
  * For detailed documentation, see {@link ./auth.d.ts}
153
154
  *
154
155
  */
@@ -156,9 +157,9 @@ export interface AmasterClient {
156
157
 
157
158
  /**
158
159
  * Entity CRUD operations module
159
- *
160
+ *
160
161
  * Provides methods for creating, reading, updating, and deleting entities.
161
- *
162
+ *
162
163
  * For detailed documentation, see {@link ./entity.d.ts}
163
164
  *
164
165
  */
@@ -166,9 +167,9 @@ export interface AmasterClient {
166
167
 
167
168
  /**
168
169
  * Business Process Management (BPM) module
169
- *
170
+ *
170
171
  * Provides methods for managing BPMN processes and tasks.
171
- *
172
+ *
172
173
  * For detailed documentation, see {@link ./bpm.d.ts}
173
174
  *
174
175
  */
@@ -176,9 +177,9 @@ export interface AmasterClient {
176
177
 
177
178
  /**
178
179
  * Workflow execution module
179
- *
180
+ *
180
181
  * Provides methods for executing Dify-style workflows.
181
- *
182
+ *
182
183
  * For detailed documentation, see {@link ./workflow.d.ts}
183
184
  *
184
185
  */
@@ -186,18 +187,27 @@ export interface AmasterClient {
186
187
 
187
188
  /**
188
189
  * ASR (Automatic Speech Recognition) module
189
- *
190
+ *
190
191
  * Provides methods for real-time speech-to-text conversion via WebSocket.
191
- *
192
+ *
192
193
  * For detailed documentation, see {@link ./asr.d.ts}
193
194
  */
194
- asr: ASRClientAPI;
195
+ asr: (config: ASRClientConfig) => ASRClient;
196
+
197
+ /**
198
+ * ASR HTTP module
199
+ *
200
+ * Provides methods for speech-to-text conversion via HTTP API.
201
+ *
202
+ * For detailed documentation, see
203
+ */
204
+ asrHttp: (config: ASRHttpClientConfig) => ASRHttpClient;
195
205
 
196
206
  /**
197
207
  * Copilot AI Assistant module
198
- *
208
+ *
199
209
  * Provides methods for interactive AI conversations with a2a streaming.
200
- *
210
+ *
201
211
  * For detailed documentation, see {@link ./copilot.d.ts}
202
212
  *
203
213
  */
@@ -205,34 +215,55 @@ export interface AmasterClient {
205
215
 
206
216
  /**
207
217
  * Serverless Function module
208
- *
218
+ *
209
219
  * Provides methods for invoking serverless functions.
210
- *
220
+ *
211
221
  * For detailed documentation, see {@link ./function.d.ts}
212
222
  */
213
223
  function: FunctionClientAPI;
214
224
 
215
225
  /**
216
226
  * TTS (Text-to-Speech) module
217
- *
227
+ *
218
228
  * Provides methods for real-time text-to-speech conversion via WebSocket.
219
- *
229
+ *
220
230
  * For detailed documentation, see {@link ./tts.d.ts}
221
231
  */
222
232
  tts: TTSClientAPI;
223
233
 
224
234
  /**
225
235
  * S3 Storage module
226
- *
236
+ *
227
237
  * Provides methods for file upload, download, and management.
228
- *
238
+ *
229
239
  * For detailed documentation, see {@link ./s3.d.ts}
230
240
  */
231
241
  s3: S3ClientAPI;
232
242
 
243
+ /**
244
+ * HTTP client instance used for all requests
245
+ *
246
+ * This is the underlying HTTP client that handles all API requests.
247
+ * It automatically includes authentication headers and base URL.
248
+ * You can use this client to make custom requests to the Amaster API
249
+ * or your own backend while still benefiting from automatic token management.
250
+ * For example:
251
+ * ```typescript
252
+ * const response = await client.http.request({
253
+ * url: '/api/custom-endpoint',
254
+ * method: 'POST',
255
+ * data: { key: 'value' }
256
+ * });
257
+ * console.log(response.data);
258
+ * ```
259
+ * Note: The `http` client is an instance of the same HTTP client used internally by the Amaster client.
260
+ * It automatically includes the base URL and authentication headers configured in `createClient()`.
261
+ */
262
+ http: HttpClient;
263
+
233
264
  /**
234
265
  * Check if the user is currently authenticated
235
- *
266
+ *
236
267
  * @returns `true` if a valid access token exists, `false` otherwise
237
268
  *
238
269
  */
@@ -240,7 +271,7 @@ export interface AmasterClient {
240
271
 
241
272
  /**
242
273
  * Get the current access token
243
- *
274
+ *
244
275
  * @returns The access token string, or `null` if not authenticated
245
276
  *
246
277
  */
@@ -248,10 +279,10 @@ export interface AmasterClient {
248
279
 
249
280
  /**
250
281
  * Manually set the access token
251
- *
282
+ *
252
283
  * Useful when you have a token from another source (e.g., SSO, OAuth).
253
284
  * After setting the token, all requests will use it automatically.
254
- *
285
+ *
255
286
  * @param token - The JWT access token to set
256
287
  *
257
288
  */
@@ -259,12 +290,12 @@ export interface AmasterClient {
259
290
 
260
291
  /**
261
292
  * Clear all authentication state
262
- *
293
+ *
263
294
  * This removes:
264
295
  * - Access token
265
296
  * - User information
266
297
  * - Auto-refresh timers
267
- *
298
+ *
268
299
  * After calling this, `isAuthenticated()` will return `false`
269
300
  * and all requests will be unauthenticated.
270
301
  *
@@ -274,10 +305,10 @@ export interface AmasterClient {
274
305
 
275
306
  /**
276
307
  * Factory function to create a unified Amaster client
277
- *
308
+ *
278
309
  * This is the main entry point for using the Amaster client library.
279
310
  * It returns a client instance that provides access to all Amaster services.
280
- *
311
+ *
281
312
  * @param options - Configuration options for the client
282
313
  * @returns A configured Amaster client instance
283
314
  *
@@ -285,18 +316,19 @@ export interface AmasterClient {
285
316
  export declare function createClient(options: AmasterClientOptions): AmasterClient;
286
317
 
287
318
  // Re-export shared common types
288
- export type { ClientResult } from './common';
319
+ export type { ClientResult } from "./common";
289
320
 
290
321
  // Re-export main client interfaces
291
- export type { AuthClientAPI } from './auth';
292
- export type { EntityClientAPI } from './entity';
293
- export type { BpmClientAPI } from './bpm';
294
- export type { WorkflowClientAPI } from './workflow';
295
- export type { ASRClientAPI } from './asr';
296
- export type { CopilotClientAPI } from './copilot';
297
- export type { FunctionClientAPI } from './function';
298
- export type { TTSClientAPI } from './tts';
299
- export type { S3ClientAPI } from './s3';
322
+ export type { AuthClientAPI } from "./auth";
323
+ export type { EntityClientAPI } from "./entity";
324
+ export type { BpmClientAPI } from "./bpm";
325
+ export type { WorkflowClientAPI } from "./workflow";
326
+ export type { ASRClient, ASRClientConfig, ASRHttpClient, ASRHttpClientConfig, Recorder, RecorderOptions } from "./asr";
327
+ export type { CopilotClientAPI } from "./copilot";
328
+ export type { FunctionClientAPI } from "./function";
329
+ export type { TTSClientAPI } from "./tts";
330
+ export type { S3ClientAPI } from "./s3";
331
+ export type { HttpClient } from "./http";
300
332
 
301
333
  // For detailed types, import directly from submodules:
302
334
  // import type { LoginParams, User } from '@amaster.ai/client/auth'
package/types/tts.d.ts CHANGED
@@ -78,6 +78,12 @@ export interface TTSClientAPI {
78
78
  */
79
79
  play(): void;
80
80
 
81
+ /**
82
+ * Stop audio playback
83
+ *
84
+ */
85
+ stop(): void;
86
+
81
87
  /**
82
88
  * Close connection
83
89
  *