clinch-core 0.5.0 → 0.6.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.
Files changed (2) hide show
  1. package/README.md +124 -102
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,109 +1,121 @@
1
1
  # Clinch Core (`clinch-core`)
2
2
 
3
- > **Autonomous Agent Negotiation Mediation Protocol — Edge Client & Seller SDK**
3
+ > **Agent Negotiation Protocol (ANP) — Edge Client & Seller SDK**
4
4
 
5
- Clinch is a modular, edge-first protocol designed to mediate autonomous negotiations between a buyer AI agent and a seller AI agent. It allows agents to negotiate price and terms to a mutual, mathematically converged agreement without a human in the loop, and without the seller ever seeing the buyer's full profile.
6
-
7
- Once an agreement is reached, Clinch issues a **cryptographically co-signed deal artifact** held by both parties. This SDK provides the complete network client, state-isolated session management, cryptographic signing engines, an optional out-of-the-box local LLM bargaining sandbox, and the server-side Seller SDK.
5
+ `clinch-core` is the programmatic engine of the Clinch Protocol. It provides the state machine, cryptographic signing interfaces, local LLM sandbox adapters, and server-side utilities required to implement both buyer and seller agents conforming to the **Agent Negotiation Protocol (ANP)**.
8
6
 
9
7
  ---
10
8
 
11
- ## 🎯 Project Aim & Philosophy
9
+ ## 1. Protocol Architecture & Mechanics
12
10
 
13
- In the modern web, purchasing, SaaS licensing, transport, and commodity procurement involve endless manual comparisons, form-filling, and back-and-forth communication. Clinch replaces this overhead by allowing buyers to delegate constraints to a local agent that negotiates autonomously with the seller's hosted agent.
11
+ The Agent Negotiation Protocol (ANP) governs how two autonomous software agents establish identity, declare capabilities, and reach a cryptographically verifiable agreement on price and terms.
14
12
 
15
- * **Buyer Anonymity First**: The seller receives a simplified constraint vector (e.g., budget bracket, target category) rather than the buyer’s identity, private data, or raw history. All counter-offers are routed through the Registry proxy, guaranteeing 100% IP anonymity for the buyer.
16
- * **Edge-First Execution**: The buyer agent runs locally on-device. This SDK supports dynamically importing and running optimized 1.5B 4-bit quantized models in under **1.3 GB of RAM**, making it compatible with consumer hardware.
17
- * **Enterprise Concurrency**: Complete session isolation allows scaling horizontally. You can run hundreds of concurrent negotiations on a single server, serialize state, and resume negotiations across pod restarts or delayed webhooks.
18
- * **Cryptographic Accountability**: Identity is proven via Ed25519 keys and Proof-of-Work (PoW). The final co-signed deal artifact is self-verifying against the Registry's daily rotating key chain. Zero-trust machine-to-machine updates are enforced without centralized JWT expirations.
13
+ ### 1.1 Address Formatting & Routing
14
+ All destination routing in Clinch relies on strict, structured addressing:
19
15
 
20
- ---
16
+ $$\text{PROTOCOL\_MODE} \mathbin{.} \text{domain} \mathbin{.} \text{TLD}$$
21
17
 
22
- ## 📦 Installation
18
+ *Example:* `ANP/C.amazon.anp`
23
19
 
24
- To use `clinch-core` as a raw network client (Bring Your Own LLM or Seller Node):
25
- ```bash
26
- npm install clinch-core
27
- ```
20
+ The SDK parses the address to extract the negotiated **Protocol Mode** and target namespace domain before dispatching the initialization request.
28
21
 
