@axonflow/sdk 1.11.1 → 1.12.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.
Files changed (43) hide show
  1. package/dist/cjs/client.d.ts +199 -1
  2. package/dist/cjs/client.d.ts.map +1 -1
  3. package/dist/cjs/client.js +609 -0
  4. package/dist/cjs/client.js.map +1 -1
  5. package/dist/cjs/index.d.ts +2 -0
  6. package/dist/cjs/index.d.ts.map +1 -1
  7. package/dist/cjs/index.js.map +1 -1
  8. package/dist/cjs/types/config.d.ts +5 -0
  9. package/dist/cjs/types/config.d.ts.map +1 -1
  10. package/dist/cjs/types/cost-controls.d.ts +142 -0
  11. package/dist/cjs/types/cost-controls.d.ts.map +1 -0
  12. package/dist/cjs/types/cost-controls.js +6 -0
  13. package/dist/cjs/types/cost-controls.js.map +1 -0
  14. package/dist/cjs/types/execution-replay.d.ts +162 -0
  15. package/dist/cjs/types/execution-replay.d.ts.map +1 -0
  16. package/dist/cjs/types/execution-replay.js +9 -0
  17. package/dist/cjs/types/execution-replay.js.map +1 -0
  18. package/dist/cjs/types/index.d.ts +2 -0
  19. package/dist/cjs/types/index.d.ts.map +1 -1
  20. package/dist/cjs/types/index.js +2 -0
  21. package/dist/cjs/types/index.js.map +1 -1
  22. package/dist/esm/client.d.ts +199 -1
  23. package/dist/esm/client.d.ts.map +1 -1
  24. package/dist/esm/client.js +609 -0
  25. package/dist/esm/client.js.map +1 -1
  26. package/dist/esm/index.d.ts +2 -0
  27. package/dist/esm/index.d.ts.map +1 -1
  28. package/dist/esm/index.js.map +1 -1
  29. package/dist/esm/types/config.d.ts +5 -0
  30. package/dist/esm/types/config.d.ts.map +1 -1
  31. package/dist/esm/types/cost-controls.d.ts +142 -0
  32. package/dist/esm/types/cost-controls.d.ts.map +1 -0
  33. package/dist/esm/types/cost-controls.js +5 -0
  34. package/dist/esm/types/cost-controls.js.map +1 -0
  35. package/dist/esm/types/execution-replay.d.ts +162 -0
  36. package/dist/esm/types/execution-replay.d.ts.map +1 -0
  37. package/dist/esm/types/execution-replay.js +8 -0
  38. package/dist/esm/types/execution-replay.js.map +1 -0
  39. package/dist/esm/types/index.d.ts +2 -0
  40. package/dist/esm/types/index.d.ts.map +1 -1
  41. package/dist/esm/types/index.js +2 -0
  42. package/dist/esm/types/index.js.map +1 -1
  43. package/package.json +1 -1
@@ -18,6 +18,7 @@ export class AxonFlow {
18
18
  apiKey: config.apiKey,
19
19
  licenseKey: config.licenseKey,
20
20
  endpoint,
21
+ orchestratorEndpoint: config.orchestratorEndpoint,
21
22
  mode: config.mode || (hasCredentials ? 'production' : 'sandbox'),
22
23
  tenant: config.tenant || 'default',
23
24
  debug: config.debug || false,
@@ -1740,5 +1741,613 @@ export class AxonFlow {
1740
1741
  exportedAt: response.exported_at,
1741
1742
  };
1742
1743
  }
