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