29
- If you wish to use the **out-of-the-box local Sandbox engine** (Buyer Edge Mode), install the required peer dependency:
30
- ```bash
31
- npm install node-llama-cpp
32
- ```
33
- *(Note: `node-llama-cpp` is dynamically imported. Web/React Native builds will not fail if this is missing, provided `.sandbox()` is not called).*
22
+ ### 1.2 Protocol Modes
23
+ Sellers declare which execution profiles they support. The SDK maps these mode flags to session parameters during handshake:
24
+
25
+ * **`ANP/A`**: Standard native execution. Both buyer and seller agents run the local Clinch edge model. Best suited for high-volume, low-friction commodity exchanges.
26
+ * **`ANP/B`**: Mixed execution. One side uses the native edge model, while the other runs a custom model or external API adapter.
27
+ * **`ANP/C`**: Custom integration. Both agents run custom decision engines (e.g., GPT-4o, Claude 3.5, or proprietary heuristics).
34
28
 
35
29
  ---
36
30
 
37
- ## 🚦 Core State Machine & Event Architecture
31
+ ## 2. State Machine & Event Architecture
38
32
 
39
- `clinch-core` is driven by a strict network and negotiation state machine. You can subscribe to state transitions and real-time transaction logging to build clean, reactive user interfaces.
33
+ The SDK maintains an isolated, turn-based state machine for each active session.
40
34
 
41
35
  ### Core Statuses (`CoreStatus`)
42
- * `OFFLINE`: Client is disconnected.
43
- * `CONNECTING`: Resolving registry DNS and performing Proof-of-Work auth.
44
- * `IDLE`: Connected and authenticated. Waiting for handshakes or callbacks.
45
- * `RECONNECTING`: Socket connection lost; executing exponential backoff.
46
- * `NEGOTIATING`: Active turn-based negotiation sequence in progress.
47
- * `CONVERGED`: Mathematical agreement reached successfully.
48
- * `STALEMATE`: Negotiation terminated; max turns reached without convergence.
49
- * `ERROR`: Internal network, cryptographic, or compilation failure.
50
-
51
- ### Event Emitters
36
+ * `OFFLINE`: Client is completely disconnected.
37
+ * `CONNECTING`: Authenticating identity and performing local Proof-of-Work (PoW) verification.
38
+ * `IDLE`: Connected and authenticated. Ready to initialize new sessions.
39
+ * `NEGOTIATING`: Active, turn-based bargaining sequence in progress.
40
+ * `CONVERGED`: Mathematical convergence reached; agreement co-signed.
41
+ * `STALEMATE`: Handshake or negotiation sequence aborted or timed out.
42
+ * `ERROR`: Internal network, compilation, or cryptographic validation failure.
43
+
44
+ ### Developer Event Subscriptions
52
45
  ```typescript
46
+ // Track the operational status of the client
53
47
  core.on('status_changed', (status: CoreStatus) => {
54
- console.log(`State transitioned to: ${status}`);
48
+ console.log(`[Status] Client changed to: ${status}`);
55
49
  });
56
50
 
51
+ // Fired when a new negotiation handshake is completed
57
52
  core.on('session_started', ({ sessionId, sellerId }) => {
58
- console.log(`Negotiation initiated with ${sellerId} (Session: ${sessionId})`);
53
+ console.log(`[Session Started] Active ID: ${sessionId} targeting ${sellerId}`);
59
54
  });
60
55
 
56
+ // Fired when a session reaches terminal state (deal converged or stalemate)
61
57
  core.on('session_closed', ({ sessionId, outcome, finalPrice }) => {
62
- console.log(`Session ${sessionId} closed. Outcome: ${outcome} at $${finalPrice}`);
58
+ console.log(`[Session Closed] ID: ${sessionId} | Outcome: ${outcome} | Price: $${finalPrice}`);
63
59
  });
64
60
 
61
+ // Fired when an out-of-band message is received via the WS callback channel
65
62
  core.on('callback_received', ({ sessionId, payload }) => {
66
- // Fired when the seller routes a callback counter-offer via the Registry WS
63
+ console.log(`[Callback] Re-engagement for session ${sessionId} received`);
67
64
  });
68
65
  ```
69
66
 
70
67
  ---
71
68
 
72
- ## Quickstart: Out-of-the-Box Sandbox (Buyer)
69
+ ## 3. Installation
73
70
 
