@nlbridge/core
Advanced tools
Comparing version 0.3.5 to 0.3.6
@@ -1,1 +0,1 @@ | ||
"use strict";var e=require("openai"),t=require("process");function s(e){var t=Object.create(null);return e&&Object.keys(e).forEach((function(s){if("default"!==s){var n=Object.getOwnPropertyDescriptor(e,s);Object.defineProperty(t,s,n.get?n:{enumerable:!0,get:function(){return e[s]}})}})),t.default=e,Object.freeze(t)}var n=s(t);const o=["chat","chat-stream","assist","create-context","discard-context","get-context","reset-context-items","update-context-items","remove-context-items","reset-context-tasks","update-context-tasks","remove-context-tasks"],r=e=>o.includes(e),a={},c={},i=(e,t)=>{const s=JSON.stringify(e,null,2);return"string"==typeof t.context&&t.context.length>0?t.context.replace("{{context}}","\n\n"+s+"\n\n"):"Use the the JSON object below as a context for the conversation that you are having with the user:\n\n"+s+"\n\n"},u=["gpt-4-0125-preview","gpt-4-turbo-preview","gpt-4-1106-preview","gpt-4-vision-preview","gpt-4","gpt-4-0314","gpt-4-0613","gpt-4-32k","gpt-4-32k-0314","gpt-4-32k-0613","gpt-3.5-turbo","gpt-3.5-turbo-16k","gpt-3.5-turbo-0301","gpt-3.5-turbo-0613","gpt-3.5-turbo-1106","gpt-3.5-turbo-0125","gpt-3.5-turbo-16k-0613"],h="gpt-3.5-turbo",p=e=>{console.error("[31m"+e+"[0m")},l=async(t,s,n)=>{if(!s)return;if(!n.getContextTasks)return;const o=await n.getContextTasks();if(!o)return;const r=n.getLlmInstructions(),a=n.config?.chatModel||h,c=i(s,r),u=((e,t)=>{const s=JSON.stringify(e,null,2);if("string"!=typeof t.taskName&&!t.taskName)return;return t.taskName.replace("{{tasks}}","\n\n"+s+"\n\n")})(o,r);if(!u||!c)return;const p=[],l=new e({apiKey:n.config?.apiKey});p.push({role:"system",content:c}),p.push({role:"system",content:u}),p.push({role:"user",content:t});const m=await l.chat.completions.create({stream:!1,model:a,messages:p});if(!(m.choices&&m.choices.length>0&&m.choices[0].message.content))return;const d=m.choices[0].message.content;if(d.length<5)return;const f=d.replace(/['"]/g,"");if(["response#",'"response#"',"'response#'"].some((e=>f.toLowerCase().startsWith(e))))return;if(["task#",'"task#"',"'task#'"].every((e=>!f.toLowerCase().startsWith(e))))return;const g=d.substring(5).trim();if(!(e=>/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(e))(g))return;if(!o[g])return;const y=o[g],x=y.paramDescriptions&&0!==y.paramDescriptions.length?y.paramDescriptions:[];return{taskId:g,description:y.description,paramDescriptions:x}},m=e=>{console.warn("[33m"+e+"[0m")},d={chat:async(s,n)=>{const o=new e({apiKey:n.config?.apiKey||t.env.OPENAI_API_KEY||""}),r=[];if(n.getContextItems){const e=n.getLlmInstructions(),t=await n.getContextItems();t&&r.push({role:"system",content:i(t,e)})}n.conversationHistory&&n.conversationHistory.forEach((e=>{r.push({role:"ai"===e.role?"assistant":"system"===e.role?"system":"user",content:e.message})})),r.push({role:"user",content:s});const a=await o.chat.completions.create({stream:!1,model:n.config?.chatModel||h,messages:r});return a.choices&&0!==a.choices.length&&a.choices[0].message.content?{success:!0,message:a.choices[0].message.content}:{success:!1,error:"No response from OpenAI."}},"chat-stream":async(s,n,o)=>{const r=new e({apiKey:o.config?.apiKey||t.env.OPENAI_API_KEY||""}),a=[];if(o.getContextItems){const e=o.getLlmInstructions(),t=await o.getContextItems();t&&a.push({role:"system",content:i(t,e)})}o.conversationHistory&&o.conversationHistory.forEach((e=>{a.push({role:"ai"===e.role?"assistant":"system"===e.role?"system":"user",content:e.message})})),a.push({role:"user",content:s});try{let e=(await r.chat.completions.create({stream:!0,model:o.config?.chatModel||h,messages:a}))[Symbol.asyncIterator](),t=await e.next();for(;!t.done;){const s=t.value;if("stop"===(s.choices?.length>0?s.choices[0].finish_reason:void 0))break;const o=s.choices?.[0].delta.content;"string"==typeof o?n.next(o):m(`Undecodable message - value: ${s}`),t=await e.next()}n.complete()}catch(e){m(`Error: ${e}`)}},assist:async(t,s)=>{const o=s.getLlmInstructions(),r=s.getContextItems?await s.getContextItems():void 0,a=await l(t,r,s),c=a?await(async(t,s,n,o)=>{if(!n)return;const r=o.getLlmInstructions(),a=((e,t)=>{if("string"!=typeof t.parameterValues&&!t.parameterValues)return;const s=t.parameterValues,n="["+e.paramDescriptions.map(((e,t)=>`<Parameter#${t+1}>`)).join(", ")+"]";let o="";return e.paramDescriptions.forEach(((e,t)=>{o+=`The value for the parameter <Parameter#${t+1}> : ${e}\n`})),s.replace("{{taskId}}",e.taskId).replace("{{instructionsToReplaceParams}}",o).replace("{{paramsArrayTemplate}}",n)})(s,r);if(!a)return;const c=[],u=i(n,r);u&&c.push({role:"system",content:u});const l=new e({apiKey:o.config?.apiKey});c.push({role:"system",content:a}),c.push({role:"user",content:t});const m=o.config?.chatModel||h,d=await l.chat.completions.create({stream:!1,model:m,messages:c});if(!(d.choices&&d.choices.length>0&&d.choices[0].message.content))return;const f=d.choices[0].message.content;try{const e=JSON.parse(f);return Array.isArray(e)?e:void p("The response is not an array.")}catch(e){return void p("Error parsing param values: "+e)}})(t,a,r,s):void 0,u=new e({apiKey:s.config?.apiKey||n.env.OPENAI_API_KEY||""}),m=[],d=i(r,o);d&&m.push({role:"system",content:d}),a&&c&&m.push({role:"system",content:`Following the next message, the task "${a.taskId}" will be performed. Respond with a short message based on the user prompt. Your response should be related to the task and should be brief. Do not overload the response with too much information since a task is going to be performed.`}),s.conversationHistory?.forEach((e=>{m.push({role:"ai"===e.role?"assistant":"system"===e.role?"system":"user",content:e.message})})),m.push({role:"user",content:t});const f=await u.chat.completions.create({stream:!1,model:s.config?.chatModel||h,messages:m});if(!f.choices||0===f.choices.length||!f.choices[0].message.content)return{success:!1,error:"No response from OpenAI."};const g=f.choices[0].message.content;return a&&c?{success:!0,message:g,task:{taskId:a.taskId,parameters:c}}:{success:!0,message:g}},"create-context":async(e,t)=>{let s;do{s=Math.random().toString(36).substring(2,14),a[s]&&(s="")}while(!s);if(c[s]={},void 0===e)return a[s]={},{success:!0,contextId:s};const n=Object.keys(e);return a[s]=n.reduce(((t,s)=>(t[s]={itemId:s,...e[s]},t)),{}),{success:!0,contextId:s}},"discard-context":async(e,t)=>e&&a[e]?(a[e]=void 0,delete a[e],c[e]=void 0,delete c[e],{success:!0}):{success:!1,error:"Context not found"},"get-context":async(e,t,s,n)=>{if(!e||!a[e])return{success:!1,error:"Context not found"};const o=a[e],r=c[e];return t?o&&o[t]||r&&r[t]?{success:!0,items:o&&o[t]?{[t]:o[t]}:void 0,tasks:r&&r[t]?{[t]:r[t]}:void 0}:{success:!1,error:"Item not found"}:{success:!0,items:o,tasks:r}},"reset-items":async(e,t,s)=>{if(!a[e])return{success:!1,error:"Context not found"};if(!t)return a[e]={},{success:!0};const n=Object.keys(t);return a[e]=n.reduce(((e,s)=>{const n=t[s];return{...e,[s]:{...n,itemId:s}}}),{}),{success:!0}},"update-items":async(e,t,s)=>{const n=a[e];if(!n)return{success:!1,error:"Context not found"};const o=Object.keys(t);for(const e of o){const s=t[e];void 0!==s&&(n[e]={...n[e],...s,itemId:e})}return{success:!0}},"remove-items":async(e,t,s)=>{const n=a[e];if(!n)return{success:!1,error:"Context not found"};for(const e of t)delete n[e];return{success:!0}},"reset-tasks":async(e,t,s)=>{if(!c[e])return{success:!1,error:"Context not found"};if(void 0===t)return c[e]={},{success:!0};const n=Object.keys(t);return c[e]=n.reduce(((e,s)=>{const n=t[s];return{...e,[s]:{...n,taskId:s}}}),{}),{success:!0}},"update-tasks":async(e,t,s)=>{const n=c[e];if(!n)return{success:!1,error:"Context not found"};const o=Object.keys(t);for(const e of o){const s=t[e];void 0!==s&&(n[e]={...n[e],...s,taskId:e})}return{success:!0}},"remove-tasks":async(e,t,s)=>{const n=c[e];if(!n)return{success:!1,error:"Context not found"};for(const e of t)delete n[e];return{success:!0}}};exports.actionIds=o,exports.asOpenAiChatModel=e=>{if(u.includes(e))return e},exports.asValidActionId=e=>r(e)?e:void 0,exports.createRuntime=(e,t,s)=>({run:(n,...o)=>{const r=e[n];if(!r)throw new Error("Unsupported action");const a=Array.isArray(o)&&o.length>0?o.slice(0,-1):[],c=!t||0===Object.keys(t).length,i=c?{context:"The conversation is taking as part while user is using a web or mobile application.\nBelow is a JSON object that contains contextual information about user's session.\nThis context data should be taken into account when generating a response.\nYou should not display JSON code from the context, but rather use it to\ngenerate a response that is relevant to the user based on that context.\n\nContext JSON object:\n\n{{context}}\n",taskName:'The conversation is taking as part while user is using a web or mobile application.\nThe previous message contains information about the user\'s context.\n\nBelow is a Javascript array with a list of tasks that the user may expect to be performed by the application.\nThe object contains a task identifier (string)\n\nTASKS LIST:\n\n{{tasks}}\n\nWhile the user is interacting with the application, they can either expect a response, or they can expect a\ntask to be performed by the application.\n\nThe next message is going to be a prompt from a user.\nYour job is to determine whether the user expects a response or a task.\nIf the user expects a response, you must reply with the string "response#".\n\nIf the user expects a task, you must reply with the string that matches the following format:\n\n"task#<TASK NAME>"\n\nWhere:\n\n<Task Name> should be replaced with the name of the task as it appears in the TASKS LIST.\n\nIf you think that the task that the user expects is not in the TASKS LIST, you should reply with the string "response#".\n\nDo not provide a direct response to the user\'s message.\nOnly analyze the message and determine what the user expects.\nStrictly respond with a string with the format "task#<TASK NAME>" or with "response#".\nIf you think that the user expects only a response, reply by one single word: "response#".\n',parameterValues:"The conversation is taking part while user is using a web or mobile application.\nThe previous message contains information about the user's context.\n\nWe know that the user would like to execute a function with the identifier: {{taskId}}\nThis function is a Javascript function that is part of the application. Your responsibility is to determine the\nvalues of the parameters that should be passed to this {{taskId}} function based on the user context, the conversation\nhistory, the user message, the taskId, and the parameter descriptions provided below.\n\nBelow is Javascript table that should be used as a template to fill in the values of the parameters:\n\nTHE TEMPLATE:\n\n{{paramsArrayTemplate}}\n\nUse the instructions below to fill in the values of the parameters.\n\nINSTRUCTIONS:\n\n{{instructionsToReplaceParams}}\n\nEach parameter marked with the notation <Parameter#(index)> (where index is a number) should be replaced with a\nvalue that will be passed to the function. Each value should either be a string (between double quotes), a number,\na boolean, or null (if you are unable to determine the value of the parameter).\n\nUse information from the context, from the conversation history, from the user input, and the task ID to\ndetermine the values of the parameters.\n\nStrictly respond with a valid and well-structured and flat Javascript array that starts with [ and ends with ].\nIf you are unable to determine the value of a specific parameter, use null for.\nIf you are unable to process the request, response with null.\n\nBe smart and don't mislead the user.\nDo not ask the user for more information than what is already available.\nReply on the INSTRUCTIONS to fill in the values of the parameters.\nYou can make it!\n"}:{},u=c?{context:t?.context??i.context,parameterValues:t?.parameterValues??i.parameterValues,taskName:t?.taskName??i.taskName}:t,h={config:s,getLlmInstructions:()=>u},p=Array.isArray(o)&&o.length>0?o[o.length-1]:void 0;"object"==typeof p&&null!==p&&("string"==typeof p.contextId&&(h.contextId=p.contextId),Array.isArray(p.conversationHistory)&&(h.conversationHistory=p.conversationHistory),"function"==typeof p.getContextItems&&(h.getContextItems=p.getContextItems),"function"==typeof p.getContextItem&&(h.getContextItem=p.getContextItem),"function"==typeof p.getContextTasks&&(h.getContextTasks=p.getContextTasks));const l=h.contextId;return l&&!h.getContextItems&&(h.getContextItems=async t=>{const s=await e["get-context"](l,t,"data",h);if(s&&s.success)return s.items}),l&&!h.getContextTasks&&(h.getContextTasks=async t=>{const s=await e["get-context"](l,t,"task",h);if(s&&s.success)return s.tasks}),r(...a,h)}}),exports.defaultActionHandlers=d,exports.isValidActionId=r,exports.openAiDefaultChatModel=h,exports.supportedOpenAiChatModels=u; | ||
"use strict";var e=require("openai"),t=require("process");function s(e){var t=Object.create(null);return e&&Object.keys(e).forEach((function(s){if("default"!==s){var n=Object.getOwnPropertyDescriptor(e,s);Object.defineProperty(t,s,n.get?n:{enumerable:!0,get:function(){return e[s]}})}})),t.default=e,Object.freeze(t)}var n=s(t);const o=["chat","chat-stream","assist","create-context","discard-context","get-context","reset-context-items","update-context-items","remove-context-items","reset-context-tasks","update-context-tasks","remove-context-tasks"],r=e=>o.includes(e),a={},i={},c=(e,t)=>{const s=JSON.stringify(e,null,2);return"string"==typeof t.context&&t.context.length>0?t.context.replace("{{context}}","\n\n"+s+"\n\n"):"Use the the JSON object below as a context for the conversation that you are having with the user:\n\n"+s+"\n\n"},u=["gpt-4-0125-preview","gpt-4-turbo-preview","gpt-4-1106-preview","gpt-4-vision-preview","gpt-4","gpt-4-0314","gpt-4-0613","gpt-4-32k","gpt-4-32k-0314","gpt-4-32k-0613","gpt-3.5-turbo","gpt-3.5-turbo-16k","gpt-3.5-turbo-0301","gpt-3.5-turbo-0613","gpt-3.5-turbo-1106","gpt-3.5-turbo-0125","gpt-3.5-turbo-16k-0613"],h="gpt-3.5-turbo",l=e=>{console.error("[31m"+e+"[0m")},p=async(t,s,n)=>{if(!s)return;if(!n.getContextTasks)return;const o=await n.getContextTasks();if(!o)return;const r=n.getLlmInstructions(),a=n.config?.chatModel||h,i=c(s,r),u=((e,t)=>{const s=JSON.stringify(e,null,2);if("string"!=typeof t.taskName&&!t.taskName)return;return t.taskName.replace("{{tasks}}","\n\n"+s+"\n\n")})(o,r);if(!u||!i)return;const l=[],p=new e({apiKey:n.config?.apiKey});l.push({role:"system",content:i}),l.push({role:"system",content:u}),l.push({role:"user",content:t});const m=await p.chat.completions.create({stream:!1,model:a,messages:l});if(!(m.choices&&m.choices.length>0&&m.choices[0].message.content))return;const d=m.choices[0].message.content;if(d.length<5)return;const f=d.replace(/['"]/g,"");if(["response#",'"response#"',"'response#'"].some((e=>f.toLowerCase().startsWith(e))))return;if(["task#",'"task#"',"'task#'"].every((e=>!f.toLowerCase().startsWith(e))))return;const g=d.substring(5).trim();if(!(e=>/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(e))(g))return;if(!o[g])return;const y=o[g],x=y.paramDescriptions&&0!==y.paramDescriptions.length?y.paramDescriptions:[];return{taskId:g,description:y.description,paramDescriptions:x}},m=e=>{console.warn("[33m"+e+"[0m")},d={chat:async(s,n)=>{console.log("openAiChat handler");const o=n.getLlmInstructions(),r=n.getContextItems?await n.getContextItems():void 0,a=new e({apiKey:n.config?.apiKey||t.env.OPENAI_API_KEY||""}),i=[];i.push({role:"system",content:c(r,o)}),n.conversationHistory?.forEach((e=>{i.push({role:"ai"===e.role?"assistant":"system"===e.role?"system":"user",content:e.message})})),i.push({role:"user",content:s}),console.log("Conversation history from chat:"),console.dir(n.conversationHistory),console.log("Messages to send:"),console.dir(i);const u=await a.chat.completions.create({stream:!1,model:n.config?.chatModel||h,messages:i});return u.choices&&0!==u.choices.length&&u.choices[0].message.content?{success:!0,message:u.choices[0].message.content}:{success:!1,error:"No response from OpenAI."}},"chat-stream":async(s,n,o)=>{const r=new e({apiKey:o.config?.apiKey||t.env.OPENAI_API_KEY||""}),a=[];if(o.getContextItems){const e=o.getLlmInstructions(),t=await o.getContextItems();t&&a.push({role:"system",content:c(t,e)})}o.conversationHistory&&o.conversationHistory.forEach((e=>{a.push({role:"ai"===e.role?"assistant":"system"===e.role?"system":"user",content:e.message})})),a.push({role:"user",content:s});try{let e=(await r.chat.completions.create({stream:!0,model:o.config?.chatModel||h,messages:a}))[Symbol.asyncIterator](),t=await e.next();for(;!t.done;){const s=t.value;if("stop"===(s.choices?.length>0?s.choices[0].finish_reason:void 0))break;const o=s.choices?.[0].delta.content;"string"==typeof o?n.next(o):m(`Undecodable message - value: ${s}`),t=await e.next()}n.complete()}catch(e){m(`Error: ${e}`)}},assist:async(t,s)=>{console.log("openAiAssist handler");const o=s.getLlmInstructions(),r=s.getContextItems?await s.getContextItems():void 0,a=await p(t,r,s),i=a?await(async(t,s,n,o)=>{if(!n)return;const r=o.getLlmInstructions(),a=((e,t)=>{if("string"!=typeof t.parameterValues&&!t.parameterValues)return;const s=t.parameterValues,n="["+e.paramDescriptions.map(((e,t)=>`<Parameter#${t+1}>`)).join(", ")+"]";let o="";return e.paramDescriptions.forEach(((e,t)=>{o+=`The value for the parameter <Parameter#${t+1}> : ${e}\n`})),s.replace("{{taskId}}",e.taskId).replace("{{instructionsToReplaceParams}}",o).replace("{{paramsArrayTemplate}}",n)})(s,r);if(!a)return;const i=[],u=c(n,r);u&&i.push({role:"system",content:u});const p=new e({apiKey:o.config?.apiKey});i.push({role:"system",content:a}),i.push({role:"user",content:t});const m=o.config?.chatModel||h,d=await p.chat.completions.create({stream:!1,model:m,messages:i});if(!(d.choices&&d.choices.length>0&&d.choices[0].message.content))return;const f=d.choices[0].message.content;try{const e=JSON.parse(f);return Array.isArray(e)?e:void l("The response is not an array.")}catch(e){return void l("Error parsing param values: "+e)}})(t,a,r,s):void 0,u=new e({apiKey:s.config?.apiKey||n.env.OPENAI_API_KEY||""}),m=[];m.push({role:"system",content:c(r,o)}),a&&i&&m.push({role:"system",content:`Following the next message, the task "${a.taskId}" will be performed. Respond with a short message based on the user prompt. Your response should be related to the task and should be brief. Do not overload the response with too much information since a task is going to be performed.`}),s.conversationHistory?.forEach((e=>{m.push({role:"ai"===e.role?"assistant":"system"===e.role?"system":"user",content:e.message})})),m.push({role:"user",content:t}),console.log("Conversation history from chat:"),console.dir(s.conversationHistory),console.log("Messages to send:"),console.dir(m);const d=await u.chat.completions.create({stream:!1,model:s.config?.chatModel||h,messages:m});if(!d.choices||0===d.choices.length||!d.choices[0].message.content)return{success:!1,error:"No response from OpenAI."};const f=d.choices[0].message.content;return a&&i?{success:!0,message:f,task:{taskId:a.taskId,parameters:i}}:{success:!0,message:f}},"create-context":async(e,t)=>{let s;do{s=Math.random().toString(36).substring(2,14),a[s]&&(s="")}while(!s);if(i[s]={},void 0===e)return a[s]={},{success:!0,contextId:s};const n=Object.keys(e);return a[s]=n.reduce(((t,s)=>(t[s]={itemId:s,...e[s]},t)),{}),{success:!0,contextId:s}},"discard-context":async(e,t)=>e&&a[e]?(a[e]=void 0,delete a[e],i[e]=void 0,delete i[e],{success:!0}):{success:!1,error:"Context not found"},"get-context":async(e,t,s,n)=>{if(!e||!a[e])return{success:!1,error:"Context not found"};const o=a[e],r=i[e];return t?o&&o[t]||r&&r[t]?{success:!0,items:o&&o[t]?{[t]:o[t]}:void 0,tasks:r&&r[t]?{[t]:r[t]}:void 0}:{success:!1,error:"Item not found"}:{success:!0,items:o,tasks:r}},"reset-items":async(e,t,s)=>{if(!a[e])return{success:!1,error:"Context not found"};if(!t)return a[e]={},{success:!0};const n=Object.keys(t);return a[e]=n.reduce(((e,s)=>{const n=t[s];return{...e,[s]:{...n,itemId:s}}}),{}),{success:!0}},"update-items":async(e,t,s)=>{const n=a[e];if(!n)return{success:!1,error:"Context not found"};const o=Object.keys(t);for(const e of o){const s=t[e];void 0!==s&&(n[e]={...n[e],...s,itemId:e})}return{success:!0}},"remove-items":async(e,t,s)=>{const n=a[e];if(!n)return{success:!1,error:"Context not found"};for(const e of t)delete n[e];return{success:!0}},"reset-tasks":async(e,t,s)=>{if(!i[e])return{success:!1,error:"Context not found"};if(void 0===t)return i[e]={},{success:!0};const n=Object.keys(t);return i[e]=n.reduce(((e,s)=>{const n=t[s];return{...e,[s]:{...n,taskId:s}}}),{}),{success:!0}},"update-tasks":async(e,t,s)=>{const n=i[e];if(!n)return{success:!1,error:"Context not found"};const o=Object.keys(t);for(const e of o){const s=t[e];void 0!==s&&(n[e]={...n[e],...s,taskId:e})}return{success:!0}},"remove-tasks":async(e,t,s)=>{const n=i[e];if(!n)return{success:!1,error:"Context not found"};for(const e of t)delete n[e];return{success:!0}}};exports.actionIds=o,exports.asOpenAiChatModel=e=>{if(u.includes(e))return e},exports.asValidActionId=e=>r(e)?e:void 0,exports.createRuntime=(e,t,s)=>({run:(n,...o)=>{const r=e[n];if(!r)throw new Error("Unsupported action");const a=Array.isArray(o)&&o.length>0?o.slice(0,-1):[],i=!t||0===Object.keys(t).length,c=i?{context:"The conversation is taking as part while user is using a web or mobile application.\nBelow is a JSON object that contains contextual information about user's session.\nThis context data should be taken into account when generating a response.\nYou should not display JSON code from the context, but rather use it to\ngenerate a response that is relevant to the user based on that context.\n\nContext JSON object:\n\n{{context}}\n",taskName:'The conversation is taking as part while user is using a web or mobile application.\nThe previous message contains information about the user\'s context.\n\nBelow is a Javascript array with a list of tasks that the user may expect to be performed by the application.\nThe object contains a task identifier (string)\n\nTASKS LIST:\n\n{{tasks}}\n\nWhile the user is interacting with the application, they can either expect a response, or they can expect a\ntask to be performed by the application.\n\nThe next message is going to be a prompt from a user.\nYour job is to determine whether the user expects a response or a task.\nIf the user expects a response, you must reply with the string "response#".\n\nIf the user expects a task, you must reply with the string that matches the following format:\n\n"task#<TASK NAME>"\n\nWhere:\n\n<Task Name> should be replaced with the name of the task as it appears in the TASKS LIST.\n\nIf you think that the task that the user expects is not in the TASKS LIST, you should reply with the string "response#".\n\nDo not provide a direct response to the user\'s message.\nOnly analyze the message and determine what the user expects.\nStrictly respond with a string with the format "task#<TASK NAME>" or with "response#".\nIf you think that the user expects only a response, reply by one single word: "response#".\n',parameterValues:"The conversation is taking part while user is using a web or mobile application.\nThe previous message contains information about the user's context.\n\nWe know that the user would like to execute a function with the identifier: {{taskId}}\nThis function is a Javascript function that is part of the application. Your responsibility is to determine the\nvalues of the parameters that should be passed to this {{taskId}} function based on the user context, the conversation\nhistory, the user message, the taskId, and the parameter descriptions provided below.\n\nBelow is Javascript table that should be used as a template to fill in the values of the parameters:\n\nTHE TEMPLATE:\n\n{{paramsArrayTemplate}}\n\nUse the instructions below to fill in the values of the parameters.\n\nINSTRUCTIONS:\n\n{{instructionsToReplaceParams}}\n\nEach parameter marked with the notation <Parameter#(index)> (where index is a number) should be replaced with a\nvalue that will be passed to the function. Each value should either be a string (between double quotes), a number,\na boolean, or null (if you are unable to determine the value of the parameter).\n\nUse information from the context, from the conversation history, from the user input, and the task ID to\ndetermine the values of the parameters.\n\nStrictly respond with a valid and well-structured and flat Javascript array that starts with [ and ends with ].\nIf you are unable to determine the value of a specific parameter, use null for.\nIf you are unable to process the request, response with null.\n\nBe smart and don't mislead the user.\nDo not ask the user for more information than what is already available.\nReply on the INSTRUCTIONS to fill in the values of the parameters.\nYou can make it!\n"}:{},u=i?{context:t?.context??c.context,parameterValues:t?.parameterValues??c.parameterValues,taskName:t?.taskName??c.taskName}:t,h={config:s,getLlmInstructions:()=>u},l=Array.isArray(o)&&o.length>0?o[o.length-1]:void 0;"object"==typeof l&&null!==l&&("string"==typeof l.contextId&&(h.contextId=l.contextId),Array.isArray(l.conversationHistory)&&(h.conversationHistory=l.conversationHistory),"function"==typeof l.getContextItems&&(h.getContextItems=l.getContextItems),"function"==typeof l.getContextItem&&(h.getContextItem=l.getContextItem),"function"==typeof l.getContextTasks&&(h.getContextTasks=l.getContextTasks));const p=h.contextId;return p&&!h.getContextItems&&(h.getContextItems=async t=>{const s=await e["get-context"](p,t,"data",h);if(s&&s.success)return s.items}),p&&!h.getContextTasks&&(h.getContextTasks=async t=>{const s=await e["get-context"](p,t,"task",h);if(s&&s.success)return s.tasks}),r(...a,h)}}),exports.defaultActionHandlers=d,exports.isValidActionId=r,exports.openAiDefaultChatModel=h,exports.supportedOpenAiChatModels=u; |
@@ -1,1 +0,1 @@ | ||
import e from"openai";import*as t from"process";import s from"process";const n=["chat","chat-stream","assist","create-context","discard-context","get-context","reset-context-items","update-context-items","remove-context-items","reset-context-tasks","update-context-tasks","remove-context-tasks"],o=e=>n.includes(e),r=e=>o(e)?e:void 0,a={},c={},i=(e,t)=>{const s=JSON.stringify(e,null,2);return"string"==typeof t.context&&t.context.length>0?t.context.replace("{{context}}","\n\n"+s+"\n\n"):"Use the the JSON object below as a context for the conversation that you are having with the user:\n\n"+s+"\n\n"},u=["gpt-4-0125-preview","gpt-4-turbo-preview","gpt-4-1106-preview","gpt-4-vision-preview","gpt-4","gpt-4-0314","gpt-4-0613","gpt-4-32k","gpt-4-32k-0314","gpt-4-32k-0613","gpt-3.5-turbo","gpt-3.5-turbo-16k","gpt-3.5-turbo-0301","gpt-3.5-turbo-0613","gpt-3.5-turbo-1106","gpt-3.5-turbo-0125","gpt-3.5-turbo-16k-0613"],h="gpt-3.5-turbo",p=e=>{if(u.includes(e))return e},m=e=>{console.error("[31m"+e+"[0m")},l=async(t,s,n)=>{if(!s)return;if(!n.getContextTasks)return;const o=await n.getContextTasks();if(!o)return;const r=n.getLlmInstructions(),a=n.config?.chatModel||h,c=i(s,r),u=((e,t)=>{const s=JSON.stringify(e,null,2);if("string"!=typeof t.taskName&&!t.taskName)return;return t.taskName.replace("{{tasks}}","\n\n"+s+"\n\n")})(o,r);if(!u||!c)return;const p=[],m=new e({apiKey:n.config?.apiKey});p.push({role:"system",content:c}),p.push({role:"system",content:u}),p.push({role:"user",content:t});const l=await m.chat.completions.create({stream:!1,model:a,messages:p});if(!(l.choices&&l.choices.length>0&&l.choices[0].message.content))return;const d=l.choices[0].message.content;if(d.length<5)return;const f=d.replace(/['"]/g,"");if(["response#",'"response#"',"'response#'"].some((e=>f.toLowerCase().startsWith(e))))return;if(["task#",'"task#"',"'task#'"].every((e=>!f.toLowerCase().startsWith(e))))return;const g=d.substring(5).trim();if(!(e=>/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(e))(g))return;if(!o[g])return;const y=o[g],x=y.paramDescriptions&&0!==y.paramDescriptions.length?y.paramDescriptions:[];return{taskId:g,description:y.description,paramDescriptions:x}},d=e=>{console.warn("[33m"+e+"[0m")},f={chat:async(t,n)=>{const o=new e({apiKey:n.config?.apiKey||s.env.OPENAI_API_KEY||""}),r=[];if(n.getContextItems){const e=n.getLlmInstructions(),t=await n.getContextItems();t&&r.push({role:"system",content:i(t,e)})}n.conversationHistory&&n.conversationHistory.forEach((e=>{r.push({role:"ai"===e.role?"assistant":"system"===e.role?"system":"user",content:e.message})})),r.push({role:"user",content:t});const a=await o.chat.completions.create({stream:!1,model:n.config?.chatModel||h,messages:r});return a.choices&&0!==a.choices.length&&a.choices[0].message.content?{success:!0,message:a.choices[0].message.content}:{success:!1,error:"No response from OpenAI."}},"chat-stream":async(t,n,o)=>{const r=new e({apiKey:o.config?.apiKey||s.env.OPENAI_API_KEY||""}),a=[];if(o.getContextItems){const e=o.getLlmInstructions(),t=await o.getContextItems();t&&a.push({role:"system",content:i(t,e)})}o.conversationHistory&&o.conversationHistory.forEach((e=>{a.push({role:"ai"===e.role?"assistant":"system"===e.role?"system":"user",content:e.message})})),a.push({role:"user",content:t});try{let e=(await r.chat.completions.create({stream:!0,model:o.config?.chatModel||h,messages:a}))[Symbol.asyncIterator](),t=await e.next();for(;!t.done;){const s=t.value;if("stop"===(s.choices?.length>0?s.choices[0].finish_reason:void 0))break;const o=s.choices?.[0].delta.content;"string"==typeof o?n.next(o):d(`Undecodable message - value: ${s}`),t=await e.next()}n.complete()}catch(e){d(`Error: ${e}`)}},assist:async(s,n)=>{const o=n.getLlmInstructions(),r=n.getContextItems?await n.getContextItems():void 0,a=await l(s,r,n),c=a?await(async(t,s,n,o)=>{if(!n)return;const r=o.getLlmInstructions(),a=((e,t)=>{if("string"!=typeof t.parameterValues&&!t.parameterValues)return;const s=t.parameterValues,n="["+e.paramDescriptions.map(((e,t)=>`<Parameter#${t+1}>`)).join(", ")+"]";let o="";return e.paramDescriptions.forEach(((e,t)=>{o+=`The value for the parameter <Parameter#${t+1}> : ${e}\n`})),s.replace("{{taskId}}",e.taskId).replace("{{instructionsToReplaceParams}}",o).replace("{{paramsArrayTemplate}}",n)})(s,r);if(!a)return;const c=[],u=i(n,r);u&&c.push({role:"system",content:u});const p=new e({apiKey:o.config?.apiKey});c.push({role:"system",content:a}),c.push({role:"user",content:t});const l=o.config?.chatModel||h,d=await p.chat.completions.create({stream:!1,model:l,messages:c});if(!(d.choices&&d.choices.length>0&&d.choices[0].message.content))return;const f=d.choices[0].message.content;try{const e=JSON.parse(f);return Array.isArray(e)?e:void m("The response is not an array.")}catch(e){return void m("Error parsing param values: "+e)}})(s,a,r,n):void 0,u=new e({apiKey:n.config?.apiKey||t.env.OPENAI_API_KEY||""}),p=[],d=i(r,o);d&&p.push({role:"system",content:d}),a&&c&&p.push({role:"system",content:`Following the next message, the task "${a.taskId}" will be performed. Respond with a short message based on the user prompt. Your response should be related to the task and should be brief. Do not overload the response with too much information since a task is going to be performed.`}),n.conversationHistory?.forEach((e=>{p.push({role:"ai"===e.role?"assistant":"system"===e.role?"system":"user",content:e.message})})),p.push({role:"user",content:s});const f=await u.chat.completions.create({stream:!1,model:n.config?.chatModel||h,messages:p});if(!f.choices||0===f.choices.length||!f.choices[0].message.content)return{success:!1,error:"No response from OpenAI."};const g=f.choices[0].message.content;return a&&c?{success:!0,message:g,task:{taskId:a.taskId,parameters:c}}:{success:!0,message:g}},"create-context":async(e,t)=>{let s;do{s=Math.random().toString(36).substring(2,14),a[s]&&(s="")}while(!s);if(c[s]={},void 0===e)return a[s]={},{success:!0,contextId:s};const n=Object.keys(e);return a[s]=n.reduce(((t,s)=>(t[s]={itemId:s,...e[s]},t)),{}),{success:!0,contextId:s}},"discard-context":async(e,t)=>e&&a[e]?(a[e]=void 0,delete a[e],c[e]=void 0,delete c[e],{success:!0}):{success:!1,error:"Context not found"},"get-context":async(e,t,s,n)=>{if(!e||!a[e])return{success:!1,error:"Context not found"};const o=a[e],r=c[e];return t?o&&o[t]||r&&r[t]?{success:!0,items:o&&o[t]?{[t]:o[t]}:void 0,tasks:r&&r[t]?{[t]:r[t]}:void 0}:{success:!1,error:"Item not found"}:{success:!0,items:o,tasks:r}},"reset-items":async(e,t,s)=>{if(!a[e])return{success:!1,error:"Context not found"};if(!t)return a[e]={},{success:!0};const n=Object.keys(t);return a[e]=n.reduce(((e,s)=>{const n=t[s];return{...e,[s]:{...n,itemId:s}}}),{}),{success:!0}},"update-items":async(e,t,s)=>{const n=a[e];if(!n)return{success:!1,error:"Context not found"};const o=Object.keys(t);for(const e of o){const s=t[e];void 0!==s&&(n[e]={...n[e],...s,itemId:e})}return{success:!0}},"remove-items":async(e,t,s)=>{const n=a[e];if(!n)return{success:!1,error:"Context not found"};for(const e of t)delete n[e];return{success:!0}},"reset-tasks":async(e,t,s)=>{if(!c[e])return{success:!1,error:"Context not found"};if(void 0===t)return c[e]={},{success:!0};const n=Object.keys(t);return c[e]=n.reduce(((e,s)=>{const n=t[s];return{...e,[s]:{...n,taskId:s}}}),{}),{success:!0}},"update-tasks":async(e,t,s)=>{const n=c[e];if(!n)return{success:!1,error:"Context not found"};const o=Object.keys(t);for(const e of o){const s=t[e];void 0!==s&&(n[e]={...n[e],...s,taskId:e})}return{success:!0}},"remove-tasks":async(e,t,s)=>{const n=c[e];if(!n)return{success:!1,error:"Context not found"};for(const e of t)delete n[e];return{success:!0}}};const g=(e,t,s)=>({run:(n,...o)=>{const r=e[n];if(!r)throw new Error("Unsupported action");const a=Array.isArray(o)&&o.length>0?o.slice(0,-1):[],c=!t||0===Object.keys(t).length,i=c?{context:"The conversation is taking as part while user is using a web or mobile application.\nBelow is a JSON object that contains contextual information about user's session.\nThis context data should be taken into account when generating a response.\nYou should not display JSON code from the context, but rather use it to\ngenerate a response that is relevant to the user based on that context.\n\nContext JSON object:\n\n{{context}}\n",taskName:'The conversation is taking as part while user is using a web or mobile application.\nThe previous message contains information about the user\'s context.\n\nBelow is a Javascript array with a list of tasks that the user may expect to be performed by the application.\nThe object contains a task identifier (string)\n\nTASKS LIST:\n\n{{tasks}}\n\nWhile the user is interacting with the application, they can either expect a response, or they can expect a\ntask to be performed by the application.\n\nThe next message is going to be a prompt from a user.\nYour job is to determine whether the user expects a response or a task.\nIf the user expects a response, you must reply with the string "response#".\n\nIf the user expects a task, you must reply with the string that matches the following format:\n\n"task#<TASK NAME>"\n\nWhere:\n\n<Task Name> should be replaced with the name of the task as it appears in the TASKS LIST.\n\nIf you think that the task that the user expects is not in the TASKS LIST, you should reply with the string "response#".\n\nDo not provide a direct response to the user\'s message.\nOnly analyze the message and determine what the user expects.\nStrictly respond with a string with the format "task#<TASK NAME>" or with "response#".\nIf you think that the user expects only a response, reply by one single word: "response#".\n',parameterValues:"The conversation is taking part while user is using a web or mobile application.\nThe previous message contains information about the user's context.\n\nWe know that the user would like to execute a function with the identifier: {{taskId}}\nThis function is a Javascript function that is part of the application. Your responsibility is to determine the\nvalues of the parameters that should be passed to this {{taskId}} function based on the user context, the conversation\nhistory, the user message, the taskId, and the parameter descriptions provided below.\n\nBelow is Javascript table that should be used as a template to fill in the values of the parameters:\n\nTHE TEMPLATE:\n\n{{paramsArrayTemplate}}\n\nUse the instructions below to fill in the values of the parameters.\n\nINSTRUCTIONS:\n\n{{instructionsToReplaceParams}}\n\nEach parameter marked with the notation <Parameter#(index)> (where index is a number) should be replaced with a\nvalue that will be passed to the function. Each value should either be a string (between double quotes), a number,\na boolean, or null (if you are unable to determine the value of the parameter).\n\nUse information from the context, from the conversation history, from the user input, and the task ID to\ndetermine the values of the parameters.\n\nStrictly respond with a valid and well-structured and flat Javascript array that starts with [ and ends with ].\nIf you are unable to determine the value of a specific parameter, use null for.\nIf you are unable to process the request, response with null.\n\nBe smart and don't mislead the user.\nDo not ask the user for more information than what is already available.\nReply on the INSTRUCTIONS to fill in the values of the parameters.\nYou can make it!\n"}:{},u=c?{context:t?.context??i.context,parameterValues:t?.parameterValues??i.parameterValues,taskName:t?.taskName??i.taskName}:t,h={config:s,getLlmInstructions:()=>u},p=Array.isArray(o)&&o.length>0?o[o.length-1]:void 0;"object"==typeof p&&null!==p&&("string"==typeof p.contextId&&(h.contextId=p.contextId),Array.isArray(p.conversationHistory)&&(h.conversationHistory=p.conversationHistory),"function"==typeof p.getContextItems&&(h.getContextItems=p.getContextItems),"function"==typeof p.getContextItem&&(h.getContextItem=p.getContextItem),"function"==typeof p.getContextTasks&&(h.getContextTasks=p.getContextTasks));const m=h.contextId;return m&&!h.getContextItems&&(h.getContextItems=async t=>{const s=await e["get-context"](m,t,"data",h);if(s&&s.success)return s.items}),m&&!h.getContextTasks&&(h.getContextTasks=async t=>{const s=await e["get-context"](m,t,"task",h);if(s&&s.success)return s.tasks}),r(...a,h)}});export{n as actionIds,p as asOpenAiChatModel,r as asValidActionId,g as createRuntime,f as defaultActionHandlers,o as isValidActionId,h as openAiDefaultChatModel,u as supportedOpenAiChatModels}; | ||
import e from"openai";import*as t from"process";import s from"process";const n=["chat","chat-stream","assist","create-context","discard-context","get-context","reset-context-items","update-context-items","remove-context-items","reset-context-tasks","update-context-tasks","remove-context-tasks"],o=e=>n.includes(e),r=e=>o(e)?e:void 0,a={},c={},i=(e,t)=>{const s=JSON.stringify(e,null,2);return"string"==typeof t.context&&t.context.length>0?t.context.replace("{{context}}","\n\n"+s+"\n\n"):"Use the the JSON object below as a context for the conversation that you are having with the user:\n\n"+s+"\n\n"},u=["gpt-4-0125-preview","gpt-4-turbo-preview","gpt-4-1106-preview","gpt-4-vision-preview","gpt-4","gpt-4-0314","gpt-4-0613","gpt-4-32k","gpt-4-32k-0314","gpt-4-32k-0613","gpt-3.5-turbo","gpt-3.5-turbo-16k","gpt-3.5-turbo-0301","gpt-3.5-turbo-0613","gpt-3.5-turbo-1106","gpt-3.5-turbo-0125","gpt-3.5-turbo-16k-0613"],h="gpt-3.5-turbo",l=e=>{if(u.includes(e))return e},p=e=>{console.error("[31m"+e+"[0m")},m=async(t,s,n)=>{if(!s)return;if(!n.getContextTasks)return;const o=await n.getContextTasks();if(!o)return;const r=n.getLlmInstructions(),a=n.config?.chatModel||h,c=i(s,r),u=((e,t)=>{const s=JSON.stringify(e,null,2);if("string"!=typeof t.taskName&&!t.taskName)return;return t.taskName.replace("{{tasks}}","\n\n"+s+"\n\n")})(o,r);if(!u||!c)return;const l=[],p=new e({apiKey:n.config?.apiKey});l.push({role:"system",content:c}),l.push({role:"system",content:u}),l.push({role:"user",content:t});const m=await p.chat.completions.create({stream:!1,model:a,messages:l});if(!(m.choices&&m.choices.length>0&&m.choices[0].message.content))return;const d=m.choices[0].message.content;if(d.length<5)return;const g=d.replace(/['"]/g,"");if(["response#",'"response#"',"'response#'"].some((e=>g.toLowerCase().startsWith(e))))return;if(["task#",'"task#"',"'task#'"].every((e=>!g.toLowerCase().startsWith(e))))return;const f=d.substring(5).trim();if(!(e=>/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(e))(f))return;if(!o[f])return;const y=o[f],x=y.paramDescriptions&&0!==y.paramDescriptions.length?y.paramDescriptions:[];return{taskId:f,description:y.description,paramDescriptions:x}},d=e=>{console.warn("[33m"+e+"[0m")},g={chat:async(t,n)=>{console.log("openAiChat handler");const o=n.getLlmInstructions(),r=n.getContextItems?await n.getContextItems():void 0,a=new e({apiKey:n.config?.apiKey||s.env.OPENAI_API_KEY||""}),c=[];c.push({role:"system",content:i(r,o)}),n.conversationHistory?.forEach((e=>{c.push({role:"ai"===e.role?"assistant":"system"===e.role?"system":"user",content:e.message})})),c.push({role:"user",content:t}),console.log("Conversation history from chat:"),console.dir(n.conversationHistory),console.log("Messages to send:"),console.dir(c);const u=await a.chat.completions.create({stream:!1,model:n.config?.chatModel||h,messages:c});return u.choices&&0!==u.choices.length&&u.choices[0].message.content?{success:!0,message:u.choices[0].message.content}:{success:!1,error:"No response from OpenAI."}},"chat-stream":async(t,n,o)=>{const r=new e({apiKey:o.config?.apiKey||s.env.OPENAI_API_KEY||""}),a=[];if(o.getContextItems){const e=o.getLlmInstructions(),t=await o.getContextItems();t&&a.push({role:"system",content:i(t,e)})}o.conversationHistory&&o.conversationHistory.forEach((e=>{a.push({role:"ai"===e.role?"assistant":"system"===e.role?"system":"user",content:e.message})})),a.push({role:"user",content:t});try{let e=(await r.chat.completions.create({stream:!0,model:o.config?.chatModel||h,messages:a}))[Symbol.asyncIterator](),t=await e.next();for(;!t.done;){const s=t.value;if("stop"===(s.choices?.length>0?s.choices[0].finish_reason:void 0))break;const o=s.choices?.[0].delta.content;"string"==typeof o?n.next(o):d(`Undecodable message - value: ${s}`),t=await e.next()}n.complete()}catch(e){d(`Error: ${e}`)}},assist:async(s,n)=>{console.log("openAiAssist handler");const o=n.getLlmInstructions(),r=n.getContextItems?await n.getContextItems():void 0,a=await m(s,r,n),c=a?await(async(t,s,n,o)=>{if(!n)return;const r=o.getLlmInstructions(),a=((e,t)=>{if("string"!=typeof t.parameterValues&&!t.parameterValues)return;const s=t.parameterValues,n="["+e.paramDescriptions.map(((e,t)=>`<Parameter#${t+1}>`)).join(", ")+"]";let o="";return e.paramDescriptions.forEach(((e,t)=>{o+=`The value for the parameter <Parameter#${t+1}> : ${e}\n`})),s.replace("{{taskId}}",e.taskId).replace("{{instructionsToReplaceParams}}",o).replace("{{paramsArrayTemplate}}",n)})(s,r);if(!a)return;const c=[],u=i(n,r);u&&c.push({role:"system",content:u});const l=new e({apiKey:o.config?.apiKey});c.push({role:"system",content:a}),c.push({role:"user",content:t});const m=o.config?.chatModel||h,d=await l.chat.completions.create({stream:!1,model:m,messages:c});if(!(d.choices&&d.choices.length>0&&d.choices[0].message.content))return;const g=d.choices[0].message.content;try{const e=JSON.parse(g);return Array.isArray(e)?e:void p("The response is not an array.")}catch(e){return void p("Error parsing param values: "+e)}})(s,a,r,n):void 0,u=new e({apiKey:n.config?.apiKey||t.env.OPENAI_API_KEY||""}),l=[];l.push({role:"system",content:i(r,o)}),a&&c&&l.push({role:"system",content:`Following the next message, the task "${a.taskId}" will be performed. Respond with a short message based on the user prompt. Your response should be related to the task and should be brief. Do not overload the response with too much information since a task is going to be performed.`}),n.conversationHistory?.forEach((e=>{l.push({role:"ai"===e.role?"assistant":"system"===e.role?"system":"user",content:e.message})})),l.push({role:"user",content:s}),console.log("Conversation history from chat:"),console.dir(n.conversationHistory),console.log("Messages to send:"),console.dir(l);const d=await u.chat.completions.create({stream:!1,model:n.config?.chatModel||h,messages:l});if(!d.choices||0===d.choices.length||!d.choices[0].message.content)return{success:!1,error:"No response from OpenAI."};const g=d.choices[0].message.content;return a&&c?{success:!0,message:g,task:{taskId:a.taskId,parameters:c}}:{success:!0,message:g}},"create-context":async(e,t)=>{let s;do{s=Math.random().toString(36).substring(2,14),a[s]&&(s="")}while(!s);if(c[s]={},void 0===e)return a[s]={},{success:!0,contextId:s};const n=Object.keys(e);return a[s]=n.reduce(((t,s)=>(t[s]={itemId:s,...e[s]},t)),{}),{success:!0,contextId:s}},"discard-context":async(e,t)=>e&&a[e]?(a[e]=void 0,delete a[e],c[e]=void 0,delete c[e],{success:!0}):{success:!1,error:"Context not found"},"get-context":async(e,t,s,n)=>{if(!e||!a[e])return{success:!1,error:"Context not found"};const o=a[e],r=c[e];return t?o&&o[t]||r&&r[t]?{success:!0,items:o&&o[t]?{[t]:o[t]}:void 0,tasks:r&&r[t]?{[t]:r[t]}:void 0}:{success:!1,error:"Item not found"}:{success:!0,items:o,tasks:r}},"reset-items":async(e,t,s)=>{if(!a[e])return{success:!1,error:"Context not found"};if(!t)return a[e]={},{success:!0};const n=Object.keys(t);return a[e]=n.reduce(((e,s)=>{const n=t[s];return{...e,[s]:{...n,itemId:s}}}),{}),{success:!0}},"update-items":async(e,t,s)=>{const n=a[e];if(!n)return{success:!1,error:"Context not found"};const o=Object.keys(t);for(const e of o){const s=t[e];void 0!==s&&(n[e]={...n[e],...s,itemId:e})}return{success:!0}},"remove-items":async(e,t,s)=>{const n=a[e];if(!n)return{success:!1,error:"Context not found"};for(const e of t)delete n[e];return{success:!0}},"reset-tasks":async(e,t,s)=>{if(!c[e])return{success:!1,error:"Context not found"};if(void 0===t)return c[e]={},{success:!0};const n=Object.keys(t);return c[e]=n.reduce(((e,s)=>{const n=t[s];return{...e,[s]:{...n,taskId:s}}}),{}),{success:!0}},"update-tasks":async(e,t,s)=>{const n=c[e];if(!n)return{success:!1,error:"Context not found"};const o=Object.keys(t);for(const e of o){const s=t[e];void 0!==s&&(n[e]={...n[e],...s,taskId:e})}return{success:!0}},"remove-tasks":async(e,t,s)=>{const n=c[e];if(!n)return{success:!1,error:"Context not found"};for(const e of t)delete n[e];return{success:!0}}};const f=(e,t,s)=>({run:(n,...o)=>{const r=e[n];if(!r)throw new Error("Unsupported action");const a=Array.isArray(o)&&o.length>0?o.slice(0,-1):[],c=!t||0===Object.keys(t).length,i=c?{context:"The conversation is taking as part while user is using a web or mobile application.\nBelow is a JSON object that contains contextual information about user's session.\nThis context data should be taken into account when generating a response.\nYou should not display JSON code from the context, but rather use it to\ngenerate a response that is relevant to the user based on that context.\n\nContext JSON object:\n\n{{context}}\n",taskName:'The conversation is taking as part while user is using a web or mobile application.\nThe previous message contains information about the user\'s context.\n\nBelow is a Javascript array with a list of tasks that the user may expect to be performed by the application.\nThe object contains a task identifier (string)\n\nTASKS LIST:\n\n{{tasks}}\n\nWhile the user is interacting with the application, they can either expect a response, or they can expect a\ntask to be performed by the application.\n\nThe next message is going to be a prompt from a user.\nYour job is to determine whether the user expects a response or a task.\nIf the user expects a response, you must reply with the string "response#".\n\nIf the user expects a task, you must reply with the string that matches the following format:\n\n"task#<TASK NAME>"\n\nWhere:\n\n<Task Name> should be replaced with the name of the task as it appears in the TASKS LIST.\n\nIf you think that the task that the user expects is not in the TASKS LIST, you should reply with the string "response#".\n\nDo not provide a direct response to the user\'s message.\nOnly analyze the message and determine what the user expects.\nStrictly respond with a string with the format "task#<TASK NAME>" or with "response#".\nIf you think that the user expects only a response, reply by one single word: "response#".\n',parameterValues:"The conversation is taking part while user is using a web or mobile application.\nThe previous message contains information about the user's context.\n\nWe know that the user would like to execute a function with the identifier: {{taskId}}\nThis function is a Javascript function that is part of the application. Your responsibility is to determine the\nvalues of the parameters that should be passed to this {{taskId}} function based on the user context, the conversation\nhistory, the user message, the taskId, and the parameter descriptions provided below.\n\nBelow is Javascript table that should be used as a template to fill in the values of the parameters:\n\nTHE TEMPLATE:\n\n{{paramsArrayTemplate}}\n\nUse the instructions below to fill in the values of the parameters.\n\nINSTRUCTIONS:\n\n{{instructionsToReplaceParams}}\n\nEach parameter marked with the notation <Parameter#(index)> (where index is a number) should be replaced with a\nvalue that will be passed to the function. Each value should either be a string (between double quotes), a number,\na boolean, or null (if you are unable to determine the value of the parameter).\n\nUse information from the context, from the conversation history, from the user input, and the task ID to\ndetermine the values of the parameters.\n\nStrictly respond with a valid and well-structured and flat Javascript array that starts with [ and ends with ].\nIf you are unable to determine the value of a specific parameter, use null for.\nIf you are unable to process the request, response with null.\n\nBe smart and don't mislead the user.\nDo not ask the user for more information than what is already available.\nReply on the INSTRUCTIONS to fill in the values of the parameters.\nYou can make it!\n"}:{},u=c?{context:t?.context??i.context,parameterValues:t?.parameterValues??i.parameterValues,taskName:t?.taskName??i.taskName}:t,h={config:s,getLlmInstructions:()=>u},l=Array.isArray(o)&&o.length>0?o[o.length-1]:void 0;"object"==typeof l&&null!==l&&("string"==typeof l.contextId&&(h.contextId=l.contextId),Array.isArray(l.conversationHistory)&&(h.conversationHistory=l.conversationHistory),"function"==typeof l.getContextItems&&(h.getContextItems=l.getContextItems),"function"==typeof l.getContextItem&&(h.getContextItem=l.getContextItem),"function"==typeof l.getContextTasks&&(h.getContextTasks=l.getContextTasks));const p=h.contextId;return p&&!h.getContextItems&&(h.getContextItems=async t=>{const s=await e["get-context"](p,t,"data",h);if(s&&s.success)return s.items}),p&&!h.getContextTasks&&(h.getContextTasks=async t=>{const s=await e["get-context"](p,t,"task",h);if(s&&s.success)return s.tasks}),r(...a,h)}});export{n as actionIds,l as asOpenAiChatModel,r as asValidActionId,f as createRuntime,g as defaultActionHandlers,o as isValidActionId,h as openAiDefaultChatModel,u as supportedOpenAiChatModels}; |
{ | ||
"name": "@nlbridge/core", | ||
"version": "0.3.5", | ||
"version": "0.3.6", | ||
"description": "The core library content for @nlbridge", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
@@ -1,1 +0,1 @@ | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("openai"),require("process")):"function"==typeof define&&define.amd?define(["exports","openai","process"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self)["@nlbridge/core"]={},e.OpenAI,e.process)}(this,(function(e,t,s){"use strict";function n(e){var t=Object.create(null);return e&&Object.keys(e).forEach((function(s){if("default"!==s){var n=Object.getOwnPropertyDescriptor(e,s);Object.defineProperty(t,s,n.get?n:{enumerable:!0,get:function(){return e[s]}})}})),t.default=e,Object.freeze(t)}var o=n(s);const r=["chat","chat-stream","assist","create-context","discard-context","get-context","reset-context-items","update-context-items","remove-context-items","reset-context-tasks","update-context-tasks","remove-context-tasks"],a=e=>r.includes(e),i={},c={},u=(e,t)=>{const s=JSON.stringify(e,null,2);return"string"==typeof t.context&&t.context.length>0?t.context.replace("{{context}}","\n\n"+s+"\n\n"):"Use the the JSON object below as a context for the conversation that you are having with the user:\n\n"+s+"\n\n"},h=["gpt-4-0125-preview","gpt-4-turbo-preview","gpt-4-1106-preview","gpt-4-vision-preview","gpt-4","gpt-4-0314","gpt-4-0613","gpt-4-32k","gpt-4-32k-0314","gpt-4-32k-0613","gpt-3.5-turbo","gpt-3.5-turbo-16k","gpt-3.5-turbo-0301","gpt-3.5-turbo-0613","gpt-3.5-turbo-1106","gpt-3.5-turbo-0125","gpt-3.5-turbo-16k-0613"],p="gpt-3.5-turbo",l=e=>{console.error("[31m"+e+"[0m")},m=async(e,s,n)=>{if(!s)return;if(!n.getContextTasks)return;const o=await n.getContextTasks();if(!o)return;const r=n.getLlmInstructions(),a=n.config?.chatModel||p,i=u(s,r),c=((e,t)=>{const s=JSON.stringify(e,null,2);if("string"!=typeof t.taskName&&!t.taskName)return;return t.taskName.replace("{{tasks}}","\n\n"+s+"\n\n")})(o,r);if(!c||!i)return;const h=[],l=new t({apiKey:n.config?.apiKey});h.push({role:"system",content:i}),h.push({role:"system",content:c}),h.push({role:"user",content:e});const m=await l.chat.completions.create({stream:!1,model:a,messages:h});if(!(m.choices&&m.choices.length>0&&m.choices[0].message.content))return;const d=m.choices[0].message.content;if(d.length<5)return;const f=d.replace(/['"]/g,"");if(["response#",'"response#"',"'response#'"].some((e=>f.toLowerCase().startsWith(e))))return;if(["task#",'"task#"',"'task#'"].every((e=>!f.toLowerCase().startsWith(e))))return;const g=d.substring(5).trim();if(!(e=>/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(e))(g))return;if(!o[g])return;const y=o[g],x=y.paramDescriptions&&0!==y.paramDescriptions.length?y.paramDescriptions:[];return{taskId:g,description:y.description,paramDescriptions:x}},d=e=>{console.warn("[33m"+e+"[0m")},f={chat:async(e,n)=>{const o=new t({apiKey:n.config?.apiKey||s.env.OPENAI_API_KEY||""}),r=[];if(n.getContextItems){const e=n.getLlmInstructions(),t=await n.getContextItems();t&&r.push({role:"system",content:u(t,e)})}n.conversationHistory&&n.conversationHistory.forEach((e=>{r.push({role:"ai"===e.role?"assistant":"system"===e.role?"system":"user",content:e.message})})),r.push({role:"user",content:e});const a=await o.chat.completions.create({stream:!1,model:n.config?.chatModel||p,messages:r});return a.choices&&0!==a.choices.length&&a.choices[0].message.content?{success:!0,message:a.choices[0].message.content}:{success:!1,error:"No response from OpenAI."}},"chat-stream":async(e,n,o)=>{const r=new t({apiKey:o.config?.apiKey||s.env.OPENAI_API_KEY||""}),a=[];if(o.getContextItems){const e=o.getLlmInstructions(),t=await o.getContextItems();t&&a.push({role:"system",content:u(t,e)})}o.conversationHistory&&o.conversationHistory.forEach((e=>{a.push({role:"ai"===e.role?"assistant":"system"===e.role?"system":"user",content:e.message})})),a.push({role:"user",content:e});try{let e=(await r.chat.completions.create({stream:!0,model:o.config?.chatModel||p,messages:a}))[Symbol.asyncIterator](),t=await e.next();for(;!t.done;){const s=t.value;if("stop"===(s.choices?.length>0?s.choices[0].finish_reason:void 0))break;const o=s.choices?.[0].delta.content;"string"==typeof o?n.next(o):d(`Undecodable message - value: ${s}`),t=await e.next()}n.complete()}catch(e){d(`Error: ${e}`)}},assist:async(e,s)=>{const n=s.getLlmInstructions(),r=s.getContextItems?await s.getContextItems():void 0,a=await m(e,r,s),i=a?await(async(e,s,n,o)=>{if(!n)return;const r=o.getLlmInstructions(),a=((e,t)=>{if("string"!=typeof t.parameterValues&&!t.parameterValues)return;const s=t.parameterValues,n="["+e.paramDescriptions.map(((e,t)=>`<Parameter#${t+1}>`)).join(", ")+"]";let o="";return e.paramDescriptions.forEach(((e,t)=>{o+=`The value for the parameter <Parameter#${t+1}> : ${e}\n`})),s.replace("{{taskId}}",e.taskId).replace("{{instructionsToReplaceParams}}",o).replace("{{paramsArrayTemplate}}",n)})(s,r);if(!a)return;const i=[],c=u(n,r);c&&i.push({role:"system",content:c});const h=new t({apiKey:o.config?.apiKey});i.push({role:"system",content:a}),i.push({role:"user",content:e});const m=o.config?.chatModel||p,d=await h.chat.completions.create({stream:!1,model:m,messages:i});if(!(d.choices&&d.choices.length>0&&d.choices[0].message.content))return;const f=d.choices[0].message.content;try{const e=JSON.parse(f);return Array.isArray(e)?e:void l("The response is not an array.")}catch(e){return void l("Error parsing param values: "+e)}})(e,a,r,s):void 0,c=new t({apiKey:s.config?.apiKey||o.env.OPENAI_API_KEY||""}),h=[],d=u(r,n);d&&h.push({role:"system",content:d}),a&&i&&h.push({role:"system",content:`Following the next message, the task "${a.taskId}" will be performed. Respond with a short message based on the user prompt. Your response should be related to the task and should be brief. Do not overload the response with too much information since a task is going to be performed.`}),s.conversationHistory?.forEach((e=>{h.push({role:"ai"===e.role?"assistant":"system"===e.role?"system":"user",content:e.message})})),h.push({role:"user",content:e});const f=await c.chat.completions.create({stream:!1,model:s.config?.chatModel||p,messages:h});if(!f.choices||0===f.choices.length||!f.choices[0].message.content)return{success:!1,error:"No response from OpenAI."};const g=f.choices[0].message.content;return a&&i?{success:!0,message:g,task:{taskId:a.taskId,parameters:i}}:{success:!0,message:g}},"create-context":async(e,t)=>{let s;do{s=Math.random().toString(36).substring(2,14),i[s]&&(s="")}while(!s);if(c[s]={},void 0===e)return i[s]={},{success:!0,contextId:s};const n=Object.keys(e);return i[s]=n.reduce(((t,s)=>(t[s]={itemId:s,...e[s]},t)),{}),{success:!0,contextId:s}},"discard-context":async(e,t)=>e&&i[e]?(i[e]=void 0,delete i[e],c[e]=void 0,delete c[e],{success:!0}):{success:!1,error:"Context not found"},"get-context":async(e,t,s,n)=>{if(!e||!i[e])return{success:!1,error:"Context not found"};const o=i[e],r=c[e];return t?o&&o[t]||r&&r[t]?{success:!0,items:o&&o[t]?{[t]:o[t]}:void 0,tasks:r&&r[t]?{[t]:r[t]}:void 0}:{success:!1,error:"Item not found"}:{success:!0,items:o,tasks:r}},"reset-items":async(e,t,s)=>{if(!i[e])return{success:!1,error:"Context not found"};if(!t)return i[e]={},{success:!0};const n=Object.keys(t);return i[e]=n.reduce(((e,s)=>{const n=t[s];return{...e,[s]:{...n,itemId:s}}}),{}),{success:!0}},"update-items":async(e,t,s)=>{const n=i[e];if(!n)return{success:!1,error:"Context not found"};const o=Object.keys(t);for(const e of o){const s=t[e];void 0!==s&&(n[e]={...n[e],...s,itemId:e})}return{success:!0}},"remove-items":async(e,t,s)=>{const n=i[e];if(!n)return{success:!1,error:"Context not found"};for(const e of t)delete n[e];return{success:!0}},"reset-tasks":async(e,t,s)=>{if(!c[e])return{success:!1,error:"Context not found"};if(void 0===t)return c[e]={},{success:!0};const n=Object.keys(t);return c[e]=n.reduce(((e,s)=>{const n=t[s];return{...e,[s]:{...n,taskId:s}}}),{}),{success:!0}},"update-tasks":async(e,t,s)=>{const n=c[e];if(!n)return{success:!1,error:"Context not found"};const o=Object.keys(t);for(const e of o){const s=t[e];void 0!==s&&(n[e]={...n[e],...s,taskId:e})}return{success:!0}},"remove-tasks":async(e,t,s)=>{const n=c[e];if(!n)return{success:!1,error:"Context not found"};for(const e of t)delete n[e];return{success:!0}}};e.actionIds=r,e.asOpenAiChatModel=e=>{if(h.includes(e))return e},e.asValidActionId=e=>a(e)?e:void 0,e.createRuntime=(e,t,s)=>({run:(n,...o)=>{const r=e[n];if(!r)throw new Error("Unsupported action");const a=Array.isArray(o)&&o.length>0?o.slice(0,-1):[],i=!t||0===Object.keys(t).length,c=i?{context:"The conversation is taking as part while user is using a web or mobile application.\nBelow is a JSON object that contains contextual information about user's session.\nThis context data should be taken into account when generating a response.\nYou should not display JSON code from the context, but rather use it to\ngenerate a response that is relevant to the user based on that context.\n\nContext JSON object:\n\n{{context}}\n",taskName:'The conversation is taking as part while user is using a web or mobile application.\nThe previous message contains information about the user\'s context.\n\nBelow is a Javascript array with a list of tasks that the user may expect to be performed by the application.\nThe object contains a task identifier (string)\n\nTASKS LIST:\n\n{{tasks}}\n\nWhile the user is interacting with the application, they can either expect a response, or they can expect a\ntask to be performed by the application.\n\nThe next message is going to be a prompt from a user.\nYour job is to determine whether the user expects a response or a task.\nIf the user expects a response, you must reply with the string "response#".\n\nIf the user expects a task, you must reply with the string that matches the following format:\n\n"task#<TASK NAME>"\n\nWhere:\n\n<Task Name> should be replaced with the name of the task as it appears in the TASKS LIST.\n\nIf you think that the task that the user expects is not in the TASKS LIST, you should reply with the string "response#".\n\nDo not provide a direct response to the user\'s message.\nOnly analyze the message and determine what the user expects.\nStrictly respond with a string with the format "task#<TASK NAME>" or with "response#".\nIf you think that the user expects only a response, reply by one single word: "response#".\n',parameterValues:"The conversation is taking part while user is using a web or mobile application.\nThe previous message contains information about the user's context.\n\nWe know that the user would like to execute a function with the identifier: {{taskId}}\nThis function is a Javascript function that is part of the application. Your responsibility is to determine the\nvalues of the parameters that should be passed to this {{taskId}} function based on the user context, the conversation\nhistory, the user message, the taskId, and the parameter descriptions provided below.\n\nBelow is Javascript table that should be used as a template to fill in the values of the parameters:\n\nTHE TEMPLATE:\n\n{{paramsArrayTemplate}}\n\nUse the instructions below to fill in the values of the parameters.\n\nINSTRUCTIONS:\n\n{{instructionsToReplaceParams}}\n\nEach parameter marked with the notation <Parameter#(index)> (where index is a number) should be replaced with a\nvalue that will be passed to the function. Each value should either be a string (between double quotes), a number,\na boolean, or null (if you are unable to determine the value of the parameter).\n\nUse information from the context, from the conversation history, from the user input, and the task ID to\ndetermine the values of the parameters.\n\nStrictly respond with a valid and well-structured and flat Javascript array that starts with [ and ends with ].\nIf you are unable to determine the value of a specific parameter, use null for.\nIf you are unable to process the request, response with null.\n\nBe smart and don't mislead the user.\nDo not ask the user for more information than what is already available.\nReply on the INSTRUCTIONS to fill in the values of the parameters.\nYou can make it!\n"}:{},u=i?{context:t?.context??c.context,parameterValues:t?.parameterValues??c.parameterValues,taskName:t?.taskName??c.taskName}:t,h={config:s,getLlmInstructions:()=>u},p=Array.isArray(o)&&o.length>0?o[o.length-1]:void 0;"object"==typeof p&&null!==p&&("string"==typeof p.contextId&&(h.contextId=p.contextId),Array.isArray(p.conversationHistory)&&(h.conversationHistory=p.conversationHistory),"function"==typeof p.getContextItems&&(h.getContextItems=p.getContextItems),"function"==typeof p.getContextItem&&(h.getContextItem=p.getContextItem),"function"==typeof p.getContextTasks&&(h.getContextTasks=p.getContextTasks));const l=h.contextId;return l&&!h.getContextItems&&(h.getContextItems=async t=>{const s=await e["get-context"](l,t,"data",h);if(s&&s.success)return s.items}),l&&!h.getContextTasks&&(h.getContextTasks=async t=>{const s=await e["get-context"](l,t,"task",h);if(s&&s.success)return s.tasks}),r(...a,h)}}),e.defaultActionHandlers=f,e.isValidActionId=a,e.openAiDefaultChatModel=p,e.supportedOpenAiChatModels=h})); | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("openai"),require("process")):"function"==typeof define&&define.amd?define(["exports","openai","process"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self)["@nlbridge/core"]={},e.OpenAI,e.process)}(this,(function(e,t,s){"use strict";function n(e){var t=Object.create(null);return e&&Object.keys(e).forEach((function(s){if("default"!==s){var n=Object.getOwnPropertyDescriptor(e,s);Object.defineProperty(t,s,n.get?n:{enumerable:!0,get:function(){return e[s]}})}})),t.default=e,Object.freeze(t)}var o=n(s);const r=["chat","chat-stream","assist","create-context","discard-context","get-context","reset-context-items","update-context-items","remove-context-items","reset-context-tasks","update-context-tasks","remove-context-tasks"],a=e=>r.includes(e),i={},c={},u=(e,t)=>{const s=JSON.stringify(e,null,2);return"string"==typeof t.context&&t.context.length>0?t.context.replace("{{context}}","\n\n"+s+"\n\n"):"Use the the JSON object below as a context for the conversation that you are having with the user:\n\n"+s+"\n\n"},h=["gpt-4-0125-preview","gpt-4-turbo-preview","gpt-4-1106-preview","gpt-4-vision-preview","gpt-4","gpt-4-0314","gpt-4-0613","gpt-4-32k","gpt-4-32k-0314","gpt-4-32k-0613","gpt-3.5-turbo","gpt-3.5-turbo-16k","gpt-3.5-turbo-0301","gpt-3.5-turbo-0613","gpt-3.5-turbo-1106","gpt-3.5-turbo-0125","gpt-3.5-turbo-16k-0613"],l="gpt-3.5-turbo",p=e=>{console.error("[31m"+e+"[0m")},m=async(e,s,n)=>{if(!s)return;if(!n.getContextTasks)return;const o=await n.getContextTasks();if(!o)return;const r=n.getLlmInstructions(),a=n.config?.chatModel||l,i=u(s,r),c=((e,t)=>{const s=JSON.stringify(e,null,2);if("string"!=typeof t.taskName&&!t.taskName)return;return t.taskName.replace("{{tasks}}","\n\n"+s+"\n\n")})(o,r);if(!c||!i)return;const h=[],p=new t({apiKey:n.config?.apiKey});h.push({role:"system",content:i}),h.push({role:"system",content:c}),h.push({role:"user",content:e});const m=await p.chat.completions.create({stream:!1,model:a,messages:h});if(!(m.choices&&m.choices.length>0&&m.choices[0].message.content))return;const d=m.choices[0].message.content;if(d.length<5)return;const f=d.replace(/['"]/g,"");if(["response#",'"response#"',"'response#'"].some((e=>f.toLowerCase().startsWith(e))))return;if(["task#",'"task#"',"'task#'"].every((e=>!f.toLowerCase().startsWith(e))))return;const g=d.substring(5).trim();if(!(e=>/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(e))(g))return;if(!o[g])return;const y=o[g],x=y.paramDescriptions&&0!==y.paramDescriptions.length?y.paramDescriptions:[];return{taskId:g,description:y.description,paramDescriptions:x}},d=e=>{console.warn("[33m"+e+"[0m")},f={chat:async(e,n)=>{console.log("openAiChat handler");const o=n.getLlmInstructions(),r=n.getContextItems?await n.getContextItems():void 0,a=new t({apiKey:n.config?.apiKey||s.env.OPENAI_API_KEY||""}),i=[];i.push({role:"system",content:u(r,o)}),n.conversationHistory?.forEach((e=>{i.push({role:"ai"===e.role?"assistant":"system"===e.role?"system":"user",content:e.message})})),i.push({role:"user",content:e}),console.log("Conversation history from chat:"),console.dir(n.conversationHistory),console.log("Messages to send:"),console.dir(i);const c=await a.chat.completions.create({stream:!1,model:n.config?.chatModel||l,messages:i});return c.choices&&0!==c.choices.length&&c.choices[0].message.content?{success:!0,message:c.choices[0].message.content}:{success:!1,error:"No response from OpenAI."}},"chat-stream":async(e,n,o)=>{const r=new t({apiKey:o.config?.apiKey||s.env.OPENAI_API_KEY||""}),a=[];if(o.getContextItems){const e=o.getLlmInstructions(),t=await o.getContextItems();t&&a.push({role:"system",content:u(t,e)})}o.conversationHistory&&o.conversationHistory.forEach((e=>{a.push({role:"ai"===e.role?"assistant":"system"===e.role?"system":"user",content:e.message})})),a.push({role:"user",content:e});try{let e=(await r.chat.completions.create({stream:!0,model:o.config?.chatModel||l,messages:a}))[Symbol.asyncIterator](),t=await e.next();for(;!t.done;){const s=t.value;if("stop"===(s.choices?.length>0?s.choices[0].finish_reason:void 0))break;const o=s.choices?.[0].delta.content;"string"==typeof o?n.next(o):d(`Undecodable message - value: ${s}`),t=await e.next()}n.complete()}catch(e){d(`Error: ${e}`)}},assist:async(e,s)=>{console.log("openAiAssist handler");const n=s.getLlmInstructions(),r=s.getContextItems?await s.getContextItems():void 0,a=await m(e,r,s),i=a?await(async(e,s,n,o)=>{if(!n)return;const r=o.getLlmInstructions(),a=((e,t)=>{if("string"!=typeof t.parameterValues&&!t.parameterValues)return;const s=t.parameterValues,n="["+e.paramDescriptions.map(((e,t)=>`<Parameter#${t+1}>`)).join(", ")+"]";let o="";return e.paramDescriptions.forEach(((e,t)=>{o+=`The value for the parameter <Parameter#${t+1}> : ${e}\n`})),s.replace("{{taskId}}",e.taskId).replace("{{instructionsToReplaceParams}}",o).replace("{{paramsArrayTemplate}}",n)})(s,r);if(!a)return;const i=[],c=u(n,r);c&&i.push({role:"system",content:c});const h=new t({apiKey:o.config?.apiKey});i.push({role:"system",content:a}),i.push({role:"user",content:e});const m=o.config?.chatModel||l,d=await h.chat.completions.create({stream:!1,model:m,messages:i});if(!(d.choices&&d.choices.length>0&&d.choices[0].message.content))return;const f=d.choices[0].message.content;try{const e=JSON.parse(f);return Array.isArray(e)?e:void p("The response is not an array.")}catch(e){return void p("Error parsing param values: "+e)}})(e,a,r,s):void 0,c=new t({apiKey:s.config?.apiKey||o.env.OPENAI_API_KEY||""}),h=[];h.push({role:"system",content:u(r,n)}),a&&i&&h.push({role:"system",content:`Following the next message, the task "${a.taskId}" will be performed. Respond with a short message based on the user prompt. Your response should be related to the task and should be brief. Do not overload the response with too much information since a task is going to be performed.`}),s.conversationHistory?.forEach((e=>{h.push({role:"ai"===e.role?"assistant":"system"===e.role?"system":"user",content:e.message})})),h.push({role:"user",content:e}),console.log("Conversation history from chat:"),console.dir(s.conversationHistory),console.log("Messages to send:"),console.dir(h);const d=await c.chat.completions.create({stream:!1,model:s.config?.chatModel||l,messages:h});if(!d.choices||0===d.choices.length||!d.choices[0].message.content)return{success:!1,error:"No response from OpenAI."};const f=d.choices[0].message.content;return a&&i?{success:!0,message:f,task:{taskId:a.taskId,parameters:i}}:{success:!0,message:f}},"create-context":async(e,t)=>{let s;do{s=Math.random().toString(36).substring(2,14),i[s]&&(s="")}while(!s);if(c[s]={},void 0===e)return i[s]={},{success:!0,contextId:s};const n=Object.keys(e);return i[s]=n.reduce(((t,s)=>(t[s]={itemId:s,...e[s]},t)),{}),{success:!0,contextId:s}},"discard-context":async(e,t)=>e&&i[e]?(i[e]=void 0,delete i[e],c[e]=void 0,delete c[e],{success:!0}):{success:!1,error:"Context not found"},"get-context":async(e,t,s,n)=>{if(!e||!i[e])return{success:!1,error:"Context not found"};const o=i[e],r=c[e];return t?o&&o[t]||r&&r[t]?{success:!0,items:o&&o[t]?{[t]:o[t]}:void 0,tasks:r&&r[t]?{[t]:r[t]}:void 0}:{success:!1,error:"Item not found"}:{success:!0,items:o,tasks:r}},"reset-items":async(e,t,s)=>{if(!i[e])return{success:!1,error:"Context not found"};if(!t)return i[e]={},{success:!0};const n=Object.keys(t);return i[e]=n.reduce(((e,s)=>{const n=t[s];return{...e,[s]:{...n,itemId:s}}}),{}),{success:!0}},"update-items":async(e,t,s)=>{const n=i[e];if(!n)return{success:!1,error:"Context not found"};const o=Object.keys(t);for(const e of o){const s=t[e];void 0!==s&&(n[e]={...n[e],...s,itemId:e})}return{success:!0}},"remove-items":async(e,t,s)=>{const n=i[e];if(!n)return{success:!1,error:"Context not found"};for(const e of t)delete n[e];return{success:!0}},"reset-tasks":async(e,t,s)=>{if(!c[e])return{success:!1,error:"Context not found"};if(void 0===t)return c[e]={},{success:!0};const n=Object.keys(t);return c[e]=n.reduce(((e,s)=>{const n=t[s];return{...e,[s]:{...n,taskId:s}}}),{}),{success:!0}},"update-tasks":async(e,t,s)=>{const n=c[e];if(!n)return{success:!1,error:"Context not found"};const o=Object.keys(t);for(const e of o){const s=t[e];void 0!==s&&(n[e]={...n[e],...s,taskId:e})}return{success:!0}},"remove-tasks":async(e,t,s)=>{const n=c[e];if(!n)return{success:!1,error:"Context not found"};for(const e of t)delete n[e];return{success:!0}}};e.actionIds=r,e.asOpenAiChatModel=e=>{if(h.includes(e))return e},e.asValidActionId=e=>a(e)?e:void 0,e.createRuntime=(e,t,s)=>({run:(n,...o)=>{const r=e[n];if(!r)throw new Error("Unsupported action");const a=Array.isArray(o)&&o.length>0?o.slice(0,-1):[],i=!t||0===Object.keys(t).length,c=i?{context:"The conversation is taking as part while user is using a web or mobile application.\nBelow is a JSON object that contains contextual information about user's session.\nThis context data should be taken into account when generating a response.\nYou should not display JSON code from the context, but rather use it to\ngenerate a response that is relevant to the user based on that context.\n\nContext JSON object:\n\n{{context}}\n",taskName:'The conversation is taking as part while user is using a web or mobile application.\nThe previous message contains information about the user\'s context.\n\nBelow is a Javascript array with a list of tasks that the user may expect to be performed by the application.\nThe object contains a task identifier (string)\n\nTASKS LIST:\n\n{{tasks}}\n\nWhile the user is interacting with the application, they can either expect a response, or they can expect a\ntask to be performed by the application.\n\nThe next message is going to be a prompt from a user.\nYour job is to determine whether the user expects a response or a task.\nIf the user expects a response, you must reply with the string "response#".\n\nIf the user expects a task, you must reply with the string that matches the following format:\n\n"task#<TASK NAME>"\n\nWhere:\n\n<Task Name> should be replaced with the name of the task as it appears in the TASKS LIST.\n\nIf you think that the task that the user expects is not in the TASKS LIST, you should reply with the string "response#".\n\nDo not provide a direct response to the user\'s message.\nOnly analyze the message and determine what the user expects.\nStrictly respond with a string with the format "task#<TASK NAME>" or with "response#".\nIf you think that the user expects only a response, reply by one single word: "response#".\n',parameterValues:"The conversation is taking part while user is using a web or mobile application.\nThe previous message contains information about the user's context.\n\nWe know that the user would like to execute a function with the identifier: {{taskId}}\nThis function is a Javascript function that is part of the application. Your responsibility is to determine the\nvalues of the parameters that should be passed to this {{taskId}} function based on the user context, the conversation\nhistory, the user message, the taskId, and the parameter descriptions provided below.\n\nBelow is Javascript table that should be used as a template to fill in the values of the parameters:\n\nTHE TEMPLATE:\n\n{{paramsArrayTemplate}}\n\nUse the instructions below to fill in the values of the parameters.\n\nINSTRUCTIONS:\n\n{{instructionsToReplaceParams}}\n\nEach parameter marked with the notation <Parameter#(index)> (where index is a number) should be replaced with a\nvalue that will be passed to the function. Each value should either be a string (between double quotes), a number,\na boolean, or null (if you are unable to determine the value of the parameter).\n\nUse information from the context, from the conversation history, from the user input, and the task ID to\ndetermine the values of the parameters.\n\nStrictly respond with a valid and well-structured and flat Javascript array that starts with [ and ends with ].\nIf you are unable to determine the value of a specific parameter, use null for.\nIf you are unable to process the request, response with null.\n\nBe smart and don't mislead the user.\nDo not ask the user for more information than what is already available.\nReply on the INSTRUCTIONS to fill in the values of the parameters.\nYou can make it!\n"}:{},u=i?{context:t?.context??c.context,parameterValues:t?.parameterValues??c.parameterValues,taskName:t?.taskName??c.taskName}:t,h={config:s,getLlmInstructions:()=>u},l=Array.isArray(o)&&o.length>0?o[o.length-1]:void 0;"object"==typeof l&&null!==l&&("string"==typeof l.contextId&&(h.contextId=l.contextId),Array.isArray(l.conversationHistory)&&(h.conversationHistory=l.conversationHistory),"function"==typeof l.getContextItems&&(h.getContextItems=l.getContextItems),"function"==typeof l.getContextItem&&(h.getContextItem=l.getContextItem),"function"==typeof l.getContextTasks&&(h.getContextTasks=l.getContextTasks));const p=h.contextId;return p&&!h.getContextItems&&(h.getContextItems=async t=>{const s=await e["get-context"](p,t,"data",h);if(s&&s.success)return s.items}),p&&!h.getContextTasks&&(h.getContextTasks=async t=>{const s=await e["get-context"](p,t,"task",h);if(s&&s.success)return s.tasks}),r(...a,h)}}),e.defaultActionHandlers=f,e.isValidActionId=a,e.openAiDefaultChatModel=l,e.supportedOpenAiChatModels=h})); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
48565
310
1