@elizaos/plugin-openai 1.6.0 → 2.0.0-alpha.10
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/browser/index.browser.js +2 -2
- package/dist/browser/index.browser.js.map +18 -17
- package/dist/build.d.ts +13 -0
- package/dist/build.d.ts.map +1 -0
- package/dist/cjs/index.node.cjs +1027 -658
- package/dist/cjs/index.node.js.map +18 -17
- package/dist/generated/specs/specs.d.ts +55 -0
- package/dist/generated/specs/specs.d.ts.map +1 -0
- package/dist/index.browser.d.ts +1 -0
- package/dist/index.browser.d.ts.map +1 -0
- package/dist/index.d.ts +1 -5
- package/dist/index.d.ts.map +1 -0
- package/dist/index.node.d.ts +1 -0
- package/dist/index.node.d.ts.map +1 -0
- package/dist/init.d.ts +4 -5
- package/dist/init.d.ts.map +1 -0
- package/dist/models/audio.d.ts +9 -10
- package/dist/models/audio.d.ts.map +1 -0
- package/dist/models/embedding.d.ts +1 -3
- package/dist/models/embedding.d.ts.map +1 -0
- package/dist/models/image.d.ts +4 -13
- package/dist/models/image.d.ts.map +1 -0
- package/dist/models/index.d.ts +7 -5
- package/dist/models/index.d.ts.map +1 -0
- package/dist/models/object.d.ts +4 -9
- package/dist/models/object.d.ts.map +1 -0
- package/dist/models/research.d.ts +34 -0
- package/dist/models/research.d.ts.map +1 -0
- package/dist/models/text.d.ts +22 -3
- package/dist/models/text.d.ts.map +1 -0
- package/dist/models/tokenizer.d.ts +4 -9
- package/dist/models/tokenizer.d.ts.map +1 -0
- package/dist/node/index.node.js +1016 -644
- package/dist/node/index.node.js.map +18 -17
- package/dist/providers/index.d.ts +2 -1
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/openai.d.ts +3 -7
- package/dist/providers/openai.d.ts.map +1 -0
- package/dist/types/index.d.ts +329 -10
- package/dist/types/index.d.ts.map +1 -0
- package/dist/utils/audio.d.ts +6 -12
- package/dist/utils/audio.d.ts.map +1 -0
- package/dist/utils/config.d.ts +16 -59
- package/dist/utils/config.d.ts.map +1 -0
- package/dist/utils/events.d.ts +20 -9
- package/dist/utils/events.d.ts.map +1 -0
- package/dist/utils/index.d.ts +2 -1
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/json.d.ts +9 -6
- package/dist/utils/json.d.ts.map +1 -0
- package/dist/utils/tokenization.d.ts +5 -16
- package/dist/utils/tokenization.d.ts.map +1 -0
- package/package.json +37 -29
- package/LICENSE +0 -21
- package/README.md +0 -160
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{logger as G,ModelType as j}from"@elizaos/core";import{logger as D}from"@elizaos/core";import{logger as U}from"@elizaos/core";function w(W,Q,$){let Z=W.getSetting(Q);if(Z!==void 0&&Z!==null)return String(Z);return process.env[Q]??$}function B(){return typeof globalThis<"u"&&"document"in globalThis&&typeof globalThis.document<"u"}function i(W){return B()&&!!w(W,"OPENAI_BROWSER_BASE_URL")}function C(W,Q=!1){if(B())return{};let $=Q?KQ(W):A(W);return $?{Authorization:`Bearer ${$}`}:{}}function V(W){let Q=w(W,"OPENAI_BROWSER_BASE_URL"),$=B()&&Q?Q:w(W,"OPENAI_BASE_URL","https://api.openai.com/v1");return U.debug(`[OpenAI] Default base URL: ${$}`),$}function n(W){let Q=B()?w(W,"OPENAI_BROWSER_EMBEDDING_URL")||w(W,"OPENAI_BROWSER_BASE_URL"):w(W,"OPENAI_EMBEDDING_URL");if(Q)return U.debug(`[OpenAI] Using specific embedding base URL: ${Q}`),Q;return U.debug("[OpenAI] Falling back to general base URL for embeddings."),V(W)}function A(W){return w(W,"OPENAI_API_KEY")}function KQ(W){let Q=w(W,"OPENAI_EMBEDDING_API_KEY");if(Q)return U.debug("[OpenAI] Using specific embedding API key (present)"),Q;return U.debug("[OpenAI] Falling back to general API key for embeddings."),A(W)}function I(W){return w(W,"OPENAI_SMALL_MODEL")??w(W,"SMALL_MODEL","gpt-4o-mini")}function P(W){return w(W,"OPENAI_LARGE_MODEL")??w(W,"LARGE_MODEL","gpt-4o")}function o(W){return w(W,"OPENAI_IMAGE_DESCRIPTION_MODEL","gpt-5-nano")}function m(W){let Q=w(W,"OPENAI_EXPERIMENTAL_TELEMETRY","false"),$=String(Q).toLowerCase(),Z=$==="true";return U.debug(`[OpenAI] Experimental telemetry in function: "${Q}" (type: ${typeof Q}, normalized: "${$}", result: ${Z})`),Z}function a(W,Q){(async()=>{try{if(!A(Q)&&!B()){D.warn("OPENAI_API_KEY is not set in environment - OpenAI functionality will be limited");return}try{let $=V(Q),Z=await fetch(`${$}/models`,{headers:C(Q)});if(!Z.ok)D.warn(`OpenAI API key validation failed: ${Z.statusText}`),D.warn("OpenAI functionality will be limited until a valid API key is provided");else D.log("OpenAI API key validated successfully")}catch($){let Z=$ instanceof Error?$.message:String($);D.warn(`Error validating OpenAI API key: ${Z}`),D.warn("OpenAI functionality will be limited until a valid API key is provided")}}catch($){let Z=$?.errors?.map((J)=>J.message).join(", ")||($ instanceof Error?$.message:String($));D.warn(`OpenAI plugin configuration issue: ${Z} - You need to configure the OPENAI_API_KEY in your environment variables`)}})()}import{logger as GQ,ModelType as t}from"@elizaos/core";import{generateText as VQ,streamText as CQ}from"ai";import{createOpenAI as jQ}from"@ai-sdk/openai";function R(W){let Q=V(W),$=A(W)??(i(W)?"sk-proxy":void 0);return jQ({apiKey:$??"",baseURL:Q})}import{EventType as wQ}from"@elizaos/core";function _(W,Q,$,Z){let J=("promptTokens"in Z?Z.promptTokens:void 0)??("inputTokens"in Z?Z.inputTokens:void 0)??0,Y=("completionTokens"in Z?Z.completionTokens:void 0)??("outputTokens"in Z?Z.outputTokens:void 0)??0,X=("totalTokens"in Z?Z.totalTokens:void 0)??J+Y,H=typeof $==="string"?$.length>200?`${$.slice(0,200)}…`:$:"";W.emitEvent(wQ.MODEL_USED,{runtime:W,source:"openai",provider:"openai",type:Q,prompt:H,tokens:{prompt:J,completion:Y,total:X}})}async function r(W,Q,$,Z){let J=R(W),Y=Z(W);GQ.debug(`[OpenAI] ${$} model: ${Y}`);let X={model:J.languageModel(Y),prompt:Q.prompt,system:W.character.system??void 0,temperature:Q.temperature??0.7,maxOutputTokens:Q.maxTokens??8192,frequencyPenalty:Q.frequencyPenalty??0.7,presencePenalty:Q.presencePenalty??0.7,stopSequences:Q.stopSequences??[],experimental_telemetry:{isEnabled:m(W)}};if(Q.stream){let q=CQ(X);return{textStream:q.textStream,text:q.text,usage:q.usage.then((F)=>F?{promptTokens:F.inputTokens??0,completionTokens:F.outputTokens??0,totalTokens:(F.inputTokens??0)+(F.outputTokens??0)}:void 0),finishReason:q.finishReason}}let{text:H,usage:K}=await VQ(X);if(K)_(W,$,Q.prompt,K);return H}async function E(W,Q){return r(W,Q,t.TEXT_SMALL,I)}async function k(W,Q){return r(W,Q,t.TEXT_LARGE,P)}import{logger as O,ModelType as OQ,VECTOR_DIMS as e}from"@elizaos/core";async function M(W,Q){let $=w(W,"OPENAI_EMBEDDING_MODEL","text-embedding-3-small"),Z=Number.parseInt(w(W,"OPENAI_EMBEDDING_DIMENSIONS","1536")||"1536",10);if(!Object.values(e).includes(Z)){let X=`Invalid embedding dimension: ${Z}. Must be one of: ${Object.values(e).join(", ")}`;throw O.error(X),Error(X)}if(Q===null){O.debug("Creating test embedding for initialization");let X=Array(Z).fill(0);return X[0]=0.1,X}let J;if(typeof Q==="string")J=Q;else if(typeof Q==="object"&&Q.text)J=Q.text;else{O.warn("Invalid input format for embedding");let H=Array(Z).fill(0);return H[0]=0.2,H}if(!J.trim()){O.warn("Empty text for embedding");let H=Array(Z).fill(0);return H[0]=0.3,H}let Y=n(W);try{let X=await fetch(`${Y}/embeddings`,{method:"POST",headers:{...C(W,!0),"Content-Type":"application/json"},body:JSON.stringify({model:$,input:J})});if(!X.ok)throw O.error(`OpenAI API error: ${X.status} - ${X.statusText}`),Error(`OpenAI API error: ${X.status} - ${X.statusText}`);let H=await X.json();if(!H?.data?.[0]?.embedding)throw O.error("API returned invalid structure"),Error("API returned invalid structure");let K=H.data[0].embedding;if(!Array.isArray(K)||K.length!==Z){let q=`Embedding length ${K?.length??0} does not match configured dimension ${Z}`;O.error(q);let F=Array(Z).fill(0);return F[0]=0.4,F}if(H.usage){let q={inputTokens:H.usage.prompt_tokens,outputTokens:0,totalTokens:H.usage.total_tokens};_(W,OQ.TEXT_EMBEDDING,J,q)}return O.log(`Got valid embedding with length ${K.length}`),K}catch(X){let H=X instanceof Error?X.message:String(X);throw O.error(`Error generating embedding: ${H}`),X instanceof Error?X:Error(H)}}import{logger as h,ModelType as _Q}from"@elizaos/core";async function f(W,Q){let $=Q.count||1,Z=Q.size||"1024x1024",J=Q.prompt,Y=w(W,"OPENAI_IMAGE_MODEL","gpt-image-1");h.log(`[OpenAI] Using IMAGE model: ${Y}`);let X=V(W);try{let H=await fetch(`${X}/images/generations`,{method:"POST",headers:{...C(W),"Content-Type":"application/json"},body:JSON.stringify({model:Y,prompt:J,n:$,size:Z})});if(!H.ok)throw Error(`Failed to generate image: ${H.statusText}`);return(await H.json()).data}catch(H){let K=H instanceof Error?H.message:String(H);throw H}}async function b(W,Q){let $,Z,J=o(W);h.log(`[OpenAI] Using IMAGE_DESCRIPTION model: ${J}`);let Y=Number.parseInt(w(W,"OPENAI_IMAGE_DESCRIPTION_MAX_TOKENS","8192")||"8192",10),X="Please analyze this image and provide a title and detailed description.";if(typeof Q==="string")$=Q,Z=X;else $=Q.imageUrl,Z=Q.prompt||X;let H=[{role:"user",content:[{type:"text",text:Z},{type:"image_url",image_url:{url:$}}]}],K=V(W);try{let q={model:J,messages:H,max_tokens:Y},F=await fetch(`${K}/chat/completions`,{method:"POST",headers:{"Content-Type":"application/json",...C(W)},body:JSON.stringify(q)});if(!F.ok)throw Error(`OpenAI API error: ${F.status}`);let x=await F.json(),S=x.choices?.[0]?.message?.content;if(x.usage)_(W,_Q.IMAGE_DESCRIPTION,typeof Q==="string"?Q:Q.prompt||"",{inputTokens:x.usage.prompt_tokens,outputTokens:x.usage.completion_tokens,totalTokens:x.usage.total_tokens});if(!S)return{title:"Failed to analyze image",description:"No response from API"};let s=S.match(/title[:\s]+(.+?)(?:\n|$)/i)?.[1]?.trim();if(!s)h.warn("Could not extract title from image description response");let HQ=s||"Image Analysis",YQ=S.replace(/title[:\s]+(.+?)(?:\n|$)/i,"").trim();return{title:HQ,description:YQ}}catch(q){let F=q instanceof Error?q.message:String(q);return h.error(`Error analyzing image: ${F}`),{title:"Failed to analyze image",description:`Error: ${F}`}}}import{logger as z}from"@elizaos/core";import{logger as IQ}from"@elizaos/core";var N={WAV:{HEADER:[82,73,70,70],IDENTIFIER:[87,65,86,69]},MP3_ID3:[73,68,51],OGG:[79,103,103,83],FLAC:[102,76,97,67],FTYP:[102,116,121,112],WEBM_EBML:[26,69,223,163]};function v(W,Q,$){for(let Z=0;Z<$.length;Z++)if(W[Q+Z]!==$[Z])return!1;return!0}function y(W){if(W.length<12)return"application/octet-stream";if(v(W,0,N.WAV.HEADER)&&v(W,8,N.WAV.IDENTIFIER))return"audio/wav";if(v(W,0,N.MP3_ID3)||W[0]===255&&(W[1]&224)===224)return"audio/mpeg";if(v(W,0,N.OGG))return"audio/ogg";if(v(W,0,N.FLAC))return"audio/flac";if(v(W,4,N.FTYP))return"audio/mp4";if(v(W,0,N.WEBM_EBML))return"audio/webm";return IQ.warn("Could not detect audio format from buffer, using generic binary type"),"application/octet-stream"}async function PQ(W,Q){let $=w(W,"OPENAI_TTS_MODEL","gpt-4o-mini-tts"),Z=w(W,"OPENAI_TTS_VOICE","nova"),J=w(W,"OPENAI_TTS_INSTRUCTIONS",""),Y=V(W),X=Q.model||$,H=Q.voice||Z,K=Q.instructions??J,q=Q.format||"mp3";try{let F=await fetch(`${Y}/audio/speech`,{method:"POST",headers:{...C(W),"Content-Type":"application/json",...q==="mp3"?{Accept:"audio/mpeg"}:{}},body:JSON.stringify({model:X,voice:H,input:Q.text,format:q,...K&&{instructions:K}})});if(!F.ok){let L=await F.text();throw Error(`OpenAI TTS error ${F.status}: ${L}`)}return await F.arrayBuffer()}catch(F){let L=F instanceof Error?F.message:String(F);throw Error(`Failed to fetch speech from OpenAI TTS: ${L}`)}}async function c(W,Q){let $=w(W,"OPENAI_TRANSCRIPTION_MODEL","gpt-4o-mini-transcribe");z.log(`[OpenAI] Using TRANSCRIPTION model: ${$}`);let Z=V(W),J,Y=null;if(Q instanceof Blob||Q instanceof File)J=Q;else if(Buffer.isBuffer(Q)){let q=y(Q);z.debug(`Auto-detected audio MIME type: ${q}`);let F=new Uint8Array(Q);J=new Blob([F],{type:q})}else if(typeof Q==="object"&&Q!==null&&Q.audio!=null){let q=Q;if(!(q.audio instanceof Blob)&&!(q.audio instanceof File)&&!Buffer.isBuffer(q.audio))throw Error("TRANSCRIPTION param 'audio' must be a Blob/File/Buffer.");if(Buffer.isBuffer(q.audio)){let F=q.mimeType;if(!F)F=y(q.audio),z.debug(`Auto-detected audio MIME type: ${F}`);else z.debug(`Using provided MIME type: ${F}`);let L=new Uint8Array(q.audio);J=new Blob([L],{type:F})}else J=q.audio;if(Y=q,typeof q.model==="string"&&q.model)$=q.model}else throw Error("TRANSCRIPTION expects a Blob/File/Buffer or an object { audio: Blob/File/Buffer, mimeType?, language?, response_format?, timestampGranularities?, prompt?, temperature?, model? }");let X=J.type||"audio/webm",H=J.name||(X.includes("mp3")||X.includes("mpeg")?"recording.mp3":X.includes("ogg")?"recording.ogg":X.includes("wav")?"recording.wav":X.includes("webm")?"recording.webm":"recording.bin"),K=new FormData;if(K.append("file",J,H),K.append("model",String($)),Y){if(typeof Y.language==="string")K.append("language",String(Y.language));if(typeof Y.response_format==="string")K.append("response_format",String(Y.response_format));if(typeof Y.prompt==="string")K.append("prompt",String(Y.prompt));if(typeof Y.temperature==="number")K.append("temperature",String(Y.temperature));if(Array.isArray(Y.timestampGranularities))for(let q of Y.timestampGranularities)K.append("timestamp_granularities[]",String(q))}try{let q=await fetch(`${Z}/audio/transcriptions`,{method:"POST",headers:{...C(W)},body:K});if(!q.ok)throw Error(`Failed to transcribe audio: ${q.status} ${q.statusText}`);return(await q.json()).text||""}catch(q){let F=q instanceof Error?q.message:String(q);throw z.error(`TRANSCRIPTION error: ${F}`),q}}async function T(W,Q){let $=typeof Q==="string"?{text:Q}:Q,Z=$.model||w(W,"OPENAI_TTS_MODEL","gpt-4o-mini-tts");z.log(`[OpenAI] Using TEXT_TO_SPEECH model: ${Z}`);try{return await PQ(W,$)}catch(J){let Y=J instanceof Error?J.message:String(J);throw z.error(`Error in TEXT_TO_SPEECH: ${Y}`),J}}import{logger as d,ModelType as WQ}from"@elizaos/core";import{generateObject as vQ}from"ai";import{logger as DQ}from"@elizaos/core";import{JSONParseError as NQ}from"ai";function QQ(){return async({text:W,error:Q})=>{try{if(Q instanceof NQ){let $=W.replace(/```json\n|\n```|```/g,"");return JSON.parse($),$}return null}catch($){let Z=$ instanceof Error?$.message:String($);return DQ.warn(`Failed to repair JSON text: ${Z}`),null}}}async function $Q(W,Q,$,Z){let J=R(W),Y=Z(W);d.log(`[OpenAI] Using ${$} model: ${Y}`);let X=Q.temperature??0;if(!!Q.schema)d.warn("Schema provided but ignored: OpenAI object generation currently uses output=no-schema. The schema parameter has no effect.");try{let{object:K,usage:q}=await vQ({model:J.languageModel(Y),output:"no-schema",prompt:Q.prompt,temperature:X,experimental_repairText:QQ()});if(q)_(W,$,Q.prompt,q);return K}catch(K){let q=K instanceof Error?K.message:String(K);throw d.error(`[generateObject] Error: ${q}`),K}}async function p(W,Q){return $Q(W,Q,WQ.OBJECT_SMALL,I)}async function l(W,Q){return $Q(W,Q,WQ.OBJECT_LARGE,P)}import{ModelType as FQ}from"@elizaos/core";import{ModelType as ZQ}from"@elizaos/core";import{encodingForModel as zQ,getEncoding as LQ}from"js-tiktoken";function qQ(W){let $=W.toLowerCase().includes("4o")?"o200k_base":"cl100k_base";try{return zQ(W)}catch(Z){return LQ($)}}async function XQ(W,Q,$){let Z=Q===ZQ.TEXT_SMALL?I(W):P(W);return qQ(Z).encode($)}async function JQ(W,Q,$){let Z=Q===ZQ.TEXT_SMALL?I(W):P(W);return qQ(Z).decode($)}async function g(W,{prompt:Q,modelType:$=FQ.TEXT_LARGE}){return await XQ(W,$,Q)}async function u(W,{tokens:Q,modelType:$=FQ.TEXT_LARGE}){return await JQ(W,$,Q)}var UQ={name:"openai",description:"OpenAI plugin",config:{OPENAI_API_KEY:process.env.OPENAI_API_KEY,OPENAI_BASE_URL:process.env.OPENAI_BASE_URL,OPENAI_SMALL_MODEL:process.env.OPENAI_SMALL_MODEL,OPENAI_LARGE_MODEL:process.env.OPENAI_LARGE_MODEL,SMALL_MODEL:process.env.SMALL_MODEL,LARGE_MODEL:process.env.LARGE_MODEL,OPENAI_EMBEDDING_MODEL:process.env.OPENAI_EMBEDDING_MODEL,OPENAI_EMBEDDING_API_KEY:process.env.OPENAI_EMBEDDING_API_KEY,OPENAI_EMBEDDING_URL:process.env.OPENAI_EMBEDDING_URL,OPENAI_EMBEDDING_DIMENSIONS:process.env.OPENAI_EMBEDDING_DIMENSIONS,OPENAI_IMAGE_DESCRIPTION_MODEL:process.env.OPENAI_IMAGE_DESCRIPTION_MODEL,OPENAI_IMAGE_DESCRIPTION_MAX_TOKENS:process.env.OPENAI_IMAGE_DESCRIPTION_MAX_TOKENS,OPENAI_EXPERIMENTAL_TELEMETRY:process.env.OPENAI_EXPERIMENTAL_TELEMETRY},async init(W,Q){a(W,Q)},models:{[j.TEXT_EMBEDDING]:async(W,Q)=>{return M(W,Q)},[j.TEXT_TOKENIZER_ENCODE]:async(W,Q)=>{return g(W,Q)},[j.TEXT_TOKENIZER_DECODE]:async(W,Q)=>{return u(W,Q)},[j.TEXT_SMALL]:async(W,Q)=>{return E(W,Q)},[j.TEXT_LARGE]:async(W,Q)=>{return k(W,Q)},[j.IMAGE]:async(W,Q)=>{return f(W,Q)},[j.IMAGE_DESCRIPTION]:async(W,Q)=>{return b(W,Q)},[j.TRANSCRIPTION]:async(W,Q)=>{return c(W,Q)},[j.TEXT_TO_SPEECH]:async(W,Q)=>{return T(W,Q)},[j.OBJECT_SMALL]:async(W,Q)=>{return p(W,Q)},[j.OBJECT_LARGE]:async(W,Q)=>{return l(W,Q)}},tests:[{name:"openai_plugin_tests",tests:[{name:"openai_test_url_and_api_key_validation",fn:async(W)=>{let Q=V(W),$=await fetch(`${Q}/models`,{headers:C(W)}),Z=await $.json();if(G.log({data:Z?.data?.length??"N/A"},"Models Available"),!$.ok)throw Error(`Failed to validate OpenAI API key: ${$.statusText}`)}},{name:"openai_test_text_embedding",fn:async(W)=>{try{let Q=await W.useModel(j.TEXT_EMBEDDING,{text:"Hello, world!"});G.log({embedding:Q},"embedding")}catch(Q){let $=Q instanceof Error?Q.message:String(Q);throw G.error(`Error in test_text_embedding: ${$}`),Q}}},{name:"openai_test_text_large",fn:async(W)=>{try{let Q=await W.useModel(j.TEXT_LARGE,{prompt:"What is the nature of reality in 10 words?"});if(Q.length===0)throw Error("Failed to generate text");G.log({text:Q},"generated with test_text_large")}catch(Q){let $=Q instanceof Error?Q.message:String(Q);throw G.error(`Error in test_text_large: ${$}`),Q}}},{name:"openai_test_text_small",fn:async(W)=>{try{let Q=await W.useModel(j.TEXT_SMALL,{prompt:"What is the nature of reality in 10 words?"});if(Q.length===0)throw Error("Failed to generate text");G.log({text:Q},"generated with test_text_small")}catch(Q){let $=Q instanceof Error?Q.message:String(Q);throw G.error(`Error in test_text_small: ${$}`),Q}}},{name:"openai_test_image_generation",fn:async(W)=>{G.log("openai_test_image_generation");try{let Q=await W.useModel(j.IMAGE,{prompt:"A beautiful sunset over a calm ocean",count:1,size:"1024x1024"});G.log({image:Q},"generated with test_image_generation")}catch(Q){let $=Q instanceof Error?Q.message:String(Q);throw G.error(`Error in test_image_generation: ${$}`),Q}}},{name:"image-description",fn:async(W)=>{try{G.log("openai_test_image_description");try{let Q=await W.useModel(j.IMAGE_DESCRIPTION,"https://upload.wikimedia.org/wikipedia/commons/thumb/1/1c/Vitalik_Buterin_TechCrunch_London_2015_%28cropped%29.jpg/537px-Vitalik_Buterin_TechCrunch_London_2015_%28cropped%29.jpg");if(Q&&typeof Q==="object"&&"title"in Q&&"description"in Q)G.log({result:Q},"Image description");else G.error("Invalid image description result format:",Q)}catch(Q){let $=Q instanceof Error?Q.message:String(Q);G.error(`Error in image description test: ${$}`)}}catch(Q){let $=Q instanceof Error?Q.message:String(Q);G.error(`Error in openai_test_image_description: ${$}`)}}},{name:"openai_test_transcription",fn:async(W)=>{G.log("openai_test_transcription");try{let $=await(await fetch("https://upload.wikimedia.org/wikipedia/en/4/40/Chris_Benoit_Voice_Message.ogg")).arrayBuffer(),Z=await W.useModel(j.TRANSCRIPTION,Buffer.from(new Uint8Array($)));G.log({transcription:Z},"generated with test_transcription")}catch(Q){let $=Q instanceof Error?Q.message:String(Q);throw G.error(`Error in test_transcription: ${$}`),Q}}},{name:"openai_test_text_tokenizer_encode",fn:async(W)=>{let $=await W.useModel(j.TEXT_TOKENIZER_ENCODE,{prompt:"Hello tokenizer encode!",modelType:j.TEXT_SMALL});if(!Array.isArray($)||$.length===0)throw Error("Failed to tokenize text: expected non-empty array of tokens");G.log({tokens:$},"Tokenized output")}},{name:"openai_test_text_tokenizer_decode",fn:async(W)=>{let $=await W.useModel(j.TEXT_TOKENIZER_ENCODE,{prompt:"Hello tokenizer decode!",modelType:j.TEXT_SMALL}),Z=await W.useModel(j.TEXT_TOKENIZER_DECODE,{tokens:$,modelType:j.TEXT_SMALL});if(Z!=="Hello tokenizer decode!")throw Error(`Decoded text does not match original. Expected "Hello tokenizer decode!", got "${Z}"`);G.log({decodedText:Z},"Decoded text")}},{name:"openai_test_text_to_speech",fn:async(W)=>{try{if(!await W.useModel(j.TEXT_TO_SPEECH,{text:"Hello, this is a test for text-to-speech."}))throw Error("Failed to generate speech");G.log("Generated speech successfully")}catch(Q){let $=Q instanceof Error?Q.message:String(Q);throw G.error(`Error in openai_test_text_to_speech: ${$}`),Q}}},{name:"openai_test_text_generation_large",fn:async(W)=>{try{let Q=await W.useModel(j.TEXT_LARGE,{prompt:"Say hello in 5 words."});if(!Q||Q.length===0)throw Error("Text generation returned empty result");G.log({result:Q},"Text generation test completed")}catch(Q){let $=Q instanceof Error?Q.message:String(Q);throw G.error(`Error in openai_test_text_generation_large: ${$}`),Q}}},{name:"openai_test_streaming",fn:async(W)=>{try{let Q=[],$=await W.useModel(j.TEXT_LARGE,{prompt:"Count from 1 to 5.",onStreamChunk:(Z)=>{Q.push(Z)}});if(!$||$.length===0)throw Error("Streaming returned empty result");if(Q.length===0)throw Error("No streaming chunks received");G.log({chunks:Q.length,result:$.substring(0,50)},"Streaming test completed")}catch(Q){let $=Q instanceof Error?Q.message:String(Q);throw G.error(`Error in openai_test_streaming: ${$}`),Q}}}]}]},BQ=UQ;export{UQ as openaiPlugin,BQ as default};
|
|
1
|
+
import{logger as l,ModelType as P}from"@elizaos/core";import{logger as L}from"@elizaos/core";import{logger as _}from"@elizaos/core";function Lo(o){if(typeof process>"u"||!process.env)return;let n=process.env[o];return n===void 0?void 0:String(n)}function w(o,n,c){let r=o.getSetting(n);if(r!==void 0&&r!==null)return String(r);return Lo(n)??c}function x(o,n,c){let r=w(o,n);if(r===void 0)return c;let f=Number.parseInt(r,10);if(!Number.isFinite(f))throw Error(`Setting '${n}' must be a valid integer, got: ${r}`);return f}function v(o,n,c){let r=w(o,n);if(r===void 0)return c;let f=r.toLowerCase();return f==="true"||f==="1"||f==="yes"}function j(){return typeof globalThis<"u"&&typeof globalThis.document<"u"}function g(o){return j()&&!!w(o,"OPENAI_BROWSER_BASE_URL")}function y(o){return w(o,"OPENAI_API_KEY")}function Ko(o){let n=w(o,"OPENAI_EMBEDDING_API_KEY");if(n)return _.debug("[OpenAI] Using specific embedding API key"),n;return _.debug("[OpenAI] Falling back to general API key for embeddings"),y(o)}function R(o,n=!1){if(j()&&!v(o,"OPENAI_ALLOW_BROWSER_API_KEY",!1))return{};let c=n?Ko(o):y(o);return c?{Authorization:`Bearer ${c}`}:{}}function O(o){let n=w(o,"OPENAI_BROWSER_BASE_URL"),c=j()&&n?n:w(o,"OPENAI_BASE_URL")??"https://api.openai.com/v1";return _.debug(`[OpenAI] Base URL: ${c}`),c}function u(o){let n=j()?w(o,"OPENAI_BROWSER_EMBEDDING_URL")??w(o,"OPENAI_BROWSER_BASE_URL"):w(o,"OPENAI_EMBEDDING_URL");if(n)return _.debug(`[OpenAI] Using embedding base URL: ${n}`),n;return _.debug("[OpenAI] Falling back to general base URL for embeddings"),O(o)}function F(o){return w(o,"OPENAI_SMALL_MODEL")??w(o,"SMALL_MODEL")??"gpt-5-mini"}function d(o){return w(o,"OPENAI_LARGE_MODEL")??w(o,"LARGE_MODEL")??"gpt-5"}function m(o){return w(o,"OPENAI_EMBEDDING_MODEL")??"text-embedding-3-small"}function oo(o){return w(o,"OPENAI_IMAGE_DESCRIPTION_MODEL")??"gpt-5-mini"}function no(o){return w(o,"OPENAI_TRANSCRIPTION_MODEL")??"gpt-5-mini-transcribe"}function co(o){return w(o,"OPENAI_TTS_MODEL")??"tts-1"}function ro(o){return w(o,"OPENAI_TTS_VOICE")??"nova"}function fo(o){return w(o,"OPENAI_TTS_INSTRUCTIONS")??""}function To(o){return w(o,"OPENAI_IMAGE_MODEL")??"dall-e-3"}function io(o){return v(o,"OPENAI_EXPERIMENTAL_TELEMETRY",!1)}function ko(o){return x(o,"OPENAI_EMBEDDING_DIMENSIONS",1536)}function Ao(o){return x(o,"OPENAI_IMAGE_DESCRIPTION_MAX_TOKENS",8192)}function to(o){return w(o,"OPENAI_RESEARCH_MODEL")??"o3-deep-research"}function Io(o){return x(o,"OPENAI_RESEARCH_TIMEOUT",3600000)}globalThis.AI_SDK_LOG_WARNINGS??=!1;function Po(o,n){xo(n)}async function xo(o){if(j()){L.debug("[OpenAI] Skipping API validation in browser environment");return}if(!y(o)){L.warn("[OpenAI] OPENAI_API_KEY is not configured. OpenAI functionality will fail until a valid API key is provided.");return}try{let c=O(o),r=await fetch(`${c}/models`,{headers:R(o)});if(!r.ok){L.warn(`[OpenAI] API key validation failed: ${r.status} ${r.statusText}. Please verify your OPENAI_API_KEY is correct.`);return}}catch(c){let r=c instanceof Error?c.message:String(c);L.warn(`[OpenAI] API validation error: ${r}. OpenAI functionality may be limited.`)}}import{logger as U}from"@elizaos/core";import{logger as Xo}from"@elizaos/core";var $={WAV:{HEADER:[82,73,70,70],IDENTIFIER:[87,65,86,69]},MP3_ID3:[73,68,51],OGG:[79,103,103,83],FLAC:[102,76,97,67],FTYP:[102,116,121,112],WEBM_EBML:[26,69,223,163]},Do=12;function b(o,n,c){for(let r=0;r<c.length;r++){let f=c[r];if(f===void 0||o[n+r]!==f)return!1}return!0}function X(o){if(o.length<Do)return"application/octet-stream";if(b(o,0,$.WAV.HEADER)&&b(o,8,$.WAV.IDENTIFIER))return"audio/wav";let n=o[0],c=o[1];if(b(o,0,$.MP3_ID3)||n===255&&c!==void 0&&(c&224)===224)return"audio/mpeg";if(b(o,0,$.OGG))return"audio/ogg";if(b(o,0,$.FLAC))return"audio/flac";if(b(o,4,$.FTYP))return"audio/mp4";if(b(o,0,$.WEBM_EBML))return"audio/webm";return Xo.warn("Could not detect audio format from buffer, using generic binary type"),"application/octet-stream"}function Wo(o){switch(o){case"audio/wav":return"wav";case"audio/mpeg":return"mp3";case"audio/ogg":return"ogg";case"audio/flac":return"flac";case"audio/mp4":return"m4a";case"audio/webm":return"webm";case"application/octet-stream":return"bin"}}function po(o){return`recording.${Wo(o)}`}function so(o){return o instanceof Blob||o instanceof File}function D(o){return Buffer.isBuffer(o)}function Co(o){return typeof o==="object"&&o!==null&&"audio"in o&&(so(o.audio)||D(o.audio))}function Ho(o){return typeof o==="object"&&o!==null&&"audioUrl"in o&&typeof o.audioUrl==="string"}async function wo(o){let n=await fetch(o);if(!n.ok)throw Error(`Failed to fetch audio from URL: ${n.status}`);return n.blob()}async function W(o,n){let c=no(o),r,f={};if(typeof n==="string")U.debug(`[OpenAI] Fetching audio from URL: ${n}`),r=await wo(n);else if(so(n))r=n;else if(D(n)){let I=X(n);U.debug(`[OpenAI] Auto-detected audio MIME type: ${I}`),r=new Blob([new Uint8Array(n)],{type:I})}else if(Co(n)){if(f=n,n.model)c=n.model;if(D(n.audio)){let I=n.mimeType??X(n.audio);U.debug(`[OpenAI] Using MIME type: ${I}`),r=new Blob([new Uint8Array(n.audio)],{type:I})}else r=n.audio}else if(Ho(n))U.debug(`[OpenAI] Fetching audio from URL: ${n.audioUrl}`),r=await wo(n.audioUrl),f={prompt:n.prompt};else throw Error("TRANSCRIPTION expects Blob, File, Buffer, URL string, or TranscriptionParams object");U.debug(`[OpenAI] Using TRANSCRIPTION model: ${c}`);let T=r.type||"audio/webm",A=r.name||po(T.startsWith("audio/")?T:"audio/webm"),k=new FormData;if(k.append("file",r,A),k.append("model",c),f.language)k.append("language",f.language);if(f.responseFormat)k.append("response_format",f.responseFormat);if(f.prompt)k.append("prompt",f.prompt);if(f.temperature!==void 0)k.append("temperature",String(f.temperature));if(f.timestampGranularities)for(let I of f.timestampGranularities)k.append("timestamp_granularities[]",I);let t=O(o),i=await fetch(`${t}/audio/transcriptions`,{method:"POST",headers:R(o),body:k});if(!i.ok){let I=await i.text().catch(()=>"Unknown error");throw Error(`OpenAI transcription failed: ${i.status} ${i.statusText} - ${I}`)}return(await i.json()).text}async function C(o,n){let c,r,f="mp3",T,A;if(typeof n==="string")c=n,r=void 0;else{if(c=n.text,r=n.voice,"format"in n&&n.format)f=n.format;if("model"in n&&n.model)T=n.model;if("instructions"in n&&n.instructions)A=n.instructions}if(T=T??co(o),r=r??ro(o),A=A??fo(o),U.debug(`[OpenAI] Using TEXT_TO_SPEECH model: ${T}`),!c||c.trim().length===0)throw Error("TEXT_TO_SPEECH requires non-empty text");if(c.length>4096)throw Error("TEXT_TO_SPEECH text exceeds 4096 character limit");let k=["alloy","echo","fable","onyx","nova","shimmer"];if(r&&!k.includes(r))throw Error(`Invalid voice: ${r}. Must be one of: ${k.join(", ")}`);let t=O(o),i={model:T,voice:r,input:c,response_format:f};if(A&&A.length>0)i.instructions=A;let p=await fetch(`${t}/audio/speech`,{method:"POST",headers:{...R(o),"Content-Type":"application/json",...f==="mp3"?{Accept:"audio/mpeg"}:{}},body:JSON.stringify(i)});if(!p.ok){let I=await p.text().catch(()=>"Unknown error");throw Error(`OpenAI TTS failed: ${p.status} ${p.statusText} - ${I}`)}return p.arrayBuffer()}import{logger as K,ModelType as Zo,VECTOR_DIMS as Yo}from"@elizaos/core";import{EventType as Vo}from"@elizaos/core";var Oo=200;function Qo(o){if(o.length<=Oo)return o;return`${o.slice(0,Oo)}…`}function Go(o){if("promptTokens"in o){let n="promptTokensDetails"in o?o.promptTokensDetails:void 0,c=o.cachedPromptTokens??n?.cachedTokens;return{promptTokens:o.promptTokens??0,completionTokens:o.completionTokens??0,totalTokens:o.totalTokens??(o.promptTokens??0)+(o.completionTokens??0),cachedPromptTokens:c}}if("inputTokens"in o||"outputTokens"in o){let n=o.inputTokens??0,c=o.outputTokens??0,r=o.totalTokens??n+c;return{promptTokens:n,completionTokens:c,totalTokens:r,cachedPromptTokens:o.cachedInputTokens}}return{promptTokens:0,completionTokens:0,totalTokens:0}}function J(o,n,c,r){let f=Go(r),T={runtime:o,source:"openai",provider:"openai",type:n,prompt:Qo(c),tokens:{prompt:f.promptTokens,completion:f.completionTokens,total:f.totalTokens,...f.cachedPromptTokens!==void 0?{cached:f.cachedPromptTokens}:{}}};o.emitEvent(Vo.MODEL_USED,T)}function qo(o){let n=Object.values(Yo);if(!n.includes(o))throw Error(`Invalid embedding dimension: ${o}. Must be one of: ${n.join(", ")}`);return o}function Mo(o){if(o===null)return null;if(typeof o==="string")return o;if(typeof o==="object"&&typeof o.text==="string")return o.text;throw Error("Invalid embedding params: expected string, { text: string }, or null")}async function H(o,n){let c=m(o),r=qo(ko(o)),f=Mo(n);if(f===null){K.debug("[OpenAI] Creating test embedding for initialization");let N=Array(r).fill(0);return N[0]=0.1,N}let T=f.trim();if(T.length===0)throw Error("Cannot generate embedding for empty text");let A=32000;if(T.length>A)K.warn(`[OpenAI] Embedding input too long (~${Math.ceil(T.length/4)} tokens), truncating to ~8000 tokens`),T=T.slice(0,A);let t=`${u(o)}/embeddings`;K.debug(`[OpenAI] Generating embedding with model: ${c}`);let i=await fetch(t,{method:"POST",headers:{...R(o,!0),"Content-Type":"application/json"},body:JSON.stringify({model:c,input:T})});if(!i.ok){let N=await i.text().catch(()=>"Unknown error");throw Error(`OpenAI embedding API error: ${i.status} ${i.statusText} - ${N}`)}let p=await i.json(),I=p?.data?.[0];if(!I||!I.embedding)throw Error("OpenAI API returned invalid embedding response structure");let s=I.embedding;if(s.length!==r)throw Error(`Embedding dimension mismatch: got ${s.length}, expected ${r}. Check OPENAI_EMBEDDING_DIMENSIONS setting.`);if(p.usage)J(o,Zo.TEXT_EMBEDDING,T,{promptTokens:p.usage.prompt_tokens,completionTokens:0,totalTokens:p.usage.total_tokens});return K.debug(`[OpenAI] Generated embedding with ${s.length} dimensions`),s}import{logger as Ro,ModelType as eo}from"@elizaos/core";var ho="Please analyze this image and provide a title and detailed description.";async function V(o,n){let c=To(o),r=n.count??1,f=n.size??"1024x1024",T=n;if(Ro.debug(`[OpenAI] Using IMAGE model: ${c}`),!n.prompt||n.prompt.trim().length===0)throw Error("IMAGE generation requires a non-empty prompt");if(r<1||r>10)throw Error("IMAGE count must be between 1 and 10");let A=O(o),k={model:c,prompt:n.prompt,n:r,size:f};if(T.quality)k.quality=T.quality;if(T.style)k.style=T.style;let t=await fetch(`${A}/images/generations`,{method:"POST",headers:{...R(o),"Content-Type":"application/json"},body:JSON.stringify(k)});if(!t.ok){let p=await t.text().catch(()=>"Unknown error");throw Error(`OpenAI image generation failed: ${t.status} ${t.statusText} - ${p}`)}let i=await t.json();if(!i.data||i.data.length===0)throw Error("OpenAI API returned no images");return i.data.map((p)=>({url:p.url,revisedPrompt:p.revised_prompt}))}function Bo(o){return o.match(/title[:\s]+(.+?)(?:\n|$)/i)?.[1]?.trim()??"Image Analysis"}function ao(o){return o.replace(/title[:\s]+(.+?)(?:\n|$)/i,"").trim()}async function Q(o,n){let c=oo(o),r=Ao(o);Ro.debug(`[OpenAI] Using IMAGE_DESCRIPTION model: ${c}`);let f,T;if(typeof n==="string")f=n,T=ho;else f=n.imageUrl,T=n.prompt??ho;if(!f||f.trim().length===0)throw Error("IMAGE_DESCRIPTION requires a valid image URL");let A=O(o),k={model:c,messages:[{role:"user",content:[{type:"text",text:T},{type:"image_url",image_url:{url:f}}]}],max_tokens:r},t=await fetch(`${A}/chat/completions`,{method:"POST",headers:{...R(o),"Content-Type":"application/json"},body:JSON.stringify(k)});if(!t.ok){let s=await t.text().catch(()=>"Unknown error");throw Error(`OpenAI image description failed: ${t.status} ${t.statusText} - ${s}`)}let i=await t.json();if(i.usage)J(o,eo.IMAGE_DESCRIPTION,typeof n==="string"?n:n.prompt??"",{promptTokens:i.usage.prompt_tokens,completionTokens:i.usage.completion_tokens,totalTokens:i.usage.total_tokens});let I=i.choices?.[0]?.message?.content;if(!I)throw Error("OpenAI API returned empty image description");return{title:Bo(I),description:ao(I)}}import{logger as Jo,ModelType as Eo}from"@elizaos/core";import{generateObject as mo}from"ai";import{createOpenAI as lo}from"@ai-sdk/openai";var vo="sk-proxy";function z(o){let n=O(o),c=y(o);if(!c&&g(o))return lo({apiKey:vo,baseURL:n});if(!c)throw Error("OPENAI_API_KEY is required. Set it in your environment variables or runtime settings.");return lo({apiKey:c,baseURL:n})}import{logger as No}from"@elizaos/core";import{JSONParseError as go}from"ai";var uo={MARKDOWN_JSON:/```json\n|\n```|```/g,WHITESPACE:/^\s+|\s+$/g};function yo(){return async({text:o,error:n})=>{if(!(n instanceof go))return null;try{let c=o.replace(uo.MARKDOWN_JSON,"");return JSON.parse(c),No.debug("[JSON Repair] Successfully repaired JSON by removing markdown wrappers"),c}catch{return No.warn("[JSON Repair] Unable to repair JSON text"),null}}}async function So(o,n,c,r){let f=z(o),T=r(o);if(Jo.debug(`[OpenAI] Using ${c} model: ${T}`),!n.prompt||n.prompt.trim().length===0)throw Error("Object generation requires a non-empty prompt");if(n.schema)Jo.debug("[OpenAI] Schema provided but using no-schema mode. Structure is determined by prompt instructions.");let A=f.chat(T),{object:k,usage:t}=await mo({model:A,output:"no-schema",prompt:n.prompt,experimental_repairText:yo()});if(t)J(o,c,n.prompt,t);if(typeof k!=="object"||k===null)throw Error(`Object generation returned ${typeof k}, expected object`);return k}async function G(o,n){return So(o,n,Eo.OBJECT_SMALL,F)}async function Z(o,n){return So(o,n,Eo.OBJECT_LARGE,d)}import{logger as E}from"@elizaos/core";function on(o){switch(o.type){case"web_search_preview":return{type:"web_search_preview"};case"file_search":return{type:"file_search",vector_store_ids:o.vectorStoreIds};case"code_interpreter":return{type:"code_interpreter",container:o.container??{type:"auto"}};case"mcp":return{type:"mcp",server_label:o.serverLabel,server_url:o.serverUrl,require_approval:o.requireApproval??"never"};default:throw Error(`Unknown research tool type: ${o.type}`)}}function nn(o){switch(o.type){case"web_search_call":return{id:o.id??"",type:"web_search_call",status:o.status??"completed",action:{type:o.action?.type??"search",query:o.action?.query,url:o.action?.url}};case"file_search_call":return{id:o.id??"",type:"file_search_call",status:o.status??"completed",query:o.query??"",results:o.results?.map((n)=>({fileId:n.file_id,fileName:n.file_name,score:n.score}))};case"code_interpreter_call":return{id:o.id??"",type:"code_interpreter_call",status:o.status??"completed",code:o.code??"",output:o.output};case"mcp_tool_call":return{id:o.id??"",type:"mcp_tool_call",status:o.status??"completed",serverLabel:o.server_label??"",toolName:o.tool_name??"",arguments:o.arguments??{},result:o.result};case"message":return{type:"message",content:o.content?.map((n)=>({type:"output_text",text:n.text,annotations:n.annotations?.map((c)=>({url:c.url,title:c.title,startIndex:c.start_index,endIndex:c.end_index}))??[]}))??[]};default:return null}}function cn(o){if(o.output_text){let r=[];if(o.output){for(let f of o.output)if(f.type==="message"&&f.content){for(let T of f.content)if(T.annotations)for(let A of T.annotations)r.push({url:A.url,title:A.title,startIndex:A.start_index,endIndex:A.end_index})}}return{text:o.output_text,annotations:r}}let n="",c=[];if(o.output){for(let r of o.output)if(r.type==="message"&&r.content){for(let f of r.content)if(n+=f.text,f.annotations)for(let T of f.annotations)c.push({url:T.url,title:T.title,startIndex:T.start_index,endIndex:T.end_index})}}return{text:n,annotations:c}}async function Y(o,n){let c=y(o);if(!c)throw Error("OPENAI_API_KEY is required for deep research. Set it in your environment variables or runtime settings.");let r=O(o),f=n.model??to(o),T=Io(o);E.debug(`[OpenAI] Starting deep research with model: ${f}`),E.debug(`[OpenAI] Research input: ${n.input.substring(0,100)}...`);let A=n.tools?.filter((S)=>S.type==="web_search_preview"||S.type==="file_search"||S.type==="mcp");if(!A||A.length===0)E.debug("[OpenAI] No data source tools specified, defaulting to web_search_preview"),n.tools=[{type:"web_search_preview"},...n.tools??[]];let k={model:f,input:n.input};if(n.instructions)k.instructions=n.instructions;if(n.background!==void 0)k.background=n.background;if(n.tools&&n.tools.length>0)k.tools=n.tools.map(on);if(n.maxToolCalls!==void 0)k.max_tool_calls=n.maxToolCalls;if(n.reasoningSummary)k.reasoning={summary:n.reasoningSummary};E.debug(`[OpenAI] Research request body: ${JSON.stringify(k,null,2)}`);let t=await fetch(`${r}/responses`,{method:"POST",headers:{Authorization:`Bearer ${c}`,"Content-Type":"application/json"},body:JSON.stringify(k),signal:AbortSignal.timeout(T)});if(!t.ok){let S=await t.text();throw E.error(`[OpenAI] Research request failed: ${t.status} ${S}`),Error(`Deep research request failed: ${t.status} ${t.statusText}`)}let i=await t.json();if(i.error)throw E.error(`[OpenAI] Research API error: ${i.error.message}`),Error(`Deep research error: ${i.error.message}`);E.debug(`[OpenAI] Research response received. Status: ${i.status??"completed"}`);let{text:p,annotations:I}=cn(i),s=[];if(i.output)for(let S of i.output){let a=nn(S);if(a)s.push(a)}let N={id:i.id,text:p,annotations:I,outputItems:s,status:i.status};return E.info(`[OpenAI] Research completed. Text length: ${p.length}, Annotations: ${I.length}, Output items: ${s.length}`),N}import{logger as rn,ModelType as $o}from"@elizaos/core";import{generateText as fn,streamText as Tn}from"ai";function kn(o){if(!o)return;let n=o.inputTokens??0,c=o.outputTokens??0,r=o;return{promptTokens:n,completionTokens:c,totalTokens:n+c,cachedPromptTokens:r.cachedInputTokens}}function An(o){let n=o;return{promptCacheKey:n.providerOptions?.openai?.promptCacheKey,promptCacheRetention:n.providerOptions?.openai?.promptCacheRetention}}async function bo(o,n,c,r){let f=z(o),T=r(o);rn.debug(`[OpenAI] Using ${c} model: ${T}`);let A=An(n),k=o.character.system??void 0,i={model:f.chat(T),prompt:n.prompt,system:k,maxOutputTokens:n.maxTokens??8192,experimental_telemetry:{isEnabled:io(o)},...A.promptCacheKey||A.promptCacheRetention?{providerOptions:{openai:{...A.promptCacheKey?{promptCacheKey:A.promptCacheKey}:{},...A.promptCacheRetention?{promptCacheRetention:A.promptCacheRetention}:{}}}}:{}};if(n.stream){let s=Tn(i);return{textStream:s.textStream,text:Promise.resolve(s.text),usage:Promise.resolve(s.usage).then(kn),finishReason:Promise.resolve(s.finishReason).then((N)=>N)}}let{text:p,usage:I}=await fn(i);if(I)J(o,c,n.prompt,I);return p}async function q(o,n){return bo(o,n,$o.TEXT_SMALL,F)}async function M(o,n){return bo(o,n,$o.TEXT_LARGE,d)}import{ModelType as zo}from"@elizaos/core";import{ModelType as tn}from"@elizaos/core";import{encodingForModel as In,getEncoding as Pn}from"js-tiktoken";function jo(o){let c=o.toLowerCase().includes("4o")?"o200k_base":"cl100k_base";try{return In(o)}catch{return Pn(c)}}function Fo(o,n){if(n===tn.TEXT_SMALL)return F(o);return d(o)}function Uo(o,n,c){let r=Fo(o,n);return jo(r).encode(c)}function _o(o,n,c){let r=Fo(o,n);return jo(r).decode(c)}async function e(o,n){if(!n.prompt)throw Error("Tokenization requires a non-empty prompt");let c=n.modelType??zo.TEXT_LARGE;return Uo(o,c,n.prompt)}async function B(o,n){if(!n.tokens||!Array.isArray(n.tokens))throw Error("Detokenization requires a valid tokens array");if(n.tokens.length===0)return"";for(let r=0;r<n.tokens.length;r++){let f=n.tokens[r];if(typeof f!=="number"||!Number.isFinite(f))throw Error(`Invalid token at index ${r}: expected number`)}let c=n.modelType??zo.TEXT_LARGE;return _o(o,c,n.tokens)}function pn(){if(typeof process>"u")return{};return process.env}var h=pn(),wn={name:"openai",description:"OpenAI API integration for text, image, audio, and embedding models",config:{OPENAI_API_KEY:h.OPENAI_API_KEY??null,OPENAI_BASE_URL:h.OPENAI_BASE_URL??null,OPENAI_SMALL_MODEL:h.OPENAI_SMALL_MODEL??null,OPENAI_LARGE_MODEL:h.OPENAI_LARGE_MODEL??null,SMALL_MODEL:h.SMALL_MODEL??null,LARGE_MODEL:h.LARGE_MODEL??null,OPENAI_EMBEDDING_MODEL:h.OPENAI_EMBEDDING_MODEL??null,OPENAI_EMBEDDING_API_KEY:h.OPENAI_EMBEDDING_API_KEY??null,OPENAI_EMBEDDING_URL:h.OPENAI_EMBEDDING_URL??null,OPENAI_EMBEDDING_DIMENSIONS:h.OPENAI_EMBEDDING_DIMENSIONS??null,OPENAI_IMAGE_DESCRIPTION_MODEL:h.OPENAI_IMAGE_DESCRIPTION_MODEL??null,OPENAI_IMAGE_DESCRIPTION_MAX_TOKENS:h.OPENAI_IMAGE_DESCRIPTION_MAX_TOKENS??null,OPENAI_EXPERIMENTAL_TELEMETRY:h.OPENAI_EXPERIMENTAL_TELEMETRY??null,OPENAI_RESEARCH_MODEL:h.OPENAI_RESEARCH_MODEL??null,OPENAI_RESEARCH_TIMEOUT:h.OPENAI_RESEARCH_TIMEOUT??null},async init(o,n){Po(o,n)},models:{[P.TEXT_EMBEDDING]:async(o,n)=>{return H(o,n)},[P.TEXT_TOKENIZER_ENCODE]:async(o,n)=>{return e(o,n)},[P.TEXT_TOKENIZER_DECODE]:async(o,n)=>{return B(o,n)},[P.TEXT_SMALL]:async(o,n)=>{return q(o,n)},[P.TEXT_LARGE]:async(o,n)=>{return M(o,n)},[P.IMAGE]:async(o,n)=>{return V(o,n)},[P.IMAGE_DESCRIPTION]:async(o,n)=>{return Q(o,n)},[P.TRANSCRIPTION]:async(o,n)=>{return W(o,n)},[P.TEXT_TO_SPEECH]:async(o,n)=>{return C(o,n)},[P.OBJECT_SMALL]:async(o,n)=>{return G(o,n)},[P.OBJECT_LARGE]:async(o,n)=>{return Z(o,n)},[P.RESEARCH]:async(o,n)=>{return Y(o,n)}},tests:[{name:"openai_plugin_tests",tests:[{name:"openai_test_api_connectivity",fn:async(o)=>{let n=O(o),c=await fetch(`${n}/models`,{headers:R(o)});if(!c.ok)throw Error(`API connectivity test failed: ${c.status} ${c.statusText}`);let r=await c.json();l.info(`[OpenAI Test] API connected. ${r.data?.length??0} models available.`)}},{name:"openai_test_text_embedding",fn:async(o)=>{let n=await o.useModel(P.TEXT_EMBEDDING,{text:"Hello, world!"});if(!Array.isArray(n)||n.length===0)throw Error("Embedding should return a non-empty array");l.info(`[OpenAI Test] Generated embedding with ${n.length} dimensions`)}},{name:"openai_test_text_small",fn:async(o)=>{let n=await o.useModel(P.TEXT_SMALL,{prompt:"Say hello in exactly 5 words."});if(typeof n!=="string"||n.length===0)throw Error("TEXT_SMALL should return non-empty string");l.info(`[OpenAI Test] TEXT_SMALL generated: "${n.substring(0,50)}..."`)}},{name:"openai_test_text_large",fn:async(o)=>{let n=await o.useModel(P.TEXT_LARGE,{prompt:"Explain quantum computing in 2 sentences."});if(typeof n!=="string"||n.length===0)throw Error("TEXT_LARGE should return non-empty string");l.info(`[OpenAI Test] TEXT_LARGE generated: "${n.substring(0,50)}..."`)}},{name:"openai_test_tokenizer_roundtrip",fn:async(o)=>{let c=await o.useModel(P.TEXT_TOKENIZER_ENCODE,{prompt:"Hello, tokenizer test!",modelType:P.TEXT_SMALL});if(!Array.isArray(c)||c.length===0)throw Error("Tokenization should return non-empty token array");let r=await o.useModel(P.TEXT_TOKENIZER_DECODE,{tokens:c,modelType:P.TEXT_SMALL});if(r!=="Hello, tokenizer test!")throw Error(`Tokenizer roundtrip failed: expected "Hello, tokenizer test!", got "${r}"`);l.info(`[OpenAI Test] Tokenizer roundtrip successful (${c.length} tokens)`)}},{name:"openai_test_streaming",fn:async(o)=>{let n=[],c=await o.useModel(P.TEXT_LARGE,{prompt:"Count from 1 to 5, one number per line.",stream:!0,onStreamChunk:(r)=>{n.push(r)}});if(typeof c!=="string"||c.length===0)throw Error("Streaming should return non-empty result");if(n.length===0)throw Error("No streaming chunks received");l.info(`[OpenAI Test] Streaming test: ${n.length} chunks received`)}},{name:"openai_test_image_description",fn:async(o)=>{let c=await o.useModel(P.IMAGE_DESCRIPTION,"https://upload.wikimedia.org/wikipedia/commons/thumb/a/a7/Camponotus_flavomarginatus_ant.jpg/440px-Camponotus_flavomarginatus_ant.jpg");if(!c||typeof c!=="object"||!("title"in c)||!("description"in c))throw Error("Image description should return { title, description }");l.info(`[OpenAI Test] Image described: "${c.title}"`)}},{name:"openai_test_transcription",fn:async(o)=>{let r=await(await fetch("https://upload.wikimedia.org/wikipedia/commons/2/25/En-Open_Source.ogg")).arrayBuffer(),f=Buffer.from(new Uint8Array(r)),T=await o.useModel(P.TRANSCRIPTION,f);if(typeof T!=="string")throw Error("Transcription should return a string");l.info(`[OpenAI Test] Transcription: "${T.substring(0,50)}..."`)}},{name:"openai_test_text_to_speech",fn:async(o)=>{let n=await o.useModel(P.TEXT_TO_SPEECH,{text:"Hello, this is a text-to-speech test."});if(!(n instanceof ArrayBuffer)||n.byteLength===0)throw Error("TTS should return non-empty ArrayBuffer");l.info(`[OpenAI Test] TTS generated ${n.byteLength} bytes of audio`)}},{name:"openai_test_object_generation",fn:async(o)=>{let n=await o.useModel(P.OBJECT_SMALL,{prompt:"Return a JSON object with exactly these fields: name (string), age (number), active (boolean)"});if(!n||typeof n!=="object")throw Error("Object generation should return an object");l.info(`[OpenAI Test] Object generated: ${JSON.stringify(n).substring(0,100)}`)}},{name:"openai_test_research",fn:async(o)=>{let n=await o.useModel(P.RESEARCH,{input:"What is the current date and time?",tools:[{type:"web_search_preview"}],maxToolCalls:3});if(!n||typeof n!=="object"||!("text"in n))throw Error("Research should return an object with text property");if(typeof n.text!=="string"||n.text.length===0)throw Error("Research result text should be a non-empty string");l.info(`[OpenAI Test] Research completed. Text length: ${n.text.length}, Annotations: ${n.annotations?.length??0}`)}}]}]},sn=wn;export{wn as openaiPlugin,sn as default};
|
|
2
2
|
|
|
3
|
-
//# debugId=
|
|
3
|
+
//# debugId=E8CD784814D20F5364756E2164756E21
|