@thirdfy/agent-cli 0.1.24 → 0.1.25
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/CHANGELOG.md +16 -0
- package/bin/thirdfy-agent.mjs +64 -8
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,22 @@ All notable changes to `@thirdfy/agent-cli` are documented here. The format is b
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [0.1.25] - 2026-05-04
|
|
8
|
+
|
|
9
|
+
**npm:** `@thirdfy/agent-cli@0.1.25` (publish after merge)
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
- **Capabilities negotiation:** Cache negotiated Thirdfy CLI capabilities and derive provider hints from the live API response to reduce static hint drift.
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
|
|
17
|
+
- **Managed wallet payloads:** Align swap and related `params` with human-readable amount fields expected by the Thirdfy API when using `amountInHuman`.
|
|
18
|
+
|
|
19
|
+
### Added
|
|
20
|
+
|
|
21
|
+
- **Tests:** `test/managed-wallet-payload.test.cjs` for managed-wallet payload shape.
|
|
22
|
+
|
|
7
23
|
## [0.1.24] - 2026-05-02
|
|
8
24
|
|
|
9
25
|
**npm:** [`@thirdfy/agent-cli@0.1.24`](https://www.npmjs.com/package/@thirdfy/agent-cli/v/0.1.24)
|
package/bin/thirdfy-agent.mjs
CHANGED
|
@@ -27,6 +27,7 @@ const RUN_MODES = ['thirdfy', 'self', 'hybrid', 'agent_wallet'];
|
|
|
27
27
|
const HYBRID_WALLET_MODES = ['self', 'agent_wallet'];
|
|
28
28
|
const CUSTODY_MODES = ['managed', 'external'];
|
|
29
29
|
const EFFECT_CHECK_MODES = ['strict', 'relaxed', 'off'];
|
|
30
|
+
let negotiatedCapabilitiesCache = null;
|
|
30
31
|
const PROFILE_DEFAULTS = {
|
|
31
32
|
personal: 'self',
|
|
32
33
|
builder: 'hybrid',
|
|
@@ -153,6 +154,7 @@ async function main() {
|
|
|
153
154
|
}
|
|
154
155
|
|
|
155
156
|
const capabilities = await negotiateCapabilities(context);
|
|
157
|
+
negotiatedCapabilitiesCache = capabilities;
|
|
156
158
|
|
|
157
159
|
switch (commandKey) {
|
|
158
160
|
case 'agent run':
|
|
@@ -556,8 +558,57 @@ function getTradingProviderHint(providerId) {
|
|
|
556
558
|
return null;
|
|
557
559
|
}
|
|
558
560
|
|
|
559
|
-
function getCachedProviderHintFromCapabilities(
|
|
560
|
-
|
|
561
|
+
function getCachedProviderHintFromCapabilities(provider) {
|
|
562
|
+
const normalizedProvider = String(provider || '').trim().toLowerCase();
|
|
563
|
+
if (!normalizedProvider) return null;
|
|
564
|
+
const manifests = Array.isArray(negotiatedCapabilitiesCache?.providers?.manifests)
|
|
565
|
+
? negotiatedCapabilitiesCache.providers.manifests
|
|
566
|
+
: [];
|
|
567
|
+
const match = manifests.find((entry) => String(entry?.providerId || '').trim().toLowerCase() === normalizedProvider);
|
|
568
|
+
if (!match) return null;
|
|
569
|
+
const canonicalWriteActions = {
|
|
570
|
+
trading: 'swap',
|
|
571
|
+
hyperliquid: 'place_hyperliquid_perps_order',
|
|
572
|
+
polymarket: 'place_polymarket_order',
|
|
573
|
+
prediction: 'place_prediction_order',
|
|
574
|
+
earn: 'deposit_earn_position',
|
|
575
|
+
morpho: 'deposit_earn_position',
|
|
576
|
+
curve: 'deposit_earn_position',
|
|
577
|
+
};
|
|
578
|
+
const canonicalReadActions = {
|
|
579
|
+
earn: 'get_earn_opportunities',
|
|
580
|
+
morpho: 'get_morpho_vaults',
|
|
581
|
+
curve: 'get_curve_pools',
|
|
582
|
+
prediction: 'get_prediction_markets',
|
|
583
|
+
};
|
|
584
|
+
return {
|
|
585
|
+
provider: normalizedProvider,
|
|
586
|
+
category: match.category || match.domain || match.providerKind || null,
|
|
587
|
+
...(canonicalReadActions[normalizedProvider] ? { canonicalReadAction: canonicalReadActions[normalizedProvider] } : {}),
|
|
588
|
+
...(canonicalWriteActions[normalizedProvider] ? { canonicalWriteAction: canonicalWriteActions[normalizedProvider] } : {}),
|
|
589
|
+
providerKind: match.providerKind || null,
|
|
590
|
+
capabilities: Array.isArray(match.capabilities) ? match.capabilities : [],
|
|
591
|
+
supportedChains: Array.isArray(match.supportedChains) ? match.supportedChains : [],
|
|
592
|
+
custodyMode: match.custodyMode || null,
|
|
593
|
+
description: match.description || null,
|
|
594
|
+
source: 'cli_capabilities_manifest',
|
|
595
|
+
};
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
function formatProviderAmbiguousActionHint(providerHint) {
|
|
599
|
+
if (!providerHint) return '';
|
|
600
|
+
const p = providerHint.provider;
|
|
601
|
+
const w = providerHint.canonicalWriteAction;
|
|
602
|
+
if (w) return ` Provider ${p} expects ${w}.`;
|
|
603
|
+
return ` Provider ${p} did not declare a canonical write action in capabilities; run actions --provider ${p} first.`;
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
function formatProviderUnknownActionHint(providerHint) {
|
|
607
|
+
if (!providerHint) return '';
|
|
608
|
+
const p = providerHint.provider;
|
|
609
|
+
const w = providerHint.canonicalWriteAction;
|
|
610
|
+
if (w) return ` Provider ${p} expects ${w}; run actions --provider ${p} first.`;
|
|
611
|
+
return ` Provider ${p} did not declare a canonical write action in capabilities; run actions --provider ${p} first.`;
|
|
561
612
|
}
|
|
562
613
|
|
|
563
614
|
const OFFCHAIN_VENUE_ORDER_ACTIONS = new Set([
|
|
@@ -2966,11 +3017,16 @@ function buildBuildTxPayload(flags, resolvedAction) {
|
|
|
2966
3017
|
|
|
2967
3018
|
function buildManagedExecutePayload(flags, options) {
|
|
2968
3019
|
const runMode = String(options.runMode || flags.runMode || 'agent_wallet').trim().toLowerCase();
|
|
3020
|
+
const params = getPreparedParams(flags);
|
|
3021
|
+
const managedParams = { ...params };
|
|
3022
|
+
if (flags.__swapInput?.unitSource === 'human' && flags.__swapInput.amountInHuman) {
|
|
3023
|
+
managedParams.amountIn = flags.__swapInput.amountInHuman;
|
|
3024
|
+
}
|
|
2969
3025
|
const payload = {
|
|
2970
3026
|
agentApiKey: resolveAgentApiKey(flags, runMode),
|
|
2971
3027
|
action: String(options.resolvedAction || requireFlag(flags, 'action', 'Missing --action')).trim(),
|
|
2972
3028
|
userDid: String(flags.userDid || process.env.THIRDFY_USER_DID || '').trim(),
|
|
2973
|
-
params:
|
|
3029
|
+
params: managedParams,
|
|
2974
3030
|
chainId: Number(flags.chainId || 8453),
|
|
2975
3031
|
executionStrategy: {
|
|
2976
3032
|
runMode,
|
|
@@ -3235,7 +3291,7 @@ async function resolveActionSelection(ctx, flags) {
|
|
|
3235
3291
|
throw new Error(
|
|
3236
3292
|
`Ambiguous --action "${requestedAction}". Alias matches multiple actions: ${formatActionList(
|
|
3237
3293
|
exactAlias.map((v) => v.key)
|
|
3238
|
-
)}.${providerHint
|
|
3294
|
+
)}.${formatProviderAmbiguousActionHint(providerHint)}`
|
|
3239
3295
|
);
|
|
3240
3296
|
}
|
|
3241
3297
|
|
|
@@ -3252,14 +3308,14 @@ async function resolveActionSelection(ctx, flags) {
|
|
|
3252
3308
|
throw new Error(
|
|
3253
3309
|
`Ambiguous --action "${requestedAction}". Did you mean one of: ${formatActionList(
|
|
3254
3310
|
fuzzy.slice(0, 10).map((v) => v.key)
|
|
3255
|
-
)}?${providerHint
|
|
3311
|
+
)}?${formatProviderAmbiguousActionHint(providerHint)}`
|
|
3256
3312
|
);
|
|
3257
3313
|
}
|
|
3258
3314
|
const providerHint = flags.provider ? getTradingProviderHint(flags.provider) : null;
|
|
3259
3315
|
throw new Error(
|
|
3260
|
-
`Unknown --action "${requestedAction}". No compatible action found in current catalog/provider scope.${
|
|
3261
|
-
providerHint
|
|
3262
|
-
}`
|
|
3316
|
+
`Unknown --action "${requestedAction}". No compatible action found in current catalog/provider scope.${formatProviderUnknownActionHint(
|
|
3317
|
+
providerHint
|
|
3318
|
+
)}`
|
|
3263
3319
|
);
|
|
3264
3320
|
}
|
|
3265
3321
|
|