@thirdfy/agent-cli 0.1.2 → 0.1.3
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 +25 -3
- package/bin/thirdfy-agent.mjs +85 -15
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -34,25 +34,47 @@ npx @thirdfy/agent-cli --help
|
|
|
34
34
|
export THIRDFY_API_BASE="https://api.thirdfy.com"
|
|
35
35
|
export AGENT_API_KEY="..."
|
|
36
36
|
export THIRDFY_AUTH_TOKEN="..."
|
|
37
|
+
export THIRDFY_OWNER_SESSION_TOKEN="..."
|
|
37
38
|
|
|
38
39
|
thirdfy-agent actions --api-base "$THIRDFY_API_BASE" --agent-api-key "$AGENT_API_KEY" --json
|
|
39
40
|
thirdfy-agent preflight --api-base "$THIRDFY_API_BASE" --agent-api-key "$AGENT_API_KEY" --action swap --params '{"tokenIn":"0x...","tokenOut":"0x...","amountIn":"1000000"}' --estimated-amount-usd 25 --json
|
|
40
|
-
thirdfy-agent run --api-base "$THIRDFY_API_BASE" --agent-api-key "$AGENT_API_KEY" --action swap --params '{"tokenIn":"0x...","tokenOut":"0x...","amountIn":"1000000"}' --estimated-amount-usd 25 --
|
|
41
|
+
thirdfy-agent run --api-base "$THIRDFY_API_BASE" --agent-api-key "$AGENT_API_KEY" --action swap --params '{"tokenIn":"0x...","tokenOut":"0x...","amountIn":"1000000"}' --estimated-amount-usd 25 --json
|
|
41
42
|
thirdfy-agent intent-status --api-base "$THIRDFY_API_BASE" --intent-id "<intentId>" --json
|
|
42
43
|
```
|
|
43
44
|
|
|
44
45
|
## Auth model
|
|
45
46
|
|
|
46
47
|
- `AGENT_API_KEY`: execution identity and policy-aware action access (`actions --agent-api-key`, `preflight`, `run`)
|
|
47
|
-
- `THIRDFY_AUTH_TOKEN`:
|
|
48
|
+
- `THIRDFY_AUTH_TOKEN`: Privy-native owner/account auth (`agent register`, `agent key *`, `delegation *`, `credentials *`, `credits balance`)
|
|
49
|
+
- `THIRDFY_OWNER_SESSION_TOKEN`: wallet-sign owner auth session (`agent register`, `agent key *`)
|
|
48
50
|
|
|
49
51
|
Execution-only workflows can run with only `AGENT_API_KEY` after onboarding is complete.
|
|
50
52
|
|
|
53
|
+
### Wallet-sign onboarding path
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
thirdfy-agent agent auth challenge --api-base "$THIRDFY_API_BASE" --agent-key "0xYOUR_AGENT_KEY" --json
|
|
57
|
+
# Sign challenge.message with your wallet, then:
|
|
58
|
+
thirdfy-agent agent auth verify --api-base "$THIRDFY_API_BASE" --challenge-id "<challengeId>" --signature "0x..." --agent-key "0xYOUR_AGENT_KEY" --json
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Use the returned session token:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
thirdfy-agent agent register --api-base "$THIRDFY_API_BASE" --owner-session-token "$THIRDFY_OWNER_SESSION_TOKEN" --agent-key "0xYOUR_AGENT_KEY" --name "my-agent" --json
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Idempotency behavior (`run`)
|
|
68
|
+
|
|
69
|
+
- `run` auto-generates `idempotencyKey` by default when not provided.
|
|
70
|
+
- For deterministic retries across workers/restarts, pass your own stable `--idempotency-key`.
|
|
71
|
+
- `preflight` does not force idempotency keys.
|
|
72
|
+
|
|
51
73
|
## Command groups
|
|
52
74
|
|
|
53
75
|
- Discovery: `catalogs list`, `actions`
|
|
54
76
|
- Execution: `preflight`, `run`, `intent-status`
|
|
55
|
-
- Onboarding: `agent register`, `agent key rotate`, `agent key revoke`
|
|
77
|
+
- Onboarding: `agent auth challenge`, `agent auth verify`, `agent register`, `agent key rotate`, `agent key revoke`
|
|
56
78
|
- Governance readiness: `delegation upsert`, `delegation status`, `credentials upsert`, `credentials status`
|
|
57
79
|
- Account: `credits balance`
|
|
58
80
|
|
package/bin/thirdfy-agent.mjs
CHANGED
|
@@ -113,6 +113,14 @@ async function main() {
|
|
|
113
113
|
await commandAgentKeyRevoke(context, subFlags, capabilities);
|
|
114
114
|
return;
|
|
115
115
|
}
|
|
116
|
+
if (commandKey3 === 'agent auth challenge') {
|
|
117
|
+
await commandAgentAuthChallenge(context, subFlags, capabilities);
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
if (commandKey3 === 'agent auth verify') {
|
|
121
|
+
await commandAgentAuthVerify(context, subFlags, capabilities);
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
116
124
|
|
|
117
125
|
const rootCommand = parsed.positionals[0];
|
|
118
126
|
switch (rootCommand) {
|
|
@@ -483,7 +491,10 @@ async function commandCredentialsStatus(ctx, flags, capabilities) {
|
|
|
483
491
|
}
|
|
484
492
|
|
|
485
493
|
async function commandAgentRegister(ctx, flags, capabilities) {
|
|
486
|
-
const
|
|
494
|
+
const ownerHeaders = buildOwnerAuthHeaders(
|
|
495
|
+
flags,
|
|
496
|
+
'Missing owner auth for agent register: provide --auth-token (THIRDFY_AUTH_TOKEN) or --owner-session-token'
|
|
497
|
+
);
|
|
487
498
|
const payload = {
|
|
488
499
|
agentKey: requireFlag(flags, 'agentKey', 'Missing --agent-key'),
|
|
489
500
|
name: requireFlag(flags, 'name', 'Missing --name'),
|
|
@@ -501,9 +512,10 @@ async function commandAgentRegister(ctx, flags, capabilities) {
|
|
|
501
512
|
if (flags.strategy) payload.strategy = parseJsonFlag(flags, 'strategy');
|
|
502
513
|
if (flags.apiKeyEnvelopePublicKey) payload.apiKeyEnvelopePublicKey = String(flags.apiKeyEnvelopePublicKey);
|
|
503
514
|
|
|
504
|
-
const
|
|
505
|
-
|
|
506
|
-
|
|
515
|
+
const route = ownerHeaders['x-owner-session-token']
|
|
516
|
+
? '/api/v1/agent/onboarding/register-with-wallet'
|
|
517
|
+
: '/api/v1/agent/onboarding/register-with-privy';
|
|
518
|
+
const response = await apiPost(ctx, route, payload, ownerHeaders);
|
|
507
519
|
printEnvelope({
|
|
508
520
|
success: true,
|
|
509
521
|
code: 'AGENT_REGISTERED',
|
|
@@ -517,12 +529,13 @@ async function commandAgentRegister(ctx, flags, capabilities) {
|
|
|
517
529
|
}
|
|
518
530
|
|
|
519
531
|
async function commandAgentKeyRotate(ctx, flags, capabilities) {
|
|
520
|
-
const
|
|
532
|
+
const ownerHeaders = buildOwnerAuthHeaders(
|
|
533
|
+
flags,
|
|
534
|
+
'Missing owner auth for agent key rotate: provide --auth-token (THIRDFY_AUTH_TOKEN) or --owner-session-token'
|
|
535
|
+
);
|
|
521
536
|
const payload = {};
|
|
522
537
|
if (flags.agentKey) payload.agentKey = String(flags.agentKey).trim();
|
|
523
|
-
const response = await apiPost(ctx, '/api/v1/agent/onboarding/me/api-key/rotate', payload,
|
|
524
|
-
Authorization: `Bearer ${authToken}`,
|
|
525
|
-
});
|
|
538
|
+
const response = await apiPost(ctx, '/api/v1/agent/onboarding/me/api-key/rotate', payload, ownerHeaders);
|
|
526
539
|
printEnvelope({
|
|
527
540
|
success: true,
|
|
528
541
|
code: 'AGENT_KEY_ROTATED',
|
|
@@ -536,12 +549,13 @@ async function commandAgentKeyRotate(ctx, flags, capabilities) {
|
|
|
536
549
|
}
|
|
537
550
|
|
|
538
551
|
async function commandAgentKeyRevoke(ctx, flags, capabilities) {
|
|
539
|
-
const
|
|
552
|
+
const ownerHeaders = buildOwnerAuthHeaders(
|
|
553
|
+
flags,
|
|
554
|
+
'Missing owner auth for agent key revoke: provide --auth-token (THIRDFY_AUTH_TOKEN) or --owner-session-token'
|
|
555
|
+
);
|
|
540
556
|
const payload = {};
|
|
541
557
|
if (flags.agentKey) payload.agentKey = String(flags.agentKey).trim();
|
|
542
|
-
const response = await apiPost(ctx, '/api/v1/agent/onboarding/me/api-key/revoke', payload,
|
|
543
|
-
Authorization: `Bearer ${authToken}`,
|
|
544
|
-
});
|
|
558
|
+
const response = await apiPost(ctx, '/api/v1/agent/onboarding/me/api-key/revoke', payload, ownerHeaders);
|
|
545
559
|
printEnvelope({
|
|
546
560
|
success: true,
|
|
547
561
|
code: 'AGENT_KEY_REVOKED',
|
|
@@ -554,6 +568,47 @@ async function commandAgentKeyRevoke(ctx, flags, capabilities) {
|
|
|
554
568
|
});
|
|
555
569
|
}
|
|
556
570
|
|
|
571
|
+
async function commandAgentAuthChallenge(ctx, flags, capabilities) {
|
|
572
|
+
const payload = {
|
|
573
|
+
agentKey: requireFlag(flags, 'agentKey', 'Missing --agent-key'),
|
|
574
|
+
chainId: Number(flags.chainId || 8453),
|
|
575
|
+
};
|
|
576
|
+
if (flags.walletAddress) payload.walletAddress = String(flags.walletAddress).trim();
|
|
577
|
+
|
|
578
|
+
const response = await apiPost(ctx, '/api/v1/agent/onboarding/wallet/challenge', payload);
|
|
579
|
+
printEnvelope({
|
|
580
|
+
success: true,
|
|
581
|
+
code: 'OWNER_CHALLENGE_CREATED',
|
|
582
|
+
message: 'Wallet challenge created',
|
|
583
|
+
data: response,
|
|
584
|
+
meta: {
|
|
585
|
+
apiBase: ctx.apiBase,
|
|
586
|
+
capabilitiesVersion: capabilities?.contractVersion || null,
|
|
587
|
+
},
|
|
588
|
+
});
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
async function commandAgentAuthVerify(ctx, flags, capabilities) {
|
|
592
|
+
const payload = {
|
|
593
|
+
challengeId: requireFlag(flags, 'challengeId', 'Missing --challenge-id'),
|
|
594
|
+
signature: requireFlag(flags, 'signature', 'Missing --signature'),
|
|
595
|
+
agentKey: requireFlag(flags, 'agentKey', 'Missing --agent-key'),
|
|
596
|
+
};
|
|
597
|
+
if (flags.walletAddress) payload.walletAddress = String(flags.walletAddress).trim();
|
|
598
|
+
|
|
599
|
+
const response = await apiPost(ctx, '/api/v1/agent/onboarding/wallet/verify', payload);
|
|
600
|
+
printEnvelope({
|
|
601
|
+
success: true,
|
|
602
|
+
code: 'OWNER_VERIFIED',
|
|
603
|
+
message: 'Wallet challenge verified',
|
|
604
|
+
data: response,
|
|
605
|
+
meta: {
|
|
606
|
+
apiBase: ctx.apiBase,
|
|
607
|
+
capabilitiesVersion: capabilities?.contractVersion || null,
|
|
608
|
+
},
|
|
609
|
+
});
|
|
610
|
+
}
|
|
611
|
+
|
|
557
612
|
function buildIntentPayload(flags, options) {
|
|
558
613
|
const payload = {
|
|
559
614
|
agentApiKey: requireFlag(flags, 'agentApiKey', 'Missing --agent-api-key'),
|
|
@@ -687,6 +742,18 @@ function getAuthToken(flags, missingMessage) {
|
|
|
687
742
|
return authToken;
|
|
688
743
|
}
|
|
689
744
|
|
|
745
|
+
function buildOwnerAuthHeaders(flags, missingMessage) {
|
|
746
|
+
const authToken = String(flags.authToken || process.env.THIRDFY_AUTH_TOKEN || '').trim();
|
|
747
|
+
const ownerSessionToken = String(flags.ownerSessionToken || process.env.THIRDFY_OWNER_SESSION_TOKEN || '').trim();
|
|
748
|
+
if (!authToken && !ownerSessionToken) {
|
|
749
|
+
throw new Error(missingMessage);
|
|
750
|
+
}
|
|
751
|
+
if (authToken) {
|
|
752
|
+
return { Authorization: `Bearer ${authToken}` };
|
|
753
|
+
}
|
|
754
|
+
return { 'x-owner-session-token': ownerSessionToken };
|
|
755
|
+
}
|
|
756
|
+
|
|
690
757
|
function extractActions(response) {
|
|
691
758
|
if (Array.isArray(response)) return response;
|
|
692
759
|
if (Array.isArray(response.actions)) return response.actions;
|
|
@@ -793,9 +860,11 @@ Core commands:
|
|
|
793
860
|
thirdfy-agent delegation status --auth-token <token> --agent-key <key> [--verify] [--json]
|
|
794
861
|
thirdfy-agent credentials upsert --auth-token <token> --venue <id> --api-key <key> --api-secret <secret> [--json]
|
|
795
862
|
thirdfy-agent credentials status --auth-token <token> [--venue <id>] [--json]
|
|
796
|
-
thirdfy-agent agent
|
|
797
|
-
thirdfy-agent agent
|
|
798
|
-
thirdfy-agent agent key
|
|
863
|
+
thirdfy-agent agent auth challenge --agent-key <key> [--wallet-address <addr>] [--chain-id <id>] [--json]
|
|
864
|
+
thirdfy-agent agent auth verify --challenge-id <id> --signature <hex> --agent-key <key> [--wallet-address <addr>] [--json]
|
|
865
|
+
thirdfy-agent agent register --agent-key <key> --name <name> [--auth-token <token> | --owner-session-token <token>] [--json]
|
|
866
|
+
thirdfy-agent agent key rotate [--agent-key <key>] [--auth-token <token> | --owner-session-token <token>] [--json]
|
|
867
|
+
thirdfy-agent agent key revoke [--agent-key <key>] [--auth-token <token> | --owner-session-token <token>] [--json]
|
|
799
868
|
thirdfy-agent preflight --agent-api-key <key> --action <id> --params <json> [--json]
|
|
800
869
|
thirdfy-agent run --agent-api-key <key> --action <id> --params <json> [--idempotency-key <key>] [--json]
|
|
801
870
|
thirdfy-agent intent-status --intent-id <id> [--json]
|
|
@@ -805,6 +874,7 @@ Global flags:
|
|
|
805
874
|
--api-base <url> default: https://api.thirdfy.com
|
|
806
875
|
--env <file> load env vars from file
|
|
807
876
|
--timeout <ms> request timeout
|
|
877
|
+
--owner-session-token <token> owner session token (or THIRDFY_OWNER_SESSION_TOKEN)
|
|
808
878
|
--json stable machine-readable output
|
|
809
879
|
--verbose print adapter diagnostics
|
|
810
880
|
--version print version
|