@thirdfy/agent-cli 0.4.0 → 0.4.2
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 +35 -0
- package/README.md +5 -8
- package/package.json +3 -3
- package/scripts/validate-cli-contract-schemas.mjs +1 -0
- package/src/cli/help.mjs +1 -1
- package/src/cli/manifest.mjs +8 -1
- package/src/cli/options/index.mjs +11 -11
- package/src/cli/program.mjs +1 -1
- package/src/commands/{agent.mjs → account/agent.mjs} +5 -5
- package/src/commands/{credits.mjs → account/credits.mjs} +73 -17
- package/src/commands/{wallet.mjs → account/wallet.mjs} +136 -21
- package/src/commands/{walletControl.mjs → account/walletControl.mjs} +3 -3
- package/src/commands/discovery.mjs +9 -9
- package/src/commands/execute.mjs +2 -2
- package/src/commands/index.mjs +9 -9
- package/src/commands/{bootstrap.mjs → onboarding/bootstrap.mjs} +8 -8
- package/src/commands/{consoleMandate.mjs → onboarding/consoleMandate.mjs} +2 -2
- package/src/commands/{credentials.mjs → onboarding/credentials.mjs} +6 -6
- package/src/commands/{delegation.mjs → onboarding/delegation.mjs} +5 -5
- package/src/commands/{avantis.mjs → venues/avantis.mjs} +1 -1
- package/src/commands/{condor.mjs → venues/condor.mjs} +4 -4
- package/src/commands/{hummingbot.mjs → venues/hummingbot.mjs} +4 -4
- package/src/commands/{hyperliquid.mjs → venues/hyperliquid.mjs} +1 -1
- package/src/commands/{lighter.mjs → venues/lighter.mjs} +1 -1
- package/src/commands/{polymarket.mjs → venues/polymarket.mjs} +4 -4
- package/src/commands/{venue.mjs → venues/venue.mjs} +3 -3
- package/src/contracts/cli/schemas/wallet-profile.response.schema.json +127 -0
- package/src/core/context.mjs +20 -0
- package/src/core/earnclawAttribution.mjs +1 -1
- package/src/core/{actionTimeouts.mjs → execution/actionTimeouts.mjs} +2 -2
- package/src/core/{walletExecuteChainId.mjs → execution/walletExecuteChainId.mjs} +1 -1
- package/src/core/http.mjs +1 -1
- package/src/runtime/execution/hostedRuntimeWriteGate.mjs +1 -1
- package/src/runtime/execution/payloads.mjs +4 -4
- package/src/runtime/execution/runners/agentWalletLane.mjs +109 -0
- package/src/runtime/execution/runners/createExecutionRunners.mjs +315 -0
- package/src/runtime/execution/runners/fallbackHints.mjs +54 -0
- package/src/runtime/execution/runners/hybridLane.mjs +88 -0
- package/src/runtime/execution/runners/managedPreflight.mjs +253 -0
- package/src/runtime/execution/runners/managedResponse.mjs +119 -0
- package/src/runtime/execution/runners/selfLane.mjs +232 -0
- package/src/runtime/execution/runners/thirdfyLane.mjs +97 -0
- package/src/runtime/execution/svmLane.mjs +1 -1
- package/src/runtime/handlers.mjs +17 -16
- package/src/runtime/main.mjs +1 -1
- package/src/runtime/risk/notional.mjs +1 -1
- package/src/runtime/validation/actionParamsGate.mjs +1 -1
- package/src/runtime/execution/runners.mjs +0 -1134
- /package/src/cli/options/{agent.mjs → account/agent.mjs} +0 -0
- /package/src/cli/options/{credits.mjs → account/credits.mjs} +0 -0
- /package/src/cli/options/{wallet.mjs → account/wallet.mjs} +0 -0
- /package/src/cli/options/{walletControl.mjs → account/walletControl.mjs} +0 -0
- /package/src/cli/options/{bootstrap.mjs → onboarding/bootstrap.mjs} +0 -0
- /package/src/cli/options/{credentials.mjs → onboarding/credentials.mjs} +0 -0
- /package/src/cli/options/{delegation.mjs → onboarding/delegation.mjs} +0 -0
- /package/src/cli/options/{condor.mjs → venues/condor.mjs} +0 -0
- /package/src/cli/options/{hummingbot.mjs → venues/hummingbot.mjs} +0 -0
- /package/src/cli/options/{polymarket.mjs → venues/polymarket.mjs} +0 -0
- /package/src/cli/options/{venue.mjs → venues/venue.mjs} +0 -0
- /package/src/core/{executionContext.mjs → execution/executionContext.mjs} +0 -0
- /package/src/core/{fundingTokenIn.mjs → execution/fundingTokenIn.mjs} +0 -0
- /package/src/core/{hostedRuntimeIdempotency.mjs → execution/hostedRuntimeIdempotency.mjs} +0 -0
- /package/src/core/{readOnlyActions.mjs → execution/readOnlyActions.mjs} +0 -0
- /package/src/core/{signedTx.mjs → execution/signedTx.mjs} +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { requireFlag } from '
|
|
2
|
-
import { apiGet, apiPost } from '
|
|
1
|
+
import { requireFlag } from '../../core/args.mjs';
|
|
2
|
+
import { apiGet, apiPost } from '../../core/http.mjs';
|
|
3
3
|
|
|
4
4
|
/** Aligned with chat.mjs NETWORK_CHAIN_IDS and thirdfy-mcp consoleMandateChains. */
|
|
5
5
|
const CONSOLE_MANDATE_NETWORK_CHAIN_IDS = {
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { createRequire } from 'module';
|
|
2
|
-
import { requireFlag, parseJsonFlag } from '
|
|
3
|
-
import { requestWithRouteFallback } from '
|
|
4
|
-
import { createCliError } from '
|
|
5
|
-
import { BITFINEX_PERMISSION_PROFILES, DEFAULT_BITFINEX_BASE_URL } from '
|
|
6
|
-
import { parseBooleanFlag } from '
|
|
2
|
+
import { requireFlag, parseJsonFlag } from '../../core/args.mjs';
|
|
3
|
+
import { requestWithRouteFallback } from '../../core/http.mjs';
|
|
4
|
+
import { createCliError } from '../../core/envelope.mjs';
|
|
5
|
+
import { BITFINEX_PERMISSION_PROFILES, DEFAULT_BITFINEX_BASE_URL } from '../../core/constants.mjs';
|
|
6
|
+
import { parseBooleanFlag } from '../../core/runMode.mjs';
|
|
7
7
|
|
|
8
8
|
const require = createRequire(import.meta.url);
|
|
9
|
-
const { normalizeCredentialStatus } = require('
|
|
9
|
+
const { normalizeCredentialStatus } = require('../../utils/cli/delegationNormalization.cjs');
|
|
10
10
|
export function createCredentialsCommands({ printEnvelope, getAuthToken, buildOwnerAuthHeaders, probeBitfinexPermissions }) {
|
|
11
11
|
async function commandCredentialsUpsert(ctx, flags, capabilities) {
|
|
12
12
|
const authToken = getAuthToken(flags, 'Missing --auth-token (or THIRDFY_AUTH_TOKEN) for credentials upsert');
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { requireFlag, parseJsonFlag } from '
|
|
2
|
-
import { createCliError } from '
|
|
3
|
-
import { getEffectiveRunMode } from '
|
|
4
|
-
import { apiGet, apiPost, requestWithRouteFallback } from '
|
|
1
|
+
import { requireFlag, parseJsonFlag } from '../../core/args.mjs';
|
|
2
|
+
import { createCliError } from '../../core/envelope.mjs';
|
|
3
|
+
import { getEffectiveRunMode } from '../../core/runMode.mjs';
|
|
4
|
+
import { apiGet, apiPost, requestWithRouteFallback } from '../../core/http.mjs';
|
|
5
5
|
import { createRequire } from 'module';
|
|
6
6
|
|
|
7
7
|
const require = createRequire(import.meta.url);
|
|
8
|
-
const { normalizeDelegationStatus } = require('
|
|
8
|
+
const { normalizeDelegationStatus } = require('../../utils/cli/delegationNormalization.cjs');
|
|
9
9
|
|
|
10
10
|
export function createDelegationCommands(deps) {
|
|
11
11
|
const {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { apiPost } from '
|
|
2
|
-
import { exitAfterOutput } from '
|
|
3
|
-
import { parseJsonFlag } from '
|
|
4
|
-
import { negotiateCapabilities } from '
|
|
1
|
+
import { apiPost } from '../../core/http.mjs';
|
|
2
|
+
import { exitAfterOutput } from '../../core/envelope.mjs';
|
|
3
|
+
import { parseJsonFlag } from '../../core/args.mjs';
|
|
4
|
+
import { negotiateCapabilities } from '../../core/http.mjs';
|
|
5
5
|
import { resolveConfigAgentKey } from './polymarket.mjs';
|
|
6
6
|
|
|
7
7
|
function agentApiKeyFromFlags(flags, ctx) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { apiGet, apiPost } from '
|
|
2
|
-
import { exitAfterOutput } from '
|
|
3
|
-
import { parseJsonFlag } from '
|
|
4
|
-
import { negotiateCapabilities } from '
|
|
1
|
+
import { apiGet, apiPost } from '../../core/http.mjs';
|
|
2
|
+
import { exitAfterOutput } from '../../core/envelope.mjs';
|
|
3
|
+
import { parseJsonFlag } from '../../core/args.mjs';
|
|
4
|
+
import { negotiateCapabilities } from '../../core/http.mjs';
|
|
5
5
|
import { resolveConfigAgentKey } from './polymarket.mjs';
|
|
6
6
|
|
|
7
7
|
function orgIdFromFlags(flags) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { loadProfileConfig } from '
|
|
2
|
-
import { negotiateCapabilities } from '
|
|
3
|
-
import { parseBooleanFlag } from '
|
|
4
|
-
import { exitAfterOutput } from '
|
|
1
|
+
import { loadProfileConfig } from '../../core/context.mjs';
|
|
2
|
+
import { negotiateCapabilities } from '../../core/http.mjs';
|
|
3
|
+
import { parseBooleanFlag } from '../../core/runMode.mjs';
|
|
4
|
+
import { exitAfterOutput } from '../../core/envelope.mjs';
|
|
5
5
|
|
|
6
6
|
function extractAgentKey(value) {
|
|
7
7
|
if (!value || typeof value !== 'object') return '';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { apiGet, apiPost } from '
|
|
2
|
-
import { loadProfileConfig } from '
|
|
3
|
-
import { normalizeVenueProviderId } from '
|
|
1
|
+
import { apiGet, apiPost } from '../../core/http.mjs';
|
|
2
|
+
import { loadProfileConfig } from '../../core/context.mjs';
|
|
3
|
+
import { normalizeVenueProviderId } from '../../core/venueBrand.mjs';
|
|
4
4
|
|
|
5
5
|
// `avantis` is the internal venue id the API expects; `veranta` (the venue's new name) maps onto it.
|
|
6
6
|
const VENUES = new Set(['polymarket', 'hyperliquid', 'lighter', 'avantis']);
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"title": "CLI response data: wallet profile (thirdfy-mcp getWalletProfile parity)",
|
|
4
|
+
"type": "object",
|
|
5
|
+
"required": [
|
|
6
|
+
"auth",
|
|
7
|
+
"source"
|
|
8
|
+
],
|
|
9
|
+
"properties": {
|
|
10
|
+
"auth": {
|
|
11
|
+
"enum": [
|
|
12
|
+
"owner",
|
|
13
|
+
"agent_api_key"
|
|
14
|
+
]
|
|
15
|
+
},
|
|
16
|
+
"source": {
|
|
17
|
+
"enum": [
|
|
18
|
+
"/api/v1/agent/onboarding/cli/status",
|
|
19
|
+
"/api/v1/agent/execution-wallet"
|
|
20
|
+
]
|
|
21
|
+
},
|
|
22
|
+
"profile": {
|
|
23
|
+
"type": "object"
|
|
24
|
+
},
|
|
25
|
+
"agentKey": {
|
|
26
|
+
"type": [
|
|
27
|
+
"string",
|
|
28
|
+
"null"
|
|
29
|
+
]
|
|
30
|
+
},
|
|
31
|
+
"chainId": {
|
|
32
|
+
"type": "integer"
|
|
33
|
+
},
|
|
34
|
+
"chainIdAssumed": {
|
|
35
|
+
"enum": [
|
|
36
|
+
true
|
|
37
|
+
]
|
|
38
|
+
},
|
|
39
|
+
"chainIdNote": {
|
|
40
|
+
"type": "string"
|
|
41
|
+
},
|
|
42
|
+
"ready": {
|
|
43
|
+
"type": "boolean"
|
|
44
|
+
},
|
|
45
|
+
"fundingReady": {
|
|
46
|
+
"type": "boolean"
|
|
47
|
+
},
|
|
48
|
+
"gas": {
|
|
49
|
+
"type": "object"
|
|
50
|
+
},
|
|
51
|
+
"walletControl": {
|
|
52
|
+
"type": "object"
|
|
53
|
+
},
|
|
54
|
+
"nextAction": {
|
|
55
|
+
"type": "string"
|
|
56
|
+
},
|
|
57
|
+
"userMessage": {
|
|
58
|
+
"type": "string"
|
|
59
|
+
},
|
|
60
|
+
"executionWallet": {
|
|
61
|
+
"type": "object",
|
|
62
|
+
"required": [
|
|
63
|
+
"executionWalletAddress"
|
|
64
|
+
],
|
|
65
|
+
"properties": {
|
|
66
|
+
"executionWalletAddress": {
|
|
67
|
+
"type": [
|
|
68
|
+
"string",
|
|
69
|
+
"null"
|
|
70
|
+
]
|
|
71
|
+
},
|
|
72
|
+
"userDid": {
|
|
73
|
+
"type": [
|
|
74
|
+
"string",
|
|
75
|
+
"null"
|
|
76
|
+
]
|
|
77
|
+
},
|
|
78
|
+
"data": {
|
|
79
|
+
"type": "object"
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
"additionalProperties": true
|
|
83
|
+
},
|
|
84
|
+
"note": {
|
|
85
|
+
"type": "string"
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
"additionalProperties": true,
|
|
89
|
+
"oneOf": [
|
|
90
|
+
{
|
|
91
|
+
"properties": {
|
|
92
|
+
"auth": {
|
|
93
|
+
"enum": [
|
|
94
|
+
"owner"
|
|
95
|
+
]
|
|
96
|
+
},
|
|
97
|
+
"source": {
|
|
98
|
+
"enum": [
|
|
99
|
+
"/api/v1/agent/onboarding/cli/status"
|
|
100
|
+
]
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
"required": [
|
|
104
|
+
"profile"
|
|
105
|
+
]
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
"properties": {
|
|
109
|
+
"auth": {
|
|
110
|
+
"enum": [
|
|
111
|
+
"agent_api_key"
|
|
112
|
+
]
|
|
113
|
+
},
|
|
114
|
+
"source": {
|
|
115
|
+
"enum": [
|
|
116
|
+
"/api/v1/agent/execution-wallet"
|
|
117
|
+
]
|
|
118
|
+
}
|
|
119
|
+
},
|
|
120
|
+
"required": [
|
|
121
|
+
"executionWallet",
|
|
122
|
+
"ready",
|
|
123
|
+
"chainId"
|
|
124
|
+
]
|
|
125
|
+
}
|
|
126
|
+
]
|
|
127
|
+
}
|
package/src/core/context.mjs
CHANGED
|
@@ -132,6 +132,26 @@ export function findAgentApiKey(flags = {}) {
|
|
|
132
132
|
return String(loadProfileConfig()?.agent?.apiKey || '').trim();
|
|
133
133
|
}
|
|
134
134
|
|
|
135
|
+
/**
|
|
136
|
+
* Whose credits a credits read is about. Same precedence as `wallet profile`: an owner credential
|
|
137
|
+
* passed as a flag (--owner-session-token or --auth-token), then an explicit --agent-api-key, then
|
|
138
|
+
* owner auth from env or config, then an agent key from env or config. Returns `{ ledger, agentApiKey,
|
|
139
|
+
* agentApiKeyExplicit }`; `ledger` is `agent` or `owner`.
|
|
140
|
+
*/
|
|
141
|
+
export function resolveCreditsLedger(flags = {}) {
|
|
142
|
+
const config = loadProfileConfig();
|
|
143
|
+
const explicitOwner = Boolean(String(flags.ownerSessionToken || flags.authToken || '').trim());
|
|
144
|
+
const agentApiKeyExplicit = Boolean(String(flags.agentApiKey || '').trim());
|
|
145
|
+
const storedOwner = Boolean(
|
|
146
|
+
String(
|
|
147
|
+
process.env.THIRDFY_OWNER_SESSION_TOKEN || process.env.THIRDFY_AUTH_TOKEN || config?.auth?.ownerSessionToken || config?.auth?.authToken || '',
|
|
148
|
+
).trim(),
|
|
149
|
+
);
|
|
150
|
+
const agentApiKey = findAgentApiKey(flags);
|
|
151
|
+
const agent = !explicitOwner && (agentApiKeyExplicit || (!storedOwner && Boolean(agentApiKey)));
|
|
152
|
+
return { ledger: agent ? 'agent' : 'owner', agentApiKey, agentApiKeyExplicit };
|
|
153
|
+
}
|
|
154
|
+
|
|
135
155
|
/**
|
|
136
156
|
* The actions list for this caller, cached per API base and key: the agent's own list
|
|
137
157
|
* (`GET /api/v1/agent/actions`) whenever an agent key is set (flag, env or config, `findAgentApiKey`),
|
|
@@ -4,4 +4,4 @@ export {
|
|
|
4
4
|
resolveExecutionContextFromInput as resolveEarnClawAttributionFromInput,
|
|
5
5
|
buildExecutionContextHeaders as buildEarnClawAttributionHeaders,
|
|
6
6
|
mergeExecutionContext as mergeEarnClawContext,
|
|
7
|
-
} from './executionContext.mjs';
|
|
7
|
+
} from './execution/executionContext.mjs';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { DEFAULT_TIMEOUT_MS } from '
|
|
1
|
+
import { DEFAULT_TIMEOUT_MS } from '../constants.mjs';
|
|
2
2
|
import { isReadOnlyActionName, isReadOnlyResolvedAction } from './readOnlyActions.mjs';
|
|
3
|
-
import { toLegacyVenueActionKey } from '
|
|
3
|
+
import { toLegacyVenueActionKey } from '../venueBrand.mjs';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Default HTTP timeout for managed writes. A perps order or TP/SL update signs, broadcasts, and waits
|
package/src/core/http.mjs
CHANGED
|
@@ -2,7 +2,7 @@ import { createCliError } from '../../core/envelope.mjs';
|
|
|
2
2
|
import {
|
|
3
3
|
HOSTED_RUNTIME_IDEMPOTENCY_NAMESPACE,
|
|
4
4
|
readHostedRuntimeUuid,
|
|
5
|
-
} from '../../core/hostedRuntimeIdempotency.mjs';
|
|
5
|
+
} from '../../core/execution/hostedRuntimeIdempotency.mjs';
|
|
6
6
|
|
|
7
7
|
const POLYMARKET_PLACE_ACTIONS = new Set([
|
|
8
8
|
'place_polymarket_order',
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { randomUUID } from 'crypto';
|
|
2
|
-
import { wrapWriteIdempotencyKeyForHostedRuntime } from '../../core/hostedRuntimeIdempotency.mjs';
|
|
3
|
-
import { resolveExecutionContextFromEnv } from '../../core/executionContext.mjs';
|
|
2
|
+
import { wrapWriteIdempotencyKeyForHostedRuntime } from '../../core/execution/hostedRuntimeIdempotency.mjs';
|
|
3
|
+
import { resolveExecutionContextFromEnv } from '../../core/execution/executionContext.mjs';
|
|
4
4
|
import { requireFlag, parseJsonFlag } from '../../core/args.mjs';
|
|
5
5
|
import { findAgentApiKey, loadProfileConfig } from '../../core/context.mjs';
|
|
6
6
|
import { createCliError } from '../../core/envelope.mjs';
|
|
7
7
|
import { toLegacyVenueActionKey } from '../../core/venueBrand.mjs';
|
|
8
8
|
import { normalizeRunMode, normalizeManagedRunMode, normalizeHybridWalletMode } from '../../core/runMode.mjs';
|
|
9
9
|
import { assertHostedRuntimePolymarketWriteIdempotency } from './hostedRuntimeWriteGate.mjs';
|
|
10
|
-
import { resolveTokenInForFunding } from '../../core/fundingTokenIn.mjs';
|
|
11
|
-
import { resolveWalletExecuteChainId } from '../../core/walletExecuteChainId.mjs';
|
|
10
|
+
import { resolveTokenInForFunding } from '../../core/execution/fundingTokenIn.mjs';
|
|
11
|
+
import { resolveWalletExecuteChainId } from '../../core/execution/walletExecuteChainId.mjs';
|
|
12
12
|
|
|
13
13
|
function isTruthyFlag(value) {
|
|
14
14
|
return value === true || String(value || '').trim().toLowerCase() === 'true';
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { apiPost } from '../../../core/http.mjs';
|
|
2
|
+
import { withActionTimeout } from '../../../core/execution/actionTimeouts.mjs';
|
|
3
|
+
import { actionNameForApi } from '../../actions/selection.mjs';
|
|
4
|
+
import { isEmptyQueuedExecuteIntent } from '../managedReadExecuteRail.mjs';
|
|
5
|
+
import {
|
|
6
|
+
isReadOnlyAction,
|
|
7
|
+
shouldFallbackAgentWalletToExecuteIntent,
|
|
8
|
+
normalizeManagedExecuteResponse,
|
|
9
|
+
READ_FAST_PATH_PREFLIGHT,
|
|
10
|
+
fastPathWalletMismatch,
|
|
11
|
+
} from './managedResponse.mjs';
|
|
12
|
+
import { createRequire } from 'module';
|
|
13
|
+
|
|
14
|
+
const require = createRequire(import.meta.url);
|
|
15
|
+
const { normalizeIntentResponse } = require('../../../utils/cli/intentNormalization.cjs');
|
|
16
|
+
|
|
17
|
+
/** The agent_wallet lane: the API signs with the agent's execution wallet. */
|
|
18
|
+
export function createAgentWalletLane(deps, lanes) {
|
|
19
|
+
const {
|
|
20
|
+
buildManagedExecutePayload,
|
|
21
|
+
} = deps;
|
|
22
|
+
const { shouldUseManagedReadFastPath, runReadOnlyActionViaIntentRail, resolveManagedExecutionPreflight } = lanes;
|
|
23
|
+
|
|
24
|
+
async function executeManagedWalletRun(ctx, flags, resolved, options) {
|
|
25
|
+
// Market-data reads under agent_wallet must use /execute and keep the provider payload on the
|
|
26
|
+
// envelope (raw + parsed data.result). Routing them only through /execute-intent was the 0.2.34
|
|
27
|
+
// attempt to avoid a burial bug, but solo Hermes agent_wallet intents come back as an empty
|
|
28
|
+
// queued envelope with no universe. Live /execute still returns the Hyperliquid meta payload
|
|
29
|
+
// (often as a JSON string under data.result). Reads skip funding gates; routing still fails closed.
|
|
30
|
+
const isRead = isReadOnlyAction(resolved);
|
|
31
|
+
const skipPreflight = Boolean(options?.skipPreflight);
|
|
32
|
+
// A seeded preflight (Hyperliquid/Lighter/Veranta address defaults) already ran; reuse it.
|
|
33
|
+
const readFastPath =
|
|
34
|
+
!skipPreflight && !options?.managedPreflight && shouldUseManagedReadFastPath(flags, resolved, options);
|
|
35
|
+
let preflight = readFastPath ? READ_FAST_PATH_PREFLIGHT : null;
|
|
36
|
+
if (!skipPreflight && !readFastPath) {
|
|
37
|
+
preflight = await resolveManagedExecutionPreflight(ctx, flags, resolved, {
|
|
38
|
+
runMode: 'agent_wallet',
|
|
39
|
+
requireFundingCheck: !isRead,
|
|
40
|
+
preflightSeed: options?.managedPreflight,
|
|
41
|
+
});
|
|
42
|
+
if (!preflight.success) {
|
|
43
|
+
const normalized = normalizeIntentResponse({
|
|
44
|
+
success: false,
|
|
45
|
+
status: 'failed',
|
|
46
|
+
mode: 'agent_wallet',
|
|
47
|
+
blockedReason: preflight.blockedReason || 'PRECHECK_FAILED',
|
|
48
|
+
blockedStage: preflight.blockedStage || 'routing',
|
|
49
|
+
error: preflight.error || 'Managed wallet preflight failed',
|
|
50
|
+
preflightBlocked: true,
|
|
51
|
+
executionWalletAddress: preflight.executionWalletAddress || null,
|
|
52
|
+
executionWalletPreflight: preflight,
|
|
53
|
+
});
|
|
54
|
+
normalized.executionWalletAddress = preflight.executionWalletAddress || null;
|
|
55
|
+
normalized.executionWalletPreflight = preflight;
|
|
56
|
+
return normalized;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
const payload = buildManagedExecutePayload(flags, {
|
|
60
|
+
resolvedAction: resolved.resolvedAction,
|
|
61
|
+
apiAction: actionNameForApi(resolved),
|
|
62
|
+
runMode: 'agent_wallet',
|
|
63
|
+
forceIdempotency: true,
|
|
64
|
+
});
|
|
65
|
+
const actionCtx = withActionTimeout(ctx, resolved);
|
|
66
|
+
const response = await apiPost(actionCtx, '/api/v1/agent/execute', payload);
|
|
67
|
+
if (readFastPath) {
|
|
68
|
+
const mismatch = fastPathWalletMismatch(flags, response);
|
|
69
|
+
if (mismatch) return mismatch;
|
|
70
|
+
}
|
|
71
|
+
if (shouldFallbackAgentWalletToExecuteIntent(resolved, response)) {
|
|
72
|
+
// On the fast path the wallet comes from the /execute answer, not a preflight.
|
|
73
|
+
const fallbackPreflight = readFastPath
|
|
74
|
+
? {
|
|
75
|
+
...READ_FAST_PATH_PREFLIGHT,
|
|
76
|
+
executionWalletAddress: response?.executionWalletAddress || response?.data?.executionWalletAddress || null,
|
|
77
|
+
}
|
|
78
|
+
: preflight;
|
|
79
|
+
const intentResult = await runReadOnlyActionViaIntentRail(ctx, flags, resolved, options, fallbackPreflight);
|
|
80
|
+
if (isEmptyQueuedExecuteIntent(intentResult.raw || intentResult)) {
|
|
81
|
+
// A read that did not answer in time (often a cold provider cache): nothing changed, and the
|
|
82
|
+
// same read usually answers on the next try. Same fields as thirdfy-mcp walletExecute.
|
|
83
|
+
intentResult.success = false;
|
|
84
|
+
intentResult.status = 'failed';
|
|
85
|
+
intentResult.error = intentResult.error || 'MANAGED_READ_EMPTY_EXECUTE_INTENT';
|
|
86
|
+
Object.assign(intentResult, {
|
|
87
|
+
errorCode: 'MANAGED_READ_EMPTY_EXECUTE_INTENT',
|
|
88
|
+
retryable: true,
|
|
89
|
+
retryAfterSeconds: 3,
|
|
90
|
+
nextAction: 'retry_later',
|
|
91
|
+
hint:
|
|
92
|
+
intentResult.hint ||
|
|
93
|
+
'The read did not answer in time; nothing was changed. Repeat the same read in a few seconds. Do not treat the empty queued result as data.',
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
intentResult.executionWalletAddress =
|
|
97
|
+
preflight?.executionWalletAddress ||
|
|
98
|
+
response?.executionWalletAddress ||
|
|
99
|
+
response?.data?.executionWalletAddress ||
|
|
100
|
+
null;
|
|
101
|
+
return intentResult;
|
|
102
|
+
}
|
|
103
|
+
return normalizeManagedExecuteResponse(response, { preflight, payload, isRead });
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return {
|
|
107
|
+
executeManagedWalletRun,
|
|
108
|
+
};
|
|
109
|
+
}
|