@jazzmine-ui/sdk 0.1.3 → 0.1.4

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.
@@ -1,5 +1,5 @@
1
1
  import { JazzmineEndpoints } from '../discovery';
2
- import { ChatRequestPayload, ChatResponse, ConversationCreateRequest, ConversationCreateResponse, ConversationDeleteResponse, HealthResponse, InfoResponse, JazzmineClientOptions, RequestOptions, StreamHandlers } from '../types';
2
+ import { ChatRequestPayload, ChatResponse, ConversationCreateRequest, ConversationCreateResponse, ConversationDeleteResponse, ConversationListParams, ConversationPage, ConversationSearchParams, ConversationUpdateRequest, ConversationUpdateResponse, HealthResponse, InfoResponse, JazzmineClientOptions, RequestOptions, StreamHandlers } from '../types';
3
3
  export declare class JazzmineClient {
4
4
  private readonly baseUrl;
5
5
  private readonly apiKey?;
@@ -16,6 +16,9 @@ export declare class JazzmineClient {
16
16
  getInfo(requestOptions?: RequestOptions): Promise<InfoResponse>;
17
17
  createConversation(payload?: ConversationCreateRequest, requestOptions?: RequestOptions): Promise<ConversationCreateResponse>;
18
18
  deleteConversation(conversationId: string, requestOptions?: RequestOptions): Promise<ConversationDeleteResponse>;
19
+ listConversations(params: ConversationListParams, requestOptions?: RequestOptions): Promise<ConversationPage>;
20
+ searchConversations(params: ConversationSearchParams, requestOptions?: RequestOptions): Promise<ConversationPage>;
21
+ updateConversation(conversationId: string, payload: ConversationUpdateRequest, requestOptions?: RequestOptions): Promise<ConversationUpdateResponse>;
19
22
  chat(payload: ChatRequestPayload, requestOptions?: RequestOptions): Promise<ChatResponse>;
20
23
  chatStream(payload: ChatRequestPayload, handlers?: StreamHandlers, requestOptions?: RequestOptions): Promise<ChatResponse>;
21
24
  sendMessage(message: string, options?: {
@@ -1 +1 @@
1
- {"version":3,"file":"JazzmineClient.d.ts","sourceRoot":"","sources":["../../src/client/JazzmineClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,iBAAiB,EACvB,MAAM,cAAc,CAAC;AAYtB,OAAO,KAAK,EACV,kBAAkB,EAClB,YAAY,EACZ,yBAAyB,EACzB,0BAA0B,EAC1B,0BAA0B,EAC1B,cAAc,EACd,YAAY,EACZ,qBAAqB,EACrB,cAAc,EAEd,cAAc,EACf,MAAM,UAAU,CAAC;AAYlB,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAU;IAChD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAe;IAEvC,OAAO,CAAC,SAAS,CAAoB;IACrC,OAAO,CAAC,iBAAiB,CAAS;gBAEtB,YAAY,EAAE,MAAM,EAAE,OAAO,GAAE,qBAA0B;IA6B/D,SAAS,CAAC,cAAc,GAAE,cAAmB,GAAG,OAAO,CAAC,cAAc,CAAC;IAYvE,OAAO,CAAC,cAAc,GAAE,cAAmB,GAAG,OAAO,CAAC,YAAY,CAAC;IAYnE,kBAAkB,CACtB,OAAO,GAAE,yBAA8B,EACvC,cAAc,GAAE,cAAmB,GAClC,OAAO,CAAC,0BAA0B,CAAC;IAiBhC,kBAAkB,CACtB,cAAc,EAAE,MAAM,EACtB,cAAc,GAAE,cAAmB,GAClC,OAAO,CAAC,0BAA0B,CAAC;IAiBhC,IAAI,CACR,OAAO,EAAE,kBAAkB,EAC3B,cAAc,GAAE,cAAmB,GAClC,OAAO,CAAC,YAAY,CAAC;IAqBlB,UAAU,CACd,OAAO,EAAE,kBAAkB,EAC3B,QAAQ,GAAE,cAAmB,EAC7B,cAAc,GAAE,cAAmB,GAClC,OAAO,CAAC,YAAY,CAAC;IA0DlB,WAAW,CACf,OAAO,EAAE,MAAM,EACf,OAAO,GAAE;QACP,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;QAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACnC,sBAAsB,CAAC,EAAE,OAAO,CAAC;QACjC,iBAAiB,CAAC,EAAE,MAAM,CAAC;QAC3B,cAAc,CAAC,EAAE,cAAc,CAAC;KAC5B,GACL,OAAO,CAAC;QAAE,QAAQ,EAAE,YAAY,CAAC;QAAC,cAAc,EAAE,MAAM,CAAA;KAAE,CAAC;IA0BxD,sBAAsB,CAAC,cAAc,GAAE,cAAmB,GAAG,OAAO,CAAC,iBAAiB,CAAC;YAmB/E,eAAe;IAS7B,OAAO,CAAC,WAAW;IAYnB,OAAO,CAAC,kBAAkB;IAe1B,OAAO,CAAC,aAAa;IAYrB,OAAO,CAAC,YAAY;CAMrB;AAED,eAAe,cAAc,CAAC"}
1
+ {"version":3,"file":"JazzmineClient.d.ts","sourceRoot":"","sources":["../../src/client/JazzmineClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,iBAAiB,EACvB,MAAM,cAAc,CAAC;AAYtB,OAAO,KAAK,EACV,kBAAkB,EAClB,YAAY,EACZ,yBAAyB,EACzB,0BAA0B,EAC1B,0BAA0B,EAC1B,sBAAsB,EAEtB,gBAAgB,EAChB,wBAAwB,EACxB,yBAAyB,EACzB,0BAA0B,EAC1B,cAAc,EACd,YAAY,EACZ,qBAAqB,EACrB,cAAc,EAEd,cAAc,EACf,MAAM,UAAU,CAAC;AAYlB,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAU;IAChD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAe;IAEvC,OAAO,CAAC,SAAS,CAAoB;IACrC,OAAO,CAAC,iBAAiB,CAAS;gBAEtB,YAAY,EAAE,MAAM,EAAE,OAAO,GAAE,qBAA0B;IA6B/D,SAAS,CAAC,cAAc,GAAE,cAAmB,GAAG,OAAO,CAAC,cAAc,CAAC;IAYvE,OAAO,CAAC,cAAc,GAAE,cAAmB,GAAG,OAAO,CAAC,YAAY,CAAC;IAYnE,kBAAkB,CACtB,OAAO,GAAE,yBAA8B,EACvC,cAAc,GAAE,cAAmB,GAClC,OAAO,CAAC,0BAA0B,CAAC;IAiBhC,kBAAkB,CACtB,cAAc,EAAE,MAAM,EACtB,cAAc,GAAE,cAAmB,GAClC,OAAO,CAAC,0BAA0B,CAAC;IAiBhC,iBAAiB,CACrB,MAAM,EAAE,sBAAsB,EAC9B,cAAc,GAAE,cAAmB,GAClC,OAAO,CAAC,gBAAgB,CAAC;IAmCtB,mBAAmB,CACvB,MAAM,EAAE,wBAAwB,EAChC,cAAc,GAAE,cAAmB,GAClC,OAAO,CAAC,gBAAgB,CAAC;IA4CtB,kBAAkB,CACtB,cAAc,EAAE,MAAM,EACtB,OAAO,EAAE,yBAAyB,EAClC,cAAc,GAAE,cAAmB,GAClC,OAAO,CAAC,0BAA0B,CAAC;IAwBhC,IAAI,CACR,OAAO,EAAE,kBAAkB,EAC3B,cAAc,GAAE,cAAmB,GAClC,OAAO,CAAC,YAAY,CAAC;IAqBlB,UAAU,CACd,OAAO,EAAE,kBAAkB,EAC3B,QAAQ,GAAE,cAAmB,EAC7B,cAAc,GAAE,cAAmB,GAClC,OAAO,CAAC,YAAY,CAAC;IA0DlB,WAAW,CACf,OAAO,EAAE,MAAM,EACf,OAAO,GAAE;QACP,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;QAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACnC,sBAAsB,CAAC,EAAE,OAAO,CAAC;QACjC,iBAAiB,CAAC,EAAE,MAAM,CAAC;QAC3B,cAAc,CAAC,EAAE,cAAc,CAAC;KAC5B,GACL,OAAO,CAAC;QAAE,QAAQ,EAAE,YAAY,CAAC;QAAC,cAAc,EAAE,MAAM,CAAA;KAAE,CAAC;IA0BxD,sBAAsB,CAAC,cAAc,GAAE,cAAmB,GAAG,OAAO,CAAC,iBAAiB,CAAC;YAmB/E,eAAe;IAS7B,OAAO,CAAC,WAAW;IAYnB,OAAO,CAAC,kBAAkB;IAe1B,OAAO,CAAC,aAAa;IAYrB,OAAO,CAAC,YAAY;CAMrB;AAED,eAAe,cAAc,CAAC"}
package/dist/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const x={chat:"/chat",stream:"/chat/stream",conversations:"/conversations",health:"/health",info:"/info"};async function I(r){if(r.endpointsResolved||!r.autoDiscoverEndpoints)return r.endpointsResolved;try{return await r.resolveServerEndpoints(r.requestOptions),!0}catch{return!0}}function A(r,t){const e={},n=r==null?void 0:r.endpoints;if(!n||typeof n!="object")return e;const s=m(n.chat,"POST",t),i=m(n.stream,"POST",t),a=m(n.conversations_create,"POST",t),h=m(n.health,"GET",t),d=m(n.info,"GET",t);return s&&(e.chat=s),i?e.stream=i:s&&(e.stream=`${s.replace(/\/+$/,"")}/stream`),a&&(e.conversations=a),h&&(e.health=h),d&&(e.info=d),e}function m(r,t,e){if(typeof r!="string")return null;const n=r.match(/^([A-Z]+)\s+(.+)$/i);if(!n)return null;const s=n[1].toUpperCase(),i=n[2].trim();if(s!==t.toUpperCase())return null;try{const a=new URL(i,e);return`${a.pathname}${a.search}`}catch{return null}}class o extends Error{constructor(t,e){super(t),this.name="JazzmineClientError",this.status=e==null?void 0:e.status,this.code=e==null?void 0:e.code,this.details=e==null?void 0:e.details}}function b(r,t){if(!r&&!t)return;if(!r)return t;if(!t)return r;const e=AbortSignal.any;if(typeof e=="function")return e([r,t]);const n=new AbortController,s=()=>{n.abort()};return r.aborted||t.aborted?(n.abort(),n.signal):(r.addEventListener("abort",s,{once:!0}),t.addEventListener("abort",s,{once:!0}),n.signal)}function M(r){return r instanceof DOMException&&(r.name==="AbortError"||r.name==="TimeoutError")}function U(r){const t=r.trim().replace(/\/+$/,"");let e;try{e=new URL(t)}catch{throw new o("Invalid baseEndpoint. Provide a full URL like https://api.example.com or http://127.0.0.1:8010.")}if(!e.protocol.startsWith("http"))throw new o("baseEndpoint must use http or https.");return`${e.protocol}//${e.host}${e.pathname.replace(/\/+$/,"")}`}function k(r,t){const e=t.startsWith("/")?t:`/${t}`;return`${r}${e}`}function E(r){const t=r==null?void 0:r.message;if(typeof t!="string"||!t.trim())throw new o("chat payload requires a non-empty message string.");if(r.explicit_context&&!Array.isArray(r.explicit_context))throw new o("explicit_context must be an array of strings.");if(Array.isArray(r.explicit_context)&&r.explicit_context.some(n=>typeof n!="string"))throw new o("explicit_context must contain only strings.");if(r.metadata!==void 0&&(r.metadata===null||typeof r.metadata!="object"))throw new o("metadata must be an object when provided.")}function J(r,t,e){if(r===void 0)return t;if(!Number.isFinite(r)||r<=0)throw new o(`${e} must be a positive number.`);return Math.round(r)}function g(r,t,e,n,s){if(r===void 0)return t;if(!Number.isInteger(r)||r<n||r>s)throw new o(`${e} must be an integer between ${n} and ${s}.`);return r}async function N(r,t){const e=r*(t+1);e<=0||await new Promise(n=>setTimeout(n,e))}async function P(r){let t;for(let e=0;e<=r.retries;e+=1)try{return await r.runAttempt(e)}catch(n){if(t=n,r.allowRetry&&e<r.retries&&r.shouldRetry(n)){await N(r.retryBackoffMs,e);continue}throw n}throw t}class w extends Error{constructor(t){const e=`Request timed out after ${t} ms.`;super(e),this.name="RetryableTimeoutError",this.finalError=new o(e)}}class p extends Error{constructor(t){super(t),this.name="RetryableNetworkError",this.finalError=new o(t)}}async function z(r,t){try{return await P({retries:t.retries,allowRetry:t.allowRetry,retryBackoffMs:r.retryBackoffMs,runAttempt:async()=>{const e=new AbortController,n=setTimeout(()=>{e.abort()},t.timeoutMs),s=b(t.signal,e.signal);try{const i=await r.fetchFn(_(r.baseUrl,t.path),{method:t.method,headers:T(r.apiKey,{accept:"application/json",contentType:t.body!==void 0?"application/json":void 0}),body:t.body!==void 0?JSON.stringify(t.body):void 0,signal:s});if(!i.ok)throw await R(i,t.path);const a=await i.text();if(!a.trim())return{};try{return JSON.parse(a)}catch{throw new o(`Expected JSON response from ${t.path}, but received invalid JSON.`)}}catch(i){throw M(i)?new w(t.timeoutMs):i instanceof o?i:i instanceof TypeError?new p(y(i,"Network request failed.")):new o(y(i,"Network request failed."))}finally{clearTimeout(n)}},shouldRetry:e=>{if(e instanceof w||e instanceof p)return!0;if(e instanceof o){const n=e.status??0;return n===429||n>=500}return!1}})}catch(e){throw e instanceof w||e instanceof p?e.finalError:e instanceof o?e:new o(y(e,"Network request failed."))}}async function R(r,t){const e=await r.text();let n;if(e.trim())try{n=JSON.parse(e)}catch{n=e}const s=D(n),i=`HTTP ${r.status} on ${t}${s?`: ${s}`:""}`;return new o(i,{status:r.status,details:n})}function T(r,t){const e={};return t.accept&&(e.Accept=t.accept),t.contentType&&(e["Content-Type"]=t.contentType),r&&(e.Authorization=`Bearer ${r}`),e}function _(r,t){return k(r,t)}function D(r){if(!r)return"";if(typeof r=="string")return r.slice(0,300);if(typeof r=="object"){const t=r,e=t.detail,n=t.error;if(typeof e=="string")return e.slice(0,300);if(typeof n=="string")return n.slice(0,300)}return""}function y(r,t){return r instanceof Error&&r.message?r.message:t}function j(r){const t=r.split(/\r?\n/).map(i=>i.trimEnd()).filter(i=>i.length>0&&!i.startsWith(":"));if(t.length===0)return null;let e="message";const n=[];for(const i of t){if(i.startsWith("event:")){e=i.slice(6).trim()||"message";continue}i.startsWith("data:")&&n.push(i.slice(5).trim())}const s=n.join(`
2
- `);if(!s)return{event:e,data:null};try{return{event:e,data:JSON.parse(s)}}catch{return{event:e,data:s}}}async function F(r){var a,h,d,c;const t=r.handlers??{},e=r.body.getReader(),n=new TextDecoder("utf-8");let s="",i=null;for(;;){const{done:l,value:C}=await e.read();if(l)break;s+=n.decode(C,{stream:!0});const v=s.split(/\n\n/);s=v.pop()??"";for(const $ of v){const u=j($);if(u){if((a=t.onRawEvent)==null||a.call(t,u.event,u.data),u.event==="intermediate"){(h=t.onIntermediate)==null||h.call(t,u.data);continue}if(u.event==="done"){i=r.expectChatResponse(u.data),(d=t.onDone)==null||d.call(t,i);continue}if(u.event==="error"){const f=r.toStreamError(u.data);throw(c=t.onErrorEvent)==null||c.call(t,f),new o(f.detail||f.error||"Stream error event received.",{code:f.error,details:f})}}}}if(!i)throw new o("Stream ended without a final done event containing ChatResponse.");return i}const B=2e4,L=2,W=350;class S{constructor(t,e={}){if(this.endpointsResolved=!1,!t||!t.trim())throw new o("baseEndpoint is required.");if(typeof fetch!="function"&&!e.fetchImpl)throw new o("fetch is not available in this runtime. Provide options.fetchImpl.");this.baseUrl=U(t),this.apiKey=e.apiKey,this.timeoutMs=J(e.timeoutMs,B,"timeoutMs"),this.retries=g(e.retries,L,"retries",0,10),this.retryBackoffMs=g(e.retryBackoffMs,W,"retryBackoffMs",0,6e4),this.autoDiscoverEndpoints=e.autoDiscoverEndpoints!==!1,this.defaultUserId=(e.defaultUserId??"user").trim()||"user",this.fetchFn=e.fetchImpl??fetch.bind(globalThis),this.endpoints={...x}}async getHealth(t={}){return await this.ensureEndpoints(t),this.requestJson({method:"GET",path:this.endpoints.health,timeoutMs:t.timeoutMs??this.timeoutMs,retries:t.retries??this.retries,signal:t.signal,allowRetry:!0})}async getInfo(t={}){return await this.ensureEndpoints(t),this.requestJson({method:"GET",path:this.endpoints.info,timeoutMs:t.timeoutMs??this.timeoutMs,retries:t.retries??this.retries,signal:t.signal,allowRetry:!0})}async createConversation(t={},e={}){return await this.ensureEndpoints(e),this.requestJson({method:"POST",path:this.endpoints.conversations,body:{conversation_id:t.conversation_id??"",user_id:t.user_id??this.defaultUserId,title:t.title??"New conversation"},timeoutMs:e.timeoutMs??this.timeoutMs,retries:e.retries??0,signal:e.signal,allowRetry:!1})}async deleteConversation(t,e={}){const n=t==null?void 0:t.trim();if(!n)throw new o("conversationId is required.");return await this.ensureEndpoints(e),this.requestJson({method:"DELETE",path:`${this.endpoints.conversations}/${encodeURIComponent(n)}`,timeoutMs:e.timeoutMs??this.timeoutMs,retries:e.retries??this.retries,signal:e.signal,allowRetry:!0})}async chat(t,e={}){return E(t),await this.ensureEndpoints(e),this.requestJson({method:"POST",path:this.endpoints.chat,body:{message:t.message,conversation_id:t.conversation_id??"",user_id:t.user_id??this.defaultUserId,explicit_context:t.explicit_context,metadata:t.metadata??{}},timeoutMs:e.timeoutMs??this.timeoutMs,retries:e.retries??0,signal:e.signal,allowRetry:!1})}async chatStream(t,e={},n={}){E(t),await this.ensureEndpoints(n);const s=n.timeoutMs??this.timeoutMs,i=n.signal,a=new AbortController,h=setTimeout(()=>{a.abort()},s),d=b(i,a.signal);try{const c=await this.fetchFn(_(this.baseUrl,this.endpoints.stream),{method:"POST",headers:T(this.apiKey,{accept:"text/event-stream",contentType:"application/json"}),body:JSON.stringify({message:t.message,conversation_id:t.conversation_id??"",user_id:t.user_id??this.defaultUserId,explicit_context:t.explicit_context,metadata:t.metadata??{}}),signal:d});if(!c.ok)throw await R(c,this.endpoints.stream);if(!c.body)throw new o("Streaming response body is missing.");return await F({body:c.body,handlers:e,expectChatResponse:l=>this.expectChatResponse(l),toStreamError:l=>this.toStreamError(l)})}catch(c){throw M(c)?new o(`Streaming request timed out after ${s} ms.`):c instanceof o?c:new o(this.errorMessage(c,"Streaming request failed."))}finally{clearTimeout(h)}}async sendMessage(t,e={}){var a;const n={message:t,conversation_id:e.conversationId,user_id:e.userId,explicit_context:e.explicitContext,metadata:e.metadata};let s=(a=e.conversationId)==null?void 0:a.trim();!s&&e.autoCreateConversation&&(s=(await this.createConversation({user_id:e.userId??this.defaultUserId,title:e.conversationTitle??"New conversation"},e.requestOptions)).conversation_id,n.conversation_id=s);const i=await this.chat(n,e.requestOptions);return{response:i,conversationId:i.conversation_id||s||""}}async resolveServerEndpoints(t={}){const e=await this.requestJson({method:"GET",path:this.endpoints.info,timeoutMs:t.timeoutMs??this.timeoutMs,retries:t.retries??this.retries,signal:t.signal,allowRetry:!0}),n=A(e,this.baseUrl);return this.endpoints={...this.endpoints,...n},this.endpointsResolved=!0,{...this.endpoints}}async ensureEndpoints(t={}){this.endpointsResolved=await I({endpointsResolved:this.endpointsResolved,autoDiscoverEndpoints:this.autoDiscoverEndpoints,requestOptions:t,resolveServerEndpoints:e=>this.resolveServerEndpoints(e)})}requestJson(t){return z({baseUrl:this.baseUrl,apiKey:this.apiKey,fetchFn:this.fetchFn,retryBackoffMs:this.retryBackoffMs},t)}expectChatResponse(t){if(!t||typeof t!="object")throw new o("Invalid stream done payload: expected ChatResponse object.");const e=t;if(typeof e.response!="string"||typeof e.conversation_id!="string")throw new o("Invalid ChatResponse payload: missing required fields response/conversation_id.");return e}toStreamError(t){if(!t||typeof t!="object")return{error:"stream_error",detail:"Unknown stream error payload."};const e=t;return{error:typeof e.error=="string"?e.error:"stream_error",detail:typeof e.detail=="string"?e.detail:void 0}}errorMessage(t,e){return t instanceof Error&&t.message?t.message:e}}exports.JazzmineClient=S;exports.JazzmineClientError=o;exports.default=S;
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const I={chat:"/chat",stream:"/chat/stream",conversations:"/conversations",health:"/health",info:"/info"};async function x(r){if(r.endpointsResolved||!r.autoDiscoverEndpoints)return r.endpointsResolved;try{return await r.resolveServerEndpoints(r.requestOptions),!0}catch{return!0}}function U(r,t){const e={},n=r==null?void 0:r.endpoints;if(!n||typeof n!="object")return e;const s=m(n.chat,"POST",t),i=m(n.stream,"POST",t),a=m(n.conversations_create,"POST",t),u=m(n.health,"GET",t),h=m(n.info,"GET",t);return s&&(e.chat=s),i?e.stream=i:s&&(e.stream=`${s.replace(/\/+$/,"")}/stream`),a&&(e.conversations=a),u&&(e.health=u),h&&(e.info=h),e}function m(r,t,e){if(typeof r!="string")return null;const n=r.match(/^([A-Z]+)\s+(.+)$/i);if(!n)return null;const s=n[1].toUpperCase(),i=n[2].trim();if(s!==t.toUpperCase())return null;try{const a=new URL(i,e);return`${a.pathname}${a.search}`}catch{return null}}class o extends Error{constructor(t,e){super(t),this.name="JazzmineClientError",this.status=e==null?void 0:e.status,this.code=e==null?void 0:e.code,this.details=e==null?void 0:e.details}}function M(r,t){if(!r&&!t)return;if(!r)return t;if(!t)return r;const e=AbortSignal.any;if(typeof e=="function")return e([r,t]);const n=new AbortController,s=()=>{n.abort()};return r.aborted||t.aborted?(n.abort(),n.signal):(r.addEventListener("abort",s,{once:!0}),t.addEventListener("abort",s,{once:!0}),n.signal)}function R(r){return r instanceof DOMException&&(r.name==="AbortError"||r.name==="TimeoutError")}function A(r){const t=r.trim().replace(/\/+$/,"");let e;try{e=new URL(t)}catch{throw new o("Invalid baseEndpoint. Provide a full URL like https://api.example.com or http://127.0.0.1:8010.")}if(!e.protocol.startsWith("http"))throw new o("baseEndpoint must use http or https.");return`${e.protocol}//${e.host}${e.pathname.replace(/\/+$/,"")}`}function J(r,t){const e=t.startsWith("/")?t:`/${t}`;return`${r}${e}`}function E(r){const t=r==null?void 0:r.message;if(typeof t!="string"||!t.trim())throw new o("chat payload requires a non-empty message string.");if(r.explicit_context&&!Array.isArray(r.explicit_context))throw new o("explicit_context must be an array of strings.");if(Array.isArray(r.explicit_context)&&r.explicit_context.some(n=>typeof n!="string"))throw new o("explicit_context must contain only strings.");if(r.metadata!==void 0&&(r.metadata===null||typeof r.metadata!="object"))throw new o("metadata must be an object when provided.")}function k(r,t,e){if(r===void 0)return t;if(!Number.isFinite(r)||r<=0)throw new o(`${e} must be a positive number.`);return Math.round(r)}function b(r,t,e,n,s){if(r===void 0)return t;if(!Number.isInteger(r)||r<n||r>s)throw new o(`${e} must be an integer between ${n} and ${s}.`);return r}async function P(r,t){const e=r*(t+1);e<=0||await new Promise(n=>setTimeout(n,e))}async function N(r){let t;for(let e=0;e<=r.retries;e+=1)try{return await r.runAttempt(e)}catch(n){if(t=n,r.allowRetry&&e<r.retries&&r.shouldRetry(n)){await P(r.retryBackoffMs,e);continue}throw n}throw t}class p extends Error{constructor(t){const e=`Request timed out after ${t} ms.`;super(e),this.name="RetryableTimeoutError",this.finalError=new o(e)}}class y extends Error{constructor(t){super(t),this.name="RetryableNetworkError",this.finalError=new o(t)}}async function z(r,t){try{return await N({retries:t.retries,allowRetry:t.allowRetry,retryBackoffMs:r.retryBackoffMs,runAttempt:async()=>{const e=new AbortController,n=setTimeout(()=>{e.abort()},t.timeoutMs),s=M(t.signal,e.signal);try{const i=await r.fetchFn(_(r.baseUrl,t.path),{method:t.method,headers:T(r.apiKey,{accept:"application/json",contentType:t.body!==void 0?"application/json":void 0}),body:t.body!==void 0?JSON.stringify(t.body):void 0,signal:s});if(!i.ok)throw await S(i,t.path);const a=await i.text();if(!a.trim())return{};try{return JSON.parse(a)}catch{throw new o(`Expected JSON response from ${t.path}, but received invalid JSON.`)}}catch(i){throw R(i)?new p(t.timeoutMs):i instanceof o?i:i instanceof TypeError?new y(v(i,"Network request failed.")):new o(v(i,"Network request failed."))}finally{clearTimeout(n)}},shouldRetry:e=>{if(e instanceof p||e instanceof y)return!0;if(e instanceof o){const n=e.status??0;return n===429||n>=500}return!1}})}catch(e){throw e instanceof p||e instanceof y?e.finalError:e instanceof o?e:new o(v(e,"Network request failed."))}}async function S(r,t){const e=await r.text();let n;if(e.trim())try{n=JSON.parse(e)}catch{n=e}const s=D(n),i=`HTTP ${r.status} on ${t}${s?`: ${s}`:""}`;return new o(i,{status:r.status,details:n})}function T(r,t){const e={};return t.accept&&(e.Accept=t.accept),t.contentType&&(e["Content-Type"]=t.contentType),r&&(e.Authorization=`Bearer ${r}`),e}function _(r,t){return J(r,t)}function D(r){if(!r)return"";if(typeof r=="string")return r.slice(0,300);if(typeof r=="object"){const t=r,e=t.detail,n=t.error;if(typeof e=="string")return e.slice(0,300);if(typeof n=="string")return n.slice(0,300)}return""}function v(r,t){return r instanceof Error&&r.message?r.message:t}function j(r){const t=r.split(/\r?\n/).map(i=>i.trimEnd()).filter(i=>i.length>0&&!i.startsWith(":"));if(t.length===0)return null;let e="message";const n=[];for(const i of t){if(i.startsWith("event:")){e=i.slice(6).trim()||"message";continue}i.startsWith("data:")&&n.push(i.slice(5).trim())}const s=n.join(`
2
+ `);if(!s)return{event:e,data:null};try{return{event:e,data:JSON.parse(s)}}catch{return{event:e,data:s}}}async function F(r){var a,u,h,c;const t=r.handlers??{},e=r.body.getReader(),n=new TextDecoder("utf-8");let s="",i=null;for(;;){const{done:d,value:w}=await e.read();if(d)break;s+=n.decode(w,{stream:!0});const g=s.split(/\n\n/);s=g.pop()??"";for(const $ of g){const l=j($);if(l){if((a=t.onRawEvent)==null||a.call(t,l.event,l.data),l.event==="intermediate"){(u=t.onIntermediate)==null||u.call(t,l.data);continue}if(l.event==="done"){i=r.expectChatResponse(l.data),(h=t.onDone)==null||h.call(t,i);continue}if(l.event==="error"){const f=r.toStreamError(l.data);throw(c=t.onErrorEvent)==null||c.call(t,f),new o(f.detail||f.error||"Stream error event received.",{code:f.error,details:f})}}}}if(!i)throw new o("Stream ended without a final done event containing ChatResponse.");return i}const L=2e4,B=2,q=350;class C{constructor(t,e={}){if(this.endpointsResolved=!1,!t||!t.trim())throw new o("baseEndpoint is required.");if(typeof fetch!="function"&&!e.fetchImpl)throw new o("fetch is not available in this runtime. Provide options.fetchImpl.");this.baseUrl=A(t),this.apiKey=e.apiKey,this.timeoutMs=k(e.timeoutMs,L,"timeoutMs"),this.retries=b(e.retries,B,"retries",0,10),this.retryBackoffMs=b(e.retryBackoffMs,q,"retryBackoffMs",0,6e4),this.autoDiscoverEndpoints=e.autoDiscoverEndpoints!==!1,this.defaultUserId=(e.defaultUserId??"user").trim()||"user",this.fetchFn=e.fetchImpl??fetch.bind(globalThis),this.endpoints={...I}}async getHealth(t={}){return await this.ensureEndpoints(t),this.requestJson({method:"GET",path:this.endpoints.health,timeoutMs:t.timeoutMs??this.timeoutMs,retries:t.retries??this.retries,signal:t.signal,allowRetry:!0})}async getInfo(t={}){return await this.ensureEndpoints(t),this.requestJson({method:"GET",path:this.endpoints.info,timeoutMs:t.timeoutMs??this.timeoutMs,retries:t.retries??this.retries,signal:t.signal,allowRetry:!0})}async createConversation(t={},e={}){return await this.ensureEndpoints(e),this.requestJson({method:"POST",path:this.endpoints.conversations,body:{conversation_id:t.conversation_id??"",user_id:t.user_id??this.defaultUserId,title:t.title??"New conversation"},timeoutMs:e.timeoutMs??this.timeoutMs,retries:e.retries??0,signal:e.signal,allowRetry:!1})}async deleteConversation(t,e={}){const n=t==null?void 0:t.trim();if(!n)throw new o("conversationId is required.");return await this.ensureEndpoints(e),this.requestJson({method:"DELETE",path:`${this.endpoints.conversations}/${encodeURIComponent(n)}`,timeoutMs:e.timeoutMs??this.timeoutMs,retries:e.retries??this.retries,signal:e.signal,allowRetry:!0})}async listConversations(t,e={}){var h;const n=(h=t.userId)==null?void 0:h.trim();if(!n)throw new o("userId is required.");const s=t.limit??100,i=t.offset??0;await this.ensureEndpoints(e);const a=new URLSearchParams({user_id:n,limit:String(s),offset:String(i)}).toString(),u=await this.requestJson({method:"GET",path:`${this.endpoints.conversations}?${a}`,timeoutMs:e.timeoutMs??this.timeoutMs,retries:e.retries??this.retries,signal:e.signal,allowRetry:!0});return{conversations:u.conversations,total:u.total,limit:u.limit,offset:u.offset,hasMore:u.total>i+u.conversations.length}}async searchConversations(t,e={}){var d,w;const n=(d=t.userId)==null?void 0:d.trim(),s=(w=t.query)==null?void 0:w.trim();if(!n)throw new o("userId is required.");if(!s)throw new o("query is required.");const i=t.limit??100,a=t.offset??0;await this.ensureEndpoints(e);const u=new URLSearchParams({user_id:n,query:s,limit:String(i),offset:String(a)}).toString(),h=`${this.endpoints.conversations}/search?${u}`,c=await this.requestJson({method:"GET",path:h,timeoutMs:e.timeoutMs??this.timeoutMs,retries:e.retries??this.retries,signal:e.signal,allowRetry:!0});return{conversations:c.conversations,total:c.total,limit:c.limit,offset:c.offset,hasMore:c.total>a+c.conversations.length,query:c.query}}async updateConversation(t,e,n={}){var a;const s=t==null?void 0:t.trim();if(!s)throw new o("conversationId is required.");const i=(a=e.title)==null?void 0:a.trim();if(!i)throw new o("title is required.");return await this.ensureEndpoints(n),this.requestJson({method:"PATCH",path:`${this.endpoints.conversations}/${encodeURIComponent(s)}`,body:{title:i},timeoutMs:n.timeoutMs??this.timeoutMs,retries:n.retries??0,signal:n.signal,allowRetry:!1})}async chat(t,e={}){return E(t),await this.ensureEndpoints(e),this.requestJson({method:"POST",path:this.endpoints.chat,body:{message:t.message,conversation_id:t.conversation_id??"",user_id:t.user_id??this.defaultUserId,explicit_context:t.explicit_context,metadata:t.metadata??{}},timeoutMs:e.timeoutMs??this.timeoutMs,retries:e.retries??0,signal:e.signal,allowRetry:!1})}async chatStream(t,e={},n={}){E(t),await this.ensureEndpoints(n);const s=n.timeoutMs??this.timeoutMs,i=n.signal,a=new AbortController,u=setTimeout(()=>{a.abort()},s),h=M(i,a.signal);try{const c=await this.fetchFn(_(this.baseUrl,this.endpoints.stream),{method:"POST",headers:T(this.apiKey,{accept:"text/event-stream",contentType:"application/json"}),body:JSON.stringify({message:t.message,conversation_id:t.conversation_id??"",user_id:t.user_id??this.defaultUserId,explicit_context:t.explicit_context,metadata:t.metadata??{}}),signal:h});if(!c.ok)throw await S(c,this.endpoints.stream);if(!c.body)throw new o("Streaming response body is missing.");return await F({body:c.body,handlers:e,expectChatResponse:d=>this.expectChatResponse(d),toStreamError:d=>this.toStreamError(d)})}catch(c){throw R(c)?new o(`Streaming request timed out after ${s} ms.`):c instanceof o?c:new o(this.errorMessage(c,"Streaming request failed."))}finally{clearTimeout(u)}}async sendMessage(t,e={}){var a;const n={message:t,conversation_id:e.conversationId,user_id:e.userId,explicit_context:e.explicitContext,metadata:e.metadata};let s=(a=e.conversationId)==null?void 0:a.trim();!s&&e.autoCreateConversation&&(s=(await this.createConversation({user_id:e.userId??this.defaultUserId,title:e.conversationTitle??"New conversation"},e.requestOptions)).conversation_id,n.conversation_id=s);const i=await this.chat(n,e.requestOptions);return{response:i,conversationId:i.conversation_id||s||""}}async resolveServerEndpoints(t={}){const e=await this.requestJson({method:"GET",path:this.endpoints.info,timeoutMs:t.timeoutMs??this.timeoutMs,retries:t.retries??this.retries,signal:t.signal,allowRetry:!0}),n=U(e,this.baseUrl);return this.endpoints={...this.endpoints,...n},this.endpointsResolved=!0,{...this.endpoints}}async ensureEndpoints(t={}){this.endpointsResolved=await x({endpointsResolved:this.endpointsResolved,autoDiscoverEndpoints:this.autoDiscoverEndpoints,requestOptions:t,resolveServerEndpoints:e=>this.resolveServerEndpoints(e)})}requestJson(t){return z({baseUrl:this.baseUrl,apiKey:this.apiKey,fetchFn:this.fetchFn,retryBackoffMs:this.retryBackoffMs},t)}expectChatResponse(t){if(!t||typeof t!="object")throw new o("Invalid stream done payload: expected ChatResponse object.");const e=t;if(typeof e.response!="string"||typeof e.conversation_id!="string")throw new o("Invalid ChatResponse payload: missing required fields response/conversation_id.");return e}toStreamError(t){if(!t||typeof t!="object")return{error:"stream_error",detail:"Unknown stream error payload."};const e=t;return{error:typeof e.error=="string"?e.error:"stream_error",detail:typeof e.detail=="string"?e.detail:void 0}}errorMessage(t,e){return t instanceof Error&&t.message?t.message:e}}exports.JazzmineClient=C;exports.JazzmineClientError=o;exports.default=C;
package/dist/index.js CHANGED
@@ -5,7 +5,7 @@ const C = {
5
5
  health: "/health",
6
6
  info: "/info"
7
7
  };
8
- async function $(r) {
8
+ async function I(r) {
9
9
  if (r.endpointsResolved || !r.autoDiscoverEndpoints)
10
10
  return r.endpointsResolved;
11
11
  try {
@@ -14,12 +14,12 @@ async function $(r) {
14
14
  return !0;
15
15
  }
16
16
  }
17
- function I(r, t) {
17
+ function x(r, t) {
18
18
  const e = {}, n = r == null ? void 0 : r.endpoints;
19
19
  if (!n || typeof n != "object")
20
20
  return e;
21
- const i = m(n.chat, "POST", t), s = m(n.stream, "POST", t), a = m(n.conversations_create, "POST", t), h = m(n.health, "GET", t), d = m(n.info, "GET", t);
22
- return i && (e.chat = i), s ? e.stream = s : i && (e.stream = `${i.replace(/\/+$/, "")}/stream`), a && (e.conversations = a), h && (e.health = h), d && (e.info = d), e;
21
+ const s = m(n.chat, "POST", t), i = m(n.stream, "POST", t), a = m(n.conversations_create, "POST", t), h = m(n.health, "GET", t), u = m(n.info, "GET", t);
22
+ return s && (e.chat = s), i ? e.stream = i : s && (e.stream = `${s.replace(/\/+$/, "")}/stream`), a && (e.conversations = a), h && (e.health = h), u && (e.info = u), e;
23
23
  }
24
24
  function m(r, t, e) {
25
25
  if (typeof r != "string")
@@ -27,11 +27,11 @@ function m(r, t, e) {
27
27
  const n = r.match(/^([A-Z]+)\s+(.+)$/i);
28
28
  if (!n)
29
29
  return null;
30
- const i = n[1].toUpperCase(), s = n[2].trim();
31
- if (i !== t.toUpperCase())
30
+ const s = n[1].toUpperCase(), i = n[2].trim();
31
+ if (s !== t.toUpperCase())
32
32
  return null;
33
33
  try {
34
- const a = new URL(s, e);
34
+ const a = new URL(i, e);
35
35
  return `${a.pathname}${a.search}`;
36
36
  } catch {
37
37
  return null;
@@ -42,7 +42,7 @@ class o extends Error {
42
42
  super(t), this.name = "JazzmineClientError", this.status = e == null ? void 0 : e.status, this.code = e == null ? void 0 : e.code, this.details = e == null ? void 0 : e.details;
43
43
  }
44
44
  }
45
- function b(r, t) {
45
+ function M(r, t) {
46
46
  if (!r && !t)
47
47
  return;
48
48
  if (!r)
@@ -52,15 +52,15 @@ function b(r, t) {
52
52
  const e = AbortSignal.any;
53
53
  if (typeof e == "function")
54
54
  return e([r, t]);
55
- const n = new AbortController(), i = () => {
55
+ const n = new AbortController(), s = () => {
56
56
  n.abort();
57
57
  };
58
- return r.aborted || t.aborted ? (n.abort(), n.signal) : (r.addEventListener("abort", i, { once: !0 }), t.addEventListener("abort", i, { once: !0 }), n.signal);
58
+ return r.aborted || t.aborted ? (n.abort(), n.signal) : (r.addEventListener("abort", s, { once: !0 }), t.addEventListener("abort", s, { once: !0 }), n.signal);
59
59
  }
60
60
  function R(r) {
61
61
  return r instanceof DOMException && (r.name === "AbortError" || r.name === "TimeoutError");
62
62
  }
63
- function A(r) {
63
+ function U(r) {
64
64
  const t = r.trim().replace(/\/+$/, "");
65
65
  let e;
66
66
  try {
@@ -74,7 +74,7 @@ function A(r) {
74
74
  throw new o("baseEndpoint must use http or https.");
75
75
  return `${e.protocol}//${e.host}${e.pathname.replace(/\/+$/, "")}`;
76
76
  }
77
- function U(r, t) {
77
+ function A(r, t) {
78
78
  const e = t.startsWith("/") ? t : `/${t}`;
79
79
  return `${r}${e}`;
80
80
  }
@@ -89,72 +89,72 @@ function E(r) {
89
89
  if (r.metadata !== void 0 && (r.metadata === null || typeof r.metadata != "object"))
90
90
  throw new o("metadata must be an object when provided.");
91
91
  }
92
- function k(r, t, e) {
92
+ function J(r, t, e) {
93
93
  if (r === void 0)
94
94
  return t;
95
95
  if (!Number.isFinite(r) || r <= 0)
96
96
  throw new o(`${e} must be a positive number.`);
97
97
  return Math.round(r);
98
98
  }
99
- function g(r, t, e, n, i) {
99
+ function b(r, t, e, n, s) {
100
100
  if (r === void 0)
101
101
  return t;
102
- if (!Number.isInteger(r) || r < n || r > i)
103
- throw new o(`${e} must be an integer between ${n} and ${i}.`);
102
+ if (!Number.isInteger(r) || r < n || r > s)
103
+ throw new o(`${e} must be an integer between ${n} and ${s}.`);
104
104
  return r;
105
105
  }
106
- async function J(r, t) {
106
+ async function k(r, t) {
107
107
  const e = r * (t + 1);
108
108
  e <= 0 || await new Promise((n) => setTimeout(n, e));
109
109
  }
110
- async function N(r) {
110
+ async function P(r) {
111
111
  let t;
112
112
  for (let e = 0; e <= r.retries; e += 1)
113
113
  try {
114
114
  return await r.runAttempt(e);
115
115
  } catch (n) {
116
116
  if (t = n, r.allowRetry && e < r.retries && r.shouldRetry(n)) {
117
- await J(r.retryBackoffMs, e);
117
+ await k(r.retryBackoffMs, e);
118
118
  continue;
119
119
  }
120
120
  throw n;
121
121
  }
122
122
  throw t;
123
123
  }
124
- class w extends Error {
124
+ class p extends Error {
125
125
  constructor(t) {
126
126
  const e = `Request timed out after ${t} ms.`;
127
127
  super(e), this.name = "RetryableTimeoutError", this.finalError = new o(e);
128
128
  }
129
129
  }
130
- class p extends Error {
130
+ class y extends Error {
131
131
  constructor(t) {
132
132
  super(t), this.name = "RetryableNetworkError", this.finalError = new o(t);
133
133
  }
134
134
  }
135
- async function D(r, t) {
135
+ async function N(r, t) {
136
136
  try {
137
- return await N({
137
+ return await P({
138
138
  retries: t.retries,
139
139
  allowRetry: t.allowRetry,
140
140
  retryBackoffMs: r.retryBackoffMs,
141
141
  runAttempt: async () => {
142
142
  const e = new AbortController(), n = setTimeout(() => {
143
143
  e.abort();
144
- }, t.timeoutMs), i = b(t.signal, e.signal);
144
+ }, t.timeoutMs), s = M(t.signal, e.signal);
145
145
  try {
146
- const s = await r.fetchFn(_(r.baseUrl, t.path), {
146
+ const i = await r.fetchFn(_(r.baseUrl, t.path), {
147
147
  method: t.method,
148
148
  headers: T(r.apiKey, {
149
149
  accept: "application/json",
150
150
  contentType: t.body !== void 0 ? "application/json" : void 0
151
151
  }),
152
152
  body: t.body !== void 0 ? JSON.stringify(t.body) : void 0,
153
- signal: i
153
+ signal: s
154
154
  });
155
- if (!s.ok)
156
- throw await M(s, t.path);
157
- const a = await s.text();
155
+ if (!i.ok)
156
+ throw await S(i, t.path);
157
+ const a = await i.text();
158
158
  if (!a.trim())
159
159
  return {};
160
160
  try {
@@ -164,14 +164,14 @@ async function D(r, t) {
164
164
  `Expected JSON response from ${t.path}, but received invalid JSON.`
165
165
  );
166
166
  }
167
- } catch (s) {
168
- throw R(s) ? new w(t.timeoutMs) : s instanceof o ? s : s instanceof TypeError ? new p(y(s, "Network request failed.")) : new o(y(s, "Network request failed."));
167
+ } catch (i) {
168
+ throw R(i) ? new p(t.timeoutMs) : i instanceof o ? i : i instanceof TypeError ? new y(v(i, "Network request failed.")) : new o(v(i, "Network request failed."));
169
169
  } finally {
170
170
  clearTimeout(n);
171
171
  }
172
172
  },
173
173
  shouldRetry: (e) => {
174
- if (e instanceof w || e instanceof p)
174
+ if (e instanceof p || e instanceof y)
175
175
  return !0;
176
176
  if (e instanceof o) {
177
177
  const n = e.status ?? 0;
@@ -181,10 +181,10 @@ async function D(r, t) {
181
181
  }
182
182
  });
183
183
  } catch (e) {
184
- throw e instanceof w || e instanceof p ? e.finalError : e instanceof o ? e : new o(y(e, "Network request failed."));
184
+ throw e instanceof p || e instanceof y ? e.finalError : e instanceof o ? e : new o(v(e, "Network request failed."));
185
185
  }
186
186
  }
187
- async function M(r, t) {
187
+ async function S(r, t) {
188
188
  const e = await r.text();
189
189
  let n;
190
190
  if (e.trim())
@@ -193,8 +193,8 @@ async function M(r, t) {
193
193
  } catch {
194
194
  n = e;
195
195
  }
196
- const i = P(n), s = `HTTP ${r.status} on ${t}${i ? `: ${i}` : ""}`;
197
- return new o(s, {
196
+ const s = D(n), i = `HTTP ${r.status} on ${t}${s ? `: ${s}` : ""}`;
197
+ return new o(i, {
198
198
  status: r.status,
199
199
  details: n
200
200
  });
@@ -204,9 +204,9 @@ function T(r, t) {
204
204
  return t.accept && (e.Accept = t.accept), t.contentType && (e["Content-Type"] = t.contentType), r && (e.Authorization = `Bearer ${r}`), e;
205
205
  }
206
206
  function _(r, t) {
207
- return U(r, t);
207
+ return A(r, t);
208
208
  }
209
- function P(r) {
209
+ function D(r) {
210
210
  if (!r)
211
211
  return "";
212
212
  if (typeof r == "string")
@@ -220,56 +220,56 @@ function P(r) {
220
220
  }
221
221
  return "";
222
222
  }
223
- function y(r, t) {
223
+ function v(r, t) {
224
224
  return r instanceof Error && r.message ? r.message : t;
225
225
  }
226
226
  function j(r) {
227
- const t = r.split(/\r?\n/).map((s) => s.trimEnd()).filter((s) => s.length > 0 && !s.startsWith(":"));
227
+ const t = r.split(/\r?\n/).map((i) => i.trimEnd()).filter((i) => i.length > 0 && !i.startsWith(":"));
228
228
  if (t.length === 0)
229
229
  return null;
230
230
  let e = "message";
231
231
  const n = [];
232
- for (const s of t) {
233
- if (s.startsWith("event:")) {
234
- e = s.slice(6).trim() || "message";
232
+ for (const i of t) {
233
+ if (i.startsWith("event:")) {
234
+ e = i.slice(6).trim() || "message";
235
235
  continue;
236
236
  }
237
- s.startsWith("data:") && n.push(s.slice(5).trim());
237
+ i.startsWith("data:") && n.push(i.slice(5).trim());
238
238
  }
239
- const i = n.join(`
239
+ const s = n.join(`
240
240
  `);
241
- if (!i)
241
+ if (!s)
242
242
  return { event: e, data: null };
243
243
  try {
244
- return { event: e, data: JSON.parse(i) };
244
+ return { event: e, data: JSON.parse(s) };
245
245
  } catch {
246
- return { event: e, data: i };
246
+ return { event: e, data: s };
247
247
  }
248
248
  }
249
249
  async function F(r) {
250
- var a, h, d, c;
250
+ var a, h, u, c;
251
251
  const t = r.handlers ?? {}, e = r.body.getReader(), n = new TextDecoder("utf-8");
252
- let i = "", s = null;
252
+ let s = "", i = null;
253
253
  for (; ; ) {
254
- const { done: l, value: S } = await e.read();
254
+ const { done: l, value: w } = await e.read();
255
255
  if (l)
256
256
  break;
257
- i += n.decode(S, { stream: !0 });
258
- const v = i.split(/\n\n/);
259
- i = v.pop() ?? "";
260
- for (const x of v) {
261
- const u = j(x);
262
- if (u) {
263
- if ((a = t.onRawEvent) == null || a.call(t, u.event, u.data), u.event === "intermediate") {
264
- (h = t.onIntermediate) == null || h.call(t, u.data);
257
+ s += n.decode(w, { stream: !0 });
258
+ const g = s.split(/\n\n/);
259
+ s = g.pop() ?? "";
260
+ for (const $ of g) {
261
+ const d = j($);
262
+ if (d) {
263
+ if ((a = t.onRawEvent) == null || a.call(t, d.event, d.data), d.event === "intermediate") {
264
+ (h = t.onIntermediate) == null || h.call(t, d.data);
265
265
  continue;
266
266
  }
267
- if (u.event === "done") {
268
- s = r.expectChatResponse(u.data), (d = t.onDone) == null || d.call(t, s);
267
+ if (d.event === "done") {
268
+ i = r.expectChatResponse(d.data), (u = t.onDone) == null || u.call(t, i);
269
269
  continue;
270
270
  }
271
- if (u.event === "error") {
272
- const f = r.toStreamError(u.data);
271
+ if (d.event === "error") {
272
+ const f = r.toStreamError(d.data);
273
273
  throw (c = t.onErrorEvent) == null || c.call(t, f), new o(f.detail || f.error || "Stream error event received.", {
274
274
  code: f.error,
275
275
  details: f
@@ -278,14 +278,14 @@ async function F(r) {
278
278
  }
279
279
  }
280
280
  }
281
- if (!s)
281
+ if (!i)
282
282
  throw new o(
283
283
  "Stream ended without a final done event containing ChatResponse."
284
284
  );
285
- return s;
285
+ return i;
286
286
  }
287
- const B = 2e4, z = 2, L = 350;
288
- class W {
287
+ const L = 2e4, B = 2, z = 350;
288
+ class q {
289
289
  constructor(t, e = {}) {
290
290
  if (this.endpointsResolved = !1, !t || !t.trim())
291
291
  throw new o("baseEndpoint is required.");
@@ -293,9 +293,9 @@ class W {
293
293
  throw new o(
294
294
  "fetch is not available in this runtime. Provide options.fetchImpl."
295
295
  );
296
- this.baseUrl = A(t), this.apiKey = e.apiKey, this.timeoutMs = k(e.timeoutMs, B, "timeoutMs"), this.retries = g(e.retries, z, "retries", 0, 10), this.retryBackoffMs = g(
296
+ this.baseUrl = U(t), this.apiKey = e.apiKey, this.timeoutMs = J(e.timeoutMs, L, "timeoutMs"), this.retries = b(e.retries, B, "retries", 0, 10), this.retryBackoffMs = b(
297
297
  e.retryBackoffMs,
298
- L,
298
+ z,
299
299
  "retryBackoffMs",
300
300
  0,
301
301
  6e4
@@ -349,6 +349,82 @@ class W {
349
349
  allowRetry: !0
350
350
  });
351
351
  }
352
+ async listConversations(t, e = {}) {
353
+ var u;
354
+ const n = (u = t.userId) == null ? void 0 : u.trim();
355
+ if (!n)
356
+ throw new o("userId is required.");
357
+ const s = t.limit ?? 100, i = t.offset ?? 0;
358
+ await this.ensureEndpoints(e);
359
+ const a = new URLSearchParams({
360
+ user_id: n,
361
+ limit: String(s),
362
+ offset: String(i)
363
+ }).toString(), h = await this.requestJson({
364
+ method: "GET",
365
+ path: `${this.endpoints.conversations}?${a}`,
366
+ timeoutMs: e.timeoutMs ?? this.timeoutMs,
367
+ retries: e.retries ?? this.retries,
368
+ signal: e.signal,
369
+ allowRetry: !0
370
+ });
371
+ return {
372
+ conversations: h.conversations,
373
+ total: h.total,
374
+ limit: h.limit,
375
+ offset: h.offset,
376
+ hasMore: h.total > i + h.conversations.length
377
+ };
378
+ }
379
+ async searchConversations(t, e = {}) {
380
+ var l, w;
381
+ const n = (l = t.userId) == null ? void 0 : l.trim(), s = (w = t.query) == null ? void 0 : w.trim();
382
+ if (!n)
383
+ throw new o("userId is required.");
384
+ if (!s)
385
+ throw new o("query is required.");
386
+ const i = t.limit ?? 100, a = t.offset ?? 0;
387
+ await this.ensureEndpoints(e);
388
+ const h = new URLSearchParams({
389
+ user_id: n,
390
+ query: s,
391
+ limit: String(i),
392
+ offset: String(a)
393
+ }).toString(), u = `${this.endpoints.conversations}/search?${h}`, c = await this.requestJson({
394
+ method: "GET",
395
+ path: u,
396
+ timeoutMs: e.timeoutMs ?? this.timeoutMs,
397
+ retries: e.retries ?? this.retries,
398
+ signal: e.signal,
399
+ allowRetry: !0
400
+ });
401
+ return {
402
+ conversations: c.conversations,
403
+ total: c.total,
404
+ limit: c.limit,
405
+ offset: c.offset,
406
+ hasMore: c.total > a + c.conversations.length,
407
+ query: c.query
408
+ };
409
+ }
410
+ async updateConversation(t, e, n = {}) {
411
+ var a;
412
+ const s = t == null ? void 0 : t.trim();
413
+ if (!s)
414
+ throw new o("conversationId is required.");
415
+ const i = (a = e.title) == null ? void 0 : a.trim();
416
+ if (!i)
417
+ throw new o("title is required.");
418
+ return await this.ensureEndpoints(n), this.requestJson({
419
+ method: "PATCH",
420
+ path: `${this.endpoints.conversations}/${encodeURIComponent(s)}`,
421
+ body: { title: i },
422
+ timeoutMs: n.timeoutMs ?? this.timeoutMs,
423
+ retries: n.retries ?? 0,
424
+ signal: n.signal,
425
+ allowRetry: !1
426
+ });
427
+ }
352
428
  async chat(t, e = {}) {
353
429
  return E(t), await this.ensureEndpoints(e), this.requestJson({
354
430
  method: "POST",
@@ -368,9 +444,9 @@ class W {
368
444
  }
369
445
  async chatStream(t, e = {}, n = {}) {
370
446
  E(t), await this.ensureEndpoints(n);
371
- const i = n.timeoutMs ?? this.timeoutMs, s = n.signal, a = new AbortController(), h = setTimeout(() => {
447
+ const s = n.timeoutMs ?? this.timeoutMs, i = n.signal, a = new AbortController(), h = setTimeout(() => {
372
448
  a.abort();
373
- }, i), d = b(s, a.signal);
449
+ }, s), u = M(i, a.signal);
374
450
  try {
375
451
  const c = await this.fetchFn(_(this.baseUrl, this.endpoints.stream), {
376
452
  method: "POST",
@@ -385,10 +461,10 @@ class W {
385
461
  explicit_context: t.explicit_context,
386
462
  metadata: t.metadata ?? {}
387
463
  }),
388
- signal: d
464
+ signal: u
389
465
  });
390
466
  if (!c.ok)
391
- throw await M(c, this.endpoints.stream);
467
+ throw await S(c, this.endpoints.stream);
392
468
  if (!c.body)
393
469
  throw new o("Streaming response body is missing.");
394
470
  return await F({
@@ -398,7 +474,7 @@ class W {
398
474
  toStreamError: (l) => this.toStreamError(l)
399
475
  });
400
476
  } catch (c) {
401
- throw R(c) ? new o(`Streaming request timed out after ${i} ms.`) : c instanceof o ? c : new o(this.errorMessage(c, "Streaming request failed."));
477
+ throw R(c) ? new o(`Streaming request timed out after ${s} ms.`) : c instanceof o ? c : new o(this.errorMessage(c, "Streaming request failed."));
402
478
  } finally {
403
479
  clearTimeout(h);
404
480
  }
@@ -412,16 +488,16 @@ class W {
412
488
  explicit_context: e.explicitContext,
413
489
  metadata: e.metadata
414
490
  };
415
- let i = (a = e.conversationId) == null ? void 0 : a.trim();
416
- !i && e.autoCreateConversation && (i = (await this.createConversation(
491
+ let s = (a = e.conversationId) == null ? void 0 : a.trim();
492
+ !s && e.autoCreateConversation && (s = (await this.createConversation(
417
493
  {
418
494
  user_id: e.userId ?? this.defaultUserId,
419
495
  title: e.conversationTitle ?? "New conversation"
420
496
  },
421
497
  e.requestOptions
422
- )).conversation_id, n.conversation_id = i);
423
- const s = await this.chat(n, e.requestOptions);
424
- return { response: s, conversationId: s.conversation_id || i || "" };
498
+ )).conversation_id, n.conversation_id = s);
499
+ const i = await this.chat(n, e.requestOptions);
500
+ return { response: i, conversationId: i.conversation_id || s || "" };
425
501
  }
426
502
  async resolveServerEndpoints(t = {}) {
427
503
  const e = await this.requestJson({
@@ -431,14 +507,14 @@ class W {
431
507
  retries: t.retries ?? this.retries,
432
508
  signal: t.signal,
433
509
  allowRetry: !0
434
- }), n = I(e, this.baseUrl);
510
+ }), n = x(e, this.baseUrl);
435
511
  return this.endpoints = {
436
512
  ...this.endpoints,
437
513
  ...n
438
514
  }, this.endpointsResolved = !0, { ...this.endpoints };
439
515
  }
440
516
  async ensureEndpoints(t = {}) {
441
- this.endpointsResolved = await $({
517
+ this.endpointsResolved = await I({
442
518
  endpointsResolved: this.endpointsResolved,
443
519
  autoDiscoverEndpoints: this.autoDiscoverEndpoints,
444
520
  requestOptions: t,
@@ -446,7 +522,7 @@ class W {
446
522
  });
447
523
  }
448
524
  requestJson(t) {
449
- return D(
525
+ return N(
450
526
  {
451
527
  baseUrl: this.baseUrl,
452
528
  apiKey: this.apiKey,
@@ -480,7 +556,7 @@ class W {
480
556
  }
481
557
  }
482
558
  export {
483
- W as JazzmineClient,
559
+ q as JazzmineClient,
484
560
  o as JazzmineClientError,
485
- W as default
561
+ q as default
486
562
  };
@@ -15,4 +15,46 @@ export interface ConversationDeleteResponse {
15
15
  conversation_id: string;
16
16
  deleted: boolean;
17
17
  }
18
+ export interface ConversationListParams {
19
+ userId: string;
20
+ limit?: number;
21
+ offset?: number;
22
+ }
23
+ export interface ConversationSearchParams {
24
+ userId: string;
25
+ query: string;
26
+ limit?: number;
27
+ offset?: number;
28
+ }
29
+ export interface ConversationUpdateRequest {
30
+ title: string;
31
+ }
32
+ export interface ConversationUpdateResponse {
33
+ conversation_id: string;
34
+ user_id: string;
35
+ agent_id: string;
36
+ title: string;
37
+ created_at: number;
38
+ last_updated_at: number;
39
+ }
40
+ export interface ConversationListResponse {
41
+ user_id: string;
42
+ total: number;
43
+ limit: number;
44
+ offset: number;
45
+ query?: string;
46
+ conversations: ConversationCreateResponse[];
47
+ }
48
+ /**
49
+ * Helper type for infinite scroll pagination.
50
+ * Tells the consumer whether more pages are available.
51
+ */
52
+ export interface ConversationPage {
53
+ conversations: ConversationCreateResponse[];
54
+ total: number;
55
+ limit: number;
56
+ offset: number;
57
+ hasMore: boolean;
58
+ query?: string;
59
+ }
18
60
  //# sourceMappingURL=conversation.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"conversation.d.ts","sourceRoot":"","sources":["../../src/types/conversation.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,yBAAyB;IACxC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,0BAA0B;IACzC,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,0BAA0B;IACzC,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,OAAO,CAAC;CAClB"}
1
+ {"version":3,"file":"conversation.d.ts","sourceRoot":"","sources":["../../src/types/conversation.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,yBAAyB;IACxC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,0BAA0B;IACzC,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,0BAA0B;IACzC,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,yBAAyB;IACxC,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,0BAA0B;IACzC,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,0BAA0B,EAAE,CAAC;CAC7C;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,aAAa,EAAE,0BAA0B,EAAE,CAAC;IAC5C,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB"}
@@ -1,5 +1,5 @@
1
1
  export * from './chat';
2
- export * from './conversation';
2
+ export type { ConversationCreateRequest, ConversationCreateResponse, ConversationDeleteResponse, ConversationListParams, ConversationSearchParams, ConversationUpdateRequest, ConversationUpdateResponse, ConversationListResponse, ConversationPage, } from './conversation';
3
3
  export * from './health';
4
4
  export * from './info';
5
5
  export * from './options';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC;AACvB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,UAAU,CAAC;AACzB,cAAc,QAAQ,CAAC;AACvB,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC;AACvB,YAAY,EACX,yBAAyB,EACzB,0BAA0B,EAC1B,0BAA0B,EAC1B,sBAAsB,EACtB,wBAAwB,EACxB,yBAAyB,EACzB,0BAA0B,EAC1B,wBAAwB,EACxB,gBAAgB,GAChB,MAAM,gBAAgB,CAAC;AACxB,cAAc,UAAU,CAAC;AACzB,cAAc,QAAQ,CAAC;AACvB,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC"}
@@ -1,4 +1,4 @@
1
- export type InfoEndpointsMap = Record<string, string>;
1
+ export type InfoEndpointsMap = Partial<Record<"chat" | "stream" | "conversations_create" | "conversations_list" | "conversations_search" | "conversations_update" | "conversations_delete" | "health" | "info", string>>;
2
2
  export interface InfoResponse {
3
3
  agent_name: string;
4
4
  agent_id: string;
@@ -1 +1 @@
1
- {"version":3,"file":"info.d.ts","sourceRoot":"","sources":["../../src/types/info.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,gBAAgB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAEtD,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,gBAAgB,CAAC;CAC7B"}
1
+ {"version":3,"file":"info.d.ts","sourceRoot":"","sources":["../../src/types/info.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,gBAAgB,GAAG,OAAO,CACpC,MAAM,CACF,MAAM,GACN,QAAQ,GACR,sBAAsB,GACtB,oBAAoB,GACpB,sBAAsB,GACtB,sBAAsB,GACtB,sBAAsB,GACtB,QAAQ,GACR,MAAM,EACR,MAAM,CACP,CACF,CAAC;AAEF,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,gBAAgB,CAAC;CAC7B"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jazzmine-ui/sdk",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "type": "module",
5
5
  "description": "Framework-agnostic TypeScript client for Jazzmine agentic backends",
6
6
  "repository": {
@@ -33,7 +33,10 @@
33
33
  "test:watch": "vitest",
34
34
  "lint": "eslint src tests",
35
35
  "typecheck": "tsc --noEmit",
36
- "prepublishOnly": "npm run typecheck && npm run test && npm run build"
36
+ "prepublishOnly": "npm run typecheck && npm run test && npm run build",
37
+ "release:patch": "npm version patch && git push --follow-tags origin HEAD",
38
+ "release:minor": "npm version minor && git push --follow-tags origin HEAD",
39
+ "release:major": "npm version major && git push --follow-tags origin HEAD"
37
40
  },
38
41
  "devDependencies": {
39
42
  "@types/node": "^25.5.2",