@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.
- package/dist/cjs/client.d.ts +199 -1
- package/dist/cjs/client.d.ts.map +1 -1
- package/dist/cjs/client.js +617 -10
- package/dist/cjs/client.js.map +1 -1
- package/dist/cjs/index.d.ts +2 -0
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/types/config.d.ts +5 -0
- package/dist/cjs/types/config.d.ts.map +1 -1
- package/dist/cjs/types/cost-controls.d.ts +142 -0
- package/dist/cjs/types/cost-controls.d.ts.map +1 -0
- package/dist/cjs/types/cost-controls.js +6 -0
- package/dist/cjs/types/cost-controls.js.map +1 -0
- package/dist/cjs/types/execution-replay.d.ts +162 -0
- package/dist/cjs/types/execution-replay.d.ts.map +1 -0
- package/dist/cjs/types/execution-replay.js +9 -0
- package/dist/cjs/types/execution-replay.js.map +1 -0
- package/dist/cjs/types/index.d.ts +2 -0
- package/dist/cjs/types/index.d.ts.map +1 -1
- package/dist/cjs/types/index.js +2 -0
- package/dist/cjs/types/index.js.map +1 -1
- package/dist/esm/client.d.ts +199 -1
- package/dist/esm/client.d.ts.map +1 -1
- package/dist/esm/client.js +617 -10
- package/dist/esm/client.js.map +1 -1
- package/dist/esm/index.d.ts +2 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/types/config.d.ts +5 -0
- package/dist/esm/types/config.d.ts.map +1 -1
- package/dist/esm/types/cost-controls.d.ts +142 -0
- package/dist/esm/types/cost-controls.d.ts.map +1 -0
- package/dist/esm/types/cost-controls.js +5 -0
- package/dist/esm/types/cost-controls.js.map +1 -0
- package/dist/esm/types/execution-replay.d.ts +162 -0
- package/dist/esm/types/execution-replay.d.ts.map +1 -0
- package/dist/esm/types/execution-replay.js +8 -0
- package/dist/esm/types/execution-replay.js.map +1 -0
- package/dist/esm/types/index.d.ts +2 -0
- package/dist/esm/types/index.d.ts.map +1 -1
- package/dist/esm/types/index.js +2 -0
- package/dist/esm/types/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cjs/client.js
CHANGED
|
@@ -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
|
|
685
|
-
|
|
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
|
|
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
|
|
777
|
-
|
|
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
|
|
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
|