opik 1.11.1 → 1.11.2
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/dist/chunk-WMVCENG3.js +10 -0
- package/dist/index.cjs +35 -35
- package/dist/index.d.cts +121 -5
- package/dist/index.d.ts +121 -5
- package/dist/index.js +30 -30
- package/dist/{typeHelpers-EBAVSLFP.js → typeHelpers-MEOKD5HI.js} +1 -1
- package/package.json +1 -1
- package/dist/chunk-HYAYEFG6.js +0 -10
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import {formatDistanceToNow}from'date-fns';import {diffStringsUnified}from'jest-diff';import {link}from'ansi-escapes';import {Logger}from'tslog';import pt from'mustache';import dt from'nunjucks';var Y=Object.create;var v=Object.defineProperty;var Q=Object.getOwnPropertyDescriptor;var U=(r,t)=>(t=Symbol[r])?t:Symbol.for("Symbol."+r),V=r=>{throw TypeError(r)};var X=(r,t,e)=>t in r?v(r,t,{enumerable:true,configurable:true,writable:true,value:e}):r[t]=e;var z=(r,t)=>v(r,"name",{value:t,configurable:true});var yt=(r,t)=>{for(var e in t)v(r,e,{get:t[e],enumerable:true});};var Pt=r=>{var t;return [,,,Y((t=r==null?void 0:r[U("metadata")])!=null?t:null)]},L=["class","method","getter","setter","accessor","field","value","get","set"],T=r=>r!==void 0&&typeof r!="function"?V("Function expected"):r,tt=(r,t,e,i,o)=>({kind:L[r],name:t,metadata:i,addInitializer:n=>e._?V("Already initialized"):o.push(T(n||null))}),et=(r,t)=>X(t,U("metadata"),r[3]),bt=(r,t,e,i)=>{for(var o=0,n=r[t>>1],s=n&&n.length;o<s;o++)t&1?n[o].call(e):i=n[o].call(e,i);return i},wt=(r,t,e,i,o,n)=>{var s,a,d,f,h,p=t&7,A=!!(t&8),c=!!(t&16),b=p>3?r.length+1:p?A?1:2:0,l=L[p+5],w=p>3&&(r[b-1]=[]),C=r[b]||(r[b]=[]),u=p&&(!c&&!A&&(o=o.prototype),p<5&&(p>3||!c)&&Q(p<4?o:{get[e](){return E(this,n)},set[e](y){return Z(this,n,y)}},e));p?c&&p<4&&z(n,(p>2?"set ":p>1?"get ":"")+e):z(o,e);for(var N=i.length-1;N>=0;N--)f=tt(p,e,d={},r[3],C),p&&(f.static=A,f.private=c,h=f.access={has:c?y=>rt(o,y):y=>e in y},p^3&&(h.get=c?y=>(p^1?E:it)(y,o,p^4?n:u.get):y=>y[e]),p>2&&(h.set=c?(y,j)=>Z(y,o,j,p^4?n:u.set):(y,j)=>y[e]=j)),a=(0, i[N])(p?p<4?c?n:u[l]:p>4?void 0:{get:u.get,set:u.set}:o,f),d._=1,p^4||a===void 0?T(a)&&(p>4?w.unshift(a):p?c?n=a:u[l]=a:o=a):typeof a!="object"||a===null?V("Object expected"):(T(s=a.get)&&(u.get=s),T(s=a.set)&&(u.set=s),T(s=a.init)&&w.unshift(s));return p||et(r,o),u&&v(o,e,u),c?p^4?n:u:o};var D=(r,t,e)=>t.has(r)||V("Cannot "+e),rt=(r,t)=>Object(t)!==t?V('Cannot use the "in" operator on this value'):r.has(t),E=(r,t,e)=>(D(r,t,"read from private field"),e?e.call(r):t.get(r));var Z=(r,t,e,i)=>(D(r,t,"write to private field"),i?i.call(r,e):t.set(r,e),e),it=(r,t,e)=>(D(r,t,"access private method"),e);var st={SILLY:0,TRACE:1,DEBUG:2,INFO:3,WARN:4,ERROR:5,FATAL:6};function At(r,t=r){return link(t,r)}var g=new Logger({hideLogPositionForProduction:true,prettyLogTemplate:"{{yyyy}}.{{mm}}.{{dd}} {{hh}}:{{MM}}:{{ss}}:{{ms}} {{logLevelName}} "}),at=r=>{g.settings.minLevel=st[r];},Ot=()=>{g.settings.minLevel=100;};at(process.env.OPIK_LOG_LEVEL||"INFO");var O={MUSTACHE:"mustache",JINJA2:"jinja2",PYTHON:"python"},S={Text:"text",Chat:"chat"};var m=class r extends Error{constructor(t){super(t),this.name="PromptValidationError",Object.setPrototypeOf(this,r.prototype);}},F=class r extends Error{constructor(t,e,i){let o=`Prompt '${t}' has template_structure='${e}' but attempted to access as '${i}'. Template structure is immutable after creation.`;super(o),this.name="PromptTemplateStructureMismatch",this.promptName=t,this.existingStructure=e,this.attemptedStructure=i,Object.setPrototypeOf(this,r.prototype);}};function mt(r){try{let e=pt.parse(r).filter(i=>{let o=i[0];return o==="name"||o==="#"||o==="&"||o==="^"}).map(i=>i[1].split(".")[0]);return new Set(e)}catch(t){throw new m(`Invalid Mustache template syntax: ${t instanceof Error?t.message:String(t)}`)}}function q(r,t,e){if(e!=="mustache")return;let i=mt(r),o=new Set(Object.keys(t)),n=new Set([...i].filter(s=>!o.has(s)));if(n.size>0){let s=[];throw s.push(`Missing required variables: ${[...n].join(", ")}`),s.push(`Template placeholders: {${[...i].join(", ")}}`),s.push(`Provided variables: {${[...o].join(", ")}}`),new m(`Template variables validation failed:
|
|
2
|
+
${s.join(`
|
|
3
|
+
`)}`)}}function P(r,t,e){try{switch(q(r,t,e),e){case "mustache":return pt.render(r,t,{},{escape:i=>i});case "jinja2":return dt.renderString(r,t);default:return r}}catch(i){if(i instanceof m)throw i;let o=i instanceof Error?i.message:String(i);throw new m(`Failed to format prompt template: ${o}`)}}function W(r){let t=[];for(let e=0;e<r.length;e++){let i=r[e];if(t.push(`Message ${e+1} [${i.role}]:`),typeof i.content=="string")t.push(R(i.content));else if(Array.isArray(i.content))for(let o=0;o<i.content.length;o++){let n=i.content[o];if(t.push(` Part ${o+1}:`),t.push(` Type: ${n.type}`),n.type==="text"&&"text"in n){let s=n;t.push(R(String(s.text),4)),$(s,["type","text"],t,4);}else if(n.type==="image_url"&&"image_url"in n){let s=n,a=s.image_url;t.push(` URL: ${a.url}`),J(a,["url"],t,4),$(s,["type","image_url"],t,4);}else if(n.type==="video_url"&&"video_url"in n){let s=n,a=s.video_url;t.push(` URL: ${a.url}`),J(a,["url"],t,4),$(s,["type","video_url"],t,4);}else t.push(" [Difference found in unrecognized content type]");}e<r.length-1&&t.push("");}return t.join(`
|
|
4
|
+
`)}function $(r,t,e,i=4){let o=Object.keys(r).filter(n=>!t.includes(n));if(o.length>0)for(let n of o.sort()){let s=r[n];e.push(`${" ".repeat(i)}${n}: ${K(s)}`);}}function J(r,t,e,i=4){let o=Object.keys(r).filter(n=>!t.includes(n));if(o.length>0)for(let n of o.sort()){let s=r[n];e.push(`${" ".repeat(i)}${n}: ${K(s)}`);}}function K(r){return r===null?"null":r===void 0?"undefined":typeof r=="string"?r:typeof r=="number"||typeof r=="boolean"?String(r):Array.isArray(r)||typeof r=="object"?JSON.stringify(r):String(r)}function R(r,t=2){let e=" ".repeat(t);return r.split(`
|
|
5
|
+
`).map(i=>`${e}${i}`).join(`
|
|
6
|
+
`)}var x=class r{constructor(t){this.id=t.versionId,this.name=t.name,this.prompt=t.prompt,this.commit=t.commit,this.type=t.type,this.metadata=t.metadata,this.changeDescription=t.changeDescription,this.tags=t.tags,this.createdAt=t.createdAt,this.createdBy=t.createdBy;}format(t){return P(this.prompt,t,this.type)}getVersionAge(){return this.createdAt?formatDistanceToNow(new Date(this.createdAt),{addSuffix:true}):"Unknown"}getVersionInfo(){let t=[`[${this.commit}]`];if(this.createdAt){let e=new Date(this.createdAt);t.push(e.toISOString().split("T")[0]);}return this.createdBy&&t.push(`by ${this.createdBy}`),this.changeDescription&&t.push(`- ${this.changeDescription}`),t.join(" ")}compareTo(t){let e=`Current version [${this.commit}]`,i=`Other version [${t.commit}]`,o=this.prompt,n=t.prompt;this.isChatPrompt(this.prompt)&&(o=this.formatChatPromptString(this.prompt)),this.isChatPrompt(t.prompt)&&(n=this.formatChatPromptString(t.prompt));let s=diffStringsUnified(n,o,{aAnnotation:i,bAnnotation:e,includeChangeCounts:true,contextLines:3,expand:false});return g.info(`
|
|
7
|
+
Prompt version comparison:
|
|
8
|
+
${s}`),s}isChatPrompt(t){try{let e=JSON.parse(t);return Array.isArray(e)&&e.length>0&&typeof e[0]=="object"&&"role"in e[0]&&"content"in e[0]}catch{return false}}formatChatPromptString(t){try{let e=JSON.parse(t);return W(e)}catch{return t}}static fromApiResponse(t,e){var i;if(!e.template)throw new m("Invalid API response: missing required field 'template'");if(!e.commit)throw new m("Invalid API response: missing required field 'commit'");if(!e.promptId)throw new m("Invalid API response: missing required field 'promptId'");if(!e.id)throw new m("Invalid API response: missing required field 'id'");return new r({name:t,prompt:e.template,commit:e.commit,promptId:e.promptId,versionId:e.id,type:(i=e.type)!=null?i:O.MUSTACHE,metadata:e.metadata,changeDescription:e.changeDescription,tags:e.tags,createdAt:e.createdAt?new Date(e.createdAt):void 0,createdBy:e.createdBy})}};var k=class{constructor(t,e){var i,o,n;this.id=t.promptId,this.versionId=t.versionId,this.commit=t.commit,this.type=(i=t.type)!=null?i:"mustache",this.changeDescription=t.changeDescription,this.templateStructure=(o=t.templateStructure)!=null?o:"text",this.synced=(n=t.synced)!=null?n:false,this._name=t.name,this._description=t.description,this._tags=t.tags?[...t.tags]:[],this._metadata=t.metadata,this.opik=e;}get name(){return this._name}get description(){return this._description}get tags(){return Object.freeze([...this._tags])}get metadata(){if(this._metadata)return structuredClone(this._metadata)}async updateProperties(t){var e,i,o,n;return this.requireSynced("updateProperties"),await this.opik.api.prompts.updatePrompt(this.id,{name:(e=t.name)!=null?e:this._name,description:t.description,tags:t.tags},this.opik.api.requestOptions),this._name=(i=t.name)!=null?i:this._name,this._description=(o=t.description)!=null?o:this._description,this._tags=(n=t.tags)!=null?n:this._tags,this}async delete(){this.requireSynced("delete"),await this.opik.deletePrompts([this.id]);}async getVersions(t){var e;this.requireSynced("getVersions"),g.debug("Getting versions for prompt",{promptId:this.id,name:this.name});try{let i=[],o=1,n=100;for(;;){let a=(e=(await this.opik.api.prompts.getPromptVersions(this.id,{page:o,size:n,search:t==null?void 0:t.search,sorting:t==null?void 0:t.sorting,filters:t==null?void 0:t.filters},this.opik.api.requestOptions)).content)!=null?e:[];if(i.push(...a),a.length<n)break;o++;}return g.debug("Successfully retrieved prompt versions",{promptId:this.id,name:this.name,totalVersions:i.length}),i.map(s=>x.fromApiResponse(this.name,s))}catch(i){throw g.error("Failed to get prompt versions",{promptId:this.id,name:this.name,error:i}),i}}async restoreVersion(t){this.requireSynced("restoreVersion"),g.debug("Restoring prompt version",{promptId:this.id,name:this.name,versionId:t.id,versionCommit:t.commit});try{let e=await this.opik.api.prompts.restorePromptVersion(this.id,t.id,this.opik.api.requestOptions);return g.debug("Successfully restored prompt version",{promptId:this.id,name:this.name,restoredVersionId:e.id,restoredCommit:e.commit}),e}catch(e){throw g.error("Failed to restore prompt version",{promptId:this.id,name:this.name,versionId:t.id,versionCommit:t.commit,error:e}),e}}async retrieveVersionByCommit(t){try{return await this.opik.api.prompts.retrievePromptVersion({name:this.name,commit:t},this.opik.api.requestOptions)}catch(e){if(e&&typeof e=="object"&&"statusCode"in e&&e.statusCode===404)return null;throw g.error("Failed to retrieve prompt version",{promptName:this.name,commit:t,error:e}),e}}requireSynced(t){if(!this.synced)throw new Error(`Cannot call ${t}() on an unsynced prompt. Call syncWithBackend() first to sync the prompt with the backend.`)}};var I=class r extends k{constructor(t,e){super({...t,templateStructure:S.Text},e),this.prompt=t.prompt;}get template(){return this.prompt}format(t){return P(this.prompt,t,this.type)}static fromApiResponse(t,e,i){var n;if(!e.template)throw new m("Invalid API response: missing required field 'template'");if(!e.commit)throw new m("Invalid API response: missing required field 'commit'");if(!e.promptId)throw new m("Invalid API response: missing required field 'promptId'");if(!e.id)throw new m("Invalid API response: missing required field 'id' (version ID)");let o=(n=e.type)!=null?n:O.MUSTACHE;if(o!=="mustache"&&o!=="jinja2")throw new m(`Invalid API response: unknown prompt type '${o}'`);return new r({promptId:e.promptId,versionId:e.id,name:t.name,prompt:e.template,commit:e.commit,metadata:e.metadata,type:o,changeDescription:e.changeDescription,description:t.description,tags:t.tags,synced:true},i)}async useVersion(t){var i;let e=await this.restoreVersion(t);return r.fromApiResponse({name:this.name,description:this.description,tags:Array.from((i=this.tags)!=null?i:[])},e,this.opik)}async syncWithBackend(){try{return await this.opik.createPrompt({name:this.name,prompt:this.prompt,metadata:this.metadata,type:this.type,description:this.description,tags:this.tags?Array.from(this.tags):void 0})}catch(t){return g.warn(`Failed to sync prompt '${this.name}' with the backend. The prompt will work locally but is not persisted on the server. You can retry by calling .syncWithBackend().`,{error:t}),this}}async getVersion(t){var i;let e=await this.retrieveVersionByCommit(t);return e?r.fromApiResponse({name:this.name,description:this.description,tags:Array.from((i=this.tags)!=null?i:[])},e,this.opik):null}};var _=class{constructor(t,e="mustache",i=false){this.messages=t,this.templateType=e,this.validatePlaceholders=i;}format(t,e){let i={vision:true,video:true,...e},o=[];for(let n of this.messages){let s=n.role;if(!s)continue;let a=n.content,d;if(typeof a=="string")d=P(a,t,this.templateType);else if(Array.isArray(a))d=this.renderContentParts(a,t,i);else throw new m(`Invalid message content type. Expected string or array of content parts, got: ${typeof a}`);o.push({role:s,content:d});}return o}renderContentParts(t,e,i){var s,a,d,f,h,p,A;let o=[],n=false;for(let c of t){if(!c||typeof c!="object")continue;switch(c.type){case "text":{let w=P(c.text||"",e,this.templateType);o.push({type:"text",text:w});break}case "image_url":{if(i.vision===false)n=true,o.push({type:"text",text:"<<<image>>><<</image>>>"});else {let l=c,w=((s=l.image_url)==null?void 0:s.url)||"",C=P(w,e,this.templateType);if(C){let u={type:"image_url",image_url:{url:C}};(a=l.image_url)!=null&&a.detail&&(u.image_url.detail=l.image_url.detail),o.push(u);}}break}case "video_url":{if(i.video===false)n=true,o.push({type:"text",text:"<<<video>>><<</video>>>"});else {let l=c,w=((d=l.video_url)==null?void 0:d.url)||"",C=P(w,e,this.templateType);if(C){let u={type:"video_url",video_url:{url:C}};(f=l.video_url)!=null&&f.mime_type&&(u.video_url.mime_type=l.video_url.mime_type),(h=l.video_url)!=null&&h.duration&&(u.video_url.duration=l.video_url.duration),(p=l.video_url)!=null&&p.format&&(u.video_url.format=l.video_url.format),(A=l.video_url)!=null&&A.detail&&(u.video_url.detail=l.video_url.detail),o.push(u);}}break}default:o.push(c);}}if(n){let c=[];for(let b of o)if(b.type==="text"){let l=b.text;l&&c.push(l);}else c.push(JSON.stringify(b));return c.join(`
|
|
9
|
+
|
|
10
|
+
`)}return o.length===1&&o[0].type==="text"?o[0].text:o}};var M=class r extends k{constructor(t,e){super({...t,templateStructure:S.Chat},e),this.messages=t.messages,this.chatTemplate=new _(t.messages,this.type);}get template(){return structuredClone(this.messages)}format(t,e){return this.chatTemplate.format(t,e)}static fromApiResponse(t,e,i){var s;if(!e.template)throw new m("Invalid API response: missing required field 'template'");if(!e.commit)throw new m("Invalid API response: missing required field 'commit'");if(!e.promptId)throw new m("Invalid API response: missing required field 'promptId'");if(!e.id)throw new m("Invalid API response: missing required field 'id' (version ID)");let o;try{if(o=JSON.parse(e.template),!Array.isArray(o))throw new m("Invalid chat prompt template: expected array of messages")}catch(a){throw a instanceof m?a:new m(`Failed to parse chat prompt template: ${a instanceof Error?a.message:String(a)}`)}let n=(s=e.type)!=null?s:O.MUSTACHE;if(n!=="mustache"&&n!=="jinja2")throw new m(`Invalid API response: unknown prompt type '${n}'`);return new r({promptId:e.promptId,versionId:e.id,name:t.name,messages:o,commit:e.commit,metadata:e.metadata,type:n,changeDescription:e.changeDescription,description:t.description,tags:t.tags,synced:true},i)}async useVersion(t){var i;let e=await this.restoreVersion(t);return r.fromApiResponse({name:this.name,description:this.description,tags:Array.from((i=this.tags)!=null?i:[])},e,this.opik)}async syncWithBackend(){try{return await this.opik.createChatPrompt({name:this.name,messages:structuredClone(this.messages),metadata:this.metadata,type:this.type,description:this.description,tags:this.tags?Array.from(this.tags):void 0})}catch(t){return g.warn(`Failed to sync chat prompt '${this.name}' with the backend. The prompt will work locally but is not persisted on the server. You can retry by calling .syncWithBackend().`,{error:t}),this}}async getVersion(t){var i;let e=await this.retrieveVersionByCommit(t);return e?r.fromApiResponse({name:this.name,description:this.description,tags:Array.from((i=this.tags)!=null?i:[])},e,this.opik):null}};function Pe(r){let t=r._def.description;if(!t)throw new TypeError("Schema must have a .describe() name \u2014 e.g. z.object({...}).describe('MyConfig')");return t}function H(r){let t=r,e=false;return (t._def.typeName==="ZodOptional"||t._def.typeName==="ZodNullable")&&(t=t.unwrap(),e=true),{inner:t,isOptional:e}}function ft(r){var e;let{inner:t}=H(r);if(t._def.typeName==="ZodString")return "string";if(t._def.typeName==="ZodBoolean")return "boolean";if(t._def.typeName==="ZodNumber")return ((e=t._def.checks)!=null?e:[]).some(o=>o.kind==="int")?"integer":"float";if(t._def.typeName==="ZodArray"||t._def.typeName==="ZodRecord"||t._def.typeName==="ZodObject")return "string";if(t._def.typeName==="ZodEffects"){let i=Object.create(null);if(Object.setPrototypeOf(i,I.prototype),t.safeParse(i).success||(Object.setPrototypeOf(i,M.prototype),t.safeParse(i).success))return "prompt";if(Object.setPrototypeOf(i,x.prototype),t.safeParse(i).success)return "prompt_commit"}throw new TypeError(`Unsupported Zod type: ${t._def.typeName}`)}function B(r,t){let e=new Map;for(let[i,o]of Object.entries(r.shape)){let n=o,{inner:s,isOptional:a}=H(n),d=ft(n),f=n._def.description,h=s._def.typeName==="ZodArray"||s._def.typeName==="ZodRecord"||s._def.typeName==="ZodObject";e.set(i,{prefixedKey:`${t}.${i}`,backendType:d,description:f,isOptional:a||n.isOptional(),isJsonEncoded:h});}return e}function G(r,t){let e=t!=null?t:ht(r);if(e==="boolean")return r?"true":"false";if(e==="integer"||e==="float"){if(!Number.isFinite(r))throw new TypeError(`Cannot serialize non-finite number: ${r}`);return String(r)}if(e==="string")return Array.isArray(r)||typeof r=="object"&&r!==null?JSON.stringify(r):r;if(e==="prompt"){let i=r;if(!i.commit)throw new TypeError("Cannot serialize prompt without a commit");return i.commit}if(e==="prompt_commit")return r.commit;throw new TypeError(`Unsupported backend type: ${e}`)}function be(r,t,e){let i=B(r,e),o=[];for(let[n,s]of i.entries()){let a=t[n];if(a==null){o.push({key:s.prefixedKey,value:void 0,type:"string",description:s.description});continue}o.push({key:s.prefixedKey,value:G(a,s.backendType),type:s.backendType,description:s.description});}return o}function gt(r,t){if(r==null)return null;switch(t){case "boolean":return r.toLowerCase()==="true";case "integer":return Math.trunc(Number(r));case "float":return Number(r);case "string":case "prompt":case "prompt_commit":return r;default:return r}}function we(r,t,e,i,o){var a;let n=B(r,e),s={};for(let[d,f]of n.entries()){let h=t[f.prefixedKey];if(h!==void 0)if((f.backendType==="prompt"||f.backendType==="prompt_commit")&&o)s[d]=o[f.prefixedKey];else {let p=gt(h.value,(a=h.type)!=null?a:f.backendType);s[d]=f.isJsonEncoded&&typeof p=="string"?JSON.parse(p):p;}else s[d]=i[d];}return s}function ke(r,t,e,i){let o=B(r,i);for(let[n,s]of o.entries()){let a=t[n],d=e.getRawValue(s.prefixedKey);if(a==null){if(d!==void 0)return false;continue}let f=G(a,s.backendType);if(d===void 0||d!==f)return false;let h=e.getFieldDescription(s.prefixedKey);if(s.description!==h)return false}return true}function ht(r){if(typeof r=="boolean")return "boolean";if(typeof r=="number")return Number.isInteger(r)?"integer":"float";if(typeof r=="string")return "string";if(r instanceof k)return "prompt";if(r instanceof x)return "prompt_commit";if(Array.isArray(r)||typeof r=="object"&&r!==null)return "string";throw new TypeError(`Unsupported value type: ${typeof r}`)}export{yt as a,Pt as b,et as c,bt as d,wt as e,At as f,g,at as h,Ot as i,O as j,S as k,F as l,P as m,x as n,I as o,M as p,Pe as q,ft as r,B as s,G as t,be as u,gt as v,we as w,ke as x};
|