@erdoai/server 0.1.7 → 0.1.8

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 CHANGED
@@ -58,7 +58,7 @@ const serverClient = new ErdoClient({
58
58
  authToken: process.env.ERDO_AUTH_TOKEN,
59
59
  });
60
60
 
61
- const { token, expiresAt } = await serverClient.createToken({
61
+ const { token, tokenId, expiresAt } = await serverClient.createToken({
62
62
  botKeys: ['my-org.data-analyst'],
63
63
  externalUserId: 'user_123',
64
64
  expiresInSeconds: 3600,
@@ -151,8 +151,9 @@ class ErdoClient {
151
151
 
152
152
  ```typescript
153
153
  interface CreateTokenParams {
154
- botKeys?: string[]; // Bot keys the token can access
154
+ botKeys?: string[]; // Bot keys the token can access (e.g., "my-org.data-analyst")
155
155
  datasetIds?: string[]; // Dataset IDs the token can access
156
+ threadIds?: string[]; // Thread IDs the token can access
156
157
  externalUserId?: string; // External user ID for RBAC (enables thread access)
157
158
  expiresInSeconds?: number; // Token lifetime (default: 3600)
158
159
  }
package/dist/index.d.ts CHANGED
@@ -26,7 +26,7 @@ declare class ErdoClient {
26
26
  * ```typescript
27
27
  * // Server-side: Create a token for the frontend
28
28
  * const serverClient = new ErdoClient({ authToken: process.env.ERDO_AUTH_TOKEN });
29
- * const { token, expiresAt } = await serverClient.createToken({
29
+ * const { token, tokenId, expiresAt } = await serverClient.createToken({
30
30
  * botKeys: ['my-org.data-analyst'],
31
31
  * expiresInSeconds: 3600,
32
32
  * });
package/dist/index.js CHANGED
@@ -1,3 +1,3 @@
1
- var v="https://api.erdo.ai";function E(){let i=typeof process<"u"?process.env:{};return {endpoint:i.ERDO_ENDPOINT||v,authToken:i.ERDO_AUTH_TOKEN}}function k(i){let e=E(),t=i?.endpoint||e.endpoint||v,o=i?.authToken||e.authToken,n=i?.token;return {endpoint:t,authToken:o,token:n}}async function*f(i){if(!i.body)throw new Error("Response body is null");let e=i.body.getReader(),t=new TextDecoder,o="",n,s;try{for(;;){let{done:a,value:u}=await e.read();if(a){if(s!==void 0){let r=w(n,s);r&&(yield r);}break}o+=t.decode(u,{stream:!0});let h=o.split(`
2
- `);o=h.pop()||"";for(let r of h){let c=r.trim();if(!c){if(s!==void 0){let d=w(n,s);d&&(yield d),n=void 0,s=void 0;}continue}if(c.startsWith("event:"))n=c.slice(6).trim();else if(c.startsWith("data:")){let d=c.slice(5).trim();s===void 0?s=d:s+=`
3
- `+d;}}}}finally{e.releaseLock();}}function w(i,e){if(!e)return null;try{let t=JSON.parse(e);return i&&(t.type=i),t}catch{return {type:i,raw:e}}}async function p(i){let e=[];for await(let t of f(i))e.push(t);return e}var l=class{endpoint;authToken;token;constructor(e){let t=k(e);if(this.endpoint=t.endpoint,this.authToken=t.authToken,this.token=t.token,!this.authToken&&!this.token)throw new Error("Either authToken or token is required")}async createToken(e){if(!this.authToken)throw new Error("createToken requires authToken (API key) authentication");let t=`${this.endpoint}/tokens`,o={};e.botKeys&&(o.bot_keys=e.botKeys),e.datasetIds&&(o.dataset_ids=e.datasetIds),e.externalUserId&&(o.external_user_id=e.externalUserId),e.expiresInSeconds&&(o.expires_in_seconds=e.expiresInSeconds);let n=await fetch(t,{method:"POST",headers:{Authorization:`Bearer ${this.authToken}`,"Content-Type":"application/json"},body:JSON.stringify(o)});if(!n.ok){let a=await n.text();throw new Error(`Failed to create token: ${n.status}: ${a}`)}let s=await n.json();return {token:s.token,expiresAt:s.expires_at}}async createThread(e={}){if(!this.token)throw new Error("createThread requires token authentication");let t=`${this.endpoint}/threads`,o={};e.name&&(o.name=e.name),e.datasetIds&&(o.dataset_ids=e.datasetIds);let n=await fetch(t,{method:"POST",headers:{Authorization:`Bearer ${this.token}`,"Content-Type":"application/json"},body:JSON.stringify(o)});if(!n.ok){let a=await n.text();throw new Error(`Failed to create thread: ${n.status}: ${a}`)}let s=await n.json();return {id:s.id,name:s.name,createdAt:s.created_at,updatedAt:s.updated_at}}async listThreads(){if(!this.token)throw new Error("listThreads requires token authentication");let e=`${this.endpoint}/threads-user`,t=await fetch(e,{method:"GET",headers:{Authorization:`Bearer ${this.token}`}});if(!t.ok){let n=await t.text();throw new Error(`Failed to list threads: ${t.status}: ${n}`)}return {threads:(await t.json()).threads.map(n=>({id:n.id,name:n.name,createdAt:n.created_at,updatedAt:n.updated_at}))}}async getThread(e){if(!this.token)throw new Error("getThread requires token authentication");let t=`${this.endpoint}/threads/${e}`,o=await fetch(t,{method:"GET",headers:{Authorization:`Bearer ${this.token}`}});if(!o.ok){let s=await o.text();throw new Error(`Failed to get thread: ${o.status}: ${s}`)}let n=await o.json();return {id:n.id,name:n.name,createdAt:n.created_at,updatedAt:n.updated_at}}async*sendMessage(e,t){if(!this.token)throw new Error("sendMessage requires token authentication");let o=`${this.endpoint}/threads/${e}/message`,n={content:t.content};t.botKey&&(n.bot_key=t.botKey);let s=await fetch(o,{method:"POST",headers:{Authorization:`Bearer ${this.token}`,"Content-Type":"application/json",Accept:"text/event-stream"},body:JSON.stringify(n)});if(!s.ok){let a=await s.text();throw new Error(`Failed to send message: ${s.status}: ${a}`)}yield*f(s);}async sendMessageAndWait(e,t){if(!this.token)throw new Error("sendMessageAndWait requires token authentication");let o=`${this.endpoint}/threads/${e}/message`,n={content:t.content};t.botKey&&(n.bot_key=t.botKey);let s=await fetch(o,{method:"POST",headers:{Authorization:`Bearer ${this.token}`,"Content-Type":"application/json",Accept:"text/event-stream"},body:JSON.stringify(n)});if(!s.ok){let a=await s.text();throw new Error(`Failed to send message: ${s.status}: ${a}`)}return p(s)}async invoke(e,t={}){let o=await this.collectEvents(e,t);return this.extractResult(e,o)}async*invokeStream(e,t={}){let o=await this.makeRequest(e,t);yield*f(o);}async collectEvents(e,t){let o=await this.makeRequest(e,t);return p(o)}async makeRequest(e,t){let o=`${this.endpoint}/bots/${e}/invoke`,n={};t.messages&&(n.messages=t.messages),t.parameters&&(n.parameters=t.parameters),t.datasets&&(n.dataset_slugs=t.datasets),t.mode&&(n.mode=t.mode),t.manualMocks&&(n.manual_mocks=t.manualMocks);let s=this.token||this.authToken,a=await fetch(o,{method:"POST",headers:{Authorization:`Bearer ${s}`,"Content-Type":"application/json",Accept:"text/event-stream"},body:JSON.stringify(n)});if(!a.ok){let u=await a.text();throw new Error(`API request failed with status ${a.status}: ${u}`)}return a}extractResult(e,t){let o=[],n=[],s=new Set,a,u;for(let h of t){if(!h)continue;let r=h.payload,c=h.metadata;if(r&&typeof r=="object"&&"invocation_id"in r&&!u&&(u=r.invocation_id),r&&typeof r=="object"&&"action_type"in r&&"key"in r){let d=r.key;s.has(d)||(s.add(d),n.push({key:d,action:r.action_type,status:"completed"}));}if(r&&typeof r=="object"&&"output"in r&&c?.user_visibility==="visible"){let d=r.output;if(d&&typeof d=="object"&&"content"in d){let y=d.content;if(Array.isArray(y)){for(let m of y)if(m.content_type==="text"){let T=c?.role||"assistant";o.push({role:T,content:m.content||""});}}}}r&&typeof r=="object"&&"status"in r&&"output"in r&&(a={status:r.status,parameters:r.parameters,output:r.output,message:r.message,error:r.error});}return {success:true,botKey:e,invocationId:u,result:a,messages:o,events:t,steps:n}}},g=null;function S(){return g||(g=new l),g}async function x(i,e={}){return S().invoke(i,e)}async function*P(i,e={}){yield*S().invokeStream(i,e);}export{l as ErdoClient,p as collectSSEEvents,E as getConfigFromEnv,x as invoke,P as invokeStream,f as parseSSEStream,k as resolveConfig};
1
+ var m="https://api.erdo.ai";function w(){let i=typeof process<"u"?process.env:{};return {endpoint:i.ERDO_ENDPOINT||m,authToken:i.ERDO_AUTH_TOKEN}}function k(i){let e=w(),t=i?.endpoint||e.endpoint||m,s=i?.authToken||e.authToken,n=i?.token;return {endpoint:t,authToken:s,token:n}}async function*f(i){if(!i.body)throw new Error("Response body is null");let e=i.body.getReader(),t=new TextDecoder,s="",n,o;try{for(;;){let{done:a,value:c}=await e.read();if(a){if(o!==void 0){let r=E(n,o);r&&(yield r);}break}s+=t.decode(c,{stream:!0});let u=s.split(`
2
+ `);s=u.pop()||"";for(let r of u){let h=r.trim();if(!h){if(o!==void 0){let d=E(n,o);d&&(yield d),n=void 0,o=void 0;}continue}if(h.startsWith("event:"))n=h.slice(6).trim();else if(h.startsWith("data:")){let d=h.slice(5).trim();o===void 0?o=d:o+=`
3
+ `+d;}}}}finally{e.releaseLock();}}function E(i,e){if(!e)return null;try{let t=JSON.parse(e);return i&&(t.type=i),t}catch{return {type:i,raw:e}}}async function l(i){let e=[];for await(let t of f(i))e.push(t);return e}var p=class{endpoint;authToken;token;constructor(e){let t=k(e);if(this.endpoint=t.endpoint,this.authToken=t.authToken,this.token=t.token,!this.authToken&&!this.token)throw new Error("Either authToken or token is required")}async createToken(e){if(!this.authToken)throw new Error("createToken requires authToken (API key) authentication");let t;if(e.botKeys&&e.botKeys.length>0){let c=`${this.endpoint}/resolve-bot-keys`,u=await fetch(c,{method:"POST",headers:{Authorization:`Bearer ${this.authToken}`,"Content-Type":"application/json"},body:JSON.stringify({keys:e.botKeys})});if(!u.ok){let d=await u.text();throw new Error(`Failed to resolve bot keys: ${u.status}: ${d}`)}let r=await u.json();t=Object.values(r.bots);let h=e.botKeys.filter(d=>!r.bots[d]);if(h.length>0)throw new Error(`Bot keys not found or access denied: ${h.join(", ")}`)}let s=`${this.endpoint}/tokens`,n={};t&&(n.bot_ids=t),e.datasetIds&&(n.dataset_ids=e.datasetIds),e.threadIds&&(n.thread_ids=e.threadIds),e.externalUserId&&(n.external_user_id=e.externalUserId),e.expiresInSeconds&&(n.expires_in_seconds=e.expiresInSeconds);let o=await fetch(s,{method:"POST",headers:{Authorization:`Bearer ${this.authToken}`,"Content-Type":"application/json"},body:JSON.stringify(n)});if(!o.ok){let c=await o.text();throw new Error(`Failed to create token: ${o.status}: ${c}`)}let a=await o.json();return {tokenId:a.token_id,token:a.token,expiresAt:a.expires_at}}async createThread(e={}){if(!this.token)throw new Error("createThread requires token authentication");let t=`${this.endpoint}/threads`,s={};e.name&&(s.name=e.name),e.datasetIds&&(s.dataset_ids=e.datasetIds);let n=await fetch(t,{method:"POST",headers:{Authorization:`Bearer ${this.token}`,"Content-Type":"application/json"},body:JSON.stringify(s)});if(!n.ok){let a=await n.text();throw new Error(`Failed to create thread: ${n.status}: ${a}`)}let o=await n.json();return {id:o.id,name:o.name,createdAt:o.created_at,updatedAt:o.updated_at}}async listThreads(){if(!this.token)throw new Error("listThreads requires token authentication");let e=`${this.endpoint}/threads-user`,t=await fetch(e,{method:"GET",headers:{Authorization:`Bearer ${this.token}`}});if(!t.ok){let n=await t.text();throw new Error(`Failed to list threads: ${t.status}: ${n}`)}return {threads:(await t.json()).threads.map(n=>({id:n.id,name:n.name,createdAt:n.created_at,updatedAt:n.updated_at}))}}async getThread(e){if(!this.token)throw new Error("getThread requires token authentication");let t=`${this.endpoint}/threads/${e}`,s=await fetch(t,{method:"GET",headers:{Authorization:`Bearer ${this.token}`}});if(!s.ok){let o=await s.text();throw new Error(`Failed to get thread: ${s.status}: ${o}`)}let n=await s.json();return {id:n.id,name:n.name,createdAt:n.created_at,updatedAt:n.updated_at}}async*sendMessage(e,t){if(!this.token)throw new Error("sendMessage requires token authentication");let s=`${this.endpoint}/threads/${e}/message`,n={content:t.content};t.botKey&&(n.bot_key=t.botKey);let o=await fetch(s,{method:"POST",headers:{Authorization:`Bearer ${this.token}`,"Content-Type":"application/json",Accept:"text/event-stream"},body:JSON.stringify(n)});if(!o.ok){let a=await o.text();throw new Error(`Failed to send message: ${o.status}: ${a}`)}yield*f(o);}async sendMessageAndWait(e,t){if(!this.token)throw new Error("sendMessageAndWait requires token authentication");let s=`${this.endpoint}/threads/${e}/message`,n={content:t.content};t.botKey&&(n.bot_key=t.botKey);let o=await fetch(s,{method:"POST",headers:{Authorization:`Bearer ${this.token}`,"Content-Type":"application/json",Accept:"text/event-stream"},body:JSON.stringify(n)});if(!o.ok){let a=await o.text();throw new Error(`Failed to send message: ${o.status}: ${a}`)}return l(o)}async invoke(e,t={}){let s=await this.collectEvents(e,t);return this.extractResult(e,s)}async*invokeStream(e,t={}){let s=await this.makeRequest(e,t);yield*f(s);}async collectEvents(e,t){let s=await this.makeRequest(e,t);return l(s)}async makeRequest(e,t){let s=`${this.endpoint}/bots/${e}/invoke`,n={};t.messages&&(n.messages=t.messages),t.parameters&&(n.parameters=t.parameters),t.datasets&&(n.dataset_slugs=t.datasets),t.mode&&(n.mode=t.mode),t.manualMocks&&(n.manual_mocks=t.manualMocks);let o=this.token||this.authToken,a=await fetch(s,{method:"POST",headers:{Authorization:`Bearer ${o}`,"Content-Type":"application/json",Accept:"text/event-stream"},body:JSON.stringify(n)});if(!a.ok){let c=await a.text();throw new Error(`API request failed with status ${a.status}: ${c}`)}return a}extractResult(e,t){let s=[],n=[],o=new Set,a,c;for(let u of t){if(!u)continue;let r=u.payload,h=u.metadata;if(r&&typeof r=="object"&&"invocation_id"in r&&!c&&(c=r.invocation_id),r&&typeof r=="object"&&"action_type"in r&&"key"in r){let d=r.key;o.has(d)||(o.add(d),n.push({key:d,action:r.action_type,status:"completed"}));}if(r&&typeof r=="object"&&"output"in r&&h?.user_visibility==="visible"){let d=r.output;if(d&&typeof d=="object"&&"content"in d){let y=d.content;if(Array.isArray(y)){for(let v of y)if(v.content_type==="text"){let T=h?.role||"assistant";s.push({role:T,content:v.content||""});}}}}r&&typeof r=="object"&&"status"in r&&"output"in r&&(a={status:r.status,parameters:r.parameters,output:r.output,message:r.message,error:r.error});}return {success:true,botKey:e,invocationId:c,result:a,messages:s,events:t,steps:n}}},g=null;function S(){return g||(g=new p),g}async function x(i,e={}){return S().invoke(i,e)}async function*b(i,e={}){yield*S().invokeStream(i,e);}export{p as ErdoClient,l as collectSSEEvents,w as getConfigFromEnv,x as invoke,b as invokeStream,f as parseSSEStream,k as resolveConfig};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@erdoai/server",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "description": "Erdo server SDK for invoking agents",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -39,7 +39,7 @@
39
39
  "directory": "packages/server"
40
40
  },
41
41
  "dependencies": {
42
- "@erdoai/types": "^0.1.6"
42
+ "@erdoai/types": "^0.1.7"
43
43
  },
44
44
  "devDependencies": {
45
45
  "@types/node": "^24.10.1",