1744
+ // ============================================================================
1745
+ // Execution Replay Methods
1746
+ // ============================================================================
1747
+ /**
1748
+ * Get the orchestrator URL for Execution Replay API.
1749
+ * Falls back to agent endpoint with port 8081 if not configured.
1750
+ */
1751
+ getOrchestratorUrl() {
1752
+ if (this.config.orchestratorEndpoint) {
1753
+ return this.config.orchestratorEndpoint;
1754
+ }
1755
+ // Default: assume orchestrator is on same host as agent, port 8081
1756
+ try {
1757
+ const url = new URL(this.config.endpoint);
1758
+ url.port = '8081';
1759
+ return url.toString().replace(/\/$/, '');
1760
+ }
1761
+ catch {
1762
+ return 'http://localhost:8081';
1763
+ }
1764
+ }
1765
+ /**
1766
+ * Generic HTTP request helper for orchestrator APIs
1767
+ */
1768
+ async orchestratorRequest(method, path, body) {
1769
+ const url = `${this.getOrchestratorUrl()}${path}`;
1770
+ const headers = this.buildAuthHeaders();
1771
+ const options = {
1772
+ method,
1773
+ headers,
1774
+ signal: AbortSignal.timeout(this.config.timeout),
1775
+ };
1776
+ if (body && (method === 'POST' || method === 'PUT' || method === 'PATCH')) {
1777
+ options.body = JSON.stringify(body);
1778
+ }
1779
+ const response = await fetch(url, options);
1780
+ if (!response.ok) {
1781
+ const errorText = await response.text();
1782
+ if (response.status === 401 || response.status === 403) {
1783
+ throw new AuthenticationError(`Request failed: ${errorText}`);
1784
+ }
1785
+ if (response.status === 404) {
1786
+ throw new APIError(404, 'Not Found', errorText);
1787
+ }
1788
+ throw new APIError(response.status, response.statusText, errorText);
1789
+ }
1790
+ // Handle DELETE responses with no body
1791
+ if (response.status === 204 || method === 'DELETE') {
1792
+ return undefined;
1793
+ }
1794
+ return response.json();
1795
+ }
1796
+ /**
1797
+ * List workflow executions with optional filtering and pagination.
1798
+ *
1799
+ * @param options - Filtering and pagination options
1800
+ * @returns Paginated list of execution summaries
1801
+ *
1802
+ * @example
1803
+ * ```typescript
1804
+ * // List completed executions
1805
+ * const { executions, total } = await axonflow.listExecutions({
1806
+ * status: 'completed',
1807
+ * limit: 10
1808
+ * });
1809
+ *
1810
+ * for (const exec of executions) {
1811
+ * console.log(`${exec.requestId}: ${exec.status} (${exec.totalSteps} steps)`);
1812
+ * }
1813
+ * ```
1814
+ */
1815
+ async listExecutions(options) {
1816
+ const params = new URLSearchParams();
1817
+ if (options?.limit)
1818
+ params.set('limit', String(options.limit));
1819
+ if (options?.offset)
1820
+ params.set('offset', String(options.offset));
1821
+ if (options?.status)
1822
+ params.set('status', options.status);
1823
+ if (options?.workflowId)
1824
+ params.set('workflow_id', options.workflowId);
1825
+ if (options?.startTime)
1826
+ params.set('start_time', options.startTime);
1827
+ if (options?.endTime)
1828
+ params.set('end_time', options.endTime);
1829
+ const queryString = params.toString();
1830
+ const path = `/api/v1/executions${queryString ? `?${queryString}` : ''}`;
1831
+ if (this.config.debug) {
1832
+ debugLog('Listing executions', { options });
1833
+ }
1834
+ const response = await this.orchestratorRequest('GET', path);
1835
+ return {
1836
+ executions: (response.executions || []).map(e => ({
1837
+ requestId: e.request_id,
1838
+ workflowName: e.workflow_name,
1839
+ status: e.status,
1840
+ totalSteps: e.total_steps,
1841
+ completedSteps: e.completed_steps,
1842
+ startedAt: e.started_at,
1843
+ completedAt: e.completed_at,
1844
+ durationMs: e.duration_ms,
1845
+ totalTokens: e.total_tokens,
1846
+ totalCostUsd: e.total_cost_usd,
1847
+ orgId: e.org_id,
1848
+ tenantId: e.tenant_id,
1849
+ userId: e.user_id,
1850
+ errorMessage: e.error_message,
1851
+ inputSummary: e.input_summary,
1852
+ outputSummary: e.output_summary,
1853
+ })),
1854
+ total: response.total,
1855
+ limit: response.limit,
1856
+ offset: response.offset,
1857
+ };
1858
+ }
1859
+ /**
1860
+ * Get a complete execution record including summary and all steps.
1861
+ *
1862
+ * @param executionId - Execution ID (request_id)
1863
+ * @returns Full execution details with all step snapshots
1864
+ *
1865
+ * @example
1866
+ * ```typescript
1867
+ * const execution = await axonflow.getExecution('exec-abc123');
1868
+ * console.log(`Execution: ${execution.summary.requestId} - ${execution.summary.status}`);
1869
+ *
1870
+ * for (const step of execution.steps) {
1871
+ * console.log(` Step ${step.stepIndex}: ${step.stepName} (${step.durationMs}ms)`);
1872
+ * }
1873
+ * ```
1874
+ */
1875
+ async getExecution(executionId) {
1876
+ if (this.config.debug) {
1877
+ debugLog('Getting execution', { executionId });
1878
+ }
1879
+ const response = await this.orchestratorRequest('GET', `/api/v1/executions/${executionId}`);
1880
+ return {
1881
+ summary: {
1882
+ requestId: response.summary.request_id,
1883
+ workflowName: response.summary.workflow_name,
1884
+ status: response.summary.status,
1885
+ totalSteps: response.summary.total_steps,
1886
+ completedSteps: response.summary.completed_steps,
1887
+ startedAt: response.summary.started_at,
1888
+ completedAt: response.summary.completed_at,
1889
+ durationMs: response.summary.duration_ms,
1890
+ totalTokens: response.summary.total_tokens,
1891
+ totalCostUsd: response.summary.total_cost_usd,
1892
+ orgId: response.summary.org_id,
1893
+ tenantId: response.summary.tenant_id,
1894
+ userId: response.summary.user_id,
1895
+ errorMessage: response.summary.error_message,
1896
+ inputSummary: response.summary.input_summary,
1897
+ outputSummary: response.summary.output_summary,
1898
+ },
1899
+ steps: response.steps.map(s => ({
1900
+ requestId: s.request_id,
1901
+ stepIndex: s.step_index,
1902
+ stepName: s.step_name,
1903
+ status: s.status,
1904
+ startedAt: s.started_at,
1905
+ completedAt: s.completed_at,
1906
+ durationMs: s.duration_ms,
1907
+ provider: s.provider,
1908
+ model: s.model,
1909
+ tokensIn: s.tokens_in,
1910
+ tokensOut: s.tokens_out,
1911
+ costUsd: s.cost_usd,
1912
+ input: s.input,
1913
+ output: s.output,
1914
+ errorMessage: s.error_message,
1915
+ policiesChecked: s.policies_checked,
1916
+ policiesTriggered: s.policies_triggered,
1917
+ approvalRequired: s.approval_required,
1918
+ approvedBy: s.approved_by,
1919
+ approvedAt: s.approved_at,
1920
+ })),
1921
+ };
1922
+ }
1923
+ /**
1924
+ * Get all step snapshots for an execution.
1925
+ *
1926
+ * @param executionId - Execution ID (request_id)
1927
+ * @returns Array of step snapshots
1928
+ *
1929
+ * @example
1930
+ * ```typescript
1931
+ * const steps = await axonflow.getExecutionSteps('exec-abc123');
1932
+ * for (const step of steps) {
1933
+ * console.log(`Step ${step.stepIndex}: ${step.stepName} - ${step.status}`);
1934
+ * }
1935
+ * ```
1936
+ */
1937
+ async getExecutionSteps(executionId) {
1938
+ if (this.config.debug) {
1939
+ debugLog('Getting execution steps', { executionId });
1940
+ }
1941
+ const response = await this.orchestratorRequest('GET', `/api/v1/executions/${executionId}/steps`);
1942
+ return response.map(s => ({
1943
+ requestId: s.request_id,
1944
+ stepIndex: s.step_index,
1945
+ stepName: s.step_name,
1946
+ status: s.status,
1947
+ startedAt: s.started_at,
1948
+ completedAt: s.completed_at,
1949
+ durationMs: s.duration_ms,
1950
+ provider: s.provider,
1951
+ model: s.model,
1952
+ tokensIn: s.tokens_in,
1953
+ tokensOut: s.tokens_out,
1954
+ costUsd: s.cost_usd,
1955
+ input: s.input,
1956
+ output: s.output,
1957
+ errorMessage: s.error_message,
1958
+ policiesChecked: s.policies_checked,
1959
+ policiesTriggered: s.policies_triggered,
1960
+ approvalRequired: s.approval_required,
1961
+ approvedBy: s.approved_by,
1962
+ approvedAt: s.approved_at,
1963
+ }));
1964
+ }
1965
+ /**
1966
+ * Get a timeline view of execution events for visualization.
1967
+ *
1968
+ * @param executionId - Execution ID (request_id)
1969
+ * @returns Array of timeline entries
1970
+ *
1971
+ * @example
1972
+ * ```typescript
1973
+ * const timeline = await axonflow.getExecutionTimeline('exec-abc123');
1974
+ * for (const entry of timeline) {
1975
+ * let info = `[${entry.stepIndex}] ${entry.stepName}: ${entry.status}`;
1976
+ * if (entry.hasError) info += ' [ERROR]';
1977
+ * if (entry.hasApproval) info += ' [APPROVED]';
1978
+ * console.log(info);
1979
+ * }
1980
+ * ```
1981
+ */
1982
+ async getExecutionTimeline(executionId) {
1983
+ if (this.config.debug) {
1984
+ debugLog('Getting execution timeline', { executionId });
1985
+ }
1986
+ const response = await this.orchestratorRequest('GET', `/api/v1/executions/${executionId}/timeline`);
1987
+ return response.map(t => ({
1988
+ stepIndex: t.step_index,
1989
+ stepName: t.step_name,
1990
+ status: t.status,
1991
+ startedAt: t.started_at,
1992
+ completedAt: t.completed_at,
1993
+ durationMs: t.duration_ms,
1994
+ hasError: t.has_error,
1995
+ hasApproval: t.has_approval,
1996
+ }));
1997
+ }
1998
+ /**
1999
+ * Export a complete execution record for compliance or archival.
2000
+ *
2001
+ * @param executionId - Execution ID (request_id)
2002
+ * @param options - Export options
2003
+ * @returns Execution data in requested format
2004
+ *
2005
+ * @example
2006
+ * ```typescript
2007
+ * const exportData = await axonflow.exportExecution('exec-abc123', {
2008
+ * includeInput: true,
2009
+ * includeOutput: true
2010
+ * });
2011
+ *
2012
+ * // Save to file for audit
2013
+ * fs.writeFileSync('audit-export.json', JSON.stringify(exportData, null, 2));
2014
+ * ```
2015
+ */
2016
+ async exportExecution(executionId, options) {
2017
+ const params = new URLSearchParams();
2018
+ if (options?.format)
2019
+ params.set('format', options.format);
2020
+ if (options?.includeInput)
2021
+ params.set('include_input', 'true');
2022
+ if (options?.includeOutput)
2023
+ params.set('include_output', 'true');
2024
+ if (options?.includePolicies)
2025
+ params.set('include_policies', 'true');
2026
+ const queryString = params.toString();
2027
+ const path = `/api/v1/executions/${executionId}/export${queryString ? `?${queryString}` : ''}`;
2028
+ if (this.config.debug) {
2029
+ debugLog('Exporting execution', { executionId, options });
2030
+ }
2031
+ return this.orchestratorRequest('GET', path);
2032
+ }
2033
+ /**
2034
+ * Delete an execution and all associated step snapshots.
2035
+ *
2036
+ * @param executionId - Execution ID (request_id)
2037
+ *
2038
+ * @example
2039
+ * ```typescript
2040
+ * await axonflow.deleteExecution('exec-abc123');
2041
+ * console.log('Execution deleted');
2042
+ * ```
2043
+ */
2044
+ async deleteExecution(executionId) {
2045
+ if (this.config.debug) {
2046
+ debugLog('Deleting execution', { executionId });
2047
+ }
2048
+ await this.orchestratorRequest('DELETE', `/api/v1/executions/${executionId}`);
2049
+ }
2050
+ // ========================================
2051
+ // COST CONTROLS - BUDGETS
2052
+ // ========================================
2053
+ /**
2054
+ * Create a new budget.
2055
+ *
2056
+ * @param request - Budget creation request
2057
+ * @returns Created budget
2058
+ */
2059
+ async createBudget(request) {
2060
+ const body = {
2061
+ id: request.id,
2062
+ name: request.name,
2063
+ scope: request.scope,
2064
+ limit_usd: request.limitUsd,
2065
+ period: request.period,
2066
+ on_exceed: request.onExceed,
2067
+ alert_thresholds: request.alertThresholds,
2068
+ scope_id: request.scopeId,
2069
+ };
2070
+ const response = await this.orchestratorRequest('POST', '/api/v1/budgets', body);
2071
+ return this.mapBudgetResponse(response);
2072
+ }
2073
+ /**
2074
+ * Get a budget by ID.
2075
+ *
2076
+ * @param budgetId - Budget ID
2077
+ * @returns Budget
2078
+ */
2079
+ async getBudget(budgetId) {
2080
+ const response = await this.orchestratorRequest('GET', `/api/v1/budgets/${budgetId}`);
2081
+ return this.mapBudgetResponse(response);
2082
+ }
2083
+ /**
2084
+ * List all budgets.
2085
+ *
2086
+ * @param options - Filtering and pagination options
2087
+ * @returns List of budgets
2088
+ */
2089
+ async listBudgets(options) {
2090
+ const params = new URLSearchParams();
2091
+ if (options?.scope)
2092
+ params.set('scope', options.scope);
2093
+ if (options?.limit)
2094
+ params.set('limit', String(options.limit));
2095
+ if (options?.offset)
2096
+ params.set('offset', String(options.offset));
2097
+ const queryString = params.toString();
2098
+ const path = `/api/v1/budgets${queryString ? `?${queryString}` : ''}`;
2099
+ const response = await this.orchestratorRequest('GET', path);
2100
+ return {
2101
+ budgets: (response.budgets || []).map(b => this.mapBudgetResponse(b)),
2102
+ total: response.total || 0,
2103
+ };
2104
+ }
2105
+ /**
2106
+ * Update an existing budget.
2107
+ *
2108
+ * @param budgetId - Budget ID
2109
+ * @param request - Update request
2110
+ * @returns Updated budget
2111
+ */
2112
+ async updateBudget(budgetId, request) {
2113
+ const body = {};
2114
+ if (request.name !== undefined)
2115
+ body.name = request.name;
2116
+ if (request.limitUsd !== undefined)
2117
+ body.limit_usd = request.limitUsd;
2118
+ if (request.onExceed !== undefined)
2119
+ body.on_exceed = request.onExceed;
2120
+ if (request.alertThresholds !== undefined)
2121
+ body.alert_thresholds = request.alertThresholds;
2122
+ const response = await this.orchestratorRequest('PUT', `/api/v1/budgets/${budgetId}`, body);
2123
+ return this.mapBudgetResponse(response);
2124
+ }
2125
+ /**
2126
+ * Delete a budget.
2127
+ *
2128
+ * @param budgetId - Budget ID
2129
+ */
2130
+ async deleteBudget(budgetId) {
2131
+ await this.orchestratorRequest('DELETE', `/api/v1/budgets/${budgetId}`);
2132
+ }
2133
+ // ========================================
2134
+ // COST CONTROLS - BUDGET STATUS & ALERTS
2135
+ // ========================================
2136
+ /**
2137
+ * Get the current status of a budget.
2138
+ *
2139
+ * @param budgetId - Budget ID
2140
+ * @returns Budget status
2141
+ */
2142
+ async getBudgetStatus(budgetId) {
2143
+ const response = await this.orchestratorRequest('GET', `/api/v1/budgets/${budgetId}/status`);
2144
+ return {
2145
+ budget: this.mapBudgetResponse(response.budget),
2146
+ usedUsd: response.used_usd || 0,
2147
+ remainingUsd: response.remaining_usd || 0,
2148
+ percentage: response.percentage || 0,
2149
+ isExceeded: response.is_exceeded || false,
2150
+ isBlocked: response.is_blocked || false,
2151
+ periodStart: response.period_start || '',
2152
+ periodEnd: response.period_end || '',
2153
+ };
2154
+ }
2155
+ /**
2156
+ * Get alerts for a budget.
2157
+ *
2158
+ * @param budgetId - Budget ID
2159
+ * @returns Budget alerts
2160
+ */
2161
+ async getBudgetAlerts(budgetId) {
2162
+ const response = await this.orchestratorRequest('GET', `/api/v1/budgets/${budgetId}/alerts`);
2163
+ const alerts = (response.alerts || []).map((a) => ({
2164
+ id: a.id || '',
2165
+ budgetId: a.budget_id || '',
2166
+ alertType: a.alert_type || '',
2167
+ threshold: a.threshold || 0,
2168
+ percentageReached: a.percentage_reached || 0,
2169
+ amountUsd: a.amount_usd || 0,
2170
+ message: a.message || '',
2171
+ createdAt: a.created_at || '',
2172
+ }));
2173
+ return {
2174
+ alerts,
2175
+ count: response.count || 0,
2176
+ };
2177
+ }
2178
+ /**
2179
+ * Perform a pre-flight budget check.
2180
+ *
2181
+ * @param request - Check request
2182
+ * @returns Budget decision
2183
+ */
2184
+ async checkBudget(request) {
2185
+ const body = {};
2186
+ if (request.orgId)
2187
+ body.org_id = request.orgId;
2188
+ if (request.teamId)
2189
+ body.team_id = request.teamId;
2190
+ if (request.agentId)
2191
+ body.agent_id = request.agentId;
2192
+ if (request.workflowId)
2193
+ body.workflow_id = request.workflowId;
2194
+ if (request.userId)
2195
+ body.user_id = request.userId;
2196
+ const response = await this.orchestratorRequest('POST', '/api/v1/budgets/check', body);
2197
+ return {
2198
+ allowed: response.allowed || false,
2199
+ action: response.action,
2200
+ message: response.message,
2201
+ budgets: response.budgets
2202
+ ? (response.budgets || []).map(b => this.mapBudgetResponse(b))
2203
+ : undefined,
2204
+ };
2205
+ }
2206
+ // ========================================
2207
+ // COST CONTROLS - USAGE
2208
+ // ========================================
2209
+ /**
2210
+ * Get usage summary for a period.
2211
+ *
2212
+ * @param period - Period (daily, weekly, monthly, quarterly, yearly)
2213
+ * @returns Usage summary
2214
+ */
2215
+ async getUsageSummary(period) {
2216
+ const path = period ? `/api/v1/usage?period=${period}` : '/api/v1/usage';
2217
+ const response = await this.orchestratorRequest('GET', path);
2218
+ return {
2219
+ totalCostUsd: response.total_cost_usd || 0,
2220
+ totalRequests: response.total_requests || 0,
2221
+ totalTokensIn: response.total_tokens_in || 0,
2222
+ totalTokensOut: response.total_tokens_out || 0,
2223
+ averageCostPerRequest: response.average_cost_per_request || 0,
2224
+ period: response.period || '',
2225
+ periodStart: response.period_start || '',
2226
+ periodEnd: response.period_end || '',
2227
+ };
2228
+ }
2229
+ /**
2230
+ * Get usage breakdown by a grouping dimension.
2231
+ *
2232
+ * @param groupBy - Dimension to group by (provider, model, agent, team, workflow)
2233
+ * @param period - Period (daily, weekly, monthly, quarterly, yearly)
2234
+ * @returns Usage breakdown
2235
+ */
2236
+ async getUsageBreakdown(groupBy, period) {
2237
+ const params = new URLSearchParams();
2238
+ params.set('group_by', groupBy);
2239
+ if (period)
2240
+ params.set('period', period);
2241
+ const response = await this.orchestratorRequest('GET', `/api/v1/usage/breakdown?${params.toString()}`);
2242
+ const items = (response.items || []).map((i) => ({
2243
+ groupValue: i.group_value || '',
2244
+ costUsd: i.cost_usd || 0,
2245
+ percentage: i.percentage || 0,
2246
+ requestCount: i.request_count || 0,
2247
+ tokensIn: i.tokens_in || 0,
2248
+ tokensOut: i.tokens_out || 0,
2249
+ }));
2250
+ return {
2251
+ groupBy: response.group_by || '',
2252
+ totalCostUsd: response.total_cost_usd || 0,
2253
+ items,
2254
+ period: response.period || '',
2255
+ periodStart: response.period_start || '',
2256
+ periodEnd: response.period_end || '',
2257
+ };
2258
+ }
2259
+ /**
2260
+ * List usage records.
2261
+ *
2262
+ * @param options - Filtering and pagination options
2263
+ * @returns List of usage records
2264
+ */
2265
+ async listUsageRecords(options) {
2266
+ const params = new URLSearchParams();
2267
+ if (options?.limit)
2268
+ params.set('limit', String(options.limit));
2269
+ if (options?.offset)
2270
+ params.set('offset', String(options.offset));
2271
+ if (options?.provider)
2272
+ params.set('provider', options.provider);
2273
+ if (options?.model)
2274
+ params.set('model', options.model);
2275
+ const queryString = params.toString();
2276
+ const path = `/api/v1/usage/records${queryString ? `?${queryString}` : ''}`;
2277
+ const response = await this.orchestratorRequest('GET', path);
2278
+ const records = (response.records || []).map((r) => ({
2279
+ id: r.id || '',
2280
+ provider: r.provider || '',
2281
+ model: r.model || '',
2282
+ tokensIn: r.tokens_in || 0,
2283
+ tokensOut: r.tokens_out || 0,
2284
+ costUsd: r.cost_usd || 0,
2285
+ requestId: r.request_id,
2286
+ orgId: r.org_id,
2287
+ agentId: r.agent_id,
2288
+ timestamp: r.timestamp,
2289
+ }));
2290
+ return {
2291
+ records,
2292
+ total: response.total || 0,
2293
+ };
2294
+ }
2295
+ // ========================================
2296
+ // COST CONTROLS - PRICING
2297
+ // ========================================
2298
+ /**
2299
+ * Get pricing information for models.
2300
+ *
2301
+ * @param provider - Filter by provider (optional)
2302
+ * @param model - Filter by model (optional)
2303
+ * @returns Pricing information
2304
+ */
2305
+ async getPricing(provider, model) {
2306
+ const params = new URLSearchParams();
2307
+ if (provider)
2308
+ params.set('provider', provider);
2309
+ if (model)
2310
+ params.set('model', model);
2311
+ const queryString = params.toString();
2312
+ const path = `/api/v1/pricing${queryString ? `?${queryString}` : ''}`;
2313
+ const response = await this.orchestratorRequest('GET', path);
2314
+ // Handle single object vs array response
2315
+ if (response.provider !== undefined) {
2316
+ // Single object response - wrap in list
2317
+ const pricing = this.mapPricingResponse(response);
2318
+ return { pricing: [pricing] };
2319
+ }
2320
+ const pricingList = (response.pricing || []).map(p => this.mapPricingResponse(p));
2321
+ return { pricing: pricingList };
2322
+ }
2323
+ // ========================================
2324
+ // COST CONTROLS - HELPER METHODS
2325
+ // ========================================
2326
+ mapBudgetResponse(response) {
2327
+ return {
2328
+ id: response.id || '',
2329
+ name: response.name || '',
2330
+ scope: response.scope || '',
2331
+ limitUsd: response.limit_usd || 0,
2332
+ period: response.period || '',
2333
+ onExceed: response.on_exceed || '',
2334
+ alertThresholds: response.alert_thresholds || [],
2335
+ enabled: response.enabled ?? true,
2336
+ scopeId: response.scope_id,
2337
+ createdAt: response.created_at,
2338
+ updatedAt: response.updated_at,
2339
+ };
2340
+ }
2341
+ mapPricingResponse(response) {
2342
+ const pricingData = response.pricing;
2343
+ return {
2344
+ provider: response.provider || '',
2345
+ model: response.model || '',
2346
+ pricing: {
2347
+ inputPer1k: pricingData?.input_per_1k || 0,
2348
+ outputPer1k: pricingData?.output_per_1k || 0,
2349
+ },
2350
+ };
2351
+ }
1743
2352
  }
1744
2353
  //# sourceMappingURL=client.js.map