@mixrpay/agent-sdk 0.8.6 → 0.8.8
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/README.md +58 -4
- package/dist/index.cjs +396 -1
- package/dist/index.d.cts +423 -2
- package/dist/index.d.ts +423 -2
- package/dist/index.js +396 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,15 +2,71 @@
|
|
|
2
2
|
|
|
3
3
|
Enable AI agents to make payments to MixrPay-powered APIs.
|
|
4
4
|
|
|
5
|
+
## Getting Started: Claim an Access Code
|
|
6
|
+
|
|
7
|
+
Agents get spending authorization by claiming an **Access Code** from a human wallet owner.
|
|
8
|
+
|
|
9
|
+
### Step 1: Human Creates Access Code
|
|
10
|
+
|
|
11
|
+
The human logs in at [mixrpay.com/manage/invites](https://www.mixrpay.com/manage/invites), deposits funds, and creates an Access Code (e.g., `mixr-abc123`) with a budget.
|
|
12
|
+
|
|
13
|
+
### Step 2: Agent Claims the Access Code
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
import { AgentWallet } from '@mixrpay/agent-sdk';
|
|
17
|
+
|
|
18
|
+
// Claim the Access Code to get your session key
|
|
19
|
+
const result = await AgentWallet.claimInvite({
|
|
20
|
+
inviteCode: 'mixr-abc123', // From the human
|
|
21
|
+
privateKey: process.env.AGENT_WALLET_KEY as `0x${string}`,
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
// IMPORTANT: Save this immediately — shown ONCE, cannot be recovered!
|
|
25
|
+
console.log('Session Key:', result.sessionKey); // sk_live_xxx
|
|
26
|
+
console.log('Budget:', result.limits.budgetUsd);
|
|
27
|
+
console.log('Invited by:', result.inviterName);
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Step 3: Use the Session Key
|
|
31
|
+
|
|
32
|
+
```typescript
|
|
33
|
+
const wallet = new AgentWallet({
|
|
34
|
+
sessionKey: result.sessionKey, // or process.env.MIXRPAY_SESSION_KEY
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
// All spending is authorized from the human's wallet
|
|
38
|
+
const response = await wallet.fetch('https://api.example.com/paid-endpoint');
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Understanding Wallet Addresses
|
|
42
|
+
|
|
43
|
+
When you claim an Access Code, two addresses are involved:
|
|
44
|
+
|
|
45
|
+
| Address | What it is | Purpose |
|
|
46
|
+
|---------|-----------|---------|
|
|
47
|
+
| `info.address` | Session key's derived address | Used for signing requests |
|
|
48
|
+
| `info.walletAddress` | Human's funded wallet | Where funds are charged FROM |
|
|
49
|
+
|
|
50
|
+
**Verify which wallet you're spending from:**
|
|
51
|
+
|
|
52
|
+
```typescript
|
|
53
|
+
const info = await wallet.getSessionKeyInfo();
|
|
54
|
+
console.log('Session key:', info.address); // Your signing key
|
|
55
|
+
console.log('Spending from:', info.walletAddress); // Human's wallet (funding source)
|
|
56
|
+
console.log('Budget remaining:', info.limits.totalUsd);
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
This is important: your session key authorizes spending from the **human's wallet**, not your own external wallet. The human controls the budget and can revoke access at any time.
|
|
60
|
+
|
|
5
61
|
## Important: Session Key Security
|
|
6
62
|
|
|
7
63
|
Your session key (`sk_live_...`) is a **private key**. Treat it like a password:
|
|
8
64
|
|
|
9
|
-
- **Save it immediately** when you receive it (from `claimInvite()`
|
|
65
|
+
- **Save it immediately** when you receive it (from `claimInvite()`)
|
|
10
66
|
- **Store it securely** (environment variable, secrets manager)
|
|
11
67
|
- **Never commit it** to version control
|
|
12
68
|
- **Never log it** to console or files
|
|
13
|
-
- **It cannot be recovered** if lost - you will need a new
|
|
69
|
+
- **It cannot be recovered** if lost - you will need a new Access Code
|
|
14
70
|
|
|
15
71
|
The session key is shown **only once** when claimed. MixrPay does not store it.
|
|
16
72
|
|
|
@@ -39,8 +95,6 @@ const response = await wallet.callMerchantApi({
|
|
|
39
95
|
const data = await response.json();
|
|
40
96
|
```
|
|
41
97
|
|
|
42
|
-
Get session keys at [mixrpay.com/wallet/sessions](https://www.mixrpay.com/wallet/sessions).
|
|
43
|
-
|
|
44
98
|
## Core Methods
|
|
45
99
|
|
|
46
100
|
```typescript
|
package/dist/index.cjs
CHANGED
|
@@ -532,7 +532,7 @@ function getAmountUsd(requirements) {
|
|
|
532
532
|
}
|
|
533
533
|
|
|
534
534
|
// src/agent-wallet.ts
|
|
535
|
-
var SDK_VERSION = "0.8.
|
|
535
|
+
var SDK_VERSION = "0.8.7";
|
|
536
536
|
var DEFAULT_BASE_URL = process.env.MIXRPAY_BASE_URL || "https://www.mixrpay.com";
|
|
537
537
|
var DEFAULT_TIMEOUT = 3e4;
|
|
538
538
|
var NETWORKS = {
|
|
@@ -1707,6 +1707,7 @@ var AgentWallet = class {
|
|
|
1707
1707
|
const data = await response.json();
|
|
1708
1708
|
this.sessionKeyInfo = {
|
|
1709
1709
|
address: this.sessionKey.address,
|
|
1710
|
+
walletAddress: data.wallet_address ?? data.walletAddress ?? null,
|
|
1710
1711
|
isValid: data.is_valid ?? data.isValid ?? true,
|
|
1711
1712
|
limits: {
|
|
1712
1713
|
perTxUsd: data.per_tx_limit_usd ?? data.perTxLimitUsd ?? null,
|
|
@@ -1731,6 +1732,7 @@ var AgentWallet = class {
|
|
|
1731
1732
|
}
|
|
1732
1733
|
return {
|
|
1733
1734
|
address: this.sessionKey.address,
|
|
1735
|
+
walletAddress: null,
|
|
1734
1736
|
isValid: true,
|
|
1735
1737
|
limits: { perTxUsd: null, dailyUsd: null, totalUsd: null },
|
|
1736
1738
|
usage: { todayUsd: this.totalSpentUsd, totalUsd: this.totalSpentUsd, txCount: this.payments.length },
|
|
@@ -2829,6 +2831,399 @@ Timestamp: ${timestamp}`;
|
|
|
2829
2831
|
};
|
|
2830
2832
|
}
|
|
2831
2833
|
// ===========================================================================
|
|
2834
|
+
// JIT Task Agent Methods
|
|
2835
|
+
// ===========================================================================
|
|
2836
|
+
/**
|
|
2837
|
+
* Deploy a JIT Task Agent - a serverless agent that executes a specific task.
|
|
2838
|
+
*
|
|
2839
|
+
* JIT Task Agents run on Cloudflare Workers and execute an agentic loop
|
|
2840
|
+
* (LLM + tools) within a budget cap. They self-destruct when complete.
|
|
2841
|
+
*
|
|
2842
|
+
* @param options - Task agent deployment options
|
|
2843
|
+
* @returns Deployed task agent instance with endpoints
|
|
2844
|
+
*
|
|
2845
|
+
* @example Basic usage
|
|
2846
|
+
* ```typescript
|
|
2847
|
+
* const result = await wallet.deployTaskAgent({
|
|
2848
|
+
* name: 'Research Agent',
|
|
2849
|
+
* prompt: 'Research the top 5 AI startups in San Francisco',
|
|
2850
|
+
* budgetUsd: 5.00,
|
|
2851
|
+
* tools: ['platform/exa-search', 'platform/firecrawl-scrape'],
|
|
2852
|
+
* });
|
|
2853
|
+
*
|
|
2854
|
+
* console.log('Task ID:', result.instance.id);
|
|
2855
|
+
* console.log('Status URL:', result.instance.statusUrl);
|
|
2856
|
+
* ```
|
|
2857
|
+
*
|
|
2858
|
+
* @example With auto-run
|
|
2859
|
+
* ```typescript
|
|
2860
|
+
* const result = await wallet.deployTaskAgent({
|
|
2861
|
+
* name: 'Data Collector',
|
|
2862
|
+
* prompt: 'Collect pricing data from competitor websites',
|
|
2863
|
+
* budgetUsd: 10.00,
|
|
2864
|
+
* tools: ['platform/firecrawl-scrape'],
|
|
2865
|
+
* autoRun: true, // Start immediately
|
|
2866
|
+
* });
|
|
2867
|
+
*
|
|
2868
|
+
* // Wait for completion
|
|
2869
|
+
* const finalResult = await wallet.waitForTaskAgent(result.instance.id);
|
|
2870
|
+
* console.log('Result:', finalResult.result);
|
|
2871
|
+
* ```
|
|
2872
|
+
*/
|
|
2873
|
+
async deployTaskAgent(options) {
|
|
2874
|
+
this.logger.debug("deployTaskAgent", { name: options.name, budgetUsd: options.budgetUsd });
|
|
2875
|
+
const authHeaders = await this.getSessionAuthHeaders();
|
|
2876
|
+
const response = await fetch(`${this.baseUrl}/api/v2/jit-task/deploy`, {
|
|
2877
|
+
method: "POST",
|
|
2878
|
+
headers: {
|
|
2879
|
+
"Content-Type": "application/json",
|
|
2880
|
+
...authHeaders
|
|
2881
|
+
},
|
|
2882
|
+
body: JSON.stringify({
|
|
2883
|
+
name: options.name,
|
|
2884
|
+
prompt: options.prompt,
|
|
2885
|
+
system_prompt: options.systemPrompt,
|
|
2886
|
+
model: options.model || "claude-sonnet-4-5",
|
|
2887
|
+
tools: options.tools || [],
|
|
2888
|
+
budget_usd: options.budgetUsd,
|
|
2889
|
+
ttl_hours: options.ttlHours || 24,
|
|
2890
|
+
max_iterations: options.maxIterations || 10,
|
|
2891
|
+
plan_id: options.planId,
|
|
2892
|
+
task_id: options.taskId,
|
|
2893
|
+
idempotency_key: options.idempotencyKey,
|
|
2894
|
+
auto_run: options.autoRun || false
|
|
2895
|
+
})
|
|
2896
|
+
});
|
|
2897
|
+
if (!response.ok) {
|
|
2898
|
+
const error = await response.json().catch(() => ({}));
|
|
2899
|
+
throw new MixrPayError(error.error || `Task agent deploy failed: ${response.status}`);
|
|
2900
|
+
}
|
|
2901
|
+
const data = await response.json();
|
|
2902
|
+
return {
|
|
2903
|
+
instance: this.parseTaskAgentInstance(data.instance),
|
|
2904
|
+
idempotent: data.idempotent || false,
|
|
2905
|
+
requestId: data.request_id
|
|
2906
|
+
};
|
|
2907
|
+
}
|
|
2908
|
+
/**
|
|
2909
|
+
* Get the status of a JIT Task Agent.
|
|
2910
|
+
*
|
|
2911
|
+
* @param instanceId - The task agent instance ID
|
|
2912
|
+
* @returns Current status and details
|
|
2913
|
+
*
|
|
2914
|
+
* @example
|
|
2915
|
+
* ```typescript
|
|
2916
|
+
* const status = await wallet.getTaskAgentStatus('cuid_abc123');
|
|
2917
|
+
* console.log('Status:', status.status);
|
|
2918
|
+
* console.log('Iterations:', status.iterations.current, '/', status.iterations.max);
|
|
2919
|
+
* console.log('Spent:', status.budget.spentUsd, '/', status.budget.totalUsd);
|
|
2920
|
+
* ```
|
|
2921
|
+
*/
|
|
2922
|
+
async getTaskAgentStatus(instanceId) {
|
|
2923
|
+
this.logger.debug("getTaskAgentStatus", { instanceId });
|
|
2924
|
+
const authHeaders = await this.getSessionAuthHeaders();
|
|
2925
|
+
const response = await fetch(`${this.baseUrl}/api/v2/jit-task/${instanceId}`, {
|
|
2926
|
+
method: "GET",
|
|
2927
|
+
headers: authHeaders
|
|
2928
|
+
});
|
|
2929
|
+
if (!response.ok) {
|
|
2930
|
+
const error = await response.json().catch(() => ({}));
|
|
2931
|
+
throw new MixrPayError(error.error || `Failed to get task status: ${response.status}`);
|
|
2932
|
+
}
|
|
2933
|
+
const data = await response.json();
|
|
2934
|
+
return this.parseTaskAgentStatus(data);
|
|
2935
|
+
}
|
|
2936
|
+
/**
|
|
2937
|
+
* Trigger execution of a JIT Task Agent.
|
|
2938
|
+
*
|
|
2939
|
+
* Only works for agents in 'active' status (not yet started).
|
|
2940
|
+
*
|
|
2941
|
+
* @param instanceId - The task agent instance ID
|
|
2942
|
+
* @returns Trigger result
|
|
2943
|
+
*
|
|
2944
|
+
* @example
|
|
2945
|
+
* ```typescript
|
|
2946
|
+
* // Deploy without auto-run
|
|
2947
|
+
* const { instance } = await wallet.deployTaskAgent({
|
|
2948
|
+
* name: 'Research',
|
|
2949
|
+
* prompt: 'Research AI trends',
|
|
2950
|
+
* budgetUsd: 5.00,
|
|
2951
|
+
* });
|
|
2952
|
+
*
|
|
2953
|
+
* // Later, trigger execution
|
|
2954
|
+
* await wallet.triggerTaskAgent(instance.id);
|
|
2955
|
+
* ```
|
|
2956
|
+
*/
|
|
2957
|
+
async triggerTaskAgent(instanceId) {
|
|
2958
|
+
this.logger.debug("triggerTaskAgent", { instanceId });
|
|
2959
|
+
const authHeaders = await this.getSessionAuthHeaders();
|
|
2960
|
+
const response = await fetch(`${this.baseUrl}/api/v2/jit-task/${instanceId}`, {
|
|
2961
|
+
method: "POST",
|
|
2962
|
+
headers: {
|
|
2963
|
+
"Content-Type": "application/json",
|
|
2964
|
+
...authHeaders
|
|
2965
|
+
}
|
|
2966
|
+
});
|
|
2967
|
+
if (!response.ok) {
|
|
2968
|
+
const error = await response.json().catch(() => ({}));
|
|
2969
|
+
throw new MixrPayError(error.error || `Failed to trigger task: ${response.status}`);
|
|
2970
|
+
}
|
|
2971
|
+
const data = await response.json();
|
|
2972
|
+
return {
|
|
2973
|
+
success: data.success,
|
|
2974
|
+
status: data.status
|
|
2975
|
+
};
|
|
2976
|
+
}
|
|
2977
|
+
/**
|
|
2978
|
+
* Cancel a JIT Task Agent.
|
|
2979
|
+
*
|
|
2980
|
+
* Stops execution and marks the task as cancelled.
|
|
2981
|
+
* Cannot cancel tasks that are already completed/failed.
|
|
2982
|
+
*
|
|
2983
|
+
* @param instanceId - The task agent instance ID
|
|
2984
|
+
* @returns Cancel result
|
|
2985
|
+
*
|
|
2986
|
+
* @example
|
|
2987
|
+
* ```typescript
|
|
2988
|
+
* await wallet.cancelTaskAgent('cuid_abc123');
|
|
2989
|
+
* console.log('Task cancelled');
|
|
2990
|
+
* ```
|
|
2991
|
+
*/
|
|
2992
|
+
async cancelTaskAgent(instanceId) {
|
|
2993
|
+
this.logger.debug("cancelTaskAgent", { instanceId });
|
|
2994
|
+
const authHeaders = await this.getSessionAuthHeaders();
|
|
2995
|
+
const response = await fetch(`${this.baseUrl}/api/v2/jit-task/${instanceId}`, {
|
|
2996
|
+
method: "DELETE",
|
|
2997
|
+
headers: authHeaders
|
|
2998
|
+
});
|
|
2999
|
+
if (!response.ok) {
|
|
3000
|
+
const error = await response.json().catch(() => ({}));
|
|
3001
|
+
throw new MixrPayError(error.error || `Failed to cancel task: ${response.status}`);
|
|
3002
|
+
}
|
|
3003
|
+
const data = await response.json();
|
|
3004
|
+
return {
|
|
3005
|
+
success: data.success,
|
|
3006
|
+
status: data.status
|
|
3007
|
+
};
|
|
3008
|
+
}
|
|
3009
|
+
/**
|
|
3010
|
+
* List JIT Task Agents for the authenticated user.
|
|
3011
|
+
*
|
|
3012
|
+
* Returns deployed task agents with optional filtering by status,
|
|
3013
|
+
* plan, or task. Includes pagination and summary statistics.
|
|
3014
|
+
*
|
|
3015
|
+
* @param options - Optional filter and pagination parameters
|
|
3016
|
+
* @returns List of task agents with pagination and stats
|
|
3017
|
+
*
|
|
3018
|
+
* @example List all task agents
|
|
3019
|
+
* ```typescript
|
|
3020
|
+
* const { taskAgents, pagination, stats } = await wallet.listTaskAgents();
|
|
3021
|
+
* console.log(`${pagination.total} total agents, ${stats.active} active`);
|
|
3022
|
+
* ```
|
|
3023
|
+
*
|
|
3024
|
+
* @example Filter by status
|
|
3025
|
+
* ```typescript
|
|
3026
|
+
* const { taskAgents } = await wallet.listTaskAgents({ status: 'running' });
|
|
3027
|
+
* for (const agent of taskAgents) {
|
|
3028
|
+
* console.log(`${agent.name}: $${agent.budget.spentUsd}/$${agent.budget.totalUsd}`);
|
|
3029
|
+
* }
|
|
3030
|
+
* ```
|
|
3031
|
+
*
|
|
3032
|
+
* @example Filter by plan
|
|
3033
|
+
* ```typescript
|
|
3034
|
+
* const { taskAgents } = await wallet.listTaskAgents({ planId: 'plan_abc' });
|
|
3035
|
+
* ```
|
|
3036
|
+
*/
|
|
3037
|
+
async listTaskAgents(options) {
|
|
3038
|
+
this.logger.debug("listTaskAgents", { options });
|
|
3039
|
+
const authHeaders = await this.getSessionAuthHeaders();
|
|
3040
|
+
const searchParams = new URLSearchParams();
|
|
3041
|
+
if (options?.status) searchParams.set("status", options.status);
|
|
3042
|
+
if (options?.planId) searchParams.set("plan_id", options.planId);
|
|
3043
|
+
if (options?.taskId) searchParams.set("task_id", options.taskId);
|
|
3044
|
+
if (options?.limit !== void 0) searchParams.set("limit", String(options.limit));
|
|
3045
|
+
if (options?.offset !== void 0) searchParams.set("offset", String(options.offset));
|
|
3046
|
+
const qs = searchParams.toString();
|
|
3047
|
+
const url = `${this.baseUrl}/api/v2/jit-task${qs ? `?${qs}` : ""}`;
|
|
3048
|
+
const response = await fetch(url, {
|
|
3049
|
+
method: "GET",
|
|
3050
|
+
headers: authHeaders
|
|
3051
|
+
});
|
|
3052
|
+
if (!response.ok) {
|
|
3053
|
+
const error = await response.json().catch(() => ({}));
|
|
3054
|
+
throw new MixrPayError(error.error || `Failed to list task agents: ${response.status}`);
|
|
3055
|
+
}
|
|
3056
|
+
const data = await response.json();
|
|
3057
|
+
return {
|
|
3058
|
+
taskAgents: (data.task_agents || []).map((agent) => {
|
|
3059
|
+
const budget = agent.budget;
|
|
3060
|
+
const iterations = agent.iterations;
|
|
3061
|
+
const usage = agent.usage;
|
|
3062
|
+
const plan = agent.plan;
|
|
3063
|
+
const task = agent.task;
|
|
3064
|
+
return {
|
|
3065
|
+
id: agent.id,
|
|
3066
|
+
name: agent.name,
|
|
3067
|
+
prompt: agent.prompt,
|
|
3068
|
+
model: agent.model,
|
|
3069
|
+
tools: agent.tools,
|
|
3070
|
+
status: agent.status,
|
|
3071
|
+
budget: {
|
|
3072
|
+
totalUsd: budget.total_usd,
|
|
3073
|
+
spentUsd: budget.spent_usd,
|
|
3074
|
+
remainingUsd: budget.remaining_usd
|
|
3075
|
+
},
|
|
3076
|
+
iterations: {
|
|
3077
|
+
current: iterations.current,
|
|
3078
|
+
max: iterations.max
|
|
3079
|
+
},
|
|
3080
|
+
usage: {
|
|
3081
|
+
toolCalls: usage.tool_calls,
|
|
3082
|
+
inputTokens: usage.input_tokens,
|
|
3083
|
+
outputTokens: usage.output_tokens
|
|
3084
|
+
},
|
|
3085
|
+
result: agent.result,
|
|
3086
|
+
error: agent.error,
|
|
3087
|
+
depth: agent.depth,
|
|
3088
|
+
plan: plan ? { id: plan.id, title: plan.title } : null,
|
|
3089
|
+
task: task ? { id: task.id, title: task.title } : null,
|
|
3090
|
+
ttlHours: agent.ttl_hours,
|
|
3091
|
+
expiresAt: new Date(agent.expires_at),
|
|
3092
|
+
createdAt: new Date(agent.created_at),
|
|
3093
|
+
startedAt: agent.started_at ? new Date(agent.started_at) : void 0,
|
|
3094
|
+
completedAt: agent.completed_at ? new Date(agent.completed_at) : void 0
|
|
3095
|
+
};
|
|
3096
|
+
}),
|
|
3097
|
+
pagination: {
|
|
3098
|
+
total: data.pagination.total,
|
|
3099
|
+
limit: data.pagination.limit,
|
|
3100
|
+
offset: data.pagination.offset,
|
|
3101
|
+
hasMore: data.pagination.has_more
|
|
3102
|
+
},
|
|
3103
|
+
stats: {
|
|
3104
|
+
active: data.stats.active ?? 0,
|
|
3105
|
+
completed: data.stats.completed ?? 0,
|
|
3106
|
+
failed: data.stats.failed ?? 0,
|
|
3107
|
+
totalSpentUsd: data.stats.total_spent_usd ?? 0
|
|
3108
|
+
}
|
|
3109
|
+
};
|
|
3110
|
+
}
|
|
3111
|
+
/**
|
|
3112
|
+
* Wait for a JIT Task Agent to complete.
|
|
3113
|
+
*
|
|
3114
|
+
* Polls the status until the task reaches a terminal state
|
|
3115
|
+
* (completed, failed, cancelled, budget_exceeded, expired).
|
|
3116
|
+
*
|
|
3117
|
+
* @param instanceId - The task agent instance ID
|
|
3118
|
+
* @param options - Wait options
|
|
3119
|
+
* @returns Final task result
|
|
3120
|
+
*
|
|
3121
|
+
* @example
|
|
3122
|
+
* ```typescript
|
|
3123
|
+
* const result = await wallet.waitForTaskAgent('cuid_abc123', {
|
|
3124
|
+
* pollIntervalMs: 2000,
|
|
3125
|
+
* timeoutMs: 300000, // 5 minutes
|
|
3126
|
+
* });
|
|
3127
|
+
*
|
|
3128
|
+
* if (result.status === 'completed') {
|
|
3129
|
+
* console.log('Result:', result.result);
|
|
3130
|
+
* } else {
|
|
3131
|
+
* console.log('Failed:', result.error);
|
|
3132
|
+
* }
|
|
3133
|
+
* ```
|
|
3134
|
+
*/
|
|
3135
|
+
async waitForTaskAgent(instanceId, options) {
|
|
3136
|
+
const pollIntervalMs = options?.pollIntervalMs || 2e3;
|
|
3137
|
+
const timeoutMs = options?.timeoutMs || 3e5;
|
|
3138
|
+
const startTime = Date.now();
|
|
3139
|
+
this.logger.debug("waitForTaskAgent", { instanceId, pollIntervalMs, timeoutMs });
|
|
3140
|
+
while (true) {
|
|
3141
|
+
const status = await this.getTaskAgentStatus(instanceId);
|
|
3142
|
+
if (["completed", "failed", "cancelled", "budget_exceeded", "expired"].includes(status.status)) {
|
|
3143
|
+
return {
|
|
3144
|
+
id: status.id,
|
|
3145
|
+
status: status.status,
|
|
3146
|
+
result: status.result,
|
|
3147
|
+
error: status.error,
|
|
3148
|
+
spentUsd: status.budget.spentUsd,
|
|
3149
|
+
iterations: status.iterations.current,
|
|
3150
|
+
toolCalls: status.usage.toolCalls,
|
|
3151
|
+
completedAt: status.completedAt
|
|
3152
|
+
};
|
|
3153
|
+
}
|
|
3154
|
+
if (Date.now() - startTime > timeoutMs) {
|
|
3155
|
+
throw new MixrPayError(`Task agent wait timeout after ${timeoutMs}ms`);
|
|
3156
|
+
}
|
|
3157
|
+
await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
|
|
3158
|
+
}
|
|
3159
|
+
}
|
|
3160
|
+
/**
|
|
3161
|
+
* Parse task agent instance from API response.
|
|
3162
|
+
*/
|
|
3163
|
+
parseTaskAgentInstance(data) {
|
|
3164
|
+
return {
|
|
3165
|
+
id: data.id,
|
|
3166
|
+
name: data.name,
|
|
3167
|
+
endpointUrl: data.endpoint_url,
|
|
3168
|
+
statusUrl: data.status_url,
|
|
3169
|
+
triggerUrl: data.trigger_url,
|
|
3170
|
+
cancelUrl: data.cancel_url,
|
|
3171
|
+
resultUrl: data.result_url,
|
|
3172
|
+
status: data.status,
|
|
3173
|
+
budgetUsd: data.budget_usd,
|
|
3174
|
+
expiresAt: new Date(data.expires_at),
|
|
3175
|
+
depth: data.depth,
|
|
3176
|
+
maxIterations: data.max_iterations
|
|
3177
|
+
};
|
|
3178
|
+
}
|
|
3179
|
+
/**
|
|
3180
|
+
* Parse task agent status from API response.
|
|
3181
|
+
*/
|
|
3182
|
+
parseTaskAgentStatus(data) {
|
|
3183
|
+
const budget = data.budget;
|
|
3184
|
+
const iterations = data.iterations;
|
|
3185
|
+
const usage = data.usage;
|
|
3186
|
+
const endpoints = data.endpoints;
|
|
3187
|
+
return {
|
|
3188
|
+
id: data.id,
|
|
3189
|
+
name: data.name,
|
|
3190
|
+
prompt: data.prompt,
|
|
3191
|
+
model: data.model,
|
|
3192
|
+
tools: data.tools,
|
|
3193
|
+
status: data.status,
|
|
3194
|
+
budget: {
|
|
3195
|
+
totalUsd: budget?.total_usd ?? 0,
|
|
3196
|
+
spentUsd: budget?.spent_usd ?? 0,
|
|
3197
|
+
remainingUsd: budget?.remaining_usd ?? 0
|
|
3198
|
+
},
|
|
3199
|
+
iterations: {
|
|
3200
|
+
current: iterations?.current ?? 0,
|
|
3201
|
+
max: iterations?.max ?? 0
|
|
3202
|
+
},
|
|
3203
|
+
usage: {
|
|
3204
|
+
toolCalls: usage?.tool_calls ?? 0,
|
|
3205
|
+
inputTokens: usage?.input_tokens ?? 0,
|
|
3206
|
+
outputTokens: usage?.output_tokens ?? 0
|
|
3207
|
+
},
|
|
3208
|
+
result: data.result,
|
|
3209
|
+
error: data.error,
|
|
3210
|
+
depth: data.depth,
|
|
3211
|
+
planId: data.plan_id,
|
|
3212
|
+
taskId: data.task_id,
|
|
3213
|
+
endpoints: {
|
|
3214
|
+
statusUrl: endpoints?.status_url ?? "",
|
|
3215
|
+
triggerUrl: endpoints?.trigger_url ?? "",
|
|
3216
|
+
cancelUrl: endpoints?.cancel_url ?? "",
|
|
3217
|
+
resultUrl: endpoints?.result_url ?? ""
|
|
3218
|
+
},
|
|
3219
|
+
ttlHours: data.ttl_hours,
|
|
3220
|
+
expiresAt: new Date(data.expires_at),
|
|
3221
|
+
createdAt: new Date(data.created_at),
|
|
3222
|
+
startedAt: data.started_at ? new Date(data.started_at) : void 0,
|
|
3223
|
+
completedAt: data.completed_at ? new Date(data.completed_at) : void 0
|
|
3224
|
+
};
|
|
3225
|
+
}
|
|
3226
|
+
// ===========================================================================
|
|
2832
3227
|
// LLM Completion Methods
|
|
2833
3228
|
// ===========================================================================
|
|
2834
3229
|
/**
|