74
- The Sandbox automatically downloads an optimized **Qwen 2.5 1.5B Q4_K_M** model (~1.1GB), loads it securely into local RAM, and automatically wires up the WebSocket listeners to negotiate autonomously on incoming network events.
71
+ Install the library using your package manager:
72
+ ```bash
73
+ npm install clinch-core
74
+ ```
75
+
76
+ To run the local autonomous **Sandbox engine**, install the required peer dependency:
77
+ ```bash
78
+ npm install node-llama-cpp
79
+ ```
80
+ *(Note: `node-llama-cpp` is dynamically imported at runtime. Web builds or headless environments will not fail if this dependency is omitted, provided `.sandbox()` is not invoked).*
81
+
82
+ ---
83
+
84
+ ## 4. Integration Guide: Buyer Agents
85
+
86
+ ### 4.1 Running the On-Device Sandbox
87
+ The local Sandbox runs an optimized **Qwen 2.5 1.5B Q4_K_M** model on local hardware resources. It automatically handles handshake math and turn-based counter-offers based on your strict constraints.
75
88
 
76
89
  ```javascript
77
90
  const { ClinchCore } = require('clinch-core');
78
91
 
79
- async function startLocalAgent() {
92
+ async function runAutonomousSession() {
80
93
  const core = new ClinchCore();
81
94
 
82
95
  core.on('log', (msg) => console.log(msg));
83
- core.on('session_closed', ({ finalPrice }) => console.log(`Deal secured at $${finalPrice}!`));
96
+ core.on('session_closed', ({ finalPrice }) => {
97
+ console.log(`✓ Negotiation completed at $${finalPrice}`);
98
+ });
84
99
 
85
- // 1. Initialize Sandbox: Handles network auth, downloads GGUF, & registers auto-listeners
100
+ // 1. Initialize local LLM, solve PoW, and connect WebSocket
86
101
  await core.sandbox({ downloadLLM: true });
87
102
 
88
- // 2. Initiate Negotiation: Session automatically transitions to 'NEGOTIATING'
103
+ // 2. Begin autonomous negotiation
89
104
  const sessionId = await core.negotiate('ANP/C.amazon.anp', {
90
105
  intent: 'purchase',
91
106
  category: 'electronics',
92
107
  item: 'Ninja Blender',
93
- max_budget: 85.00 // Strictly enforced constraint
108
+ max_budget: 85.00
94
109
  });
95
110
 
96
- console.log(`🤖 Auto-agent listening on Session ${sessionId}`);
111
+ console.log(`Session active: ${sessionId}`);
97
112
  }
98
113
 
99
- startLocalAgent();
114
+ runAutonomousSession();
100
115
  ```
101
116
 
102
- ---
103
-
104
- ## 🔌 Quickstart: Bring Your Own AI & Webhook Persistence
105
-
106
- If you are running in a cloud environment (e.g., handling webhooks) and want to leverage high-end hosted APIs (e.g. Claude 3.5 Sonnet or OpenAI GPT-4o), bypass the sandbox. The Core provides **State Serialization** to survive server restarts.
117
+ ### 4.2 Cloud Webhook & Horizontal Scale Pattern
118
+ For enterprise cloud environments where processes must remain stateless or scale horizontally across server pods, you must serialize and rehydrate active sessions dynamically. This ensures that when an asynchronous callback arrives, any pod can load the session state and use the matching ephemeral key to sign the next turn.
107
119
 
