@buildaureon/sdk 0.1.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.
@@ -0,0 +1,182 @@
1
+ # Detailed Error Model and Diagnostics
2
+
3
+ This document outlines the error classification system used by `@buildaureon/sdk`. It provides field specifications, JSON payloads returned by the hosted API, and diagnostic patterns for production environments.
4
+
5
+ ---
6
+
7
+ ## 1. Core Exception Classes
8
+
9
+ All custom exceptions thrown by the SDK extend the base class `AureonError`. The classes are organized to allow granular catch blocks based on failure categories.
10
+
11
+ ```mermaid
12
+ graph TD
13
+ Error[native Error] --> AureonError[AureonError Base]
14
+ AureonError --> AureonValidationError[AureonValidationError HTTP 400]
15
+ AureonError --> AureonNotFoundError[AureonNotFoundError HTTP 404]
16
+ AureonError --> AureonConflictError[AureonConflictError HTTP 409]
17
+ AureonError --> AureonNetworkError[AureonNetworkError DNS / Connect]
18
+ AureonError --> AureonTimeoutError[AureonTimeoutError Abort / Limit]
19
+ ```
20
+
21
+ ### Property Reference
22
+
23
+ ```ts
24
+ export class AureonError extends Error {
25
+ /** Stable error code string. Use this for programmatic branching. */
26
+ readonly code: AureonErrorCode;
27
+ /** HTTP status code from the server, or null for network failures. */
28
+ readonly status: number | null;
29
+ /** Additional key-value metadata returned by the API (e.g. form fields validation). */
30
+ readonly details: Record<string, unknown> | null;
31
+ /** Indicates whether the request can be retried immediately. */
32
+ readonly retryable: boolean;
33
+
34
+ constructor(
35
+ message: string,
36
+ code: AureonErrorCode,
37
+ status: number | null = null,
38
+ details: Record<string, unknown> | null = null
39
+ ) {
40
+ super(message);
41
+ this.name = this.constructor.name;
42
+ this.code = code;
43
+ this.status = status;
44
+ this.details = details;
45
+ this.retryable = isRetryableCode(code);
46
+
47
+ // Capture stack trace, preserving original V8 exception stack where supported
48
+ if (Error.captureStackTrace) {
49
+ Error.captureStackTrace(this, this.constructor);
50
+ }
51
+ }
52
+ }
53
+ ```
54
+
55
+ ---
56
+
57
+ ## 2. API JSON Error Payload Formats
58
+
59
+ When an API request fails, the gateway returns a structured JSON payload. The SDK's HTTP transport layer automatically parses this payload and maps it to the appropriate error class.
60
+
61
+ ### 2.1 Validation Error Payload (HTTP 400)
62
+ Returned when objective creation weights, names, or tolerances violate system rules.
63
+
64
+ ```json
65
+ {
66
+ "code": "VALIDATION_ERROR",
67
+ "message": "Create objective parameters failed validation checks",
68
+ "details": {
69
+ "name": "Objective display name must be at least 3 characters long",
70
+ "targetWeight": "Weight must be a number between 0.0 and 1.0",
71
+ "tolerance": "Tolerance must be a number between 0.0 and 0.5"
72
+ }
73
+ }
74
+ ```
75
+
76
+ ### 2.2 Conflict Error Payload (HTTP 409)
77
+ Returned when modifying a resource that is currently locked or undergoing execution.
78
+
79
+ ```json
80
+ {
81
+ "code": "CONFLICT",
82
+ "message": "Cannot modify objective state while rebalance swap is processing",
83
+ "details": {
84
+ "objectiveId": "obj_01h8v12x8p8p3z2v1q45r3m2e1",
85
+ "executionId": "exec_01h8v5t7p8p3z2v1q45r3m2e99",
86
+ "status": "pending_confirmation"
87
+ }
88
+ }
89
+ ```
90
+
91
+ ### 2.3 Rate Limit Payload (HTTP 429)
92
+ Returned when requests exceed rate limits.
93
+
94
+ ```json
95
+ {
96
+ "code": "RATE_LIMITED",
97
+ "message": "Too many requests. Please slow down.",
98
+ "details": {
99
+ "retryAfterSeconds": 15,
100
+ "limit": 100,
101
+ "windowMs": 60000
102
+ }
103
+ }
104
+ ```
105
+
106
+ ---
107
+
108
+ ## 3. Custom Diagnostics and Logging Hooks
109
+
110
+ Integrators can register a logger interface during client construction to track network requests, retries, and errors in production.
111
+
112
+ ```ts
113
+ import { createAureonClient, AureonLogger } from "@buildaureon/sdk";
114
+
115
+ const productionLogger: AureonLogger = {
116
+ debug(msg, ctx) { console.debug(`[DEBUG] ${msg}`, ctx || ""); },
117
+ info(msg, ctx) { console.info(`[INFO] ${msg}`, ctx || ""); },
118
+ warn(msg, ctx) { console.warn(`[WARN] ${msg}`, ctx || ""); },
119
+ error(msg, ctx) {
120
+ // Send critical anomalies to third-party alert services
121
+ if (ctx?.code === "SERVER_ERROR" || ctx?.code === "CONFLICT") {
122
+ sendToSentry(msg, ctx);
123
+ }
124
+ console.error(`[ERROR] ${msg}`, ctx || "");
125
+ }
126
+ };
127
+
128
+ const aureon = createAureonClient({
129
+ apiKey: process.env.AUREON_API_KEY,
130
+ logger: productionLogger
131
+ });
132
+ ```
133
+
134
+ ---
135
+
136
+ ## 4. Operational Recovery Patterns
137
+
138
+ ```mermaid
139
+ flowchart TD
140
+ Catch[Catch AureonError] --> CodeBranch{Switch error.code}
141
+
142
+ CodeBranch -->|UNAUTHORIZED| HandleAuth[Clear storage and restart EIP-191 signature challenge]
143
+ CodeBranch -->|VALIDATION_ERROR| HandleValidation[Parse details dictionary and highlight fields in UI]
144
+ CodeBranch -->|NOT_FOUND| HandleNotFound[Redirect to list and show warning toast]
145
+ CodeBranch -->|RATE_LIMITED| HandleRate[Wait retryAfterSeconds or exponential backoff then retry]
146
+ CodeBranch -->|TIMEOUT| HandleTimeout[Increase timeoutMs client configuration and retry]
147
+ CodeBranch -->|SERVER_ERROR| HandleServer[Alert ops team and fallback to staged settlement]
148
+ ```
149
+
150
+ ---
151
+
152
+ ## 5. Unit Testing and Mocking Guide
153
+
154
+ When writing tests for your agent rebalancing scripts, you can assert error handling behavior using mock response status codes.
155
+
156
+ ```ts
157
+ import { describe, it } from "node:test";
158
+ import assert from "node:assert";
159
+ import { AureonClient, AureonValidationError, isAureonError } from "@buildaureon/sdk";
160
+
161
+ describe("SDK Error Handling Tests", () => {
162
+ it("should throw AureonValidationError on empty objective name", async () => {
163
+ const client = new AureonClient({ baseUrl: "https://api.aureonlabs.network" });
164
+
165
+ try {
166
+ await client.createObjective({
167
+ name: " ", // Empty string
168
+ kind: "stable_allocation",
169
+ targetWeight: 0.2,
170
+ tolerance: 0.02
171
+ });
172
+ assert.fail("Should have failed pre-flight validation");
173
+ } catch (err) {
174
+ assert.ok(isAureonError(err));
175
+ assert.strictEqual(err.code, "VALIDATION_ERROR");
176
+ assert.ok(err instanceof AureonValidationError);
177
+ assert.match(err.message, /length/);
178
+ }
179
+ });
180
+ });
181
+ ```
182
+ Using programmatic switches on `error.code` ensures your code resists backend modifications.
@@ -0,0 +1,196 @@
1
+ # Production Integration Guide
2
+
3
+ This guide details how to integrate `@buildaureon/sdk` into server-side agents, automated rebalancing scripts, and frontend user interfaces.
4
+
5
+ ---
6
+
7
+ ## 1. End-to-End Integration Plan
8
+
9
+ Follow this six-step sequence to configure and start the automated rebalancing loop.
10
+
11
+ ```mermaid
12
+ flowchart TD
13
+ Client[1. Client Init] --> Auth[2. Sign Handshake]
14
+ Auth --> Sync[3. Sync Capital Book]
15
+ Sync --> Deposit[4. Fund Vault]
16
+ Deposit --> Objective[5. Add Objective]
17
+ Objective --> Watchdog[6. Run Heartbeat Loop]
18
+ Watchdog --> Watchdog
19
+ ```
20
+
21
+ ### Step 1: Client Construction
22
+ Set up the client, leveraging environment variables for configuration options.
23
+
24
+ ```ts
25
+ import { createAureonClient, createSessionTokenProvider } from "@buildaureon/sdk";
26
+
27
+ const session = createSessionTokenProvider(
28
+ typeof localStorage !== "undefined"
29
+ ? localStorage.getItem("aureon_bearer_token")
30
+ : process.env.AUREON_TOKEN ?? null
31
+ );
32
+
33
+ export const aureon = createAureonClient({
34
+ baseUrl: process.env.AUREON_API_URL || "https://api.aureonlabs.network",
35
+ apiKey: process.env.AUREON_API_KEY ?? null,
36
+ getAccessToken: session.getAccessToken
37
+ });
38
+ ```
39
+
40
+ ### Step 2: EIP-191 Cryptographic Verification
41
+ Authenticate session tokens using cryptographic challenge-response verification.
42
+
43
+ ```ts
44
+ async function authenticate(walletAddress: string, signerFn: (msg: string) => Promise<string>) {
45
+ // 1. Fetch challenge message
46
+ const { message } = await aureon.getAuthNonce(walletAddress);
47
+
48
+ // 2. Sign EIP-191 personal message locally
49
+ const signature = await signerFn(message);
50
+
51
+ // 3. Post verification payload
52
+ const { token } = await aureon.verifyWallet({
53
+ address: walletAddress,
54
+ message,
55
+ signature
56
+ });
57
+
58
+ session.setToken(token);
59
+ return token;
60
+ }
61
+ ```
62
+
63
+ ### Step 3: Align the Capital Book
64
+ Populate local assets into the gateway database.
65
+
66
+ ```ts
67
+ const { portfolio, chainId } = await aureon.syncPortfolio();
68
+ console.log(`Portfolios aligned for Chain ID ${chainId}. Total Valuation: $${portfolio.totalNotionalUsd}`);
69
+ ```
70
+
71
+ ### Step 4: Fund the Smart Vault
72
+ Automated objectives rebalance tokens held in your Smart Vault on the Robinhood Chain. Allocate capital into the vault before creating rules.
73
+
74
+ ```ts
75
+ async function ensureVaultFunded(symbol: string, amount: string, executeTx: (step: any) => Promise<string>) {
76
+ const status = await aureon.getVaultStatus();
77
+ if (status.empty) {
78
+ const prep = await aureon.prepareVaultDeposit({ symbol, amount });
79
+ for (const step of prep.steps) {
80
+ console.log(`Executing step: ${step.label}`);
81
+ const txHash = await executeTx(step);
82
+ console.log(`Step complete. Hash: ${txHash}`);
83
+ }
84
+ }
85
+ }
86
+ ```
87
+
88
+ ### Step 5: Register the Objective
89
+ Create the objective. SDK integrations default to `automationMode: "auto"`.
90
+
91
+ ```ts
92
+ const objective = await aureon.createObjective({
93
+ name: "Liquid Stable Reserves",
94
+ kind: "stable_allocation",
95
+ targetWeight: 0.30,
96
+ tolerance: 0.03
97
+ });
98
+ console.log(`Objective ${objective.name} registered. Status: ${objective.status}`);
99
+ ```
100
+
101
+ ### Step 6: Execute the Watchdog Loop
102
+ Poll the gateway regularly to check policy health and execute restorations.
103
+
104
+ ```ts
105
+ async function watchdogHeartbeat() {
106
+ try {
107
+ const result = await aureon.refreshWatchdog();
108
+ console.log(`Watchdog completed at ${result.refreshedAt}. System state: ${result.breaches.length} breaches.`);
109
+
110
+ for (const breach of result.breaches) {
111
+ const plan = await aureon.getRestorePlan(breach.objectiveId);
112
+ if (plan.kind === "vault_swap") {
113
+ const receipt = await aureon.restoreObjective(breach.objectiveId);
114
+ console.log(`Rebalance executed. Settlement: ${receipt.settlement}, Hash: ${receipt.transactionHash}`);
115
+ }
116
+ }
117
+ } catch (error) {
118
+ console.error("Watchdog heartbeat failed:", error);
119
+ }
120
+ }
121
+ ```
122
+
123
+ ---
124
+
125
+ ## 2. Advanced Scripting Guidelines
126
+
127
+ ### 2.1 Implementing daemon runners
128
+ For long-running processes, wrap the heartbeat logic in daemon controllers like PM2 or run them as systemd services.
129
+
130
+ #### PM2 Configuration (`ecosystem.config.js`)
131
+ ```js
132
+ module.exports = {
133
+ apps: [{
134
+ name: "aureon-agent-loop",
135
+ script: "./dist/index.js",
136
+ instances: 1,
137
+ autorestart: true,
138
+ watch: false,
139
+ env: {
140
+ NODE_ENV: "production",
141
+ AUREON_API_URL: "https://api.aureonlabs.network"
142
+ }
143
+ }]
144
+ };
145
+ ```
146
+
147
+ #### Systemd Service (`/etc/systemd/system/aureon.service`)
148
+ ```ini
149
+ [Unit]
150
+ Description=Aureon Rebalance Watchdog Daemon
151
+ After=network.target
152
+
153
+ [Service]
154
+ Type=simple
155
+ User=node
156
+ WorkingDirectory=/home/node/app
157
+ ExecStart=/usr/bin/node dist/index.js
158
+ Restart=on-failure
159
+ RestartSec=10
160
+ Environment=NODE_ENV=production
161
+
162
+ [Install]
163
+ WantedBy=multi-user.target
164
+ ```
165
+
166
+ ### 2.2 Server-Side Logger Configuration (Pino / Winston)
167
+ Log JSON payloads to persistent logging collectors.
168
+
169
+ ```ts
170
+ import winston from "winston";
171
+ import { createAureonClient } from "@buildaureon/sdk";
172
+
173
+ const logger = winston.createLogger({
174
+ level: "info",
175
+ format: winston.format.json(),
176
+ transports: [new winston.transports.File({ filename: "aureon-combined.log" })]
177
+ });
178
+
179
+ const aureon = createAureonClient({
180
+ apiKey: process.env.AUREON_API_KEY,
181
+ logger: {
182
+ debug: (msg, ctx) => logger.debug(msg, ctx),
183
+ info: (msg, ctx) => logger.info(msg, ctx),
184
+ warn: (msg, ctx) => logger.warn(msg, ctx),
185
+ error: (msg, ctx) => logger.error(msg, ctx)
186
+ }
187
+ });
188
+ ```
189
+
190
+ ---
191
+
192
+ ## 3. Frontend Deployment (SPA/Vite Environments)
193
+
194
+ * **Credential Leakage Prevention**: Never commit `AUREON_API_KEY` to public repositories. Deploy client credentials via backend server API proxy routes.
195
+ * **CORS Configurations**: The production gateway allows request origins matching allowlisted domains configured in the Developer console. For local development, localhost calls are permitted.
196
+ * **Decoupled loop execution**: Frontend interfaces should only allow users to manage objectives and inspect histories. Keep the active rebalancing loops (`refreshWatchdog` and `restoreObjective`) on secure server-side cron loops.
@@ -0,0 +1,74 @@
1
+ # Security Model and Practices
2
+
3
+ This document outlines the security architecture of `@buildaureon/sdk`, its integration with Smart Vault smart contracts, and practices for secure production environments.
4
+
5
+ ---
6
+
7
+ ## 1. Gateway Trust Boundaries
8
+
9
+ AUREON operates on a non-custodial gateway model. The API acts as an analytical policy engine, price indexer, and coordinator, but does not control asset custody.
10
+
11
+ ```mermaid
12
+ flowchart TD
13
+ Host[Host Application Boundary] -->|1. Request Calldata| Gateway[Aureon API Gateway]
14
+ Gateway -->|2. Generate Unsigned Steps| Host
15
+ Host -->|3. Sign Locally| Wallet[Private Key / HSM / KMS]
16
+ Wallet -->|4. Broadcast Tx| Chain[Robinhood Chain RPC]
17
+
18
+ subgraph OnChain [Smart Contract Controls]
19
+ Vault[Smart Vault Contract]
20
+ DX[Decentralized Exchanges]
21
+ Vault -->|Only allowlisted actions| DX
22
+ end
23
+ Wallet -.->|Call deposit / withdraw| Vault
24
+ ```
25
+
26
+ ### 1.1 Private Key Isolation
27
+ The SDK provides no features for loading or storing private keys or mnemonics. The host application handles transaction signing locally using EIP-191 signatures or raw transaction serializers. Because private keys are never transmitted to the AUREON API, a gateway breach cannot compromise user keys.
28
+
29
+ ### 1.2 Unsigned Calldata Generation
30
+ Endpoints like `prepareVaultDeposit` and `prepareVaultWithdraw` return structured calldata. You can decode and verify this data against open-source contract ABIs before signing and broadcasting.
31
+
32
+ ---
33
+
34
+ ## 2. Smart Contract Access Control
35
+
36
+ The AUREON Smart Vault contracts on the Robinhood Chain enforce strict permission boundaries:
37
+
38
+ * **Owner Gate**: Only the address that deployed the vault (or was assigned ownership) can execute direct withdrawals.
39
+ * **Allowlisted Keepers**: Swap routes can only be executed by registered keeper addresses. The keeper cannot withdraw tokens to external third-party addresses; they are restricted to swapping allowlisted assets within the vault.
40
+ * **Limits and Slippage**: The contracts enforce maximum slippage tolerances on swaps to prevent sandwich attacks and price manipulation.
41
+
42
+ ---
43
+
44
+ ## 3. Credentials and API Keys Management
45
+
46
+ * **Zero Commits**: Never check API keys into git repositories. Load keys from environment variables or secure stores (e.g. AWS Secrets Manager, HashiCorp Vault).
47
+ * **CI/CD Configuration**: If you run tests in automated pipelines (e.g., GitHub Actions, GitLab CI), store credentials as encrypted secrets.
48
+ * **Frontend Mitigation**: Frontends should query an intermediate backend service instead of exposing API keys directly to the client bundle.
49
+ * **Key Rotation**: Generate replacement credentials and deprecate compromised tokens in the developer console immediately if a breach is suspected.
50
+
51
+ ---
52
+
53
+ ## 4. Understanding Staged Settlement
54
+
55
+ AUREON receipts contain a `settlement` field:
56
+
57
+ * **Vault Settlement (`vault`)**: Transactions are settled on-chain on the Robinhood Chain. These have a real transaction hash and are verifiable via explorer.
58
+ * **Staged Settlement (`staged`)**: Simulated rebalances that update gateway database states without broadcasting transactions. This is used during rehearsals and testing.
59
+
60
+ > [!WARNING]
61
+ > Do not display staged rebalances as completed on-chain transactions in your dashboards. Always check the `settlement` attribute before presenting transaction confirmations to operators.
62
+
63
+ ---
64
+
65
+ ## 5. Production Checklist
66
+
67
+ Review this security checklist before deploying your rebalancing daemon to production:
68
+
69
+ - [ ] **Private Key Isolation**: Confirm that private keys are stored in environment variables or KMS, and are never logged or exposed.
70
+ - [ ] **EIP-191 Handshake**: Ensure all user logins use the cryptographic challenge-response flow (`verifyWallet`).
71
+ - [ ] **Scope Checks**: Verify that the API Key has the minimum permissions needed to run the target agent.
72
+ - [ ] **Gas Auditing**: Maintain a gas reserve on the signing wallet to cover deposit and withdrawal transactions on the Robinhood Chain.
73
+ - [ ] **Staged Handling**: Confirm your user interface clearly distinguishes between staged and vault settlements.
74
+ - [ ] **Slippage Bounds**: Configure appropriate slippage tolerances on objectives to prevent execution failure during market volatility.
@@ -0,0 +1,128 @@
1
+ # Transport Layer Reference
2
+
3
+ This document describes the transport layer of `@buildaureon/sdk`, implemented in `src/transport/http.ts`.
4
+
5
+ ---
6
+
7
+ ## 1. Network Request Lifecycle
8
+
9
+ Every SDK client call delegates network execution to the `requestJson` helper.
10
+
11
+ ```mermaid
12
+ flowchart TD
13
+ Call[Client Method Call] --> Prep[Join URL & Compile Headers]
14
+ Prep --> Auth[Resolve Bearer Token]
15
+ Auth --> Abort[Set AbortController Timer]
16
+ Abort --> Fetch[Execute fetchImpl]
17
+ Fetch --> Code{HTTP Status OK?}
18
+ Code -->|Yes| Parse[Parse Response JSON]
19
+ Code -->|No| Map[map Status to AureonError]
20
+ Map --> Retry{Is Error Retryable?}
21
+ Retry -->|Yes| Sleep[Sleep retryDelayMs]
22
+ Sleep --> Fetch
23
+ Retry -->|No| Throw[Throw Custom Exception]
24
+ ```
25
+
26
+ 1. **URL Join and Query Compilation**: The transport engine normalizes the base URL and path string, then serializes any query parameters.
27
+ 2. **Bearer Token Resolution**: The `getAccessToken` async function evaluates the current session token to attach the `Authorization` header.
28
+ 3. **Timeout Guard Configuration**: An `AbortController` handles request timeouts, defaulting to 30 seconds.
29
+ 4. **Execution and Error Mapping**: The client fires the request. If the gateway returns an error, it is converted to a typed `AureonError` subclass.
30
+ 5. **Bounded Retry**: The client retries the request if it encountered a transient failure (e.g. rate limit, gateway timeout) and retry budget is remaining.
31
+
32
+ ---
33
+
34
+ ## 2. Standard Header Layout
35
+
36
+ Every HTTP request sent by the SDK contains these default headers:
37
+
38
+ | Header | Required | Typical Value | Purpose |
39
+ |--------|----------|---------------|---------|
40
+ | `Accept` | Yes | `application/json` | Specifies the accepted media type. |
41
+ | `Content-Type` | Optional | `application/json` | Specifies the payload format (attached if a request body is present). |
42
+ | `X-Aureon-SDK` | Yes | `@buildaureon/sdk/0.1.0` | Identifies client package version. |
43
+ | `X-Aureon-Api-Key` | Optional | `api_key_abc123` | Sent if the client is configured with an API key. |
44
+ | `Authorization` | Optional | `Bearer token_xyz` | Session JWT, attached if a token provider is active. |
45
+
46
+ ---
47
+
48
+ ## 3. URL Utility Implementations
49
+
50
+ ### 3.1 `joinUrl`
51
+ Normalizes base URLs and paths to prevent double slashes at joining boundaries:
52
+ ```ts
53
+ function joinUrl(base: string, path: string): string {
54
+ const cleanBase = base.endsWith("/") ? base.slice(0, -1) : base;
55
+ const cleanPath = path.startsWith("/") ? path.slice(1) : path;
56
+ return `${cleanBase}/${cleanPath}`;
57
+ }
58
+ ```
59
+
60
+ ### 3.2 `withQuery`
61
+ Serializes query parameter dictionaries into standard URL format:
62
+ ```ts
63
+ function withQuery(path: string, query?: Record<string, any>): string {
64
+ if (!query) return path;
65
+ const parts = Object.entries(query)
66
+ .filter(([_, v]) => v !== undefined && v !== null)
67
+ .map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`);
68
+ if (parts.length === 0) return path;
69
+ const separator = path.includes("?") ? "&" : "?";
70
+ return `${path}${separator}${parts.join("&")}`;
71
+ }
72
+ ```
73
+
74
+ ---
75
+
76
+ ## 4. Timeout Budgets and Request Aborts
77
+
78
+ The transport engine protects applications from hanging sockets using the Fetch API's `AbortController` signal.
79
+
80
+ ```ts
81
+ const controller = new AbortController();
82
+ const timeoutId = setTimeout(() => controller.abort(), options.timeoutMs);
83
+
84
+ try {
85
+ const response = await options.fetchImpl(url, {
86
+ ...init,
87
+ signal: controller.signal
88
+ });
89
+ return response;
90
+ } catch (error) {
91
+ if (error instanceof Error && error.name === "AbortError") {
92
+ throw new AureonTimeoutError("Request timed out", options.timeoutMs);
93
+ }
94
+ throw new AureonNetworkError(error instanceof Error ? error.message : String(error));
95
+ } finally {
96
+ clearTimeout(timeoutId);
97
+ }
98
+ ```
99
+
100
+ * **Configuring Timeout**: Pass `timeoutMs` (in milliseconds) when instantiating `createAureonClient`.
101
+ * **Custom Abort Signals**: You can pass a custom `AbortSignal` in `RequestOptions` to cancel requests manually based on user actions.
102
+
103
+ ---
104
+
105
+ ## 5. Retry Loop and Backoff Configurations
106
+
107
+ The SDK implements a retry mechanism for transient exceptions:
108
+
109
+ * **Retryable Failures**: `NETWORK_ERROR`, `TIMEOUT`, `RATE_LIMITED` (HTTP 429), and `SERVER_ERROR` (HTTP 5xx).
110
+ * **Default Behavior**: `maxRetries` is 0. If you configure `maxRetries: 2` and `retryDelayMs: 500`, the client will try the request up to 3 times, waiting 500ms between attempts.
111
+
112
+ ---
113
+
114
+ ## 6. Built-in Logger Adapters
115
+
116
+ Integrate with internal request diagnostics using the `AureonLogger` interface:
117
+
118
+ ```ts
119
+ export interface AureonLogger {
120
+ debug(message: string, context?: Record<string, unknown>): void;
121
+ info(message: string, context?: Record<string, unknown>): void;
122
+ warn(message: string, context?: Record<string, unknown>): void;
123
+ error(message: string, context?: Record<string, unknown>): void;
124
+ }
125
+ ```
126
+
127
+ * `createConsoleLogger(prefix)`: Logs requests, attempts, and errors to the developer console.
128
+ * `silentLogger`: Suppresses logs.