ethagent 1.1.0 → 1.1.1
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 +18 -81
- package/package.json +1 -1
- package/src/chat/chatTurnOrchestrator.ts +1 -1
- package/src/identity/hub/screens/ContinuityDashboardScreen.tsx +1 -1
- package/src/identity/hub/screens/ErrorScreen.tsx +1 -1
- package/src/identity/hub/screens/MenuScreen.tsx +2 -2
- package/src/identity/wallet/wallet-page/wallet.html +370 -379
package/README.md
CHANGED
|
@@ -3,118 +3,59 @@
|
|
|
3
3
|
|
|
4
4
|
A privacy-first AI agent with a portable Ethereum identity.
|
|
5
5
|
|
|
6
|
-
ethagent
|
|
7
|
-
|
|
8
|
-
The identity stays portable. The model can change. The private memory stays under wallet-gated encryption.
|
|
6
|
+
ethagent binds an AI agent to a wallet-owned ERC-8004 token. Persona and memory stay encrypted under your wallet signature and pinned to IPFS. Public skills publish as machine-readable JSON so other agents can discover what it does. Swap models, switch machines, restore the same agent from one onchain pointer.
|
|
9
7
|
|
|
10
8
|
## Install
|
|
11
9
|
|
|
12
10
|
ethagent requires Node.js 20 or newer. Install it from npm with `npm install -g ethagent`, then start it with `ethagent`.
|
|
13
11
|
|
|
14
|
-
On first run, ethagent guides you through model setup and identity setup. You can use a local GGUF model through llama.cpp, or connect OpenAI, Anthropic, or Gemini.
|
|
15
|
-
|
|
16
|
-
## What It Does
|
|
17
|
-
|
|
18
|
-
* Runs an AI coding agent in your terminal.
|
|
19
|
-
* Switches between cloud models and local GGUF models.
|
|
20
|
-
* Creates or loads a wallet-owned ERC-8004 agent identity.
|
|
21
|
-
* Encrypts private continuity before IPFS pinning.
|
|
22
|
-
* Publishes public `skills.json` and Agent Card metadata for discovery.
|
|
23
|
-
* Restores the same agent on another machine from the onchain record.
|
|
24
|
-
* Supports workspace tools, managed edit rewind, session resume, context compaction, and MCP servers.
|
|
25
|
-
|
|
26
12
|
## First Run
|
|
27
13
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
You can create a new ERC-8004 agent with a browser wallet, load an agent token you already own, or skip identity setup and add it later from the Identity Hub.
|
|
31
|
-
|
|
32
|
-
Use `Alt+P` to switch models and `Alt+I` to open the Identity Hub. Inside the agent, `/help` shows the live command list for the version you are running.
|
|
14
|
+
First run walks model setup, then identity setup. You can use a local GGUF model through llama.cpp, or connect OpenAI, Anthropic, or Gemini.
|
|
33
15
|
|
|
34
|
-
|
|
16
|
+
Create a new ERC-8004 agent with a browser wallet, load an agent token you already own, or skip identity setup and add it later from the Identity Hub.
|
|
35
17
|
|
|
36
|
-
|
|
18
|
+
Use `Alt+P` to swap models and `Alt+I` to open the Identity Hub. Inside the agent, `/help` shows the live command list for the version you are running.
|
|
37
19
|
|
|
38
|
-
|
|
39
|
-
| --- | --- |
|
|
40
|
-
| Public Metadata | Profile name, description, image, `skills.json`, and Agent Card. |
|
|
41
|
-
| Private Local Files | `SOUL.md`, `MEMORY.md`, and the local copy of `skills.json`. |
|
|
42
|
-
| Recovery | Publishing the current encrypted snapshot or refetching the latest one from chain. |
|
|
43
|
-
| Storage | The Pinata JWT used to pin continuity and metadata to IPFS. |
|
|
44
|
-
| Agent Token | Registry, owner, token, URI, CID, and copyable identity values. |
|
|
45
|
-
|
|
46
|
-
The hub is a recovery panel, not a history archive. The current tokenURI is the source of truth for the latest published state.
|
|
47
|
-
|
|
48
|
-
## Continuity
|
|
20
|
+
## Identity & Continuity
|
|
49
21
|
|
|
50
|
-
Each identity gets a local continuity vault under `~/.ethagent/continuity`.
|
|
22
|
+
The Identity Hub manages the portable identity. Each identity gets a local continuity vault under `~/.ethagent/continuity`.
|
|
51
23
|
|
|
52
24
|
| File | Visibility | Purpose |
|
|
53
25
|
| --- | --- | --- |
|
|
54
26
|
| `SOUL.md` | Private | Persona, boundaries, standing instructions, and identity framing. |
|
|
55
27
|
| `MEMORY.md` | Private | Durable preferences, project context, decisions, and operating notes. |
|
|
56
|
-
| `skills.json` | Public | Machine-readable capabilities
|
|
57
|
-
|
|
58
|
-
`SOUL.md` and `MEMORY.md` are encrypted before they are pinned to IPFS. They are not published as plaintext in token metadata.
|
|
59
|
-
|
|
60
|
-
`skills.json` is public by design. It uses schema `ethagent.public-skills.v1` and is meant to be easy for other agents, apps, and scanners to parse.
|
|
61
|
-
|
|
62
|
-
## Recovery
|
|
28
|
+
| `skills.json` | Public | Machine-readable capabilities under schema `ethagent.public-skills.v1`, easy for other agents and apps to parse. |
|
|
63
29
|
|
|
64
|
-
|
|
30
|
+
`SOUL.md` and `MEMORY.md` are encrypted before they reach IPFS. They are never published as plaintext in token metadata.
|
|
65
31
|
|
|
66
|
-
**Refetch Latest Snapshot** reads the current tokenURI from chain,
|
|
67
|
-
|
|
68
|
-
Publishing replaces the current onchain pointer. Registration metadata contains the current CIDs only.
|
|
69
|
-
|
|
70
|
-
## Public Discovery
|
|
71
|
-
|
|
72
|
-
The public registration metadata is intentionally compact. It describes the current state of the agent, not its history.
|
|
73
|
-
|
|
74
|
-
It can include:
|
|
75
|
-
|
|
76
|
-
* Agent name, description, and image.
|
|
77
|
-
* Current encrypted continuity CID.
|
|
78
|
-
* Current public `skills.json` CID.
|
|
79
|
-
* Current Agent Card CID.
|
|
80
|
-
* Service entries with canonical `endpoint` values.
|
|
81
|
-
* Registry linkage through `registrations[]`.
|
|
82
|
-
|
|
83
|
-
This is enough for baseline agent-to-agent discovery and delegation without exposing private memory or installing executable code.
|
|
32
|
+
**Save Snapshot Now** encrypts the current private continuity, pins the public discovery files, writes registration metadata, and updates the ERC-8004 tokenURI. **Refetch Latest Snapshot** reads the current tokenURI from chain, asks the owner wallet to sign the decrypt challenge, and restores local files from the published state. The current tokenURI is the source of truth.
|
|
84
33
|
|
|
85
34
|
## Models
|
|
86
35
|
|
|
87
36
|
ethagent works with OpenAI, Anthropic, Gemini, and local GGUF models served through a llama.cpp-compatible endpoint.
|
|
88
37
|
|
|
89
|
-
The model picker
|
|
38
|
+
The model picker discovers provider models, manages API keys, recommends GGUF files for your machine, and starts or attaches to a local runner. The featured local model is [Qwen3.5-9B-Uncensored](https://huggingface.co/HauhauCS/Qwen3.5-9B-Uncensored-HauhauCS-Aggressive); other Hugging Face GGUF models work by repo ID or URL.
|
|
90
39
|
|
|
91
|
-
|
|
40
|
+
Cloud API keys live in the OS keyring when available, with an encrypted local file under `~/.ethagent` as fallback.
|
|
92
41
|
|
|
93
|
-
|
|
42
|
+
## Tools & Sessions
|
|
94
43
|
|
|
95
|
-
|
|
44
|
+
File ops, shell, clipboard, and MCP tools, all permissioned. Managed edits support `/rewind`. Sessions support `/resume`, `/compact`, and `/export`.
|
|
96
45
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
Tool use is permissioned. Managed edits are tracked so recent workspace changes can be rewound from inside the agent.
|
|
100
|
-
|
|
101
|
-
Sessions are local. You can resume prior sessions, export a transcript, compact older context, and review saved project permissions.
|
|
46
|
+
`Shift+Tab` cycles Plan, Accept-Edits, and Chat modes. `Alt+T` toggles reasoning display.
|
|
102
47
|
|
|
103
48
|
## Privacy
|
|
104
49
|
|
|
105
50
|
Public information includes token ownership, tokenURI metadata, public discovery files, and IPFS CIDs.
|
|
106
51
|
|
|
107
|
-
Private information includes plaintext `SOUL.md`, plaintext `MEMORY.md`, sessions, prompt history, API keys, local permissions, and wallet signatures used for
|
|
52
|
+
Private information includes plaintext `SOUL.md`, plaintext `MEMORY.md`, sessions, prompt history, API keys, local permissions, and wallet signatures used for decryption.
|
|
108
53
|
|
|
109
54
|
Continuity snapshots use an EIP-191 wallet signature as unlock material and encrypt with ML-KEM-1024, HKDF-SHA256, and AES-256-GCM. The unlock signature does not submit a transaction, spend funds, or grant token approval.
|
|
110
55
|
|
|
111
|
-
If an ERC-8004 token is transferred, the new holder can see public metadata and encrypted backup CIDs. They cannot decrypt private continuity that was
|
|
112
|
-
|
|
113
|
-
## Local Reset
|
|
56
|
+
If an ERC-8004 token is transferred, the new holder can see public metadata and encrypted backup CIDs. They cannot decrypt private continuity that was sealed for the previous owner wallet.
|
|
114
57
|
|
|
115
|
-
`ethagent reset` deletes local ethagent data from this machine while preserving installed local model assets. It does not burn or transfer ERC-8004 tokens, remove public IPFS content, or mutate onchain metadata.
|
|
116
|
-
|
|
117
|
-
Before resetting, use **Publish Snapshot Now** if local continuity changes should become the current recoverable state.
|
|
58
|
+
`ethagent reset` deletes local ethagent data from this machine while preserving installed local model assets. It does not burn or transfer ERC-8004 tokens, remove public IPFS content, or mutate onchain metadata. Run **Save Snapshot Now** before resetting if local changes should become the recoverable state.
|
|
118
59
|
|
|
119
60
|
## Architecture
|
|
120
61
|
|
|
@@ -129,10 +70,6 @@ Before resetting, use **Publish Snapshot Now** if local continuity changes shoul
|
|
|
129
70
|
|
|
130
71
|
The ERC-8004 token is the durable handle. The machine, model, and local session can change around it.
|
|
131
72
|
|
|
132
|
-
## Links
|
|
133
|
-
|
|
134
73
|
[npm](https://www.npmjs.com/package/ethagent) · [GitHub](https://github.com/baairon/ethagent) · [ERC-8004](https://eips.ethereum.org/EIPS/eip-8004) · [soul.md](https://soul.md/)
|
|
135
74
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
MIT
|
|
75
|
+
MIT License.
|
package/package.json
CHANGED
|
@@ -665,7 +665,7 @@ export async function buildIdentityContinuityContextMessages(
|
|
|
665
665
|
content: [
|
|
666
666
|
'<identity_continuity_files>',
|
|
667
667
|
`Automatic identity continuity load failed: ${(err as Error).message}`,
|
|
668
|
-
'If the user asks about continuity, surface this failure and route them to the
|
|
668
|
+
'If the user asks about continuity, surface this failure and route them to the Identity Hub.',
|
|
669
669
|
'</identity_continuity_files>',
|
|
670
670
|
].join('\n'),
|
|
671
671
|
}]
|
|
@@ -135,7 +135,7 @@ const PublicProfileRows: React.FC<{ identity?: EthagentIdentity }> = ({ identity
|
|
|
135
135
|
function privateSubtitle(ready: boolean): string {
|
|
136
136
|
return ready
|
|
137
137
|
? 'SOUL.md and MEMORY.md are private local files on this machine.'
|
|
138
|
-
: 'Use "Refetch Latest Snapshot" from the
|
|
138
|
+
: 'Use "Refetch Latest Snapshot" from the Identity Hub menu to recover files.'
|
|
139
139
|
}
|
|
140
140
|
|
|
141
141
|
function readStateString(state: Record<string, unknown> | undefined, key: string): string {
|
|
@@ -22,7 +22,7 @@ export const ErrorScreen: React.FC<ErrorScreenProps> = ({ error, back, footer, o
|
|
|
22
22
|
{ value: 'back', role: 'section', prefix: '--', label: 'Recovery' },
|
|
23
23
|
{ value: 'back', label: 'Go Back', hint: 'Return to the previous identity step' },
|
|
24
24
|
{ value: 'close', role: 'section', prefix: '--', label: 'Exit' },
|
|
25
|
-
{ value: 'close', label: 'Close Hub', hint: 'Return to chat without retrying', role: 'utility' },
|
|
25
|
+
{ value: 'close', label: 'Close Identity Hub', hint: 'Return to chat without retrying', role: 'utility' },
|
|
26
26
|
]}
|
|
27
27
|
hintLayout="inline"
|
|
28
28
|
onSubmit={choice => {
|
|
@@ -78,7 +78,7 @@ export const MenuScreen: React.FC<MenuScreenProps> = ({
|
|
|
78
78
|
{ value: 'load', label: 'Switch Agent', hint: 'Load a different token owned by your wallet' },
|
|
79
79
|
{ value: 'create', label: 'New Agent', hint: 'Mint another token and make it active here' },
|
|
80
80
|
{ value: 'cancel', role: 'section', prefix: '--', label: 'Exit' },
|
|
81
|
-
{ value: 'cancel', label: 'Close Hub', hint: 'Return to chat without changing identity', role: 'utility' },
|
|
81
|
+
{ value: 'cancel', label: 'Close Identity Hub', hint: 'Return to chat without changing identity', role: 'utility' },
|
|
82
82
|
]
|
|
83
83
|
: [
|
|
84
84
|
{ value: 'create', role: 'section', prefix: '--', label: 'Setup' },
|
|
@@ -87,7 +87,7 @@ export const MenuScreen: React.FC<MenuScreenProps> = ({
|
|
|
87
87
|
{ value: 'skip', role: 'section', prefix: '--', label: 'Exit' },
|
|
88
88
|
...(mode === 'first-run'
|
|
89
89
|
? [{ value: 'skip' as Action, label: 'Skip For Now', hint: 'Continue now; use /identity later', role: 'utility' as const }]
|
|
90
|
-
: [{ value: 'cancel' as Action, label: 'Close Hub', hint: 'Return to chat without changing identity', role: 'utility' as const }]),
|
|
90
|
+
: [{ value: 'cancel' as Action, label: 'Close Identity Hub', hint: 'Return to chat without changing identity', role: 'utility' as const }]),
|
|
91
91
|
]
|
|
92
92
|
|
|
93
93
|
return (
|