108
120
  ```javascript
109
121
  import { ClinchCore } from 'clinch-core';
@@ -112,53 +124,59 @@ import Anthropic from '@anthropic-ai/sdk';
112
124
  const anthropic = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY });
113
125
  const core = new ClinchCore();
114
126
 
115
- await core.initialize();
127
+ await core.initialize();
116
128
 
117
- // 1. Start session and save state to DB
129
+ // 1. Start session
118
130
  const sessionId = await core.negotiate('ANP/C.amazon.anp', {
119
131
  intent: 'purchase',
120
132
  item: 'Ninja Blender',
121
133
  max_budget: 85.00
122
134
  });
123
- const savedState = core.exportSessionState(sessionId);
124
- await db.save(sessionId, savedState);
125
135
 
126
- // --- LATER, ON A DIFFERENT SERVER OR WEBHOOK --- //
136
+ // 2. Serialize and persist the state to your DB (Redis, Postgres, etc.)
137
+ const exportedState = core.exportSessionState(sessionId);
138
+ await db.saveSession(sessionId, exportedState);
139
+
140
+ // --- LATER, ON A DIFFERENT POD OR ASYNCHRONOUS WEBHOOK TRIGGER --- //
127
141
 
128
142
  const webhookCore = new ClinchCore();
129
- webhookCore.importSessionState(savedState);
143
+ webhookCore.importSessionState(exportedState);
130
144
 
131
145
  webhookCore.on('callback_received', async (event) => {
132
- // 2. Let the Core build the perfect state-aware protocol prompt
146
+ // 3. Generate system prompt using rehydrated session data
133
147
  const systemPrompt = webhookCore.buildAgentPrompt(event.sessionId, event.payload.message);
134
148
 
135
- // 3. Feed it to Claude/OpenAI
149
+ // 4. Evaluate with hosted LLM
136
150
  const msg = await anthropic.messages.create({
137
151
  model: "claude-3-5-sonnet-20241022",
138
152
  maxTokens: 150,
139
153
  system: systemPrompt,
140
- messages: [{ role: "user", content: "Determine our next protocol move." }]
154
+ messages: [{ role: "user", content: "Calculate next move." }]
141
155
  });
142
156
 
143
- const aiDecision = JSON.parse(msg.content[0].text);
157
+ const decision = JSON.parse(msg.content[0].text);
144
158
 
145
- // 4. Act on the deterministic JSON response
146
- if (aiDecision.action === 'accept') {
147
- console.log("Deal reached!");
159
+ // 5. Submit cryptographic counter-offer
160
+ if (decision.action === 'accept') {
161
+ console.log("Agreement reached!");
148
162
  } else {
149
- await webhookCore.sendCounter(event.sessionId, aiDecision.price, aiDecision.message);
150
- await db.update(event.sessionId, webhookCore.exportSessionState(event.sessionId));
163
+ await webhookCore.sendCounter(event.sessionId, decision.price, decision.message);
164
+ // 6. Update DB with new turn state and counters
165
+ await db.updateSession(event.sessionId, webhookCore.exportSessionState(event.sessionId));
151
166
  }
152
167
  });
153
168
  ```
154
169
 
155
170
  ---
156
171
 
157
- ## 🏪 Quickstart: Building a Seller Node
172
+ ## 5. Integration Guide: Seller Nodes
158
173
 
159
- `clinch-core` exports the `ClinchSeller` class to make building a native seller server seamless.
174
+ Sellers use the `ClinchSeller` class to build compliant, automated endpoints.
160
175
 
161
- **Architecture Note:** Seller Nodes do not use JWTs. You generate a permanent Ed25519 Keypair in the Clinch Dashboard, claim your domain, and pass the private key to your Node. The node securely self-publishes its endpoint and capabilities on boot.
176
+ ### 5.1 Decoupled Routing Architecture
177
+ To prevent centralized token expiration failures, Clinch separates ownership from routing:
178
+ 1. **The Control Plane**: The merchant claims their domain name (e.g., `amazon.anp`) and binds their permanent public key to it once using the dashboard.
179
+ 2. **The Data Plane**: The actual seller server is initialized with the matching permanent private key. On boot, the machine signs its dynamic endpoint configuration locally and publishes it to the registry. No JWTs are used on-wire for machine routing.
162
180
 
