@cascade-fyi/sati-agent0-sdk 0.1.1 → 0.2.0

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 CHANGED
@@ -5,6 +5,49 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.2.0] - 2026-02-12
9
+
10
+ ### Breaking Changes
11
+
12
+ - **Write operations now return `SolanaTransactionHandle<T>`** instead of `Promise<{ signature }>` or `Promise<{ signature, feedback }>`. Use `.hash` for the transaction signature, `.waitMined()` or `.waitConfirmed()` for the result. Migration:
13
+ ```typescript
14
+ // Before:
15
+ const { signature, feedback } = await sdk.giveFeedback(agentId, 85);
16
+ // After:
17
+ const handle = await sdk.giveFeedback(agentId, 85);
18
+ const { result: feedback } = await handle.waitMined();
19
+ console.log(handle.hash); // signature
20
+ ```
21
+ - **`giveFeedback` 7th parameter (`satiOptions`) removed.** Pass `outcome` and `taskRef` via the `feedbackFile` parameter instead:
22
+ ```typescript
23
+ // Before:
24
+ await sdk.giveFeedback(agentId, 85, "tag1", "tag2", endpoint, feedbackFile, { outcome, taskRef });
25
+ // After:
26
+ await sdk.giveFeedback(agentId, 85, "tag1", "tag2", endpoint, { ...feedbackFile, outcome, taskRef });
27
+ ```
28
+ - **`prepareFeedback` 6th parameter (`satiOptions`) removed.** Pass `outcome` and `taskRef` via the `opts` parameter instead.
29
+ - **`SatiFeedbackOptions` type removed.** Fields moved into `feedbackFile`/`opts`.
30
+ - **`agent.registerIPFS()` / `agent.registerHTTP()`** now return `SolanaTransactionHandle<RegistrationFile>`. Access `agentId` via `agent.agentId` after registration.
31
+ - All `throw new Error(...)` replaced with typed error classes (see Added section).
32
+
33
+ ### Added
34
+
35
+ - `SolanaTransactionHandle<T>` - agent0-sdk `TransactionHandle` pattern for Solana (`.hash`, `.waitMined()`, `.waitConfirmed()`)
36
+ - Typed error classes: `SatiError`, `AgentNotFoundError`, `ReadOnlyError`, `SignerRequiredError`, `SchemaNotDeployedError`, `InvalidAgentIdError`, `UnsupportedOperationError`
37
+ - `FeedbackCache` - TTL cache for feedback queries, reducing redundant RPC calls
38
+ - `agent.updateIPFS()` - re-upload current registration file to IPFS and update on-chain URI
39
+ - `agent.updateHTTP(uri)` - update on-chain URI to a new HTTP endpoint
40
+ - `revokeFeedback(feedback)` overload - pass a `Feedback` object directly for stable addressing (index-based overload deprecated)
41
+ - `SatiSearchOptions.limit` and `SatiSearchOptions.offset` for agent pagination
42
+ - Server-side memcmp filtering for `searchFeedback` (schema + agentMint) via Photon RPC
43
+ - Client-side filtering for `counterparty` and `outcome` in attestation queries
44
+ - Lazy feedback stats in `searchAgents` - cheap filters applied first, feedback stats fetched only for surviving agents
45
+ - JSDoc documenting timestamp imprecision on `createdAt` fields
46
+
47
+ ### Fixed
48
+
49
+ - `searchAgents` no longer fetches all 1000 agents before filtering - supports pagination and applies cheap filters before expensive feedback stats
50
+
8
51
  ## [0.1.1] - 2026-02-11
9
52
 
10
53
  ### Fixed
@@ -41,5 +84,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
41
84
  - Transaction sender support for browser wallet integration
42
85
  - Re-exports of agent0-sdk types and SATI constants for consumer convenience
43
86
 
87
+ [0.2.0]: https://github.com/cascade-protocol/sati/compare/@cascade-fyi/sati-agent0-sdk@0.1.1...@cascade-fyi/sati-agent0-sdk@0.2.0
44
88
  [0.1.1]: https://github.com/cascade-protocol/sati/compare/@cascade-fyi/sati-agent0-sdk@0.1.0...@cascade-fyi/sati-agent0-sdk@0.1.1
