@circuitorg/agent-sdk 1.0.12 → 1.0.13
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 +11 -11
- package/index.js +1 -1
- package/package.json +2 -2
- package/utils/auth-loader.cjs +13 -3
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@ A TypeScript SDK for building automated agents to deploy on Circuit. Features a
|
|
|
8
8
|
|
|
9
9
|
## ✨ Features
|
|
10
10
|
|
|
11
|
-
- **🎯 Simple API**: Only 2 main methods - `
|
|
11
|
+
- **🎯 Simple API**: Only 2 main methods - `sendLog()` and `signAndSend()`
|
|
12
12
|
- **🔒 Type Safety**: Network parameter determines valid request shapes automatically
|
|
13
13
|
- **🚀 Cross-Chain**: Unified interface for EVM and Solana networks
|
|
14
14
|
|
|
@@ -36,10 +36,10 @@ const sdk = new AgentSdk({
|
|
|
36
36
|
|
|
37
37
|
## 🎯 Core SDK API (Only 2 Methods!)
|
|
38
38
|
|
|
39
|
-
### 1. Add
|
|
39
|
+
### 1. Add Logs to Timeline
|
|
40
40
|
|
|
41
41
|
```typescript
|
|
42
|
-
await sdk.
|
|
42
|
+
await sdk.sendLog({
|
|
43
43
|
type: "observe",
|
|
44
44
|
shortMessage: "Starting swap operation"
|
|
45
45
|
});
|
|
@@ -104,14 +104,14 @@ const executionFunction: ExecutionFunctionContract = async (request) => {
|
|
|
104
104
|
// Get user's wallet address (use vitalik.eth for demo if no address provided)
|
|
105
105
|
const userAddress = request.sessionWalletAddress
|
|
106
106
|
|
|
107
|
-
await sdk.
|
|
107
|
+
await sdk.sendLog({
|
|
108
108
|
type: "observe",
|
|
109
109
|
shortMessage: `🚀 Agent SDK v1.0 demo - Hello ${userAddress}`
|
|
110
110
|
});
|
|
111
111
|
|
|
112
112
|
return { success: true};
|
|
113
113
|
} catch (error) {
|
|
114
|
-
await sdk.
|
|
114
|
+
await sdk.sendLog({
|
|
115
115
|
type: "error",
|
|
116
116
|
shortMessage: `Agent execution error: ${error instanceof Error ? error.message : 'Unknown error'}`
|
|
117
117
|
});
|
|
@@ -126,7 +126,7 @@ const stopFunction: StopFunctionContract = async (request) => {
|
|
|
126
126
|
});
|
|
127
127
|
|
|
128
128
|
try {
|
|
129
|
-
await sdk.
|
|
129
|
+
await sdk.sendLog({
|
|
130
130
|
type: "observe",
|
|
131
131
|
shortMessage: "🛑 Agent stopping with new SDK v1.0"
|
|
132
132
|
});
|
|
@@ -287,7 +287,7 @@ const executionFunction: ExecutionFunctionContract = async (request) => {
|
|
|
287
287
|
});
|
|
288
288
|
|
|
289
289
|
try {
|
|
290
|
-
await sdk.
|
|
290
|
+
await sdk.sendLog({
|
|
291
291
|
type: "observe",
|
|
292
292
|
shortMessage:
|
|
293
293
|
"🚀 Starting Agent SDK v1.0 comprehensive demo -- live test",
|
|
@@ -305,7 +305,7 @@ const executionFunction: ExecutionFunctionContract = async (request) => {
|
|
|
305
305
|
pepeBalance.decimals
|
|
306
306
|
);
|
|
307
307
|
|
|
308
|
-
await sdk.
|
|
308
|
+
await sdk.sendLog({
|
|
309
309
|
type: "observe",
|
|
310
310
|
shortMessage: `PEPE Balance (Arbitrum): ${pepeBalanceFormatted} PEPE`,
|
|
311
311
|
});
|
|
@@ -334,7 +334,7 @@ const executionFunction: ExecutionFunctionContract = async (request) => {
|
|
|
334
334
|
});
|
|
335
335
|
|
|
336
336
|
|
|
337
|
-
await sdk.
|
|
337
|
+
await sdk.sendLog({
|
|
338
338
|
type: "observe",
|
|
339
339
|
shortMessage:
|
|
340
340
|
"✅ Agent SDK v1.0 comprehensive demo completed successfully!",
|
|
@@ -344,7 +344,7 @@ const executionFunction: ExecutionFunctionContract = async (request) => {
|
|
|
344
344
|
} catch (error) {
|
|
345
345
|
console.error("💥 Agent execution error:", error);
|
|
346
346
|
|
|
347
|
-
await sdk.
|
|
347
|
+
await sdk.sendLog({
|
|
348
348
|
type: "error",
|
|
349
349
|
shortMessage: `Agent execution error: ${
|
|
350
350
|
error instanceof Error ? error.message : "Unknown error"
|
|
@@ -375,7 +375,7 @@ const stopFunction: StopFunctionContract = async (request) => {
|
|
|
375
375
|
});
|
|
376
376
|
|
|
377
377
|
try {
|
|
378
|
-
await sdk.
|
|
378
|
+
await sdk.sendLog({
|
|
379
379
|
type: "observe",
|
|
380
380
|
shortMessage: "🛑 Agent stopping with new SDK v1.0",
|
|
381
381
|
});
|
package/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var __getOwnPropNames=Object.getOwnPropertyNames,__require=(t=>"undefined"!=typeof require?require:"undefined"!=typeof Proxy?new Proxy(t,{get:(t,e)=>("undefined"!=typeof require?require:t)[e]}):t)(function(t){if("undefined"!=typeof require)return require.apply(this,arguments);throw Error('Dynamic require of "'+t+'" is not supported')}),__commonJS=(t,e)=>function(){return e||(0,t[__getOwnPropNames(t)[0]])((e={exports:{}}).exports,e),e.exports},require_auth_loader=__commonJS({"src/utils/auth-loader.cjs"(exports,module){function loadAuthFromFileSystem(){try{if("undefined"==typeof process
|
|
1
|
+
var __getOwnPropNames=Object.getOwnPropertyNames,__require=(t=>"undefined"!=typeof require?require:"undefined"!=typeof Proxy?new Proxy(t,{get:(t,e)=>("undefined"!=typeof require?require:t)[e]}):t)(function(t){if("undefined"!=typeof require)return require.apply(this,arguments);throw Error('Dynamic require of "'+t+'" is not supported')}),__commonJS=(t,e)=>function(){return e||(0,t[__getOwnPropNames(t)[0]])((e={exports:{}}).exports,e),e.exports},require_auth_loader=__commonJS({"src/utils/auth-loader.cjs"(exports,module){function loadAuthFromFileSystem(){try{if("undefined"==typeof process)return;const fs=eval("require")("fs"),path=eval("require")("path"),os=eval("require")("os"),homeDir=os.homedir();let authPath=path.join(homeDir,".config","circuit","auth.json");if(!fs.existsSync(authPath)&&(authPath=path.join(homeDir,".circuit","auth.json"),!fs.existsSync(authPath)))return;const authContent=fs.readFileSync(authPath,"utf-8");return JSON.parse(authContent)}catch(t){return}}module.exports={loadAuthFromFileSystem:loadAuthFromFileSystem}}}),API_BASE_URL_LOCAL="https://agents.circuit.org",APIClient=class{config;baseUrl;isCloudflareWorker(){return"undefined"!=typeof globalThis&&void 0!==globalThis.Cloudflare}hasServiceBinding(){let t=!1;return this.isCloudflareWorker()&&(void 0!==globalThis.AGENTS_TO_API_PROXY||void 0!==globalThis.__AGENT_ENV__&&globalThis.__AGENT_ENV__?.AGENTS_TO_API_PROXY)&&(t=!0),this.config.verbose,t}constructor(t){this.config=t,this.baseUrl=t.baseUrl||API_BASE_URL_LOCAL}getAgentSlug(){return"undefined"!=typeof process&&process.env?.CIRCUIT_AGENT_SLUG?process.env.CIRCUIT_AGENT_SLUG:void 0!==globalThis.CIRCUIT_AGENT_SLUG?globalThis.CIRCUIT_AGENT_SLUG:void 0}getAuthHeaders(){const t={};t["X-Session-Id"]=this.config.sessionId.toString();const e=this.getAgentSlug();if(e&&(t["X-Agent-Slug"]=e),!this.hasServiceBinding())try{const e=this.loadAuthConfig();e?.sessionToken&&(t.Authorization=`Bearer ${e.sessionToken}`)}catch(t){}return t}loadAuthConfig(){try{const{loadAuthFromFileSystem:t}=require_auth_loader();return t()}catch(t){this.config.verbose}}logging(t,e){this.config.verbose}async makeRequest(t,e={}){const s={...{"Content-Type":"application/json",...this.getAuthHeaders()},...e.headers};let r;if(this.logging("=== REQUEST DETAILS ==="),this.logging("Endpoint:",t),this.logging("Method:",e.method||"GET"),this.logging("Headers:",s),this.logging("Body:",e.body),this.logging("Session ID:",this.config.sessionId),this.logging("Agent Slug:",this.getAgentSlug()||"not set"),this.logging("Using Service Binding:",this.hasServiceBinding()),this.logging("====================="),this.hasServiceBinding()){let n;if(void 0!==globalThis.AGENTS_TO_API_PROXY)n=globalThis.AGENTS_TO_API_PROXY;else{if(void 0===globalThis.__AGENT_ENV__||!globalThis.__AGENT_ENV__?.AGENTS_TO_API_PROXY)throw new Error("Service binding detected but not accessible");n=globalThis.__AGENT_ENV__.AGENTS_TO_API_PROXY}this.logging("Using service binding AGENTS_TO_API_PROXY"),this.logging("Service binding type:",typeof n);const o={...e,headers:s},i=`https://agents-to-api-proxy.circuit-0bc.workers.dev${t}`;r=await n.fetch(i,o)}else{this.logging("Using HTTP fallback to:",this.baseUrl);const n=`${this.baseUrl}${t}`,o={...e,headers:s};r=await fetch(n,o)}if(this.logging("=== RESPONSE DETAILS ==="),this.logging("Status:",r.status),this.logging("Status Text:",r.statusText),this.logging("Response Headers:",Object.fromEntries(r.headers.entries())),this.logging("======================"),!r.ok){const t=await r.json().catch(()=>({}));throw this.logging("=== ERROR RESPONSE ==="),this.logging("Error Data:",t),this.logging("===================="),new Error(t.message||`HTTP ${r.status}: ${r.statusText}`)}const n=await r.json();return this.logging("=== SUCCESS RESPONSE ==="),this.logging("Response Data:",n),this.logging("======================"),n}async get(t){return this.makeRequest(t,{method:"GET"})}async post(t,e){return this.makeRequest(t,{method:"POST",body:e?JSON.stringify(e):void 0})}};function isEthereumNetwork(t){return t.startsWith("ethereum:")}function isSolanaNetwork(t){return"solana"===t}function getChainIdFromNetwork(t){return Number(t.split(":")[1])}var AgentSdk=class{client;config;constructor(t){this.config=t,this.client=new APIClient(t)}logging(t,e){this.config.verbose}async sendLog(t){this.logging("=== ADD MESSAGE ==="),this.logging("Message:",t),this.logging("==================="),await this.t([t])}async signAndSend(t){if(this.logging("=== SIGN AND SEND ==="),this.logging("Request:",t),this.logging("Testing mode:",this.config.testing),this.logging("===================="),this.config.testing)return{internalTransactionId:123,txHash:isEthereumNetwork(t.network)?"0xTEST":"TEST_SOL_TX",transactionUrl:void 0};if(isEthereumNetwork(t.network)){const e=getChainIdFromNetwork(t.network);if("toAddress"in t.request)return this.handleEvmTransaction({chainId:e,toAddress:t.request.toAddress,data:t.request.data,valueWei:t.request.value,message:t.message})}if(isSolanaNetwork(t.network)&&"hexTransaction"in t.request)return this.handleSolanaTransaction({hexTransaction:t.request.hexTransaction,message:t.message});throw new Error(`Unsupported network: ${t.network}`)}async signMessage(t){if(this.logging("=== SIGN MESSAGE ==="),this.logging("Request:",t),this.logging("Testing mode:",this.config.testing),this.logging("===================="),this.config.testing)return{v:27,r:"0xTEST_R",s:"0xTEST_S",formattedSignature:"0xTEST_FORMATTED",type:"evm"};if(isEthereumNetwork(t.network))return this.handleEvmSignMessage(t);throw new Error(`Unsupported network: ${t.network}`)}async handleEvmTransaction(t){const e=await this.client.post("/v1/transactions/evm",t),s=await this.client.post(`/v1/transactions/evm/${e.internalTransactionId}/broadcast`);return{internalTransactionId:e.internalTransactionId,txHash:s.txHash,transactionUrl:s.transactionUrl}}async handleSolanaTransaction(t){const e=await this.client.post("/v1/transactions/solana",t),s=await this.client.post(`/v1/transactions/solana/${e.internalTransactionId}/broadcast`);return{internalTransactionId:e.internalTransactionId,txHash:s.txHash,transactionUrl:s.transactionUrl}}async handleEvmSignMessage(t){return await this.client.post("/v1/messages/evm",{messageType:t.request.messageType,data:t.request.data,chainId:t.request.chainId})}async t(t){return this.config.testing?{status:200,message:"Logs added successfully (TESTING)"}:this.client.post("/v1/logs",t)}};import{zValidator}from"@hono/zod-validator";import{Hono}from"hono";import{cors}from"hono/cors";import{z}from"zod";var AgentRequestSchema=z.object({sessionId:z.number(),sessionWalletAddress:z.string(),otherParameters:z.object().optional()}),AgentResponseSchema=z.object({success:z.boolean(),error:z.string().optional(),message:z.string().optional()}),HealthResponseSchema=z.object({status:z.string()}),Agent=class{app;executionFunction;stopFunction;healthCheckFunction;constructor(t){this.app=new Hono,this.executionFunction=t.executionFunction,this.stopFunction=t.stopFunction,this.healthCheckFunction=t.healthCheckFunction||(async()=>({status:"healthy"})),this.app.use("*",cors()),this.setupRoutes()}setupRoutes(){this.app.post("/execute",zValidator("json",AgentRequestSchema),async t=>{try{const e=t.req.valid("json"),s=await this.executionFunction(e);return t.json(s)}catch(e){return t.json({success:!1,error:e instanceof Error?e.message:"Unknown error",message:"Execution failed"},500)}}),this.stopFunction&&(this.app.post("/stop",zValidator("json",AgentRequestSchema),async t=>{try{const e=t.req.valid("json"),s=await(this.stopFunction?.(e));return t.json(s)}catch(e){return t.json({success:!1,error:e instanceof Error?e.message:"Unknown error",message:"Stop operation failed"},500)}}),this.app.delete("/",zValidator("json",AgentRequestSchema),async t=>{try{const e=t.req.valid("json"),s=await(this.stopFunction?.(e));return t.json(s)}catch(e){return t.json({success:!1,error:e instanceof Error?e.message:"Unknown error",message:"Stop operation failed"},500)}})),this.app.get("/health",async t=>{try{const e=await(this.healthCheckFunction?.());return t.json(e)}catch(e){return t.json({status:"unhealthy",error:e instanceof Error?e.message:"Unknown error",timestamp:(new Date).toISOString()},500)}})}getPortFromPackageJson(){try{const t=__require("fs"),e=__require("path").join(process.cwd(),"package.json");if(t.existsSync(e)){const s=JSON.parse(t.readFileSync(e,"utf-8"));if(s.circuit?.port)return Number.parseInt(s.circuit.port,10)}}catch(t){}return null}run(port){const isCloudflareWorker="undefined"!=typeof globalThis&&void 0!==globalThis.Cloudflare;if(isCloudflareWorker)return this.getWorkerExport();const bunEnv=globalThis.Bun?.env,envPort=process.env.AGENT_PORT||bunEnv?.AGENT_PORT,packageJsonPort=this.getPortFromPackageJson();let finalPort=port;!finalPort&&envPort&&(finalPort=Number.parseInt(envPort,10)),!finalPort&&packageJsonPort&&(finalPort=packageJsonPort),finalPort||(finalPort=3e3);try{const req=eval("require"),{serve:serve}=req("@hono/node-server");serve({fetch:this.app.fetch,port:finalPort})}catch(t){process.exit(1)}}getWorkerExport(){return{fetch:async(t,e,s)=>(e&&"undefined"!=typeof globalThis&&(globalThis.__AGENT_ENV__=e),this.app.fetch(t,e,s))}}};function createAgentHandler(t,e,s){return new Agent({executionFunction:t,stopFunction:e,healthCheckFunction:s})}export{APIClient,Agent,AgentSdk,getChainIdFromNetwork,isEthereumNetwork,isSolanaNetwork};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@circuitorg/agent-sdk",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.13",
|
|
4
4
|
"description": "typescript sdk for the Agent Toolset Service",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
|
@@ -65,6 +65,6 @@
|
|
|
65
65
|
},
|
|
66
66
|
"repository": {
|
|
67
67
|
"type": "git",
|
|
68
|
-
"url": "git+https://github.com/circuitorg/
|
|
68
|
+
"url": "git+https://github.com/circuitorg/agent-sdk-typescript.git"
|
|
69
69
|
}
|
|
70
70
|
}
|
package/utils/auth-loader.cjs
CHANGED
|
@@ -4,18 +4,28 @@
|
|
|
4
4
|
function loadAuthFromFileSystem() {
|
|
5
5
|
try {
|
|
6
6
|
// Check if we're in a Node.js environment
|
|
7
|
-
if (typeof process === 'undefined'
|
|
7
|
+
if (typeof process === 'undefined') {
|
|
8
8
|
return undefined;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
// Use dynamic require to avoid bundler processing
|
|
12
12
|
const fs = eval("require")('fs');
|
|
13
13
|
const path = eval("require")('path');
|
|
14
|
+
const os = eval("require")('os');
|
|
14
15
|
|
|
15
|
-
|
|
16
|
+
// Use os.homedir() for cross-platform compatibility (works on Windows, Mac, Linux)
|
|
17
|
+
const homeDir = os.homedir();
|
|
18
|
+
|
|
19
|
+
// Try main config directory first (matches CLI behavior)
|
|
20
|
+
let authPath = path.join(homeDir, '.config', 'circuit', 'auth.json');
|
|
16
21
|
|
|
17
22
|
if (!fs.existsSync(authPath)) {
|
|
18
|
-
|
|
23
|
+
// Try fallback directory (matches CLI fallback behavior)
|
|
24
|
+
authPath = path.join(homeDir, '.circuit', 'auth.json');
|
|
25
|
+
|
|
26
|
+
if (!fs.existsSync(authPath)) {
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
19
29
|
}
|
|
20
30
|
|
|
21
31
|
const authContent = fs.readFileSync(authPath, 'utf-8');
|