163
181
  ```javascript
164
182
  import { ClinchSeller } from 'clinch-core';
@@ -167,10 +185,12 @@ import express from 'express';
167
185
  const app = express();
168
186
  app.use(express.json());
169
187
 
170
- // Initialize with your permanent Dashboard-generated Private Key
171
- const seller = new ClinchSeller({ privateKeyHex: process.env.SELLER_PRIVATE_KEY });
188
+ // 1. Initialize seller with the permanent cryptographic key
189
+ const seller = new ClinchSeller({
190
+ privateKeyHex: process.env.SELLER_PRIVATE_KEY
191
+ });
172
192
 
173
- // Publish your routing endpoint to the network on boot
193
+ // 2. Publish endpoint to the registry on boot (Self-Signing)
174
194
  await seller.registerEndpoint({
175
195
  agent_id: 'amazon.anp',
176
196
  endpoint: 'https://your-seller-api.com/anp/v1',
@@ -179,21 +199,21 @@ await seller.registerEndpoint({
179
199
  capabilities: ['price_flex']
180
200
  });
181
201
 
182
- // Create your counter-offer route
202
+ // 3. Implement the standard ANP counter-offer endpoint
183
203
  app.post('/anp/v1/counter', (req, res) => {
184
204
  const { session_id, turn, price, reason, buyer_sig } = req.body;
185
205
 
186
- // Verify the payload actually came from the buyer who holds the session key
206
+ // Cryptographically verify the buyer's ephemeral signature
187
207
  const isValid = seller.verifyBuyerSignature(
188
208
  { session_id, turn, price, reason },
189
209
  buyer_sig,
190
210
  req.headers['x-buyer-pubkey']
191
211
  );
192
212
 
193
- if (!isValid) return res.status(401).send("Invalid signature");
213
+ if (!isValid) return res.status(401).json({ error: "Invalid signature" });
194
214
 
195
- // Process logic and return standard counter JSON...
196
- res.json({ msg_type: 'counter', price: 95.00, reason: "Best I can do is $95." });
215
+ // Execute bargaining logic and respond
216
+ res.json({ msg_type: 'counter', price: 95.00, reason: "Best we can offer is $95." });
197
217
  });
198
218
 
199
219
  app.listen(8080);
@@ -201,53 +221,55 @@ app.listen(8080);
201
221
 
202
222
  ---
203
223
 
204
- ## 📖 API Reference
224
+ ## 6. API Reference
205
225
 
206
- ### Buyer Client (`ClinchCore`)
226
+ ### 6.1 `ClinchCore` (Buyer Client)
207
227
 
208
228
  #### `new ClinchCore(config)`
209
- * `config.registryUrl` *(string)*: Override Firebase dynamic routing.
210
- * `config.timeoutMs` *(number)*: Connection timeout limit (Default: `5000`ms).
229
+ * `config.registryUrl` *(string)*: Optional. Direct override pointing to a local development registry.
230
+ * `config.timeoutMs` *(number)*: Network connection timeout limit (Default: `5000`ms).
211
231
 
212
232
  #### `async initialize(cachedToken?)`
213
- Authenticates the node, completes Identity-Bound PoW, and connects the WebSocket.
233
+ Resolves network configurations, computes Proof-of-Work proof, and opens active WebSocket channels.
234
+ * `cachedToken` *(string)*: Optional. Pastes a previous registry authorization token to skip PoW calculations on startup.
214
235
 
215
236
  #### `async negotiate(address, constraints)`
216
- Launches a cryptographic session handshake. Returns `sessionId`.
217
- * `address` *(string)*: e.g. `ANP/C.cloudflare.anp`. (Must include mode prefix).
218
- * `constraints` *(ConstraintVector)*: Must include `max_budget` (number).
237
+ Initializes the cryptographic handshake with a seller. Returns `sessionId`.
238
+ * `address` *(string)*: Target address formatted strictly as `PROTOCOL_MODE.domain` (e.g., `ANP/C.amazon.anp`).
239
+ * `constraints` *(ConstraintVector)*: Schema requiring `max_budget` (number) and `item` (string).
219
240
 
220
241
  #### `exportSessionState(sessionId)` / `importSessionState(serializedData)`
221
- Serializes the active sessionincluding the ephemeral cryptographic keys, current turn, and LLM context parameters—to a JSON string. Used to scale instances horizontally or survive pod restarts.
242
+ Serializes or de-serializes all in-flight state for a given session, including ephemeral Ed25519 keys, state metrics, and local sandbox parameters, into an exchangeable JSON string.
222
243
 
223
244
  #### `buildAgentPrompt(sessionId, incomingMessage)`
224
- Returns a highly-optimized, state-aware string to pass to an external LLM as a System Prompt. Ensures the LLM outputs strict JSON matching the protocol rules.
245
+ Assembles a contextual, structure-compliant system prompt for external LLMs to ensure compliant JSON execution.
225
246
 
226
247
  #### `async sendCounter(sessionId, price, reason)`
227
- Signs and dispatches a counter-offer to the seller via the Registry proxy.
248
+ Signs and dispatches a standard counter-offer to the seller endpoint.
228
249
 
229
250
  #### `async exitSession(sessionId)`
230
- Closes the active connection and generates a single-use re-engagement Callback token.
251
+ Stops the live execution channel and requests a callback token.
231
252
 
232
- #### `async sandbox(config)`
233
- Initializes the edge-AI execution context, downloads the GGUF, and auto-listens.
253
+ ---
234
254
 
235
- ### Seller Client (`ClinchSeller`)
255
+ ### 6.2 `ClinchSeller` (Seller Client)
236
256
 
237
257
  #### `new ClinchSeller(config)`
238
- * `config.privateKeyHex` *(string)*: The Ed25519 private key generated from the Clinch Dashboard. Used to cryptographically authenticate endpoint updates.
258
+ * `config.privateKeyHex` *(string)*: The permanent Ed25519 private key generated via the registration interface.
259
+ * `config.registryUrl` *(string)*: Optional. Point to a dev registry for local testing.
239
260
 
240
261
  #### `async registerEndpoint(record)`
241
- Publishes the seller's DNS-style record to the Registry so buyers can discover and route to it. Signed locally via the Ed25519 identity key.
262
+ Locally signs and publishes dynamic endpoint mappings and categories to the discovery registry.
242
263
 
243
- #### `verifyBuyerSignature(payload, signatureHex, pubKeyHex)`
244
- Returns `boolean`. Cryptographically verifies that incoming counter-offers were signed by the exact ephemeral session key generated by the buyer during the handshake.
264
+ #### `verifyBuyerSignature(payload, signatureHex, buyerPubKeyHex)`
265
+ Verifies that the provided turn payload matches the cryptographic signature produced by the session's ephemeral public key.
245
266
 
246
267
  ---
247
268
 
248
- ## 🔏 Cryptographic Guarantees
249
- Clinch operates on a strictly zero-trust model.
250
- 1. **Identity-Bound PoW**: Buyer challenge hashes include the client's `pubKey`, making outsourcing/bot-farming mathematically impossible.
251
- 2. **Ed25519 Seller Authority**: Seller endpoints and capabilities are updated via Ed25519 signatures, completely decoupling the control plane (Dashboard) from the data plane (Server).
252
- 3. **Ephemeral Sessions**: `negotiate()` generates an ephemeral Session Key. This key signs every individual message. If a session key is compromised, your global identity remains secure, and historical session logs remain completely un-linkable.
253
- 4. **Anonymity Proxy**: Counter-offers are routed strictly through the Registry. The seller never logs the buyer's IP address.
269
+ ## 7. Cryptographic Properties
270
+
271
+ Clinch relies entirely on zero-trust cryptography to maintain buyer privacy and seller authenticity:
272
+
273
+ 1. **Proof-of-Work Binding**: The PoW challenge solution includes the client's public key hash, ensuring challenges cannot be pre-computed or farmed.
274
+ 2. **Ephemeral Session Keypairs**: Calling `negotiate()` generates a single-use keypair (`nacl.sign.keyPair()`). This ephemeral key signs every message sent within the session context. In the event of a key compromise, your permanent global identity remains secure, and historical session logs are completely unlinkable.
275
+ 3. **Decoupled Verification**: Agreement artifacts are sequentially co-signed by the buyer's session key, the seller's verified identity key, and countersigned by the active registry key. This provides independent verification offline using only the registry's public key chain.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clinch-core",
3
- "version": "0.5.0",
3
+ "version": "0.6.1",
4
4
 
5
5
  "description": "Clinch Protocol Edge Client",
6
6
  "main": "dist/index.js",