@kroxy/kroxy 1.0.7 → 1.0.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/dist/index.d.ts.map +1 -1
- package/dist/index.js +73 -4
- package/dist/index.js.map +1 -1
- package/dist/src/client.d.ts +43 -0
- package/dist/src/client.d.ts.map +1 -1
- package/dist/src/client.js +90 -13
- package/dist/src/client.js.map +1 -1
- package/dist/src/tools/balance.d.ts +13 -0
- package/dist/src/tools/balance.d.ts.map +1 -0
- package/dist/src/tools/balance.js +34 -0
- package/dist/src/tools/balance.js.map +1 -0
- package/dist/src/tools/browse.d.ts +19 -0
- package/dist/src/tools/browse.d.ts.map +1 -0
- package/dist/src/tools/browse.js +75 -0
- package/dist/src/tools/browse.js.map +1 -0
- package/dist/src/tools/dispute.d.ts +15 -0
- package/dist/src/tools/dispute.d.ts.map +1 -0
- package/dist/src/tools/dispute.js +61 -0
- package/dist/src/tools/dispute.js.map +1 -0
- package/dist/src/tools/hire.d.ts +2 -0
- package/dist/src/tools/hire.d.ts.map +1 -1
- package/dist/src/tools/hire.js +84 -16
- package/dist/src/tools/hire.js.map +1 -1
- package/dist/src/tools/history.d.ts +15 -0
- package/dist/src/tools/history.d.ts.map +1 -0
- package/dist/src/tools/history.js +54 -0
- package/dist/src/tools/history.js.map +1 -0
- package/dist/src/tools/setup.d.ts +9 -0
- package/dist/src/tools/setup.d.ts.map +1 -0
- package/dist/src/tools/setup.js +141 -0
- package/dist/src/tools/setup.js.map +1 -0
- package/dist/src/tools/status.d.ts +13 -0
- package/dist/src/tools/status.d.ts.map +1 -0
- package/dist/src/tools/status.js +79 -0
- package/dist/src/tools/status.js.map +1 -0
- package/dist/src/utils/fetchWithRetry.d.ts +12 -0
- package/dist/src/utils/fetchWithRetry.d.ts.map +1 -0
- package/dist/src/utils/fetchWithRetry.js +58 -0
- package/dist/src/utils/fetchWithRetry.js.map +1 -0
- package/index.ts +97 -4
- package/package.json +1 -1
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
const RETRY_DELAYS = [500, 1000, 2000];
|
|
2
|
+
/**
|
|
3
|
+
* fetch with exponential backoff retry and per-attempt timeout.
|
|
4
|
+
*
|
|
5
|
+
* Retries on:
|
|
6
|
+
* - TypeError (network / DNS failure)
|
|
7
|
+
* - HTTP 429 Too Many Requests (respects Retry-After header, cap 30s)
|
|
8
|
+
* - HTTP 503 Service Unavailable
|
|
9
|
+
*
|
|
10
|
+
* Does NOT retry on other 4xx or 500/502.
|
|
11
|
+
*/
|
|
12
|
+
export async function fetchWithRetry(url, options = {}, timeoutMs = 10_000) {
|
|
13
|
+
let lastError;
|
|
14
|
+
for (let attempt = 0; attempt < 3; attempt++) {
|
|
15
|
+
const controller = new AbortController();
|
|
16
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
17
|
+
try {
|
|
18
|
+
const resp = await fetch(url, { ...options, signal: controller.signal });
|
|
19
|
+
clearTimeout(timer);
|
|
20
|
+
if (resp.ok)
|
|
21
|
+
return resp;
|
|
22
|
+
if ((resp.status === 429 || resp.status === 503) && attempt < 2) {
|
|
23
|
+
let delay = RETRY_DELAYS[attempt];
|
|
24
|
+
if (resp.status === 429) {
|
|
25
|
+
const retryAfter = resp.headers.get('Retry-After');
|
|
26
|
+
if (retryAfter) {
|
|
27
|
+
const secs = parseFloat(retryAfter);
|
|
28
|
+
if (!isNaN(secs))
|
|
29
|
+
delay = Math.min(secs * 1000, 30_000);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
await sleep(delay);
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
return resp;
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
clearTimeout(timer);
|
|
39
|
+
const isAbort = err instanceof Error && (err.name === 'AbortError' || err.name === 'TimeoutError');
|
|
40
|
+
const isNetwork = err instanceof TypeError;
|
|
41
|
+
if ((isAbort || isNetwork) && attempt < 2) {
|
|
42
|
+
lastError = isAbort
|
|
43
|
+
? new Error(`Request timed out after ${timeoutMs}ms`)
|
|
44
|
+
: err;
|
|
45
|
+
await sleep(RETRY_DELAYS[attempt]);
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
if (isAbort)
|
|
49
|
+
throw new Error(`Request timed out after ${timeoutMs}ms (3 attempts)`);
|
|
50
|
+
throw err;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
throw lastError ?? new Error('fetchWithRetry: all attempts failed');
|
|
54
|
+
}
|
|
55
|
+
function sleep(ms) {
|
|
56
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=fetchWithRetry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetchWithRetry.js","sourceRoot":"","sources":["../../../src/utils/fetchWithRetry.ts"],"names":[],"mappings":"AAAA,MAAM,YAAY,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AAEvC;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,GAAW,EACX,UAAuB,EAAE,EACzB,SAAS,GAAG,MAAM;IAElB,IAAI,SAAkB,CAAC;IAEvB,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC;QAC7C,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,SAAS,CAAC,CAAC;QAE9D,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,GAAG,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC;YACzE,YAAY,CAAC,KAAK,CAAC,CAAC;YAEpB,IAAI,IAAI,CAAC,EAAE;gBAAE,OAAO,IAAI,CAAC;YAEzB,IAAI,CAAC,IAAI,CAAC,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,MAAM,KAAK,GAAG,CAAC,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;gBAChE,IAAI,KAAK,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;gBAClC,IAAI,IAAI,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;oBACxB,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;oBACnD,IAAI,UAAU,EAAE,CAAC;wBACf,MAAM,IAAI,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC;wBACpC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;4BAAE,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,EAAE,MAAM,CAAC,CAAC;oBAC1D,CAAC;gBACH,CAAC;gBACD,MAAM,KAAK,CAAC,KAAK,CAAC,CAAC;gBACnB,SAAS;YACX,CAAC;YAED,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,YAAY,CAAC,KAAK,CAAC,CAAC;YAEpB,MAAM,OAAO,GACX,GAAG,YAAY,KAAK,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,YAAY,IAAI,GAAG,CAAC,IAAI,KAAK,cAAc,CAAC,CAAC;YACrF,MAAM,SAAS,GAAG,GAAG,YAAY,SAAS,CAAC;YAE3C,IAAI,CAAC,OAAO,IAAI,SAAS,CAAC,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;gBAC1C,SAAS,GAAG,OAAO;oBACjB,CAAC,CAAC,IAAI,KAAK,CAAC,2BAA2B,SAAS,IAAI,CAAC;oBACrD,CAAC,CAAC,GAAG,CAAC;gBACR,MAAM,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC;gBACnC,SAAS;YACX,CAAC;YAED,IAAI,OAAO;gBAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,SAAS,iBAAiB,CAAC,CAAC;YACpF,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;IAED,MAAM,SAAS,IAAI,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;AACtE,CAAC;AAED,SAAS,KAAK,CAAC,EAAU;IACvB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAC3D,CAAC"}
|
package/index.ts
CHANGED
|
@@ -2,10 +2,22 @@ import type { OpenClawPluginApi } from 'openclaw/plugin-sdk';
|
|
|
2
2
|
import { hireParams, executeHire } from './src/tools/hire.js';
|
|
3
3
|
import { offerParams, executeOffer } from './src/tools/offer.js';
|
|
4
4
|
import { reputationParams, executeReputation } from './src/tools/reputation.js';
|
|
5
|
+
import { setupParams, executeSetup } from './src/tools/setup.js';
|
|
6
|
+
import { statusParams, executeStatus } from './src/tools/status.js';
|
|
7
|
+
import { balanceParams, executeBalance } from './src/tools/balance.js';
|
|
8
|
+
import { browseParams, executeBrowse } from './src/tools/browse.js';
|
|
9
|
+
import { disputeParams, executeDispute } from './src/tools/dispute.js';
|
|
10
|
+
import { historyParams, executeHistory } from './src/tools/history.js';
|
|
5
11
|
|
|
6
12
|
type ReputationToolParams = Parameters<typeof executeReputation>[0];
|
|
7
13
|
type OfferToolParams = Parameters<typeof executeOffer>[0];
|
|
8
14
|
type HireToolParams = Parameters<typeof executeHire>[0];
|
|
15
|
+
type SetupToolParams = Parameters<typeof executeSetup>[0];
|
|
16
|
+
type StatusToolParams = Parameters<typeof executeStatus>[0];
|
|
17
|
+
type BalanceToolParams = Parameters<typeof executeBalance>[0];
|
|
18
|
+
type BrowseToolParams = Parameters<typeof executeBrowse>[0];
|
|
19
|
+
type DisputeToolParams = Parameters<typeof executeDispute>[0];
|
|
20
|
+
type HistoryToolParams = Parameters<typeof executeHistory>[0];
|
|
9
21
|
|
|
10
22
|
export default {
|
|
11
23
|
id: 'kroxy',
|
|
@@ -18,7 +30,23 @@ export default {
|
|
|
18
30
|
if (cfg.KROXY_AGENT_PRIVATE_KEY) process.env.KROXY_AGENT_PRIVATE_KEY = cfg.KROXY_AGENT_PRIVATE_KEY;
|
|
19
31
|
if (cfg.KROXY_DEMO_MODE) process.env.KROXY_DEMO_MODE = cfg.KROXY_DEMO_MODE;
|
|
20
32
|
if (cfg.NEXUS_URL) process.env.NEXUS_URL = cfg.NEXUS_URL;
|
|
21
|
-
|
|
33
|
+
|
|
34
|
+
// ── Setup / Onboarding ────────────────────────────────────────────────────
|
|
35
|
+
// Run this first to check configuration and get guided setup instructions.
|
|
36
|
+
api.registerTool({
|
|
37
|
+
name: 'kroxy_setup',
|
|
38
|
+
label: 'Kroxy Setup',
|
|
39
|
+
description:
|
|
40
|
+
'Check your Kroxy configuration and connectivity. Run this first to diagnose any setup issues. ' +
|
|
41
|
+
'Shows API reachability, demo mode status, wallet config, and what to fix next.',
|
|
42
|
+
parameters: setupParams,
|
|
43
|
+
async execute(_id: string, params: SetupToolParams) {
|
|
44
|
+
return executeSetup(params);
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
// ── Read-only tools — always available ────────────────────────────────────
|
|
49
|
+
|
|
22
50
|
api.registerTool({
|
|
23
51
|
name: 'kroxy_reputation',
|
|
24
52
|
label: 'Kroxy Reputation',
|
|
@@ -31,8 +59,57 @@ export default {
|
|
|
31
59
|
},
|
|
32
60
|
});
|
|
33
61
|
|
|
62
|
+
api.registerTool({
|
|
63
|
+
name: 'kroxy_status',
|
|
64
|
+
label: 'Kroxy Job Status',
|
|
65
|
+
description:
|
|
66
|
+
'Check the status of an active job mid-flight. Shows current status, agent assigned, ' +
|
|
67
|
+
'escrow amount, and time elapsed. Use after kroxy_hire with the returned jobId.',
|
|
68
|
+
parameters: statusParams,
|
|
69
|
+
async execute(_id: string, params: StatusToolParams) {
|
|
70
|
+
return executeStatus(params);
|
|
71
|
+
},
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
api.registerTool({
|
|
75
|
+
name: 'kroxy_balance',
|
|
76
|
+
label: 'Kroxy Balance',
|
|
77
|
+
description:
|
|
78
|
+
'Check your USDC balance, pending escrow totals, and total earned in one call. ' +
|
|
79
|
+
'Defaults to your own agent wallet (KROXY_AGENT_WALLET).',
|
|
80
|
+
parameters: balanceParams,
|
|
81
|
+
async execute(_id: string, params: BalanceToolParams) {
|
|
82
|
+
return executeBalance(params);
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
api.registerTool({
|
|
87
|
+
name: 'kroxy_browse',
|
|
88
|
+
label: 'Kroxy Browse',
|
|
89
|
+
description:
|
|
90
|
+
'Browse available agents on the Kroxy network or view the open job board. ' +
|
|
91
|
+
'Filter by capability and price. Use mode="agents" to find providers, mode="jobs" for open work.',
|
|
92
|
+
parameters: browseParams,
|
|
93
|
+
async execute(_id: string, params: BrowseToolParams) {
|
|
94
|
+
return executeBrowse(params);
|
|
95
|
+
},
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
api.registerTool({
|
|
99
|
+
name: 'kroxy_history',
|
|
100
|
+
label: 'Kroxy History',
|
|
101
|
+
description:
|
|
102
|
+
'View your full job history — tasks hired, amounts paid, durations, and escrow tx hashes. ' +
|
|
103
|
+
'Provides a full audit trail for any agent wallet.',
|
|
104
|
+
parameters: historyParams,
|
|
105
|
+
async execute(_id: string, params: HistoryToolParams) {
|
|
106
|
+
return executeHistory(params);
|
|
107
|
+
},
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
// ── Mutating tools — require configuration ────────────────────────────────
|
|
111
|
+
|
|
34
112
|
// Register your agent as a paid service provider on the Kroxy job board.
|
|
35
|
-
// Optional: requires a public webhook endpoint and configures on-chain identity.
|
|
36
113
|
api.registerTool(
|
|
37
114
|
{
|
|
38
115
|
name: 'kroxy_offer',
|
|
@@ -49,7 +126,6 @@ export default {
|
|
|
49
126
|
);
|
|
50
127
|
|
|
51
128
|
// Hire another agent with USDC held in conditional escrow on Base.
|
|
52
|
-
// Optional: requires private key for on-chain signing and triggers financial transactions.
|
|
53
129
|
api.registerTool(
|
|
54
130
|
{
|
|
55
131
|
name: 'kroxy_hire',
|
|
@@ -57,7 +133,7 @@ export default {
|
|
|
57
133
|
description:
|
|
58
134
|
'Hire a specialist agent to complete a task, paid in USDC via conditional escrow on Base. ' +
|
|
59
135
|
'Funds are locked until work quality is verified — payment is automatic and trustless. ' +
|
|
60
|
-
'Requires KROXY_AGENT_WALLET
|
|
136
|
+
'Requires KROXY_AGENT_WALLET. Set KROXY_DEMO_MODE=1 to try without a real private key.',
|
|
61
137
|
parameters: hireParams,
|
|
62
138
|
async execute(_id: string, params: HireToolParams) {
|
|
63
139
|
return executeHire(params);
|
|
@@ -65,5 +141,22 @@ export default {
|
|
|
65
141
|
},
|
|
66
142
|
{ optional: true },
|
|
67
143
|
);
|
|
144
|
+
|
|
145
|
+
// Raise a dispute on a job in escrow.
|
|
146
|
+
api.registerTool(
|
|
147
|
+
{
|
|
148
|
+
name: 'kroxy_dispute',
|
|
149
|
+
label: 'Kroxy Dispute',
|
|
150
|
+
description:
|
|
151
|
+
'Raise a dispute on a job that is in escrow. Triggers arbitration by three independent ' +
|
|
152
|
+
'AI judges (Claude, GPT-4o, Gemini). Use when the delivered work does not meet requirements. ' +
|
|
153
|
+
'Requires KROXY_API_KEY.',
|
|
154
|
+
parameters: disputeParams,
|
|
155
|
+
async execute(_id: string, params: DisputeToolParams) {
|
|
156
|
+
return executeDispute(params);
|
|
157
|
+
},
|
|
158
|
+
},
|
|
159
|
+
{ optional: true },
|
|
160
|
+
);
|
|
68
161
|
},
|
|
69
162
|
};
|