45
89
  [0.1.0]: https://github.com/cascade-protocol/sati/releases/tag/@cascade-fyi/sati-agent0-sdk@0.1.0
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Agent0-compatible adapter for [SATI](https://github.com/cascade-protocol/sati) - Solana Agent Trust Infrastructure.
4
4
 
5
- Drop-in replacement for [agent0-sdk](https://github.com/agent0-ai/agent0-sdk) that routes all operations through SATI's Solana infrastructure instead of EVM chains. Same method signatures, same types - different backend.
5
+ API-compatible adapter for [agent0-sdk](https://github.com/agent0-ai/agent0-sdk) that routes all operations through SATI's Solana infrastructure instead of EVM chains. Same method names and types - write operations return `SolanaTransactionHandle<T>` (compatible with agent0-sdk's `TransactionHandle` via `.hash`, `.waitMined()`, `.waitConfirmed()`).
6
6
 
7
7
  ## Installation
8
8
 
@@ -31,14 +31,22 @@ const sdk = new SatiSDK({
31
31
  const agents = await sdk.searchAgents({ hasMCP: true });
32
32
 
33
33
  // Give feedback
34
- const { signature, feedback } = await sdk.giveFeedback(
35
- agents[0].agentId,
36
- 85,
37
- "quality",
38
- "speed",
39
- );
34
+ const handle = await sdk.giveFeedback(agents[0].agentId, 85, "quality", "speed");
35
+ const { result: feedback } = await handle.waitMined();
36
+ console.log(handle.hash); // transaction signature
40
37
  ```
41
38
 
39
+ ### Return type differences from agent0-sdk
40
+
41
+ | Method | agent0-sdk | sati-agent0-sdk |
42
+ |---|---|---|
43
+ | `giveFeedback` | `TransactionHandle<Feedback>` | `SolanaTransactionHandle<Feedback>` |
44
+ | `transferAgent` | `TransactionHandle<TransferResult>` | `SolanaTransactionHandle<TransferResult>` |
45
+ | `revokeFeedback` | `TransactionHandle<Feedback>` | `SolanaTransactionHandle<Feedback>` |
46
+ | `agent.registerIPFS()` | `TransactionHandle<RegistrationFile>` | `SolanaTransactionHandle<RegistrationFile>` |
47
+
48
+ `SolanaTransactionHandle<T>` provides the same `.hash`, `.waitMined()`, `.waitConfirmed()` API. Key difference: `.hash` is a base58 Solana signature (not EVM hex), and both `waitMined`/`waitConfirmed` resolve immediately since Solana's `sendAndConfirmTransaction` already waits for confirmation.
49
+
42
50
  ---
43
51
 
44
52
  ## SDK Modes
@@ -78,7 +86,23 @@ agent.setX402Support(true);
78
86
  agent.setTrust(true, false, false); // reputation only
79
87
 
80
88
  // Register on-chain via IPFS (requires pinataJwt in config)
81
- const { signature, agentId } = await agent.registerIPFS();
89
+ const handle = await agent.registerIPFS();
90
+ console.log(agent.agentId, handle.hash);
91
+ ```
92
+
93
+ ### Update an existing agent
94
+
95
+ ```typescript
96
+ const agent = await sdk.loadAgent(agentId);
97
+ agent.updateInfo("Updated Name", "Updated description");
98
+ await agent.setMCP("https://new-mcp.example.com");
99
+
100
+ // Re-upload to IPFS and update on-chain URI
101
+ const handle = await agent.updateIPFS();
102
+ console.log(handle.hash);
103
+
104
+ // Or update with a custom HTTP URI
105
+ await agent.updateHTTP("https://example.com/agent-metadata.json");
82
106
  ```
83
107
 
84
108
  ### Load an existing agent
@@ -102,12 +126,15 @@ const ranked = await sdk.searchAgents(
102
126
  { active: true },
103
127
  { includeFeedbackStats: true, sort: ["averageValue:desc"] },
104
128
  );
129
+
130
+ // With pagination
131
+ const page = await sdk.searchAgents({}, { limit: 25, offset: 50n });
105
132
  ```
106
133
 
107
134
  ### Transfer ownership
108
135
 
109
136
  ```typescript
110
- await sdk.transferAgent(agentId, "NewOwnerAddress");
137
+ const handle = await sdk.transferAgent(agentId, "NewOwnerAddress");
111
138
  // or via agent instance
112
139
  await agent.transfer("NewOwnerAddress");
113
140
  ```
@@ -119,7 +146,7 @@ await agent.transfer("NewOwnerAddress");
119
146
  ### Give feedback (server-side)
120
147
 
121
148
  ```typescript
122
- const { signature, feedback } = await sdk.giveFeedback(
149
+ const handle = await sdk.giveFeedback(
123
150
  agentId,
124
151
  85, // value (0-100)
125
152
  "quality", // tag1
@@ -127,26 +154,27 @@ const { signature, feedback } = await sdk.giveFeedback(
127
154
  "https://api.example.com", // endpoint
128
155
  { text: "Excellent work" }, // feedbackFile
129
156
  );
157
+ const { result: feedback } = await handle.waitMined();
130
158
  ```
131
159
 
132
- ### Governance attestations with SatiFeedbackOptions
160
+ ### Governance attestations with outcome/taskRef
133
161
 
134
- For governance and other use cases that need custom outcomes or deterministic task references:
162
+ For governance and other use cases that need custom outcomes or deterministic task references, pass them via the `feedbackFile` parameter:
135
163
 
136
164
  ```typescript
137
165
  import { Outcome } from "@cascade-fyi/sati-agent0-sdk";
138
166
 
139
167
  // Vote on a DAO proposal
140
- await sdk.giveFeedback(
168
+ const handle = await sdk.giveFeedback(
141
169
  agentId,
142
170
  85,
143
171
  "governance",
144
172
  "defi",
145
173
  undefined,
146
- { text: "Proposal increases emissions by 20%, net positive for growth" },
147
174
  {
148
- outcome: Outcome.Positive, // For (Negative=Against, Neutral=Abstain)
149
- taskRef: proposalHashBytes, // deterministic per proposal
175
+ text: "Proposal increases emissions by 20%, net positive for growth",
176
+ outcome: Outcome.Positive, // For (Negative=Against, Neutral=Abstain)
177
+ taskRef: proposalHashBytes, // deterministic per proposal
150
178
  },
151
179
  );
152
180
  ```
@@ -161,7 +189,7 @@ const prepared = await sdk.prepareFeedback(agentId, 85, "quality", "speed");
161
189
  const walletSig = await wallet.signMessage(prepared.messageBytes);
162
190
 
163
191
  // 3. Submit via server-side signer
164
- const { signature } = await sdk.submitPreparedFeedback(prepared, walletSig);
192
+ const handle = await sdk.submitPreparedFeedback(prepared, walletSig);
165
193
  ```
166
194
 
167
195
  ### Search feedback
@@ -176,9 +204,36 @@ const feedbacks = await sdk.searchFeedback(
176
204
  ### Revoke feedback
177
205
 
178
206
  ```typescript
179
- await sdk.revokeFeedback(agentId, feedbackIndex);
207
+ // Preferred: pass the Feedback object directly (stable addressing)
208
+ const [feedback] = await sdk.searchFeedback({ agentId, reviewers: [myAddress] });
209
+ const handle = await sdk.revokeFeedback(feedback);
210
+
211
+ // Legacy: by index (fragile - index can shift as feedbacks are added/removed)
212
+ const handle2 = await sdk.revokeFeedback(agentId, 0);
213
+ ```
214
+
215
+ ---
216
+
217
+ ## Error Handling
218
+
219
+ All SDK errors extend `SatiError` with a `code` string for programmatic matching:
220
+
221
+ ```typescript
222
+ import { SatiError, AgentNotFoundError, ReadOnlyError } from "@cascade-fyi/sati-agent0-sdk";
223
+
224
+ try {
225
+ await sdk.giveFeedback(agentId, 85);
226
+ } catch (err) {
227
+ if (err instanceof AgentNotFoundError) {
228
+ console.log("Agent not found:", err.code); // "AGENT_NOT_FOUND"
229
+ } else if (err instanceof ReadOnlyError) {
230
+ console.log("Need a signer:", err.code); // "READ_ONLY"
231
+ }
232
+ }
180
233
  ```
181
234
 
235
+ Error classes: `AgentNotFoundError`, `ReadOnlyError`, `SignerRequiredError`, `SchemaNotDeployedError`, `InvalidAgentIdError`, `UnsupportedOperationError`.
236
+
182
237
  ---
183
238
 
184
239
  ## Validations
@@ -190,6 +245,8 @@ for (const v of validations) {
190
245
  }
191
246
  ```
192
247
 
248
+ Note: `createdAt` is approximate (derived from Solana slot numbers). For exact timestamps, use `sdk.getCreationSignature()` + Solana's `getBlockTime()`.
249
+
193
250
  ---
194
251
 
195
252
  ## Agent IDs
@@ -226,23 +283,6 @@ sdk.sati; // underlying Sati client for advanced ops
226
283
 
227
284
  ---
228
285
 
229
- ## Adapters
230
-
231
- Convert between SATI and agent0 data formats:
232
-
233
- ```typescript
234
- import {
235
- toAgentSummary,
236
- toAgent0RegistrationFile,
237
- fromAgent0RegistrationFile,
238
- toAgent0Endpoints,
239
- fromAgent0Endpoints,
240
- toFeedback,
241
- } from "@cascade-fyi/sati-agent0-sdk";
242
- ```
243
-
244
- ---
245
-
246
286
  ## Re-exports
247
287
 
248
288
  For convenience, the package re-exports commonly used types and enums from both `agent0-sdk` and `@cascade-fyi/sati-sdk`, so consumers don't need to install them for basic usage:
@@ -252,7 +292,8 @@ For convenience, the package re-exports commonly used types and enums from both
252
292
  import type { AgentSummary, Feedback, RegistrationFile, AgentId } from "@cascade-fyi/sati-agent0-sdk";
253
293
  import { EndpointType, TrustModel, EndpointCrawler } from "@cascade-fyi/sati-agent0-sdk";
254
294
 
255
- // SATI types and constants
295
+ // SATI types, errors, and constants
296
+ import { SolanaTransactionHandle, SatiError, AgentNotFoundError } from "@cascade-fyi/sati-agent0-sdk";
256
297
  import { Outcome, ContentType, SATI_PROGRAM_ADDRESS } from "@cascade-fyi/sati-agent0-sdk";
257
298
  import { parseFeedbackContent, getImageUrl, handleTransactionError } from "@cascade-fyi/sati-agent0-sdk";
258
299
  ```