diff --git a/404.html b/404.html index e6161a23..c6680912 100644 --- a/404.html +++ b/404.html @@ -4,8 +4,8 @@ Page Not Found | TaskWeaver - - + +
Skip to main content

Page Not Found

We could not find what you were looking for.

Please contact the owner of the site that linked you to the original URL and let them know their link is broken.

diff --git a/assets/images/taskweaver_arch-5ec2a704cfc8e6939f7140fe6d6727f9.png b/assets/images/taskweaver_arch-5ec2a704cfc8e6939f7140fe6d6727f9.png new file mode 100644 index 00000000..d884f973 Binary files /dev/null and b/assets/images/taskweaver_arch-5ec2a704cfc8e6939f7140fe6d6727f9.png differ diff --git a/assets/js/03e8cedb.9a2b7dab.js b/assets/js/03e8cedb.9a2b7dab.js new file mode 100644 index 00000000..7784e8f8 --- /dev/null +++ b/assets/js/03e8cedb.9a2b7dab.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1290],{901:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>l,frontMatter:()=>a,metadata:()=>o,toc:()=>d});var s=n(5893),r=n(1151);const a={},i="Terminal",o={id:"usage/cmd",title:"Terminal",description:"This is the command line interface for TaskWeaver. You can interact with TaskWeaver through this interface.",source:"@site/docs/usage/cmd.md",sourceDirName:"usage",slug:"/usage/cmd",permalink:"/TaskWeaver/docs/usage/cmd",draft:!1,unlisted:!1,editUrl:"https://github.com/microsoft/TaskWeaver/tree/main/website/docs/usage/cmd.md",tags:[],version:"current",frontMatter:{},sidebar:"documentSidebar",previous:{title:"Usage Options",permalink:"/TaskWeaver/docs/usage"},next:{title:"Web UI",permalink:"/TaskWeaver/docs/usage/webui"}},c={},d=[];function h(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.h1,{id:"terminal",children:"Terminal"}),"\n",(0,s.jsx)(t.p,{children:"This is the command line interface for TaskWeaver. You can interact with TaskWeaver through this interface."}),"\n",(0,s.jsxs)(t.p,{children:["Follow the instruction in ",(0,s.jsx)(t.a,{href:"/TaskWeaver/docs/quickstart",children:"Quick Start"})," to clone the repository and fill in the necessary configurations."]}),"\n",(0,s.jsx)(t.p,{children:"Run the following command in terminal."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"# assume you are in the TaskWeaver folder\npython -m taskweaver -p ./project/ # -p is the path to the project directory\n"})}),"\n",(0,s.jsx)(t.p,{children:"This will start the TaskWeaver process, and you can interact with it through the command line interface.\nIf everything goes well, you will see the following prompt:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"=========================================================\n _____ _ _ __\n|_ _|_ _ ___| | _ | | / /__ ____ __ _____ _____\n | |/ _` / __| |/ /| | /| / / _ \\/ __ `/ | / / _ \\/ ___/\n | | (_| \\__ \\ < | |/ |/ / __/ /_/ /| |/ / __/ /\n |_|\\__,_|___/_|\\_\\|__/|__/\\___/\\__,_/ |___/\\___/_/\n=========================================================\nTaskWeaver: I am TaskWeaver, an AI assistant. To get started, could you please enter your request?\nHuman: ___\n"})}),"\n",(0,s.jsxs)(t.p,{children:["We have provided a set of commands to interact with TaskWeaver. You can type ",(0,s.jsx)(t.code,{children:"help"})," to see the list of available commands.\nAll commands start with a ",(0,s.jsx)(t.code,{children:"/"})," character. For example, you can type ",(0,s.jsx)(t.code,{children:"/help"})," to see the list of available commands."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:" TaskWeaver \u25b6 I am TaskWeaver, an AI assistant. To get started, could you please enter your request?\n Human \u25b6 /help\n\nTaskWeaver Chat Console\n-----------------------\n/load : load a file\n/info: print the information of the current session\n/reset: reset the session\n/clear: clear the console\n/exit: exit the chat console\n/help: print this help message\n/save: save the chat history of the current session for experience extraction\n"})}),"\n",(0,s.jsx)(t.p,{children:"The table of commands supported by TaskWeaver is as follows:"}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Command"}),(0,s.jsx)(t.th,{children:"Description"})]})}),(0,s.jsxs)(t.tbody,{children:[(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"/load "})}),(0,s.jsx)(t.td,{children:"Load a file by its absolute path, e.g., /load /home/taskweaver/sample.csv"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"/info"})}),(0,s.jsx)(t.td,{children:"Print the session id and the active roles of the current session"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"/reset"})}),(0,s.jsx)(t.td,{children:"Reset the current session and start a new session"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"/clear"})}),(0,s.jsx)(t.td,{children:"Clear the console content"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"/exit"})}),(0,s.jsx)(t.td,{children:"Exit the chat console"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"/help"})}),(0,s.jsx)(t.td,{children:"Print the help message"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"/save"})}),(0,s.jsx)(t.td,{children:"Save the chat history of the current session for experience extraction"})]})]})]}),"\n",(0,s.jsx)(t.admonition,{type:"tip",children:(0,s.jsxs)(t.p,{children:["When TaskWeaver runs generated code, the CWD (current working directory) is set to the ",(0,s.jsx)(t.code,{children:"project/workspace/session_id/cwd"})," directory.\nIf you need to use relative paths in the generated code, the ",(0,s.jsx)(t.code,{children:"cwd"})," directory should be the base path."]})})]})}function l(e={}){const{wrapper:t}={...(0,r.a)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},1151:(e,t,n)=>{n.d(t,{Z:()=>o,a:()=>i});var s=n(7294);const r={},a=s.createContext(r);function i(e){const t=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),s.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/03e8cedb.f46f2851.js b/assets/js/03e8cedb.f46f2851.js deleted file mode 100644 index b9edb4da..00000000 --- a/assets/js/03e8cedb.f46f2851.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1290],{901:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>d,frontMatter:()=>r,metadata:()=>i,toc:()=>l});var s=t(5893),a=t(1151);const r={},o="Terminal",i={id:"usage/cmd",title:"Terminal",description:"1. Follow the instruction in Quick Start to clone the repo and make configurations",source:"@site/docs/usage/cmd.md",sourceDirName:"usage",slug:"/usage/cmd",permalink:"/TaskWeaver/docs/usage/cmd",draft:!1,unlisted:!1,editUrl:"https://github.com/microsoft/TaskWeaver/tree/main/website/docs/usage/cmd.md",tags:[],version:"current",frontMatter:{},sidebar:"documentSidebar",previous:{title:"Usage Options",permalink:"/TaskWeaver/docs/usage"},next:{title:"Web UI",permalink:"/TaskWeaver/docs/usage/webui"}},c={},l=[];function _(e){const n={a:"a",code:"code",h1:"h1",li:"li",ol:"ol",p:"p",pre:"pre",...(0,a.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"terminal",children:"Terminal"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["Follow the instruction in ",(0,s.jsx)(n.a,{href:"/TaskWeaver/docs/quickstart",children:"Quick Start"})," to clone the repo and make configurations"]}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/microsoft/TaskWeaver.git\ncd TaskWeaver\n# install the requirements\npip install -r requirements.txt\n"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n"llm.api_key": "the api key",\n"llm.model": "the model name, e.g., gpt-4"\n}\n'})}),"\n",(0,s.jsxs)(n.ol,{start:"2",children:["\n",(0,s.jsx)(n.li,{children:"Run the following command in terminal."}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"# assume you are in the taskweaver folder\n# -p is the path to the project directory\npython -m taskweaver -p ./project/\n"})}),"\n",(0,s.jsx)(n.p,{children:"This will start the TaskWeaver process and you can interact with it through the command line interface.\nIf everything goes well, you will see the following prompt:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"=========================================================\n _____ _ _ __\n|_ _|_ _ ___| | _ | | / /__ ____ __ _____ _____\n | |/ _` / __| |/ /| | /| / / _ \\/ __ `/ | / / _ \\/ ___/\n | | (_| \\__ \\ < | |/ |/ / __/ /_/ /| |/ / __/ /\n |_|\\__,_|___/_|\\_\\|__/|__/\\___/\\__,_/ |___/\\___/_/\n=========================================================\nTaskWeaver: I am TaskWeaver, an AI assistant. To get started, could you please enter your request?\nHuman: ___\n"})})]})}function d(e={}){const{wrapper:n}={...(0,a.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(_,{...e})}):_(e)}},1151:(e,n,t)=>{t.d(n,{Z:()=>i,a:()=>o});var s=t(7294);const a={},r=s.createContext(a);function o(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:o(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/1db64337.e8dee0f1.js b/assets/js/1db64337.e8dee0f1.js new file mode 100644 index 00000000..ba0842db --- /dev/null +++ b/assets/js/1db64337.e8dee0f1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1372],{9674:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>r,toc:()=>d});var n=s(5893),i=s(1151);const a={},o="Overview",r={id:"overview",title:"Overview",description:"{s.d(t,{Z:()=>n});const n=s.p+"assets/images/taskweaver_arch-5ec2a704cfc8e6939f7140fe6d6727f9.png"},1151:(e,t,s)=>{s.d(t,{Z:()=>r,a:()=>o});var n=s(7294);const i={},a=n.createContext(i);function o(e){const t=n.useContext(a);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),n.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/1db64337.ff141280.js b/assets/js/1db64337.ff141280.js deleted file mode 100644 index 585dc70c..00000000 --- a/assets/js/1db64337.ff141280.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1372],{9674:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>r,toc:()=>d});var n=s(5893),i=s(1151);const a={},o="Overview",r={id:"overview",title:"Overview",description:"{s.d(t,{Z:()=>r,a:()=>o});var n=s(7294);const i={},a=n.createContext(i);function o(e){const t=n.useContext(a);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),n.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/2114d3cd.793259c4.js b/assets/js/2114d3cd.793259c4.js new file mode 100644 index 00000000..61e1cb9a --- /dev/null +++ b/assets/js/2114d3cd.793259c4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9190],{563:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>a,default:()=>u,frontMatter:()=>s,metadata:()=>i,toc:()=>h});var r=t(5893),o=t(1151);const s={},a="Prompt Compression",i={id:"advanced/compression",title:"Prompt Compression",description:"After chatting for a few rounds, the chat history can become quite long, especially when we have code and execution results in it.",source:"@site/docs/advanced/compression.md",sourceDirName:"advanced",slug:"/advanced/compression",permalink:"/TaskWeaver/docs/advanced/compression",draft:!1,unlisted:!1,editUrl:"https://github.com/microsoft/TaskWeaver/tree/main/website/docs/advanced/compression.md",tags:[],version:"current",frontMatter:{},sidebar:"documentSidebar",previous:{title:"Experience",permalink:"/TaskWeaver/docs/customization/experience"},next:{title:"Auto Plugin Selection",permalink:"/TaskWeaver/docs/advanced/plugin_selection"}},d={},h=[{value:"Configurations",id:"configurations",level:2}];function c(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",li:"li",mermaid:"mermaid",p:"p",pre:"pre",ul:"ul",...(0,o.a)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h1,{id:"prompt-compression",children:"Prompt Compression"}),"\n",(0,r.jsx)(n.p,{children:"After chatting for a few rounds, the chat history can become quite long, especially when we have code and execution results in it.\nThis can cause the problem of exceeding the context window of the LLMs.\nTo solve the problem, one way is to summarize the chat history a few rounds ago,\nand only keep the latest rounds of the chat history."}),"\n",(0,r.jsx)(n.p,{children:"Another way is to use a vector database to store the chat history entries, and only retrieve the last few rounds of the relevant\npart given the current user request. However, in TaskWeaver, code is also part of the chat history.\nIt is not an option to skip some intermediate code and execution results in order to correctly\ngenerate the code for the current user request. Therefore, we choose the first way to solve the problem."}),"\n",(0,r.jsx)(n.p,{children:"The following figure shows the idea of chat history summarization where the chat history is divided into two parts:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Rounds to compress: this part is summarized and only the summary is kept in the chat history. If the context_summary\nalready exists, a new summary is generated based on the previous summary adding the rounds to be summarized."}),"\n",(0,r.jsx)(n.li,{children:"Rounds to retain: this part is kept in the chat history without summarization."}),"\n"]}),"\n",(0,r.jsx)(n.mermaid,{value:" flowchart LR\n ConversationSummary--\x3eRound1\n subgraph Rounds to compress \n Round1--\x3eRound2\n end\n subgraph Rounds to retain\n Round2--\x3eRound3--\x3eRound4--\x3eRound5 \n end"}),"\n",(0,r.jsxs)(n.p,{children:["Imagine that, at the beginning, the ConversationSummary is empty.\nOnce the chat history reaches the ",(0,r.jsx)(n.code,{children:"rounds_to_compress"})," (default 2) rounds plus ",(0,r.jsx)(n.code,{children:"rounds_to_retain"})," (default 3) rounds,\nthe ConversationSummary is generated based on the ",(0,r.jsx)(n.code,{children:"rounds_to_compress"})," rounds and the ",(0,r.jsx)(n.code,{children:"rounds_to_retain"})," rounds are kept in the chat history.\nAfter that, there will be only ",(0,r.jsx)(n.code,{children:"rounds_to_retain"})," rounds in the chat history.\nThe next time the chat history reaches the ",(0,r.jsx)(n.code,{children:"rounds_to_compress"})," rounds plus ",(0,r.jsx)(n.code,{children:"rounds_to_retain"})," rounds,\nthe ConversationSummary is generated based on the ",(0,r.jsx)(n.code,{children:"rounds_to_compress"})," rounds and the previous ConversationSummary.\nWe use these two parameters to control the frequency of the chat history summarization."]}),"\n",(0,r.jsx)(n.p,{children:"An example of the chat history summarization in the Code Generator is shown below:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-json",children:'{\n "ConversationSummary": "The user requested the generation of 100 random numbers, which was successfully executed. Then, the user asked to show the top 5 largest numbers from the generated random numbers. The assistant provided a code snippet to sort the generated random numbers in descending order and select the top 5 largest numbers, which was also successfully executed. After that, the user requested to plot the distribution of the 100 numbers, which was successfully executed. The user then asked to count the frequency of numbers in each bin of the histogram and identify the bin with the most numbers for the 0.1 bin width, which was also successfully executed.",\n "Variables": [\n {\n "name": "random_numbers_100",\n "type": "numpy array",\n "description": "An array containing 100 random numbers generated using np.random.rand()"\n },\n {\n "name": "top_5_largest",\n "type": "numpy array",\n "description": "An array containing the top 5 largest numbers from the generated random numbers"\n }\n ]\n}\n'})}),"\n",(0,r.jsx)(n.p,{children:"The JSON object has two fields:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"ConversationSummary: the summary of the chat history."}),"\n",(0,r.jsx)(n.li,{children:"Variables: the variables in the chat history that could be used in the current user request."}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"The chat history summary of the Planner has only the ConversationSummary field."}),"\n",(0,r.jsx)(n.p,{children:"The actual code generated in the summarized rounds is ignored and only the variables are kept in the summary\nso that the LLM can still refer the these variables in future code generation."}),"\n",(0,r.jsxs)(n.p,{children:["One thing to note is that chat history summarization requires call the LLM which incurs additional latency and cost.\nThe prompts for chat history summarization could be found for ",(0,r.jsx)(n.a,{target:"_blank",href:t(9585).Z+"",children:"planner"}),"\nand ",(0,r.jsx)(n.a,{target:"_blank",href:t(6956).Z+"",children:"code generator"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"configurations",children:"Configurations"}),"\n",(0,r.jsxs)(n.p,{children:["As explained above, there are two parameters in controlling the chat history summarization:\n",(0,r.jsx)(n.code,{children:"round_compressor.rounds_to_compress"})," (default 2) and ",(0,r.jsx)(n.code,{children:"round_compressor.rounds_to_retain"})," (default 3).\nTo enable the chat history summarization, you need to set ",(0,r.jsx)(n.code,{children:"planner.prompt_compression"}),"\nand ",(0,r.jsx)(n.code,{children:"code_generator.prompt_compression"})," to ",(0,r.jsx)(n.code,{children:"true"}),"."]})]})}function u(e={}){const{wrapper:n}={...(0,o.a)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(c,{...e})}):c(e)}},6956:(e,n,t)=>{t.d(n,{Z:()=>r});const r=t.p+"assets/files/compression_prompt-b02606dbb37ec1a39beb98a2d45cad99.yaml"},9585:(e,n,t)=>{t.d(n,{Z:()=>r});const r=t.p+"assets/files/compression_prompt-04e803fc1bad28b70d25b824281c0211.yaml"},1151:(e,n,t)=>{t.d(n,{Z:()=>i,a:()=>a});var r=t(7294);const o={},s=r.createContext(o);function a(e){const n=r.useContext(s);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),r.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/2114d3cd.b12d6e47.js b/assets/js/2114d3cd.b12d6e47.js deleted file mode 100644 index 3a11fe28..00000000 --- a/assets/js/2114d3cd.b12d6e47.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[9190],{563:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>a,default:()=>u,frontMatter:()=>s,metadata:()=>i,toc:()=>h});var r=t(5893),o=t(1151);const s={},a="Prompt Compression",i={id:"advanced/compression",title:"Prompt Compression",description:"After chatting for a few rounds, the chat history can become quite long, especially when we have code and execution results in it.",source:"@site/docs/advanced/compression.md",sourceDirName:"advanced",slug:"/advanced/compression",permalink:"/TaskWeaver/docs/advanced/compression",draft:!1,unlisted:!1,editUrl:"https://github.com/microsoft/TaskWeaver/tree/main/website/docs/advanced/compression.md",tags:[],version:"current",frontMatter:{},sidebar:"documentSidebar",previous:{title:"Experience",permalink:"/TaskWeaver/docs/customization/experience"},next:{title:"Code Verification",permalink:"/TaskWeaver/docs/advanced/code_verification"}},d={},h=[{value:"Configurations",id:"configurations",level:2}];function c(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",li:"li",mermaid:"mermaid",p:"p",pre:"pre",ul:"ul",...(0,o.a)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h1,{id:"prompt-compression",children:"Prompt Compression"}),"\n",(0,r.jsx)(n.p,{children:"After chatting for a few rounds, the chat history can become quite long, especially when we have code and execution results in it.\nThis can cause the problem of exceeding the context window of the LLMs.\nTo solve the problem, one way is to summarize the chat history a few rounds ago,\nand only keep the latest rounds of the chat history."}),"\n",(0,r.jsx)(n.p,{children:"Another way is to use a vector database to store the chat history entries, and only retrieve the last few rounds of the relevant\npart given the current user request. However, in TaskWeaver, code is also part of the chat history.\nIt is not an option to skip some intermediate code and execution results in order to correctly\ngenerate the code for the current user request. Therefore, we choose the first way to solve the problem."}),"\n",(0,r.jsx)(n.p,{children:"The following figure shows the idea of chat history summarization where the chat history is divided into two parts:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Rounds to compress: this part is summarized and only the summary is kept in the chat history. If the context_summary\nalready exists, a new summary is generated based on the previous summary adding the rounds to be summarized."}),"\n",(0,r.jsx)(n.li,{children:"Rounds to retain: this part is kept in the chat history without summarization."}),"\n"]}),"\n",(0,r.jsx)(n.mermaid,{value:" flowchart LR\n ConversationSummary--\x3eRound1\n subgraph Rounds to compress \n Round1--\x3eRound2\n end\n subgraph Rounds to retain\n Round2--\x3eRound3--\x3eRound4--\x3eRound5 \n end"}),"\n",(0,r.jsxs)(n.p,{children:["Imagine that, at the beginning, the ConversationSummary is empty.\nOnce the chat history reaches the ",(0,r.jsx)(n.code,{children:"rounds_to_compress"})," (default 2) rounds plus ",(0,r.jsx)(n.code,{children:"rounds_to_retain"})," (default 3) rounds,\nthe ConversationSummary is generated based on the ",(0,r.jsx)(n.code,{children:"rounds_to_compress"})," rounds and the ",(0,r.jsx)(n.code,{children:"rounds_to_retain"})," rounds are kept in the chat history.\nAfter that, there will be only ",(0,r.jsx)(n.code,{children:"rounds_to_retain"})," rounds in the chat history.\nThe next time the chat history reaches the ",(0,r.jsx)(n.code,{children:"rounds_to_compress"})," rounds plus ",(0,r.jsx)(n.code,{children:"rounds_to_retain"})," rounds,\nthe ConversationSummary is generated based on the ",(0,r.jsx)(n.code,{children:"rounds_to_compress"})," rounds and the previous ConversationSummary.\nWe use these two parameters to control the frequency of the chat history summarization."]}),"\n",(0,r.jsx)(n.p,{children:"An example of the chat history summarization in the Code Generator is shown below:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-json",children:'{\n "ConversationSummary": "The user requested the generation of 100 random numbers, which was successfully executed. Then, the user asked to show the top 5 largest numbers from the generated random numbers. The assistant provided a code snippet to sort the generated random numbers in descending order and select the top 5 largest numbers, which was also successfully executed. After that, the user requested to plot the distribution of the 100 numbers, which was successfully executed. The user then asked to count the frequency of numbers in each bin of the histogram and identify the bin with the most numbers for the 0.1 bin width, which was also successfully executed.",\n "Variables": [\n {\n "name": "random_numbers_100",\n "type": "numpy array",\n "description": "An array containing 100 random numbers generated using np.random.rand()"\n },\n {\n "name": "top_5_largest",\n "type": "numpy array",\n "description": "An array containing the top 5 largest numbers from the generated random numbers"\n }\n ]\n}\n'})}),"\n",(0,r.jsx)(n.p,{children:"The JSON object has two fields:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"ConversationSummary: the summary of the chat history."}),"\n",(0,r.jsx)(n.li,{children:"Variables: the variables in the chat history that could be used in the current user request."}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"The chat history summary of the Planner has only the ConversationSummary field."}),"\n",(0,r.jsx)(n.p,{children:"The actual code generated in the summarized rounds is ignored and only the variables are kept in the summary\nso that the LLM can still refer the these variables in future code generation."}),"\n",(0,r.jsxs)(n.p,{children:["One thing to note is that chat history summarization requires call the LLM which incurs additional latency and cost.\nThe prompts for chat history summarization could be found for ",(0,r.jsx)(n.a,{target:"_blank",href:t(9585).Z+"",children:"planner"}),"\nand ",(0,r.jsx)(n.a,{target:"_blank",href:t(6956).Z+"",children:"code generator"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"configurations",children:"Configurations"}),"\n",(0,r.jsxs)(n.p,{children:["As explained above, there are two parameters in controlling the chat history summarization:\n",(0,r.jsx)(n.code,{children:"round_compressor.rounds_to_compress"})," (default 2) and ",(0,r.jsx)(n.code,{children:"round_compressor.rounds_to_retain"})," (default 3).\nTo enable the chat history summarization, you need to set ",(0,r.jsx)(n.code,{children:"planner.prompt_compression"}),"\nand ",(0,r.jsx)(n.code,{children:"code_generator.prompt_compression"})," to ",(0,r.jsx)(n.code,{children:"true"}),"."]})]})}function u(e={}){const{wrapper:n}={...(0,o.a)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(c,{...e})}):c(e)}},6956:(e,n,t)=>{t.d(n,{Z:()=>r});const r=t.p+"assets/files/compression_prompt-b02606dbb37ec1a39beb98a2d45cad99.yaml"},9585:(e,n,t)=>{t.d(n,{Z:()=>r});const r=t.p+"assets/files/compression_prompt-04e803fc1bad28b70d25b824281c0211.yaml"},1151:(e,n,t)=>{t.d(n,{Z:()=>i,a:()=>a});var r=t(7294);const o={},s=r.createContext(o);function a(e){const n=r.useContext(s);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),r.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/2726c345.3b1ff4bb.js b/assets/js/2726c345.3b1ff4bb.js deleted file mode 100644 index b977b10d..00000000 --- a/assets/js/2726c345.3b1ff4bb.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[3450],{286:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>s,metadata:()=>i,toc:()=>l});var o=n(5893),r=n(1151);const s={},a="Telemetry",i={id:"advanced/telemetry",title:"Telemetry",description:"TaskWeaver now supports tracing with OpenTelemetry,",source:"@site/docs/advanced/telemetry.md",sourceDirName:"advanced",slug:"/advanced/telemetry",permalink:"/TaskWeaver/docs/advanced/telemetry",draft:!1,unlisted:!1,editUrl:"https://github.com/microsoft/TaskWeaver/tree/main/website/docs/advanced/telemetry.md",tags:[],version:"current",frontMatter:{},sidebar:"documentSidebar",previous:{title:"CLI Only Mode",permalink:"/TaskWeaver/docs/advanced/cli_only"},next:{title:"FAQ",permalink:"/TaskWeaver/docs/FAQ"}},c={},l=[{value:"How to enable tracing",id:"how-to-enable-tracing",level:2},{value:"Tracing Infrastructure Configuration",id:"tracing-infrastructure-configuration",level:2},{value:"How to view the metrics",id:"how-to-view-the-metrics",level:2},{value:"How to customize tracing",id:"how-to-customize-tracing",level:2}];function h(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",img:"img",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.a)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.h1,{id:"telemetry",children:"Telemetry"}),"\n",(0,o.jsx)(t.p,{children:"TaskWeaver now supports tracing with OpenTelemetry,\nwhich is one of the most popular open-source observability frameworks. This allows you to trace the following:"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsx)(t.li,{children:"Interactions between roles, i.e., the Planner, the CodeInterpreter, and the Executor."}),"\n",(0,o.jsx)(t.li,{children:"The time consumed by each role and major components of TaskWeaver."}),"\n",(0,o.jsx)(t.li,{children:"The prompts sent to the LLM and the responses received from the LLM."}),"\n",(0,o.jsx)(t.li,{children:"The status of the tasks and the errors encountered."}),"\n",(0,o.jsx)(t.li,{children:"The number of tokens consumed by each role."}),"\n"]}),"\n",(0,o.jsx)(t.p,{children:"The following screenshot shows a trace of a simple task: analyzing an uploaded file."}),"\n",(0,o.jsx)(t.p,{children:(0,o.jsx)(t.img,{alt:"Tracing",src:n(6645).Z+"",width:"1859",height:"553"})}),"\n",(0,o.jsx)(t.p,{children:"From this view, you can see the timeline of the task execution, which breaks majorly into\nthree parts:"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsx)(t.li,{children:"The planning phase, where the Planner decides the sub-tasks to be executed."}),"\n",(0,o.jsx)(t.li,{children:"The code generation and execution phase, where the CodeGenerator generates the code and the CodeExecutor executes it."}),"\n",(0,o.jsx)(t.li,{children:"The reply phase, where the Planner sends the reply to the user."}),"\n"]}),"\n",(0,o.jsx)(t.p,{children:"The bars with a black line represent the critical path of the task execution, which is the longest path through the task execution.\nThis is useful for identifying the bottleneck of the task execution.\nWe can clearly see that, currently, the task execution is dominated by the calls to the LLM."}),"\n",(0,o.jsx)(t.p,{children:"We can click the span (a unit of work in the trace) to see the details of the span, including the logs and the attributes."}),"\n",(0,o.jsx)(t.p,{children:"The screenshot below shows the details of the span of Planner's reply function:"}),"\n",(0,o.jsx)(t.p,{children:(0,o.jsx)(t.img,{alt:"Tracing Prompt",src:n(4525).Z+"",width:"1746",height:"541"})}),"\n",(0,o.jsx)(t.p,{children:"From this view, we can see the user query, the prompt sent to the LLM, and the tokens consumed (prompt_size and output_size) by the LLM.\nWe also recorded the generated code, the posts between different roles, etc. in the trace."}),"\n",(0,o.jsx)(t.p,{children:"There are also views of the trace, for example the call graph view, which shows the call hierarchy of the spans.\nHere is the call graph of the trace:"}),"\n",(0,o.jsx)(t.p,{children:(0,o.jsx)(t.img,{alt:"Tracing Call Graph",src:n(5900).Z+"",width:"1785",height:"326"})}),"\n",(0,o.jsx)(t.h2,{id:"how-to-enable-tracing",children:"How to enable tracing"}),"\n",(0,o.jsxs)(t.p,{children:["Tracing is by default disabled. To enable tracing, you need to install packages required by OpenTelemetry.\nPlease check the ",(0,o.jsx)(t.a,{href:"https://opentelemetry.io/docs/languages/python/",children:"OpenTelemetry website"})," for the installation guide.\nIt basically requires you to install the ",(0,o.jsx)(t.code,{children:"opentelemetry-api"}),", ",(0,o.jsx)(t.code,{children:"opentelemetry-sdk"}),", ",(0,o.jsx)(t.code,{children:"opentelemetry-exporter-otlp"}),",\n",(0,o.jsx)(t.code,{children:"opentelemetry-instrumentation"})," and ",(0,o.jsx)(t.code,{children:"tiktoken"})," packages.\nTo count the number of tokens consumed during task execution, you also need to install the ",(0,o.jsx)(t.a,{href:"https://github.com/openai/tiktoken",children:"tiktoken"})," package.\nWe now only support the tokenizers of the OpenAI models.\nAfter installing the packages, you can enable tracing by setting the ",(0,o.jsx)(t.code,{children:"tracing.enabled=true"})," in the project configuration file.\nThe default tokenizer target model is ",(0,o.jsx)(t.code,{children:"gpt-4"}),", if you want to use another model, you can set the ",(0,o.jsx)(t.code,{children:"tracing.tokenizer_target_model"}),"\nin the project configuration file.\nYou can find the available models in the ",(0,o.jsx)(t.a,{href:"https://github.com/openai/tiktoken/blob/main/tiktoken/model.py",children:"tiktoken code"}),"."]}),"\n",(0,o.jsx)(t.p,{children:"A typical configuration for tracing in the project configuration file is as follows:"}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-json",children:'{\n "tracing.enabled": true,\n "tracing.exporter": "otlp",\n "tracing.endpoint": "http://127.0.0.1:4317",\n "tracing.tokenizer_target_model": "gpt-4"\n}\n'})}),"\n",(0,o.jsxs)(t.p,{children:["Next, we need to set up the infrastructure for tracing. The following diagram shows the architecture of a toy tracing system.\nIt is a toy system and the data is not persisted. In a real-world scenario, you need to set up a more robust system.\nThe instrumentation in the TaskWeaver code will send the traces and metrics to the OpenTelemetry collector.\nAn OpenTelemetry collector is a component that receives traces and metrics from the instrumentation, does some processing, and exports them to\nanother collector or a backend. In our case, we configure the collector to export the traces to a ",(0,o.jsx)(t.a,{href:"https://www.jaegertracing.io/",children:"Jaeger"})," backend and the metrics\nto a ",(0,o.jsx)(t.a,{href:"https://prometheus.io/",children:"Prometheus"})," backend.\n",(0,o.jsx)(t.img,{alt:"Tracing Architecture",src:n(3643).Z+"",width:"1027",height:"332"})]}),"\n",(0,o.jsx)(t.p,{children:"You can run the following command to set up the infrastructure:"}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:"cd /TaskWeaver/tracing\ndocker-compose up\n"})}),"\n",(0,o.jsxs)(t.p,{children:["You shall see a bunch of logs from the containers.\nTake a look at the logs to see if there are any errors.\nIf no errors are found, you can access the Prometheus frontend at ",(0,o.jsx)(t.code,{children:"http://localhost:9090"})," and the Jaeger frontend at ",(0,o.jsx)(t.code,{children:"http://localhost:16686"}),".\nIn this setup, we assume you are running the containers on the same machine of TaskWeaver.\nIf you are running the containers on different machines, you need to configure the endpoint of the OpenTelemetry collector in the TaskWeaver configuration file.\nThe default endpoint is ",(0,o.jsx)(t.code,{children:"http://127.0.0.1:4317"}),", you can set the ",(0,o.jsx)(t.code,{children:"tracing.endpoint"})," in the project configuration file to change the endpoint address."]}),"\n",(0,o.jsx)(t.h2,{id:"tracing-infrastructure-configuration",children:"Tracing Infrastructure Configuration"}),"\n",(0,o.jsxs)(t.p,{children:["Both Jaeger and Prometheus are popular open-source monitoring systems. We have prepared a docker-compose file to set up the infrastructure\nin ",(0,o.jsx)(t.code,{children:"/TaskWeaver/tracing_configure/docker-compose.yaml"}),".\nThe content of the file is as follows:"]}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-yaml",children:'version: \'3\'\nservices:\n optl-collector:\n image: otel/opentelemetry-collector:0.96.0\n command: ["--config=/etc/collector-config.yaml"]\n volumes:\n - ./collector-config.yaml:/etc/collector-config.yaml\n ports:\n - "4317:4317" # Expose the gRPC receiver port for the collector\n depends_on:\n - jaeger\n\n jaeger:\n image: jaegertracing/all-in-one:1.54\n ports:\n - "16686:16686" # Jaeger UI\n\n prometheus:\n image: prom/prometheus:latest\n ports:\n - "9090:9090" # Prometheus UI\n volumes:\n - ./prometheus-config.yml:/etc/prometheus/prometheus.yml\n command: ["--config.file=/etc/prometheus/prometheus.yml"]\n depends_on:\n - optl-collector\n'})}),"\n",(0,o.jsxs)(t.p,{children:["If you read the file, you can see that we use the ",(0,o.jsx)(t.code,{children:"otl/opentelemetry-collector"})," image to set up the OpenTelemetry collector,\nWe only expose the gRPC receiver port for the collector, which is ",(0,o.jsx)(t.code,{children:"4317"}),".\nThe collector configuration file is ",(0,o.jsx)(t.code,{children:"collector-config.yaml"}),", which is mounted to the container.\nThe configuration file is as follows:"]}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-yaml",children:'receivers:\n otlp:\n protocols:\n grpc:\n endpoint: 0.0.0.0:4317\n http:\n endpoint: 0.0.0.0:4318\n\n\nexporters:\n debug:\n verbosity: detailed\n otlp:\n endpoint: "jaeger:4317"\n tls:\n insecure: true\n prometheus:\n endpoint: "0.0.0.0:9464"\n\nservice:\n pipelines:\n traces:\n receivers: [otlp]\n exporters: [otlp]\n metrics:\n receivers: [otlp]\n exporters: [prometheus]\n logs:\n receivers: [otlp]\n exporters: [debug]\n'})}),"\n",(0,o.jsxs)(t.p,{children:["Because Jaeger is compatible with the OpenTelemetry collector, we can export the traces to Jaeger by setting the ",(0,o.jsx)(t.code,{children:"otlp"})," exporter.\nWe also export the metrics to Prometheus by setting the ",(0,o.jsx)(t.code,{children:"prometheus"})," exporter.\nThe ",(0,o.jsx)(t.code,{children:"prometheus-config.yml"})," file is the configuration file for Prometheus, which is as follows:"]}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-yaml",children:'scrape_configs:\n - job_name: optl-collector\n scrape_interval: 5s\n static_configs:\n - targets: ["optl-collector:9464"]\n'})}),"\n",(0,o.jsx)(t.p,{children:"We only scrape the metrics from the OpenTelemetry collector."}),"\n",(0,o.jsx)(t.h2,{id:"how-to-view-the-metrics",children:"How to view the metrics"}),"\n",(0,o.jsxs)(t.p,{children:["In the first section, we have explained how to view the traces in the Jaeger frontend.\nViewing the metrics in the Prometheus frontend is more complicated as each metric is a time series.\nA time series is a sequence of data points, which are usually timestamped.\nOpenTelemetry allows to add attributes to the metrics, so that you can filter the metrics by the attributes.\nIn our current implementation, we only have one metric called ",(0,o.jsx)(t.code,{children:"prompt_size"})," which records the size of the prompt sent to the LLM.\nIn Prometheus, you should be able to see a time series for the ",(0,o.jsx)(t.code,{children:"prompt_size"})," metric, namely ",(0,o.jsx)(t.code,{children:"prompt_size_total"}),".\n",(0,o.jsx)(t.code,{children:"prompt_size_total"})," is the accumulated prompt size of all the traces which increases monotonically."]}),"\n",(0,o.jsxs)(t.p,{children:["We annotate the traces with the only one attribute called ",(0,o.jsx)(t.code,{children:"direction"}),", which can be either ",(0,o.jsx)(t.code,{children:"input"})," or ",(0,o.jsx)(t.code,{children:"output"}),".\nThey are indicating the input prompt size and the LLM response output size, respectively."]}),"\n",(0,o.jsx)(t.p,{children:(0,o.jsx)(t.img,{alt:"Tracing Metrics",src:n(8826).Z+"",width:"1849",height:"748"})}),"\n",(0,o.jsxs)(t.p,{children:["You can query the metrics in the Prometheus frontend. The query language is called PromQL which is quite powerful.\nYou can refer to the ",(0,o.jsx)(t.a,{href:"https://prometheus.io/docs/prometheus/latest/querying/basics/",children:"Prometheus documentation"})," for the details of the query language.\nThe query for the above chart is ",(0,o.jsx)(t.code,{children:"increase(prompt_size_total[10m])"}),",\nwhich means to show the increase of the token consumption in the last 10 minutes sliding window."]}),"\n",(0,o.jsxs)(t.p,{children:["If you want to use Grafana to visualize the metrics, you can set up a Grafana instance and add Prometheus as the data source.\nThis can be done by appending the following content to the ",(0,o.jsx)(t.code,{children:"docker-compose.yaml"})," file:"]}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-yaml",children:" grafana:\n image: grafana/grafana-enterprise:latest\n ports:\n - \"3000:3000\" # Grafana UI\n environment:\n - GF_SECURITY_ADMIN_PASSWORD=secret # You should change 'secret' to a password of your choosing\n - GF_USERS_ALLOW_SIGN_UP=false\n volumes:\n - grafana_data:/var/lib/grafana\n depends_on:\n - prometheus\n\nvolumes:\n grafana_data:\n"})}),"\n",(0,o.jsx)(t.h2,{id:"how-to-customize-tracing",children:"How to customize tracing"}),"\n",(0,o.jsxs)(t.p,{children:["The instrumentation of TaskWeaver is done by the OpenTelemetry Python SDK.\nSo, if you want to customize the tracing, you need to modify the TaskWeaver code.\nIn TaskWeaver, we add a layer of abstraction to the OpenTelemetry SDK,\nso that it is easier to hide the details of the OpenTelemetry SDK from the TaskWeaver code.\nYou can find the abstraction layer in the ",(0,o.jsx)(t.code,{children:"taskweaver.module.tracing"})," module."]}),"\n",(0,o.jsxs)(t.p,{children:["In the ",(0,o.jsx)(t.code,{children:"taskweaver.module.tracing"})," module, we define the ",(0,o.jsx)(t.code,{children:"Tracing"})," class,\nwhich is a wrapper of the OpenTelemetry SDK. The ",(0,o.jsx)(t.code,{children:"Tracing"})," class provides the following methods:"]}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsx)(t.li,{children:"set_span_status: Set the status of the span."}),"\n",(0,o.jsx)(t.li,{children:"set_span_attribute: Set the attribute of the span."}),"\n",(0,o.jsx)(t.li,{children:"set_span_exception: Set the exception of the span."}),"\n",(0,o.jsx)(t.li,{children:"add_prompt_size: Add the prompt size to the span."}),"\n"]}),"\n",(0,o.jsxs)(t.p,{children:["In addition, we define the decorator ",(0,o.jsx)(t.code,{children:"tracing_decorator"})," (or the non-class version ",(0,o.jsx)(t.code,{children:"tracing_decorator_non_class"}),")\nto trace the function calls.\nWhen you need to create a context for tracing, you can use"]}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-python",children:'with get_tracer().start_as_current_span("span_name") as span:\n # your code\n'})}),"\n",(0,o.jsx)(t.p,{children:"When you need to trace a function, you can use"}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-python",children:"@tracing_decorator\ndef your_function(self, *args, **kwargs):\n # your code\n"})})]})}function d(e={}){const{wrapper:t}={...(0,r.a)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(h,{...e})}):h(e)}},8826:(e,t,n)=>{n.d(t,{Z:()=>o});const o=n.p+"assets/images/prometheus_chart-0860159d15ddc3fa0753c4eccb4b190d.png"},6645:(e,t,n)=>{n.d(t,{Z:()=>o});const o=n.p+"assets/images/trace-f562ffc9ba2eba5acb5f8d9403c327ec.png"},5900:(e,t,n)=>{n.d(t,{Z:()=>o});const o=n.p+"assets/images/trace_graph-b5a2d47a94e2653a08ec325c0131954d.png"},4525:(e,t,n)=>{n.d(t,{Z:()=>o});const o=n.p+"assets/images/trace_prompt-1a16096cc7cf481796e058a691167287.png"},3643:(e,t,n)=>{n.d(t,{Z:()=>o});const o=n.p+"assets/images/tracing-arch-85baf8dedb28553470d3ae733f0f28b3.png"},1151:(e,t,n)=>{n.d(t,{Z:()=>i,a:()=>a});var o=n(7294);const r={},s=o.createContext(r);function a(e){const t=o.useContext(s);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),o.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/2726c345.fe3a06a8.js b/assets/js/2726c345.fe3a06a8.js new file mode 100644 index 00000000..621b22a4 --- /dev/null +++ b/assets/js/2726c345.fe3a06a8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[3450],{286:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>s,metadata:()=>i,toc:()=>l});var o=n(5893),r=n(1151);const s={},a="Telemetry",i={id:"advanced/telemetry",title:"Telemetry",description:"TaskWeaver now supports tracing with OpenTelemetry,",source:"@site/docs/advanced/telemetry.md",sourceDirName:"advanced",slug:"/advanced/telemetry",permalink:"/TaskWeaver/docs/advanced/telemetry",draft:!1,unlisted:!1,editUrl:"https://github.com/microsoft/TaskWeaver/tree/main/website/docs/advanced/telemetry.md",tags:[],version:"current",frontMatter:{},sidebar:"documentSidebar",previous:{title:"CLI Only Mode",permalink:"/TaskWeaver/docs/advanced/cli_only"},next:{title:"The Plugin-Only Mode",permalink:"/TaskWeaver/docs/plugin/plugin_only"}},c={},l=[{value:"How to enable tracing",id:"how-to-enable-tracing",level:2},{value:"Tracing Infrastructure Configuration",id:"tracing-infrastructure-configuration",level:2},{value:"How to view the metrics",id:"how-to-view-the-metrics",level:2},{value:"How to customize tracing",id:"how-to-customize-tracing",level:2}];function h(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",img:"img",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.a)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.h1,{id:"telemetry",children:"Telemetry"}),"\n",(0,o.jsx)(t.p,{children:"TaskWeaver now supports tracing with OpenTelemetry,\nwhich is one of the most popular open-source observability frameworks. This allows you to trace the following:"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsx)(t.li,{children:"Interactions between roles, i.e., the Planner, the CodeInterpreter, and the Executor."}),"\n",(0,o.jsx)(t.li,{children:"The time consumed by each role and major components of TaskWeaver."}),"\n",(0,o.jsx)(t.li,{children:"The prompts sent to the LLM and the responses received from the LLM."}),"\n",(0,o.jsx)(t.li,{children:"The status of the tasks and the errors encountered."}),"\n",(0,o.jsx)(t.li,{children:"The number of tokens consumed by each role."}),"\n"]}),"\n",(0,o.jsx)(t.p,{children:"The following screenshot shows a trace of a simple task: analyzing an uploaded file."}),"\n",(0,o.jsx)(t.p,{children:(0,o.jsx)(t.img,{alt:"Tracing",src:n(6645).Z+"",width:"1859",height:"553"})}),"\n",(0,o.jsx)(t.p,{children:"From this view, you can see the timeline of the task execution, which breaks majorly into\nthree parts:"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsx)(t.li,{children:"The planning phase, where the Planner decides the sub-tasks to be executed."}),"\n",(0,o.jsx)(t.li,{children:"The code generation and execution phase, where the CodeGenerator generates the code and the CodeExecutor executes it."}),"\n",(0,o.jsx)(t.li,{children:"The reply phase, where the Planner sends the reply to the user."}),"\n"]}),"\n",(0,o.jsx)(t.p,{children:"The bars with a black line represent the critical path of the task execution, which is the longest path through the task execution.\nThis is useful for identifying the bottleneck of the task execution.\nWe can clearly see that, currently, the task execution is dominated by the calls to the LLM."}),"\n",(0,o.jsx)(t.p,{children:"We can click the span (a unit of work in the trace) to see the details of the span, including the logs and the attributes."}),"\n",(0,o.jsx)(t.p,{children:"The screenshot below shows the details of the span of Planner's reply function:"}),"\n",(0,o.jsx)(t.p,{children:(0,o.jsx)(t.img,{alt:"Tracing Prompt",src:n(4525).Z+"",width:"1746",height:"541"})}),"\n",(0,o.jsx)(t.p,{children:"From this view, we can see the user query, the prompt sent to the LLM, and the tokens consumed (prompt_size and output_size) by the LLM.\nWe also recorded the generated code, the posts between different roles, etc. in the trace."}),"\n",(0,o.jsx)(t.p,{children:"There are also views of the trace, for example the call graph view, which shows the call hierarchy of the spans.\nHere is the call graph of the trace:"}),"\n",(0,o.jsx)(t.p,{children:(0,o.jsx)(t.img,{alt:"Tracing Call Graph",src:n(5900).Z+"",width:"1785",height:"326"})}),"\n",(0,o.jsx)(t.h2,{id:"how-to-enable-tracing",children:"How to enable tracing"}),"\n",(0,o.jsxs)(t.p,{children:["Tracing is by default disabled. To enable tracing, you need to install packages required by OpenTelemetry.\nPlease check the ",(0,o.jsx)(t.a,{href:"https://opentelemetry.io/docs/languages/python/",children:"OpenTelemetry website"})," for the installation guide.\nIt basically requires you to install the ",(0,o.jsx)(t.code,{children:"opentelemetry-api"}),", ",(0,o.jsx)(t.code,{children:"opentelemetry-sdk"}),", ",(0,o.jsx)(t.code,{children:"opentelemetry-exporter-otlp"}),",\n",(0,o.jsx)(t.code,{children:"opentelemetry-instrumentation"})," and ",(0,o.jsx)(t.code,{children:"tiktoken"})," packages.\nTo count the number of tokens consumed during task execution, you also need to install the ",(0,o.jsx)(t.a,{href:"https://github.com/openai/tiktoken",children:"tiktoken"})," package.\nWe now only support the tokenizers of the OpenAI models.\nAfter installing the packages, you can enable tracing by setting the ",(0,o.jsx)(t.code,{children:"tracing.enabled=true"})," in the project configuration file.\nThe default tokenizer target model is ",(0,o.jsx)(t.code,{children:"gpt-4"}),", if you want to use another model, you can set the ",(0,o.jsx)(t.code,{children:"tracing.tokenizer_target_model"}),"\nin the project configuration file.\nYou can find the available models in the ",(0,o.jsx)(t.a,{href:"https://github.com/openai/tiktoken/blob/main/tiktoken/model.py",children:"tiktoken code"}),"."]}),"\n",(0,o.jsx)(t.p,{children:"A typical configuration for tracing in the project configuration file is as follows:"}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-json",children:'{\n "tracing.enabled": true,\n "tracing.exporter": "otlp",\n "tracing.endpoint": "http://127.0.0.1:4317",\n "tracing.tokenizer_target_model": "gpt-4"\n}\n'})}),"\n",(0,o.jsxs)(t.p,{children:["Next, we need to set up the infrastructure for tracing. The following diagram shows the architecture of a toy tracing system.\nIt is a toy system and the data is not persisted. In a real-world scenario, you need to set up a more robust system.\nThe instrumentation in the TaskWeaver code will send the traces and metrics to the OpenTelemetry collector.\nAn OpenTelemetry collector is a component that receives traces and metrics from the instrumentation, does some processing, and exports them to\nanother collector or a backend. In our case, we configure the collector to export the traces to a ",(0,o.jsx)(t.a,{href:"https://www.jaegertracing.io/",children:"Jaeger"})," backend and the metrics\nto a ",(0,o.jsx)(t.a,{href:"https://prometheus.io/",children:"Prometheus"})," backend.\n",(0,o.jsx)(t.img,{alt:"Tracing Architecture",src:n(3643).Z+"",width:"1027",height:"332"})]}),"\n",(0,o.jsx)(t.p,{children:"You can run the following command to set up the infrastructure:"}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-bash",children:"cd /TaskWeaver/tracing\ndocker-compose up\n"})}),"\n",(0,o.jsxs)(t.p,{children:["You shall see a bunch of logs from the containers.\nTake a look at the logs to see if there are any errors.\nIf no errors are found, you can access the Prometheus frontend at ",(0,o.jsx)(t.code,{children:"http://localhost:9090"})," and the Jaeger frontend at ",(0,o.jsx)(t.code,{children:"http://localhost:16686"}),".\nIn this setup, we assume you are running the containers on the same machine of TaskWeaver.\nIf you are running the containers on different machines, you need to configure the endpoint of the OpenTelemetry collector in the TaskWeaver configuration file.\nThe default endpoint is ",(0,o.jsx)(t.code,{children:"http://127.0.0.1:4317"}),", you can set the ",(0,o.jsx)(t.code,{children:"tracing.endpoint"})," in the project configuration file to change the endpoint address."]}),"\n",(0,o.jsx)(t.h2,{id:"tracing-infrastructure-configuration",children:"Tracing Infrastructure Configuration"}),"\n",(0,o.jsxs)(t.p,{children:["Both Jaeger and Prometheus are popular open-source monitoring systems. We have prepared a docker-compose file to set up the infrastructure\nin ",(0,o.jsx)(t.code,{children:"/TaskWeaver/tracing_configure/docker-compose.yaml"}),".\nThe content of the file is as follows:"]}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-yaml",children:'version: \'3\'\nservices:\n optl-collector:\n image: otel/opentelemetry-collector:0.96.0\n command: ["--config=/etc/collector-config.yaml"]\n volumes:\n - ./collector-config.yaml:/etc/collector-config.yaml\n ports:\n - "4317:4317" # Expose the gRPC receiver port for the collector\n depends_on:\n - jaeger\n\n jaeger:\n image: jaegertracing/all-in-one:1.54\n ports:\n - "16686:16686" # Jaeger UI\n\n prometheus:\n image: prom/prometheus:latest\n ports:\n - "9090:9090" # Prometheus UI\n volumes:\n - ./prometheus-config.yml:/etc/prometheus/prometheus.yml\n command: ["--config.file=/etc/prometheus/prometheus.yml"]\n depends_on:\n - optl-collector\n'})}),"\n",(0,o.jsxs)(t.p,{children:["If you read the file, you can see that we use the ",(0,o.jsx)(t.code,{children:"otl/opentelemetry-collector"})," image to set up the OpenTelemetry collector,\nWe only expose the gRPC receiver port for the collector, which is ",(0,o.jsx)(t.code,{children:"4317"}),".\nThe collector configuration file is ",(0,o.jsx)(t.code,{children:"collector-config.yaml"}),", which is mounted to the container.\nThe configuration file is as follows:"]}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-yaml",children:'receivers:\n otlp:\n protocols:\n grpc:\n endpoint: 0.0.0.0:4317\n http:\n endpoint: 0.0.0.0:4318\n\n\nexporters:\n debug:\n verbosity: detailed\n otlp:\n endpoint: "jaeger:4317"\n tls:\n insecure: true\n prometheus:\n endpoint: "0.0.0.0:9464"\n\nservice:\n pipelines:\n traces:\n receivers: [otlp]\n exporters: [otlp]\n metrics:\n receivers: [otlp]\n exporters: [prometheus]\n logs:\n receivers: [otlp]\n exporters: [debug]\n'})}),"\n",(0,o.jsxs)(t.p,{children:["Because Jaeger is compatible with the OpenTelemetry collector, we can export the traces to Jaeger by setting the ",(0,o.jsx)(t.code,{children:"otlp"})," exporter.\nWe also export the metrics to Prometheus by setting the ",(0,o.jsx)(t.code,{children:"prometheus"})," exporter.\nThe ",(0,o.jsx)(t.code,{children:"prometheus-config.yml"})," file is the configuration file for Prometheus, which is as follows:"]}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-yaml",children:'scrape_configs:\n - job_name: optl-collector\n scrape_interval: 5s\n static_configs:\n - targets: ["optl-collector:9464"]\n'})}),"\n",(0,o.jsx)(t.p,{children:"We only scrape the metrics from the OpenTelemetry collector."}),"\n",(0,o.jsx)(t.h2,{id:"how-to-view-the-metrics",children:"How to view the metrics"}),"\n",(0,o.jsxs)(t.p,{children:["In the first section, we have explained how to view the traces in the Jaeger frontend.\nViewing the metrics in the Prometheus frontend is more complicated as each metric is a time series.\nA time series is a sequence of data points, which are usually timestamped.\nOpenTelemetry allows to add attributes to the metrics, so that you can filter the metrics by the attributes.\nIn our current implementation, we only have one metric called ",(0,o.jsx)(t.code,{children:"prompt_size"})," which records the size of the prompt sent to the LLM.\nIn Prometheus, you should be able to see a time series for the ",(0,o.jsx)(t.code,{children:"prompt_size"})," metric, namely ",(0,o.jsx)(t.code,{children:"prompt_size_total"}),".\n",(0,o.jsx)(t.code,{children:"prompt_size_total"})," is the accumulated prompt size of all the traces which increases monotonically."]}),"\n",(0,o.jsxs)(t.p,{children:["We annotate the traces with the only one attribute called ",(0,o.jsx)(t.code,{children:"direction"}),", which can be either ",(0,o.jsx)(t.code,{children:"input"})," or ",(0,o.jsx)(t.code,{children:"output"}),".\nThey are indicating the input prompt size and the LLM response output size, respectively."]}),"\n",(0,o.jsx)(t.p,{children:(0,o.jsx)(t.img,{alt:"Tracing Metrics",src:n(8826).Z+"",width:"1849",height:"748"})}),"\n",(0,o.jsxs)(t.p,{children:["You can query the metrics in the Prometheus frontend. The query language is called PromQL which is quite powerful.\nYou can refer to the ",(0,o.jsx)(t.a,{href:"https://prometheus.io/docs/prometheus/latest/querying/basics/",children:"Prometheus documentation"})," for the details of the query language.\nThe query for the above chart is ",(0,o.jsx)(t.code,{children:"increase(prompt_size_total[10m])"}),",\nwhich means to show the increase of the token consumption in the last 10 minutes sliding window."]}),"\n",(0,o.jsxs)(t.p,{children:["If you want to use Grafana to visualize the metrics, you can set up a Grafana instance and add Prometheus as the data source.\nThis can be done by appending the following content to the ",(0,o.jsx)(t.code,{children:"docker-compose.yaml"})," file:"]}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-yaml",children:" grafana:\n image: grafana/grafana-enterprise:latest\n ports:\n - \"3000:3000\" # Grafana UI\n environment:\n - GF_SECURITY_ADMIN_PASSWORD=secret # You should change 'secret' to a password of your choosing\n - GF_USERS_ALLOW_SIGN_UP=false\n volumes:\n - grafana_data:/var/lib/grafana\n depends_on:\n - prometheus\n\nvolumes:\n grafana_data:\n"})}),"\n",(0,o.jsx)(t.h2,{id:"how-to-customize-tracing",children:"How to customize tracing"}),"\n",(0,o.jsxs)(t.p,{children:["The instrumentation of TaskWeaver is done by the OpenTelemetry Python SDK.\nSo, if you want to customize the tracing, you need to modify the TaskWeaver code.\nIn TaskWeaver, we add a layer of abstraction to the OpenTelemetry SDK,\nso that it is easier to hide the details of the OpenTelemetry SDK from the TaskWeaver code.\nYou can find the abstraction layer in the ",(0,o.jsx)(t.code,{children:"taskweaver.module.tracing"})," module."]}),"\n",(0,o.jsxs)(t.p,{children:["In the ",(0,o.jsx)(t.code,{children:"taskweaver.module.tracing"})," module, we define the ",(0,o.jsx)(t.code,{children:"Tracing"})," class,\nwhich is a wrapper of the OpenTelemetry SDK. The ",(0,o.jsx)(t.code,{children:"Tracing"})," class provides the following methods:"]}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsx)(t.li,{children:"set_span_status: Set the status of the span."}),"\n",(0,o.jsx)(t.li,{children:"set_span_attribute: Set the attribute of the span."}),"\n",(0,o.jsx)(t.li,{children:"set_span_exception: Set the exception of the span."}),"\n",(0,o.jsx)(t.li,{children:"add_prompt_size: Add the prompt size to the span."}),"\n"]}),"\n",(0,o.jsxs)(t.p,{children:["In addition, we define the decorator ",(0,o.jsx)(t.code,{children:"tracing_decorator"})," (or the non-class version ",(0,o.jsx)(t.code,{children:"tracing_decorator_non_class"}),")\nto trace the function calls.\nWhen you need to create a context for tracing, you can use"]}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-python",children:'with get_tracer().start_as_current_span("span_name") as span:\n # your code\n'})}),"\n",(0,o.jsx)(t.p,{children:"When you need to trace a function, you can use"}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-python",children:"@tracing_decorator\ndef your_function(self, *args, **kwargs):\n # your code\n"})})]})}function d(e={}){const{wrapper:t}={...(0,r.a)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(h,{...e})}):h(e)}},8826:(e,t,n)=>{n.d(t,{Z:()=>o});const o=n.p+"assets/images/prometheus_chart-0860159d15ddc3fa0753c4eccb4b190d.png"},6645:(e,t,n)=>{n.d(t,{Z:()=>o});const o=n.p+"assets/images/trace-f562ffc9ba2eba5acb5f8d9403c327ec.png"},5900:(e,t,n)=>{n.d(t,{Z:()=>o});const o=n.p+"assets/images/trace_graph-b5a2d47a94e2653a08ec325c0131954d.png"},4525:(e,t,n)=>{n.d(t,{Z:()=>o});const o=n.p+"assets/images/trace_prompt-1a16096cc7cf481796e058a691167287.png"},3643:(e,t,n)=>{n.d(t,{Z:()=>o});const o=n.p+"assets/images/tracing-arch-85baf8dedb28553470d3ae733f0f28b3.png"},1151:(e,t,n)=>{n.d(t,{Z:()=>i,a:()=>a});var o=n(7294);const r={},s=o.createContext(r);function a(e){const t=o.useContext(s);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),o.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/30613cee.85e1c30a.js b/assets/js/30613cee.85e1c30a.js deleted file mode 100644 index 83f37686..00000000 --- a/assets/js/30613cee.85e1c30a.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1559],{3924:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>u,frontMatter:()=>a,metadata:()=>i,toc:()=>l});var o=t(5893),s=t(1151);const a={},r="CLI Only Mode",i={id:"advanced/cli_only",title:"CLI Only Mode",description:"TaskWeaver's CLI-only mode enables users to effortlessly communicate with the Command Line Interface (CLI) using natural language.",source:"@site/docs/advanced/cli_only.md",sourceDirName:"advanced",slug:"/advanced/cli_only",permalink:"/TaskWeaver/docs/advanced/cli_only",draft:!1,unlisted:!1,editUrl:"https://github.com/microsoft/TaskWeaver/tree/main/website/docs/advanced/cli_only.md",tags:[],version:"current",frontMatter:{},sidebar:"documentSidebar",previous:{title:"Code Execution",permalink:"/TaskWeaver/docs/advanced/code_execution"},next:{title:"Telemetry",permalink:"/TaskWeaver/docs/advanced/telemetry"}},c={},l=[{value:"Demo",id:"demo",level:2},{value:"How to enable",id:"how-to-enable",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",...(0,s.a)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h1,{id:"cli-only-mode",children:"CLI Only Mode"}),"\n",(0,o.jsx)(n.p,{children:"TaskWeaver's CLI-only mode enables users to effortlessly communicate with the Command Line Interface (CLI) using natural language.\nCodeInterpreter generates CLI commands, such as bash or PowerShell to address the user's needs.\nThis mode allows users to operate your system by simply chatting with the command line in natural language!"}),"\n",(0,o.jsx)(n.h2,{id:"demo",children:"Demo"}),"\n",(0,o.jsx)(n.p,{children:(0,o.jsx)(n.a,{href:"https://github.com/microsoft/TaskWeaver/assets/32928431/3724d321-0e0b-49e0-8f77-7b3855069a82",children:"TaskWeaver-CLI"})}),"\n",(0,o.jsx)(n.h2,{id:"how-to-enable",children:"How to enable"}),"\n",(0,o.jsxs)(n.p,{children:["Just add the following configuration to the project configuration file ",(0,o.jsx)(n.code,{children:"taskweaver_config.json"}),":"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-json",children:'{\n "session.roles": ["code_interpreter_cli_only"]\n}\n'})}),"\n",(0,o.jsxs)(n.p,{children:["Please refer to the ",(0,o.jsx)(n.a,{href:"../configurations/configurations_in_detail",children:"session"})," documentation for more details."]})]})}function u(e={}){const{wrapper:n}={...(0,s.a)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},1151:(e,n,t)=>{t.d(n,{Z:()=>i,a:()=>r});var o=t(7294);const s={},a=o.createContext(s);function r(e){const n=o.useContext(a);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),o.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/30613cee.e59ce107.js b/assets/js/30613cee.e59ce107.js new file mode 100644 index 00000000..aa8f636c --- /dev/null +++ b/assets/js/30613cee.e59ce107.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1559],{3924:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>u,frontMatter:()=>s,metadata:()=>i,toc:()=>l});var o=t(5893),a=t(1151);const s={},r="CLI Only Mode",i={id:"advanced/cli_only",title:"CLI Only Mode",description:"TaskWeaver's CLI-only mode enables users to effortlessly communicate with the Command Line Interface (CLI) using natural language.",source:"@site/docs/advanced/cli_only.md",sourceDirName:"advanced",slug:"/advanced/cli_only",permalink:"/TaskWeaver/docs/advanced/cli_only",draft:!1,unlisted:!1,editUrl:"https://github.com/microsoft/TaskWeaver/tree/main/website/docs/advanced/cli_only.md",tags:[],version:"current",frontMatter:{},sidebar:"documentSidebar",previous:{title:"Code Verification",permalink:"/TaskWeaver/docs/advanced/code_verification"},next:{title:"Telemetry",permalink:"/TaskWeaver/docs/advanced/telemetry"}},c={},l=[{value:"Demo",id:"demo",level:2},{value:"How to enable",id:"how-to-enable",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",...(0,a.a)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h1,{id:"cli-only-mode",children:"CLI Only Mode"}),"\n",(0,o.jsx)(n.p,{children:"TaskWeaver's CLI-only mode enables users to effortlessly communicate with the Command Line Interface (CLI) using natural language.\nCodeInterpreter generates CLI commands, such as bash or PowerShell to address the user's needs.\nThis mode allows users to operate your system by simply chatting with the command line in natural language!"}),"\n",(0,o.jsx)(n.h2,{id:"demo",children:"Demo"}),"\n",(0,o.jsx)("iframe",{width:"560",height:"315",src:"https://github.com/microsoft/TaskWeaver/assets/32928431/3724d321-0e0b-49e0-8f77-7b3855069a82",frameborder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowfullscreen:!0}),"\n",(0,o.jsx)(n.h2,{id:"how-to-enable",children:"How to enable"}),"\n",(0,o.jsxs)(n.p,{children:["Just add the following configuration to the project configuration file ",(0,o.jsx)(n.code,{children:"taskweaver_config.json"}),":"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-json",children:'{\n "session.roles": ["code_interpreter_cli_only"]\n}\n'})}),"\n",(0,o.jsxs)(n.p,{children:["Please refer to the ",(0,o.jsx)(n.a,{href:"../configurations/configurations_in_detail",children:"session"})," documentation for more details."]})]})}function u(e={}){const{wrapper:n}={...(0,a.a)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},1151:(e,n,t)=>{t.d(n,{Z:()=>i,a:()=>r});var o=t(7294);const a={},s=o.createContext(a);function r(e){const n=o.useContext(s);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),o.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/360ca471.7a95a742.js b/assets/js/360ca471.7a95a742.js new file mode 100644 index 00000000..7c9ca044 --- /dev/null +++ b/assets/js/360ca471.7a95a742.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[7399],{1951:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>r,contentTitle:()=>o,default:()=>u,frontMatter:()=>l,metadata:()=>s,toc:()=>d});var t=i(5893),a=i(1151);const l={id:"plugin_intro",description:"Plugin introduction",slug:"/plugin/plugin_intro"},o="Plugin Introduction",s={id:"customization/plugin/plugin_intro",title:"Plugin Introduction",description:"Plugin introduction",source:"@site/docs/customization/plugin/plugin_intro.md",sourceDirName:"customization/plugin",slug:"/plugin/plugin_intro",permalink:"/TaskWeaver/docs/plugin/plugin_intro",draft:!1,unlisted:!1,editUrl:"https://github.com/microsoft/TaskWeaver/tree/main/website/docs/customization/plugin/plugin_intro.md",tags:[],version:"current",frontMatter:{id:"plugin_intro",description:"Plugin introduction",slug:"/plugin/plugin_intro"},sidebar:"documentSidebar",previous:{title:"Customization",permalink:"/TaskWeaver/docs/customization"},next:{title:"An Example of Developing a New Plugin",permalink:"/TaskWeaver/docs/plugin/how_to_develop_a_new_plugin"}},r={},d=[{value:"Plugin Structure",id:"plugin-structure",level:2},{value:"Plugin Implementation",id:"plugin-implementation",level:2},{value:"Important Notes",id:"important-notes",level:3},{value:"Plugin Schema",id:"plugin-schema",level:2}];function c(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,a.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"plugin-introduction",children:"Plugin Introduction"}),"\n",(0,t.jsx)(n.p,{children:"Plugins are the units that could be orchestrated by TaskWeaver. One could view the plugins as tools that the LLM can\nutilize to accomplish certain tasks."}),"\n",(0,t.jsx)(n.p,{children:"In TaskWeaver, each plugin is represented as a Python function that can be called within the generated code snippet.\nOne concrete example would be pulling data from database and apply anomaly detection. The generated code (simplified) looks like\nfollows:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-python",children:'df, data_description = sql_pull_data(query="pull data from time_series table") \nanomaly_df, anomaly_description = anomaly_detection(df, time_col_name="ts", value_col_name="val") \n'})}),"\n",(0,t.jsxs)(n.p,{children:["The generated code snippet above calls two plugins: ",(0,t.jsx)(n.code,{children:"sql_pull_data"})," and ",(0,t.jsx)(n.code,{children:"anomaly_detection"}),". The ",(0,t.jsx)(n.code,{children:"sql_pull_data"})," plugin\npulls data from a database, and the ",(0,t.jsx)(n.code,{children:"anomaly_detection"})," plugin detects anomalies in the data."]}),"\n",(0,t.jsx)(n.h2,{id:"plugin-structure",children:"Plugin Structure"}),"\n",(0,t.jsx)(n.p,{children:"A plugin involves two files:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Plugin Implementation"}),": a Python file that defines the plugin"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Plugin Schema"}),": a file in yaml that defines the schema of the plugin"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"plugin-implementation",children:"Plugin Implementation"}),"\n",(0,t.jsx)(n.p,{children:"The plugin function needs to be implemented in Python.\nTo be coordinated with the orchestration by TaskWeaver, a plugin python file consists of two parts:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Plugin function implementation code"}),"\n",(0,t.jsx)(n.li,{children:"TaskWeaver plugin decorator"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Here we exhibit an example of the anomaly detection plugin as the following code:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-python",children:'import pandas as pd\nfrom pandas.api.types import is_numeric_dtype\n\nfrom taskweaver.plugin import Plugin, register_plugin\n\n\n@register_plugin\nclass AnomalyDetectionPlugin(Plugin):\n def __call__(self, df: pd.DataFrame, time_col_name: str, value_col_name: str):\n\n """\n anomaly_detection function identifies anomalies from an input dataframe of time series.\n It will add a new column "Is_Anomaly", where each entry will be marked with "True" if the value is an anomaly\n or "False" otherwise.\n\n :param df: the input data, must be a dataframe\n :param time_col_name: name of the column that contains the datetime\n :param value_col_name: name of the column that contains the numeric values.\n :return df: a new df that adds an additional "Is_Anomaly" column based on the input df.\n :return description: the description about the anomaly detection results.\n """\n try:\n df[time_col_name] = pd.to_datetime(df[time_col_name])\n except Exception:\n print("Time column is not datetime")\n return\n\n if not is_numeric_dtype(df[value_col_name]):\n try:\n df[value_col_name] = df[value_col_name].astype(float)\n except ValueError:\n print("Value column is not numeric")\n return\n\n mean, std = df[value_col_name].mean(), df[value_col_name].std()\n cutoff = std * 3\n lower, upper = mean - cutoff, mean + cutoff\n df["Is_Anomaly"] = df[value_col_name].apply(lambda x: x < lower or x > upper)\n anomaly_count = df["Is_Anomaly"].sum()\n description = "There are {} anomalies in the time series data".format(anomaly_count)\n \n self.ctx.add_artifact(\n name="anomaly_detection_results", # a brief description of the artifact\n file_name="anomaly_detection_results.csv", # artifact file name\n type="df", # artifact data type, support chart/df/file/txt/svg\n val=df, # variable to be dumped\n )\n \n return df, description\n\n'})}),"\n",(0,t.jsx)(n.p,{children:"You need to go through the following steps to register a plugin:"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["import the TaskWeaver plugin decorator ",(0,t.jsx)(n.code,{children:"from taskWeaver.plugin import Plugin, register_plugin"})]}),"\n",(0,t.jsxs)(n.li,{children:["create your plugin class inherited from ",(0,t.jsx)(n.code,{children:"Plugin"})," parent class (e.g., ",(0,t.jsx)(n.code,{children:"AnomalyDetectionPlugin(Plugin)"}),"), which is\ndecorated by ",(0,t.jsx)(n.code,{children:"@register_plugin"})]}),"\n",(0,t.jsxs)(n.li,{children:["implement your plugin function in ",(0,t.jsx)(n.code,{children:"__call__"})," method of the plugin class."]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["We provide an example process of developing a new plugin in ",(0,t.jsx)(n.a,{href:"/TaskWeaver/docs/plugin/how_to_develop_a_new_plugin",children:"this tutorial"}),"."]}),"\n",(0,t.jsx)(n.admonition,{type:"tip",children:(0,t.jsx)(n.p,{children:"A good practice in a plugin implementation is to return a description of\nthe result in natural language. As LLMs only understand natural language, it is important to let the model understand\nwhat the execution result is. In the example implementation above, the description says how many anomalies are detected.\nIn other cases such as loading a csv file, a good description could be showing the schema of the loaded data.\nThis description can be used by the LLM to plan the next steps."})}),"\n",(0,t.jsx)(n.h3,{id:"important-notes",children:"Important Notes"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"If the functionality of your plugin depends on additional libraries or packages, it is essential to ensure that they\nare installed before proceeding."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["If you wish to persist intermediate results, such as data, figures, or prompts, in your plugin implementation,\nTaskWeaver provides an ",(0,t.jsx)(n.code,{children:"add_artifact"})," API that allows you to store these results in the workspace. In the example we\nprovide, if you have performed anomaly detection and obtained results in the form of a CSV file, you can utilize\nthe ",(0,t.jsx)(n.code,{children:"add_artifact"})," API to save this file as an artifact. The artifacts are stored in the ",(0,t.jsx)(n.code,{children:"project/workspace/session_id/cwd"})," folder in the project directory."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-python",children:'self.ctx.add_artifact(\n name="anomaly_detection_results", # a brief description of the artifact\n file_name="anomaly_detection_results.csv", # artifact file name\n type="df", # artifact data type, support chart/df/file/txt/svg\n val=df, # variable to be dumped\n)\n'})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"plugin-schema",children:"Plugin Schema"}),"\n",(0,t.jsx)(n.p,{children:"The plugin schema is composed of several parts:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["*",(0,t.jsx)(n.strong,{children:"name"}),": The main function name of the Python code."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"enabled"}),": determine whether the plugin is enabled for selection during conversations. The default value is true."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"plugin_only"}),": determine if this plugin is enabled under the plugin-only mode. The default value is false."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"code"}),": the code file name of the plugin. The default value is the same as the plugin name."]}),"\n",(0,t.jsxs)(n.li,{children:["*",(0,t.jsx)(n.strong,{children:"descriptions"}),": A brief description that introduces the plugin function."]}),"\n",(0,t.jsxs)(n.li,{children:["*",(0,t.jsx)(n.strong,{children:"parameters"}),": This section lists all the input parameter information. It includes the parameter's name, type,\nwhether it is required or optional, and a description providing more details about the parameter."]}),"\n",(0,t.jsxs)(n.li,{children:["*",(0,t.jsx)(n.strong,{children:"returns"}),": This section lists all the return value information. It includes the return value's name, type, and\ndescription that provides information about the value that is returned by the function."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"configurations"}),": the configuration parameters for the plugin. The default value is an empty dictionary."]}),"\n"]}),"\n",(0,t.jsx)(n.admonition,{type:"tip",children:(0,t.jsx)(n.p,{children:"The addition of any extra fields or missing of mandatory fields (marked by * above) would result in a validation failure within the plugin schema."})}),"\n",(0,t.jsx)(n.p,{children:"The plugin schema is required to be written in YAML format. Here is the plugin schema example of the above anomaly\ndetection plugin:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:'name: anomaly_detection\nenabled: true\nplugin_only: false\nrequired: false\ndescription: >-\n anomaly_detection function identifies anomalies from an input DataFrame of\n time series. It will add a new column "Is_Anomaly", where each entry will be marked with "True" if the value is an anomaly or "False" otherwise.\n\nparameters:\n - name: df\n type: DataFrame\n required: true\n description: >-\n the input data from which we can identify the anomalies with the 3-sigma\n algorithm.\n - name: time_col_name\n type: str\n required: true\n description: name of the column that contains the datetime\n - name: value_col_name\n type: str\n required: true\n description: name of the column that contains the numeric values.\n\nreturns:\n - name: df\n type: DataFrame\n description: >-\n This DataFrame extends the input DataFrame with a newly-added column\n "Is_Anomaly" containing the anomaly detection result.\n - name: description\n type: str\n description: This is a string describing the anomaly detection results.\n\n'})}),"\n",(0,t.jsxs)(n.admonition,{type:"info",children:[(0,t.jsxs)(n.p,{children:["Without specifying the ",(0,t.jsx)(n.code,{children:"code"})," field, the plugin schema will use the plugin name as the code file name.\nFor example, the plugin name is ",(0,t.jsx)(n.code,{children:"anomaly_detection"})," and the code file name is ",(0,t.jsx)(n.code,{children:"anomaly_detection.py"}),".\nIn cases where the plugin name is not the same as the code file name, you can specify the code name (code file) in\nthe plugin schema to ensure clarity and accuracy. For example, the plugin name is ",(0,t.jsx)(n.code,{children:"anomaly_detection"})," and the code\nfile name is ",(0,t.jsx)(n.code,{children:"anomaly_detection_code.py"}),". Then, you can specify the code name in the plugin schema as follows:"]}),(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"code: anomaly_detection_code\n"})}),(0,t.jsxs)(n.p,{children:["Note that the code file name should be the same as the code name without the ",(0,t.jsx)(n.code,{children:".py"})," extension.\nRefer to ",(0,t.jsx)(n.a,{href:"/TaskWeaver/docs/plugin/multi_yaml_single_impl",children:"Multiple YAML files to one Python implementation"})," for more information on how to\nuse this feature."]})]}),"\n",(0,t.jsxs)(n.admonition,{type:"info",children:[(0,t.jsx)(n.p,{children:"When using common code that requires some configuration parameter modifications for different\nplugins, it is important to specify these configuration parameters in the plugin schema.\nThe configuration parameters are specified in the plugin schema as follows:"}),(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:" configurations:\n key1: value1\n key2: value2\n"})}),(0,t.jsx)(n.p,{children:"These configuration parameters can be accessed in the plugin implementation as follows:"}),(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-python",children:'self.config.get("key1")\nself.config.get("key2")\n'})})]}),"\n",(0,t.jsx)(n.admonition,{type:"info",children:(0,t.jsxs)(n.p,{children:["When this plugin is enabled for the ",(0,t.jsx)(n.a,{href:"/TaskWeaver/docs/plugin/plugin_only",children:"plugin-only mode"}),", set the ",(0,t.jsx)(n.code,{children:"plugin_only"})," field to ",(0,t.jsx)(n.code,{children:"true"}),".\nThe default value is ",(0,t.jsx)(n.code,{children:"false"}),". Note that all plugins will be loaded in the non-plugin-only mode which is the default mode.\nBut in the plugin-only mode, only the plugins with ",(0,t.jsx)(n.code,{children:"plugin_only: true"})," will be loaded."]})})]})}function u(e={}){const{wrapper:n}={...(0,a.a)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(c,{...e})}):c(e)}},1151:(e,n,i)=>{i.d(n,{Z:()=>s,a:()=>o});var t=i(7294);const a={},l=t.createContext(a);function o(e){const n=t.useContext(l);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function s(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:o(e.components),t.createElement(l.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/360ca471.986b29ef.js b/assets/js/360ca471.986b29ef.js deleted file mode 100644 index f011d873..00000000 --- a/assets/js/360ca471.986b29ef.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[7399],{1951:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>r,contentTitle:()=>l,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>c});var i=t(5893),a=t(1151);const o={id:"plugin_intro",description:"Plugin introduction",slug:"/plugin/plugin_intro"},l="Plugin Introduction",s={id:"customization/plugin/plugin_intro",title:"Plugin Introduction",description:"Plugin introduction",source:"@site/docs/customization/plugin/plugin_intro.md",sourceDirName:"customization/plugin",slug:"/plugin/plugin_intro",permalink:"/TaskWeaver/docs/plugin/plugin_intro",draft:!1,unlisted:!1,editUrl:"https://github.com/microsoft/TaskWeaver/tree/main/website/docs/customization/plugin/plugin_intro.md",tags:[],version:"current",frontMatter:{id:"plugin_intro",description:"Plugin introduction",slug:"/plugin/plugin_intro"},sidebar:"documentSidebar",previous:{title:"Customization",permalink:"/TaskWeaver/docs/customization"},next:{title:"Auto Plugin Selection",permalink:"/TaskWeaver/docs/customization/plugin/plugin_selection"}},r={},c=[{value:"Plugin Structure",id:"plugin-structure",level:2},{value:"Plugin Implementation",id:"plugin-implementation",level:2},{value:"Important Notes",id:"important-notes",level:3},{value:"Plugin Schema",id:"plugin-schema",level:2}];function d(e){const n={a:"a",blockquote:"blockquote",code:"code",h1:"h1",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,a.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"plugin-introduction",children:"Plugin Introduction"}),"\n",(0,i.jsx)(n.p,{children:"Plugins are the units that could be orchestrated by TaskWeaver. One could view the plugins as tools that the LLM can\nutilize to accomplish certain tasks."}),"\n",(0,i.jsx)(n.p,{children:"In TaskWeaver, each plugin is represented as a Python function that can be called within a code snippet. The\norchestration is essentially the process of generating Python code snippets consisting of a certain number of plugins.\nOne concrete example would be pulling data from database and apply anomaly detection. The generated code (simplified) looks like\nfollows:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-python",children:'df, data_description = sql_pull_data(query="pull data from time_series table") \nanomaly_df, anomaly_description = anomaly_detection(df, time_col_name="ts", value_col_name="val") \n'})}),"\n",(0,i.jsx)(n.h2,{id:"plugin-structure",children:"Plugin Structure"}),"\n",(0,i.jsx)(n.p,{children:"A plugin has two files:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Plugin Implementation"}),": a Python file that defines the plugin"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Plugin Schema"}),": a file in yaml that defines the schema of the plugin"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"plugin-implementation",children:"Plugin Implementation"}),"\n",(0,i.jsx)(n.p,{children:"The plugin function needs to be implemented in Python.\nTo be coordinated with the orchestration by TaskWeaver, a plugin python file consists of two parts:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Plugin function implementation code"}),"\n",(0,i.jsx)(n.li,{children:"TaskWeaver plugin decorator"}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Here we exhibit an example of the anomaly detection plugin as the following code:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-python",children:'import pandas as pd\nfrom pandas.api.types import is_numeric_dtype\n\nfrom taskweaver.plugin import Plugin, register_plugin\n\n\n@register_plugin\nclass AnomalyDetectionPlugin(Plugin):\n def __call__(self, df: pd.DataFrame, time_col_name: str, value_col_name: str):\n\n """\n anomaly_detection function identifies anomalies from an input dataframe of time series.\n It will add a new column "Is_Anomaly", where each entry will be marked with "True" if the value is an anomaly\n or "False" otherwise.\n\n :param df: the input data, must be a dataframe\n :param time_col_name: name of the column that contains the datetime\n :param value_col_name: name of the column that contains the numeric values.\n :return df: a new df that adds an additional "Is_Anomaly" column based on the input df.\n :return description: the description about the anomaly detection results.\n """\n try:\n df[time_col_name] = pd.to_datetime(df[time_col_name])\n except Exception:\n print("Time column is not datetime")\n return\n\n if not is_numeric_dtype(df[value_col_name]):\n try:\n df[value_col_name] = df[value_col_name].astype(float)\n except ValueError:\n print("Value column is not numeric")\n return\n\n mean, std = df[value_col_name].mean(), df[value_col_name].std()\n cutoff = std * 3\n lower, upper = mean - cutoff, mean + cutoff\n df["Is_Anomaly"] = df[value_col_name].apply(lambda x: x < lower or x > upper)\n anomaly_count = df["Is_Anomaly"].sum()\n description = "There are {} anomalies in the time series data".format(anomaly_count)\n \n self.ctx.add_artifact(\n name="anomaly_detection_results", # a brief description of the artifact\n file_name="anomaly_detection_results.csv", # artifact file name\n type="df", # artifact data type, support chart/df/file/txt/svg\n val=df, # variable to be dumped\n )\n \n return df, description\n\n'})}),"\n",(0,i.jsx)(n.p,{children:"You need to go through the following steps to implement your own plugin."}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["import the TaskWeaver plugin decorator ",(0,i.jsx)(n.code,{children:"from taskWeaver.plugin import Plugin, register_plugin"})]}),"\n",(0,i.jsxs)(n.li,{children:["create your plugin class inherited from ",(0,i.jsx)(n.code,{children:"Plugin"})," parent class (e.g., ",(0,i.jsx)(n.code,{children:"AnomalyDetectionPlugin(Plugin)"}),"), which is\ndecorated by ",(0,i.jsx)(n.code,{children:"@register_plugin"})]}),"\n",(0,i.jsxs)(n.li,{children:["implement your plugin function in ",(0,i.jsx)(n.code,{children:"__call__"})," method of the plugin class. ",(0,i.jsxs)(n.strong,{children:["Most importantly, it is mandatory to\ninclude ",(0,i.jsx)(n.code,{children:"descriptions"})," of your execution results in the return values of your plugin function"]}),". These descriptions\ncan be utilized by the LLM to effectively summarize your execution results."]}),"\n"]}),"\n",(0,i.jsxs)(n.blockquote,{children:["\n",(0,i.jsx)(n.p,{children:"\ud83d\udca1A key difference in a plugin implementation and a normal python function is that it always return a description of\nthe result in natural language. As LLMs only understand natural language, it is important to let the model understand\nwhat the execution result is. In the example implementation above, the description says how many anomalies are detected.\nBehind the scene, only the description will be passed to the LLM model. In contrast, the execution result (e.g., df in\nthe above example) is not handled by the LLM."}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"important-notes",children:"Important Notes"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"If the functionality of your plugin depends on additional libraries or packages, it is essential to ensure that they\nare installed before proceeding."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["If you wish to persist intermediate results, such as data, figures, or prompts, in your plugin implementation,\nTaskWeaver provides an ",(0,i.jsx)(n.code,{children:"add_artifact"})," API that allows you to store these results in the workspace. In the example we\nprovide, if you have performed anomaly detection and obtained results in the form of a CSV file, you can utilize\nthe ",(0,i.jsx)(n.code,{children:"add_artifact"})," API to save this file as an artifact. The artifacts are stored in the ",(0,i.jsx)(n.code,{children:"project/workspace/session_id/cwd"})," folder in the project directory."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-python",children:'self.ctx.add_artifact(\n name="anomaly_detection_results", # a brief description of the artifact\n file_name="anomaly_detection_results.csv", # artifact file name\n type="df", # artifact data type, support chart/df/file/txt/svg\n val=df, # variable to be dumped\n)\n'})}),"\n",(0,i.jsx)(n.h2,{id:"plugin-schema",children:"Plugin Schema"}),"\n",(0,i.jsx)(n.p,{children:"The plugin schema is composed of several parts:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"name"}),": The main function name of the Python code."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"enabled"}),": determine whether the plugin is enabled for selection during conversations. The default value is true."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"descriptions"}),": A brief description that introduces the plugin function."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"parameters"}),": This section lists all the input parameter information. It includes the parameter's name, type,\nwhether it is required or optional, and a description providing more details about the parameter."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"returns"}),": This section lists all the return value information. It includes the return value's name, type, and\ndescription that provides information about the value that is returned by the function."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Note:"})," The addition of any extra fields would result in a validation failure within the plugin schema."]}),"\n",(0,i.jsx)(n.p,{children:"The plugin schema is required to be written in YAML format. Here is the plugin schema example of the above anomaly\ndetection plugin:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'name: anomaly_detection\nenabled: true\nrequired: false\ndescription: >-\n anomaly_detection function identifies anomalies from an input DataFrame of\n time series. It will add a new column "Is_Anomaly", where each entry will be marked with "True" if the value is an anomaly or "False" otherwise.\n\nparameters:\n - name: df\n type: DataFrame\n required: true\n description: >-\n the input data from which we can identify the anomalies with the 3-sigma\n algorithm.\n - name: time_col_name\n type: str\n required: true\n description: name of the column that contains the datetime\n - name: value_col_name\n type: str\n required: true\n description: name of the column that contains the numeric values.\n\nreturns:\n - name: df\n type: DataFrame\n description: >-\n This DataFrame extends the input DataFrame with a newly-added column\n "Is_Anomaly" containing the anomaly detection result.\n - name: description\n type: str\n description: This is a string describing the anomaly detection results.\n\n'})}),"\n",(0,i.jsx)(n.p,{children:"Besides, we also set two optional fields as below:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"code"}),": Without specifying the code file name, the plugin schema will use the plugin name as the code file name.\nFor example, the plugin name is ",(0,i.jsx)(n.code,{children:"anomaly_detection"})," and the code file name is ",(0,i.jsx)(n.code,{children:"anomaly_detection.py"}),".\nIn cases where the plugin name is not the same as the code file name, you can specify the code name (code file) in\nthe plugin schema to ensure clarity and accuracy. For example, the plugin name is ",(0,i.jsx)(n.code,{children:"anomaly_detection"})," and the code\nfile name is ",(0,i.jsx)(n.code,{children:"anomaly_detection_code.py"}),". Then, you can specify the code name in the plugin schema as follows:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"code: anomaly_detection_code\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Note that the code file name should be the same as the code name without the ",(0,i.jsx)(n.code,{children:".py"})," extension."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"configurations"}),": When using common code that requires some configuration parameter modifications for different\nplugins, it is important to specify these configuration parameters in the plugin schema.\nThe configuration parameters are specified in the plugin schema as follows:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:" configurations:\n key1: value1\n key2: value2\n"})}),"\n",(0,i.jsx)(n.p,{children:"These configuration parameters can be accessed in the plugin implementation as follows:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-python",children:'self.config.get("key1")\nself.config.get("key2")\n'})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"plugin_only"}),": When this plugin is only used for the\n",(0,i.jsx)(n.a,{href:"https://microsoft.github.io/TaskWeaver/docs/plugin/plugin_only",children:"plugin-only mode"}),",\nset this field to ",(0,i.jsx)(n.code,{children:"true"}),". The default value is ",(0,i.jsx)(n.code,{children:"false"}),". Note that all plugins will be\nloaded in the non-plugin-only mode which is the default mode.\nBut in the plugin-only mode, only the plugins with ",(0,i.jsx)(n.code,{children:"plugin_only: true"})," will be loaded."]}),"\n"]}),"\n"]})]})}function u(e={}){const{wrapper:n}={...(0,a.a)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},1151:(e,n,t)=>{t.d(n,{Z:()=>s,a:()=>l});var i=t(7294);const a={},o=i.createContext(a);function l(e){const n=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function s(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:l(e.components),i.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3bb29254.b607cba5.js b/assets/js/3bb29254.b607cba5.js deleted file mode 100644 index 3780be63..00000000 --- a/assets/js/3bb29254.b607cba5.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5887],{5461:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>r,default:()=>d,frontMatter:()=>o,metadata:()=>a,toc:()=>c});var i=t(5893),s=t(1151);const o={},r="Auto Plugin Selection",a={id:"customization/plugin/plugin_selection",title:"Auto Plugin Selection",description:"In TaskWeaver, we provide an auto plugin selection mechanism to dynamically select the best plugin for each user request.",source:"@site/docs/customization/plugin/plugin_selection.md",sourceDirName:"customization/plugin",slug:"/customization/plugin/plugin_selection",permalink:"/TaskWeaver/docs/customization/plugin/plugin_selection",draft:!1,unlisted:!1,editUrl:"https://github.com/microsoft/TaskWeaver/tree/main/website/docs/customization/plugin/plugin_selection.md",tags:[],version:"current",frontMatter:{},sidebar:"documentSidebar",previous:{title:"Plugin Introduction",permalink:"/TaskWeaver/docs/plugin/plugin_intro"},next:{title:"How to develop a new plugin",permalink:"/TaskWeaver/docs/plugin/how_to_develop_a_new_plugin"}},l={},c=[{value:"Auto Plugin Selection Overview",id:"auto-plugin-selection-overview",level:2},{value:"Auto Plugin Selection Configuration",id:"auto-plugin-selection-configuration",level:2},{value:"Auto Plugin Selection Preparation",id:"auto-plugin-selection-preparation",level:2}];function u(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,s.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"auto-plugin-selection",children:"Auto Plugin Selection"}),"\n",(0,i.jsx)(n.p,{children:"In TaskWeaver, we provide an auto plugin selection mechanism to dynamically select the best plugin for each user request.\nIt targets to solve the following two problems:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsx)(n.li,{children:"An excessive number of plugins may cause confusion for LLM, leading to inaccuracies in generating the correct code."}),"\n",(0,i.jsx)(n.li,{children:"A large number of plugins could lead to increased token usage (potentially exceeding the token limit of LLM) and extended response time."}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"auto-plugin-selection-overview",children:"Auto Plugin Selection Overview"}),"\n",(0,i.jsxs)(n.p,{children:["Below is the overview workflow of the auto plugin selection mechanism.\n",(0,i.jsx)(n.img,{alt:"Auto Plugin Selection Overview",src:t(802).Z+"",width:"1846",height:"543"})]}),"\n",(0,i.jsx)(n.p,{children:"NOTE: the automatic plugin selection mechanism is only activated during the code generation process in the Code Interpreter and does not affect the planning process of the Planner."}),"\n",(0,i.jsxs)(n.p,{children:["At the start of TaskWeaver initialization, the automatic plugin selector is activated to generate embedding vectors for all plugins, including their names and descriptions.\nThe embedding vectors are created using the specified embedding model configured in the ",(0,i.jsx)(n.code,{children:"taskweaver_config.json"})," file.\nFor more information, please refer to the ",(0,i.jsx)(n.a,{href:"/TaskWeaver/docs/configurations/configurations_in_detail",children:"embedding"})," section in documentation."]}),"\n",(0,i.jsxs)(n.p,{children:["When the Planner sends a request to the Code Interpreter, the auto plugin selection mechanism will be triggered.\nIt will first generate an embedding vector for the request using the same embedding model.\nThen, it will calculate the cosine similarity between the request embedding vector and the embedding vectors of all plugins.\nIt will select the top-k plugins with the highest cosine similarity scores and load them into the ",(0,i.jsx)(n.code,{children:"code_generator"})," prompt."]}),"\n",(0,i.jsxs)(n.p,{children:["Upon completing the code generation, the ",(0,i.jsx)(n.code,{children:"code_generator"})," employs one or more plugins to produce the desired code.\nWe have established a plugin pool to store the plugins involved in the code generation process while filtering out any unused ones.\nDuring the subsequent automatic plugin selection phase, newly chosen plugins are appended to the existing ones."]}),"\n",(0,i.jsx)(n.h2,{id:"auto-plugin-selection-configuration",children:"Auto Plugin Selection Configuration"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"code_generator.enable_auto_plugin_selection"}),": Whether to enable auto plugin selection. The default value is ",(0,i.jsx)(n.code,{children:"false"}),"."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"code_generator.auto_plugin_selection_topk"}),":\tThe number of auto selected plugins in each round. The default value is ",(0,i.jsx)(n.code,{children:"3"}),"."]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"auto-plugin-selection-preparation",children:"Auto Plugin Selection Preparation"}),"\n",(0,i.jsx)(n.p,{children:"Before using the auto plugin selection mechanism, we need to run the following command to generate the plugin meta files with embeddings."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"cd scripts\npython -m plugin_mgt --refresh\n"})}),"\n",(0,i.jsxs)(n.p,{children:["After that, you can find the ",(0,i.jsx)(n.code,{children:".meta"})," directory is generated in the ",(0,i.jsx)(n.code,{children:"plugins"})," folder.\nThen you can start a new TaskWeaver session with the auto plugin selection mechanism enabled.\nCode Generator will automatically load the plugin meta files with embeddings."]}),"\n",(0,i.jsx)(n.p,{children:"\ud83c\udf88Plugin meta files will be treated as invalid if:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"The plugin embedding vector is not generated."}),"\n",(0,i.jsx)(n.li,{children:"The plugin is modified."}),"\n",(0,i.jsx)(n.li,{children:"The plugin embedding model is changed."}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"In this case, you cannot start the TaskWeaver and you need to run the above command again to refresh the plugin meta files."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"\n## Auto Plugin Selection Example\n\nWe show the auto plugin selection mechanism in the following example.\n\nFirst, we start TaskWeaver with the auto plugin selection mechanism enabled.\n```bash\n=========================================================\n _____ _ _ __\n|_ _|_ _ ___| | _ | | / /__ ____ __ _____ _____\n | |/ _` / __| |/ /| | /| / / _ \\/ __ `/ | / / _ \\/ ___/\n | | (_| \\__ \\ < | |/ |/ / __/ /_/ /| |/ / __/ /\n |_|\\__,_|___/_|\\_\\|__/|__/\\___/\\__,_/ |___/\\___/_/\n=========================================================\nTaskWeaver: I am TaskWeaver, an AI assistant. To get started, could you please enter your request?\nHuman: \n"})}),"\n",(0,i.jsxs)(n.p,{children:["Then we can check the log file ",(0,i.jsx)(n.code,{children:"task_weaver.log"})," in the ",(0,i.jsx)(n.code,{children:"logs"})," folder to see the auto plugin selector is initialized successfully because the ",(0,i.jsx)(n.code,{children:"Plugin embeddings generated"})," message is printed."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"2023-12-18 14:23:44,197 - INFO - Planner initialized successfully\n2023-12-18 14:24:10,488 - INFO - Plugin embeddings generated\n2023-12-18 14:24:10,490 - INFO - CodeInterpreter initialized successfully.\n2023-12-18 14:24:10,490 - INFO - Session 20231218-062343-c18494b1 is initialized\n"})}),"\n",(0,i.jsx)(n.p,{children:'We ask TaskWeaver to "search Xbox price for me".\nThe Planner instructs the Code Interpreter to search Xbox price.'}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"TaskWeaver: I am TaskWeaver, an AI assistant. To get started, could you please enter your request?\nHuman: search xbox price for me\n>>> [INIT_PLAN]\n1. search xbox price\n2. report the result to the user \n>>> [PLAN]\n1. instruct CodeInterpreter to search xbox price\n2. report the result to the user\n>>> [CURRENT_PLAN_STEP]\n1. instruct CodeInterpreter to search xbox price\n>>> [SEND_TO]\nCodeInterpreter\n>>> [MESSAGE]\nPlease search xbox price\n>>> [PLANNER->CODEINTERPRETER]\nPlease search xbox price\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Back to the Code Interpreter, the auto plugin selection mechanism is triggered.\nWe can check the log file ",(0,i.jsx)(n.code,{children:"task_weaver.log"})," again to see the auto plugin selector selected the top-3 plugins with the highest cosine similarity scores."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"023-12-18 14:24:34,513 - INFO - Planner talk to CodeInterpreter: Please search xbox price using klarna_search plugin\n2023-12-18 14:24:34,669 - INFO - Selected plugins: ['klarna_search', 'sql_pull_data', 'paper_summary']\n2023-12-18 14:24:34,669 - INFO - Selected plugin pool: ['klarna_search', 'sql_pull_data', 'paper_summary']\n"})}),"\n",(0,i.jsx)(n.p,{children:"Then the Code Interpreter will generate the code using the selected plugins."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:">>> [THOUGHT]\nProgramApe will call the klarna_search plugin function to search for Xbox prices.\n>>> [PYTHON]\nsearch_results, description = klarna_search(query=\"xbox\")\nsearch_results, description\n>>> [VERIFICATION]\nNONE\n>>> [STATUS]\nSUCCESS\n>>> [RESULT]\nThe execution of the generated python code above has succeeded\n\nThe result of above Python code after execution is:\n( name price url attributes\n 0 Microsoft Xbox Series X - Black Edition $399.00 https://www.klarna.com/us/shopping/pl/cl52/495... [Release Year:2020, Included Accessories:1 gam...\n 1 Microsoft Xbox Series S 1TB - Black $349.00 https://www.klarna.com/us/shopping/pl/cl52/320... [Included Accessories:1 gamepad, Media Type:DV...\n .. ... ... ... ...\n 3 Xbox Series S \u2013 Starter Bundle $239.00 https://www.klarna.com/us/shopping/pl/cl52/320... [Platform:Xbox One]\n 4 Microsoft Xbox Series X 1TB Console - Diablo I... $385.58 https://www.klarna.com/us/shopping/pl/cl52/320... [Release Year:2023, Included Accessories:1 gam...\n\n [5 rows x 4 columns],\n 'The response is a dataframe with the following columns: name, price, url, attributes. The attributes column is a list of tags. The price is in the format of $xx.xx.')\n>>> [CODEINTERPRETER->PLANNER]\nThe following python code has been executed:\n```python\nsearch_results, description = klarna_search(query=\"xbox\")\nsearch_results, description\n```\n\nThe execution of the generated python code above has succeeded\n\nThe result of above Python code after execution is:\n( name price url attributes\n 0 Microsoft Xbox Series X - Black Edition $399.00 https://www.klarna.com/us/shopping/pl/cl52/495... [Release Year:2020, Included Accessories:1 gam...\n 1 Microsoft Xbox Series S 1TB - Black $349.00 https://www.klarna.com/us/shopping/pl/cl52/320... [Included Accessories:1 gamepad, Media Type:DV...\n .. ... ... ... ...\n 3 Xbox Series S \u2013 Starter Bundle $239.00 https://www.klarna.com/us/shopping/pl/cl52/320... [Platform:Xbox One]\n 4 Microsoft Xbox Series X 1TB Console - Diablo I... $385.58 https://www.klarna.com/us/shopping/pl/cl52/320... [Release Year:2023, Included Accessories:1 gam...\n\n [5 rows x 4 columns],\n 'The response is a dataframe with the following columns: name, price, url, attributes. The attributes column is a list of tags. The price is in the format of $xx.xx.')\n"})}),"\n",(0,i.jsx)(n.p,{children:"Finally, the Planner will report the result to the user."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:">>> [INIT_PLAN]\n1. search xbox price using klarna_search plugin\n2. report the result to the user \n>>> [PLAN]\n1. instruct CodeInterpreter to search xbox price using klarna_search plugin\n2. report the result to the user\n>>> [CURRENT_PLAN_STEP]\n2. report the result to the user\n>>> [SEND_TO]\nUser\n>>> [MESSAGE]\nHere are some Xbox prices I found:\n\n1. Microsoft Xbox Series X - Black Edition: $399.00\n2. Microsoft Xbox Series S 1TB - Black: $349.00\n3. Xbox Series S \u2013 Starter Bundle: $239.00\n4. Microsoft Xbox Series X 1TB Console - Diablo Immortal Edition: $385.58\n\nPlease note that these prices are subject to change and availability.\n>>> [PLANNER->USER]\nHere are some Xbox prices I found:\n\n1. Microsoft Xbox Series X - Black Edition: $399.00\n2. Microsoft Xbox Series S 1TB - Black: $349.00\n3. Xbox Series S \u2013 Starter Bundle: $239.00\n4. Microsoft Xbox Series X 1TB Console - Diablo Immortal Edition: $385.58\n\nPlease note that these prices are subject to change and availability.\nTaskWeaver: Here are some Xbox prices I found:\n\n1. Microsoft Xbox Series X - Black Edition: $399.00\n2. Microsoft Xbox Series S 1TB - Black: $349.00\n3. Xbox Series S \u2013 Starter Bundle: $239.00\n4. Microsoft Xbox Series X 1TB Console - Diablo Immortal Edition: $385.58\n\nPlease note that these prices are subject to change and availability.\n"})})]})}function d(e={}){const{wrapper:n}={...(0,s.a)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(u,{...e})}):u(e)}},802:(e,n,t)=>{t.d(n,{Z:()=>i});const i=t.p+"assets/images/APS-1dc4d286038dedc17487146cec8214fd.png"},1151:(e,n,t)=>{t.d(n,{Z:()=>a,a:()=>r});var i=t(7294);const s={},o=i.createContext(s);function r(e){const n=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),i.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/45fd52fa.43ac5af6.js b/assets/js/45fd52fa.43ac5af6.js deleted file mode 100644 index 11b44f0d..00000000 --- a/assets/js/45fd52fa.43ac5af6.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[3991],{186:(e,i,t)=>{t.r(i),t.d(i,{assets:()=>a,contentTitle:()=>c,default:()=>h,frontMatter:()=>d,metadata:()=>r,toc:()=>s});var n=t(5893),o=t(1151);const d={id:"code_verification",description:"Code Verification",slug:"code_verification"},c="Code Verification",r={id:"advanced/code_verification",title:"Code Verification",description:"Code Verification",source:"@site/docs/advanced/verification.md",sourceDirName:"advanced",slug:"/advanced/code_verification",permalink:"/TaskWeaver/docs/advanced/code_verification",draft:!1,unlisted:!1,editUrl:"https://github.com/microsoft/TaskWeaver/tree/main/website/docs/advanced/verification.md",tags:[],version:"current",frontMatter:{id:"code_verification",description:"Code Verification",slug:"code_verification"},sidebar:"documentSidebar",previous:{title:"Prompt Compression",permalink:"/TaskWeaver/docs/advanced/compression"},next:{title:"Code Execution",permalink:"/TaskWeaver/docs/advanced/code_execution"}},a={},s=[{value:"Why do we need code verification?",id:"why-do-we-need-code-verification",level:2},{value:"How to use code verification?",id:"how-to-use-code-verification",level:2},{value:"How is code verification implemented?",id:"how-is-code-verification-implemented",level:2}];function l(e){const i={br:"br",code:"code",h1:"h1",h2:"h2",img:"img",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,o.a)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(i.h1,{id:"code-verification",children:"Code Verification"}),"\n",(0,n.jsx)(i.h2,{id:"why-do-we-need-code-verification",children:"Why do we need code verification?"}),"\n",(0,n.jsx)(i.p,{children:"Agent developers may want to verify the generated code before running it.\nIn the following example shown in the figure, the generated code is"}),"\n",(0,n.jsx)(i.pre,{children:(0,n.jsx)(i.code,{className:"language-python",children:'import os\n\nfile = open("abc.py", "r")\ncode = file.read()\nexec(code)\n'})}),"\n",(0,n.jsx)(i.p,{children:(0,n.jsx)(i.img,{alt:"Code verification workflow",src:t(248).Z+"",width:"760",height:"351"})}),"\n",(0,n.jsx)(i.p,{children:"In this case, the generated code read the content of a file and execute it, which is potentially dangerous.\nTo prevent this, we can use code verification to check the generated code before running it.\nIf the code does not pass the verification, the errors will be reported to the CodeGenerator to re-generate the code."}),"\n",(0,n.jsx)(i.h2,{id:"how-to-use-code-verification",children:"How to use code verification?"}),"\n",(0,n.jsxs)(i.p,{children:["To use code verification, you can add the configuration ",(0,n.jsx)(i.code,{children:'"code_interpreter.code_verification_on": true'}),"\nin the project configuration file ",(0,n.jsx)(i.code,{children:"taskweaver_config.json"}),".\nThen, the generated code will be verified before running it."]}),"\n",(0,n.jsx)(i.p,{children:"After enabling code verification, you can also specify the code verification rules in the project configuration file."}),"\n",(0,n.jsxs)(i.table,{children:[(0,n.jsx)(i.thead,{children:(0,n.jsxs)(i.tr,{children:[(0,n.jsx)(i.th,{children:"Parameter"}),(0,n.jsx)(i.th,{children:"Description"}),(0,n.jsx)(i.th,{children:"Default"})]})}),(0,n.jsxs)(i.tbody,{children:[(0,n.jsxs)(i.tr,{children:[(0,n.jsx)(i.td,{children:"code_interpreter.allowed_modules"}),(0,n.jsx)(i.td,{children:"The list of allowed modules to import in code generation."}),(0,n.jsx)(i.td,{children:'["pandas", "matplotlib", "numpy", "sklearn", "scipy", "seaborn", "datetime", "typing"], if the list is empty, no modules would be allowed'})]}),(0,n.jsxs)(i.tr,{children:[(0,n.jsx)(i.td,{children:"code_interpreter.blocked_functions"}),(0,n.jsx)(i.td,{children:"The list of functions to block from code generation."}),(0,n.jsx)(i.td,{children:'["__import__","eval", "exec", "execfile", "compile", "open", "input", "raw_input", "reload"]'})]})]})]}),"\n",(0,n.jsxs)(i.p,{children:["We currently support checking the allowed modules and blocked functions.\nIf a module is in the ",(0,n.jsx)(i.code,{children:"allowed_modules"})," list, it can be imported in the generated code.\nIf a function is in the ",(0,n.jsx)(i.code,{children:"blocked_functions"})," list, it cannot be used in the generated code."]}),"\n",(0,n.jsx)(i.h2,{id:"how-is-code-verification-implemented",children:"How is code verification implemented?"}),"\n",(0,n.jsxs)(i.p,{children:["The code verification is implemented in two parts.\nFirst, we add instructions to CodeGenerator's prompt, so it generates code following the required rules.\nFor example, if we don't want the generated code to import the ",(0,n.jsx)(i.code,{children:"os"})," module,\nwe will add an instruction to the prompt to tell CodeGenerator not to import the ",(0,n.jsx)(i.code,{children:"os"})," module."]}),"\n",(0,n.jsxs)(i.p,{children:["Second, we conduct a static analysis on the generated code to check if it follows the required rules.\nThe code is parsed into an AST (Abstract Syntax Tree) and we check if the AST",(0,n.jsx)(i.br,{}),"\n","only imports the allowed modules, and does not use the blocked functions.\nThe implementation of the static analysis can be found in ",(0,n.jsx)(i.code,{children:"taskweaver/code_interpreter/code_verification.py"}),"."]})]})}function h(e={}){const{wrapper:i}={...(0,o.a)(),...e.components};return i?(0,n.jsx)(i,{...e,children:(0,n.jsx)(l,{...e})}):l(e)}},248:(e,i,t)=>{t.d(i,{Z:()=>n});const n=t.p+"assets/images/code_verification-352e772bbe2d5ab3f4db8ec6ff87b129.png"},1151:(e,i,t)=>{t.d(i,{Z:()=>r,a:()=>c});var n=t(7294);const o={},d=n.createContext(o);function c(e){const i=n.useContext(d);return n.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function r(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:c(e.components),n.createElement(d.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/45fd52fa.6413b7e3.js b/assets/js/45fd52fa.6413b7e3.js new file mode 100644 index 00000000..a8996b9f --- /dev/null +++ b/assets/js/45fd52fa.6413b7e3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[3991],{186:(e,i,n)=>{n.r(i),n.d(i,{assets:()=>a,contentTitle:()=>c,default:()=>h,frontMatter:()=>d,metadata:()=>r,toc:()=>s});var t=n(5893),o=n(1151);const d={id:"code_verification",description:"Code Verification",slug:"code_verification"},c="Code Verification",r={id:"advanced/code_verification",title:"Code Verification",description:"Code Verification",source:"@site/docs/advanced/verification.md",sourceDirName:"advanced",slug:"/advanced/code_verification",permalink:"/TaskWeaver/docs/advanced/code_verification",draft:!1,unlisted:!1,editUrl:"https://github.com/microsoft/TaskWeaver/tree/main/website/docs/advanced/verification.md",tags:[],version:"current",frontMatter:{id:"code_verification",description:"Code Verification",slug:"code_verification"},sidebar:"documentSidebar",previous:{title:"Auto Plugin Selection",permalink:"/TaskWeaver/docs/advanced/plugin_selection"},next:{title:"CLI Only Mode",permalink:"/TaskWeaver/docs/advanced/cli_only"}},a={},s=[{value:"Why do we need code verification?",id:"why-do-we-need-code-verification",level:2},{value:"How to use code verification?",id:"how-to-use-code-verification",level:2},{value:"How is code verification implemented?",id:"how-is-code-verification-implemented",level:2}];function l(e){const i={br:"br",code:"code",h1:"h1",h2:"h2",img:"img",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,o.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(i.h1,{id:"code-verification",children:"Code Verification"}),"\n",(0,t.jsx)(i.h2,{id:"why-do-we-need-code-verification",children:"Why do we need code verification?"}),"\n",(0,t.jsx)(i.p,{children:"Agent developers may want to verify the generated code before running it.\nIn the following example shown in the figure, the generated code is"}),"\n",(0,t.jsx)(i.pre,{children:(0,t.jsx)(i.code,{className:"language-python",children:'import os\n\nfile = open("abc.py", "r")\ncode = file.read()\nexec(code)\n'})}),"\n",(0,t.jsx)(i.p,{children:(0,t.jsx)(i.img,{alt:"Code verification workflow",src:n(248).Z+"",width:"760",height:"351"})}),"\n",(0,t.jsx)(i.p,{children:"In this case, the generated code read the content of a file and execute it, which is potentially dangerous.\nTo prevent this, we can use code verification to check the generated code before running it.\nIf the code does not pass the verification, the errors will be reported to the CodeGenerator to re-generate the code."}),"\n",(0,t.jsx)(i.h2,{id:"how-to-use-code-verification",children:"How to use code verification?"}),"\n",(0,t.jsxs)(i.p,{children:["To use code verification, you can add the configuration ",(0,t.jsx)(i.code,{children:'"code_interpreter.code_verification_on": true'}),"\nin the project configuration file ",(0,t.jsx)(i.code,{children:"taskweaver_config.json"}),".\nThen, the generated code will be verified before running it."]}),"\n",(0,t.jsx)(i.p,{children:"After enabling code verification, you can also specify the code verification rules in the project configuration file."}),"\n",(0,t.jsxs)(i.table,{children:[(0,t.jsx)(i.thead,{children:(0,t.jsxs)(i.tr,{children:[(0,t.jsx)(i.th,{children:"Parameter"}),(0,t.jsx)(i.th,{children:"Description"}),(0,t.jsx)(i.th,{children:"Default"})]})}),(0,t.jsxs)(i.tbody,{children:[(0,t.jsxs)(i.tr,{children:[(0,t.jsx)(i.td,{children:"code_interpreter.allowed_modules"}),(0,t.jsx)(i.td,{children:"The list of allowed modules to import in code generation."}),(0,t.jsx)(i.td,{children:'["pandas", "matplotlib", "numpy", "sklearn", "scipy", "seaborn", "datetime", "typing"], if the list is empty, no modules would be allowed'})]}),(0,t.jsxs)(i.tr,{children:[(0,t.jsx)(i.td,{children:"code_interpreter.blocked_functions"}),(0,t.jsx)(i.td,{children:"The list of functions to block from code generation."}),(0,t.jsx)(i.td,{children:'["__import__","eval", "exec", "execfile", "compile", "open", "input", "raw_input", "reload"]'})]})]})]}),"\n",(0,t.jsxs)(i.p,{children:["We currently support checking the allowed modules and blocked functions.\nIf a module is in the ",(0,t.jsx)(i.code,{children:"allowed_modules"})," list, it can be imported in the generated code.\nIf a function is in the ",(0,t.jsx)(i.code,{children:"blocked_functions"})," list, it cannot be used in the generated code."]}),"\n",(0,t.jsx)(i.h2,{id:"how-is-code-verification-implemented",children:"How is code verification implemented?"}),"\n",(0,t.jsxs)(i.p,{children:["The code verification is implemented in two parts.\nFirst, we add instructions to CodeGenerator's prompt, so it generates code following the required rules.\nFor example, if we don't want the generated code to import the ",(0,t.jsx)(i.code,{children:"os"})," module,\nwe will add an instruction to the prompt to tell CodeGenerator not to import the ",(0,t.jsx)(i.code,{children:"os"})," module."]}),"\n",(0,t.jsxs)(i.p,{children:["Second, we conduct a static analysis on the generated code to check if it follows the required rules.\nThe code is parsed into an AST (Abstract Syntax Tree) and we check if the AST",(0,t.jsx)(i.br,{}),"\n","only imports the allowed modules, and does not use the blocked functions.\nThe implementation of the static analysis can be found in ",(0,t.jsx)(i.code,{children:"taskweaver/code_interpreter/code_verification.py"}),"."]})]})}function h(e={}){const{wrapper:i}={...(0,o.a)(),...e.components};return i?(0,t.jsx)(i,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},248:(e,i,n)=>{n.d(i,{Z:()=>t});const t=n.p+"assets/images/code_verification-352e772bbe2d5ab3f4db8ec6ff87b129.png"},1151:(e,i,n)=>{n.d(i,{Z:()=>r,a:()=>c});var t=n(7294);const o={},d=t.createContext(o);function c(e){const i=t.useContext(d);return t.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function r(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:c(e.components),t.createElement(d.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/47284eb1.df65d7f9.js b/assets/js/47284eb1.df65d7f9.js deleted file mode 100644 index 74b4eb91..00000000 --- a/assets/js/47284eb1.df65d7f9.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[6063],{9297:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>u,frontMatter:()=>r,metadata:()=>i,toc:()=>l});var a=t(5893),s=t(1151);const r={},o="Library",i={id:"usage/library",title:"Library",description:"If you want to use TaskWeaver as a library, you can refer to the following code example:",source:"@site/docs/usage/library.md",sourceDirName:"usage",slug:"/usage/library",permalink:"/TaskWeaver/docs/usage/library",draft:!1,unlisted:!1,editUrl:"https://github.com/microsoft/TaskWeaver/tree/main/website/docs/usage/library.md",tags:[],version:"current",frontMatter:{},sidebar:"documentSidebar",previous:{title:"Web UI",permalink:"/TaskWeaver/docs/usage/webui"},next:{title:"All-in-One Docker Image",permalink:"/TaskWeaver/docs/usage/docker"}},c={},l=[];function d(e){const n={code:"code",h1:"h1",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.a)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.h1,{id:"library",children:"Library"}),"\n",(0,a.jsx)(n.p,{children:"If you want to use TaskWeaver as a library, you can refer to the following code example:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-python",children:'from taskweaver.app.app import TaskWeaverApp\n\n# This is the folder that contains the taskweaver_config.json file and not the repo root. Defaults to "./project/"\napp_dir = "./project/"\napp = TaskWeaverApp(app_dir=app_dir)\nsession = app.get_session()\n\nuser_query = "hello, what can you do?"\nresponse_round = session.send_message(user_query)\nprint(response_round.to_dict())\n'})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Note:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"response_round"}),": the response from TaskWeaver. which is an object of the ",(0,a.jsx)(n.code,{children:"Round"})," class.\nAn example of the ",(0,a.jsx)(n.code,{children:"Round"})," object is shown below:"]}),"\n"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "id": "round-20231201-043134-218a2681",\n "user_query": "hello, what can you do?",\n "state": "finished",\n "post_list": [\n {\n "id": "post-20231201-043134-10eedcca",\n "message": "hello, what can you do?",\n "send_from": "User",\n "send_to": "Planner",\n "attachment_list": []\n },\n {\n "id": "post-20231201-043141-86a2aaff",\n "message": "I can help you with various tasks, such as counting rows in a data file, detecting anomalies in a dataset, searching for products on Klarna, summarizing research papers, and pulling data from a SQL database. Please provide more information about the task you want to accomplish, and I\'ll guide you through the process.",\n "send_from": "Planner",\n "send_to": "User",\n "attachment_list": [\n {\n "id": "atta-20231201-043141-6bc4da86",\n "type": "init_plan",\n "content": "1. list the available functions"\n },\n {\n "id": "atta-20231201-043141-6f29f6c9",\n "type": "plan",\n "content": "1. list the available functions"\n },\n {\n "id": "atta-20231201-043141-76186c7a",\n "type": "current_plan_step",\n "content": "1. list the available functions"\n }\n ]\n }\n ]\n}\n'})})]})}function u(e={}){const{wrapper:n}={...(0,s.a)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(d,{...e})}):d(e)}},1151:(e,n,t)=>{t.d(n,{Z:()=>i,a:()=>o});var a=t(7294);const s={},r=a.createContext(s);function o(e){const n=a.useContext(r);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),a.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/47284eb1.ec8229b7.js b/assets/js/47284eb1.ec8229b7.js new file mode 100644 index 00000000..7efb0615 --- /dev/null +++ b/assets/js/47284eb1.ec8229b7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[6063],{9297:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>p,frontMatter:()=>o,metadata:()=>i,toc:()=>l});var a=t(5893),s=t(1151);const o={},r="Library",i={id:"usage/library",title:"Library",description:"If you want to use TaskWeaver as a library, you can refer to the following code example:",source:"@site/docs/usage/library.md",sourceDirName:"usage",slug:"/usage/library",permalink:"/TaskWeaver/docs/usage/library",draft:!1,unlisted:!1,editUrl:"https://github.com/microsoft/TaskWeaver/tree/main/website/docs/usage/library.md",tags:[],version:"current",frontMatter:{},sidebar:"documentSidebar",previous:{title:"Web UI",permalink:"/TaskWeaver/docs/usage/webui"},next:{title:"All-in-One Docker Image",permalink:"/TaskWeaver/docs/usage/docker"}},c={},l=[];function d(e){const n={admonition:"admonition",code:"code",h1:"h1",p:"p",pre:"pre",...(0,s.a)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.h1,{id:"library",children:"Library"}),"\n",(0,a.jsx)(n.p,{children:"If you want to use TaskWeaver as a library, you can refer to the following code example:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-python",children:'from taskweaver.app.app import TaskWeaverApp\n\n# This is the folder that contains the taskweaver_config.json file and not the repo root. Defaults to "./project/"\napp_dir = "./project/"\napp = TaskWeaverApp(app_dir=app_dir)\nsession = app.get_session()\n\nuser_query = "hello, what can you do?"\nresponse_round = session.send_message(user_query)\nprint(response_round.to_dict())\n'})}),"\n",(0,a.jsxs)(n.admonition,{type:"tip",children:[(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"response_round"}),": the response from TaskWeaver. which is an object of the ",(0,a.jsx)(n.code,{children:"Round"})," class.\nAn example of the ",(0,a.jsx)(n.code,{children:"Round"})," object is shown below:"]}),(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "id": "round-20231201-043134-218a2681",\n "user_query": "hello, what can you do?",\n "state": "finished",\n "post_list": [\n {\n "id": "post-20231201-043134-10eedcca",\n "message": "hello, what can you do?",\n "send_from": "User",\n "send_to": "Planner",\n "attachment_list": []\n },\n {\n "id": "post-20231201-043141-86a2aaff",\n "message": "I can help you with various tasks, such as counting rows in a data file, detecting anomalies in a dataset, searching for products on Klarna, summarizing research papers, and pulling data from a SQL database. Please provide more information about the task you want to accomplish, and I\'ll guide you through the process.",\n "send_from": "Planner",\n "send_to": "User",\n "attachment_list": [\n {\n "id": "atta-20231201-043141-6bc4da86",\n "type": "init_plan",\n "content": "1. list the available functions"\n },\n {\n "id": "atta-20231201-043141-6f29f6c9",\n "type": "plan",\n "content": "1. list the available functions"\n },\n {\n "id": "atta-20231201-043141-76186c7a",\n "type": "current_plan_step",\n "content": "1. list the available functions"\n }\n ]\n }\n ]\n}\n'})})]}),"\n",(0,a.jsxs)(n.admonition,{type:"tip",children:[(0,a.jsxs)(n.p,{children:["If you need to see the intermediate states of the conversation, you need to implement a ",(0,a.jsx)(n.code,{children:"SessionEventHandler"})," class and pass it\nat calling ",(0,a.jsx)(n.code,{children:"session.send_message(user_query, event_handler=your_event_handler)"}),".\nA toy example of the ",(0,a.jsx)(n.code,{children:"SessionEventHandler"})," class is shown below:"]}),(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-python",children:"from taskweaver.model.event_emitter import SessionEventHandler, TaskWeaverEvent\nclass ToyEventHandler(SessionEventHandler):\n \n def handle(self, event: TaskWeaverEvent):\n print(event.t, event.msg)\n"})})]})]})}function p(e={}){const{wrapper:n}={...(0,s.a)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(d,{...e})}):d(e)}},1151:(e,n,t)=>{t.d(n,{Z:()=>i,a:()=>r});var a=t(7294);const s={},o=a.createContext(s);function r(e){const n=a.useContext(o);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),a.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/55efe1e1.af4af1f3.js b/assets/js/55efe1e1.af4af1f3.js new file mode 100644 index 00000000..0d6d0182 --- /dev/null +++ b/assets/js/55efe1e1.af4af1f3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2646],{4517:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>i,default:()=>m,frontMatter:()=>r,metadata:()=>a,toc:()=>c});var o=s(5893),t=s(1151);const r={description:"Using LLMs from OpenAI/AOAI"},i="Azure OpenAI",a={id:"llms/aoai",title:"Azure OpenAI",description:"Using LLMs from OpenAI/AOAI",source:"@site/docs/llms/aoai.md",sourceDirName:"llms",slug:"/llms/aoai",permalink:"/TaskWeaver/docs/llms/aoai",draft:!1,unlisted:!1,editUrl:"https://github.com/microsoft/TaskWeaver/tree/main/website/docs/llms/aoai.md",tags:[],version:"current",frontMatter:{description:"Using LLMs from OpenAI/AOAI"},sidebar:"documentSidebar",previous:{title:"OpenAI",permalink:"/TaskWeaver/docs/llms/openai"},next:{title:"LiteLLM",permalink:"/TaskWeaver/docs/llms/liteLLM"}},l={},c=[];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",li:"li",ol:"ol",p:"p",pre:"pre",...(0,t.a)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h1,{id:"azure-openai",children:"Azure OpenAI"}),"\n",(0,o.jsxs)(n.ol,{children:["\n",(0,o.jsxs)(n.li,{children:["Create an account on ",(0,o.jsx)(n.a,{href:"https://azure.microsoft.com/en-us/products/ai-services/openai-service",children:"Azure OpenAI"})," and get your API key."]}),"\n",(0,o.jsxs)(n.li,{children:["Add the following to your ",(0,o.jsx)(n.code,{children:"taskweaver_config.json"})," file:"]}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-json",metastring:"showLineNumbers",children:'{\n "llm.api_base":"YOUR_AOAI_ENDPOINT",\n "llm.api_key":"YOUR_API_KEY",\n "llm.api_type":"azure",\n "llm.auth_mode":"api-key",\n "llm.model":"gpt-4-1106-preview", # this is known as deployment_name in Azure OpenAI\n "llm.response_format": "json_object"\n}\n'})}),"\n",(0,o.jsx)(n.admonition,{type:"info",children:(0,o.jsxs)(n.p,{children:["For model versions or after ",(0,o.jsx)(n.code,{children:"1106"}),", ",(0,o.jsx)(n.code,{children:"llm.response_format"})," can be set to ",(0,o.jsx)(n.code,{children:"json_object"}),".\nHowever, for the earlier models, which do not support JSON response explicitly, ",(0,o.jsx)(n.code,{children:"llm.response_format"})," should be set to ",(0,o.jsx)(n.code,{children:"null"}),"."]})}),"\n",(0,o.jsxs)(n.ol,{start:"3",children:["\n",(0,o.jsxs)(n.li,{children:["Start TaskWeaver and chat with TaskWeaver.\nYou can refer to the ",(0,o.jsx)(n.a,{href:"/TaskWeaver/docs/quickstart",children:"Quick Start"})," for more details."]}),"\n"]})]})}function m(e={}){const{wrapper:n}={...(0,t.a)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},1151:(e,n,s)=>{s.d(n,{Z:()=>a,a:()=>i});var o=s(7294);const t={},r=o.createContext(t);function i(e){const n=o.useContext(r);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:i(e.components),o.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/55efe1e1.ef4bf51b.js b/assets/js/55efe1e1.ef4bf51b.js deleted file mode 100644 index 1ddaf321..00000000 --- a/assets/js/55efe1e1.ef4bf51b.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2646],{4517:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>i,default:()=>p,frontMatter:()=>r,metadata:()=>a,toc:()=>c});var o=s(5893),t=s(1151);const r={description:"Using LLMs from OpenAI/AOAI"},i="Azure OpenAI",a={id:"llms/aoai",title:"Azure OpenAI",description:"Using LLMs from OpenAI/AOAI",source:"@site/docs/llms/aoai.md",sourceDirName:"llms",slug:"/llms/aoai",permalink:"/TaskWeaver/docs/llms/aoai",draft:!1,unlisted:!1,editUrl:"https://github.com/microsoft/TaskWeaver/tree/main/website/docs/llms/aoai.md",tags:[],version:"current",frontMatter:{description:"Using LLMs from OpenAI/AOAI"},sidebar:"documentSidebar",previous:{title:"OpenAI",permalink:"/TaskWeaver/docs/llms/openai"},next:{title:"LiteLLM",permalink:"/TaskWeaver/docs/llms/liteLLM"}},l={},c=[];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",li:"li",ol:"ol",p:"p",pre:"pre",...(0,t.a)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h1,{id:"azure-openai",children:"Azure OpenAI"}),"\n",(0,o.jsxs)(n.ol,{children:["\n",(0,o.jsxs)(n.li,{children:["Create an account on ",(0,o.jsx)(n.a,{href:"https://azure.microsoft.com/en-us/products/ai-services/openai-service",children:"Azure OpenAI"})," and get your API key."]}),"\n",(0,o.jsxs)(n.li,{children:["Add the following to your ",(0,o.jsx)(n.code,{children:"taskweaver_config.json"})," file:"]}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-json",metastring:"showLineNumbers",children:'{\n "llm.api_base":"YOUR_AOAI_ENDPOINT",\n "llm.api_key":"YOUR_API_KEY",\n "llm.api_type":"azure",\n "llm.auth_mode":"api-key",\n "llm.model":"gpt-4-1106-preview",\n "llm.response_format": "json_object"\n}\n'})}),"\n",(0,o.jsx)(n.admonition,{type:"tip",children:(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.code,{children:"llm.model"})," is the model name you want to use.\nYou can find the list of models ",(0,o.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/ai-services/openai/concepts/models",children:"here"}),"."]})}),"\n",(0,o.jsx)(n.admonition,{type:"info",children:(0,o.jsxs)(n.p,{children:["For ",(0,o.jsx)(n.code,{children:"gpt-4-1106-preview"})," and ",(0,o.jsx)(n.code,{children:"gpt-3.5-turbo-1106"}),", ",(0,o.jsx)(n.code,{children:"llm.response_format"})," can be set to ",(0,o.jsx)(n.code,{children:"json_object"}),".\nHowever, for the earlier models, which do not support JSON response explicitly, ",(0,o.jsx)(n.code,{children:"llm.response_format"})," should be set to ",(0,o.jsx)(n.code,{children:"null"}),"."]})}),"\n",(0,o.jsxs)(n.ol,{start:"3",children:["\n",(0,o.jsxs)(n.li,{children:["Start TaskWeaver and chat with TaskWeaver.\nYou can refer to the ",(0,o.jsx)(n.a,{href:"/TaskWeaver/docs/quickstart",children:"Quick Start"})," for more details."]}),"\n"]})]})}function p(e={}){const{wrapper:n}={...(0,t.a)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},1151:(e,n,s)=>{s.d(n,{Z:()=>a,a:()=>i});var o=s(7294);const t={},r=o.createContext(t);function i(e){const n=o.useContext(r);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:i(e.components),o.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5a1935a3.087eb325.js b/assets/js/5a1935a3.087eb325.js new file mode 100644 index 00000000..783114ca --- /dev/null +++ b/assets/js/5a1935a3.087eb325.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[6486],{5897:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>a,contentTitle:()=>t,default:()=>h,frontMatter:()=>s,metadata:()=>l,toc:()=>d});var r=i(5893),o=i(1151);const s={},t="More about Configurations",l={id:"configurations/configurations_in_detail",title:"More about Configurations",description:"More details about important configurations.",source:"@site/docs/configurations/configurations_in_detail.md",sourceDirName:"configurations",slug:"/configurations/configurations_in_detail",permalink:"/TaskWeaver/docs/configurations/configurations_in_detail",draft:!1,unlisted:!1,editUrl:"https://github.com/microsoft/TaskWeaver/tree/main/website/docs/configurations/configurations_in_detail.md",tags:[],version:"current",frontMatter:{},sidebar:"documentSidebar",previous:{title:"Configuration File",permalink:"/TaskWeaver/docs/configurations/overview"},next:{title:"Customization",permalink:"/TaskWeaver/docs/customization"}},a={},d=[{value:"Planner Configuration",id:"planner-configuration",level:2},{value:"Session Configuration",id:"session-configuration",level:2},{value:"Embedding Configuration",id:"embedding-configuration",level:2}];function c(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",li:"li",p:"p",pre:"pre",ul:"ul",...(0,o.a)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h1,{id:"more-about-configurations",children:"More about Configurations"}),"\n",(0,r.jsx)(n.p,{children:"More details about important configurations."}),"\n",(0,r.jsx)(n.h2,{id:"planner-configuration",children:"Planner Configuration"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"planner.example_base_path"}),":\tThe folder to store planner examples. The default value is ",(0,r.jsx)(n.code,{children:"${AppBaseDir}/planner_examples"}),".\nIf you want to create your own planner examples, you can add them to this folder. More details about ",(0,r.jsx)(n.code,{children:"example"})," can referred to ",(0,r.jsx)(n.a,{href:"/TaskWeaver/docs/customization/example/",children:"example"}),"."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"planner.prompt_compression"}),": At times, lengthy conversations with the Planner may exceed the input limitations of the LLM model.\nTo address this issue, we can compress the chat history and send it to the LLM model. The default value for this setting is ",(0,r.jsx)(n.code,{children:"false"}),".\nMore details about ",(0,r.jsx)(n.code,{children:"prompt_compression"})," can be referred to ",(0,r.jsx)(n.a,{href:"../advanced/compression",children:"prompt_compression"}),"."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"planner.use_experience"}),": Whether to use experience summarized from the previous chat history in planner. The default value is ",(0,r.jsx)(n.code,{children:"false"}),"."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"planner.llm_alias"}),": The alias of the LLM used by the Planner. If you do not specify the LLM for the Planner, the primary LLM will be used by default."]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"session-configuration",children:"Session Configuration"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"session.max_internal_chat_round_num"}),": the maximum number of internal chat rounds between Planner and Code Interpreter.\nIf the number of internal chat rounds exceeds this number, the session will be terminated.\nThe default value is ",(0,r.jsx)(n.code,{children:"10"}),"."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"session.roles"}),": the roles included for the conversation. The default value is ",(0,r.jsx)(n.code,{children:'["planner", "code_interpreter"]'}),".","\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"TaskWeaver has 3 code interpreters:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"code_interpreter"}),": it will generate Python code to fulfill the user's request. This is the default code interpreter."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"code_interpreter_plugin_only"}),": please refer to ",(0,r.jsx)(n.a,{href:"/TaskWeaver/docs/plugin/plugin_only",children:"plugin_only_mode"})," for more details."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"code_interpreter_cli_only"}),": allow users to directly communicate with the Command Line Interface (CLI) in natural language.\nPlease refer to ",(0,r.jsx)(n.a,{href:"/TaskWeaver/docs/advanced/cli_only",children:"cli_only_mode"})," for more details."]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["If you do not specify ",(0,r.jsx)(n.code,{children:"planner"}),' in the roles, you will enter the "no-planner" mode.\nIt allows users to directly communicate with the worker role, such as ',(0,r.jsx)(n.code,{children:"code_interpreter"}),".\nIn this mode, users can only send messages to the ",(0,r.jsx)(n.code,{children:"CodeInterpreter"})," and receive messages from the ",(0,r.jsx)(n.code,{children:"CodeInterpreter"}),'.\nNote that only single worker role is allowed in the "no-planner" mode because all user requests will be sent to the worker role directly.\nHere is an example:']}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:" =========================================================\n _____ _ _ __\n|_ _|_ _ ___| | _ | | / /__ ____ __ _____ _____\n | |/ _` / __| |/ /| | /| / / _ \\/ __ `/ | / / _ \\/ ___/\n | | (_| \\__ \\ < | |/ |/ / __/ /_/ /| |/ / __/ /\n |_|\\__,_|___/_|\\_\\|__/|__/\\___/\\__,_/ |___/\\___/_/\n=========================================================\nTaskWeaver: I am TaskWeaver, an AI assistant. To get started, could you please enter your request?\nHuman: generate 10 random numbers\n>>> [PYTHON]Starting... \nimport numpy as np\nrandom_numbers = np.random.rand(10)\nrandom_numbers\n>>> [VERIFICATION]\nNONE\n>>> [STATUS]Starting... \nSUCCESS\n>>> [RESULT]\nThe execution of the generated python code above has succeeded\n\nThe result of above Python code after execution is:\narray([0.09918602, 0.68732778, 0.44413814, 0.4756623 , 0.48302334,\n 0.8286594 , 0.80994359, 0.35677263, 0.45719317, 0.68240194])\n>>> [CODEINTERPRETER->PLANNER]\nThe following python code has been executed:\n```python\nimport numpy as np\nrandom_numbers = np.random.rand(10)\nrandom_numbers\n```\n\nThe execution of the generated python code above has succeeded\n\nThe result of above Python code after execution is:\narray([0.09918602, 0.68732778, 0.44413814, 0.4756623 , 0.48302334,\n 0.8286594 , 0.80994359, 0.35677263, 0.45719317, 0.68240194])\nTaskWeaver: The following python code has been executed:\n```python\nimport numpy as np\nrandom_numbers = np.random.rand(10)\nrandom_numbers\n```\n\nThe execution of the generated python code above has succeeded\n\nThe result of above Python code after execution is:\narray([0.09918602, 0.68732778, 0.44413814, 0.4756623 , 0.48302334,\n 0.8286594 , 0.80994359, 0.35677263, 0.45719317, 0.68240194])\n"})}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"embedding-configuration",children:"Embedding Configuration"}),"\n",(0,r.jsx)(n.p,{children:"In TaskWeaver, we support various embedding models to generate embeddings for auto plugin selection."}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"llm.embedding_api_type"}),": The type of the embedding API. We support the following types:"]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"openai"}),"\n",(0,r.jsx)(n.li,{children:"qwen"}),"\n",(0,r.jsx)(n.li,{children:"ollama"}),"\n",(0,r.jsx)(n.li,{children:"sentence_transformers"}),"\n",(0,r.jsx)(n.li,{children:"glm"}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"llm.embedding_model"}),": The embedding model name. The model name should be aligned with ",(0,r.jsx)(n.code,{children:"llm.embedding_api_type"}),".\nWe only list some embedding models we have tested below:"]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["openai","\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"text-embedding-ada-002"}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["qwen","\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"text-embedding-v1"}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["ollama","\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"llama2"}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["sentence_transformers","\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"all-mpnet-base-v2"}),"\n",(0,r.jsx)(n.li,{children:"multi-qa-mpnet-base-dot-v1"}),"\n",(0,r.jsx)(n.li,{children:"all-distilroberta-v1"}),"\n",(0,r.jsx)(n.li,{children:"all-MiniLM-L12-v2"}),"\n",(0,r.jsx)(n.li,{children:"multi-qa-MiniLM-L6-cos-v1"}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["zhipuai","\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"embedding-2\nYou also can use other embedding models supported by the above embedding APIs."}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,o.a)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(c,{...e})}):c(e)}},1151:(e,n,i)=>{i.d(n,{Z:()=>l,a:()=>t});var r=i(7294);const o={},s=r.createContext(o);function t(e){const n=r.useContext(s);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:t(e.components),r.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5a1935a3.89098987.js b/assets/js/5a1935a3.89098987.js deleted file mode 100644 index 28da609f..00000000 --- a/assets/js/5a1935a3.89098987.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[6486],{5897:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>l,contentTitle:()=>t,default:()=>h,frontMatter:()=>o,metadata:()=>a,toc:()=>d});var s=r(5893),i=r(1151);const o={},t="More about Configurations",a={id:"configurations/configurations_in_detail",title:"More about Configurations",description:"More details about some important configurations",source:"@site/docs/configurations/configurations_in_detail.md",sourceDirName:"configurations",slug:"/configurations/configurations_in_detail",permalink:"/TaskWeaver/docs/configurations/configurations_in_detail",draft:!1,unlisted:!1,editUrl:"https://github.com/microsoft/TaskWeaver/tree/main/website/docs/configurations/configurations_in_detail.md",tags:[],version:"current",frontMatter:{},sidebar:"documentSidebar",previous:{title:"Configuration File",permalink:"/TaskWeaver/docs/configurations/overview"},next:{title:"Customization",permalink:"/TaskWeaver/docs/customization"}},l={},d=[{value:"Planner Configuration",id:"planner-configuration",level:2},{value:"Session Configuration",id:"session-configuration",level:2},{value:"Embedding Configuration",id:"embedding-configuration",level:2}];function c(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",li:"li",p:"p",pre:"pre",ul:"ul",...(0,i.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"more-about-configurations",children:"More about Configurations"}),"\n",(0,s.jsx)(n.p,{children:"More details about some important configurations"}),"\n",(0,s.jsx)(n.h2,{id:"planner-configuration",children:"Planner Configuration"}),"\n",(0,s.jsx)(n.p,{children:"In TaskWeaver, the Planner is responsible for generating a plan to accomplish the user's task. The plan is a sequence of steps, where each step will be executed by the Code Interpreter.\nTaken the response from the Code Interpreter or new requests from the user as input, the Planner will update the plan and move on to the next step."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"planner.example_base_path"}),":\tThe folder to store planner examples. The default value is ",(0,s.jsx)(n.code,{children:"${AppBaseDir}/planner_examples"}),".\nIf you want to create your own planner examples, you can add them to this folder. More details about ",(0,s.jsx)(n.code,{children:"example"})," can referred to ",(0,s.jsx)(n.a,{href:"/TaskWeaver/docs/customization/example/",children:"example"}),"."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"planner.prompt_compression"}),": At times, lengthy conversations with the Planner may exceed the input limitations of the LLM model.\nTo address this issue, we can compress the chat history and send it to the LLM model. The default value for this setting is ",(0,s.jsx)(n.code,{children:"false"}),".\nMore details about ",(0,s.jsx)(n.code,{children:"prompt_compression"})," can be referred to ",(0,s.jsx)(n.a,{href:"../advanced/compression",children:"prompt_compression"}),"."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"planner.use_experience"}),": Whether to use experience summarized from the previous chat history in planner. The default value is ",(0,s.jsx)(n.code,{children:"false"}),"."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"session-configuration",children:"Session Configuration"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"session"})," is the entrance of TaskWeaver.\nIt is responsible for the communication between the user and TaskWeaver.\nYou can refer to ",(0,s.jsx)(n.a,{href:"/TaskWeaver/docs/usage/library",children:"taskweaver_as_a_lib"})," to see how to setup a TaskWeaver session and start chatting with TaskWeaver."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"max_internal_chat_round_num"}),": the maximum number of internal chat rounds between Planner and Code Interpreter.\nIf the number of internal chat rounds exceeds this number, the session will be terminated.\nThe default value is ",(0,s.jsx)(n.code,{children:"10"}),"."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"roles"}),": the roles included for the conversation. The default value is ",(0,s.jsx)(n.code,{children:'["planner", "code_interpreter"]'}),".\nRoles can be divided into two parts: planner roles and worker roles. In TaskWeaver, the Planner is fixed.","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Planner roles are responsible for generating a plan to accomplish the user's task, while worker roles are responsible for executing the plan generated by the Planner."}),"\n",(0,s.jsxs)(n.li,{children:["TaskWeaver supports 3 worker roles: ",(0,s.jsx)(n.code,{children:"code_interpreter"}),", ",(0,s.jsx)(n.code,{children:"code_interpreter_cli_only"}),", and ",(0,s.jsx)(n.code,{children:"code_interpreter_plugin_only"}),".","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"code_interpreter"}),": it will generate Python code to fulfill the user's request."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"code_interpreter_plugin_only"}),": please refer to ",(0,s.jsx)(n.a,{href:"/TaskWeaver/docs/plugin/plugin_only",children:"plugin_only_mode"})," for more details."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"code_interpreter_cli_only"}),": allow users to directly communicate with the Command Line Interface (CLI) in natural language. CodeInterpreter will generate CLI commands (e.g., bash/powershell), instead of Python code, to fulfill the user's request."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["If you do not specify ",(0,s.jsx)(n.code,{children:"planner"})," in the roles, you will enter the ",(0,s.jsx)(n.code,{children:"no-planner"})," mode. It allows users to directly communicate with the worker role, such as ",(0,s.jsx)(n.code,{children:"code_interpreter"}),".\nIn this mode, users can only send messages to the ",(0,s.jsx)(n.code,{children:"CodeInterpreter"})," and receive messages from the ",(0,s.jsx)(n.code,{children:"CodeInterpreter"}),".\nNote that only single worker role is allowed in the ",(0,s.jsx)(n.code,{children:"no-planner"})," mode because all user requests will be sent to the worker role directly.\nHere is an example:"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:" =========================================================\n _____ _ _ __\n|_ _|_ _ ___| | _ | | / /__ ____ __ _____ _____\n | |/ _` / __| |/ /| | /| / / _ \\/ __ `/ | / / _ \\/ ___/\n | | (_| \\__ \\ < | |/ |/ / __/ /_/ /| |/ / __/ /\n |_|\\__,_|___/_|\\_\\|__/|__/\\___/\\__,_/ |___/\\___/_/\n=========================================================\nTaskWeaver: I am TaskWeaver, an AI assistant. To get started, could you please enter your request?\nHuman: generate 10 random numbers\n>>> [PYTHON]Starting... \nimport numpy as np\nrandom_numbers = np.random.rand(10)\nrandom_numbers\n>>> [VERIFICATION]\nNONE\n>>> [STATUS]Starting... \nSUCCESS\n>>> [RESULT]\nThe execution of the generated python code above has succeeded\n\nThe result of above Python code after execution is:\narray([0.09918602, 0.68732778, 0.44413814, 0.4756623 , 0.48302334,\n 0.8286594 , 0.80994359, 0.35677263, 0.45719317, 0.68240194])\n>>> [CODEINTERPRETER->PLANNER]\nThe following python code has been executed:\n```python\nimport numpy as np\nrandom_numbers = np.random.rand(10)\nrandom_numbers\n```\n\nThe execution of the generated python code above has succeeded\n\nThe result of above Python code after execution is:\narray([0.09918602, 0.68732778, 0.44413814, 0.4756623 , 0.48302334,\n 0.8286594 , 0.80994359, 0.35677263, 0.45719317, 0.68240194])\nTaskWeaver: The following python code has been executed:\n```python\nimport numpy as np\nrandom_numbers = np.random.rand(10)\nrandom_numbers\n```\n\nThe execution of the generated python code above has succeeded\n\nThe result of above Python code after execution is:\narray([0.09918602, 0.68732778, 0.44413814, 0.4756623 , 0.48302334,\n 0.8286594 , 0.80994359, 0.35677263, 0.45719317, 0.68240194])\n"})}),"\n",(0,s.jsx)(n.h2,{id:"embedding-configuration",children:"Embedding Configuration"}),"\n",(0,s.jsx)(n.p,{children:"In TaskWeaver, we support various embedding models to generate embeddings for auto plugin selection."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"llm.embedding_api_type"}),": The type of the embedding API. We support the following types:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"openai"}),"\n",(0,s.jsx)(n.li,{children:"qwen"}),"\n",(0,s.jsx)(n.li,{children:"ollama"}),"\n",(0,s.jsx)(n.li,{children:"sentence_transformers"}),"\n",(0,s.jsx)(n.li,{children:"glm"}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"llm.embedding_model"}),": The embedding model name. The model name should be aligned with ",(0,s.jsx)(n.code,{children:"llm.embedding_api_type"}),".\nWe only list some embedding models we have tested below:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["openai","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"text-embedding-ada-002"}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["qwen","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"text-embedding-v1"}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["ollama","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"llama2"}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["sentence_transformers","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"all-mpnet-base-v2"}),"\n",(0,s.jsx)(n.li,{children:"multi-qa-mpnet-base-dot-v1"}),"\n",(0,s.jsx)(n.li,{children:"all-distilroberta-v1"}),"\n",(0,s.jsx)(n.li,{children:"all-MiniLM-L12-v2"}),"\n",(0,s.jsx)(n.li,{children:"multi-qa-MiniLM-L6-cos-v1"}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["zhipuai","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"embedding-2\nYou also can use other embedding models supported by the above embedding APIs."}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,i.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},1151:(e,n,r)=>{r.d(n,{Z:()=>a,a:()=>t});var s=r(7294);const i={},o=s.createContext(i);function t(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:t(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5cde2c1f.5e67378d.js b/assets/js/5cde2c1f.5e67378d.js deleted file mode 100644 index 53e23229..00000000 --- a/assets/js/5cde2c1f.5e67378d.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[8693],{6360:(e,n,l)=>{l.r(n),l.d(n,{assets:()=>r,contentTitle:()=>s,default:()=>a,frontMatter:()=>t,metadata:()=>d,toc:()=>c});var o=l(5893),i=l(1151);const t={id:"plugin_only",description:"The Plugin Only Mode",slug:"/plugin/plugin_only"},s="The Plugin-Only Mode",d={id:"customization/plugin/plugin_only",title:"The Plugin-Only Mode",description:"The Plugin Only Mode",source:"@site/docs/customization/plugin/plugin_only.md",sourceDirName:"customization/plugin",slug:"/plugin/plugin_only",permalink:"/TaskWeaver/docs/plugin/plugin_only",draft:!1,unlisted:!1,editUrl:"https://github.com/microsoft/TaskWeaver/tree/main/website/docs/customization/plugin/plugin_only.md",tags:[],version:"current",frontMatter:{id:"plugin_only",description:"The Plugin Only Mode",slug:"/plugin/plugin_only"},sidebar:"documentSidebar",previous:{title:"Multiple YAML files to one Python implementation",permalink:"/TaskWeaver/docs/plugin/multi_yaml_single_impl"},next:{title:"Customizing Examples",permalink:"/TaskWeaver/docs/customization/example/"}},r={},c=[{value:"What is the plugin-only mode?",id:"what-is-the-plugin-only-mode",level:2},{value:"Why do we need the plugin-only mode?",id:"why-do-we-need-the-plugin-only-mode",level:2},{value:"How is the plugin-only mode implemented?",id:"how-is-the-plugin-only-mode-implemented",level:2},{value:"Which models support the plugin-only mode?",id:"which-models-support-the-plugin-only-mode",level:2}];function h(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,i.a)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h1,{id:"the-plugin-only-mode",children:"The Plugin-Only Mode"}),"\n",(0,o.jsx)(n.h2,{id:"what-is-the-plugin-only-mode",children:"What is the plugin-only mode?"}),"\n",(0,o.jsx)(n.p,{children:"The plugin-only mode is a restricted mode of TaskWeaver that only allows you to use plugins.\nCompared to the full mode, the plugin-only mode has the following restrictions:"}),"\n",(0,o.jsxs)(n.ol,{children:["\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:["The generated code only contains the calls to the plugins.\nFor example, the following code only calls the ",(0,o.jsx)(n.code,{children:"ascii_render"}),' plugin and does not contain any "free-form" code.']}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-python",children:'r1=ascii_render(text="Hello")\nr1\n'})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:["Only the plugins with ",(0,o.jsx)(n.code,{children:"plugin_only: true"})," in the yaml file will be loaded.\nFor example, the following plugin will be loaded in the plugin-only mode:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml",children:"name: ascii_render\ncode: ascii_render\nplugin_only: true\n...\n"})}),"\n",(0,o.jsxs)(n.p,{children:["If this field is not specified, the default value is ",(0,o.jsx)(n.code,{children:"false"}),".\nFor plugins in the plugin-only mode, the argument type can only be ",(0,o.jsx)(n.code,{children:"str"}),", ",(0,o.jsx)(n.code,{children:"int"}),", ",(0,o.jsx)(n.code,{children:"boolean"}),", or ",(0,o.jsx)(n.code,{children:"float"}),".\nOther types such as ",(0,o.jsx)(n.code,{children:"DataFrame"}),' are not allowed.\nEssentially, we consider these plugins only produce "text-like" output that can be directly consumed by the LLM.']}),"\n"]}),"\n"]}),"\n",(0,o.jsxs)(n.p,{children:["To enable the plugin-only mode, you can add the configuration ",(0,o.jsx)(n.code,{children:'"session.code_gen_mode": "plugin_only"'}),"\nin the project configuration file ",(0,o.jsx)(n.code,{children:"taskweaver_config.json"}),"."]}),"\n",(0,o.jsx)(n.h2,{id:"why-do-we-need-the-plugin-only-mode",children:"Why do we need the plugin-only mode?"}),"\n",(0,o.jsx)(n.p,{children:"Although the plugin-only mode is restricted, it is still useful in some scenarios.\nFor example, you may want to use TaskWeaver to only generate the code to call a certain plugin,\nand you want to get the response from the plugin directly, without generating any other code\nfor safety reasons."}),"\n",(0,o.jsx)(n.h2,{id:"how-is-the-plugin-only-mode-implemented",children:"How is the plugin-only mode implemented?"}),"\n",(0,o.jsxs)(n.p,{children:["The plugin-only mode is implemented based on the ",(0,o.jsx)(n.a,{href:"https://platform.openai.com/docs/guides/function-calling",children:"function calling"})," mode of LLMs.\nIn this mode, the LLM is trained to generate a JSON object that contains the function name and the arguments.\nFor example, the following JSON object is generated by the LLM:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-json",children:'{\n "function": "ascii_render",\n "arguments": {\n "text": "Hello"\n }\n}\n'})}),"\n",(0,o.jsx)(n.p,{children:"With this JSON object, we assemble the code to call the plugin:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-python",children:'r1=ascii_render(text="Hello")\nr1\n'})}),"\n",(0,o.jsx)(n.p,{children:"Then, we execute the code and get the response from the plugin.\nTherefore, the code is not directly generated by the LLM in the plugin-only mode."}),"\n",(0,o.jsx)(n.h2,{id:"which-models-support-the-plugin-only-mode",children:"Which models support the plugin-only mode?"}),"\n",(0,o.jsx)(n.p,{children:"Currently, the plugin-only mode is only supported by"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:(0,o.jsx)(n.a,{href:"https://platform.openai.com/docs/guides/function-calling",children:"OpenAI models"})}),"\n",(0,o.jsx)(n.li,{children:(0,o.jsx)(n.a,{href:"https://open.bigmodel.cn/dev/api",children:"ZhipuAI models"})}),"\n"]}),"\n",(0,o.jsx)(n.p,{children:"Likely other models that are compatible with the OpenAI models will also support the plugin-only mode."})]})}function a(e={}){const{wrapper:n}={...(0,i.a)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(h,{...e})}):h(e)}},1151:(e,n,l)=>{l.d(n,{Z:()=>d,a:()=>s});var o=l(7294);const i={},t=o.createContext(i);function s(e){const n=o.useContext(t);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:s(e.components),o.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/72cb6e7f.0db656a1.js b/assets/js/72cb6e7f.0db656a1.js deleted file mode 100644 index b3febfcc..00000000 --- a/assets/js/72cb6e7f.0db656a1.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2442],{4329:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>c,contentTitle:()=>t,default:()=>u,frontMatter:()=>s,metadata:()=>i,toc:()=>l});var r=o(5893),a=o(1151);const s={},t="All-in-One Docker Image",i={id:"usage/docker",title:"All-in-One Docker Image",description:"In this document, we will show you how to run TaskWeaver using the All-in-One Docker Image.",source:"@site/docs/usage/docker.md",sourceDirName:"usage",slug:"/usage/docker",permalink:"/TaskWeaver/docs/usage/docker",draft:!1,unlisted:!1,editUrl:"https://github.com/microsoft/TaskWeaver/tree/main/website/docs/usage/docker.md",tags:[],version:"current",frontMatter:{},sidebar:"documentSidebar",previous:{title:"Library",permalink:"/TaskWeaver/docs/usage/library"},next:{title:"Supported LLMs",permalink:"/TaskWeaver/docs/llms"}},c={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Run TaskWeaver using the All-in-One Docker Image",id:"run-taskweaver-using-the-all-in-one-docker-image",level:2},{value:"How to run TaskWeaver on your own project directory",id:"how-to-run-taskweaver-on-your-own-project-directory",level:2},{value:"How to access your local files in the container",id:"how-to-access-your-local-files-in-the-container",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",li:"li",p:"p",pre:"pre",ul:"ul",...(0,a.a)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h1,{id:"all-in-one-docker-image",children:"All-in-One Docker Image"}),"\n",(0,r.jsx)(n.p,{children:"In this document, we will show you how to run TaskWeaver using the All-in-One Docker Image.\nPlease note that the All-in-One Docker Image is for development and testing purposes only.\ng"}),"\n",(0,r.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,r.jsx)(n.p,{children:"You need to have Docker installed on your machine."}),"\n",(0,r.jsxs)(n.p,{children:["For Windows and macOS users, you can use Docker Desktop. You can download it from ",(0,r.jsx)(n.a,{href:"https://www.docker.com/products/docker-desktop",children:"Docker's official website"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["For Linux users, you can install following the instructions in the ",(0,r.jsx)(n.a,{href:"https://docs.docker.com/engine/install/",children:"Docker's official website"}),".\nPlease find the installation guide for your specific Linux distribution."]}),"\n",(0,r.jsx)(n.h2,{id:"run-taskweaver-using-the-all-in-one-docker-image",children:"Run TaskWeaver using the All-in-One Docker Image"}),"\n",(0,r.jsx)(n.p,{children:"There are two versions of the TaskWeaver All-in-One Docker Image:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"taskweavercontainers/taskweaver-all-in-one:latest"}),": This version includes the Planner and CodeInterpreter roles only.\nYou can use this container for code generation and execution tasks."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"taskweavercontainers/taskweaver-all-in-one:latest-ws"}),": This version includes an additional WebSearch role which can search the web for information.\nAs it requires dependencies to the ",(0,r.jsx)(n.code,{children:"sentence-transformers"})," library, it is larger."]}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"Open a terminal and run the following command to obtain the TaskWeaver image:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"docker pull taskweavercontainers/taskweaver-all-in-one:latest\n# if you want to use the version with the WebSearch role \n# docker pull taskweavercontainers/taskweaver-all-in-one:latest-ws\n"})}),"\n",(0,r.jsx)(n.p,{children:"Once the image is pulled, you can run the TaskWeaver container using the following command:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"docker run -it -e LLM_API_BASE= \\\n -e LLM_API_KEY= \\\n -e LLM_API_TYPE= \\\n -e LLM_MODEL= \\\n taskweavercontainers/taskweaver-all-in-one:latest\n"})}),"\n",(0,r.jsx)(n.p,{children:"If you want to run TaskWeaver in UI mode, you can use the following command:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:'docker run -it -e LLM_API_BASE= \\\n -e LLM_API_KEY= \\\n -e LLM_API_TYPE= \\\n -e LLM_MODEL= \\\n -p 8000:8000 \\\n taskweavercontainers/taskweaver-all-in-one:latest /bin/sh -c "cd playground/UI/ && python -m chainlit run --host 0.0.0.0 --port 8000 app.py"\n'})}),"\n",(0,r.jsxs)(n.p,{children:["Then you can access the TaskWeaver Web UI by visiting ",(0,r.jsx)(n.a,{href:"http://localhost:8000",children:"http://localhost:8000"})," in your web browser."]}),"\n",(0,r.jsx)(n.h2,{id:"how-to-run-taskweaver-on-your-own-project-directory",children:"How to run TaskWeaver on your own project directory"}),"\n",(0,r.jsxs)(n.p,{children:["You can mount your local ",(0,r.jsx)(n.code,{children:"project"})," directory to the container. For example, you can use the following command:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"docker run -it -e LLM_API_BASE= \\\n -e LLM_API_KEY= \\\n -e LLM_API_TYPE= \\\n -e LLM_MODEL= \\\n --mount type=bind,source=,target=/app/TaskWeaver/project/ \\\n taskweavercontainers/taskweaver-all-in-one:latest\n"})}),"\n",(0,r.jsxs)(n.p,{children:["Then you can edit the ",(0,r.jsx)(n.code,{children:"taskweaver_config.json"})," file in your local ",(0,r.jsx)(n.code,{children:"project"})," directory to configure TaskWeaver.\nIn addition, you also can customize the plugins and examples in your local ",(0,r.jsx)(n.code,{children:"project"})," directory.\nThe structure of the ",(0,r.jsx)(n.code,{children:"project"})," directory can be referred to the ",(0,r.jsx)(n.code,{children:"taskweaver/project"})," directory."]}),"\n",(0,r.jsx)(n.h2,{id:"how-to-access-your-local-files-in-the-container",children:"How to access your local files in the container"}),"\n",(0,r.jsx)(n.p,{children:"You can mount your local directory to the container. For example, you can use the following command:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"docker run -it -e LLM_API_BASE= \\\n -e LLM_API_KEY= \\\n -e LLM_API_TYPE= \\\n -e LLM_MODEL= \\\n --mount type=bind,source=,target=/app/TaskWeaver/local/ \\\n taskweavercontainers/taskweaver-all-in-one:latest\n"})}),"\n",(0,r.jsxs)(n.p,{children:["Then you can access your local files in the container by visiting the ",(0,r.jsx)(n.code,{children:"/app/TaskWeaver/local/"})," directory.\nYou can load a file under the ",(0,r.jsx)(n.code,{children:"/app/TaskWeaver/local/"})," directory in the TaskWeaver CLI\nwith the ",(0,r.jsx)(n.code,{children:"/load"})," command. For example, you can load a file named ",(0,r.jsx)(n.code,{children:"example.csv"})," by running the following command:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:" TaskWeaver \u25b6 I am TaskWeaver, an AI assistant. To get started, could you please enter your request?\n Human \u25b6 /load /app/TaskWeaver/local/example.csv\n Human \u25b6 display the column names of the loaded file\n"})})]})}function u(e={}){const{wrapper:n}={...(0,a.a)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},1151:(e,n,o)=>{o.d(n,{Z:()=>i,a:()=>t});var r=o(7294);const a={},s=r.createContext(a);function t(e){const n=r.useContext(s);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:t(e.components),r.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/72cb6e7f.ff56ffd1.js b/assets/js/72cb6e7f.ff56ffd1.js new file mode 100644 index 00000000..cb5ce347 --- /dev/null +++ b/assets/js/72cb6e7f.ff56ffd1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2442],{4329:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>c,contentTitle:()=>t,default:()=>u,frontMatter:()=>s,metadata:()=>i,toc:()=>l});var r=o(5893),a=o(1151);const s={},t="All-in-One Docker Image",i={id:"usage/docker",title:"All-in-One Docker Image",description:"In this document, we will show you how to run TaskWeaver using the All-in-One Docker Image.",source:"@site/docs/usage/docker.md",sourceDirName:"usage",slug:"/usage/docker",permalink:"/TaskWeaver/docs/usage/docker",draft:!1,unlisted:!1,editUrl:"https://github.com/microsoft/TaskWeaver/tree/main/website/docs/usage/docker.md",tags:[],version:"current",frontMatter:{},sidebar:"documentSidebar",previous:{title:"Library",permalink:"/TaskWeaver/docs/usage/library"},next:{title:"Supported LLMs",permalink:"/TaskWeaver/docs/llms"}},c={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Run TaskWeaver using the All-in-One Docker Image",id:"run-taskweaver-using-the-all-in-one-docker-image",level:2},{value:"How to run TaskWeaver on your own project directory",id:"how-to-run-taskweaver-on-your-own-project-directory",level:2},{value:"How to access your local files in the container",id:"how-to-access-your-local-files-in-the-container",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",li:"li",p:"p",pre:"pre",ul:"ul",...(0,a.a)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h1,{id:"all-in-one-docker-image",children:"All-in-One Docker Image"}),"\n",(0,r.jsx)(n.p,{children:"In this document, we will show you how to run TaskWeaver using the All-in-One Docker Image.\nPlease note that the All-in-One Docker Image is for development and testing purposes only."}),"\n",(0,r.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,r.jsx)(n.p,{children:"You need to have Docker installed on your machine."}),"\n",(0,r.jsxs)(n.p,{children:["For Windows and macOS users, you can use Docker Desktop. You can download it from ",(0,r.jsx)(n.a,{href:"https://www.docker.com/products/docker-desktop",children:"Docker's official website"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["For Linux users, you can install following the instructions in the ",(0,r.jsx)(n.a,{href:"https://docs.docker.com/engine/install/",children:"Docker's official website"}),".\nPlease find the installation guide for your specific Linux distribution."]}),"\n",(0,r.jsx)(n.h2,{id:"run-taskweaver-using-the-all-in-one-docker-image",children:"Run TaskWeaver using the All-in-One Docker Image"}),"\n",(0,r.jsx)(n.p,{children:"There are two versions of the TaskWeaver All-in-One Docker Image:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"taskweavercontainers/taskweaver-all-in-one:latest"}),": This version includes the Planner and CodeInterpreter roles only.\nYou can use this container for code generation and execution tasks."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"taskweavercontainers/taskweaver-all-in-one:latest-ws"}),": This version includes an additional WebSearch role which can search the web for information.\nAs it requires dependencies to the ",(0,r.jsx)(n.code,{children:"sentence-transformers"})," library, it is larger."]}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"Open a terminal and run the following command to obtain the TaskWeaver image:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"docker pull taskweavercontainers/taskweaver-all-in-one:latest\n# if you want to use the version with the WebSearch role \n# docker pull taskweavercontainers/taskweaver-all-in-one:latest-ws\n"})}),"\n",(0,r.jsx)(n.p,{children:"Once the image is pulled, you can run the TaskWeaver container using the following command:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"docker run -it -e LLM_API_BASE= \\\n -e LLM_API_KEY= \\\n -e LLM_API_TYPE= \\\n -e LLM_MODEL= \\\n taskweavercontainers/taskweaver-all-in-one:latest\n"})}),"\n",(0,r.jsx)(n.p,{children:"If you want to run TaskWeaver in UI mode, you can use the following command:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:'docker run -it -e LLM_API_BASE= \\\n -e LLM_API_KEY= \\\n -e LLM_API_TYPE= \\\n -e LLM_MODEL= \\\n -p 8000:8000 \\\n taskweavercontainers/taskweaver-all-in-one:latest /bin/sh -c "cd playground/UI/ && python -m chainlit run --host 0.0.0.0 --port 8000 app.py"\n'})}),"\n",(0,r.jsxs)(n.p,{children:["Then you can access the TaskWeaver Web UI by visiting ",(0,r.jsx)(n.a,{href:"http://localhost:8000",children:"http://localhost:8000"})," in your web browser."]}),"\n",(0,r.jsx)(n.h2,{id:"how-to-run-taskweaver-on-your-own-project-directory",children:"How to run TaskWeaver on your own project directory"}),"\n",(0,r.jsxs)(n.p,{children:["You can mount your local ",(0,r.jsx)(n.code,{children:"project"})," directory to the container. For example, you can use the following command:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"docker run -it -e LLM_API_BASE= \\\n -e LLM_API_KEY= \\\n -e LLM_API_TYPE= \\\n -e LLM_MODEL= \\\n --mount type=bind,source=,target=/app/TaskWeaver/project/ \\\n taskweavercontainers/taskweaver-all-in-one:latest\n"})}),"\n",(0,r.jsxs)(n.p,{children:["Then you can edit the ",(0,r.jsx)(n.code,{children:"taskweaver_config.json"})," file in your local ",(0,r.jsx)(n.code,{children:"project"})," directory to configure TaskWeaver.\nIn addition, you also can customize the plugins and examples in your local ",(0,r.jsx)(n.code,{children:"project"})," directory.\nThe structure of the ",(0,r.jsx)(n.code,{children:"project"})," directory can be referred to the ",(0,r.jsx)(n.code,{children:"taskweaver/project"})," directory."]}),"\n",(0,r.jsx)(n.h2,{id:"how-to-access-your-local-files-in-the-container",children:"How to access your local files in the container"}),"\n",(0,r.jsx)(n.p,{children:"You can mount your local directory to the container. For example, you can use the following command:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"docker run -it -e LLM_API_BASE= \\\n -e LLM_API_KEY= \\\n -e LLM_API_TYPE= \\\n -e LLM_MODEL= \\\n --mount type=bind,source=,target=/app/TaskWeaver/local/ \\\n taskweavercontainers/taskweaver-all-in-one:latest\n"})}),"\n",(0,r.jsxs)(n.p,{children:["Then you can access your local files in the container by visiting the ",(0,r.jsx)(n.code,{children:"/app/TaskWeaver/local/"})," directory.\nYou can load a file under the ",(0,r.jsx)(n.code,{children:"/app/TaskWeaver/local/"})," directory in the TaskWeaver CLI\nwith the ",(0,r.jsx)(n.code,{children:"/load"})," command. For example, you can load a file named ",(0,r.jsx)(n.code,{children:"example.csv"})," by running the following command:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:" TaskWeaver \u25b6 I am TaskWeaver, an AI assistant. To get started, could you please enter your request?\n Human \u25b6 /load /app/TaskWeaver/local/example.csv\n Human \u25b6 display the column names of the loaded file\n"})})]})}function u(e={}){const{wrapper:n}={...(0,a.a)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},1151:(e,n,o)=>{o.d(n,{Z:()=>i,a:()=>t});var r=o(7294);const a={},s=r.createContext(a);function t(e){const n=r.useContext(s);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:t(e.components),r.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/8070e160.4800f253.js b/assets/js/8070e160.4800f253.js new file mode 100644 index 00000000..ffa811b7 --- /dev/null +++ b/assets/js/8070e160.4800f253.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2651],{9759:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>s,default:()=>h,frontMatter:()=>o,metadata:()=>i,toc:()=>l});var r=t(5893),a=t(1151);const o={},s="Quick Start",i={id:"quickstart",title:"Quick Start",description:"Installation",source:"@site/docs/quickstart.md",sourceDirName:".",slug:"/quickstart",permalink:"/TaskWeaver/docs/quickstart",draft:!1,unlisted:!1,editUrl:"https://github.com/microsoft/TaskWeaver/tree/main/website/docs/quickstart.md",tags:[],version:"current",frontMatter:{},sidebar:"documentSidebar",previous:{title:"Overview",permalink:"/TaskWeaver/docs/overview"},next:{title:"Code Execution",permalink:"/TaskWeaver/docs/code_execution"}},c={},l=[{value:"Installation",id:"installation",level:2},{value:"Project Directory",id:"project-directory",level:2},{value:"OpenAI Configuration",id:"openai-configuration",level:2},{value:"Azure OpenAI",id:"azure-openai",level:3},{value:"OpenAI",id:"openai",level:3},{value:"Start TaskWeaver",id:"start-taskweaver",level:2}];function d(e){const n={a:"a",blockquote:"blockquote",code:"code",h1:"h1",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",ul:"ul",...(0,a.a)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h1,{id:"quick-start",children:"Quick Start"}),"\n",(0,r.jsx)(n.h2,{id:"installation",children:"Installation"}),"\n",(0,r.jsx)(n.p,{children:"You can install TaskWeaver by running the following command:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"# [optional] create a conda environment to isolate the dependencies\n# conda create -n taskweaver python=3.10\n# conda activate taskweaver\n\n# clone the repository\ngit clone https://github.com/microsoft/TaskWeaver.git\ncd TaskWeaver\n# install the requirements\npip install -r requirements.txt\n"})}),"\n",(0,r.jsx)(n.h2,{id:"project-directory",children:"Project Directory"}),"\n",(0,r.jsxs)(n.p,{children:["TaskWeaver runs as a process, you need to create a project directory to store plugins and configuration files.\nWe provided a sample project directory in the ",(0,r.jsx)(n.code,{children:"project"})," folder. You can copy the ",(0,r.jsx)(n.code,{children:"project"})," folder to your workspace.\nA project directory typically contains the following files and folders:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"\ud83d\udce6project\n \u2523 \ud83d\udcdctaskweaver_config.json # the project configuration file for TaskWeaver\n \u2523 \ud83d\udcc2plugins # the folder to store plugins\n \u2523 \ud83d\udcc2planner_examples # the folder to store planner examples\n \u2523 \ud83d\udcc2codeinterpreter_examples # the folder to store code interpreter examples\n \u2523 \ud83d\udcc2logs # the folder to store logs, will be generated after program starts\n \u2517 \ud83d\udcc2workspace # the directory stores session data\uff0c will be generated after program starts\n \u2517 \ud83d\udcc2 session_id \n \u2523 \ud83d\udcc2ces # the folder used by the code execution service\n \u2523 \ud83d\udcc2cwd # the current working directory to run the generated code\n \u2517 other session data\n"})}),"\n",(0,r.jsx)(n.h2,{id:"openai-configuration",children:"OpenAI Configuration"}),"\n",(0,r.jsxs)(n.p,{children:["Before running TaskWeaver, you need to provide your OpenAI API key and other necessary information.\nYou can do this by editing the ",(0,r.jsx)(n.code,{children:"taskweaver_config.json"})," file.\nIf you are using Azure OpenAI, you need to set the following parameters in the ",(0,r.jsx)(n.code,{children:"taskweaver_config.json"})," file:"]}),"\n",(0,r.jsx)(n.h3,{id:"azure-openai",children:"Azure OpenAI"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-json",children:'{\n"llm.api_base": "https://xxx.openai.azure.com/",\n"llm.api_key": "your_api_key",\n"llm.api_type": "azure",\n"llm.api_version": "the api version",\n"llm.model": "the model name, e.g., gpt-4" # In Azure OpenAI, the model name is the deployment_name\n}\n'})}),"\n",(0,r.jsx)(n.h3,{id:"openai",children:"OpenAI"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-json",children:'{\n"llm.api_key": "the api key",\n"llm.model": "the model name, e.g., gpt-4"\n}\n'})}),"\n",(0,r.jsxs)(n.blockquote,{children:["\n",(0,r.jsxs)(n.p,{children:["\ud83d\udca1 Only the latest OpenAI API supports the ",(0,r.jsx)(n.code,{children:"json_object"})," response format.\nIf you are using an older version of OpenAI API, you need to set the ",(0,r.jsx)(n.code,{children:'"llm.response_format"'}),"=",(0,r.jsx)(n.code,{children:"null"})," in the ",(0,r.jsx)(n.code,{children:"taskweaver_config.json"})," file."]}),"\n"]}),"\n",(0,r.jsxs)(n.p,{children:["More configuration options can be found in the ",(0,r.jsx)(n.a,{href:"./configurations/overview",children:"configuration documentation"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"start-taskweaver",children:"Start TaskWeaver"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"# assume you are in the TaskWeaver folder cloned from the repository\npython -m taskweaver -p ./project/ # -p is the path to the project directory\n"})}),"\n",(0,r.jsx)(n.p,{children:"This will start the TaskWeaver process and you can interact with it through the command line (CLI) interface.\nIf everything goes well, you will see the following prompt:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"=========================================================\n _____ _ _ __\n|_ _|_ _ ___| | _ | | / /__ ____ __ _____ _____\n | |/ _` / __| |/ /| | /| / / _ \\/ __ `/ | / / _ \\/ ___/\n | | (_| \\__ \\ < | |/ |/ / __/ /_/ /| |/ / __/ /\n |_|\\__,_|___/_|\\_\\|__/|__/\\___/\\__,_/ |___/\\___/_/\n=========================================================\nTaskWeaver: I am TaskWeaver, an AI assistant. To get started, could you please enter your request?\nHuman: ___\n"})}),"\n",(0,r.jsx)(n.p,{children:"There are other ways to start TaskWeaver:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.a,{href:"/TaskWeaver/docs/usage/webui",children:"A Chainlit UI interface"}),": TaskWeaver provides an experimental web-based interface to interact with the system."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.a,{href:"/TaskWeaver/docs/usage/library",children:"A Library"}),": You can also use TaskWeaver as a library in your Python code."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.a,{href:"/TaskWeaver/docs/usage/docker",children:"The all-in-one Docker image"}),": We provide a Docker image that contains all the dependencies to run TaskWeaver."]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,a.a)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},1151:(e,n,t)=>{t.d(n,{Z:()=>i,a:()=>s});var r=t(7294);const a={},o=r.createContext(a);function s(e){const n=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:s(e.components),r.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/8070e160.844b05a5.js b/assets/js/8070e160.844b05a5.js deleted file mode 100644 index 13dcebf2..00000000 --- a/assets/js/8070e160.844b05a5.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2651],{9759:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>s,default:()=>p,frontMatter:()=>a,metadata:()=>i,toc:()=>c});var r=t(5893),o=t(1151);const a={},s="Quick Start",i={id:"quickstart",title:"Quick Start",description:"Installation",source:"@site/docs/quickstart.md",sourceDirName:".",slug:"/quickstart",permalink:"/TaskWeaver/docs/quickstart",draft:!1,unlisted:!1,editUrl:"https://github.com/microsoft/TaskWeaver/tree/main/website/docs/quickstart.md",tags:[],version:"current",frontMatter:{},sidebar:"documentSidebar",previous:{title:"Overview",permalink:"/TaskWeaver/docs/overview"},next:{title:"Usage Options",permalink:"/TaskWeaver/docs/usage"}},l={},c=[{value:"Installation",id:"installation",level:2},{value:"Project Directory",id:"project-directory",level:2},{value:"OpenAI Configuration",id:"openai-configuration",level:2},{value:"Azure OpenAI",id:"azure-openai",level:3},{value:"OpenAI",id:"openai",level:3},{value:"Start TaskWeaver",id:"start-taskweaver",level:2}];function d(e){const n={a:"a",blockquote:"blockquote",code:"code",h1:"h1",h2:"h2",h3:"h3",p:"p",pre:"pre",...(0,o.a)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h1,{id:"quick-start",children:"Quick Start"}),"\n",(0,r.jsx)(n.h2,{id:"installation",children:"Installation"}),"\n",(0,r.jsx)(n.p,{children:"You can install TaskWeaver by running the following command:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"# [optional] create a conda environment to isolate the dependencies\n# conda create -n taskweaver python=3.10\n# conda activate taskweaver\n\n# clone the repository\ngit clone https://github.com/microsoft/TaskWeaver.git\ncd TaskWeaver\n# install the requirements\npip install -r requirements.txt\n"})}),"\n",(0,r.jsx)(n.h2,{id:"project-directory",children:"Project Directory"}),"\n",(0,r.jsxs)(n.p,{children:["TaskWeaver runs as a process, you need to create a project directory to store plugins and configuration files.\nWe provided a sample project directory in the ",(0,r.jsx)(n.code,{children:"project"})," folder. You can copy the ",(0,r.jsx)(n.code,{children:"project"})," folder to your workspace.\nA project directory typically contains the following files and folders:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"\ud83d\udce6project\n \u2523 \ud83d\udcdctaskweaver_config.json # the configuration file for TaskWeaver\n \u2523 \ud83d\udcc2plugins # the folder to store plugins\n \u2523 \ud83d\udcc2planner_examples # the folder to store planner examples\n \u2523 \ud83d\udcc2codeinterpreter_examples # the folder to store code interpreter examples\n \u2523 \ud83d\udcc2sample_data # the folder to store sample data used for evaluations\n \u2523 \ud83d\udcc2logs # the folder to store logs, will be generated after program starts\n \u2517 \ud83d\udcc2workspace # the directory stores session data\uff0c will be generated after program starts\n \u2517 \ud83d\udcc2 session_id \n \u2523 \ud83d\udcc2ces # the folder used by the code execution service\n \u2517 \ud83d\udcc2cwd # the current working directory to run the generated code\n"})}),"\n",(0,r.jsx)(n.h2,{id:"openai-configuration",children:"OpenAI Configuration"}),"\n",(0,r.jsxs)(n.p,{children:["Before running TaskWeaver, you need to provide your OpenAI API key and other necessary information.\nYou can do this by editing the ",(0,r.jsx)(n.code,{children:"taskweaver_config.json"})," file.\nIf you are using Azure OpenAI, you need to set the following parameters in the ",(0,r.jsx)(n.code,{children:"taskweaver_config.json"})," file:"]}),"\n",(0,r.jsx)(n.h3,{id:"azure-openai",children:"Azure OpenAI"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-json",children:'{\n"llm.api_base": "https://xxx.openai.azure.com/",\n"llm.api_key": "your_api_key",\n"llm.api_type": "azure",\n"llm.api_version": "the api version",\n"llm.model": "the model name, e.g., gpt-4"\n}\n'})}),"\n",(0,r.jsx)(n.h3,{id:"openai",children:"OpenAI"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-json",children:'{\n"llm.api_key": "the api key",\n"llm.model": "the model name, e.g., gpt-4"\n}\n'})}),"\n",(0,r.jsxs)(n.blockquote,{children:["\n",(0,r.jsxs)(n.p,{children:["\ud83d\udca1 Only the latest OpenAI API supports the ",(0,r.jsx)(n.code,{children:"json_object"})," response format.\nIf you are using an older version of OpenAI API, you need to set the ",(0,r.jsx)(n.code,{children:"llm.response_format"})," to ",(0,r.jsx)(n.code,{children:"null"}),"."]}),"\n"]}),"\n",(0,r.jsxs)(n.p,{children:["More configuration options can be found in the ",(0,r.jsx)(n.a,{href:"./configurations/overview",children:"configuration documentation"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"start-taskweaver",children:"Start TaskWeaver"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"# assume you are in the taskweaver folder\n# -p is the path to the project directory\npython -m taskweaver -p ./project/\n"})}),"\n",(0,r.jsx)(n.p,{children:"This will start the TaskWeaver process and you can interact with it through the command line interface.\nIf everything goes well, you will see the following prompt:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"=========================================================\n _____ _ _ __\n|_ _|_ _ ___| | _ | | / /__ ____ __ _____ _____\n | |/ _` / __| |/ /| | /| / / _ \\/ __ `/ | / / _ \\/ ___/\n | | (_| \\__ \\ < | |/ |/ / __/ /_/ /| |/ / __/ /\n |_|\\__,_|___/_|\\_\\|__/|__/\\___/\\__,_/ |___/\\___/_/\n=========================================================\nTaskWeaver: I am TaskWeaver, an AI assistant. To get started, could you please enter your request?\nHuman: ___\n"})})]})}function p(e={}){const{wrapper:n}={...(0,o.a)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},1151:(e,n,t)=>{t.d(n,{Z:()=>i,a:()=>s});var r=t(7294);const o={},a=r.createContext(o);function s(e){const n=r.useContext(a);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),r.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/834e34cc.2e581c3f.js b/assets/js/834e34cc.2e581c3f.js deleted file mode 100644 index 8c50b0e2..00000000 --- a/assets/js/834e34cc.2e581c3f.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[4471],{1550:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>t,contentTitle:()=>i,default:()=>a,frontMatter:()=>o,metadata:()=>c,toc:()=>l});var d=r(5893),s=r(1151);const o={},i="Configuration File",c={id:"configurations/overview",title:"Configuration File",description:"An overview of all configurations available in the config file, which is located at project/taskweaver_config.json.",source:"@site/docs/configurations/overview.md",sourceDirName:"configurations",slug:"/configurations/overview",permalink:"/TaskWeaver/docs/configurations/overview",draft:!1,unlisted:!1,editUrl:"https://github.com/microsoft/TaskWeaver/tree/main/website/docs/configurations/overview.md",tags:[],version:"current",frontMatter:{},sidebar:"documentSidebar",previous:{title:"Configurations",permalink:"/TaskWeaver/docs/advanced"},next:{title:"More about Configurations",permalink:"/TaskWeaver/docs/configurations/configurations_in_detail"}},t={},l=[];function h(e){const n={a:"a",blockquote:"blockquote",code:"code",h1:"h1",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.a)(),...e.components};return(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(n.h1,{id:"configuration-file",children:"Configuration File"}),"\n",(0,d.jsxs)(n.p,{children:["An overview of all configurations available in the config file, which is located at ",(0,d.jsx)(n.code,{children:"project/taskweaver_config.json"}),".\nYou can edit this file to configure TaskWeaver.\nThe configuration file is in JSON format. So for boolean values, use ",(0,d.jsx)(n.code,{children:"true"})," or ",(0,d.jsx)(n.code,{children:"false"})," instead of ",(0,d.jsx)(n.code,{children:"True"})," or ",(0,d.jsx)(n.code,{children:"False"}),".\nFor null values, use ",(0,d.jsx)(n.code,{children:"null"})," instead of ",(0,d.jsx)(n.code,{children:"None"})," or ",(0,d.jsx)(n.code,{children:'"null"'}),". All other values should be strings in double quotes.\nThe following table lists the parameters in the configuration file:"]}),"\n",(0,d.jsxs)(n.table,{children:[(0,d.jsx)(n.thead,{children:(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.th,{children:"Parameter"}),(0,d.jsx)(n.th,{children:"Description"}),(0,d.jsx)(n.th,{children:"Default Value"})]})}),(0,d.jsxs)(n.tbody,{children:[(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"llm.model"})}),(0,d.jsx)(n.td,{children:"The model name used by the language model."}),(0,d.jsx)(n.td,{children:"gpt-4"})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"llm.api_base"})}),(0,d.jsx)(n.td,{children:"The base URL of the OpenAI API."}),(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"https://api.openai.com/v1"})})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"llm.api_key"})}),(0,d.jsx)(n.td,{children:"The API key of the OpenAI API."}),(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"null"})})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"llm.api_type"})}),(0,d.jsxs)(n.td,{children:["The type of the OpenAI API, could be ",(0,d.jsx)(n.code,{children:"openai"})," or ",(0,d.jsx)(n.code,{children:"azure"}),"."]}),(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"openai"})})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"llm.api_version"})}),(0,d.jsx)(n.td,{children:"The version of the OpenAI API."}),(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"2023-07-01-preview"})})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"llm.response_format"})}),(0,d.jsxs)(n.td,{children:["The response format of the OpenAI API, could be ",(0,d.jsx)(n.code,{children:"json_object"}),", ",(0,d.jsx)(n.code,{children:"text"})," or ",(0,d.jsx)(n.code,{children:"null"}),"."]}),(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"json_object"})})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"llm.embedding_api_type"})}),(0,d.jsx)(n.td,{children:"The type of the embedding API"}),(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"sentence_transformers"})})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"llm.embedding_model"})}),(0,d.jsx)(n.td,{children:"The name of the embedding model"}),(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"all-mpnet-base-v2"})})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"code_interpreter.code_verification_on"})}),(0,d.jsx)(n.td,{children:"Whether to enable code verification."}),(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"false"})})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"code_interpreter.allowed_modules"})}),(0,d.jsx)(n.td,{children:"The list of allowed modules to import in code generation."}),(0,d.jsxs)(n.td,{children:[(0,d.jsx)(n.code,{children:'["pandas", "matplotlib", "numpy", "sklearn", "scipy", "seaborn", "datetime", "typing"]'}),", if the list is empty, no modules would be allowed"]})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"code_interpreter.blocked_functions"})}),(0,d.jsx)(n.td,{children:"The list of functions to block from code generation."}),(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:'["__import__", "eval", "exec", "execfile", "compile", "open", "input", "raw_input", "reload"]'})})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"logging.log_file"})}),(0,d.jsx)(n.td,{children:"The name of the log file."}),(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"taskweaver.log"})})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"logging.log_folder"})}),(0,d.jsx)(n.td,{children:"The folder to store the log file."}),(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"logs"})})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"plugin.base_path"})}),(0,d.jsx)(n.td,{children:"The folder to store plugins."}),(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"${AppBaseDir}/plugins"})})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"planner.example_base_path"})}),(0,d.jsx)(n.td,{children:"The folder to store planner examples."}),(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"${AppBaseDir}/planner_examples"})})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"planner.prompt_compression"})}),(0,d.jsx)(n.td,{children:"Whether to compress the chat history for planner."}),(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"false"})})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"planner.use_experience"})}),(0,d.jsx)(n.td,{children:"Whether to use experience summarized from the previous chat history in planner."}),(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"false"})})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"code_generator.example_base_path"})}),(0,d.jsx)(n.td,{children:"The folder to store code interpreter examples."}),(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"${AppBaseDir}/codeinterpreter_examples"})})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"code_generator.prompt_compression"})}),(0,d.jsx)(n.td,{children:"Whether to compress the chat history for code interpreter."}),(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"false"})})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"code_generator.enable_auto_plugin_selection"})}),(0,d.jsx)(n.td,{children:"Whether to enable auto plugin selection."}),(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"false"})})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"code_generator.use_experience"})}),(0,d.jsx)(n.td,{children:"Whether to use experience summarized from the previous chat history in code generator."}),(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"false"})})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"code_generator.auto_plugin_selection_topk"})}),(0,d.jsx)(n.td,{children:"The number of auto selected plugins in each round."}),(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"3"})})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"session.max_internal_chat_round_num"})}),(0,d.jsx)(n.td,{children:"The maximum number of internal chat rounds between Planner and Code Interpreter."}),(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"10"})})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"session.roles"})}),(0,d.jsx)(n.td,{children:"The roles included for the conversation."}),(0,d.jsx)(n.td,{children:'["planner", "code_interpreter"]'})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"round_compressor.rounds_to_compress"})}),(0,d.jsx)(n.td,{children:"The number of rounds to compress."}),(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"2"})})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"round_compressor.rounds_to_retain"})}),(0,d.jsx)(n.td,{children:"The number of rounds to retain."}),(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"3"})})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"execution_service.kernel_mode"})}),(0,d.jsxs)(n.td,{children:["The mode of the code executor, could be ",(0,d.jsx)(n.code,{children:"local"})," or ",(0,d.jsx)(n.code,{children:"container"}),"."]}),(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"local"})})]})]})]}),"\n",(0,d.jsxs)(n.blockquote,{children:["\n",(0,d.jsx)(n.p,{children:"\ud83d\udca1 ${AppBaseDir} is the project directory."}),"\n"]}),"\n",(0,d.jsxs)(n.blockquote,{children:["\n",(0,d.jsxs)(n.p,{children:["\ud83d\udca1 Up to 11/30/2023, the ",(0,d.jsx)(n.code,{children:"json_object"})," and ",(0,d.jsx)(n.code,{children:"text"})," options of ",(0,d.jsx)(n.code,{children:"llm.response_format"})," is only supported by the OpenAI\nmodels later than 1106. If you are using an older version of OpenAI model, you need to set the ",(0,d.jsx)(n.code,{children:"llm.response_format"}),"\nto ",(0,d.jsx)(n.code,{children:"null"}),"."]}),"\n"]}),"\n",(0,d.jsxs)(n.blockquote,{children:["\n",(0,d.jsxs)(n.p,{children:["\ud83d\udca1 Read ",(0,d.jsx)(n.a,{href:"/TaskWeaver/docs/advanced/compression",children:"this"})," for more information for ",(0,d.jsx)(n.code,{children:"planner.prompt_compression"})," and ",(0,d.jsx)(n.code,{children:"code_generator.prompt_compression"}),"."]}),"\n"]}),"\n",(0,d.jsxs)(n.blockquote,{children:["\n",(0,d.jsxs)(n.p,{children:["\ud83d\udca1 We support to set configurations via environment variables. You need to transform the configuration key to uppercase and replace the dot with underscore.\nFor example, ",(0,d.jsx)(n.code,{children:"llm.model"})," should be set as ",(0,d.jsx)(n.code,{children:"LLM_MODEL"}),", ",(0,d.jsx)(n.code,{children:"llm.api_base"})," should be set as ",(0,d.jsx)(n.code,{children:"LLM_API_BASE"}),", etc."]}),"\n"]})]})}function a(e={}){const{wrapper:n}={...(0,s.a)(),...e.components};return n?(0,d.jsx)(n,{...e,children:(0,d.jsx)(h,{...e})}):h(e)}},1151:(e,n,r)=>{r.d(n,{Z:()=>c,a:()=>i});var d=r(7294);const s={},o=d.createContext(s);function i(e){const n=d.useContext(o);return d.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),d.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/834e34cc.9d7a5eb5.js b/assets/js/834e34cc.9d7a5eb5.js new file mode 100644 index 00000000..d1f69c59 --- /dev/null +++ b/assets/js/834e34cc.9d7a5eb5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[4471],{1550:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>a,frontMatter:()=>i,metadata:()=>t,toc:()=>l});var d=r(5893),s=r(1151);const i={},o="Configuration File",t={id:"configurations/overview",title:"Configuration File",description:"An overview of all configurations available in the config file, which is located at project/taskweaver_config.json.",source:"@site/docs/configurations/overview.md",sourceDirName:"configurations",slug:"/configurations/overview",permalink:"/TaskWeaver/docs/configurations/overview",draft:!1,unlisted:!1,editUrl:"https://github.com/microsoft/TaskWeaver/tree/main/website/docs/configurations/overview.md",tags:[],version:"current",frontMatter:{},sidebar:"documentSidebar",previous:{title:"Configurations",permalink:"/TaskWeaver/docs/advanced"},next:{title:"More about Configurations",permalink:"/TaskWeaver/docs/configurations/configurations_in_detail"}},c={},l=[];function h(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.a)(),...e.components};return(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(n.h1,{id:"configuration-file",children:"Configuration File"}),"\n",(0,d.jsxs)(n.p,{children:["An overview of all configurations available in the config file, which is located at ",(0,d.jsx)(n.code,{children:"project/taskweaver_config.json"}),".\nYou can edit this file to configure TaskWeaver."]}),"\n",(0,d.jsx)(n.admonition,{type:"tip",children:(0,d.jsxs)(n.p,{children:["The configuration file is in JSON format. So for boolean values, use ",(0,d.jsx)(n.code,{children:"true"})," or ",(0,d.jsx)(n.code,{children:"false"})," instead of ",(0,d.jsx)(n.code,{children:"True"})," or ",(0,d.jsx)(n.code,{children:"False"}),".\nFor null values, use ",(0,d.jsx)(n.code,{children:"null"})," instead of ",(0,d.jsx)(n.code,{children:"None"})," or ",(0,d.jsx)(n.code,{children:'"null"'}),". All other values should be strings in double quotes."]})}),"\n",(0,d.jsx)(n.p,{children:"The following table lists the parameters in the configuration file:"}),"\n",(0,d.jsxs)(n.table,{children:[(0,d.jsx)(n.thead,{children:(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.th,{children:"Parameter"}),(0,d.jsx)(n.th,{children:"Description"}),(0,d.jsx)(n.th,{children:"Default Value"})]})}),(0,d.jsxs)(n.tbody,{children:[(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"llm.model"})}),(0,d.jsx)(n.td,{children:"The model name used by the language model."}),(0,d.jsx)(n.td,{children:"gpt-4"})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"llm.api_base"})}),(0,d.jsx)(n.td,{children:"The base URL of the OpenAI API."}),(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"https://api.openai.com/v1"})})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"llm.api_key"})}),(0,d.jsx)(n.td,{children:"The API key of the OpenAI API."}),(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"null"})})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"llm.api_type"})}),(0,d.jsxs)(n.td,{children:["The type of the OpenAI API, could be ",(0,d.jsx)(n.code,{children:"openai"})," or ",(0,d.jsx)(n.code,{children:"azure"}),"."]}),(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"openai"})})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"llm.api_version"})}),(0,d.jsx)(n.td,{children:"The version of the OpenAI API."}),(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"2023-07-01-preview"})})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"llm.response_format"})}),(0,d.jsxs)(n.td,{children:["The response format of the OpenAI API, could be ",(0,d.jsx)(n.code,{children:"json_object"}),", ",(0,d.jsx)(n.code,{children:"text"})," or ",(0,d.jsx)(n.code,{children:"null"}),"."]}),(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"json_object"})})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"llm.embedding_api_type"})}),(0,d.jsx)(n.td,{children:"The type of the embedding API"}),(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"sentence_transformers"})})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"llm.embedding_model"})}),(0,d.jsx)(n.td,{children:"The name of the embedding model"}),(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"all-mpnet-base-v2"})})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"code_interpreter.code_verification_on"})}),(0,d.jsx)(n.td,{children:"Whether to enable code verification."}),(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"false"})})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"code_interpreter.allowed_modules"})}),(0,d.jsx)(n.td,{children:"The list of allowed modules to import in code generation."}),(0,d.jsxs)(n.td,{children:[(0,d.jsx)(n.code,{children:'["pandas", "matplotlib", "numpy", "sklearn", "scipy", "seaborn", "datetime", "typing"]'}),", if the list is empty, no modules would be allowed"]})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"code_interpreter.blocked_functions"})}),(0,d.jsx)(n.td,{children:"The list of functions to block from code generation."}),(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:'["__import__", "eval", "exec", "execfile", "compile", "open", "input", "raw_input", "reload"]'})})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"logging.log_file"})}),(0,d.jsx)(n.td,{children:"The name of the log file."}),(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"taskweaver.log"})})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"logging.log_folder"})}),(0,d.jsx)(n.td,{children:"The folder to store the log file."}),(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"logs"})})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"plugin.base_path"})}),(0,d.jsx)(n.td,{children:"The folder to store plugins."}),(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"${AppBaseDir}/plugins"})})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"planner.example_base_path"})}),(0,d.jsx)(n.td,{children:"The folder to store planner examples."}),(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"${AppBaseDir}/planner_examples"})})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"planner.prompt_compression"})}),(0,d.jsx)(n.td,{children:"Whether to compress the chat history for planner."}),(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"false"})})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"planner.use_experience"})}),(0,d.jsx)(n.td,{children:"Whether to use experience summarized from the previous chat history in planner."}),(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"false"})})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"code_generator.example_base_path"})}),(0,d.jsx)(n.td,{children:"The folder to store code interpreter examples."}),(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"${AppBaseDir}/codeinterpreter_examples"})})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"code_generator.prompt_compression"})}),(0,d.jsx)(n.td,{children:"Whether to compress the chat history for code interpreter."}),(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"false"})})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"code_generator.enable_auto_plugin_selection"})}),(0,d.jsx)(n.td,{children:"Whether to enable auto plugin selection."}),(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"false"})})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"code_generator.use_experience"})}),(0,d.jsx)(n.td,{children:"Whether to use experience summarized from the previous chat history in code generator."}),(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"false"})})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"code_generator.auto_plugin_selection_topk"})}),(0,d.jsx)(n.td,{children:"The number of auto selected plugins in each round."}),(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"3"})})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"session.max_internal_chat_round_num"})}),(0,d.jsx)(n.td,{children:"The maximum number of internal chat rounds between Planner and Code Interpreter."}),(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"10"})})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"session.roles"})}),(0,d.jsx)(n.td,{children:"The roles included for the conversation."}),(0,d.jsx)(n.td,{children:'["planner", "code_interpreter"]'})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"round_compressor.rounds_to_compress"})}),(0,d.jsx)(n.td,{children:"The number of rounds to compress."}),(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"2"})})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"round_compressor.rounds_to_retain"})}),(0,d.jsx)(n.td,{children:"The number of rounds to retain."}),(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"3"})})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"execution_service.kernel_mode"})}),(0,d.jsxs)(n.td,{children:["The mode of the code executor, could be ",(0,d.jsx)(n.code,{children:"local"})," or ",(0,d.jsx)(n.code,{children:"container"}),"."]}),(0,d.jsx)(n.td,{children:(0,d.jsx)(n.code,{children:"local"})})]})]})]}),"\n",(0,d.jsx)(n.admonition,{type:"tip",children:(0,d.jsx)(n.p,{children:"${AppBaseDir} is the project directory."})}),"\n",(0,d.jsx)(n.admonition,{type:"tip",children:(0,d.jsxs)(n.p,{children:["Up to 11/30/2023, the ",(0,d.jsx)(n.code,{children:"json_object"})," and ",(0,d.jsx)(n.code,{children:"text"})," options of ",(0,d.jsx)(n.code,{children:"llm.response_format"})," is only supported by the OpenAI\nmodels later than 1106. If you are using an older version of OpenAI model, you need to set the ",(0,d.jsx)(n.code,{children:"llm.response_format"}),"\nto ",(0,d.jsx)(n.code,{children:"null"}),"."]})}),"\n",(0,d.jsx)(n.admonition,{type:"tip",children:(0,d.jsxs)(n.p,{children:["Read ",(0,d.jsx)(n.a,{href:"/TaskWeaver/docs/advanced/compression",children:"this"})," for more information for ",(0,d.jsx)(n.code,{children:"planner.prompt_compression"})," and ",(0,d.jsx)(n.code,{children:"code_generator.prompt_compression"}),"."]})}),"\n",(0,d.jsx)(n.admonition,{type:"tip",children:(0,d.jsxs)(n.p,{children:["We support to set configurations via environment variables. You need to transform the configuration key to uppercase and replace the dot with underscore.\nFor example, ",(0,d.jsx)(n.code,{children:"llm.model"})," should be set as ",(0,d.jsx)(n.code,{children:"LLM_MODEL"}),", ",(0,d.jsx)(n.code,{children:"llm.api_base"})," should be set as ",(0,d.jsx)(n.code,{children:"LLM_API_BASE"}),", etc."]})})]})}function a(e={}){const{wrapper:n}={...(0,s.a)(),...e.components};return n?(0,d.jsx)(n,{...e,children:(0,d.jsx)(h,{...e})}):h(e)}},1151:(e,n,r)=>{r.d(n,{Z:()=>t,a:()=>o});var d=r(7294);const s={},i=d.createContext(s);function o(e){const n=d.useContext(i);return d.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function t(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),d.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/88f45e24.eb413e09.js b/assets/js/88f45e24.eb413e09.js new file mode 100644 index 00000000..263eb18f --- /dev/null +++ b/assets/js/88f45e24.eb413e09.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[6417],{4559:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>a,contentTitle:()=>s,default:()=>h,frontMatter:()=>r,metadata:()=>c,toc:()=>d});var t=o(5893),i=o(1151);const r={},s="Code Execution",c={id:"code_execution",title:"Code Execution",description:"\ud83d\udca1We have set the container mode as default for code execution, especially when the usage of the agent",source:"@site/docs/code_execution.md",sourceDirName:".",slug:"/code_execution",permalink:"/TaskWeaver/docs/code_execution",draft:!1,unlisted:!1,editUrl:"https://github.com/microsoft/TaskWeaver/tree/main/website/docs/code_execution.md",tags:[],version:"current",frontMatter:{},sidebar:"documentSidebar",previous:{title:"Quick Start",permalink:"/TaskWeaver/docs/quickstart"},next:{title:"FAQ",permalink:"/TaskWeaver/docs/FAQ"}},a={},d=[{value:"Two Modes of Code Execution",id:"two-modes-of-code-execution",level:2},{value:"How to Configure the Code Execution Mode",id:"how-to-configure-the-code-execution-mode",level:2},{value:"How to customize the Docker image for code execution",id:"how-to-customize-the-docker-image-for-code-execution",level:2},{value:"Limitations of the container Mode",id:"limitations-of-the-container-mode",level:2},{value:"Restricting External Network Access for Docker Containers",id:"restricting-external-network-access-for-docker-containers",level:2}];function l(e){const n={a:"a",blockquote:"blockquote",br:"br",code:"code",h1:"h1",h2:"h2",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"code-execution",children:"Code Execution"}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsxs)(n.p,{children:["\ud83d\udca1We have set the ",(0,t.jsx)(n.code,{children:"container"})," mode as default for code execution, especially when the usage of the agent\nis open to untrusted users. Refer to ",(0,t.jsx)(n.a,{href:"https://docs.docker.com/engine/security/",children:"Docker Security"})," for better understanding\nof the security features of Docker. To opt for the ",(0,t.jsx)(n.code,{children:"local"})," mode, you need to explicitly set the ",(0,t.jsx)(n.code,{children:"execution_service.kernel_mode"}),"\nparameter in the ",(0,t.jsx)(n.code,{children:"taskweaver_config.json"})," file to ",(0,t.jsx)(n.code,{children:"local"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"TaskWeaver is a code-first agent framework, which means that it always converts the user request into code\nand executes the code to generate the response. In our current implementation, we use a Jupyter Kernel\nto execute the code. We choose Jupyter Kernel because it is a well-established tool for interactive computing,\nand it supports many programming languages."}),"\n",(0,t.jsx)(n.h2,{id:"two-modes-of-code-execution",children:"Two Modes of Code Execution"}),"\n",(0,t.jsxs)(n.p,{children:["TaskWeaver supports two modes of code execution: ",(0,t.jsx)(n.code,{children:"local"})," and ",(0,t.jsx)(n.code,{children:"container"}),".\nThe ",(0,t.jsx)(n.code,{children:"container"})," mode is the default mode. The key difference between the two modes is that the ",(0,t.jsx)(n.code,{children:"container"})," mode\nexecutes the code inside a Docker container, which provides a more secure environment for code execution, while\nthe ",(0,t.jsx)(n.code,{children:"local"})," mode executes the code as a subprocess of the TaskWeaver process.\nAs a result, in the ",(0,t.jsx)(n.code,{children:"local"})," mode, if the user has malicious intent, the user could potentially\ninstruct TaskWeaver to execute harmful code on the host machine. In addition, the LLM could also generate\nharmful code, leading to potential security risks."]}),"\n",(0,t.jsx)(n.h2,{id:"how-to-configure-the-code-execution-mode",children:"How to Configure the Code Execution Mode"}),"\n",(0,t.jsxs)(n.p,{children:["To configure the code execution mode, you need to set the ",(0,t.jsx)(n.code,{children:"execution_service.kernel_mode"})," parameter in the\n",(0,t.jsx)(n.code,{children:"taskweaver_config.json"})," file. The value of the parameter could be ",(0,t.jsx)(n.code,{children:"local"})," or ",(0,t.jsx)(n.code,{children:"container"}),". The default value\nis ",(0,t.jsx)(n.code,{children:"container"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["TaskWeaver supports the ",(0,t.jsx)(n.code,{children:"local"})," mode without any additional setup. However, to use the ",(0,t.jsx)(n.code,{children:"container"})," mode,\nthere are a few prerequisites:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Docker is installed on the host machine."}),"\n",(0,t.jsx)(n.li,{children:"A Docker image is built and available on the host machine for code execution."}),"\n",(0,t.jsxs)(n.li,{children:["The ",(0,t.jsx)(n.code,{children:"execution_service.kernel_mode"})," parameter is set to ",(0,t.jsx)(n.code,{children:"container"})," in the ",(0,t.jsx)(n.code,{children:"taskweaver_config.json"})," file."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Once the code repository is cloned to your local machine, you can build the Docker image\nby running the following command in the root directory of the code repository:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cd scripts\n\n# based on your OS\n./build_executor.ps1 # for Windows\n./build_executor.sh # for Linux or macOS\n"})}),"\n",(0,t.jsxs)(n.p,{children:["After the Docker image is built, you can run ",(0,t.jsx)(n.code,{children:"docker images"})," to check if a Docker image\nnamed ",(0,t.jsx)(n.code,{children:"executor_container"})," is available.\nIf the prerequisite is met, you can now run TaskWeaver in the ",(0,t.jsx)(n.code,{children:"container"})," mode."]}),"\n",(0,t.jsxs)(n.p,{children:["After running TaskWeaver in the ",(0,t.jsx)(n.code,{children:"container"})," mode, you can check if the container is running by running ",(0,t.jsx)(n.code,{children:"docker ps"}),".\nYou should see a container of image ",(0,t.jsx)(n.code,{children:"taskweavercontainers/taskweaver-executor"})," running after executing some code."]}),"\n",(0,t.jsx)(n.h2,{id:"how-to-customize-the-docker-image-for-code-execution",children:"How to customize the Docker image for code execution"}),"\n",(0,t.jsxs)(n.p,{children:["You may want to customize the Docker image for code execution to include additional packages or libraries, especially\nfor your developed plugins. The current Docker image for code execution is ",(0,t.jsx)(n.code,{children:"taskweavercontainers/taskweaver-executor"}),", which\nonly includes the dependencies specified in the ",(0,t.jsx)(n.code,{children:"TaskWeaver/requirements.txt"})," file. To customize the Docker image, you need to\nmodify the ",(0,t.jsx)(n.code,{children:"Dockerfile"})," at ",(0,t.jsx)(n.code,{children:"TaskWeaver/docker/ces_container/Dockerfile"})," and rebuild the Docker image."]}),"\n",(0,t.jsxs)(n.p,{children:["When you open the ",(0,t.jsx)(n.code,{children:"Dockerfile"}),", you will see the following content, and you can add additional packages or libraries\nby adding the corresponding ",(0,t.jsx)(n.code,{children:"RUN"})," command. In this example, we add the ",(0,t.jsx)(n.code,{children:"sentence-transformers"})," package to the Docker image."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-Dockerfile",children:"FROM python:3.10-slim\n...\n# TODO: Install additional packages for plugins\nRUN pip install --no-cache-dir --no-warn-script-location --user sentence-transformers\n...\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Then, you need to rebuild the Docker image by running the ",(0,t.jsx)(n.code,{children:"build_executor.sh"})," script at ",(0,t.jsx)(n.code,{children:"TaskWeaver/scripts/build_executor.sh"}),"\nor ",(0,t.jsx)(n.code,{children:"TaskWeaver/scripts/build.ps1"})," depending on your operating system."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cd TaskWeaver/scripts\n./build_executor.sh\n# or ./build_executor.ps1 if you are using Windows\n"})}),"\n",(0,t.jsxs)(n.p,{children:["If you have successfully rebuilt the Docker image, you can check the new image by running ",(0,t.jsx)(n.code,{children:"docker images"}),".\nAfter building the Docker image, you need to restart the TaskWeaver agent to use the new Docker image."]}),"\n",(0,t.jsxs)(n.h2,{id:"limitations-of-the-container-mode",children:["Limitations of the ",(0,t.jsx)(n.code,{children:"container"})," Mode"]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"container"})," mode is more secure than the ",(0,t.jsx)(n.code,{children:"local"})," mode, but it also has some limitations:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["The startup time of the ",(0,t.jsx)(n.code,{children:"container"})," mode is longer than the ",(0,t.jsx)(n.code,{children:"local"})," mode, because it needs to start a Docker container."]}),"\n",(0,t.jsxs)(n.li,{children:["As the Jupyter Kernel is running inside a Docker container, it has limited access to the host machine. We are mapping the\n",(0,t.jsx)(n.code,{children:"project/workspace/sessions/"})," directory to the container, so the code executed in the container can access the\nfiles in it. One implication of this is that the user cannot ask the agent to load a file from the host machine, because the\nfile is not available in the container. Instead, the user needs to upload the file either using the ",(0,t.jsx)(n.code,{children:"/upload"})," command in\nthe console or the ",(0,t.jsx)(n.code,{children:"upload"})," button in the web interface."]}),"\n",(0,t.jsxs)(n.li,{children:["We have installed required packages in the Docker image to run the Jupyter Kernel. If the user needs to use a package that is\nnot available in the Docker image, the user needs to add the package to the Dockerfile (at ",(0,t.jsx)(n.code,{children:"TaskWeaver/ces_container/Dockerfile"}),")\nand rebuild the Docker image."]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"restricting-external-network-access-for-docker-containers",children:"Restricting External Network Access for Docker Containers"}),"\n",(0,t.jsx)(n.p,{children:"In some cases, the agent developer may want to restrict the Docker container's access to the external network, e.g., the internet.\nIn other words, the agent developer only wants to run the code in the container but does not allow either\nthe plugins or the generated code to access the internet."}),"\n",(0,t.jsx)(n.p,{children:"The following approach is a common way to restrict a Docker container's access to the internet while still\nallowing inbound connections on specific ports:"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsxs)(n.strong,{children:["Creating a Docker network with ",(0,t.jsx)(n.code,{children:"enable_ip_masquerade"})," set to false"]}),":"]}),"\n",(0,t.jsxs)(n.p,{children:["By default, Docker uses IP masquerading (a form of network address translation or NAT) to allow containers\nto communicate with external networks with the source IP address being the host IP address.\nWhen you set ",(0,t.jsx)(n.code,{children:"enable_ip_masquerade"})," to false for a custom Docker network,\nyou prevent containers on that network from having their IP addresses masqueraded, effectively blocking them\nfrom accessing the internet. To create such a network in Docker, you would use the following command:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"docker network create --opt com.docker.network.bridge.enable_ip_masquerade=false my_non_internet_network \n"})}),"\n",(0,t.jsxs)(n.p,{children:["Any container connected to ",(0,t.jsx)(n.code,{children:"my_non_internet_network"})," will not have internet access due to the disabled IP masquerade.",(0,t.jsx)(n.br,{}),"\n","Now, you can run"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"docker network inspect my_non_internet_network\n"})}),"\n",(0,t.jsx)(n.p,{children:"and you will see an output similar to the following:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'"Config": [\n {\n "Subnet": "172.19.0.0/16",\n "Gateway": "172.19.0.1"\n }\n]\n'})}),"\n",(0,t.jsx)(n.p,{children:"This shows the subnet of the docker network, all containers connected to this network will have an IP address in this subnet."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Establishing a rule on the host's firewall or using iptables"}),":"]}),"\n",(0,t.jsx)(n.p,{children:"This step is about setting up rules to block outgoing traffic from the Docker network's subnet\nto any external addresses. This adds an additional layer of security to ensure that even\nif IP masquerade is somehow enabled or if the container finds another route, the traffic will still be blocked."}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"On a Linux host using iptables"}),", you might add a rule like this:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"iptables -I FORWARD -s -j DROP \n"})}),"\n",(0,t.jsxs)(n.p,{children:["Replace ",(0,t.jsx)(n.code,{children:""})," with the actual subnet used by your Docker network.\nIn the previous example, the subnet is ",(0,t.jsx)(n.code,{children:"172.19.0.0/16"}),". This rule drops all forwarding traffic from that subnet."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"On a Windows host"}),", you would create a similar rule within the Windows Firewall\nto block outgoing traffic from the Docker network's subnet."]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Keep in mind that this approach can be considered good practice if you understand the implications\nand have a specific need to isolate your container from the internet.\nHowever, it could also complicate network troubleshooting and container communication if not managed properly.\nAlways ensure you are testing these configurations in a safe environment before applying them to production systems."})]})}function h(e={}){const{wrapper:n}={...(0,i.a)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},1151:(e,n,o)=>{o.d(n,{Z:()=>c,a:()=>s});var t=o(7294);const i={},r=t.createContext(i);function s(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:s(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/935f2afb.2d42b0b9.js b/assets/js/935f2afb.2d42b0b9.js deleted file mode 100644 index e6d7f274..00000000 --- a/assets/js/935f2afb.2d42b0b9.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[53],{1109:e=>{e.exports=JSON.parse('{"pluginId":"default","version":"current","label":"Next","banner":null,"badge":false,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"documentSidebar":[{"type":"link","label":"Overview","href":"/TaskWeaver/docs/overview","docId":"overview","unlisted":false},{"type":"link","label":"Quick Start","href":"/TaskWeaver/docs/quickstart","docId":"quickstart","unlisted":false},{"type":"category","label":"Usage Options","collapsible":true,"collapsed":false,"items":[{"type":"link","label":"Terminal","href":"/TaskWeaver/docs/usage/cmd","docId":"usage/cmd","unlisted":false},{"type":"link","label":"Web UI","href":"/TaskWeaver/docs/usage/webui","docId":"usage/webui","unlisted":false},{"type":"link","label":"Library","href":"/TaskWeaver/docs/usage/library","docId":"usage/library","unlisted":false},{"type":"link","label":"All-in-One Docker Image","href":"/TaskWeaver/docs/usage/docker","docId":"usage/docker","unlisted":false}],"href":"/TaskWeaver/docs/usage"},{"type":"category","label":"Supported LLMs","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"OpenAI","href":"/TaskWeaver/docs/llms/openai","docId":"llms/openai","unlisted":false},{"type":"link","label":"Azure OpenAI","href":"/TaskWeaver/docs/llms/aoai","docId":"llms/aoai","unlisted":false},{"type":"link","label":"LiteLLM","href":"/TaskWeaver/docs/llms/liteLLM","docId":"llms/liteLLM","unlisted":false},{"type":"link","label":"Ollama","href":"/TaskWeaver/docs/llms/ollama","docId":"llms/ollama","unlisted":false},{"type":"link","label":"Gemini","href":"/TaskWeaver/docs/llms/gemini","docId":"llms/gemini","unlisted":false},{"type":"link","label":"QWen","href":"/TaskWeaver/docs/llms/qwen","docId":"llms/qwen","unlisted":false},{"type":"link","label":"GLM","href":"/TaskWeaver/docs/llms/glm","docId":"llms/glm","unlisted":false},{"type":"link","label":"Customized LLM API","href":"/TaskWeaver/docs/llms/customized_llm_api","docId":"llms/customized_llm_api","unlisted":false},{"type":"link","label":"Multi LLM APIs","href":"/TaskWeaver/docs/llms/multi-llm","docId":"llms/multi-llm","unlisted":false}],"href":"/TaskWeaver/docs/llms"},{"type":"category","label":"Configurations","collapsible":true,"collapsed":false,"items":[{"type":"link","label":"Configuration File","href":"/TaskWeaver/docs/configurations/overview","docId":"configurations/overview","unlisted":false},{"type":"link","label":"More about Configurations","href":"/TaskWeaver/docs/configurations/configurations_in_detail","docId":"configurations/configurations_in_detail","unlisted":false}],"href":"/TaskWeaver/docs/advanced"},{"type":"category","label":"Customization","collapsible":true,"collapsed":false,"items":[{"type":"category","label":"Plugin","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Plugin Introduction","href":"/TaskWeaver/docs/plugin/plugin_intro","docId":"customization/plugin/plugin_intro","unlisted":false},{"type":"link","label":"Auto Plugin Selection","href":"/TaskWeaver/docs/customization/plugin/plugin_selection","docId":"customization/plugin/plugin_selection","unlisted":false},{"type":"link","label":"How to develop a new plugin","href":"/TaskWeaver/docs/plugin/how_to_develop_a_new_plugin","docId":"customization/plugin/develop_plugin","unlisted":false},{"type":"link","label":"Multiple YAML files to one Python implementation","href":"/TaskWeaver/docs/plugin/multi_yaml_single_impl","docId":"customization/plugin/multi_yaml_single_impl","unlisted":false},{"type":"link","label":"The Plugin-Only Mode","href":"/TaskWeaver/docs/plugin/plugin_only","docId":"customization/plugin/plugin_only","unlisted":false}]},{"type":"category","label":"Example","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Customizing Examples","href":"/TaskWeaver/docs/customization/example/","docId":"customization/example/example","unlisted":false}]},{"type":"category","label":"Experience","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Experience","href":"/TaskWeaver/docs/customization/experience","docId":"customization/experience","unlisted":false}]}],"href":"/TaskWeaver/docs/customization"},{"type":"category","label":"Advanced Features","collapsible":true,"collapsed":false,"items":[{"type":"link","label":"Prompt Compression","href":"/TaskWeaver/docs/advanced/compression","docId":"advanced/compression","unlisted":false},{"type":"link","label":"Code Verification","href":"/TaskWeaver/docs/advanced/code_verification","docId":"advanced/code_verification","unlisted":false},{"type":"link","label":"Code Execution","href":"/TaskWeaver/docs/advanced/code_execution","docId":"advanced/code_execution","unlisted":false},{"type":"link","label":"CLI Only Mode","href":"/TaskWeaver/docs/advanced/cli_only","docId":"advanced/cli_only","unlisted":false},{"type":"link","label":"Telemetry","href":"/TaskWeaver/docs/advanced/telemetry","docId":"advanced/telemetry","unlisted":false}]},{"type":"link","label":"FAQ","href":"/TaskWeaver/docs/FAQ","docId":"FAQ","unlisted":false}]},"docs":{"advanced/cli_only":{"id":"advanced/cli_only","title":"CLI Only Mode","description":"TaskWeaver\'s CLI-only mode enables users to effortlessly communicate with the Command Line Interface (CLI) using natural language.","sidebar":"documentSidebar"},"advanced/code_execution":{"id":"advanced/code_execution","title":"Code Execution","description":"\ud83d\udca1We have set the container mode as default for code execution, especially when the usage of the agent","sidebar":"documentSidebar"},"advanced/code_verification":{"id":"advanced/code_verification","title":"Code Verification","description":"Code Verification","sidebar":"documentSidebar"},"advanced/compression":{"id":"advanced/compression","title":"Prompt Compression","description":"After chatting for a few rounds, the chat history can become quite long, especially when we have code and execution results in it.","sidebar":"documentSidebar"},"advanced/telemetry":{"id":"advanced/telemetry","title":"Telemetry","description":"TaskWeaver now supports tracing with OpenTelemetry,","sidebar":"documentSidebar"},"configurations/configurations_in_detail":{"id":"configurations/configurations_in_detail","title":"More about Configurations","description":"More details about some important configurations","sidebar":"documentSidebar"},"configurations/overview":{"id":"configurations/overview","title":"Configuration File","description":"An overview of all configurations available in the config file, which is located at project/taskweaver_config.json.","sidebar":"documentSidebar"},"customization/example/example":{"id":"customization/example/example","title":"Customizing Examples","description":"There are two types of examples: (1) planning examples and (2) code interpreter examples.","sidebar":"documentSidebar"},"customization/experience":{"id":"customization/experience","title":"Experience","description":"Motivation","sidebar":"documentSidebar"},"customization/index":{"id":"customization/index","title":"Supported Customizations","description":"List for all supported customizations"},"customization/plugin/develop_plugin":{"id":"customization/plugin/develop_plugin","title":"How to develop a new plugin","description":"How to develop a new plugin","sidebar":"documentSidebar"},"customization/plugin/multi_yaml_single_impl":{"id":"customization/plugin/multi_yaml_single_impl","title":"Multiple YAML files to one Python implementation","description":"Multiple YAML files to one Python implementation","sidebar":"documentSidebar"},"customization/plugin/plugin_intro":{"id":"customization/plugin/plugin_intro","title":"Plugin Introduction","description":"Plugin introduction","sidebar":"documentSidebar"},"customization/plugin/plugin_only":{"id":"customization/plugin/plugin_only","title":"The Plugin-Only Mode","description":"The Plugin Only Mode","sidebar":"documentSidebar"},"customization/plugin/plugin_selection":{"id":"customization/plugin/plugin_selection","title":"Auto Plugin Selection","description":"In TaskWeaver, we provide an auto plugin selection mechanism to dynamically select the best plugin for each user request.","sidebar":"documentSidebar"},"FAQ":{"id":"FAQ","title":"FAQ","description":"Q: How do I know if TaskWeaver can see my plugin?","sidebar":"documentSidebar"},"llms/aoai":{"id":"llms/aoai","title":"Azure OpenAI","description":"Using LLMs from OpenAI/AOAI","sidebar":"documentSidebar"},"llms/customized_llm_api":{"id":"llms/customized_llm_api","title":"Customized LLM API","description":"We welcome developers to use your customized LLM API in TaskWeaver.","sidebar":"documentSidebar"},"llms/gemini":{"id":"llms/gemini","title":"Gemini","description":"1. Create an account on Google AI and get your API key.","sidebar":"documentSidebar"},"llms/glm":{"id":"llms/glm","title":"GLM","description":"1. GLM (ChatGLM) is a LLM developed by Zhipu AI and Tsinghua KEG. Go to ZhipuAI and register an account and get the API key. More details can be found here.","sidebar":"documentSidebar"},"llms/index":{"id":"llms/index","title":"Supported LLMs","description":"List for all supported LLMs"},"llms/liteLLM":{"id":"llms/liteLLM","title":"LiteLLM","description":"Using LLMs from LiteLLM","sidebar":"documentSidebar"},"llms/multi-llm":{"id":"llms/multi-llm","title":"Multi LLM APIs","description":"In some cases, you may want to use different LLMs for different components.","sidebar":"documentSidebar"},"llms/ollama":{"id":"llms/ollama","title":"Ollama","description":"1. Go to Ollama and follow the instructions to serve a LLM model on your local environment.","sidebar":"documentSidebar"},"llms/openai":{"id":"llms/openai","title":"OpenAI","description":"Using LLMs from OpenAI","sidebar":"documentSidebar"},"llms/qwen":{"id":"llms/qwen","title":"QWen","description":"1. QWen (Tongyi Qianwen) is a LLM developed by Alibaba. Go to QWen and register an account and get the API key. More details can be found here (in Chinese).","sidebar":"documentSidebar"},"overview":{"id":"overview","title":"Overview","description":"{e.exports=JSON.parse('{"pluginId":"default","version":"current","label":"Next","banner":null,"badge":false,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"documentSidebar":[{"type":"link","label":"Overview","href":"/TaskWeaver/docs/overview","docId":"overview","unlisted":false},{"type":"link","label":"Quick Start","href":"/TaskWeaver/docs/quickstart","docId":"quickstart","unlisted":false},{"type":"link","label":"Code Execution","href":"/TaskWeaver/docs/code_execution","docId":"code_execution","unlisted":false},{"type":"link","label":"FAQ","href":"/TaskWeaver/docs/FAQ","docId":"FAQ","unlisted":false},{"type":"category","label":"Usage Options","collapsible":true,"collapsed":false,"items":[{"type":"link","label":"Terminal","href":"/TaskWeaver/docs/usage/cmd","docId":"usage/cmd","unlisted":false},{"type":"link","label":"Web UI","href":"/TaskWeaver/docs/usage/webui","docId":"usage/webui","unlisted":false},{"type":"link","label":"Library","href":"/TaskWeaver/docs/usage/library","docId":"usage/library","unlisted":false},{"type":"link","label":"All-in-One Docker Image","href":"/TaskWeaver/docs/usage/docker","docId":"usage/docker","unlisted":false}],"href":"/TaskWeaver/docs/usage"},{"type":"category","label":"Supported LLMs","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"OpenAI","href":"/TaskWeaver/docs/llms/openai","docId":"llms/openai","unlisted":false},{"type":"link","label":"Azure OpenAI","href":"/TaskWeaver/docs/llms/aoai","docId":"llms/aoai","unlisted":false},{"type":"link","label":"LiteLLM","href":"/TaskWeaver/docs/llms/liteLLM","docId":"llms/liteLLM","unlisted":false},{"type":"link","label":"Ollama","href":"/TaskWeaver/docs/llms/ollama","docId":"llms/ollama","unlisted":false},{"type":"link","label":"Gemini","href":"/TaskWeaver/docs/llms/gemini","docId":"llms/gemini","unlisted":false},{"type":"link","label":"QWen","href":"/TaskWeaver/docs/llms/qwen","docId":"llms/qwen","unlisted":false},{"type":"link","label":"GLM","href":"/TaskWeaver/docs/llms/glm","docId":"llms/glm","unlisted":false},{"type":"link","label":"Customized LLM API","href":"/TaskWeaver/docs/llms/customized_llm_api","docId":"llms/customized_llm_api","unlisted":false},{"type":"link","label":"Multi LLM APIs","href":"/TaskWeaver/docs/llms/multi-llm","docId":"llms/multi-llm","unlisted":false}],"href":"/TaskWeaver/docs/llms"},{"type":"category","label":"Configurations","collapsible":true,"collapsed":false,"items":[{"type":"link","label":"Configuration File","href":"/TaskWeaver/docs/configurations/overview","docId":"configurations/overview","unlisted":false},{"type":"link","label":"More about Configurations","href":"/TaskWeaver/docs/configurations/configurations_in_detail","docId":"configurations/configurations_in_detail","unlisted":false}],"href":"/TaskWeaver/docs/advanced"},{"type":"category","label":"Customization","collapsible":true,"collapsed":false,"items":[{"type":"category","label":"Plugin","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Plugin Introduction","href":"/TaskWeaver/docs/plugin/plugin_intro","docId":"customization/plugin/plugin_intro","unlisted":false},{"type":"link","label":"An Example of Developing a New Plugin","href":"/TaskWeaver/docs/plugin/how_to_develop_a_new_plugin","docId":"customization/plugin/develop_plugin","unlisted":false},{"type":"link","label":"Multiple YAML files to one Python implementation","href":"/TaskWeaver/docs/plugin/multi_yaml_single_impl","docId":"customization/plugin/multi_yaml_single_impl","unlisted":false}]},{"type":"category","label":"Example","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Customizing Examples","href":"/TaskWeaver/docs/customization/example/","docId":"customization/example/example","unlisted":false}]},{"type":"category","label":"Experience","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Experience","href":"/TaskWeaver/docs/customization/experience","docId":"customization/experience","unlisted":false}]}],"href":"/TaskWeaver/docs/customization"},{"type":"category","label":"Advanced Features","collapsible":true,"collapsed":false,"items":[{"type":"link","label":"Prompt Compression","href":"/TaskWeaver/docs/advanced/compression","docId":"advanced/compression","unlisted":false},{"type":"link","label":"Auto Plugin Selection","href":"/TaskWeaver/docs/advanced/plugin_selection","docId":"advanced/plugin_selection","unlisted":false},{"type":"link","label":"Code Verification","href":"/TaskWeaver/docs/advanced/code_verification","docId":"advanced/code_verification","unlisted":false},{"type":"link","label":"CLI Only Mode","href":"/TaskWeaver/docs/advanced/cli_only","docId":"advanced/cli_only","unlisted":false},{"type":"link","label":"Telemetry","href":"/TaskWeaver/docs/advanced/telemetry","docId":"advanced/telemetry","unlisted":false},{"type":"link","label":"The Plugin-Only Mode","href":"/TaskWeaver/docs/plugin/plugin_only","docId":"advanced/plugin_only","unlisted":false}]}]},"docs":{"advanced/cli_only":{"id":"advanced/cli_only","title":"CLI Only Mode","description":"TaskWeaver\'s CLI-only mode enables users to effortlessly communicate with the Command Line Interface (CLI) using natural language.","sidebar":"documentSidebar"},"advanced/code_verification":{"id":"advanced/code_verification","title":"Code Verification","description":"Code Verification","sidebar":"documentSidebar"},"advanced/compression":{"id":"advanced/compression","title":"Prompt Compression","description":"After chatting for a few rounds, the chat history can become quite long, especially when we have code and execution results in it.","sidebar":"documentSidebar"},"advanced/plugin_only":{"id":"advanced/plugin_only","title":"The Plugin-Only Mode","description":"The Plugin Only Mode","sidebar":"documentSidebar"},"advanced/plugin_selection":{"id":"advanced/plugin_selection","title":"Auto Plugin Selection","description":"In TaskWeaver, we provide an auto plugin selection mechanism to dynamically select the best plugin for each user request.","sidebar":"documentSidebar"},"advanced/telemetry":{"id":"advanced/telemetry","title":"Telemetry","description":"TaskWeaver now supports tracing with OpenTelemetry,","sidebar":"documentSidebar"},"code_execution":{"id":"code_execution","title":"Code Execution","description":"\ud83d\udca1We have set the container mode as default for code execution, especially when the usage of the agent","sidebar":"documentSidebar"},"configurations/configurations_in_detail":{"id":"configurations/configurations_in_detail","title":"More about Configurations","description":"More details about important configurations.","sidebar":"documentSidebar"},"configurations/overview":{"id":"configurations/overview","title":"Configuration File","description":"An overview of all configurations available in the config file, which is located at project/taskweaver_config.json.","sidebar":"documentSidebar"},"customization/example/example":{"id":"customization/example/example","title":"Customizing Examples","description":"There are currently two types of examples: (1) Planner examples and (2) CodeInterpreter examples.","sidebar":"documentSidebar"},"customization/experience":{"id":"customization/experience","title":"Experience","description":"Motivation","sidebar":"documentSidebar"},"customization/index":{"id":"customization/index","title":"Supported Customizations","description":"List for all supported customizations"},"customization/plugin/develop_plugin":{"id":"customization/plugin/develop_plugin","title":"An Example of Developing a New Plugin","description":"How to develop a new plugin","sidebar":"documentSidebar"},"customization/plugin/multi_yaml_single_impl":{"id":"customization/plugin/multi_yaml_single_impl","title":"Multiple YAML files to one Python implementation","description":"Multiple YAML files to one Python implementation","sidebar":"documentSidebar"},"customization/plugin/plugin_intro":{"id":"customization/plugin/plugin_intro","title":"Plugin Introduction","description":"Plugin introduction","sidebar":"documentSidebar"},"FAQ":{"id":"FAQ","title":"FAQ","description":"Q: Why it takes so long to generate the output?","sidebar":"documentSidebar"},"llms/aoai":{"id":"llms/aoai","title":"Azure OpenAI","description":"Using LLMs from OpenAI/AOAI","sidebar":"documentSidebar"},"llms/customized_llm_api":{"id":"llms/customized_llm_api","title":"Customized LLM API","description":"We welcome developers to use your customized LLM API in TaskWeaver.","sidebar":"documentSidebar"},"llms/gemini":{"id":"llms/gemini","title":"Gemini","description":"1. Create an account on Google AI and get your API key.","sidebar":"documentSidebar"},"llms/glm":{"id":"llms/glm","title":"GLM","description":"1. GLM (ChatGLM) is a LLM developed by Zhipu AI and Tsinghua KEG. Go to ZhipuAI and register an account and get the API key. More details can be found here.","sidebar":"documentSidebar"},"llms/index":{"id":"llms/index","title":"Supported LLMs","description":"List for all supported LLMs"},"llms/liteLLM":{"id":"llms/liteLLM","title":"LiteLLM","description":"Using LLMs from LiteLLM","sidebar":"documentSidebar"},"llms/multi-llm":{"id":"llms/multi-llm","title":"Multi LLM APIs","description":"In some cases, you may want to use different LLMs for different components.","sidebar":"documentSidebar"},"llms/ollama":{"id":"llms/ollama","title":"Ollama","description":"1. Go to Ollama and follow the instructions to serve a LLM model on your local environment.","sidebar":"documentSidebar"},"llms/openai":{"id":"llms/openai","title":"OpenAI","description":"Using LLMs from OpenAI","sidebar":"documentSidebar"},"llms/qwen":{"id":"llms/qwen","title":"QWen","description":"1. QWen (Tongyi Qianwen) is a LLM developed by Alibaba. Go to QWen and register an account and get the API key. More details can be found here (in Chinese).","sidebar":"documentSidebar"},"overview":{"id":"overview","title":"Overview","description":"{l.r(n),l.d(n,{assets:()=>r,contentTitle:()=>s,default:()=>h,frontMatter:()=>t,metadata:()=>d,toc:()=>c});var o=l(5893),i=l(1151);const t={id:"plugin_only",description:"The Plugin Only Mode",slug:"/plugin/plugin_only"},s="The Plugin-Only Mode",d={id:"advanced/plugin_only",title:"The Plugin-Only Mode",description:"The Plugin Only Mode",source:"@site/docs/advanced/plugin_only.md",sourceDirName:"advanced",slug:"/plugin/plugin_only",permalink:"/TaskWeaver/docs/plugin/plugin_only",draft:!1,unlisted:!1,editUrl:"https://github.com/microsoft/TaskWeaver/tree/main/website/docs/advanced/plugin_only.md",tags:[],version:"current",frontMatter:{id:"plugin_only",description:"The Plugin Only Mode",slug:"/plugin/plugin_only"},sidebar:"documentSidebar",previous:{title:"Telemetry",permalink:"/TaskWeaver/docs/advanced/telemetry"}},r={},c=[{value:"What is the plugin-only mode?",id:"what-is-the-plugin-only-mode",level:2},{value:"How is the plugin-only mode implemented?",id:"how-is-the-plugin-only-mode-implemented",level:2},{value:"Which models support the plugin-only mode?",id:"which-models-support-the-plugin-only-mode",level:2}];function a(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,i.a)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h1,{id:"the-plugin-only-mode",children:"The Plugin-Only Mode"}),"\n",(0,o.jsx)(n.h2,{id:"what-is-the-plugin-only-mode",children:"What is the plugin-only mode?"}),"\n",(0,o.jsx)(n.p,{children:"The plugin-only mode is a restricted mode of TaskWeaver that only allows you to use plugins.\nCompared to the full mode, the plugin-only mode has the following restrictions:"}),"\n",(0,o.jsxs)(n.ol,{children:["\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:["The generated code only contains the calls to the plugins.\nFor example, the following code only calls the ",(0,o.jsx)(n.code,{children:"ascii_render"}),' plugin and does not contain any "free-form" code.']}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-python",children:'r1=ascii_render(**{"text":"Hello"})\nr1\n'})}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:["Only the plugins with ",(0,o.jsx)(n.code,{children:"plugin_only: true"})," in the yaml file will be loaded.\nFor example, the following plugin will be loaded in the plugin-only mode:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml",children:"name: ascii_render\nplugin_only: true\n...\n"})}),"\n",(0,o.jsxs)(n.p,{children:["If this field is not specified, the default value is ",(0,o.jsx)(n.code,{children:"false"}),".\nFor plugins in the plugin-only mode, the argument type can only be ",(0,o.jsx)(n.code,{children:"str"}),", ",(0,o.jsx)(n.code,{children:"int"}),", ",(0,o.jsx)(n.code,{children:"boolean"}),", or ",(0,o.jsx)(n.code,{children:"float"}),".\nOther types such as ",(0,o.jsx)(n.code,{children:"DataFrame"}),' are not allowed.\nEssentially, we consider these plugins only produce "text-like" output that can be directly consumed by the LLM.']}),"\n"]}),"\n"]}),"\n",(0,o.jsxs)(n.p,{children:["To support the plugin-only mode, we developed a new role called ",(0,o.jsx)(n.code,{children:"PluginOrchestrator"}),".\nTo enable the plugin-only mode, you can add the configuration ",(0,o.jsx)(n.code,{children:'"session.roles": ["planner", "code_interpreter_plugin_only"]'}),"\nin the project configuration file ",(0,o.jsx)(n.code,{children:"taskweaver_config.json"}),"."]}),"\n",(0,o.jsx)(n.admonition,{type:"info",children:(0,o.jsx)(n.p,{children:"Although the plugin-only mode is restricted, it is still useful in some scenarios.\nFor example, you may want to use TaskWeaver to only generate the code to call a certain plugin,\nand you want to get the response from the plugin directly, without generating any other code\nfor safety reasons."})}),"\n",(0,o.jsx)(n.h2,{id:"how-is-the-plugin-only-mode-implemented",children:"How is the plugin-only mode implemented?"}),"\n",(0,o.jsxs)(n.p,{children:["The plugin-only mode is implemented based on the ",(0,o.jsx)(n.a,{href:"https://platform.openai.com/docs/guides/function-calling",children:"function calling"})," mode of LLMs.\nIn this mode, the LLM is trained to generate a JSON object that contains the function name and the arguments.\nFor example, the following JSON object is generated by the LLM:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-json",children:'{\n "function": "ascii_render",\n "arguments": {\n "text": "Hello"\n }\n}\n'})}),"\n",(0,o.jsx)(n.p,{children:"With this JSON object, we assemble the code to call the plugin:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-python",children:'r1=ascii_render(**{"text":"Hello"})\nr1\n'})}),"\n",(0,o.jsx)(n.p,{children:"Then, we execute the code and get the response from the plugin.\nTherefore, the code is not directly generated by the LLM in the plugin-only mode."}),"\n",(0,o.jsx)(n.h2,{id:"which-models-support-the-plugin-only-mode",children:"Which models support the plugin-only mode?"}),"\n",(0,o.jsx)(n.p,{children:"Currently, the plugin-only mode is only supported by"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:(0,o.jsx)(n.a,{href:"https://platform.openai.com/docs/guides/function-calling",children:"OpenAI models"})}),"\n",(0,o.jsx)(n.li,{children:(0,o.jsx)(n.a,{href:"https://open.bigmodel.cn/dev/api",children:"ZhipuAI models"})}),"\n"]}),"\n",(0,o.jsx)(n.p,{children:"Likely other models that are compatible with the OpenAI models will also support the plugin-only mode."})]})}function h(e={}){const{wrapper:n}={...(0,i.a)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(a,{...e})}):a(e)}},1151:(e,n,l)=>{l.d(n,{Z:()=>d,a:()=>s});var o=l(7294);const i={},t=o.createContext(i);function s(e){const n=o.useContext(t);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:s(e.components),o.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a417478a.aba6c885.js b/assets/js/a417478a.aba6c885.js new file mode 100644 index 00000000..ee0b6605 --- /dev/null +++ b/assets/js/a417478a.aba6c885.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[4229],{9397:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>r,default:()=>u,frontMatter:()=>o,metadata:()=>a,toc:()=>c});var i=t(5893),s=t(1151);const o={},r="Auto Plugin Selection",a={id:"advanced/plugin_selection",title:"Auto Plugin Selection",description:"In TaskWeaver, we provide an auto plugin selection mechanism to dynamically select the best plugin for each user request.",source:"@site/docs/advanced/plugin_selection.md",sourceDirName:"advanced",slug:"/advanced/plugin_selection",permalink:"/TaskWeaver/docs/advanced/plugin_selection",draft:!1,unlisted:!1,editUrl:"https://github.com/microsoft/TaskWeaver/tree/main/website/docs/advanced/plugin_selection.md",tags:[],version:"current",frontMatter:{},sidebar:"documentSidebar",previous:{title:"Prompt Compression",permalink:"/TaskWeaver/docs/advanced/compression"},next:{title:"Code Verification",permalink:"/TaskWeaver/docs/advanced/code_verification"}},l={},c=[{value:"Auto Plugin Selection Overview",id:"auto-plugin-selection-overview",level:2},{value:"Auto Plugin Selection Configuration",id:"auto-plugin-selection-configuration",level:2},{value:"Auto Plugin Selection Preparation",id:"auto-plugin-selection-preparation",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,s.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"auto-plugin-selection",children:"Auto Plugin Selection"}),"\n",(0,i.jsx)(n.p,{children:"In TaskWeaver, we provide an auto plugin selection mechanism to dynamically select the best plugin for each user request.\nIt targets to solve the following two problems:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsx)(n.li,{children:"An excessive number of plugins may cause confusion for LLM, leading to inaccuracies in generating the correct code."}),"\n",(0,i.jsx)(n.li,{children:"A large number of plugins could lead to increased token usage (potentially exceeding the token limit of LLM) and extended response time."}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"auto-plugin-selection-overview",children:"Auto Plugin Selection Overview"}),"\n",(0,i.jsxs)(n.p,{children:["Below is the overview workflow of the auto plugin selection mechanism.\n",(0,i.jsx)(n.img,{alt:"Auto Plugin Selection Overview",src:t(802).Z+"",width:"1846",height:"543"})]}),"\n",(0,i.jsx)(n.admonition,{type:"info",children:(0,i.jsx)(n.p,{children:"Automatic plugin selection mechanism is only activated during the code generation process in the Code Interpreter and does not affect the planning process of the Planner."})}),"\n",(0,i.jsxs)(n.p,{children:["At the start of TaskWeaver initialization, the automatic plugin selector is activated to generate embedding vectors for all plugins, including their names and descriptions.\nThe embedding vectors are created using the specified embedding model configured in the ",(0,i.jsx)(n.code,{children:"taskweaver_config.json"})," file.\nFor more information, please refer to the ",(0,i.jsx)(n.a,{href:"/TaskWeaver/docs/configurations/configurations_in_detail",children:"embedding"})," section in documentation."]}),"\n",(0,i.jsxs)(n.p,{children:["When the Planner sends a request to the Code Interpreter, the auto plugin selection mechanism will be triggered.\nIt will first generate an embedding vector for the request using the same embedding model.\nThen, it will calculate the cosine similarity between the request embedding vector and the embedding vectors of all plugins.\nIt will select the top-k plugins with the highest cosine similarity scores and load them into the ",(0,i.jsx)(n.code,{children:"code_generator"})," prompt."]}),"\n",(0,i.jsxs)(n.p,{children:["Upon completing the code generation, the ",(0,i.jsx)(n.code,{children:"code_generator"})," employs one or more plugins to produce the desired code.\nWe have established a plugin pool to store the plugins involved in the code generation process while filtering out any unused ones.\nDuring the subsequent automatic plugin selection phase, newly chosen plugins are appended to the existing ones."]}),"\n",(0,i.jsx)(n.h2,{id:"auto-plugin-selection-configuration",children:"Auto Plugin Selection Configuration"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"code_generator.enable_auto_plugin_selection"}),": Whether to enable auto plugin selection. The default value is ",(0,i.jsx)(n.code,{children:"false"}),"."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"code_generator.auto_plugin_selection_topk"}),":\tThe number of auto selected plugins in each round. The default value is ",(0,i.jsx)(n.code,{children:"3"}),"."]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"auto-plugin-selection-preparation",children:"Auto Plugin Selection Preparation"}),"\n",(0,i.jsx)(n.p,{children:"Before using the auto plugin selection mechanism, we need to run the following command to generate the plugin meta files with embeddings."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"cd scripts\npython -m plugin_mgt --refresh\n"})}),"\n",(0,i.jsxs)(n.p,{children:["After that, you can find the ",(0,i.jsx)(n.code,{children:".meta"})," directory is generated in the ",(0,i.jsx)(n.code,{children:"plugins"})," folder.\nThen you can start a new TaskWeaver session with the auto plugin selection mechanism enabled.\nCode Generator will automatically load the plugin meta files with embeddings."]}),"\n",(0,i.jsx)(n.p,{children:"\ud83c\udf88Plugin meta files will be treated as invalid if:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"The plugin embedding vector is not generated."}),"\n",(0,i.jsx)(n.li,{children:"The plugin is modified."}),"\n",(0,i.jsx)(n.li,{children:"The plugin embedding model is changed."}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"In this case, you cannot start the TaskWeaver and you need to run the above command again to refresh the plugin meta files."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"\n## Auto Plugin Selection Example\n\nWe show the auto plugin selection mechanism in the following example.\n\nFirst, we start TaskWeaver with the auto plugin selection mechanism enabled.\n```bash\n=========================================================\n _____ _ _ __\n|_ _|_ _ ___| | _ | | / /__ ____ __ _____ _____\n | |/ _` / __| |/ /| | /| / / _ \\/ __ `/ | / / _ \\/ ___/\n | | (_| \\__ \\ < | |/ |/ / __/ /_/ /| |/ / __/ /\n |_|\\__,_|___/_|\\_\\|__/|__/\\___/\\__,_/ |___/\\___/_/\n=========================================================\nTaskWeaver: I am TaskWeaver, an AI assistant. To get started, could you please enter your request?\nHuman: \n"})}),"\n",(0,i.jsxs)(n.p,{children:["Then we can check the log file ",(0,i.jsx)(n.code,{children:"task_weaver.log"})," in the ",(0,i.jsx)(n.code,{children:"logs"})," folder to see the auto plugin selector is initialized successfully because the ",(0,i.jsx)(n.code,{children:"Plugin embeddings generated"})," message is printed."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"2023-12-18 14:23:44,197 - INFO - Planner initialized successfully\n2023-12-18 14:24:10,488 - INFO - Plugin embeddings generated\n2023-12-18 14:24:10,490 - INFO - CodeInterpreter initialized successfully.\n2023-12-18 14:24:10,490 - INFO - Session 20231218-062343-c18494b1 is initialized\n"})}),"\n",(0,i.jsx)(n.p,{children:'We ask TaskWeaver to "search Xbox price for me".\nThe Planner instructs the Code Interpreter to search Xbox price.'}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"TaskWeaver: I am TaskWeaver, an AI assistant. To get started, could you please enter your request?\nHuman: search xbox price for me\n>>> [INIT_PLAN]\n1. search xbox price\n2. report the result to the user \n>>> [PLAN]\n1. instruct CodeInterpreter to search xbox price\n2. report the result to the user\n>>> [CURRENT_PLAN_STEP]\n1. instruct CodeInterpreter to search xbox price\n>>> [SEND_TO]\nCodeInterpreter\n>>> [MESSAGE]\nPlease search xbox price\n>>> [PLANNER->CODEINTERPRETER]\nPlease search xbox price\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Back to the Code Interpreter, the auto plugin selection mechanism is triggered.\nWe can check the log file ",(0,i.jsx)(n.code,{children:"task_weaver.log"})," again to see the auto plugin selector selected the top-3 plugins with the highest cosine similarity scores."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"023-12-18 14:24:34,513 - INFO - Planner talk to CodeInterpreter: Please search xbox price using klarna_search plugin\n2023-12-18 14:24:34,669 - INFO - Selected plugins: ['klarna_search', 'sql_pull_data', 'paper_summary']\n2023-12-18 14:24:34,669 - INFO - Selected plugin pool: ['klarna_search', 'sql_pull_data', 'paper_summary']\n"})}),"\n",(0,i.jsx)(n.p,{children:"Then the Code Interpreter will generate the code using the selected plugins."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:">>> [THOUGHT]\nProgramApe will call the klarna_search plugin function to search for Xbox prices.\n>>> [PYTHON]\nsearch_results, description = klarna_search(query=\"xbox\")\nsearch_results, description\n>>> [VERIFICATION]\nNONE\n>>> [STATUS]\nSUCCESS\n>>> [RESULT]\nThe execution of the generated python code above has succeeded\n\nThe result of above Python code after execution is:\n( name price url attributes\n 0 Microsoft Xbox Series X - Black Edition $399.00 https://www.klarna.com/us/shopping/pl/cl52/495... [Release Year:2020, Included Accessories:1 gam...\n 1 Microsoft Xbox Series S 1TB - Black $349.00 https://www.klarna.com/us/shopping/pl/cl52/320... [Included Accessories:1 gamepad, Media Type:DV...\n .. ... ... ... ...\n 3 Xbox Series S \u2013 Starter Bundle $239.00 https://www.klarna.com/us/shopping/pl/cl52/320... [Platform:Xbox One]\n 4 Microsoft Xbox Series X 1TB Console - Diablo I... $385.58 https://www.klarna.com/us/shopping/pl/cl52/320... [Release Year:2023, Included Accessories:1 gam...\n\n [5 rows x 4 columns],\n 'The response is a dataframe with the following columns: name, price, url, attributes. The attributes column is a list of tags. The price is in the format of $xx.xx.')\n>>> [CODEINTERPRETER->PLANNER]\nThe following python code has been executed:\n```python\nsearch_results, description = klarna_search(query=\"xbox\")\nsearch_results, description\n```\n\nThe execution of the generated python code above has succeeded\n\nThe result of above Python code after execution is:\n( name price url attributes\n 0 Microsoft Xbox Series X - Black Edition $399.00 https://www.klarna.com/us/shopping/pl/cl52/495... [Release Year:2020, Included Accessories:1 gam...\n 1 Microsoft Xbox Series S 1TB - Black $349.00 https://www.klarna.com/us/shopping/pl/cl52/320... [Included Accessories:1 gamepad, Media Type:DV...\n .. ... ... ... ...\n 3 Xbox Series S \u2013 Starter Bundle $239.00 https://www.klarna.com/us/shopping/pl/cl52/320... [Platform:Xbox One]\n 4 Microsoft Xbox Series X 1TB Console - Diablo I... $385.58 https://www.klarna.com/us/shopping/pl/cl52/320... [Release Year:2023, Included Accessories:1 gam...\n\n [5 rows x 4 columns],\n 'The response is a dataframe with the following columns: name, price, url, attributes. The attributes column is a list of tags. The price is in the format of $xx.xx.')\n"})}),"\n",(0,i.jsx)(n.p,{children:"Finally, the Planner will report the result to the user."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:">>> [INIT_PLAN]\n1. search xbox price using klarna_search plugin\n2. report the result to the user \n>>> [PLAN]\n1. instruct CodeInterpreter to search xbox price using klarna_search plugin\n2. report the result to the user\n>>> [CURRENT_PLAN_STEP]\n2. report the result to the user\n>>> [SEND_TO]\nUser\n>>> [MESSAGE]\nHere are some Xbox prices I found:\n\n1. Microsoft Xbox Series X - Black Edition: $399.00\n2. Microsoft Xbox Series S 1TB - Black: $349.00\n3. Xbox Series S \u2013 Starter Bundle: $239.00\n4. Microsoft Xbox Series X 1TB Console - Diablo Immortal Edition: $385.58\n\nPlease note that these prices are subject to change and availability.\n>>> [PLANNER->USER]\nHere are some Xbox prices I found:\n\n1. Microsoft Xbox Series X - Black Edition: $399.00\n2. Microsoft Xbox Series S 1TB - Black: $349.00\n3. Xbox Series S \u2013 Starter Bundle: $239.00\n4. Microsoft Xbox Series X 1TB Console - Diablo Immortal Edition: $385.58\n\nPlease note that these prices are subject to change and availability.\nTaskWeaver: Here are some Xbox prices I found:\n\n1. Microsoft Xbox Series X - Black Edition: $399.00\n2. Microsoft Xbox Series S 1TB - Black: $349.00\n3. Xbox Series S \u2013 Starter Bundle: $239.00\n4. Microsoft Xbox Series X 1TB Console - Diablo Immortal Edition: $385.58\n\nPlease note that these prices are subject to change and availability.\n"})})]})}function u(e={}){const{wrapper:n}={...(0,s.a)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},802:(e,n,t)=>{t.d(n,{Z:()=>i});const i=t.p+"assets/images/APS-1dc4d286038dedc17487146cec8214fd.png"},1151:(e,n,t)=>{t.d(n,{Z:()=>a,a:()=>r});var i=t(7294);const s={},o=i.createContext(s);function r(e){const n=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),i.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a55bc7d4.a4e23676.js b/assets/js/a55bc7d4.a4e23676.js new file mode 100644 index 00000000..b769687e --- /dev/null +++ b/assets/js/a55bc7d4.a4e23676.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[4398],{9270:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>a,contentTitle:()=>i,default:()=>p,frontMatter:()=>r,metadata:()=>l,toc:()=>c});var s=o(5893),t=o(1151);const r={description:"Using LLMs from OpenAI"},i="OpenAI",l={id:"llms/openai",title:"OpenAI",description:"Using LLMs from OpenAI",source:"@site/docs/llms/openai.md",sourceDirName:"llms",slug:"/llms/openai",permalink:"/TaskWeaver/docs/llms/openai",draft:!1,unlisted:!1,editUrl:"https://github.com/microsoft/TaskWeaver/tree/main/website/docs/llms/openai.md",tags:[],version:"current",frontMatter:{description:"Using LLMs from OpenAI"},sidebar:"documentSidebar",previous:{title:"Supported LLMs",permalink:"/TaskWeaver/docs/llms"},next:{title:"Azure OpenAI",permalink:"/TaskWeaver/docs/llms/aoai"}},a={},c=[];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",li:"li",ol:"ol",p:"p",pre:"pre",...(0,t.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"openai",children:"OpenAI"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["Create an account on ",(0,s.jsx)(n.a,{href:"https://beta.openai.com/",children:"OpenAI"})," and get your ",(0,s.jsx)(n.a,{href:"https://platform.openai.com/api-keys",children:"API key"}),"."]}),"\n",(0,s.jsxs)(n.li,{children:["Add the following to your ",(0,s.jsx)(n.code,{children:"taskweaver_config.json"})," file:"]}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",metastring:"showLineNumbers",children:'{\n "llm.api_type":"openai",\n "llm.api_base": "https://api.openai.com/v1",\n "llm.api_key": "YOUR_API_KEY",\n "llm.model": "gpt-4",\n "llm.response_format": "json_object"\n}\n'})}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"llm.model"})," is the model name you want to use.\nYou can find the list of models ",(0,s.jsx)(n.a,{href:"https://platform.openai.com/docs/models",children:"here"}),"."]})}),"\n",(0,s.jsx)(n.admonition,{type:"info",children:(0,s.jsxs)(n.p,{children:["For model versions equal or after ",(0,s.jsx)(n.code,{children:"1106"}),", ",(0,s.jsx)(n.code,{children:"llm.response_format"})," can be set to ",(0,s.jsx)(n.code,{children:"json_object"}),".\nHowever, for the earlier models which do not support JSON response explicitly, ",(0,s.jsx)(n.code,{children:"llm.response_format"})," should be set to ",(0,s.jsx)(n.code,{children:"null"}),"."]})}),"\n",(0,s.jsxs)(n.ol,{start:"3",children:["\n",(0,s.jsxs)(n.li,{children:["Start TaskWeaver and chat with TaskWeaver.\nYou can refer to the ",(0,s.jsx)(n.a,{href:"/TaskWeaver/docs/quickstart",children:"Quick Start"})," for more details."]}),"\n"]})]})}function p(e={}){const{wrapper:n}={...(0,t.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},1151:(e,n,o)=>{o.d(n,{Z:()=>l,a:()=>i});var s=o(7294);const t={},r=s.createContext(t);function i(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:i(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a55bc7d4.c8bad8d7.js b/assets/js/a55bc7d4.c8bad8d7.js deleted file mode 100644 index a711d865..00000000 --- a/assets/js/a55bc7d4.c8bad8d7.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[4398],{9270:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>a,contentTitle:()=>i,default:()=>p,frontMatter:()=>r,metadata:()=>l,toc:()=>c});var t=o(5893),s=o(1151);const r={description:"Using LLMs from OpenAI"},i="OpenAI",l={id:"llms/openai",title:"OpenAI",description:"Using LLMs from OpenAI",source:"@site/docs/llms/openai.md",sourceDirName:"llms",slug:"/llms/openai",permalink:"/TaskWeaver/docs/llms/openai",draft:!1,unlisted:!1,editUrl:"https://github.com/microsoft/TaskWeaver/tree/main/website/docs/llms/openai.md",tags:[],version:"current",frontMatter:{description:"Using LLMs from OpenAI"},sidebar:"documentSidebar",previous:{title:"Supported LLMs",permalink:"/TaskWeaver/docs/llms"},next:{title:"Azure OpenAI",permalink:"/TaskWeaver/docs/llms/aoai"}},a={},c=[];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",li:"li",ol:"ol",p:"p",pre:"pre",...(0,s.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"openai",children:"OpenAI"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["Create an account on ",(0,t.jsx)(n.a,{href:"https://beta.openai.com/",children:"OpenAI"})," and get your ",(0,t.jsx)(n.a,{href:"https://platform.openai.com/api-keys",children:"API key"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:["Add the following to your ",(0,t.jsx)(n.code,{children:"taskweaver_config.json"})," file:"]}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",metastring:"showLineNumbers",children:'{\n "llm.api_type":"openai",\n "llm.api_base": "https://api.openai.com/v1",\n "llm.api_key": "YOUR_API_KEY",\n "llm.model": "gpt-4-1106-preview",\n "llm.response_format": "json_object"\n}\n'})}),"\n",(0,t.jsx)(n.admonition,{type:"tip",children:(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"llm.model"})," is the model name you want to use.\nYou can find the list of models ",(0,t.jsx)(n.a,{href:"https://platform.openai.com/docs/models",children:"here"}),"."]})}),"\n",(0,t.jsx)(n.admonition,{type:"info",children:(0,t.jsxs)(n.p,{children:["For ",(0,t.jsx)(n.code,{children:"gpt-4-1106-preview"})," and ",(0,t.jsx)(n.code,{children:"gpt-3.5-turbo-1106"}),", ",(0,t.jsx)(n.code,{children:"llm.response_format"})," can be set to ",(0,t.jsx)(n.code,{children:"json_object"}),".\nHowever, for the earlier models which do not support JSON response explicitly, ",(0,t.jsx)(n.code,{children:"llm.response_format"})," should be set to ",(0,t.jsx)(n.code,{children:"null"}),"."]})}),"\n",(0,t.jsxs)(n.ol,{start:"3",children:["\n",(0,t.jsxs)(n.li,{children:["Start TaskWeaver and chat with TaskWeaver.\nYou can refer to the ",(0,t.jsx)(n.a,{href:"/TaskWeaver/docs/quickstart",children:"Quick Start"})," for more details."]}),"\n"]})]})}function p(e={}){const{wrapper:n}={...(0,s.a)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},1151:(e,n,o)=>{o.d(n,{Z:()=>l,a:()=>i});var t=o(7294);const s={},r=t.createContext(s);function i(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ad895e75.9817abea.js b/assets/js/ad895e75.9817abea.js new file mode 100644 index 00000000..a0bbdfb3 --- /dev/null +++ b/assets/js/ad895e75.9817abea.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[4288],{1469:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>s,metadata:()=>r,toc:()=>c});var o=t(5893),i=t(1151);const s={},a="FAQ",r={id:"FAQ",title:"FAQ",description:"Q: Why it takes so long to generate the output?",source:"@site/docs/FAQ.md",sourceDirName:".",slug:"/FAQ",permalink:"/TaskWeaver/docs/FAQ",draft:!1,unlisted:!1,editUrl:"https://github.com/microsoft/TaskWeaver/tree/main/website/docs/FAQ.md",tags:[],version:"current",frontMatter:{},sidebar:"documentSidebar",previous:{title:"Code Execution",permalink:"/TaskWeaver/docs/code_execution"},next:{title:"Usage Options",permalink:"/TaskWeaver/docs/usage"}},l={},c=[{value:"Q: Why it takes so long to generate the output?",id:"q-why-it-takes-so-long-to-generate-the-output",level:3},{value:"Q: Why TaskWeaver fails and the logs say "Failed to connect to docker.daemon"?",id:"q-why-taskweaver-fails-and-the-logs-say-failed-to-connect-to-dockerdaemon",level:3},{value:"Q: Why I see errors saying the Planner failed to generate the send_to, message or other fields?",id:"q-why-i-see-errors-saying-the-planner-failed-to-generate-the-send_to-message-or-other-fields",level:3},{value:"Q: How do I know if TaskWeaver can see my plugin?",id:"q-how-do-i-know-if-taskweaver-can-see-my-plugin",level:3},{value:"Q: Why TaskWeaver cannot see my plugin?",id:"q-why-taskweaver-cannot-see-my-plugin",level:3},{value:"Q: Why TaskWeaver can see my plugin but cannot call it?",id:"q-why-taskweaver-can-see-my-plugin-but-cannot-call-it",level:3},{value:"Q: How to debug my plugin?",id:"q-how-to-debug-my-plugin",level:3},{value:"Q: Why I see the error message "RuntimeError: This event loop is already running"?",id:"q-why-i-see-the-error-message-runtimeerror-this-event-loop-is-already-running",level:3}];function h(e){const n={a:"a",code:"code",h1:"h1",h3:"h3",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,i.a)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h1,{id:"faq",children:"FAQ"}),"\n",(0,o.jsx)(n.h3,{id:"q-why-it-takes-so-long-to-generate-the-output",children:"Q: Why it takes so long to generate the output?"}),"\n",(0,o.jsx)(n.p,{children:"A: In the default setting, TaskWeaver typically goes through the following steps to generate the output:"}),"\n",(0,o.jsxs)(n.ol,{children:["\n",(0,o.jsx)(n.li,{children:"The User sends a query to the Planner."}),"\n",(0,o.jsx)(n.li,{children:"The Planner generates a plan based on the query and sends the plan to the CodeInterpreter."}),"\n",(0,o.jsx)(n.li,{children:"The CodeInterpreter executes the plan and sends the execution result back to the Planner."}),"\n",(0,o.jsx)(n.li,{children:"The Planner summarizes the execution result and sends the summary to the User."}),"\n",(0,o.jsx)(n.li,{children:"The User receives the summary from the Planner."}),"\n"]}),"\n",(0,o.jsx)(n.p,{children:"In some cases, the Planer and CodeInterpreter can go back and forth multiple times to generate the output.\nThis process can take a long time, mostly due to the latency of calling the LLMs.\nTo speed up the process, you can try the following:"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:"Use a smaller LLM model, such as GPT-3.5 instead of GPT-4. However, you need to experiment with your use case to see if the smaller model can still generate the output correctly."}),"\n",(0,o.jsx)(n.li,{children:"Use the CodeInterpreter only mode, which skips the Planner and generates the code directly from the User query. This mode is faster because it skips the planning step.\nHowever, you should check if your use case needs the planning step."}),"\n"]}),"\n",(0,o.jsx)(n.h3,{id:"q-why-taskweaver-fails-and-the-logs-say-failed-to-connect-to-dockerdaemon",children:'Q: Why TaskWeaver fails and the logs say "Failed to connect to docker.daemon"?'}),"\n",(0,o.jsxs)(n.p,{children:["A: This error typically happens when TaskWeaver is running in the ",(0,o.jsx)(n.code,{children:"container"})," mode and cannot connect to the Docker daemon.\nWe have switched to the ",(0,o.jsx)(n.code,{children:"container"})," mode by default to provide a more secure environment for code execution.\nTo opt out of the ",(0,o.jsx)(n.code,{children:"container"})," mode, you can set the ",(0,o.jsx)(n.code,{children:"execution_service.kernel_mode"})," parameter to ",(0,o.jsx)(n.code,{children:"local"})," in the ",(0,o.jsx)(n.code,{children:"taskweaver_config.json"})," file.\nHowever, you should be aware that TaskWeaver can interact with the host machine directly in the ",(0,o.jsx)(n.code,{children:"local"})," mode, which may have security risks."]}),"\n",(0,o.jsxs)(n.h3,{id:"q-why-i-see-errors-saying-the-planner-failed-to-generate-the-send_to-message-or-other-fields",children:["Q: Why I see errors saying the Planner failed to generate the ",(0,o.jsx)(n.code,{children:"send_to"}),", ",(0,o.jsx)(n.code,{children:"message"})," or other fields?"]}),"\n",(0,o.jsxs)(n.p,{children:["A: This is typically due to that the LLM failed to generate its output follow our schema. In Planner's prompt,\nwe asked the LLM to generate a JSON object that contains ",(0,o.jsx)(n.code,{children:"send_to"}),", ",(0,o.jsx)(n.code,{children:"message"}),", ",(0,o.jsx)(n.code,{children:"init_plan"}),", ",(0,o.jsx)(n.code,{children:"plan"}),", and ",(0,o.jsx)(n.code,{children:"current_plan_step"}),".\nMissing any of these fields will cause the parsing error.\nThe most effective way to mitigate this issue is to use switch to more powerful LLM model, such as GPT-3.5 or GPT-4."]}),"\n",(0,o.jsx)(n.h3,{id:"q-how-do-i-know-if-taskweaver-can-see-my-plugin",children:"Q: How do I know if TaskWeaver can see my plugin?"}),"\n",(0,o.jsx)(n.p,{children:'A: A simple way to check if TaskWeaver can see your plugin is to ask "What can you do?" to TaskWeaver.\nThe typical response is to list all the available plugins like the following:'}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-markdown",children:"I can assist you with various tasks, including:\n\n- Detecting anomalies in time series data.\n- Rendering text into ASCII art.\n- Searching and comparing prices from thousands of online shops (US only).\n- Telling a joke.\n\nIf you have a specific task in mind, please let me know, and I'll do my best to assist you.\n"})}),"\n",(0,o.jsxs)(n.p,{children:["If you see your plugin in the list, it means TaskWeaver can see your plugin.\nBut this is not a reliable way to check if TaskWeaver can see your plugin because the response is generated by the LLM.\nA more reliable way is to check the prompt of the Planner. You can find the prompts\nfrom ",(0,o.jsx)(n.code,{children:"project/workspace/sessions//planner_prompt_log_xxxx.yaml"}),".\nThen, search for this section as follows:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-markdown",children:'CodeInterpreter has the following plugin functions and their required parameters need to be provided before the execution:\n- anomaly_detection: anomaly_detection function identifies anomalies from an input DataFrame of time series. It will add a new column \\"Is_Anomaly\\", where each entry will be marked with \\"True\\" if the value is an anomaly or \\"False\\" otherwise. Arguments required: df: DataFrame, time_col_name: str, value_col_name: str\n- ascii_render: This plugin renders the input text into ASCII art form. Arguments required: text: str\n- klarna_search: Search and compare prices from thousands of online shops. Only available in the US. This plugin only takes user requests when searching for merchandise. If not clear, confirm with the user if they want to search for merchandise from Klarna. Arguments required: query: str\n- tell_joke: Call this plugin to tell a joke.\n'})}),"\n",(0,o.jsx)(n.p,{children:"Check if your plugin is in the list. If it is, it means TaskWeaver can see your plugin."}),"\n",(0,o.jsx)(n.h3,{id:"q-why-taskweaver-cannot-see-my-plugin",children:"Q: Why TaskWeaver cannot see my plugin?"}),"\n",(0,o.jsxs)(n.p,{children:["First, make sure you have read our ",(0,o.jsx)(n.a,{href:"https://microsoft.github.io/TaskWeaver/docs/plugin/plugin_intro",children:"Plugin Introduction"})," and this tutorial carefully.\nYou should have two files in the ",(0,o.jsx)(n.code,{children:"plugins"})," folder, e.g., ",(0,o.jsx)(n.code,{children:"ascii_render.py"})," and ",(0,o.jsx)(n.code,{children:"ascii_render.yaml"}),"."]}),"\n",(0,o.jsx)(n.p,{children:"Now, if TaskWeaver cannot see your plugin, the root cause is typically syntax errors in the yaml file.\nCheck the console output if you are using the command line interface, or the console logs if you are using the web interface.\nYou may see the following error message:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"failed to loading component from .yaml, skipping: Yaml loading failed due to: \n"})}),"\n",(0,o.jsx)(n.p,{children:"The error message will tell you the reason why the yaml file cannot be loaded.\nIt is typically easy to fix the syntax errors by using a yaml linter (e.g., in Visual Studio Code) or an online yaml linter."}),"\n",(0,o.jsxs)(n.p,{children:["If you have checked the syntax of the yaml file and TaskWeaver still cannot see your plugin, please check\nif the yaml file has included all the required fields such as the ",(0,o.jsx)(n.code,{children:"parameters"})," and ",(0,o.jsx)(n.code,{children:"returns"})," fields."]}),"\n",(0,o.jsx)(n.h3,{id:"q-why-taskweaver-can-see-my-plugin-but-cannot-call-it",children:"Q: Why TaskWeaver can see my plugin but cannot call it?"}),"\n",(0,o.jsx)(n.p,{children:"A: In this case, you may see the generated code has called the plugin function,\nbut the execution result is an error message saying that the plugin function is undefined.\nIf this happens, please check the console output if you are using the command line interface,\nor the console logs if you are using the web interface."}),"\n",(0,o.jsx)(n.p,{children:"You may see the following error message:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"Plugin failed to load: Plugin failed to register: failed to load plugin \n"})}),"\n",(0,o.jsx)(n.p,{children:"This error message will tell you the reason why the plugin function cannot be loaded.\nIt is typically easy to fix the errors by checking the console output or logs.\nThe root cause is typically errors in the python file that causes the plugin function cannot be loaded.\nTypical errors include syntax errors, missing imports, or missing packages."}),"\n",(0,o.jsx)(n.p,{children:'Note that this sort of error is not caused by the implementation "inside" the plugin function.\nOtherwise, the errors would be caught during the execution of the plugin function,\nnot during the loading of the plugin function.'}),"\n",(0,o.jsx)(n.h3,{id:"q-how-to-debug-my-plugin",children:"Q: How to debug my plugin?"}),"\n",(0,o.jsxs)(n.p,{children:["A: We are working on a debugging tool to help you debug your plugin. For now, a simple way to debug your plugin is to\ndefine a main function in the python file and run it in your local environment.\nFor example, you can define a main function in ",(0,o.jsx)(n.code,{children:"ascii_render.py"})," as follows:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-python",children:'if __name__ == "__main__":\n from taskweaver.plugin.context import temp_context\n\n with temp_context() as temp_ctx:\n render = AsciiRenderPlugin(name="ascii_render", ctx=temp_ctx, config={})\n print(render(text="hello world!"))\n'})}),"\n",(0,o.jsx)(n.p,{children:"In this main function, we create a temporary context and call the plugin function with some input.\nYou need not change the plugin implementation. Just add the main function to the end of the python file.\nThen, run the python file in your local environment. If there are any errors, you can see them in the console output."}),"\n",(0,o.jsxs)(n.p,{children:["If you have the ",(0,o.jsx)(n.code,{children:"configurations"})," section in the yaml file, you can manually set the configurations in the ",(0,o.jsx)(n.code,{children:"config"})," parameter of the plugin constructor.\nWe currently do not read the yaml file, so you need to make sure that the configurations are set correctly in the ",(0,o.jsx)(n.code,{children:"config"})," parameter.\nFor example, if an integer configuration ",(0,o.jsx)(n.code,{children:"max_length"})," is defined in the yaml file, you can set it in the ",(0,o.jsx)(n.code,{children:"config"})," parameter as follows:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-python",children:'config = {\n "max_length": 100\n}\n'})}),"\n",(0,o.jsxs)(n.p,{children:["Then, pass the ",(0,o.jsx)(n.code,{children:"config"})," to the plugin constructor. As yaml is type sensitive, you need to make sure that the type of the configuration is correct."]}),"\n",(0,o.jsx)(n.h3,{id:"q-why-i-see-the-error-message-runtimeerror-this-event-loop-is-already-running",children:'Q: Why I see the error message "RuntimeError: This event loop is already running"?'}),"\n",(0,o.jsx)(n.p,{children:'A: We use a Jupyter Kernel to execute the code in TaskWeaver. The Jupyter Kernel uses an event loop to manage the execution of the code.\nIf you see the error message "RuntimeError: This event loop is already running.", it typically means that the event loop is already running.\nThis is typically caused by the enviroment where TaskWeaver is running. For example, if you are running TaskWeaver in a Jupyter Notebook.'})]})}function d(e={}){const{wrapper:n}={...(0,i.a)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(h,{...e})}):h(e)}},1151:(e,n,t)=>{t.d(n,{Z:()=>r,a:()=>a});var o=t(7294);const i={},s=o.createContext(i);function a(e){const n=o.useContext(s);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),o.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ad895e75.dcf975bf.js b/assets/js/ad895e75.dcf975bf.js deleted file mode 100644 index 9f1f188e..00000000 --- a/assets/js/ad895e75.dcf975bf.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[4288],{1469:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>s,metadata:()=>r,toc:()=>c});var i=t(5893),o=t(1151);const s={},a="FAQ",r={id:"FAQ",title:"FAQ",description:"Q: How do I know if TaskWeaver can see my plugin?",source:"@site/docs/FAQ.md",sourceDirName:".",slug:"/FAQ",permalink:"/TaskWeaver/docs/FAQ",draft:!1,unlisted:!1,editUrl:"https://github.com/microsoft/TaskWeaver/tree/main/website/docs/FAQ.md",tags:[],version:"current",frontMatter:{},sidebar:"documentSidebar",previous:{title:"Telemetry",permalink:"/TaskWeaver/docs/advanced/telemetry"}},l={},c=[];function h(e){const n={a:"a",code:"code",h1:"h1",p:"p",pre:"pre",strong:"strong",...(0,o.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"faq",children:"FAQ"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Q: How do I know if TaskWeaver can see my plugin?"})}),"\n",(0,i.jsx)(n.p,{children:'A: A simple way to check if TaskWeaver can see your plugin is to ask "What can you do?" to TaskWeaver.\nThe typical response is to list all the available plugins like the following:'}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-markdown",children:"I can assist you with various tasks, including:\n\n- Detecting anomalies in time series data.\n- Rendering text into ASCII art.\n- Searching and comparing prices from thousands of online shops (US only).\n- Telling a joke.\n\nIf you have a specific task in mind, please let me know, and I'll do my best to assist you.\n"})}),"\n",(0,i.jsxs)(n.p,{children:["If you see your plugin in the list, it means TaskWeaver can see your plugin.\nBut this is not a reliable way to check if TaskWeaver can see your plugin because the response is generated by the LLM.\nA more reliable way is to check the prompt of the Planner. You can find the prompts\nfrom ",(0,i.jsx)(n.code,{children:"project/workspace/sessions//planner_prompt_log_xxxx.yaml"}),".\nThen, search for this section as follows:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-markdown",children:'CodeInterpreter has the following plugin functions and their required parameters need to be provided before the execution:\n- anomaly_detection: anomaly_detection function identifies anomalies from an input DataFrame of time series. It will add a new column \\"Is_Anomaly\\", where each entry will be marked with \\"True\\" if the value is an anomaly or \\"False\\" otherwise. Arguments required: df: DataFrame, time_col_name: str, value_col_name: str\n- ascii_render: This plugin renders the input text into ASCII art form. Arguments required: text: str\n- klarna_search: Search and compare prices from thousands of online shops. Only available in the US. This plugin only takes user requests when searching for merchandise. If not clear, confirm with the user if they want to search for merchandise from Klarna. Arguments required: query: str\n- tell_joke: Call this plugin to tell a joke.\n'})}),"\n",(0,i.jsx)(n.p,{children:"Check if your plugin is in the list. If it is, it means TaskWeaver can see your plugin."}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Q: Why TaskWeaver cannot see my plugin?"})}),"\n",(0,i.jsxs)(n.p,{children:["First, make sure you have read our ",(0,i.jsx)(n.a,{href:"https://microsoft.github.io/TaskWeaver/docs/plugin/plugin_intro",children:"Plugin Introduction"})," and this tutorial carefully.\nYou should have two files in the ",(0,i.jsx)(n.code,{children:"plugins"})," folder, e.g., ",(0,i.jsx)(n.code,{children:"ascii_render.py"})," and ",(0,i.jsx)(n.code,{children:"ascii_render.yaml"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"Now, if TaskWeaver cannot see your plugin, the root cause is typically syntax errors in the yaml file.\nCheck the console output if you are using the command line interface, or the console logs if you are using the web interface.\nYou may see the following error message:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"failed to loading component from .yaml, skipping: Yaml loading failed due to: \n"})}),"\n",(0,i.jsx)(n.p,{children:"The error message will tell you the reason why the yaml file cannot be loaded.\nIt is typically easy to fix the syntax errors by using a yaml linter (e.g., in Visual Studio Code) or an online yaml linter."}),"\n",(0,i.jsxs)(n.p,{children:["If you have checked the syntax of the yaml file and TaskWeaver still cannot see your plugin, please check\nif the yaml file has included all the required fields such as the ",(0,i.jsx)(n.code,{children:"parameters"})," and ",(0,i.jsx)(n.code,{children:"returns"})," fields."]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Q: Why TaskWeaver can see my plugin but cannot call it?"})}),"\n",(0,i.jsx)(n.p,{children:"A: In this case, you may see the generated code has called the plugin function,\nbut the execution result is an error message saying that the plugin function is undefined.\nIf this happens, please check the console output if you are using the command line interface,\nor the console logs if you are using the web interface."}),"\n",(0,i.jsx)(n.p,{children:"You may see the following error message:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"Plugin failed to load: Plugin failed to register: failed to load plugin \n"})}),"\n",(0,i.jsx)(n.p,{children:"This error message will tell you the reason why the plugin function cannot be loaded.\nIt is typically easy to fix the errors by checking the console output or logs.\nThe root cause is typically errors in the python file that causes the plugin function cannot be loaded.\nTypical errors include syntax errors, missing imports, or missing packages."}),"\n",(0,i.jsx)(n.p,{children:'Note that this sort of error is not caused by the implementation "inside" the plugin function.\nOtherwise, the errors would be caught during the execution of the plugin function,\nnot during the loading of the plugin function.'}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Q: How to debug my plugin?"})}),"\n",(0,i.jsxs)(n.p,{children:["A: We are working on a debugging tool to help you debug your plugin. For now, a simple way to debug your plugin is to\ndefine a main function in the python file and run it in your local environment.\nFor example, you can define a main function in ",(0,i.jsx)(n.code,{children:"ascii_render.py"})," as follows:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-python",children:'if __name__ == "__main__":\n from taskweaver.plugin.context import temp_context\n\n with temp_context() as temp_ctx:\n render = AsciiRenderPlugin(name="ascii_render", ctx=temp_ctx, config={})\n print(render(text="hello world!"))\n'})}),"\n",(0,i.jsx)(n.p,{children:"In this main function, we create a temporary context and call the plugin function with some input.\nYou need not change the plugin implementation. Just add the main function to the end of the python file.\nThen, run the python file in your local environment. If there are any errors, you can see them in the console output."}),"\n",(0,i.jsxs)(n.p,{children:["If you have the ",(0,i.jsx)(n.code,{children:"configurations"})," section in the yaml file, you can manually set the configurations in the ",(0,i.jsx)(n.code,{children:"config"})," parameter of the plugin constructor.\nWe currently do not read the yaml file, so you need to make sure that the configurations are set correctly in the ",(0,i.jsx)(n.code,{children:"config"})," parameter.\nFor example, if an integer configuration ",(0,i.jsx)(n.code,{children:"max_length"})," is defined in the yaml file, you can set it in the ",(0,i.jsx)(n.code,{children:"config"})," parameter as follows:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-python",children:'config = {\n "max_length": 100\n}\n'})}),"\n",(0,i.jsxs)(n.p,{children:["Then, pass the ",(0,i.jsx)(n.code,{children:"config"})," to the plugin constructor. As yaml is type sensitive, you need to make sure that the type of the configuration is correct."]})]})}function u(e={}){const{wrapper:n}={...(0,o.a)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(h,{...e})}):h(e)}},1151:(e,n,t)=>{t.d(n,{Z:()=>r,a:()=>a});var i=t(7294);const o={},s=i.createContext(o);function a(e){const n=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),i.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ae863774.2e480f9e.js b/assets/js/ae863774.2e480f9e.js deleted file mode 100644 index cf929c6e..00000000 --- a/assets/js/ae863774.2e480f9e.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5675],{2929:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>h,contentTitle:()=>o,default:()=>d,frontMatter:()=>r,metadata:()=>i,toc:()=>c});var s=n(5893),a=n(1151);const r={},o="Customizing Examples",i={id:"customization/example/example",title:"Customizing Examples",description:"There are two types of examples: (1) planning examples and (2) code interpreter examples.",source:"@site/docs/customization/example/example.md",sourceDirName:"customization/example",slug:"/customization/example/",permalink:"/TaskWeaver/docs/customization/example/",draft:!1,unlisted:!1,editUrl:"https://github.com/microsoft/TaskWeaver/tree/main/website/docs/customization/example/example.md",tags:[],version:"current",frontMatter:{},sidebar:"documentSidebar",previous:{title:"The Plugin-Only Mode",permalink:"/TaskWeaver/docs/plugin/plugin_only"},next:{title:"Experience",permalink:"/TaskWeaver/docs/customization/experience"}},h={},c=[{value:"Planning Examples",id:"planning-examples",level:2},{value:"Code Interpreter Examples",id:"code-interpreter-examples",level:2}];function l(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",li:"li",ol:"ol",p:"p",pre:"pre",...(0,a.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.h1,{id:"customizing-examples",children:"Customizing Examples"}),"\n",(0,s.jsx)(t.p,{children:"There are two types of examples: (1) planning examples and (2) code interpreter examples.\nPlanning examples are used to demonstrate how to use TaskWeaver to plan for a specific task.\nCode generation examples are used to demonstrate how to generate code or orchestrate plugins to perform a specific task."}),"\n",(0,s.jsx)(t.h2,{id:"planning-examples",children:"Planning Examples"}),"\n",(0,s.jsxs)(t.p,{children:["A planning example tells LLMs how to plan for a specific query from the user; talk to the code interpreter;\nreceive the execution result from the code interpreter; and summarize the execution result.\nBefore constructing the planning example, we strongly encourage you to go through the\n",(0,s.jsx)(t.a,{href:"https://github.com/microsoft/TaskWeaver/blob/main/taskweaver/planner/planner_prompt.yaml",children:"planner prompt"}),"."]}),"\n",(0,s.jsx)(t.p,{children:"The following is an example of a planning example which contains 4 posts.\nEach post contains a message, a sender, a receiver, and a list of attachments."}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsx)(t.li,{children:'The first post is sent from the user to the planner.\nThe message is "count the rows of /home/data.csv", which is the same as the user query.'}),"\n",(0,s.jsxs)(t.li,{children:['The second post is sent from the planner to the code interpreter.\nThe message is "Please load the data file /home/data.csv and count the rows of the loaded data".\nThe attachment list contains 3 attachments:',"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsx)(t.li,{children:"The first attachment is the initial plan, which is a markdown string."}),"\n",(0,s.jsx)(t.li,{children:"The second attachment is the plan, which is a markdown string."}),"\n",(0,s.jsx)(t.li,{children:"The third attachment is the current plan step, which is a markdown string."}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.li,{children:'The third post is sent from the code interpreter to the planner.\nThe message is "Load the data file /home/data.csv successfully and there are 100 rows in the data file".'}),"\n",(0,s.jsxs)(t.li,{children:['The fourth post is sent from the planner to the user.\nThe message is "The data file /home/data.csv is loaded and there are 100 rows in the data file".\nThe attachment list contains 3 attachments:',"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsx)(t.li,{children:"The first attachment is the initial plan, which is the same as the second attachment of the second post."}),"\n",(0,s.jsx)(t.li,{children:"The second attachment is the plan, which is the same as the third attachment of the second post."}),"\n",(0,s.jsx)(t.li,{children:"The third attachment is the current plan step, which is a markdown string."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"enabled: True\nrounds:\n - user_query: count the rows of /home/data.csv\n state: created\n post_list:\n - message: count the rows of /home/data.csv\n send_from: User\n send_to: Planner\n attachment_list:\n - message: Please load the data file /home/data.csv and count the rows of the loaded data\n send_from: Planner\n send_to: CodeInterpreter\n attachment_list:\n - type: init_plan\n content: |-\n 1. load the data file\n 2. count the rows of the loaded data \n 3. report the result to the user \n - type: plan\n content: |-\n 1. instruct CodeInterpreter to load the data file and count the rows of the loaded data\n 2. report the result to the user\n - type: current_plan_step\n content: 1. instruct CodeInterpreter to load the data file and count the rows of the loaded data\n - message: Load the data file /home/data.csv successfully and there are 100 rows in the data file\n send_from: CodeInterpreter\n send_to: Planner\n attachment_list:\n - message: The data file /home/data.csv is loaded and there are 100 rows in the data file\n send_from: Planner\n send_to: User\n attachment_list:\n - type: init_plan\n content: |-\n 1. load the data file\n 2. count the rows of the loaded data \n 3. report the result to the user \n - type: plan\n content: |-\n 1. instruct CodeInterpreter to load the data file and count the rows of the loaded data\n 2. report the result to the user\n - type: current_plan_step\n content: 2. report the result to the user\n"})}),"\n",(0,s.jsx)(t.h2,{id:"code-interpreter-examples",children:"Code Interpreter Examples"}),"\n",(0,s.jsxs)(t.p,{children:["A code interpreter example tells LLMs how to generate code or orchestrate plugins to perform a specific task.\nThe task is from the planner. Before constructing the code interpreter example, we strongly encourage you to\nread the ",(0,s.jsx)(t.a,{href:"https://github.com/microsoft/TaskWeaver/blob/main/taskweaver/code_interpreter/code_generator/code_generator_prompt.yaml",children:"code generator prompt"}),"."]}),"\n",(0,s.jsx)(t.p,{children:"The following is an example of a code interpreter example which contains 2 posts.\nEach post contains a message, a sender, a receiver, and a list of attachments."}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsx)(t.li,{children:'The first post is sent from the planner to the code interpreter.\nThe message is "Please read file /abc/def.txt".'}),"\n",(0,s.jsxs)(t.li,{children:['The second post is sent from the code interpreter to the planner.\nThe message is "read file /abc/def.txt".\nThe attachment list contains 6 attachments:',"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsx)(t.li,{children:"The first attachment is the thought of the code interpreter, which is a markdown string."}),"\n",(0,s.jsx)(t.li,{children:"The second attachment is the generated code, which is in python."}),"\n",(0,s.jsx)(t.li,{children:"The third attachment is the verification status, which is CORRECT, INCORRECT, or NONE."}),"\n",(0,s.jsx)(t.li,{children:"The fourth attachment is the verification error message, which is a markdown string."}),"\n",(0,s.jsx)(t.li,{children:"The fifth attachment is the execution status, which is SUCCESS, FAILURE, or NONE."}),"\n",(0,s.jsx)(t.li,{children:"The sixth attachment is the execution result, which is a markdown string."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:'enabled: True\nrounds:\n - user_query: read file /abc/def.txt\n state: finished\n post_list:\n - message: read file /abc/def.txt\n send_from: Planner\n send_to: CodeInterpreter\n attachment_list: []\n - message: I\'m sorry, I cannot find the file /abc/def.txt. An FileNotFoundException has been raised.\n send_from: CodeInterpreter\n send_to: Planner\n attachment_list:\n - type: thought\n content: "{ROLE_NAME} will generate a code snippet to read the file /abc/def.txt and present the content to the user."\n - type: python\n content: |-\n file_path = "/abc/def.txt" \n\n with open(file_path, "r") as file: \n file_contents = file.read() \n print(file_contents)\n - type: verification\n content: CORRECT\n - type: code_error\n content: No code error.\n - type: execution_status\n content: FAILURE\n - type: execution_result\n content: FileNotFoundException, the file /abc/def.txt does not exist.\n'})}),"\n",(0,s.jsxs)(t.p,{children:["In this example, ",(0,s.jsx)(t.code,{children:"verification"})," is about whether the generated code is correct or not.\nWe implemented a module to verify the generated code. If the code is syntactically incorrect,\nor the code violates the constraints, the verification status will be ",(0,s.jsx)(t.code,{children:"INCORRECT"}),"\nand some error messages will be returned.\nA verification of NONE means that the code has not been verified, which means verification has been turned off."]}),"\n",(0,s.jsxs)(t.p,{children:["In this example, ",(0,s.jsx)(t.code,{children:"execution_status"})," is about whether the generated code can be executed successfully or not.\nIf the execution is successful, the execution status will be ",(0,s.jsx)(t.code,{children:"SUCCESS"})," and the execution result will be returned.\nOtherwise, the execution status will be ",(0,s.jsx)(t.code,{children:"FAILURE"})," and some error messages will be returned.\nA execution_status of ",(0,s.jsx)(t.code,{children:"NONE"})," means that the code has not been executed."]})]})}function d(e={}){const{wrapper:t}={...(0,a.a)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},1151:(e,t,n)=>{n.d(t,{Z:()=>i,a:()=>o});var s=n(7294);const a={},r=s.createContext(a);function o(e){const t=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:o(e.components),s.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ae863774.5186e423.js b/assets/js/ae863774.5186e423.js new file mode 100644 index 00000000..15d4a1df --- /dev/null +++ b/assets/js/ae863774.5186e423.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[5675],{2929:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>c,frontMatter:()=>r,metadata:()=>i,toc:()=>h});var s=n(5893),a=n(1151);const r={},o="Customizing Examples",i={id:"customization/example/example",title:"Customizing Examples",description:"There are currently two types of examples: (1) Planner examples and (2) CodeInterpreter examples.",source:"@site/docs/customization/example/example.md",sourceDirName:"customization/example",slug:"/customization/example/",permalink:"/TaskWeaver/docs/customization/example/",draft:!1,unlisted:!1,editUrl:"https://github.com/microsoft/TaskWeaver/tree/main/website/docs/customization/example/example.md",tags:[],version:"current",frontMatter:{},sidebar:"documentSidebar",previous:{title:"Multiple YAML files to one Python implementation",permalink:"/TaskWeaver/docs/plugin/multi_yaml_single_impl"},next:{title:"Experience",permalink:"/TaskWeaver/docs/customization/experience"}},l={},h=[{value:"Planner Examples",id:"planner-examples",level:2},{value:"CodeInterpreter Examples",id:"codeinterpreter-examples",level:2}];function d(e){const t={a:"a",admonition:"admonition",br:"br",code:"code",h1:"h1",h2:"h2",li:"li",ol:"ol",p:"p",pre:"pre",...(0,a.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.h1,{id:"customizing-examples",children:"Customizing Examples"}),"\n",(0,s.jsx)(t.p,{children:"There are currently two types of examples: (1) Planner examples and (2) CodeInterpreter examples.\nPlanning examples are used to demonstrate how the Planner should plan for a specific query from the User.\nCode generation examples are used to help the CodeInterpreter generate code or orchestrate plugins to perform a specific task."}),"\n",(0,s.jsx)(t.p,{children:"Both types of examples are actually the conversation between a collection of roles, such as the User, the Planner, and the CodeInterpreter.\nEach conversation consists of one or more rounds, and each round has a User query and contains one or more posts.\nA post is a message sent from one role to another role, and it may contain some attachments."}),"\n",(0,s.jsx)(t.p,{children:"One example looks like this:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"enabled: True\nrounds:\n - User_query: ping\n state: created\n post_list:\n - message: ping\n send_from: User\n send_to: Planner\n attachment_list: []\n - message: pong\n send_from: Planner\n send_to: User\n attachment_list: []\n"})}),"\n",(0,s.jsx)(t.p,{children:"We explicitly break all examples into the two types only to make it easier to understand and maintain.\nWhen the roles are initialized, each role will only read the examples of its type."}),"\n",(0,s.jsx)(t.admonition,{type:"tip",children:(0,s.jsx)(t.p,{children:"All the text field in the examples such as the messages are in Markdown format."})}),"\n",(0,s.jsx)(t.h2,{id:"planner-examples",children:"Planner Examples"}),"\n",(0,s.jsx)(t.p,{children:"A planning example tells LLMs how to plan for a specific query from the User, talk to the CodeInterpreter,\nreceive the execution result from the CodeInterpreter, and summarize the execution result."}),"\n",(0,s.jsx)(t.p,{children:"The following is an example of a conversation between the User, the Planner, and the CodeInterpreter.\nOne of the purposes of this example is to teach the Planner on the annotation of the dependencies between the steps in the plan.\nAnother purpose is to teach the Planner to follow the right output format."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"enabled: True\nrounds:\n - User_query: count the rows of /home/data.csv\n state: created\n post_list:\n - message: count the rows of /home/data.csv\n send_from: User\n send_to: Planner\n attachment_list:\n - message: Please load the data file /home/data.csv and count the rows of the loaded data\n send_from: Planner\n send_to: CodeInterpreter\n attachment_list:\n - type: init_plan\n content: |-\n 1. load the data file\n 2. count the rows of the loaded data \n 3. report the result to the User \n - type: plan\n content: |-\n 1. instruct CodeInterpreter to load the data file and count the rows of the loaded data\n 2. report the result to the User\n - type: current_plan_step\n content: 1. instruct CodeInterpreter to load the data file and count the rows of the loaded data\n - message: Load the data file /home/data.csv successfully and there are 100 rows in the data file\n send_from: CodeInterpreter\n send_to: Planner\n attachment_list:\n - message: The data file /home/data.csv is loaded and there are 100 rows in the data file\n send_from: Planner\n send_to: User\n attachment_list:\n - type: init_plan\n content: |-\n 1. load the data file\n 2. count the rows of the loaded data \n 3. report the result to the User \n - type: plan\n content: |-\n 1. instruct CodeInterpreter to load the data file and count the rows of the loaded data\n 2. report the result to the User\n - type: current_plan_step\n content: 2. report the result to the User\n"})}),"\n",(0,s.jsx)(t.admonition,{type:"tip",children:(0,s.jsxs)(t.p,{children:["To better understand the attachments including ",(0,s.jsx)(t.code,{children:"init_plan"}),", ",(0,s.jsx)(t.code,{children:"plan"}),", and ",(0,s.jsx)(t.code,{children:"current_plan_step"}),",",(0,s.jsx)(t.br,{}),"\n","please refer to the ",(0,s.jsx)(t.a,{href:"https://github.com/microsoft/TaskWeaver/blob/main/taskweaver/planner/planner_prompt.yaml",children:"Planner's prompt"}),"."]})}),"\n",(0,s.jsx)(t.p,{children:"In this example, there are 4 posts:"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsx)(t.li,{children:'The first post is sent from the User to the Planner.\nThe message is "count the rows of /home/data.csv", which must be the same with the User query.'}),"\n",(0,s.jsxs)(t.li,{children:['The second post is sent from the Planner to the CodeInterpreter.\nThe message is "Please load the data file /home/data.csv and count the rows of the loaded data".\nThe attachment list contains 3 attachments:',"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsx)(t.li,{children:"The first attachment is the initial plan."}),"\n",(0,s.jsx)(t.li,{children:"The second attachment is the final plan."}),"\n",(0,s.jsx)(t.li,{children:"The third attachment is the current plan step."}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.li,{children:'The third post is sent from the CodeInterpreter to the Planner.\nThe message is "Load the data file /home/data.csv successfully and there are 100 rows in the data file".'}),"\n",(0,s.jsx)(t.li,{children:'The fourth post is sent from the Planner to the User.\nThe message is "The data file /home/data.csv is loaded and there are 100 rows in the data file".\nThe attachment list contains 3 attachments, which are the same as the second post.'}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"codeinterpreter-examples",children:"CodeInterpreter Examples"}),"\n",(0,s.jsx)(t.p,{children:"A CodeInterpreter example tells CodeInterpreter how to generate code or orchestrate plugins to perform a specific task.\nThe task is always from the Planner."}),"\n",(0,s.jsx)(t.p,{children:"The purpose of this example is to teach CodeInterpreter how to handle errors in execution."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:'enabled: True\nrounds:\n - User_query: read file /abc/def.txt\n state: finished\n post_list:\n - message: read file /abc/def.txt\n send_from: Planner\n send_to: CodeInterpreter\n attachment_list: []\n - message: I\'m sorry, I cannot find the file /abc/def.txt. An FileNotFoundException has been raised.\n send_from: CodeInterpreter\n send_to: Planner\n attachment_list:\n - type: thought\n content: "{ROLE_NAME} will generate a code snippet to read the file /abc/def.txt and present the content to the User."\n - type: python\n content: |-\n file_path = "/abc/def.txt" \n\n with open(file_path, "r") as file: \n file_contents = file.read() \n print(file_contents)\n - type: verification\n content: CORRECT\n - type: code_error\n content: No code error.\n - type: execution_status\n content: FAILURE\n - type: execution_result\n content: FileNotFoundException, the file /abc/def.txt does not exist.\n'})}),"\n",(0,s.jsx)(t.admonition,{type:"tip",children:(0,s.jsxs)(t.p,{children:["Read the prompt of the code generation to better understand the attachments in the example\n",(0,s.jsx)(t.a,{href:"https://github.com/microsoft/TaskWeaver/blob/main/taskweaver/code_interpreter/code_generator/code_generator_prompt.yaml",children:"code generator prompt"}),"."]})}),"\n",(0,s.jsx)(t.p,{children:"This conversation has two posts:"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsx)(t.li,{children:'The first post is sent from the Planner to the CodeInterpreter.\nThe message is "Please read file /abc/def.txt".'}),"\n",(0,s.jsxs)(t.li,{children:['The second post is sent from the CodeInterpreter to the Planner.\nThe message is "read file /abc/def.txt".\nThe attachment list contains 6 attachments:',"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsx)(t.li,{children:"The first attachment is the thought of the CodeInterpreter."}),"\n",(0,s.jsx)(t.li,{children:"The second attachment is the generated code, which is in python."}),"\n",(0,s.jsx)(t.li,{children:"The third attachment is the verification status, which is CORRECT, INCORRECT, or NONE."}),"\n",(0,s.jsx)(t.li,{children:"The fourth attachment is the verification error message."}),"\n",(0,s.jsx)(t.li,{children:"The fifth attachment is the execution status, which is SUCCESS, FAILURE, or NONE."}),"\n",(0,s.jsx)(t.li,{children:"The sixth attachment is the execution result, which is a markdown string."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.p,{children:["In this example, ",(0,s.jsx)(t.code,{children:"verification"})," is about whether the generated code is correct or not.\nWe implemented a module to verify the generated code. If the code is syntactically incorrect,\nor the code violates the constraints, the verification status will be ",(0,s.jsx)(t.code,{children:"INCORRECT"}),"\nand some error messages will be returned.\nA verification of NONE means that the code has not been verified, which means verification has been turned off."]}),"\n",(0,s.jsxs)(t.p,{children:["In this example, ",(0,s.jsx)(t.code,{children:"execution_status"})," is about whether the generated code can be executed successfully or not.\nIf the execution is successful, the execution status will be ",(0,s.jsx)(t.code,{children:"SUCCESS"})," and the execution result will be returned.\nOtherwise, the execution status will be ",(0,s.jsx)(t.code,{children:"FAILURE"})," and some error messages will be returned.\nA execution_status of ",(0,s.jsx)(t.code,{children:"NONE"})," means that the code has not been executed."]})]})}function c(e={}){const{wrapper:t}={...(0,a.a)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},1151:(e,t,n)=>{n.d(t,{Z:()=>i,a:()=>o});var s=n(7294);const a={},r=s.createContext(a);function o(e){const t=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:o(e.components),s.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b218594a.8cf1454e.js b/assets/js/b218594a.8cf1454e.js deleted file mode 100644 index e86a9fd3..00000000 --- a/assets/js/b218594a.8cf1454e.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[7659],{4570:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>a,contentTitle:()=>s,default:()=>h,frontMatter:()=>r,metadata:()=>c,toc:()=>d});var t=o(5893),i=o(1151);const r={},s="Code Execution",c={id:"advanced/code_execution",title:"Code Execution",description:"\ud83d\udca1We have set the container mode as default for code execution, especially when the usage of the agent",source:"@site/docs/advanced/code_execution.md",sourceDirName:"advanced",slug:"/advanced/code_execution",permalink:"/TaskWeaver/docs/advanced/code_execution",draft:!1,unlisted:!1,editUrl:"https://github.com/microsoft/TaskWeaver/tree/main/website/docs/advanced/code_execution.md",tags:[],version:"current",frontMatter:{},sidebar:"documentSidebar",previous:{title:"Code Verification",permalink:"/TaskWeaver/docs/advanced/code_verification"},next:{title:"CLI Only Mode",permalink:"/TaskWeaver/docs/advanced/cli_only"}},a={},d=[{value:"Two Modes of Code Execution",id:"two-modes-of-code-execution",level:2},{value:"How to Configure the Code Execution Mode",id:"how-to-configure-the-code-execution-mode",level:2},{value:"How to customize the Docker image for code execution",id:"how-to-customize-the-docker-image-for-code-execution",level:2},{value:"Limitations of the container Mode",id:"limitations-of-the-container-mode",level:2},{value:"Restricting External Network Access for Docker Containers",id:"restricting-external-network-access-for-docker-containers",level:2}];function l(e){const n={a:"a",blockquote:"blockquote",br:"br",code:"code",h1:"h1",h2:"h2",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"code-execution",children:"Code Execution"}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsxs)(n.p,{children:["\ud83d\udca1We have set the ",(0,t.jsx)(n.code,{children:"container"})," mode as default for code execution, especially when the usage of the agent\nis open to untrusted users. Refer to ",(0,t.jsx)(n.a,{href:"https://docs.docker.com/engine/security/",children:"Docker Security"})," for better understanding\nof the security features of Docker. To opt for the ",(0,t.jsx)(n.code,{children:"local"})," mode, you need to explicitly set the ",(0,t.jsx)(n.code,{children:"execution_service.kernel_mode"}),"\nparameter in the ",(0,t.jsx)(n.code,{children:"taskweaver_config.json"})," file to ",(0,t.jsx)(n.code,{children:"local"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"TaskWeaver is a code-first agent framework, which means that it always converts the user request into code\nand executes the code to generate the response. In our current implementation, we use a Jupyter Kernel\nto execute the code. We choose Jupyter Kernel because it is a well-established tool for interactive computing,\nand it supports many programming languages."}),"\n",(0,t.jsx)(n.h2,{id:"two-modes-of-code-execution",children:"Two Modes of Code Execution"}),"\n",(0,t.jsxs)(n.p,{children:["TaskWeaver supports two modes of code execution: ",(0,t.jsx)(n.code,{children:"local"})," and ",(0,t.jsx)(n.code,{children:"container"}),".\nThe ",(0,t.jsx)(n.code,{children:"container"})," mode is the default mode. The key difference between the two modes is that the ",(0,t.jsx)(n.code,{children:"container"})," mode\nexecutes the code inside a Docker container, which provides a more secure environment for code execution, while\nthe ",(0,t.jsx)(n.code,{children:"local"})," mode executes the code as a subprocess of the TaskWeaver process.\nAs a result, in the ",(0,t.jsx)(n.code,{children:"local"})," mode, if the user has malicious intent, the user could potentially\ninstruct TaskWeaver to execute harmful code on the host machine. In addition, the LLM could also generate\nharmful code, leading to potential security risks."]}),"\n",(0,t.jsx)(n.h2,{id:"how-to-configure-the-code-execution-mode",children:"How to Configure the Code Execution Mode"}),"\n",(0,t.jsxs)(n.p,{children:["To configure the code execution mode, you need to set the ",(0,t.jsx)(n.code,{children:"execution_service.kernel_mode"})," parameter in the\n",(0,t.jsx)(n.code,{children:"taskweaver_config.json"})," file. The value of the parameter could be ",(0,t.jsx)(n.code,{children:"local"})," or ",(0,t.jsx)(n.code,{children:"container"}),". The default value\nis ",(0,t.jsx)(n.code,{children:"container"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["TaskWeaver supports the ",(0,t.jsx)(n.code,{children:"local"})," mode without any additional setup. However, to use the ",(0,t.jsx)(n.code,{children:"container"})," mode,\nthere are a few prerequisites:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Docker is installed on the host machine."}),"\n",(0,t.jsx)(n.li,{children:"A Docker image is built and available on the host machine for code execution."}),"\n",(0,t.jsxs)(n.li,{children:["The ",(0,t.jsx)(n.code,{children:"execution_service.kernel_mode"})," parameter is set to ",(0,t.jsx)(n.code,{children:"container"})," in the ",(0,t.jsx)(n.code,{children:"taskweaver_config.json"})," file."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Once the code repository is cloned to your local machine, you can build the Docker image\nby running the following command in the root directory of the code repository:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cd scripts\n\n# based on your OS\n./build_executor.ps1 # for Windows\n./build_executor.sh # for Linux or macOS\n"})}),"\n",(0,t.jsxs)(n.p,{children:["After the Docker image is built, you can run ",(0,t.jsx)(n.code,{children:"docker images"})," to check if a Docker image\nnamed ",(0,t.jsx)(n.code,{children:"executor_container"})," is available.\nIf the prerequisite is met, you can now run TaskWeaver in the ",(0,t.jsx)(n.code,{children:"container"})," mode."]}),"\n",(0,t.jsxs)(n.p,{children:["After running TaskWeaver in the ",(0,t.jsx)(n.code,{children:"container"})," mode, you can check if the container is running by running ",(0,t.jsx)(n.code,{children:"docker ps"}),".\nYou should see a container of image ",(0,t.jsx)(n.code,{children:"taskweavercontainers/taskweaver-executor"})," running after executing some code."]}),"\n",(0,t.jsx)(n.h2,{id:"how-to-customize-the-docker-image-for-code-execution",children:"How to customize the Docker image for code execution"}),"\n",(0,t.jsxs)(n.p,{children:["You may want to customize the Docker image for code execution to include additional packages or libraries, especially\nfor your developed plugins. The current Docker image for code execution is ",(0,t.jsx)(n.code,{children:"taskweavercontainers/taskweaver-executor"}),", which\nonly includes the dependencies specified in the ",(0,t.jsx)(n.code,{children:"TaskWeaver/requirements.txt"})," file. To customize the Docker image, you need to\nmodify the ",(0,t.jsx)(n.code,{children:"Dockerfile"})," at ",(0,t.jsx)(n.code,{children:"TaskWeaver/docker/ces_container/Dockerfile"})," and rebuild the Docker image."]}),"\n",(0,t.jsxs)(n.p,{children:["When you open the ",(0,t.jsx)(n.code,{children:"Dockerfile"}),", you will see the following content, and you can add additional packages or libraries\nby adding the corresponding ",(0,t.jsx)(n.code,{children:"RUN"})," command. In this example, we add the ",(0,t.jsx)(n.code,{children:"sentence-transformers"})," package to the Docker image."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-Dockerfile",children:"FROM python:3.10-slim\n...\n# TODO: Install additional packages for plugins\nRUN pip install --no-cache-dir --no-warn-script-location --user sentence-transformers\n...\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Then, you need to rebuild the Docker image by running the ",(0,t.jsx)(n.code,{children:"build_executor.sh"})," script at ",(0,t.jsx)(n.code,{children:"TaskWeaver/scripts/build_executor.sh"}),"\nor ",(0,t.jsx)(n.code,{children:"TaskWeaver/scripts/build.ps1"})," depending on your operating system."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cd TaskWeaver/scripts\n./build_executor.sh\n# or ./build_executor.ps1 if you are using Windows\n"})}),"\n",(0,t.jsxs)(n.p,{children:["If you have successfully rebuilt the Docker image, you can check the new image by running ",(0,t.jsx)(n.code,{children:"docker images"}),".\nAfter building the Docker image, you need to restart the TaskWeaver agent to use the new Docker image."]}),"\n",(0,t.jsxs)(n.h2,{id:"limitations-of-the-container-mode",children:["Limitations of the ",(0,t.jsx)(n.code,{children:"container"})," Mode"]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"container"})," mode is more secure than the ",(0,t.jsx)(n.code,{children:"local"})," mode, but it also has some limitations:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["The startup time of the ",(0,t.jsx)(n.code,{children:"container"})," mode is longer than the ",(0,t.jsx)(n.code,{children:"local"})," mode, because it needs to start a Docker container."]}),"\n",(0,t.jsxs)(n.li,{children:["As the Jupyter Kernel is running inside a Docker container, it has limited access to the host machine. We are mapping the\n",(0,t.jsx)(n.code,{children:"project/workspace/sessions/"})," directory to the container, so the code executed in the container can access the\nfiles in it. One implication of this is that the user cannot ask the agent to load a file from the host machine, because the\nfile is not available in the container. Instead, the user needs to upload the file either using the ",(0,t.jsx)(n.code,{children:"/upload"})," command in\nthe console or the ",(0,t.jsx)(n.code,{children:"upload"})," button in the web interface."]}),"\n",(0,t.jsxs)(n.li,{children:["We have installed required packages in the Docker image to run the Jupyter Kernel. If the user needs to use a package that is\nnot available in the Docker image, the user needs to add the package to the Dockerfile (at ",(0,t.jsx)(n.code,{children:"TaskWeaver/ces_container/Dockerfile"}),")\nand rebuild the Docker image."]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"restricting-external-network-access-for-docker-containers",children:"Restricting External Network Access for Docker Containers"}),"\n",(0,t.jsx)(n.p,{children:"In some cases, the agent developer may want to restrict the Docker container's access to the external network, e.g., the internet.\nIn other words, the agent developer only wants to run the code in the container but does not allow either\nthe plugins or the generated code to access the internet."}),"\n",(0,t.jsx)(n.p,{children:"The following approach is a common way to restrict a Docker container's access to the internet while still\nallowing inbound connections on specific ports:"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsxs)(n.strong,{children:["Creating a Docker network with ",(0,t.jsx)(n.code,{children:"enable_ip_masquerade"})," set to false"]}),":"]}),"\n",(0,t.jsxs)(n.p,{children:["By default, Docker uses IP masquerading (a form of network address translation or NAT) to allow containers\nto communicate with external networks with the source IP address being the host IP address.\nWhen you set ",(0,t.jsx)(n.code,{children:"enable_ip_masquerade"})," to false for a custom Docker network,\nyou prevent containers on that network from having their IP addresses masqueraded, effectively blocking them\nfrom accessing the internet. To create such a network in Docker, you would use the following command:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"docker network create --opt com.docker.network.bridge.enable_ip_masquerade=false my_non_internet_network \n"})}),"\n",(0,t.jsxs)(n.p,{children:["Any container connected to ",(0,t.jsx)(n.code,{children:"my_non_internet_network"})," will not have internet access due to the disabled IP masquerade.",(0,t.jsx)(n.br,{}),"\n","Now, you can run"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"docker network inspect my_non_internet_network\n"})}),"\n",(0,t.jsx)(n.p,{children:"and you will see an output similar to the following:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'"Config": [\n {\n "Subnet": "172.19.0.0/16",\n "Gateway": "172.19.0.1"\n }\n]\n'})}),"\n",(0,t.jsx)(n.p,{children:"This shows the subnet of the docker network, all containers connected to this network will have an IP address in this subnet."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Establishing a rule on the host's firewall or using iptables"}),":"]}),"\n",(0,t.jsx)(n.p,{children:"This step is about setting up rules to block outgoing traffic from the Docker network's subnet\nto any external addresses. This adds an additional layer of security to ensure that even\nif IP masquerade is somehow enabled or if the container finds another route, the traffic will still be blocked."}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"On a Linux host using iptables"}),", you might add a rule like this:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"iptables -I FORWARD -s -j DROP \n"})}),"\n",(0,t.jsxs)(n.p,{children:["Replace ",(0,t.jsx)(n.code,{children:""})," with the actual subnet used by your Docker network.\nIn the previous example, the subnet is ",(0,t.jsx)(n.code,{children:"172.19.0.0/16"}),". This rule drops all forwarding traffic from that subnet."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"On a Windows host"}),", you would create a similar rule within the Windows Firewall\nto block outgoing traffic from the Docker network's subnet."]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Keep in mind that this approach can be considered good practice if you understand the implications\nand have a specific need to isolate your container from the internet.\nHowever, it could also complicate network troubleshooting and container communication if not managed properly.\nAlways ensure you are testing these configurations in a safe environment before applying them to production systems."})]})}function h(e={}){const{wrapper:n}={...(0,i.a)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},1151:(e,n,o)=>{o.d(n,{Z:()=>c,a:()=>s});var t=o(7294);const i={},r=t.createContext(i);function s(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:s(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b21ad4a1.77751512.js b/assets/js/b21ad4a1.77751512.js deleted file mode 100644 index c10aa232..00000000 --- a/assets/js/b21ad4a1.77751512.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2802],{5590:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>s,toc:()=>c});var i=t(5893),r=t(1151);const o={id:"develop_plugin",description:"How to develop a new plugin",slug:"/plugin/how_to_develop_a_new_plugin"},a="How to develop a new plugin",s={id:"customization/plugin/develop_plugin",title:"How to develop a new plugin",description:"How to develop a new plugin",source:"@site/docs/customization/plugin/how_to_develop_a_new_plugin.md",sourceDirName:"customization/plugin",slug:"/plugin/how_to_develop_a_new_plugin",permalink:"/TaskWeaver/docs/plugin/how_to_develop_a_new_plugin",draft:!1,unlisted:!1,editUrl:"https://github.com/microsoft/TaskWeaver/tree/main/website/docs/customization/plugin/how_to_develop_a_new_plugin.md",tags:[],version:"current",frontMatter:{id:"develop_plugin",description:"How to develop a new plugin",slug:"/plugin/how_to_develop_a_new_plugin"},sidebar:"documentSidebar",previous:{title:"Auto Plugin Selection",permalink:"/TaskWeaver/docs/customization/plugin/plugin_selection"},next:{title:"Multiple YAML files to one Python implementation",permalink:"/TaskWeaver/docs/plugin/multi_yaml_single_impl"}},l={},c=[{value:"Implement the python code",id:"implement-the-python-code",level:2},{value:"Configure the schema",id:"configure-the-schema",level:2},{value:"Call the plugin",id:"call-the-plugin",level:2},{value:"FAQ",id:"faq",level:2}];function d(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",p:"p",pre:"pre",strong:"strong",...(0,r.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"how-to-develop-a-new-plugin",children:"How to develop a new plugin"}),"\n",(0,i.jsx)(n.p,{children:"In this tutorial, we will introduce how to develop a strawman plugin in TaskWeaver. This plugin can render a input text in ascii art."}),"\n",(0,i.jsx)(n.h2,{id:"implement-the-python-code",children:"Implement the python code"}),"\n",(0,i.jsxs)(n.p,{children:["Create a python file named ",(0,i.jsx)(n.code,{children:"ascii_render.py"})," in the ",(0,i.jsx)(n.code,{children:"plugins"})," folder. The file name should be the same as the plugin name. The plugin name is defined in the plugin schema. In this example, the plugin name is ",(0,i.jsx)(n.code,{children:"ascii_render"}),".\nThe following code is the template of the plugin implementation."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-python",children:'from taskweaver.plugin import Plugin, register_plugin\n\n@register_plugin\nclass PluginTemplate(Plugin):\n def __call__(self, *args, **kwargs):\n """Implementation Starts"""\n result, description = YourImplementation()\n """Implementation Ends"""\n\n # if your want to add artifact from the execution result, uncomment the following code\n # self.ctx.add_artifact(\n # name="artifact",\n # file_name="artifact.csv",\n # type="df",\n # val=result,\n # )\n return result, description\n'})}),"\n",(0,i.jsxs)(n.p,{children:["The typical way of implementing the plugin is to change the code between ",(0,i.jsx)(n.code,{children:"Implementation Starts"})," and ",(0,i.jsx)(n.code,{children:"Implementation Ends"}),". Note that the return are two variables ",(0,i.jsx)(n.em,{children:"result"})," and ",(0,i.jsx)(n.em,{children:"description"}),". The ",(0,i.jsx)(n.em,{children:"result"})," stores whatever output required for follow-up processing (e.g., a DataFrame). The ",(0,i.jsx)(n.em,{children:"description"})," is a string to describe the result."]}),"\n",(0,i.jsx)(n.p,{children:"Let's make some changes to the code and the result is as follows:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-python",children:"from taskweaver.plugin import Plugin, register_plugin\n\n@register_plugin\nclass AsciiRenderPlugin(Plugin):\n def __call__(self, text: str):\n import pyfiglet\n ascii_art_str = pyfiglet.figlet_format(text, font='isometric1')\n return ascii_art_str\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Note that this function depends on the package ",(0,i.jsx)(n.code,{children:"pyfiglet"}),", so we need to install it with ",(0,i.jsx)(n.code,{children:"pip install pyfiglet"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"configure-the-schema",children:"Configure the schema"}),"\n",(0,i.jsxs)(n.p,{children:["Next, we need to configure the schema so that the LLM can understand the function\nof the plugin. In the schema, there are several fields that should be filled,\nincluding ",(0,i.jsx)(n.code,{children:"name"}),", ",(0,i.jsx)(n.code,{children:"enabled"}),", ",(0,i.jsx)(n.code,{children:"required"}),", ",(0,i.jsx)(n.code,{children:"description"}),", ",(0,i.jsx)(n.code,{children:"parameters"})," and ",(0,i.jsx)(n.code,{children:"returns"}),".\nPlease check ",(0,i.jsx)(n.a,{href:"https://microsoft.github.io/TaskWeaver/docs/plugin/plugin_intro",children:"Plugin Introduction"}),"\nfor more details.\nCreate a yaml file named ",(0,i.jsx)(n.code,{children:"ascii_render.yaml"})," and copy the following content into it."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"name: ascii_render\nenabled: true\nrequired: true\ndescription: >-\n This plugin renders the input text into ASCII art form. \n The input should be a string and the output is also a string in ASCII art.\n For example, result = ascii_render(text='Hello World').\n\nparameters:\n - name: text\n type: str\n required: true\n description: >-\n This is the input text to be rendered into ASCII art form.\n\nreturns:\n - name: result\n type: str\n description: >-\n The rendered text in ASCII art.\n"})}),"\n",(0,i.jsx)(n.h2,{id:"call-the-plugin",children:"Call the plugin"}),"\n",(0,i.jsx)(n.p,{children:"After the plugin is implemented and configured, we can call the plugin in the conversation.\nThe full conversation is as follows:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"=========================================================\n _____ _ _ __\n|_ _|_ _ ___| | _ | | / /__ ____ __ _____ _____\n | |/ _` / __| |/ /| | /| / / _ \\/ __ `/ | / / _ \\/ ___/\n | | (_| \\__ \\ < | |/ |/ / __/ /_/ /| |/ / __/ /\n |_|\\__,_|___/_|\\_\\|__/|__/\\___/\\__,_/ |___/\\___/_/\n=========================================================\nTaskWeaver: I am TaskWeaver, an AI assistant. To get started, could you please enter your request?\nHuman: render ABC in ascii art\n>>> [INIT_PLAN]\n1. Render the text 'ABC' into ASCII art\n>>> [PLAN]\n1. Instruct CodeInterpreter to render the text 'ABC' into ASCII art\n>>> [CURRENT_PLAN_STEP]\n1. Instruct CodeInterpreter to render the text 'ABC' into ASCII art\n>>> [SEND_TO]\nCodeInterpreter\n>>> [MESSAGE]\nPlease render the text 'ABC' into ASCII art\n>>> [PLANNER->CODEINTERPRETER]\nPlease render the text 'ABC' into ASCII art\n>>> [PYTHON]\n# Call the plugin function to render the text 'ABC' into ASCII art\nascii_art_result = ascii_render(\"ABC\")\nascii_art_result\n>>> [VERIFICATION]\nNONE\n>>> [STATUS]\nSUCCESS\n>>> [RESULT]\nThe execution of the generated python code above has succeeded\n\nThe result of above Python code after execution is:\n ___ ___ ___ \n /\\ \\ /\\ \\ /\\ \\ \n /::\\ \\ /::\\ \\ /::\\ \\ \n /:/\\:\\ \\ /:/\\:\\ \\ /:/\\:\\ \\ \n /::\\~\\:\\ \\ /::\\~\\:\\__\\ /:/ \\:\\ \\ \n /:/\\:\\ \\:\\__\\ /:/\\:\\ \\:|__| /:/__/ \\:\\__\\\n \\/__\\:\\/:/ / \\:\\~\\:\\/:/ / \\:\\ \\ \\/__/\n \\::/ / \\:\\ \\::/ / \\:\\ \\ \n /:/ / \\:\\/:/ / \\:\\ \\ \n /:/ / \\::/__/ \\:\\__\\ \n \\/__/ ~~ \\/__/ \n\n>>> [CODEINTERPRETER->PLANNER]\nThe following python code has been executed:\n\n# Call the plugin function to render the text 'ABC' into ASCII art\nascii_art_result = ascii_render(\"ABC\")\nascii_art_result\n\n\n\nThe execution of the generated python code above has succeeded\n\nThe result of above Python code after execution is:\n ___ ___ ___ \n /\\ \\ /\\ \\ /\\ \\ \n /::\\ \\ /::\\ \\ /::\\ \\ \n /:/\\:\\ \\ /:/\\:\\ \\ /:/\\:\\ \\ \n /::\\~\\:\\ \\ /::\\~\\:\\__\\ /:/ \\:\\ \\ \n /:/\\:\\ \\:\\__\\ /:/\\:\\ \\:|__| /:/__/ \\:\\__\\\n \\/__\\:\\/:/ / \\:\\~\\:\\/:/ / \\:\\ \\ \\/__/\n \\::/ / \\:\\ \\::/ / \\:\\ \\ \n /:/ / \\:\\/:/ / \\:\\ \\ \n /:/ / \\::/__/ \\:\\__\\ \n \\/__/ ~~ \\/__/ \n\n>>> [INIT_PLAN] \n1. Render the text 'ABC' into ASCII art\n>>> [PLAN]\n1. Instruct CodeInterpreter to render the text 'ABC' into ASCII art\n>>> [CURRENT_PLAN_STEP]\nReport the ASCII art to the user\n>>> [SEND_TO]\nUser\n>>> [MESSAGE]\nHere is the text 'ABC' rendered in ASCII art:\n ___ ___ ___ \n /\\ \\ /\\ \\ /\\ \\ \n /::\\ \\ /::\\ \\ /::\\ \\ \n /:/\\:\\ \\ /:/\\:\\ \\ /:/\\:\\ \\ \n /::\\~\\:\\ \\ /::\\~\\:\\__\\ /:/ \\:\\ \\ \n /:/\\:\\ \\:\\__\\ /:/\\:\\ \\:|__| /:/__/ \\:\\__\\\n \\/__\\:\\/:/ / \\:\\~\\:\\/:/ / \\:\\ \\ \\/__/\n \\::/ / \\:\\ \\::/ / \\:\\ \\ \n /:/ / \\:\\/:/ / \\:\\ \\ \n /:/ / \\::/__/ \\:\\__\\ \n \\/__/ ~~ \\/__/ \n>>> [PLANNER->USER]\nHere is the text 'ABC' rendered in ASCII art:\n ___ ___ ___ \n /\\ \\ /\\ \\ /\\ \\ \n /::\\ \\ /::\\ \\ /::\\ \\ \n /:/\\:\\ \\ /:/\\:\\ \\ /:/\\:\\ \\ \n /::\\~\\:\\ \\ /::\\~\\:\\__\\ /:/ \\:\\ \\ \n /:/\\:\\ \\:\\__\\ /:/\\:\\ \\:|__| /:/__/ \\:\\__\\\n \\/__\\:\\/:/ / \\:\\~\\:\\/:/ / \\:\\ \\ \\/__/\n \\::/ / \\:\\ \\::/ / \\:\\ \\ \n /:/ / \\:\\/:/ / \\:\\ \\ \n /:/ / \\::/__/ \\:\\__\\ \n \\/__/ ~~ \\/__/ \nTaskWeaver: Here is the text 'ABC' rendered in ASCII art:\n ___ ___ ___ \n /\\ \\ /\\ \\ /\\ \\ \n /::\\ \\ /::\\ \\ /::\\ \\ \n /:/\\:\\ \\ /:/\\:\\ \\ /:/\\:\\ \\ \n /::\\~\\:\\ \\ /::\\~\\:\\__\\ /:/ \\:\\ \\ \n /:/\\:\\ \\:\\__\\ /:/\\:\\ \\:|__| /:/__/ \\:\\__\\\n \\/__\\:\\/:/ / \\:\\~\\:\\/:/ / \\:\\ \\ \\/__/\n \\::/ / \\:\\ \\::/ / \\:\\ \\ \n /:/ / \\:\\/:/ / \\:\\ \\ \n /:/ / \\::/__/ \\:\\__\\ \n \\/__/ ~~ \\/__/ \n"})}),"\n",(0,i.jsx)(n.h2,{id:"faq",children:"FAQ"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Q: How do I know if TaskWeaver can see my plugin?"})}),"\n",(0,i.jsx)(n.p,{children:'A: A simple way to check if TaskWeaver can see your plugin is to ask "What can you do?" to TaskWeaver.\nThe typical response is to list all the available plugins like the following:'}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-markdown",children:"I can assist you with various tasks, including:\n\n- Detecting anomalies in time series data.\n- Rendering text into ASCII art.\n- Searching and comparing prices from thousands of online shops (US only).\n- Telling a joke.\n\nIf you have a specific task in mind, please let me know, and I'll do my best to assist you.\n"})}),"\n",(0,i.jsxs)(n.p,{children:["If you see your plugin in the list, it means TaskWeaver can see your plugin.\nBut this is not a reliable way to check if TaskWeaver can see your plugin because the response is generated by the LLM.\nA more reliable way is to check the prompt of the Planner. You can find the prompts\nfrom ",(0,i.jsx)(n.code,{children:"project/workspace/sessions//planner_prompt_log_xxxx.yaml"}),".\nThen, search for this section as follows:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-markdown",children:'CodeInterpreter has the following plugin functions and their required parameters need to be provided before the execution:\n- anomaly_detection: anomaly_detection function identifies anomalies from an input DataFrame of time series. It will add a new column \\"Is_Anomaly\\", where each entry will be marked with \\"True\\" if the value is an anomaly or \\"False\\" otherwise. Arguments required: df: DataFrame, time_col_name: str, value_col_name: str\n- ascii_render: This plugin renders the input text into ASCII art form. Arguments required: text: str\n- klarna_search: Search and compare prices from thousands of online shops. Only available in the US. This plugin only takes user requests when searching for merchandise. If not clear, confirm with the user if they want to search for merchandise from Klarna. Arguments required: query: str\n- tell_joke: Call this plugin to tell a joke.\n'})}),"\n",(0,i.jsx)(n.p,{children:"Check if your plugin is in the list. If it is, it means TaskWeaver can see your plugin."}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Q: Why TaskWeaver cannot see my plugin?"})}),"\n",(0,i.jsxs)(n.p,{children:["First, make sure you have read our ",(0,i.jsx)(n.a,{href:"https://microsoft.github.io/TaskWeaver/docs/plugin/plugin_intro",children:"Plugin Introduction"})," and this tutorial carefully.\nYou should have two files in the ",(0,i.jsx)(n.code,{children:"plugins"})," folder, e.g., ",(0,i.jsx)(n.code,{children:"ascii_render.py"})," and ",(0,i.jsx)(n.code,{children:"ascii_render.yaml"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"Now, if TaskWeaver cannot see your plugin, the root cause is typically syntax errors in the yaml file.\nCheck the console output if you are using the command line interface, or the console logs if you are using the web interface.\nYou may see the following error message:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"failed to loading component from .yaml, skipping: Yaml loading failed due to: \n"})}),"\n",(0,i.jsx)(n.p,{children:"The error message will tell you the reason why the yaml file cannot be loaded.\nIt is typically easy to fix the syntax errors by using a yaml linter (e.g., in Visual Studio Code) or an online yaml linter."}),"\n",(0,i.jsxs)(n.p,{children:["If you have checked the syntax of the yaml file and TaskWeaver still cannot see your plugin, please check\nif the yaml file has included all the required fields such as the ",(0,i.jsx)(n.code,{children:"parameters"})," and ",(0,i.jsx)(n.code,{children:"returns"})," fields."]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Q: Why TaskWeaver can see my plugin but cannot call it?"})}),"\n",(0,i.jsx)(n.p,{children:"A: In this case, you may see the generated code has called the plugin function,\nbut the execution result is an error message saying that the plugin function is undefined.\nIf this happens, please check the console output if you are using the command line interface,\nor the console logs if you are using the web interface."}),"\n",(0,i.jsx)(n.p,{children:"You may see the following error message:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"Plugin failed to load: Plugin failed to register: failed to load plugin \n"})}),"\n",(0,i.jsx)(n.p,{children:"This error message will tell you the reason why the plugin function cannot be loaded.\nIt is typically easy to fix the errors by checking the console output or logs.\nThe root cause is typically errors in the python file that causes the plugin function cannot be loaded.\nTypical errors include syntax errors, missing imports, or missing packages."}),"\n",(0,i.jsx)(n.p,{children:'Note that this sort of error is not caused by the implementation "inside" the plugin function.\nOtherwise, the errors would be caught during the execution of the plugin function,\nnot during the loading of the plugin function.'}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Q: How to debug my plugin?"})}),"\n",(0,i.jsxs)(n.p,{children:["A: We are working on a debugging tool to help you debug your plugin. For now, a simple way to debug your plugin is to\ndefine a main function in the python file and run it in your local environment.\nFor example, you can define a main function in ",(0,i.jsx)(n.code,{children:"ascii_render.py"})," as follows:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-python",children:'if __name__ == "__main__":\n from taskweaver.plugin.context import temp_context\n\n with temp_context() as temp_ctx:\n render = AsciiRenderPlugin(name="ascii_render", ctx=temp_ctx, config={})\n print(render(text="hello world!"))\n'})}),"\n",(0,i.jsx)(n.p,{children:"In this main function, we create a temporary context and call the plugin function with some input.\nYou need not change the plugin implementation. Just add the main function to the end of the python file.\nThen, run the python file in your local environment. If there are any errors, you can see them in the console output."}),"\n",(0,i.jsxs)(n.p,{children:["If you have the ",(0,i.jsx)(n.code,{children:"configurations"})," section in the yaml file, you can manually set the configurations in the ",(0,i.jsx)(n.code,{children:"config"})," parameter of the plugin constructor.\nWe currently do not read the yaml file, so you need to make sure that the configurations are set correctly in the ",(0,i.jsx)(n.code,{children:"config"})," parameter.\nFor example, if an integer configuration ",(0,i.jsx)(n.code,{children:"max_length"})," is defined in the yaml file, you can set it in the ",(0,i.jsx)(n.code,{children:"config"})," parameter as follows:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-python",children:'config = {\n "max_length": 100\n}\n'})}),"\n",(0,i.jsxs)(n.p,{children:["Then, pass the ",(0,i.jsx)(n.code,{children:"config"})," to the plugin constructor. As yaml is type sensitive, you need to make sure that the type of the configuration is correct."]})]})}function h(e={}){const{wrapper:n}={...(0,r.a)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},1151:(e,n,t)=>{t.d(n,{Z:()=>s,a:()=>a});var i=t(7294);const r={},o=i.createContext(r);function a(e){const n=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function s(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),i.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b21ad4a1.c8713f52.js b/assets/js/b21ad4a1.c8713f52.js new file mode 100644 index 00000000..3934534f --- /dev/null +++ b/assets/js/b21ad4a1.c8713f52.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[2802],{5590:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>c,frontMatter:()=>_,metadata:()=>a,toc:()=>s});var i=t(5893),r=t(1151);const _={id:"develop_plugin",description:"How to develop a new plugin",slug:"/plugin/how_to_develop_a_new_plugin"},o="An Example of Developing a New Plugin",a={id:"customization/plugin/develop_plugin",title:"An Example of Developing a New Plugin",description:"How to develop a new plugin",source:"@site/docs/customization/plugin/how_to_develop_a_new_plugin.md",sourceDirName:"customization/plugin",slug:"/plugin/how_to_develop_a_new_plugin",permalink:"/TaskWeaver/docs/plugin/how_to_develop_a_new_plugin",draft:!1,unlisted:!1,editUrl:"https://github.com/microsoft/TaskWeaver/tree/main/website/docs/customization/plugin/how_to_develop_a_new_plugin.md",tags:[],version:"current",frontMatter:{id:"develop_plugin",description:"How to develop a new plugin",slug:"/plugin/how_to_develop_a_new_plugin"},sidebar:"documentSidebar",previous:{title:"Plugin Introduction",permalink:"/TaskWeaver/docs/plugin/plugin_intro"},next:{title:"Multiple YAML files to one Python implementation",permalink:"/TaskWeaver/docs/plugin/multi_yaml_single_impl"}},l={},s=[{value:"Implement the python code",id:"implement-the-python-code",level:2},{value:"Configure the schema",id:"configure-the-schema",level:2},{value:"Call the plugin",id:"call-the-plugin",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",p:"p",pre:"pre",...(0,r.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"an-example-of-developing-a-new-plugin",children:"An Example of Developing a New Plugin"}),"\n",(0,i.jsx)(n.p,{children:"In this tutorial, we will introduce how to develop a strawman plugin in TaskWeaver. This plugin can render a input text in ascii art."}),"\n",(0,i.jsx)(n.h2,{id:"implement-the-python-code",children:"Implement the python code"}),"\n",(0,i.jsxs)(n.p,{children:["Create a python file named ",(0,i.jsx)(n.code,{children:"ascii_render.py"})," in the ",(0,i.jsx)(n.code,{children:"plugins"})," folder. The file name should be the same as the plugin name. The plugin name is defined in the plugin schema. In this example, the plugin name is ",(0,i.jsx)(n.code,{children:"ascii_render"}),".\nThe following code is the template of the plugin implementation."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-python",children:'from taskweaver.plugin import Plugin, register_plugin\n\n@register_plugin\nclass PluginTemplate(Plugin):\n def __call__(self, *args, **kwargs):\n """Implementation Starts"""\n result, description = YourImplementation()\n """Implementation Ends"""\n\n # if your want to add artifact from the execution result, uncomment the following code\n # self.ctx.add_artifact(\n # name="artifact",\n # file_name="artifact.csv",\n # type="df",\n # val=result,\n # )\n return result, description\n'})}),"\n",(0,i.jsxs)(n.p,{children:["The typical way of implementing the plugin is to change the code between ",(0,i.jsx)(n.code,{children:"Implementation Starts"})," and ",(0,i.jsx)(n.code,{children:"Implementation Ends"}),". Note that the return are two variables ",(0,i.jsx)(n.em,{children:"result"})," and ",(0,i.jsx)(n.em,{children:"description"}),". The ",(0,i.jsx)(n.em,{children:"result"})," stores whatever output required for follow-up processing (e.g., a DataFrame). The ",(0,i.jsx)(n.em,{children:"description"})," is a string to describe the result."]}),"\n",(0,i.jsx)(n.p,{children:"Let's make some changes to the code and the result is as follows:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-python",children:"from taskweaver.plugin import Plugin, register_plugin\n\n@register_plugin\nclass AsciiRenderPlugin(Plugin):\n def __call__(self, text: str):\n import pyfiglet\n ascii_art_str = pyfiglet.figlet_format(text, font='isometric1')\n return ascii_art_str\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Note that this function depends on the package ",(0,i.jsx)(n.code,{children:"pyfiglet"}),", so we need to install it with ",(0,i.jsx)(n.code,{children:"pip install pyfiglet"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"configure-the-schema",children:"Configure the schema"}),"\n",(0,i.jsxs)(n.p,{children:["Next, we need to configure the schema so that the LLM can understand the function\nof the plugin. In the schema, there are several fields that should be filled,\nincluding ",(0,i.jsx)(n.code,{children:"name"}),", ",(0,i.jsx)(n.code,{children:"enabled"}),", ",(0,i.jsx)(n.code,{children:"required"}),", ",(0,i.jsx)(n.code,{children:"description"}),", ",(0,i.jsx)(n.code,{children:"parameters"})," and ",(0,i.jsx)(n.code,{children:"returns"}),".\nPlease check ",(0,i.jsx)(n.a,{href:"https://microsoft.github.io/TaskWeaver/docs/plugin/plugin_intro",children:"Plugin Introduction"}),"\nfor more details.\nCreate a yaml file named ",(0,i.jsx)(n.code,{children:"ascii_render.yaml"})," and copy the following content into it."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"name: ascii_render\nenabled: true\nrequired: true\ndescription: >-\n This plugin renders the input text into ASCII art form. \n The input should be a string and the output is also a string in ASCII art.\n For example, result = ascii_render(text='Hello World').\n\nparameters:\n - name: text\n type: str\n required: true\n description: >-\n This is the input text to be rendered into ASCII art form.\n\nreturns:\n - name: result\n type: str\n description: >-\n The rendered text in ASCII art.\n"})}),"\n",(0,i.jsx)(n.h2,{id:"call-the-plugin",children:"Call the plugin"}),"\n",(0,i.jsx)(n.p,{children:"After the plugin is implemented and configured, we can call the plugin in the conversation.\nThe full conversation is as follows:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"=========================================================\n _____ _ _ __\n|_ _|_ _ ___| | _ | | / /__ ____ __ _____ _____\n | |/ _` / __| |/ /| | /| / / _ \\/ __ `/ | / / _ \\/ ___/\n | | (_| \\__ \\ < | |/ |/ / __/ /_/ /| |/ / __/ /\n |_|\\__,_|___/_|\\_\\|__/|__/\\___/\\__,_/ |___/\\___/_/\n=========================================================\nTaskWeaver: I am TaskWeaver, an AI assistant. To get started, could you please enter your request?\nHuman: render ABC in ascii art\n>>> [INIT_PLAN]\n1. Render the text 'ABC' into ASCII art\n>>> [PLAN]\n1. Instruct CodeInterpreter to render the text 'ABC' into ASCII art\n>>> [CURRENT_PLAN_STEP]\n1. Instruct CodeInterpreter to render the text 'ABC' into ASCII art\n>>> [SEND_TO]\nCodeInterpreter\n>>> [MESSAGE]\nPlease render the text 'ABC' into ASCII art\n>>> [PLANNER->CODEINTERPRETER]\nPlease render the text 'ABC' into ASCII art\n>>> [PYTHON]\n# Call the plugin function to render the text 'ABC' into ASCII art\nascii_art_result = ascii_render(\"ABC\")\nascii_art_result\n>>> [VERIFICATION]\nNONE\n>>> [STATUS]\nSUCCESS\n>>> [RESULT]\nThe execution of the generated python code above has succeeded\n\nThe result of above Python code after execution is:\n ___ ___ ___ \n /\\ \\ /\\ \\ /\\ \\ \n /::\\ \\ /::\\ \\ /::\\ \\ \n /:/\\:\\ \\ /:/\\:\\ \\ /:/\\:\\ \\ \n /::\\~\\:\\ \\ /::\\~\\:\\__\\ /:/ \\:\\ \\ \n /:/\\:\\ \\:\\__\\ /:/\\:\\ \\:|__| /:/__/ \\:\\__\\\n \\/__\\:\\/:/ / \\:\\~\\:\\/:/ / \\:\\ \\ \\/__/\n \\::/ / \\:\\ \\::/ / \\:\\ \\ \n /:/ / \\:\\/:/ / \\:\\ \\ \n /:/ / \\::/__/ \\:\\__\\ \n \\/__/ ~~ \\/__/ \n\n>>> [CODEINTERPRETER->PLANNER]\nThe following python code has been executed:\n\n# Call the plugin function to render the text 'ABC' into ASCII art\nascii_art_result = ascii_render(\"ABC\")\nascii_art_result\n\n\n\nThe execution of the generated python code above has succeeded\n\nThe result of above Python code after execution is:\n ___ ___ ___ \n /\\ \\ /\\ \\ /\\ \\ \n /::\\ \\ /::\\ \\ /::\\ \\ \n /:/\\:\\ \\ /:/\\:\\ \\ /:/\\:\\ \\ \n /::\\~\\:\\ \\ /::\\~\\:\\__\\ /:/ \\:\\ \\ \n /:/\\:\\ \\:\\__\\ /:/\\:\\ \\:|__| /:/__/ \\:\\__\\\n \\/__\\:\\/:/ / \\:\\~\\:\\/:/ / \\:\\ \\ \\/__/\n \\::/ / \\:\\ \\::/ / \\:\\ \\ \n /:/ / \\:\\/:/ / \\:\\ \\ \n /:/ / \\::/__/ \\:\\__\\ \n \\/__/ ~~ \\/__/ \n\n>>> [INIT_PLAN] \n1. Render the text 'ABC' into ASCII art\n>>> [PLAN]\n1. Instruct CodeInterpreter to render the text 'ABC' into ASCII art\n>>> [CURRENT_PLAN_STEP]\nReport the ASCII art to the user\n>>> [SEND_TO]\nUser\n>>> [MESSAGE]\nHere is the text 'ABC' rendered in ASCII art:\n ___ ___ ___ \n /\\ \\ /\\ \\ /\\ \\ \n /::\\ \\ /::\\ \\ /::\\ \\ \n /:/\\:\\ \\ /:/\\:\\ \\ /:/\\:\\ \\ \n /::\\~\\:\\ \\ /::\\~\\:\\__\\ /:/ \\:\\ \\ \n /:/\\:\\ \\:\\__\\ /:/\\:\\ \\:|__| /:/__/ \\:\\__\\\n \\/__\\:\\/:/ / \\:\\~\\:\\/:/ / \\:\\ \\ \\/__/\n \\::/ / \\:\\ \\::/ / \\:\\ \\ \n /:/ / \\:\\/:/ / \\:\\ \\ \n /:/ / \\::/__/ \\:\\__\\ \n \\/__/ ~~ \\/__/ \n>>> [PLANNER->USER]\nHere is the text 'ABC' rendered in ASCII art:\n ___ ___ ___ \n /\\ \\ /\\ \\ /\\ \\ \n /::\\ \\ /::\\ \\ /::\\ \\ \n /:/\\:\\ \\ /:/\\:\\ \\ /:/\\:\\ \\ \n /::\\~\\:\\ \\ /::\\~\\:\\__\\ /:/ \\:\\ \\ \n /:/\\:\\ \\:\\__\\ /:/\\:\\ \\:|__| /:/__/ \\:\\__\\\n \\/__\\:\\/:/ / \\:\\~\\:\\/:/ / \\:\\ \\ \\/__/\n \\::/ / \\:\\ \\::/ / \\:\\ \\ \n /:/ / \\:\\/:/ / \\:\\ \\ \n /:/ / \\::/__/ \\:\\__\\ \n \\/__/ ~~ \\/__/ \nTaskWeaver: Here is the text 'ABC' rendered in ASCII art:\n ___ ___ ___ \n /\\ \\ /\\ \\ /\\ \\ \n /::\\ \\ /::\\ \\ /::\\ \\ \n /:/\\:\\ \\ /:/\\:\\ \\ /:/\\:\\ \\ \n /::\\~\\:\\ \\ /::\\~\\:\\__\\ /:/ \\:\\ \\ \n /:/\\:\\ \\:\\__\\ /:/\\:\\ \\:|__| /:/__/ \\:\\__\\\n \\/__\\:\\/:/ / \\:\\~\\:\\/:/ / \\:\\ \\ \\/__/\n \\::/ / \\:\\ \\::/ / \\:\\ \\ \n /:/ / \\:\\/:/ / \\:\\ \\ \n /:/ / \\::/__/ \\:\\__\\ \n \\/__/ ~~ \\/__/ \n"})}),"\n",(0,i.jsx)(n.admonition,{type:"info",children:(0,i.jsxs)(n.p,{children:["Check the ",(0,i.jsx)(n.a,{href:"/TaskWeaver/docs/FAQ",children:"FAQs"})," if you have any issues in developing a plugin before submitting an issue on GitHub."]})})]})}function c(e={}){const{wrapper:n}={...(0,r.a)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},1151:(e,n,t)=>{t.d(n,{Z:()=>a,a:()=>o});var i=t(7294);const r={},_=i.createContext(r);function o(e){const n=i.useContext(_);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),i.createElement(_.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d3234990.2d61760a.js b/assets/js/d3234990.2d61760a.js new file mode 100644 index 00000000..74e6adc0 --- /dev/null +++ b/assets/js/d3234990.2d61760a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[3287],{1598:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>i,default:()=>d,frontMatter:()=>s,metadata:()=>r,toc:()=>c});var o=t(5893),l=t(1151);const s={},i="Multi LLM APIs",r={id:"llms/multi-llm",title:"Multi LLM APIs",description:"In some cases, you may want to use different LLMs for different components.",source:"@site/docs/llms/multi-llm.md",sourceDirName:"llms",slug:"/llms/multi-llm",permalink:"/TaskWeaver/docs/llms/multi-llm",draft:!1,unlisted:!1,editUrl:"https://github.com/microsoft/TaskWeaver/tree/main/website/docs/llms/multi-llm.md",tags:[],version:"current",frontMatter:{},sidebar:"documentSidebar",previous:{title:"Customized LLM API",permalink:"/TaskWeaver/docs/llms/customized_llm_api"},next:{title:"Configurations",permalink:"/TaskWeaver/docs/advanced"}},a={},c=[];function m(e){const n={admonition:"admonition",code:"code",h1:"h1",li:"li",p:"p",pre:"pre",ul:"ul",...(0,l.a)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h1,{id:"multi-llm-apis",children:"Multi LLM APIs"}),"\n",(0,o.jsx)(n.p,{children:"In some cases, you may want to use different LLMs for different components.\nFor example, you may want to use OpenAI GPT-4 for the Planner but use Google gemini-pro for the CodeInterpreter.\nIn this part, we show you how to use different LLMs for different components."}),"\n",(0,o.jsxs)(n.p,{children:["If you need only one LLM, you can have only the primary LLM settings in the ",(0,o.jsx)(n.code,{children:"taskweaver_config.json"})," file.\nIf you need multiple LLMs, you need to have ",(0,o.jsx)(n.code,{children:"ext_llms.llm_configs"})," in the ",(0,o.jsx)(n.code,{children:"taskweaver_config.json"})," file to specify the extra LLMs for different components.\nIn the following, we show you how to configure the ",(0,o.jsx)(n.code,{children:"taskweaver_config.json"})," file to use multiple LLMs."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-json",children:'"llm.api_type":"openai",\n"llm.api_base": "https://api.openai.com/v1",\n"llm.api_key": "YOUR_API_KEY",\n"llm.model": "gpt-3.5-turbo-1106",\n"llm.response_format": "json_object"\n"ext_llms.llm_configs": {\n "llm_A":\n {\n "llm.api_type": "openai",\n "llm.api_base": "https://api.openai.com/v1",\n "llm.api_key": "YOUR_API_KEY",\n "llm.model": "gpt-4-1106-preview",\n "llm.response_format": "json_object",\n },\n "llm_B":\n {\n "llm.api_type": "google_genai",\n "llm.api_key": "YOUR_API_KEY",\n "llm.model": "gemini-pro",\n },\n},\n'})}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["The primary LLM settings are specified in the ",(0,o.jsx)(n.code,{children:"llm."})," fields and it is mandatory."]}),"\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.code,{children:"ext_llms.llm_configs"})," is optional and is a dict of extra LLMs for different components. If you do not specify it, only the primary LLM will be used."]}),"\n"]}),"\n",(0,o.jsxs)(n.p,{children:["Specify the LLMs for different components in the ",(0,o.jsx)(n.code,{children:"taskweaver_config.json"}),".\nFor example, we want to use OpenAI GPT-4 for the Planner and use Google gemini-pro for the CodeInterpreter."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-json",children:'"planner.llm_alias": "llm_A",\n"code_generator.llm_alias": "llm_B"\n'})}),"\n",(0,o.jsx)(n.admonition,{type:"tip",children:(0,o.jsxs)(n.p,{children:["If you do not specify the LLM for a component, the primary LLM will be used by default.\nIn the above example, ",(0,o.jsx)(n.code,{children:"GPT-3.5-turbo-1106"})," will be used for both the Planner and the CodeInterpreter."]})})]})}function d(e={}){const{wrapper:n}={...(0,l.a)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(m,{...e})}):m(e)}},1151:(e,n,t)=>{t.d(n,{Z:()=>r,a:()=>i});var o=t(7294);const l={},s=o.createContext(l);function i(e){const n=o.useContext(s);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(l):e.components||l:i(e.components),o.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d3234990.796cd280.js b/assets/js/d3234990.796cd280.js deleted file mode 100644 index 6088078d..00000000 --- a/assets/js/d3234990.796cd280.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[3287],{1598:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>i,default:()=>m,frontMatter:()=>l,metadata:()=>r,toc:()=>c});var s=t(5893),o=t(1151);const l={},i="Multi LLM APIs",r={id:"llms/multi-llm",title:"Multi LLM APIs",description:"In some cases, you may want to use different LLMs for different components.",source:"@site/docs/llms/multi-llm.md",sourceDirName:"llms",slug:"/llms/multi-llm",permalink:"/TaskWeaver/docs/llms/multi-llm",draft:!1,unlisted:!1,editUrl:"https://github.com/microsoft/TaskWeaver/tree/main/website/docs/llms/multi-llm.md",tags:[],version:"current",frontMatter:{},sidebar:"documentSidebar",previous:{title:"Customized LLM API",permalink:"/TaskWeaver/docs/llms/customized_llm_api"},next:{title:"Configurations",permalink:"/TaskWeaver/docs/advanced"}},a={},c=[{value:"Usage",id:"usage",level:2}];function d(e){const n={code:"code",h1:"h1",h2:"h2",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,o.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"multi-llm-apis",children:"Multi LLM APIs"}),"\n",(0,s.jsx)(n.p,{children:"In some cases, you may want to use different LLMs for different components.\nFor example, you may want to use OpenAI GPT-4 for the Planner but use Google gemini-pro for the CodeInterpreter.\nIn this section, we will show you how to use different LLMs for different components."}),"\n",(0,s.jsx)(n.h2,{id:"usage",children:"Usage"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["Configure the primary LLM and extra LLMs settings in the ",(0,s.jsx)(n.code,{children:"taskweaver_config.json"})," file under ",(0,s.jsx)(n.code,{children:"project"})," directory, just as follows:"]}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'"llm.api_type":"openai",\n"llm.api_base": "https://api.openai.com/v1",\n"llm.api_key": "YOUR_API_KEY",\n"llm.model": "gpt-3.5-turbo-1106",\n"llm.response_format": "json_object"\n"ext_llms.llm_configs": {\n "llm_A":\n {\n "llm.api_type": "openai",\n "llm.api_base": "https://api.openai.com/v1",\n "llm.api_key": "YOUR_API_KEY",\n "llm.model": "gpt-4-1106-preview",\n "llm.response_format": "json_object",\n },\n "llm_B":\n {\n "llm.api_type": "google_genai",\n "llm.api_key": "YOUR_API_KEY",\n "llm.model": "gemini-pro",\n },\n},\n'})}),"\n",(0,s.jsx)(n.p,{children:"Notes:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"ext_llms.llm_configs"})," is a dict of extra LLMs for different components. It is an optional field. If you do not specify it, only the primary LLM will be used."]}),"\n",(0,s.jsx)(n.li,{children:"For each LLM setting, please should follow the configuration method described in each LLM configuration page."}),"\n",(0,s.jsxs)(n.li,{children:["Besides the extra LLMs, you should also configure the primary LLM settings in the ",(0,s.jsx)(n.code,{children:"taskweaver_config.json"}),", just as shown in the top 5 lines in the above code snippet."]}),"\n"]}),"\n",(0,s.jsxs)(n.ol,{start:"2",children:["\n",(0,s.jsxs)(n.li,{children:["Specify the LLMs for different components in the ",(0,s.jsx)(n.code,{children:"taskweaver_config.json"}),".\nFor example, we want to use OpenAI GPT-4 for the Planner and use Google gemini-pro for the CodeInterpreter."]}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'"planner.llm_alias": "llm_A",\n"code_generator.llm_alias": "llm_B"\n'})}),"\n",(0,s.jsx)(n.p,{children:"Notes:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["If you do not specify the LLM for a component, the primary LLM will be used by default.\nIn this case, ",(0,s.jsx)(n.code,{children:"GPT-3.5-turbo-1106"})," will be used for both the Planner and the CodeInterpreter, if you do not specify the LLM for them."]}),"\n"]})]})}function m(e={}){const{wrapper:n}={...(0,o.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},1151:(e,n,t)=>{t.d(n,{Z:()=>r,a:()=>i});var s=t(7294);const o={},l=s.createContext(o);function i(e){const n=s.useContext(l);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),s.createElement(l.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/dfcda4d1.8d1033e2.js b/assets/js/dfcda4d1.8d1033e2.js deleted file mode 100644 index 3de7edc8..00000000 --- a/assets/js/dfcda4d1.8d1033e2.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1916],{9366:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>o,toc:()=>l});var t=s(5893),i=s(1151);const a={},r="Web UI",o={id:"usage/webui",title:"Web UI",description:"Please note that this Web UI is for development and testing purposes only.",source:"@site/docs/usage/webui.md",sourceDirName:"usage",slug:"/usage/webui",permalink:"/TaskWeaver/docs/usage/webui",draft:!1,unlisted:!1,editUrl:"https://github.com/microsoft/TaskWeaver/tree/main/website/docs/usage/webui.md",tags:[],version:"current",frontMatter:{},sidebar:"documentSidebar",previous:{title:"Terminal",permalink:"/TaskWeaver/docs/usage/cmd"},next:{title:"Library",permalink:"/TaskWeaver/docs/usage/library"}},c={},l=[];function d(e){const n={a:"a",code:"code",h1:"h1",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",...(0,i.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"web-ui",children:"Web UI"}),"\n",(0,t.jsx)(n.p,{children:"Please note that this Web UI is for development and testing purposes only."}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["Follow the instruction in ",(0,t.jsx)(n.a,{href:"/TaskWeaver/docs/quickstart",children:"Quick Start"})," to clone the repo and make configurations"]}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/microsoft/TaskWeaver.git\ncd TaskWeaver\n# install the requirements\npip install -r requirements.txt\n"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n"llm.api_key": "the api key",\n"llm.model": "the model name, e.g., gpt-4"\n}\n'})}),"\n",(0,t.jsxs)(n.ol,{start:"2",children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Install the ",(0,t.jsx)(n.code,{children:"chainlit"})," package by ",(0,t.jsx)(n.code,{children:"pip install chainlit==1.0.100"})," if you don't have it in your env."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Start the service by running the following command."}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cd playground/UI/\nchainlit run app.py\n"})}),"\n",(0,t.jsxs)(n.ol,{start:"4",children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Open the browser with ",(0,t.jsx)(n.a,{href:"http://localhost:8000",children:"http://localhost:8000"})," and you can start the trial."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Below are some screenshots:\n",(0,t.jsx)(n.img,{alt:"TaskWeaver UI Screenshot 1",src:s(2696).Z+"",width:"1049",height:"739"}),"\n",(0,t.jsx)(n.img,{alt:"TaskWeaver UI Screenshot 2",src:s(1854).Z+"",width:"1058",height:"709"})]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,i.a)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},2696:(e,n,s)=>{s.d(n,{Z:()=>t});const t=s.p+"assets/images/ui_screenshot_1-0d5abb3bdf24df36f88e98ab175a9a06.png"},1854:(e,n,s)=>{s.d(n,{Z:()=>t});const t=s.p+"assets/images/ui_screenshot_2-9aff566449ff321369eba66cdce10ab8.png"},1151:(e,n,s)=>{s.d(n,{Z:()=>o,a:()=>r});var t=s(7294);const i={},a=t.createContext(i);function r(e){const n=t.useContext(a);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),t.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/dfcda4d1.d49fdb6b.js b/assets/js/dfcda4d1.d49fdb6b.js new file mode 100644 index 00000000..ca0189e3 --- /dev/null +++ b/assets/js/dfcda4d1.d49fdb6b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[1916],{9366:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>u,frontMatter:()=>a,metadata:()=>r,toc:()=>l});var s=t(5893),i=t(1151);const a={},o="Web UI",r={id:"usage/webui",title:"Web UI",description:"Please note that this Web UI is for development and testing purposes only.",source:"@site/docs/usage/webui.md",sourceDirName:"usage",slug:"/usage/webui",permalink:"/TaskWeaver/docs/usage/webui",draft:!1,unlisted:!1,editUrl:"https://github.com/microsoft/TaskWeaver/tree/main/website/docs/usage/webui.md",tags:[],version:"current",frontMatter:{},sidebar:"documentSidebar",previous:{title:"Terminal",permalink:"/TaskWeaver/docs/usage/cmd"},next:{title:"Library",permalink:"/TaskWeaver/docs/usage/library"}},c={},l=[];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",img:"img",p:"p",pre:"pre",...(0,i.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"web-ui",children:"Web UI"}),"\n",(0,s.jsx)(n.p,{children:"Please note that this Web UI is for development and testing purposes only."}),"\n",(0,s.jsxs)(n.p,{children:["Follow the instruction in ",(0,s.jsx)(n.a,{href:"/TaskWeaver/docs/quickstart",children:"Quick Start"})," to clone the repository and fill in the necessary configurations."]}),"\n",(0,s.jsxs)(n.p,{children:["Install the ",(0,s.jsx)(n.code,{children:"chainlit"})," package by ",(0,s.jsx)(n.code,{children:"pip install -U chainlit"})," if you don't have it in your environment."]}),"\n",(0,s.jsx)(n.p,{children:"Start the service by running the following command."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"# assume you are in the TaskWeaver folder\ncd playground/UI/\n# make sure you are in playground/UI/ folder\nchainlit run app.py\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Open the browser with ",(0,s.jsx)(n.a,{href:"http://localhost:8000",children:"http://localhost:8000"})," if it doesn't open automatically."]}),"\n",(0,s.jsx)(n.admonition,{type:"info",children:(0,s.jsx)(n.p,{children:"We now support uploading files using the Web UI."})}),"\n",(0,s.jsxs)(n.p,{children:["Below are some screenshots of the Web UI:\n",(0,s.jsx)(n.img,{alt:"TaskWeaver UI Screenshot 1",src:t(2696).Z+"",width:"1049",height:"739"}),"\n",(0,s.jsx)(n.img,{alt:"TaskWeaver UI Screenshot 2",src:t(1854).Z+"",width:"1058",height:"709"})]})]})}function u(e={}){const{wrapper:n}={...(0,i.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},2696:(e,n,t)=>{t.d(n,{Z:()=>s});const s=t.p+"assets/images/ui_screenshot_1-0d5abb3bdf24df36f88e98ab175a9a06.png"},1854:(e,n,t)=>{t.d(n,{Z:()=>s});const s=t.p+"assets/images/ui_screenshot_2-9aff566449ff321369eba66cdce10ab8.png"},1151:(e,n,t)=>{t.d(n,{Z:()=>r,a:()=>o});var s=t(7294);const i={},a=s.createContext(i);function o(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e8e13c91.19d5237a.js b/assets/js/e8e13c91.19d5237a.js new file mode 100644 index 00000000..5f36ffaa --- /dev/null +++ b/assets/js/e8e13c91.19d5237a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[679],{3606:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>r,contentTitle:()=>s,default:()=>h,frontMatter:()=>o,metadata:()=>l,toc:()=>d});var i=n(5893),a=n(1151);const o={id:"multi_yaml_single_impl",description:"Multiple YAML files to one Python implementation",slug:"/plugin/multi_yaml_single_impl"},s="Multiple YAML files to one Python implementation",l={id:"customization/plugin/multi_yaml_single_impl",title:"Multiple YAML files to one Python implementation",description:"Multiple YAML files to one Python implementation",source:"@site/docs/customization/plugin/multi_yaml_single_impl.md",sourceDirName:"customization/plugin",slug:"/plugin/multi_yaml_single_impl",permalink:"/TaskWeaver/docs/plugin/multi_yaml_single_impl",draft:!1,unlisted:!1,editUrl:"https://github.com/microsoft/TaskWeaver/tree/main/website/docs/customization/plugin/multi_yaml_single_impl.md",tags:[],version:"current",frontMatter:{id:"multi_yaml_single_impl",description:"Multiple YAML files to one Python implementation",slug:"/plugin/multi_yaml_single_impl"},sidebar:"documentSidebar",previous:{title:"An Example of Developing a New Plugin",permalink:"/TaskWeaver/docs/plugin/how_to_develop_a_new_plugin"},next:{title:"Customizing Examples",permalink:"/TaskWeaver/docs/customization/example/"}},r={},d=[{value:"Conclusion",id:"conclusion",level:2}];function c(e){const t={code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",...(0,a.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.h1,{id:"multiple-yaml-files-to-one-python-implementation",children:"Multiple YAML files to one Python implementation"}),"\n",(0,i.jsx)(t.p,{children:"In practice, you may want to have multiple plugins that share the same implementation.\nFor example, you may want to have two plugins that both pull data from a database, but one pulls data from database A and the other pulls data from database B.\nIn this case, the plugin implementation code is the same, but the plugin configuration is different.\nIt would be cumbersome to copy and paste the same implementation code to two different files."}),"\n",(0,i.jsx)(t.p,{children:"To solve this problem, TaskWeaver allows you to have multiple plugin configurations that share the same implementation.\nHere is an example of the plugin configuration for the two plugins that pull data from database A and B respectively:"}),"\n",(0,i.jsx)(t.p,{children:"The configuration for the plugin that pulls data from database A:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-yaml",children:'name: sql_pull_data_from_A\ncode: sql_pull_data\n...\ndescription: >-\n Pull data from a SQL database A. The database A contains information about merchandise sales.\nexamples: |-\n df, description = sql_pull_data_from_A("pull data from time_series table")\nparameters:\n ...\nreturns:\n ...\nconfigurations:\n ...\n sqlite_db_path: /path/to/sqlite_A.db\n'})}),"\n",(0,i.jsx)(t.p,{children:"The configuration for the plugin that pulls data from database B:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-yaml",children:'name: sql_pull_data_from_B\ncode: sql_pull_data\n...\ndescription: >-\n Pull data from a SQL database B. The database B contains information about customer information.\nexamples: |-\n df, description = sql_pull_data_from_B("pull data from time_series table")\nparameters:\n ...\nreturns:\n ...\nconfigurations:\n ...\n sqlite_db_path: /path/to/sqlite_B.db\n'})}),"\n",(0,i.jsx)(t.p,{children:"Let's discuss the differences between the two configurations."}),"\n",(0,i.jsxs)(t.p,{children:["First, you can see that the ",(0,i.jsx)(t.code,{children:"name"})," field is different, and the names are different from the python file name (without extension) which is ",(0,i.jsx)(t.code,{children:"sql_pull_data.py"}),".\nThis name is used in CodeInterpreter for code generation. So, you can see that in the ",(0,i.jsx)(t.code,{children:"examples"})," field,\nthe function name is ",(0,i.jsx)(t.code,{children:"sql_pull_data_from_A"})," and ",(0,i.jsx)(t.code,{children:"sql_pull_data_from_B"}),", respectively."]}),"\n",(0,i.jsxs)(t.p,{children:["Second, you can see that the ",(0,i.jsx)(t.code,{children:"code"})," field is the same, and the code file name is ",(0,i.jsx)(t.code,{children:"sql_pull_data.py"}),".\nThis means that the two plugins share the same implementation code.\nThe ",(0,i.jsx)(t.code,{children:"code"})," field is optional, and if you don't specify it, the plugin name will be used as the code file name without the extension."]}),"\n",(0,i.jsxs)(t.p,{children:["Third, you can see that the ",(0,i.jsx)(t.code,{children:"configurations"})," field is different, and the ",(0,i.jsx)(t.code,{children:"sqlite_db_path"})," is different.\nThis means that the two plugins have different configurations.\nThis is typically the key reason why you want to have multiple plugin configurations that share the same implementation."]}),"\n",(0,i.jsxs)(t.p,{children:["Finally, you can see that the ",(0,i.jsx)(t.code,{children:"description"})," field is different, and the descriptions are different.\nThis is important because the Planner and the CodeInterpreter will use the description to make decisions and generate code.\nThe two descriptions should be explicit enough to distinguish the two plugins.\nOtherwise, the Planner and the CodeInterpreter may not be able to make the right decisions."]}),"\n",(0,i.jsx)(t.h2,{id:"conclusion",children:"Conclusion"}),"\n",(0,i.jsxs)(t.p,{children:["When you meet the situation where you want to have multiple plugin configurations that share the same implementation,\nyou can use the ",(0,i.jsx)(t.code,{children:"code"})," field to specify the code file name, and use the ",(0,i.jsx)(t.code,{children:"configurations"})," field to specify the configurations.\nThe ",(0,i.jsx)(t.code,{children:"name"})," field is used to distinguish the plugins, and the ",(0,i.jsx)(t.code,{children:"description"})," field is used to\nhelp the Planner and the CodeInterpreter make right decisions."]})]})}function h(e={}){const{wrapper:t}={...(0,a.a)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},1151:(e,t,n)=>{n.d(t,{Z:()=>l,a:()=>s});var i=n(7294);const a={},o=i.createContext(a);function s(e){const t=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function l(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:s(e.components),i.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e8e13c91.c2d2dd00.js b/assets/js/e8e13c91.c2d2dd00.js deleted file mode 100644 index 937725f8..00000000 --- a/assets/js/e8e13c91.c2d2dd00.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[679],{3606:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>l,default:()=>h,frontMatter:()=>o,metadata:()=>s,toc:()=>r});var i=n(5893),a=n(1151);const o={id:"multi_yaml_single_impl",description:"Multiple YAML files to one Python implementation",slug:"/plugin/multi_yaml_single_impl"},l="Multiple YAML files to one Python implementation",s={id:"customization/plugin/multi_yaml_single_impl",title:"Multiple YAML files to one Python implementation",description:"Multiple YAML files to one Python implementation",source:"@site/docs/customization/plugin/multi_yaml_single_impl.md",sourceDirName:"customization/plugin",slug:"/plugin/multi_yaml_single_impl",permalink:"/TaskWeaver/docs/plugin/multi_yaml_single_impl",draft:!1,unlisted:!1,editUrl:"https://github.com/microsoft/TaskWeaver/tree/main/website/docs/customization/plugin/multi_yaml_single_impl.md",tags:[],version:"current",frontMatter:{id:"multi_yaml_single_impl",description:"Multiple YAML files to one Python implementation",slug:"/plugin/multi_yaml_single_impl"},sidebar:"documentSidebar",previous:{title:"How to develop a new plugin",permalink:"/TaskWeaver/docs/plugin/how_to_develop_a_new_plugin"},next:{title:"The Plugin-Only Mode",permalink:"/TaskWeaver/docs/plugin/plugin_only"}},d={},r=[{value:"Conclusion",id:"conclusion",level:2}];function c(e){const t={code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",...(0,a.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.h1,{id:"multiple-yaml-files-to-one-python-implementation",children:"Multiple YAML files to one Python implementation"}),"\n",(0,i.jsx)(t.p,{children:"In practice, you may want to have multiple plugins that share the same implementation.\nFor example, you may want to have two plugins that both pull data from a database, but one pulls data from database A and the other pulls data from database B.\nIn this case, the plugin implementation code is the same, but the plugin configuration is different.\nIt would be cumbersome to copy and paste the same implementation code to two different files."}),"\n",(0,i.jsx)(t.p,{children:"To solve this problem, TaskWeaver allows you to have multiple plugin configurations that share the same implementation.\nHere is an example of the plugin configuration for the two plugins that pull data from database A and B respectively:"}),"\n",(0,i.jsx)(t.p,{children:"The configuration for the plugin that pulls data from database A:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-yaml",children:'name: sql_pull_data_from_A\ncode: sql_pull_data\n...\ndescription: >-\n Pull data from a SQL database A. The database A contains information about merchandise sales.\nexamples: |-\n df, description = sql_pull_data_from_A("pull data from time_series table")\nparameters:\n ...\nreturns:\n ...\nconfigurations:\n ...\n sqlite_db_path: /path/to/sqlite_A.db\n'})}),"\n",(0,i.jsx)(t.p,{children:"The configuration for the plugin that pulls data from database B:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-yaml",children:'name: sql_pull_data_from_B\ncode: sql_pull_data\n...\ndescription: >-\n Pull data from a SQL database B. The database B contains information about customer information.\nexamples: |-\n df, description = sql_pull_data_from_B("pull data from time_series table")\nparameters:\n ...\nreturns:\n ...\nconfigurations:\n ...\n sqlite_db_path: /path/to/sqlite_B.db\n'})}),"\n",(0,i.jsx)(t.p,{children:"Let's discuss the differences between the two configurations."}),"\n",(0,i.jsxs)(t.p,{children:["First, you can see that the ",(0,i.jsx)(t.code,{children:"name"})," field is different, and the names are different from the python file name (without extension) which is ",(0,i.jsx)(t.code,{children:"sql_pull_data.py"}),".\nThis name is used in CodeInterpreter for code generation. So, you can see that in the ",(0,i.jsx)(t.code,{children:"examples"})," field,\nthe function name is ",(0,i.jsx)(t.code,{children:"sql_pull_data_from_A"})," and ",(0,i.jsx)(t.code,{children:"sql_pull_data_from_B"}),", respectively."]}),"\n",(0,i.jsxs)(t.p,{children:["Second, you can see that the ",(0,i.jsx)(t.code,{children:"code"})," field is the same, and the code file name is ",(0,i.jsx)(t.code,{children:"sql_pull_data.py"}),".\nThis means that the two plugins share the same implementation code.\nThe ",(0,i.jsx)(t.code,{children:"code"})," field is optional, and if you don't specify it, the plugin name will be used as the code file name without the extension."]}),"\n",(0,i.jsxs)(t.p,{children:["Third, you can see that the ",(0,i.jsx)(t.code,{children:"configurations"})," field is different, and the ",(0,i.jsx)(t.code,{children:"sqlite_db_path"})," is different.\nThis means that the two plugins have different configurations.\nThis is typically the key reason why you want to have multiple plugin configurations that share the same implementation."]}),"\n",(0,i.jsxs)(t.p,{children:["Finally, you can see that the ",(0,i.jsx)(t.code,{children:"description"})," field is different, and the descriptions are different.\nThis is important because the Planner and the CodeInterpreter will use the description to make decisions and generate code.\nThe two descriptions should be explicit enough to distinguish the two plugins.\nOtherwise, the Planner and the CodeInterpreter may not be able to make the right decisions."]}),"\n",(0,i.jsx)(t.h2,{id:"conclusion",children:"Conclusion"}),"\n",(0,i.jsxs)(t.p,{children:["When you meet the situation where you want to have multiple plugin configurations that share the same implementation,\nyou can use the ",(0,i.jsx)(t.code,{children:"code"})," field to specify the code file name, and use the ",(0,i.jsx)(t.code,{children:"configurations"})," field to specify the configurations.\nThe ",(0,i.jsx)(t.code,{children:"name"})," field is used to distinguish the plugins, and the ",(0,i.jsx)(t.code,{children:"description"})," field is used to\nhelp the Planner and the CodeInterpreter make right decisions."]})]})}function h(e={}){const{wrapper:t}={...(0,a.a)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},1151:(e,t,n)=>{n.d(t,{Z:()=>s,a:()=>l});var i=n(7294);const a={},o=i.createContext(a);function l(e){const t=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function s(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:l(e.components),i.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/fe04a91d.9fde9fb4.js b/assets/js/fe04a91d.2de13ec3.js similarity index 60% rename from assets/js/fe04a91d.9fde9fb4.js rename to assets/js/fe04a91d.2de13ec3.js index 2599d915..b38a83ef 100644 --- a/assets/js/fe04a91d.9fde9fb4.js +++ b/assets/js/fe04a91d.2de13ec3.js @@ -1 +1 @@ -"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[3424],{1496:e=>{e.exports=JSON.parse('{"title":"Usage Options","description":"Learn how to run TaskWeaver in different ways","slug":"/usage","permalink":"/TaskWeaver/docs/usage","navigation":{"previous":{"title":"Quick Start","permalink":"/TaskWeaver/docs/quickstart"},"next":{"title":"Terminal","permalink":"/TaskWeaver/docs/usage/cmd"}}}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[3424],{1496:e=>{e.exports=JSON.parse('{"title":"Usage Options","description":"Learn how to run TaskWeaver in different ways","slug":"/usage","permalink":"/TaskWeaver/docs/usage","navigation":{"previous":{"title":"FAQ","permalink":"/TaskWeaver/docs/FAQ"},"next":{"title":"Terminal","permalink":"/TaskWeaver/docs/usage/cmd"}}}')}}]); \ No newline at end of file diff --git a/assets/js/main.013320f9.js b/assets/js/main.013320f9.js deleted file mode 100644 index ea60149f..00000000 --- a/assets/js/main.013320f9.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! For license information please see main.013320f9.js.LICENSE.txt */ -(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[179],{1728:(e,t,n)=>{"use strict";function r(e){var t,n,a="";if("string"==typeof e||"number"==typeof e)a+=e;else if("object"==typeof e)if(Array.isArray(e))for(t=0;ta});const a=function(){for(var e,t,n=0,a="";n{"use strict";n.d(t,{Z:()=>f});n(7294);var r=n(8356),a=n.n(r),o=n(6887);const i={"03e8cedb":[()=>n.e(1290).then(n.bind(n,901)),"@site/docs/usage/cmd.md",901],"0c4a3f3a":[()=>n.e(2281).then(n.t.bind(n,7683,19)),"~docs/default/category-taskweaverdocs-documentsidebar-category-llms-1-eeb.json",7683],"14eb3368":[()=>Promise.all([n.e(532),n.e(9817)]).then(n.bind(n,5541)),"@theme/DocCategoryGeneratedIndexPage",5541],17896441:[()=>Promise.all([n.e(532),n.e(7726),n.e(7918)]).then(n.bind(n,230)),"@theme/DocItem",230],"1a4e3797":[()=>Promise.all([n.e(532),n.e(7920)]).then(n.bind(n,2027)),"@theme/SearchPage",2027],"1db64337":[()=>n.e(1372).then(n.bind(n,9674)),"@site/docs/overview.md",9674],"1f391b9e":[()=>Promise.all([n.e(532),n.e(7726),n.e(3085)]).then(n.bind(n,4247)),"@theme/MDXPage",4247],"2114d3cd":[()=>n.e(9190).then(n.bind(n,563)),"@site/docs/advanced/compression.md",563],"2644c4f4":[()=>n.e(9285).then(n.bind(n,3734)),"@site/docs/llms/glm.md",3734],"2726c345":[()=>n.e(3450).then(n.bind(n,286)),"@site/docs/advanced/telemetry.md",286],"30613cee":[()=>n.e(1559).then(n.bind(n,3924)),"@site/docs/advanced/cli_only.md",3924],"360ca471":[()=>n.e(7399).then(n.bind(n,1951)),"@site/docs/customization/plugin/plugin_intro.md",1951],"393be207":[()=>n.e(7414).then(n.bind(n,1181)),"@site/src/pages/markdown-page.md",1181],"3bb29254":[()=>n.e(5887).then(n.bind(n,5461)),"@site/docs/customization/plugin/plugin_selection.md",5461],"45fd52fa":[()=>n.e(3991).then(n.bind(n,186)),"@site/docs/advanced/verification.md",186],"47284eb1":[()=>n.e(6063).then(n.bind(n,9297)),"@site/docs/usage/library.md",9297],"55efe1e1":[()=>n.e(2646).then(n.bind(n,4517)),"@site/docs/llms/aoai.md",4517],"5a1935a3":[()=>n.e(6486).then(n.bind(n,5897)),"@site/docs/configurations/configurations_in_detail.md",5897],"5cde2c1f":[()=>n.e(8693).then(n.bind(n,6360)),"@site/docs/customization/plugin/plugin_only.md",6360],"5e95c892":[()=>n.e(9661).then(n.bind(n,1892)),"@theme/DocsRoot",1892],"5e9f5e1a":[()=>Promise.resolve().then(n.bind(n,6809)),"@generated/docusaurus.config",6809],"61db00e1":[()=>n.e(7288).then(n.t.bind(n,2371,19)),"~docs/default/category-taskweaverdocs-documentsidebar-category-llms-4af.json",2371],"6b4ad289":[()=>n.e(7252).then(n.t.bind(n,3769,19)),"/home/runner/work/TaskWeaver/TaskWeaver/website/.docusaurus/docusaurus-plugin-content-docs/default/plugin-route-context-module-100.json",3769],"72cb6e7f":[()=>n.e(2442).then(n.bind(n,4329)),"@site/docs/usage/docker.md",4329],"7555bb16":[()=>n.e(1018).then(n.bind(n,8359)),"@site/docs/llms/customized_llm_api.md",8359],"7fc9262a":[()=>n.e(746).then(n.bind(n,5333)),"@site/docs/llms/liteLLM.md",5333],"8070e160":[()=>n.e(2651).then(n.bind(n,9759)),"@site/docs/quickstart.md",9759],"834e34cc":[()=>n.e(4471).then(n.bind(n,1550)),"@site/docs/configurations/overview.md",1550],"873331c9":[()=>n.e(776).then(n.bind(n,8930)),"@site/docs/customization/experience.md",8930],"935f2afb":[()=>n.e(53).then(n.t.bind(n,1109,19)),"~docs/default/version-current-metadata-prop-751.json",1109],"93a501ed":[()=>Promise.all([n.e(532),n.e(6008)]).then(n.bind(n,995)),"@site/docs/customization/index.md",995],a4259125:[()=>Promise.all([n.e(532),n.e(419)]).then(n.bind(n,180)),"@site/docs/llms/index.md",180],a55bc7d4:[()=>n.e(4398).then(n.bind(n,9270)),"@site/docs/llms/openai.md",9270],a7bd4aaa:[()=>n.e(8518).then(n.bind(n,8564)),"@theme/DocVersionRoot",8564],a94703ab:[()=>Promise.all([n.e(532),n.e(4368)]).then(n.bind(n,2674)),"@theme/DocRoot",2674],ad895e75:[()=>n.e(4288).then(n.bind(n,1469)),"@site/docs/FAQ.md",1469],ae863774:[()=>n.e(5675).then(n.bind(n,2929)),"@site/docs/customization/example/example.md",2929],b218594a:[()=>n.e(7659).then(n.bind(n,4570)),"@site/docs/advanced/code_execution.md",4570],b21ad4a1:[()=>n.e(2802).then(n.bind(n,5590)),"@site/docs/customization/plugin/how_to_develop_a_new_plugin.md",5590],be4af720:[()=>n.e(8654).then(n.bind(n,3172)),"@site/docs/llms/qwen.md",3172],c4f5d8e4:[()=>Promise.all([n.e(532),n.e(4195)]).then(n.bind(n,3261)),"@site/src/pages/index.js",3261],cf09775e:[()=>n.e(2429).then(n.bind(n,2867)),"@site/docs/llms/gemini.md",2867],d3234990:[()=>n.e(3287).then(n.bind(n,1598)),"@site/docs/llms/multi-llm.md",1598],d385135b:[()=>n.e(5870).then(n.t.bind(n,2776,19)),"/home/runner/work/TaskWeaver/TaskWeaver/website/.docusaurus/@easyops-cn/docusaurus-search-local/default/plugin-route-context-module-100.json",2776],dfcda4d1:[()=>n.e(1916).then(n.bind(n,9366)),"@site/docs/usage/webui.md",9366],e8e13c91:[()=>n.e(679).then(n.bind(n,3606)),"@site/docs/customization/plugin/multi_yaml_single_impl.md",3606],f04cdb7e:[()=>n.e(8905).then(n.bind(n,3995)),"@site/docs/llms/ollama.md",3995],f10ee74f:[()=>n.e(9555).then(n.t.bind(n,5745,19)),"/home/runner/work/TaskWeaver/TaskWeaver/website/.docusaurus/docusaurus-plugin-content-pages/default/plugin-route-context-module-100.json",5745],fbacdda6:[()=>n.e(1070).then(n.t.bind(n,8228,19)),"~docs/default/category-taskweaverdocs-documentsidebar-category-llms-2-4a6.json",8228],fe04a91d:[()=>n.e(3424).then(n.t.bind(n,1496,19)),"~docs/default/category-taskweaverdocs-documentsidebar-category-usage-options-3fa.json",1496]};var s=n(5893);function l(e){let{error:t,retry:n,pastDelay:r}=e;return t?(0,s.jsxs)("div",{style:{textAlign:"center",color:"#fff",backgroundColor:"#fa383e",borderColor:"#fa383e",borderStyle:"solid",borderRadius:"0.25rem",borderWidth:"1px",boxSizing:"border-box",display:"block",padding:"1rem",flex:"0 0 50%",marginLeft:"25%",marginRight:"25%",marginTop:"5rem",maxWidth:"50%",width:"100%"},children:[(0,s.jsx)("p",{children:String(t)}),(0,s.jsx)("div",{children:(0,s.jsx)("button",{type:"button",onClick:n,children:"Retry"})})]}):r?(0,s.jsx)("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",height:"100vh"},children:(0,s.jsx)("svg",{id:"loader",style:{width:128,height:110,position:"absolute",top:"calc(100vh - 64%)"},viewBox:"0 0 45 45",xmlns:"http://www.w3.org/2000/svg",stroke:"#61dafb",children:(0,s.jsxs)("g",{fill:"none",fillRule:"evenodd",transform:"translate(1 1)",strokeWidth:"2",children:[(0,s.jsxs)("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0",children:[(0,s.jsx)("animate",{attributeName:"r",begin:"1.5s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),(0,s.jsx)("animate",{attributeName:"stroke-opacity",begin:"1.5s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),(0,s.jsx)("animate",{attributeName:"stroke-width",begin:"1.5s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})]}),(0,s.jsxs)("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0",children:[(0,s.jsx)("animate",{attributeName:"r",begin:"3s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),(0,s.jsx)("animate",{attributeName:"stroke-opacity",begin:"3s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),(0,s.jsx)("animate",{attributeName:"stroke-width",begin:"3s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})]}),(0,s.jsx)("circle",{cx:"22",cy:"22",r:"8",children:(0,s.jsx)("animate",{attributeName:"r",begin:"0s",dur:"1.5s",values:"6;1;2;3;4;5;6",calcMode:"linear",repeatCount:"indefinite"})})]})})}):null}var u=n(9670),c=n(226);function d(e,t){if("*"===e)return a()({loading:l,loader:()=>n.e(1772).then(n.bind(n,1772)),modules:["@theme/NotFound"],webpack:()=>[1772],render(e,t){const n=e.default;return(0,s.jsx)(c.z,{value:{plugin:{name:"native",id:"default"}},children:(0,s.jsx)(n,{...t})})}});const r=o[`${e}-${t}`],d={},f=[],p=[],h=(0,u.Z)(r);return Object.entries(h).forEach((e=>{let[t,n]=e;const r=i[n];r&&(d[t]=r[0],f.push(r[1]),p.push(r[2]))})),a().Map({loading:l,loader:d,modules:f,webpack:()=>p,render(t,n){const a=JSON.parse(JSON.stringify(r));Object.entries(t).forEach((t=>{let[n,r]=t;const o=r.default;if(!o)throw new Error(`The page component at ${e} doesn't have a default export. This makes it impossible to render anything. Consider default-exporting a React component.`);"object"!=typeof o&&"function"!=typeof o||Object.keys(r).filter((e=>"default"!==e)).forEach((e=>{o[e]=r[e]}));let i=a;const s=n.split(".");s.slice(0,-1).forEach((e=>{i=i[e]})),i[s[s.length-1]]=o}));const o=a.__comp;delete a.__comp;const i=a.__context;return delete a.__context,(0,s.jsx)(c.z,{value:i,children:(0,s.jsx)(o,{...a,...n})})}})}const f=[{path:"/TaskWeaver/markdown-page",component:d("/TaskWeaver/markdown-page","982"),exact:!0},{path:"/TaskWeaver/search",component:d("/TaskWeaver/search","a6e"),exact:!0},{path:"/TaskWeaver/docs",component:d("/TaskWeaver/docs","32b"),routes:[{path:"/TaskWeaver/docs",component:d("/TaskWeaver/docs","292"),routes:[{path:"/TaskWeaver/docs",component:d("/TaskWeaver/docs","0d3"),routes:[{path:"/TaskWeaver/docs/advanced",component:d("/TaskWeaver/docs/advanced","79d"),exact:!0,sidebar:"documentSidebar"},{path:"/TaskWeaver/docs/advanced/cli_only",component:d("/TaskWeaver/docs/advanced/cli_only","293"),exact:!0,sidebar:"documentSidebar"},{path:"/TaskWeaver/docs/advanced/code_execution",component:d("/TaskWeaver/docs/advanced/code_execution","337"),exact:!0,sidebar:"documentSidebar"},{path:"/TaskWeaver/docs/advanced/code_verification",component:d("/TaskWeaver/docs/advanced/code_verification","14e"),exact:!0,sidebar:"documentSidebar"},{path:"/TaskWeaver/docs/advanced/compression",component:d("/TaskWeaver/docs/advanced/compression","74f"),exact:!0,sidebar:"documentSidebar"},{path:"/TaskWeaver/docs/advanced/telemetry",component:d("/TaskWeaver/docs/advanced/telemetry","74c"),exact:!0,sidebar:"documentSidebar"},{path:"/TaskWeaver/docs/configurations/configurations_in_detail",component:d("/TaskWeaver/docs/configurations/configurations_in_detail","118"),exact:!0,sidebar:"documentSidebar"},{path:"/TaskWeaver/docs/configurations/overview",component:d("/TaskWeaver/docs/configurations/overview","ac6"),exact:!0,sidebar:"documentSidebar"},{path:"/TaskWeaver/docs/customization",component:d("/TaskWeaver/docs/customization","176"),exact:!0,sidebar:"documentSidebar"},{path:"/TaskWeaver/docs/customization/",component:d("/TaskWeaver/docs/customization/","72b"),exact:!0},{path:"/TaskWeaver/docs/customization/example/",component:d("/TaskWeaver/docs/customization/example/","9f9"),exact:!0,sidebar:"documentSidebar"},{path:"/TaskWeaver/docs/customization/experience",component:d("/TaskWeaver/docs/customization/experience","409"),exact:!0,sidebar:"documentSidebar"},{path:"/TaskWeaver/docs/customization/plugin/plugin_selection",component:d("/TaskWeaver/docs/customization/plugin/plugin_selection","11d"),exact:!0,sidebar:"documentSidebar"},{path:"/TaskWeaver/docs/FAQ",component:d("/TaskWeaver/docs/FAQ","cee"),exact:!0,sidebar:"documentSidebar"},{path:"/TaskWeaver/docs/llms",component:d("/TaskWeaver/docs/llms","3af"),exact:!0,sidebar:"documentSidebar"},{path:"/TaskWeaver/docs/llms/",component:d("/TaskWeaver/docs/llms/","aac"),exact:!0},{path:"/TaskWeaver/docs/llms/aoai",component:d("/TaskWeaver/docs/llms/aoai","024"),exact:!0,sidebar:"documentSidebar"},{path:"/TaskWeaver/docs/llms/customized_llm_api",component:d("/TaskWeaver/docs/llms/customized_llm_api","d01"),exact:!0,sidebar:"documentSidebar"},{path:"/TaskWeaver/docs/llms/gemini",component:d("/TaskWeaver/docs/llms/gemini","87e"),exact:!0,sidebar:"documentSidebar"},{path:"/TaskWeaver/docs/llms/glm",component:d("/TaskWeaver/docs/llms/glm","9d8"),exact:!0,sidebar:"documentSidebar"},{path:"/TaskWeaver/docs/llms/liteLLM",component:d("/TaskWeaver/docs/llms/liteLLM","d7f"),exact:!0,sidebar:"documentSidebar"},{path:"/TaskWeaver/docs/llms/multi-llm",component:d("/TaskWeaver/docs/llms/multi-llm","b4a"),exact:!0,sidebar:"documentSidebar"},{path:"/TaskWeaver/docs/llms/ollama",component:d("/TaskWeaver/docs/llms/ollama","9d4"),exact:!0,sidebar:"documentSidebar"},{path:"/TaskWeaver/docs/llms/openai",component:d("/TaskWeaver/docs/llms/openai","0db"),exact:!0,sidebar:"documentSidebar"},{path:"/TaskWeaver/docs/llms/qwen",component:d("/TaskWeaver/docs/llms/qwen","668"),exact:!0,sidebar:"documentSidebar"},{path:"/TaskWeaver/docs/overview",component:d("/TaskWeaver/docs/overview","cc3"),exact:!0,sidebar:"documentSidebar"},{path:"/TaskWeaver/docs/plugin/how_to_develop_a_new_plugin",component:d("/TaskWeaver/docs/plugin/how_to_develop_a_new_plugin","b6b"),exact:!0,sidebar:"documentSidebar"},{path:"/TaskWeaver/docs/plugin/multi_yaml_single_impl",component:d("/TaskWeaver/docs/plugin/multi_yaml_single_impl","514"),exact:!0,sidebar:"documentSidebar"},{path:"/TaskWeaver/docs/plugin/plugin_intro",component:d("/TaskWeaver/docs/plugin/plugin_intro","d35"),exact:!0,sidebar:"documentSidebar"},{path:"/TaskWeaver/docs/plugin/plugin_only",component:d("/TaskWeaver/docs/plugin/plugin_only","096"),exact:!0,sidebar:"documentSidebar"},{path:"/TaskWeaver/docs/quickstart",component:d("/TaskWeaver/docs/quickstart","1a5"),exact:!0,sidebar:"documentSidebar"},{path:"/TaskWeaver/docs/usage",component:d("/TaskWeaver/docs/usage","b52"),exact:!0,sidebar:"documentSidebar"},{path:"/TaskWeaver/docs/usage/cmd",component:d("/TaskWeaver/docs/usage/cmd","afa"),exact:!0,sidebar:"documentSidebar"},{path:"/TaskWeaver/docs/usage/docker",component:d("/TaskWeaver/docs/usage/docker","9d5"),exact:!0,sidebar:"documentSidebar"},{path:"/TaskWeaver/docs/usage/library",component:d("/TaskWeaver/docs/usage/library","184"),exact:!0,sidebar:"documentSidebar"},{path:"/TaskWeaver/docs/usage/webui",component:d("/TaskWeaver/docs/usage/webui","560"),exact:!0,sidebar:"documentSidebar"}]}]}]},{path:"/TaskWeaver/",component:d("/TaskWeaver/","b87"),exact:!0},{path:"*",component:d("*")}]},8934:(e,t,n)=>{"use strict";n.d(t,{_:()=>o,t:()=>i});var r=n(7294),a=n(5893);const o=r.createContext(!1);function i(e){let{children:t}=e;const[n,i]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{i(!0)}),[]),(0,a.jsx)(o.Provider,{value:n,children:t})}},7221:(e,t,n)=>{"use strict";var r=n(7294),a=n(745),o=n(3727),i=n(405),s=n(412);const l=[n(2497),n(3310),n(8320),n(2295)];var u=n(723),c=n(6550),d=n(8790),f=n(5893);function p(e){let{children:t}=e;return(0,f.jsx)(f.Fragment,{children:t})}var h=n(5742),m=n(2263),g=n(4996),y=n(6668),b=n(1944),v=n(4711),k=n(9727),w=n(3320),x=n(8780),S=n(197);function E(){const{i18n:{currentLocale:e,defaultLocale:t,localeConfigs:n}}=(0,m.Z)(),r=(0,v.l)(),a=n[e].htmlLang,o=e=>e.replace("-","_");return(0,f.jsxs)(h.Z,{children:[Object.entries(n).map((e=>{let[t,{htmlLang:n}]=e;return(0,f.jsx)("link",{rel:"alternate",href:r.createUrl({locale:t,fullyQualified:!0}),hrefLang:n},t)})),(0,f.jsx)("link",{rel:"alternate",href:r.createUrl({locale:t,fullyQualified:!0}),hrefLang:"x-default"}),(0,f.jsx)("meta",{property:"og:locale",content:o(a)}),Object.values(n).filter((e=>a!==e.htmlLang)).map((e=>(0,f.jsx)("meta",{property:"og:locale:alternate",content:o(e.htmlLang)},`meta-og-${e.htmlLang}`)))]})}function _(e){let{permalink:t}=e;const{siteConfig:{url:n}}=(0,m.Z)(),r=function(){const{siteConfig:{url:e,baseUrl:t,trailingSlash:n}}=(0,m.Z)(),{pathname:r}=(0,c.TH)();return e+(0,x.applyTrailingSlash)((0,g.Z)(r),{trailingSlash:n,baseUrl:t})}(),a=t?`${n}${t}`:r;return(0,f.jsxs)(h.Z,{children:[(0,f.jsx)("meta",{property:"og:url",content:a}),(0,f.jsx)("link",{rel:"canonical",href:a})]})}function T(){const{i18n:{currentLocale:e}}=(0,m.Z)(),{metadata:t,image:n}=(0,y.L)();return(0,f.jsxs)(f.Fragment,{children:[(0,f.jsxs)(h.Z,{children:[(0,f.jsx)("meta",{name:"twitter:card",content:"summary_large_image"}),(0,f.jsx)("body",{className:k.h})]}),n&&(0,f.jsx)(b.d,{image:n}),(0,f.jsx)(_,{}),(0,f.jsx)(E,{}),(0,f.jsx)(S.Z,{tag:w.HX,locale:e}),(0,f.jsx)(h.Z,{children:t.map(((e,t)=>(0,f.jsx)("meta",{...e},t)))})]})}const C=new Map;function L(e){if(C.has(e.pathname))return{...e,pathname:C.get(e.pathname)};if((0,d.f)(u.Z,e.pathname).some((e=>{let{route:t}=e;return!0===t.exact})))return C.set(e.pathname,e.pathname),e;const t=e.pathname.trim().replace(/(?:\/index)?\.html$/,"")||"/";return C.set(e.pathname,t),{...e,pathname:t}}var N=n(8934),A=n(8940),P=n(469);function O(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r{const r=t.default?.[e]??t[e];return r?.(...n)}));return()=>a.forEach((e=>e?.()))}const I=function(e){let{children:t,location:n,previousLocation:r}=e;return(0,P.Z)((()=>{r!==n&&(!function(e){let{location:t,previousLocation:n}=e;if(!n)return;const r=t.pathname===n.pathname,a=t.hash===n.hash,o=t.search===n.search;if(r&&a&&!o)return;const{hash:i}=t;if(i){const e=decodeURIComponent(i.substring(1)),t=document.getElementById(e);t?.scrollIntoView()}else window.scrollTo(0,0)}({location:n,previousLocation:r}),O("onRouteDidUpdate",{previousLocation:r,location:n}))}),[r,n]),t};function j(e){const t=Array.from(new Set([e,decodeURI(e)])).map((e=>(0,d.f)(u.Z,e))).flat();return Promise.all(t.map((e=>e.route.component.preload?.())))}class R extends r.Component{previousLocation;routeUpdateCleanupCb;constructor(e){super(e),this.previousLocation=null,this.routeUpdateCleanupCb=s.Z.canUseDOM?O("onRouteUpdate",{previousLocation:null,location:this.props.location}):()=>{},this.state={nextRouteHasLoaded:!0}}shouldComponentUpdate(e,t){if(e.location===this.props.location)return t.nextRouteHasLoaded;const n=e.location;return this.previousLocation=this.props.location,this.setState({nextRouteHasLoaded:!1}),this.routeUpdateCleanupCb=O("onRouteUpdate",{previousLocation:this.previousLocation,location:n}),j(n.pathname).then((()=>{this.routeUpdateCleanupCb(),this.setState({nextRouteHasLoaded:!0})})).catch((e=>{console.warn(e),window.location.reload()})),!1}render(){const{children:e,location:t}=this.props;return(0,f.jsx)(I,{previousLocation:this.previousLocation,location:t,children:(0,f.jsx)(c.AW,{location:t,render:()=>e})})}}const F=R,D="__docusaurus-base-url-issue-banner-container",M="__docusaurus-base-url-issue-banner",z="__docusaurus-base-url-issue-banner-suggestion-container";function B(e){return`\ndocument.addEventListener('DOMContentLoaded', function maybeInsertBanner() {\n var shouldInsert = typeof window['docusaurus'] === 'undefined';\n shouldInsert && insertBanner();\n});\n\nfunction insertBanner() {\n var bannerContainer = document.createElement('div');\n bannerContainer.id = '${D}';\n var bannerHtml = ${JSON.stringify(function(e){return`\n
\n

Your Docusaurus site did not load properly.

\n

A very common reason is a wrong site baseUrl configuration.

\n

Current configured baseUrl = ${e} ${"/"===e?" (default value)":""}

\n

We suggest trying baseUrl =

\n
\n`}(e)).replace(/{if("undefined"==typeof document)return void n();const r=document.createElement("link");r.setAttribute("rel","prefetch"),r.setAttribute("href",e),r.onload=()=>t(),r.onerror=()=>n();const a=document.getElementsByTagName("head")[0]??document.getElementsByName("script")[0]?.parentNode;a?.appendChild(r)}))}:function(e){return new Promise(((t,n)=>{const r=new XMLHttpRequest;r.open("GET",e,!0),r.withCredentials=!0,r.onload=()=>{200===r.status?t():n()},r.send(null)}))};var Y=n(9670);const K=new Set,X=new Set,J=()=>navigator.connection?.effectiveType.includes("2g")||navigator.connection?.saveData,ee={prefetch(e){if(!(e=>!J()&&!X.has(e)&&!K.has(e))(e))return!1;K.add(e);const t=(0,d.f)(u.Z,e).flatMap((e=>{return t=e.route.path,Object.entries(q).filter((e=>{let[n]=e;return n.replace(/-[^-]+$/,"")===t})).flatMap((e=>{let[,t]=e;return Object.values((0,Y.Z)(t))}));var t}));return Promise.all(t.map((e=>{const t=n.gca(e);return t&&!t.includes("undefined")?G(t).catch((()=>{})):Promise.resolve()})))},preload:e=>!!(e=>!J()&&!X.has(e))(e)&&(X.add(e),j(e))},te=Object.freeze(ee),ne=Boolean(!0);if(s.Z.canUseDOM){window.docusaurus=te;const e=document.getElementById("__docusaurus"),t=(0,f.jsx)(i.B6,{children:(0,f.jsx)(o.VK,{children:(0,f.jsx)(V,{})})}),n=(e,t)=>{console.error("Docusaurus React Root onRecoverableError:",e,t)},s=()=>{if(ne)r.startTransition((()=>{a.hydrateRoot(e,t,{onRecoverableError:n})}));else{const o=a.createRoot(e,{onRecoverableError:n});r.startTransition((()=>{o.render(t)}))}};j(window.location.pathname).then(s)}},8940:(e,t,n)=>{"use strict";n.d(t,{_:()=>d,M:()=>f});var r=n(7294),a=n(6809);const o=JSON.parse('{"docusaurus-plugin-content-docs":{"default":{"path":"/TaskWeaver/docs","versions":[{"name":"current","label":"Next","isLast":true,"path":"/TaskWeaver/docs","mainDocId":"overview","docs":[{"id":"advanced/cli_only","path":"/TaskWeaver/docs/advanced/cli_only","sidebar":"documentSidebar"},{"id":"advanced/code_execution","path":"/TaskWeaver/docs/advanced/code_execution","sidebar":"documentSidebar"},{"id":"advanced/code_verification","path":"/TaskWeaver/docs/advanced/code_verification","sidebar":"documentSidebar"},{"id":"advanced/compression","path":"/TaskWeaver/docs/advanced/compression","sidebar":"documentSidebar"},{"id":"advanced/telemetry","path":"/TaskWeaver/docs/advanced/telemetry","sidebar":"documentSidebar"},{"id":"configurations/configurations_in_detail","path":"/TaskWeaver/docs/configurations/configurations_in_detail","sidebar":"documentSidebar"},{"id":"configurations/overview","path":"/TaskWeaver/docs/configurations/overview","sidebar":"documentSidebar"},{"id":"customization/example/example","path":"/TaskWeaver/docs/customization/example/","sidebar":"documentSidebar"},{"id":"customization/experience","path":"/TaskWeaver/docs/customization/experience","sidebar":"documentSidebar"},{"id":"customization/index","path":"/TaskWeaver/docs/customization/"},{"id":"customization/plugin/develop_plugin","path":"/TaskWeaver/docs/plugin/how_to_develop_a_new_plugin","sidebar":"documentSidebar"},{"id":"customization/plugin/multi_yaml_single_impl","path":"/TaskWeaver/docs/plugin/multi_yaml_single_impl","sidebar":"documentSidebar"},{"id":"customization/plugin/plugin_intro","path":"/TaskWeaver/docs/plugin/plugin_intro","sidebar":"documentSidebar"},{"id":"customization/plugin/plugin_only","path":"/TaskWeaver/docs/plugin/plugin_only","sidebar":"documentSidebar"},{"id":"customization/plugin/plugin_selection","path":"/TaskWeaver/docs/customization/plugin/plugin_selection","sidebar":"documentSidebar"},{"id":"FAQ","path":"/TaskWeaver/docs/FAQ","sidebar":"documentSidebar"},{"id":"llms/aoai","path":"/TaskWeaver/docs/llms/aoai","sidebar":"documentSidebar"},{"id":"llms/customized_llm_api","path":"/TaskWeaver/docs/llms/customized_llm_api","sidebar":"documentSidebar"},{"id":"llms/gemini","path":"/TaskWeaver/docs/llms/gemini","sidebar":"documentSidebar"},{"id":"llms/glm","path":"/TaskWeaver/docs/llms/glm","sidebar":"documentSidebar"},{"id":"llms/index","path":"/TaskWeaver/docs/llms/"},{"id":"llms/liteLLM","path":"/TaskWeaver/docs/llms/liteLLM","sidebar":"documentSidebar"},{"id":"llms/multi-llm","path":"/TaskWeaver/docs/llms/multi-llm","sidebar":"documentSidebar"},{"id":"llms/ollama","path":"/TaskWeaver/docs/llms/ollama","sidebar":"documentSidebar"},{"id":"llms/openai","path":"/TaskWeaver/docs/llms/openai","sidebar":"documentSidebar"},{"id":"llms/qwen","path":"/TaskWeaver/docs/llms/qwen","sidebar":"documentSidebar"},{"id":"overview","path":"/TaskWeaver/docs/overview","sidebar":"documentSidebar"},{"id":"quickstart","path":"/TaskWeaver/docs/quickstart","sidebar":"documentSidebar"},{"id":"usage/cmd","path":"/TaskWeaver/docs/usage/cmd","sidebar":"documentSidebar"},{"id":"usage/docker","path":"/TaskWeaver/docs/usage/docker","sidebar":"documentSidebar"},{"id":"usage/library","path":"/TaskWeaver/docs/usage/library","sidebar":"documentSidebar"},{"id":"usage/webui","path":"/TaskWeaver/docs/usage/webui","sidebar":"documentSidebar"},{"id":"/usage","path":"/TaskWeaver/docs/usage","sidebar":"documentSidebar"},{"id":"/llms","path":"/TaskWeaver/docs/llms","sidebar":"documentSidebar"},{"id":"advanced","path":"/TaskWeaver/docs/advanced","sidebar":"documentSidebar"},{"id":"customization","path":"/TaskWeaver/docs/customization","sidebar":"documentSidebar"}],"draftIds":[],"sidebars":{"documentSidebar":{"link":{"path":"/TaskWeaver/docs/overview","label":"overview"}}}}],"breadcrumbs":true}}}'),i=JSON.parse('{"defaultLocale":"en","locales":["en"],"path":"i18n","currentLocale":"en","localeConfigs":{"en":{"label":"English","direction":"ltr","htmlLang":"en","calendar":"gregory","path":"en"}}}');var s=n(7529);const l=JSON.parse('{"docusaurusVersion":"3.0.1","siteVersion":"0.0.0","pluginVersions":{"docusaurus-plugin-content-docs":{"type":"package","name":"@docusaurus/plugin-content-docs","version":"3.0.1"},"docusaurus-plugin-content-blog":{"type":"package","name":"@docusaurus/plugin-content-blog","version":"3.0.1"},"docusaurus-plugin-content-pages":{"type":"package","name":"@docusaurus/plugin-content-pages","version":"3.0.1"},"docusaurus-plugin-sitemap":{"type":"package","name":"@docusaurus/plugin-sitemap","version":"3.0.1"},"docusaurus-theme-classic":{"type":"package","name":"@docusaurus/theme-classic","version":"3.0.1"},"@easyops-cn/docusaurus-search-local":{"type":"package","name":"@easyops-cn/docusaurus-search-local","version":"0.40.0"},"docusaurus-theme-mermaid":{"type":"package","name":"@docusaurus/theme-mermaid","version":"3.0.1"}}}');var u=n(5893);const c={siteConfig:a.default,siteMetadata:l,globalData:o,i18n:i,codeTranslations:s},d=r.createContext(c);function f(e){let{children:t}=e;return(0,u.jsx)(d.Provider,{value:c,children:t})}},4763:(e,t,n)=>{"use strict";n.d(t,{Z:()=>p});var r=n(7294),a=n(412),o=n(5742),i=n(8780),s=n(2045),l=n(5893);function u(e){let{error:t,tryAgain:n}=e;return(0,l.jsxs)("div",{style:{display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"flex-start",minHeight:"100vh",width:"100%",maxWidth:"80ch",fontSize:"20px",margin:"0 auto",padding:"1rem"},children:[(0,l.jsx)("h1",{style:{fontSize:"3rem"},children:"This page crashed"}),(0,l.jsx)("button",{type:"button",onClick:n,style:{margin:"1rem 0",fontSize:"2rem",cursor:"pointer",borderRadius:20,padding:"1rem"},children:"Try again"}),(0,l.jsx)(c,{error:t})]})}function c(e){let{error:t}=e;const n=(0,i.getErrorCausalChain)(t).map((e=>e.message)).join("\n\nCause:\n");return(0,l.jsx)("p",{style:{whiteSpace:"pre-wrap"},children:n})}function d(e){let{error:t,tryAgain:n}=e;return(0,l.jsxs)(p,{fallback:()=>(0,l.jsx)(u,{error:t,tryAgain:n}),children:[(0,l.jsx)(o.Z,{children:(0,l.jsx)("title",{children:"Page Error"})}),(0,l.jsx)(s.Z,{children:(0,l.jsx)(u,{error:t,tryAgain:n})})]})}const f=e=>(0,l.jsx)(d,{...e});class p extends r.Component{constructor(e){super(e),this.state={error:null}}componentDidCatch(e){a.Z.canUseDOM&&this.setState({error:e})}render(){const{children:e}=this.props,{error:t}=this.state;if(t){const e={error:t,tryAgain:()=>this.setState({error:null})};return(this.props.fallback??f)(e)}return e??null}}},412:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});const r="undefined"!=typeof window&&"document"in window&&"createElement"in window.document,a={canUseDOM:r,canUseEventListeners:r&&("addEventListener"in window||"attachEvent"in window),canUseIntersectionObserver:r&&"IntersectionObserver"in window,canUseViewport:r&&"screen"in window}},5742:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});n(7294);var r=n(405),a=n(5893);function o(e){return(0,a.jsx)(r.ql,{...e})}},9960:(e,t,n)=>{"use strict";n.d(t,{Z:()=>p});var r=n(7294),a=n(3727),o=n(8780),i=n(2263),s=n(3919),l=n(412),u=n(5893);const c=r.createContext({collectLink:()=>{}});var d=n(4996);function f(e,t){let{isNavLink:n,to:f,href:p,activeClassName:h,isActive:m,"data-noBrokenLinkCheck":g,autoAddBaseUrl:y=!0,...b}=e;const{siteConfig:{trailingSlash:v,baseUrl:k}}=(0,i.Z)(),{withBaseUrl:w}=(0,d.C)(),x=(0,r.useContext)(c),S=(0,r.useRef)(null);(0,r.useImperativeHandle)(t,(()=>S.current));const E=f||p;const _=(0,s.Z)(E),T=E?.replace("pathname://","");let C=void 0!==T?(L=T,y&&(e=>e.startsWith("/"))(L)?w(L):L):void 0;var L;C&&_&&(C=(0,o.applyTrailingSlash)(C,{trailingSlash:v,baseUrl:k}));const N=(0,r.useRef)(!1),A=n?a.OL:a.rU,P=l.Z.canUseIntersectionObserver,O=(0,r.useRef)(),I=()=>{N.current||null==C||(window.docusaurus.preload(C),N.current=!0)};(0,r.useEffect)((()=>(!P&&_&&null!=C&&window.docusaurus.prefetch(C),()=>{P&&O.current&&O.current.disconnect()})),[O,C,P,_]);const j=C?.startsWith("#")??!1,R=!C||!_||j;return R||g||x.collectLink(C),R?(0,u.jsx)("a",{ref:S,href:C,...E&&!_&&{target:"_blank",rel:"noopener noreferrer"},...b}):(0,u.jsx)(A,{...b,onMouseEnter:I,onTouchStart:I,innerRef:e=>{S.current=e,P&&e&&_&&(O.current=new window.IntersectionObserver((t=>{t.forEach((t=>{e===t.target&&(t.isIntersecting||t.intersectionRatio>0)&&(O.current.unobserve(e),O.current.disconnect(),null!=C&&window.docusaurus.prefetch(C))}))})),O.current.observe(e))},to:C,...n&&{isActive:m,activeClassName:h}})}const p=r.forwardRef(f)},5999:(e,t,n)=>{"use strict";n.d(t,{Z:()=>u,I:()=>l});var r=n(7294),a=n(5893);function o(e,t){const n=e.split(/(\{\w+\})/).map(((e,n)=>{if(n%2==1){const n=t?.[e.slice(1,-1)];if(void 0!==n)return n}return e}));return n.some((e=>(0,r.isValidElement)(e)))?n.map(((e,t)=>(0,r.isValidElement)(e)?r.cloneElement(e,{key:t}):e)).filter((e=>""!==e)):n.join("")}var i=n(7529);function s(e){let{id:t,message:n}=e;if(void 0===t&&void 0===n)throw new Error("Docusaurus translation declarations must have at least a translation id or a default translation message");return i[t??n]??n??t}function l(e,t){let{message:n,id:r}=e;return o(s({message:n,id:r}),t)}function u(e){let{children:t,id:n,values:r}=e;if(t&&"string"!=typeof t)throw console.warn("Illegal children",t),new Error("The Docusaurus component only accept simple string values");const i=s({message:t,id:n});return(0,a.jsx)(a.Fragment,{children:o(i,r)})}},9935:(e,t,n)=>{"use strict";n.d(t,{m:()=>r});const r="default"},3919:(e,t,n)=>{"use strict";function r(e){return/^(?:\w*:|\/\/)/.test(e)}function a(e){return void 0!==e&&!r(e)}n.d(t,{Z:()=>a,b:()=>r})},4996:(e,t,n)=>{"use strict";n.d(t,{C:()=>i,Z:()=>s});var r=n(7294),a=n(2263),o=n(3919);function i(){const{siteConfig:{baseUrl:e,url:t}}=(0,a.Z)(),n=(0,r.useCallback)(((n,r)=>function(e,t,n,r){let{forcePrependBaseUrl:a=!1,absolute:i=!1}=void 0===r?{}:r;if(!n||n.startsWith("#")||(0,o.b)(n))return n;if(a)return t+n.replace(/^\//,"");if(n===t.replace(/\/$/,""))return t;const s=n.startsWith(t)?n:t+n.replace(/^\//,"");return i?e+s:s}(t,e,n,r)),[t,e]);return{withBaseUrl:n}}function s(e,t){void 0===t&&(t={});const{withBaseUrl:n}=i();return n(e,t)}},2263:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(7294),a=n(8940);function o(){return(0,r.useContext)(a._)}},2389:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(7294),a=n(8934);function o(){return(0,r.useContext)(a._)}},469:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(7294);const a=n(412).Z.canUseDOM?r.useLayoutEffect:r.useEffect},9670:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});const r=e=>"object"==typeof e&&!!e&&Object.keys(e).length>0;function a(e){const t={};return function e(n,a){Object.entries(n).forEach((n=>{let[o,i]=n;const s=a?`${a}.${o}`:o;r(i)?e(i,s):t[s]=i}))}(e),t}},226:(e,t,n)=>{"use strict";n.d(t,{_:()=>o,z:()=>i});var r=n(7294),a=n(5893);const o=r.createContext(null);function i(e){let{children:t,value:n}=e;const i=r.useContext(o),s=(0,r.useMemo)((()=>function(e){let{parent:t,value:n}=e;if(!t){if(!n)throw new Error("Unexpected: no Docusaurus route context found");if(!("plugin"in n))throw new Error("Unexpected: Docusaurus topmost route context has no `plugin` attribute");return n}const r={...t.data,...n?.data};return{plugin:t.plugin,data:r}}({parent:i,value:n})),[i,n]);return(0,a.jsx)(o.Provider,{value:s,children:t})}},143:(e,t,n)=>{"use strict";n.d(t,{Iw:()=>m,gA:()=>f,_r:()=>c,Jo:()=>g,zh:()=>d,yW:()=>h,gB:()=>p});var r=n(6550),a=n(2263),o=n(9935);function i(e,t){void 0===t&&(t={});const n=function(){const{globalData:e}=(0,a.Z)();return e}()[e];if(!n&&t.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin.`);return n}const s=e=>e.versions.find((e=>e.isLast));function l(e,t){const n=function(e,t){const n=s(e);return[...e.versions.filter((e=>e!==n)),n].find((e=>!!(0,r.LX)(t,{path:e.path,exact:!1,strict:!1})))}(e,t),a=n?.docs.find((e=>!!(0,r.LX)(t,{path:e.path,exact:!0,strict:!1})));return{activeVersion:n,activeDoc:a,alternateDocVersions:a?function(t){const n={};return e.versions.forEach((e=>{e.docs.forEach((r=>{r.id===t&&(n[e.name]=r)}))})),n}(a.id):{}}}const u={},c=()=>i("docusaurus-plugin-content-docs")??u,d=e=>function(e,t,n){void 0===t&&(t=o.m),void 0===n&&(n={});const r=i(e),a=r?.[t];if(!a&&n.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin with id "${t}".`);return a}("docusaurus-plugin-content-docs",e,{failfast:!0});function f(e){void 0===e&&(e={});const t=c(),{pathname:n}=(0,r.TH)();return function(e,t,n){void 0===n&&(n={});const a=Object.entries(e).sort(((e,t)=>t[1].path.localeCompare(e[1].path))).find((e=>{let[,n]=e;return!!(0,r.LX)(t,{path:n.path,exact:!1,strict:!1})})),o=a?{pluginId:a[0],pluginData:a[1]}:void 0;if(!o&&n.failfast)throw new Error(`Can't find active docs plugin for "${t}" pathname, while it was expected to be found. Maybe you tried to use a docs feature that can only be used on a docs-related page? Existing docs plugin paths are: ${Object.values(e).map((e=>e.path)).join(", ")}`);return o}(t,n,e)}function p(e){return d(e).versions}function h(e){const t=d(e);return s(t)}function m(e){const t=d(e),{pathname:n}=(0,r.TH)();return l(t,n)}function g(e){const t=d(e),{pathname:n}=(0,r.TH)();return function(e,t){const n=s(e);return{latestDocSuggestion:l(e,t).alternateDocVersions[n.name],latestVersionSuggestion:n}}(t,n)}},8320:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>o});var r=n(4865),a=n.n(r);a().configure({showSpinner:!1});const o={onRouteUpdate(e){let{location:t,previousLocation:n}=e;if(n&&t.pathname!==n.pathname){const e=window.setTimeout((()=>{a().start()}),200);return()=>window.clearTimeout(e)}},onRouteDidUpdate(){a().done()}}},3310:(e,t,n)=>{"use strict";n.r(t);var r=n(2573),a=n(6809);!function(e){const{themeConfig:{prism:t}}=a.default,{additionalLanguages:r}=t;globalThis.Prism=e,r.forEach((e=>{"php"===e&&n(6854),n(9929)(`./prism-${e}`)})),delete globalThis.Prism}(r.p1)},2503:(e,t,n)=>{"use strict";n.d(t,{Z:()=>u});n(7294);var r=n(512),a=n(5999),o=n(6668),i=n(9960);const s={anchorWithStickyNavbar:"anchorWithStickyNavbar_LWe7",anchorWithHideOnScrollNavbar:"anchorWithHideOnScrollNavbar_WYt5"};var l=n(5893);function u(e){let{as:t,id:n,...u}=e;const{navbar:{hideOnScroll:c}}=(0,o.L)();if("h1"===t||!n)return(0,l.jsx)(t,{...u,id:void 0});const d=(0,a.I)({id:"theme.common.headingLinkTitle",message:"Direct link to {heading}",description:"Title for link to heading"},{heading:"string"==typeof u.children?u.children:n});return(0,l.jsxs)(t,{...u,className:(0,r.Z)("anchor",c?s.anchorWithHideOnScrollNavbar:s.anchorWithStickyNavbar,u.className),id:n,children:[u.children,(0,l.jsx)(i.Z,{className:"hash-link",to:`#${n}`,"aria-label":d,title:d,children:"\u200b"})]})}},9471:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});n(7294);const r={iconExternalLink:"iconExternalLink_nPIU"};var a=n(5893);function o(e){let{width:t=13.5,height:n=13.5}=e;return(0,a.jsx)("svg",{width:t,height:n,"aria-hidden":"true",viewBox:"0 0 24 24",className:r.iconExternalLink,children:(0,a.jsx)("path",{fill:"currentColor",d:"M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"})})}},2045:(e,t,n)=>{"use strict";n.d(t,{Z:()=>Pt});var r=n(7294),a=n(512),o=n(4763),i=n(1944),s=n(6550),l=n(5999),u=n(5936),c=n(5893);const d="__docusaurus_skipToContent_fallback";function f(e){e.setAttribute("tabindex","-1"),e.focus(),e.removeAttribute("tabindex")}function p(){const e=(0,r.useRef)(null),{action:t}=(0,s.k6)(),n=(0,r.useCallback)((e=>{e.preventDefault();const t=document.querySelector("main:first-of-type")??document.getElementById(d);t&&f(t)}),[]);return(0,u.S)((n=>{let{location:r}=n;e.current&&!r.hash&&"PUSH"===t&&f(e.current)})),{containerRef:e,onClick:n}}const h=(0,l.I)({id:"theme.common.skipToMainContent",description:"The skip to content label used for accessibility, allowing to rapidly navigate to main content with keyboard tab/enter navigation",message:"Skip to main content"});function m(e){const t=e.children??h,{containerRef:n,onClick:r}=p();return(0,c.jsx)("div",{ref:n,role:"region","aria-label":h,children:(0,c.jsx)("a",{...e,href:`#${d}`,onClick:r,children:t})})}var g=n(5281),y=n(9727);const b={skipToContent:"skipToContent_fXgn"};function v(){return(0,c.jsx)(m,{className:b.skipToContent})}var k=n(6668),w=n(9689);function x(e){let{width:t=21,height:n=21,color:r="currentColor",strokeWidth:a=1.2,className:o,...i}=e;return(0,c.jsx)("svg",{viewBox:"0 0 15 15",width:t,height:n,...i,children:(0,c.jsx)("g",{stroke:r,strokeWidth:a,children:(0,c.jsx)("path",{d:"M.75.75l13.5 13.5M14.25.75L.75 14.25"})})})}const S={closeButton:"closeButton_CVFx"};function E(e){return(0,c.jsx)("button",{type:"button","aria-label":(0,l.I)({id:"theme.AnnouncementBar.closeButtonAriaLabel",message:"Close",description:"The ARIA label for close button of announcement bar"}),...e,className:(0,a.Z)("clean-btn close",S.closeButton,e.className),children:(0,c.jsx)(x,{width:14,height:14,strokeWidth:3.1})})}const _={content:"content_knG7"};function T(e){const{announcementBar:t}=(0,k.L)(),{content:n}=t;return(0,c.jsx)("div",{...e,className:(0,a.Z)(_.content,e.className),dangerouslySetInnerHTML:{__html:n}})}const C={announcementBar:"announcementBar_mb4j",announcementBarPlaceholder:"announcementBarPlaceholder_vyr4",announcementBarClose:"announcementBarClose_gvF7",announcementBarContent:"announcementBarContent_xLdY"};function L(){const{announcementBar:e}=(0,k.L)(),{isActive:t,close:n}=(0,w.nT)();if(!t)return null;const{backgroundColor:r,textColor:a,isCloseable:o}=e;return(0,c.jsxs)("div",{className:C.announcementBar,style:{backgroundColor:r,color:a},role:"banner",children:[o&&(0,c.jsx)("div",{className:C.announcementBarPlaceholder}),(0,c.jsx)(T,{className:C.announcementBarContent}),o&&(0,c.jsx)(E,{onClick:n,className:C.announcementBarClose})]})}var N=n(2961),A=n(2466);var P=n(902),O=n(3102);const I=r.createContext(null);function j(e){let{children:t}=e;const n=function(){const e=(0,N.e)(),t=(0,O.HY)(),[n,a]=(0,r.useState)(!1),o=null!==t.component,i=(0,P.D9)(o);return(0,r.useEffect)((()=>{o&&!i&&a(!0)}),[o,i]),(0,r.useEffect)((()=>{o?e.shown||a(!0):a(!1)}),[e.shown,o]),(0,r.useMemo)((()=>[n,a]),[n])}();return(0,c.jsx)(I.Provider,{value:n,children:t})}function R(e){if(e.component){const t=e.component;return(0,c.jsx)(t,{...e.props})}}function F(){const e=(0,r.useContext)(I);if(!e)throw new P.i6("NavbarSecondaryMenuDisplayProvider");const[t,n]=e,a=(0,r.useCallback)((()=>n(!1)),[n]),o=(0,O.HY)();return(0,r.useMemo)((()=>({shown:t,hide:a,content:R(o)})),[a,o,t])}function D(e){let{header:t,primaryMenu:n,secondaryMenu:r}=e;const{shown:o}=F();return(0,c.jsxs)("div",{className:"navbar-sidebar",children:[t,(0,c.jsxs)("div",{className:(0,a.Z)("navbar-sidebar__items",{"navbar-sidebar__items--show-secondary":o}),children:[(0,c.jsx)("div",{className:"navbar-sidebar__item menu",children:n}),(0,c.jsx)("div",{className:"navbar-sidebar__item menu",children:r})]})]})}var M=n(2949),z=n(2389);function B(e){return(0,c.jsx)("svg",{viewBox:"0 0 24 24",width:24,height:24,...e,children:(0,c.jsx)("path",{fill:"currentColor",d:"M12,9c1.65,0,3,1.35,3,3s-1.35,3-3,3s-3-1.35-3-3S10.35,9,12,9 M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5 S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1 s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0 c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95 c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41 L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41 s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06 c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"})})}function $(e){return(0,c.jsx)("svg",{viewBox:"0 0 24 24",width:24,height:24,...e,children:(0,c.jsx)("path",{fill:"currentColor",d:"M9.37,5.51C9.19,6.15,9.1,6.82,9.1,7.5c0,4.08,3.32,7.4,7.4,7.4c0.68,0,1.35-0.09,1.99-0.27C17.45,17.19,14.93,19,12,19 c-3.86,0-7-3.14-7-7C5,9.07,6.81,6.55,9.37,5.51z M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36 c-0.98,1.37-2.58,2.26-4.4,2.26c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"})})}const W={toggle:"toggle_vylO",toggleButton:"toggleButton_gllP",darkToggleIcon:"darkToggleIcon_wfgR",lightToggleIcon:"lightToggleIcon_pyhR",toggleButtonDisabled:"toggleButtonDisabled_aARS"};function U(e){let{className:t,buttonClassName:n,value:r,onChange:o}=e;const i=(0,z.Z)(),s=(0,l.I)({message:"Switch between dark and light mode (currently {mode})",id:"theme.colorToggle.ariaLabel",description:"The ARIA label for the navbar color mode toggle"},{mode:"dark"===r?(0,l.I)({message:"dark mode",id:"theme.colorToggle.ariaLabel.mode.dark",description:"The name for the dark color mode"}):(0,l.I)({message:"light mode",id:"theme.colorToggle.ariaLabel.mode.light",description:"The name for the light color mode"})});return(0,c.jsx)("div",{className:(0,a.Z)(W.toggle,t),children:(0,c.jsxs)("button",{className:(0,a.Z)("clean-btn",W.toggleButton,!i&&W.toggleButtonDisabled,n),type:"button",onClick:()=>o("dark"===r?"light":"dark"),disabled:!i,title:s,"aria-label":s,"aria-live":"polite",children:[(0,c.jsx)(B,{className:(0,a.Z)(W.toggleIcon,W.lightToggleIcon)}),(0,c.jsx)($,{className:(0,a.Z)(W.toggleIcon,W.darkToggleIcon)})]})})}const H=r.memo(U),Q={darkNavbarColorModeToggle:"darkNavbarColorModeToggle_X3D1"};function Z(e){let{className:t}=e;const n=(0,k.L)().navbar.style,r=(0,k.L)().colorMode.disableSwitch,{colorMode:a,setColorMode:o}=(0,M.I)();return r?null:(0,c.jsx)(H,{className:t,buttonClassName:"dark"===n?Q.darkNavbarColorModeToggle:void 0,value:a,onChange:o})}var V=n(1327);function q(){return(0,c.jsx)(V.Z,{className:"navbar__brand",imageClassName:"navbar__logo",titleClassName:"navbar__title text--truncate"})}function G(){const e=(0,N.e)();return(0,c.jsx)("button",{type:"button","aria-label":(0,l.I)({id:"theme.docs.sidebar.closeSidebarButtonAriaLabel",message:"Close navigation bar",description:"The ARIA label for close button of mobile sidebar"}),className:"clean-btn navbar-sidebar__close",onClick:()=>e.toggle(),children:(0,c.jsx)(x,{color:"var(--ifm-color-emphasis-600)"})})}function Y(){return(0,c.jsxs)("div",{className:"navbar-sidebar__brand",children:[(0,c.jsx)(q,{}),(0,c.jsx)(Z,{className:"margin-right--md"}),(0,c.jsx)(G,{})]})}var K=n(9960),X=n(4996),J=n(3919);function ee(e,t){return void 0!==e&&void 0!==t&&new RegExp(e,"gi").test(t)}var te=n(9471);function ne(e){let{activeBasePath:t,activeBaseRegex:n,to:r,href:a,label:o,html:i,isDropdownLink:s,prependBaseUrlToHref:l,...u}=e;const d=(0,X.Z)(r),f=(0,X.Z)(t),p=(0,X.Z)(a,{forcePrependBaseUrl:!0}),h=o&&a&&!(0,J.Z)(a),m=i?{dangerouslySetInnerHTML:{__html:i}}:{children:(0,c.jsxs)(c.Fragment,{children:[o,h&&(0,c.jsx)(te.Z,{...s&&{width:12,height:12}})]})};return a?(0,c.jsx)(K.Z,{href:l?p:a,...u,...m}):(0,c.jsx)(K.Z,{to:d,isNavLink:!0,...(t||n)&&{isActive:(e,t)=>n?ee(n,t.pathname):t.pathname.startsWith(f)},...u,...m})}function re(e){let{className:t,isDropdownItem:n=!1,...r}=e;const o=(0,c.jsx)(ne,{className:(0,a.Z)(n?"dropdown__link":"navbar__item navbar__link",t),isDropdownLink:n,...r});return n?(0,c.jsx)("li",{children:o}):o}function ae(e){let{className:t,isDropdownItem:n,...r}=e;return(0,c.jsx)("li",{className:"menu__list-item",children:(0,c.jsx)(ne,{className:(0,a.Z)("menu__link",t),...r})})}function oe(e){let{mobile:t=!1,position:n,...r}=e;const a=t?ae:re;return(0,c.jsx)(a,{...r,activeClassName:r.activeClassName??(t?"menu__link--active":"navbar__link--active")})}var ie=n(6043),se=n(8596),le=n(2263);const ue={dropdownNavbarItemMobile:"dropdownNavbarItemMobile_S0Fm"};function ce(e,t){return e.some((e=>function(e,t){return!!(0,se.Mg)(e.to,t)||!!ee(e.activeBaseRegex,t)||!(!e.activeBasePath||!t.startsWith(e.activeBasePath))}(e,t)))}function de(e){let{items:t,position:n,className:o,onClick:i,...s}=e;const l=(0,r.useRef)(null),[u,d]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{const e=e=>{l.current&&!l.current.contains(e.target)&&d(!1)};return document.addEventListener("mousedown",e),document.addEventListener("touchstart",e),document.addEventListener("focusin",e),()=>{document.removeEventListener("mousedown",e),document.removeEventListener("touchstart",e),document.removeEventListener("focusin",e)}}),[l]),(0,c.jsxs)("div",{ref:l,className:(0,a.Z)("navbar__item","dropdown","dropdown--hoverable",{"dropdown--right":"right"===n,"dropdown--show":u}),children:[(0,c.jsx)(ne,{"aria-haspopup":"true","aria-expanded":u,role:"button",href:s.to?void 0:"#",className:(0,a.Z)("navbar__link",o),...s,onClick:s.to?void 0:e=>e.preventDefault(),onKeyDown:e=>{"Enter"===e.key&&(e.preventDefault(),d(!u))},children:s.children??s.label}),(0,c.jsx)("ul",{className:"dropdown__menu",children:t.map(((e,t)=>(0,r.createElement)(Ve,{isDropdownItem:!0,activeClassName:"dropdown__link--active",...e,key:t})))})]})}function fe(e){let{items:t,className:n,position:o,onClick:i,...l}=e;const u=function(){const{siteConfig:{baseUrl:e}}=(0,le.Z)(),{pathname:t}=(0,s.TH)();return t.replace(e,"/")}(),d=ce(t,u),{collapsed:f,toggleCollapsed:p,setCollapsed:h}=(0,ie.u)({initialState:()=>!d});return(0,r.useEffect)((()=>{d&&h(!d)}),[u,d,h]),(0,c.jsxs)("li",{className:(0,a.Z)("menu__list-item",{"menu__list-item--collapsed":f}),children:[(0,c.jsx)(ne,{role:"button",className:(0,a.Z)(ue.dropdownNavbarItemMobile,"menu__link menu__link--sublist menu__link--sublist-caret",n),...l,onClick:e=>{e.preventDefault(),p()},children:l.children??l.label}),(0,c.jsx)(ie.z,{lazy:!0,as:"ul",className:"menu__list",collapsed:f,children:t.map(((e,t)=>(0,r.createElement)(Ve,{mobile:!0,isDropdownItem:!0,onClick:i,activeClassName:"menu__link--active",...e,key:t})))})]})}function pe(e){let{mobile:t=!1,...n}=e;const r=t?fe:de;return(0,c.jsx)(r,{...n})}var he=n(4711);function me(e){let{width:t=20,height:n=20,...r}=e;return(0,c.jsx)("svg",{viewBox:"0 0 24 24",width:t,height:n,"aria-hidden":!0,...r,children:(0,c.jsx)("path",{fill:"currentColor",d:"M12.87 15.07l-2.54-2.51.03-.03c1.74-1.94 2.98-4.17 3.71-6.53H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z"})})}const ge="iconLanguage_nlXk";var ye=n(1029),be=n(1728),ve=n(373),ke=n(143),we=n(22),xe=n(8202),Se=n(3926),Ee=n(1073),_e=n(2539),Te=n(726);const Ce='',Le='',Ne='',Ae='',Pe='',Oe='',Ie='',je={searchBar:"searchBar_RVTs",dropdownMenu:"dropdownMenu_qbY6",searchBarLeft:"searchBarLeft_MXDe",suggestion:"suggestion_fB_2",cursor:"cursor_eG29",hitTree:"hitTree_kk6K",hitIcon:"hitIcon_a7Zy",hitPath:"hitPath_ieM4",noResultsIcon:"noResultsIcon_EBY5",hitFooter:"hitFooter_E9YW",hitWrapper:"hitWrapper_sAK8",hitTitle:"hitTitle_vyVt",hitAction:"hitAction_NqkB",hideAction:"hideAction_vcyE",noResults:"noResults_l6Q3",searchBarContainer:"searchBarContainer_NW3z",searchBarLoadingRing:"searchBarLoadingRing_YnHq",searchClearButton:"searchClearButton_qk4g",searchIndexLoading:"searchIndexLoading_EJ1f",searchHintContainer:"searchHintContainer_Pkmr",searchHint:"searchHint_iIMx",focused:"focused_OWtg",input:"input_FOTf",hint:"hint_URu1",suggestions:"suggestions_X8XU",dataset:"dataset_QiCy",empty:"empty_eITn"};function Re(e){let{document:t,type:n,page:r,metadata:a,tokens:o,isInterOfTree:i,isLastOfTree:s}=e;const l=0===n,u=1===n,c=[];i?c.push(Oe):s&&c.push(Ie);const d=c.map((e=>`${e}`)),f=`${l?Ce:u?Le:Ne}`,p=[`${(0,Te.o)(t.t,(0,Ee.m)(a,"t"),o)}`];if(!i&&!s&&ye.H6){const e=r?(r.b??[]).concat(r.t).concat(t.s&&t.s!==r.t?t.s:[]):t.b;p.push(`${(0,Se.e)(e??[])}`)}else l||p.push(`${(0,_e.C)(r.t||(t.u.startsWith("/docs/api-reference/")?"API Reference":""),o)}`);const h=`${Ae}`;return[...d,f,``,...p,"",h].join("")}function Fe(){return`${Pe}${(0,l.I)({id:"theme.SearchBar.noResultsText",message:"No results"})}`}var De=n(311),Me=n(51);async function ze(){const e=await Promise.all([n.e(8443),n.e(5525)]).then(n.t.bind(n,8443,23)),t=e.default;return t.noConflict?t.noConflict():e.noConflict&&e.noConflict(),t}const Be="_highlight";const $e=function(e){let{handleSearchBarToggle:t}=e;const n=(0,z.Z)(),{siteConfig:{baseUrl:a},i18n:{currentLocale:o}}=(0,le.Z)(),i=(0,ke.gA)();let u=a;try{const{preferredVersion:e}=(0,ve.J)(i?.pluginId??ye.gQ);e&&!e.isLast&&(u=e.path+"/")}catch(D){if(ye.l9&&!(D instanceof P.i6))throw D}const d=(0,s.k6)(),f=(0,s.TH)(),p=(0,r.useRef)(null),h=(0,r.useRef)(new Map),m=(0,r.useRef)(!1),[g,y]=(0,r.useState)(!1),[b,v]=(0,r.useState)(!1),[k,w]=(0,r.useState)(""),x=(0,r.useRef)(null),S=(0,r.useRef)(""),[E,_]=(0,r.useState)("");(0,r.useEffect)((()=>{if(!Array.isArray(ye.Kc))return;let e="";if(f.pathname.startsWith(u)){const t=f.pathname.substring(u.length);let n;for(const e of ye.Kc){const r="string"==typeof e?e:e.path;if(t===r||t.startsWith(`${r}/`)){n=r;break}}n&&(e=n)}S.current!==e&&(h.current.delete(e),S.current=e),_(e)}),[f.pathname,u]);const T=!!ye.hG&&Array.isArray(ye.Kc)&&""===E,C=(0,r.useCallback)((async()=>{if(T||h.current.get(E))return;h.current.set(E,"loading"),x.current?.autocomplete.destroy(),y(!0);const[{wrappedIndexes:e,zhDictionary:t},n]=await Promise.all([(0,we.w)(u,E),ze()]);if(x.current=n(p.current,{hint:!1,autoselect:!0,openOnFocus:!0,cssClasses:{root:(0,be.Z)(je.searchBar,{[je.searchBarLeft]:"left"===ye.pu}),noPrefix:!0,dropdownMenu:je.dropdownMenu,input:je.input,hint:je.hint,suggestions:je.suggestions,suggestion:je.suggestion,cursor:je.cursor,dataset:je.dataset,empty:je.empty}},[{source:(0,xe.v)(e,t,ye.qo),templates:{suggestion:Re,empty:Fe,footer:e=>{let{query:t,isEmpty:n}=e;if(n&&(!E||!ye.pQ))return;const r=(e=>{let{query:t,isEmpty:n}=e;const r=document.createElement("a"),i=new URLSearchParams;let s;if(i.set("q",t),E){const e=E&&Array.isArray(ye.Kc)?ye.Kc.find((e=>"string"==typeof e?e===E:e.path===E)):E,t=e?(0,Me._)(e,o).label:E;s=ye.pQ&&n?(0,l.I)({id:"theme.SearchBar.seeAllOutsideContext",message:"See results outside {context}"},{context:t}):(0,l.I)({id:"theme.SearchBar.searchInContext",message:"See all results in {context}"},{context:t})}else s=(0,l.I)({id:"theme.SearchBar.seeAll",message:"See all results"});if(!E||!Array.isArray(ye.Kc)||ye.pQ&&n||i.set("ctx",E),u!==a){if(!u.startsWith(a))throw new Error(`Version url '${u}' does not start with base url '${a}', this is a bug of \`@easyops-cn/docusaurus-search-local\`, please report it.`);i.set("version",u.substring(a.length))}const c=`${a}search?${i.toString()}`;return r.href=c,r.textContent=s,r.addEventListener("click",(e=>{e.ctrlKey||e.metaKey||(e.preventDefault(),x.current?.autocomplete.close(),d.push(c))})),r})({query:t,isEmpty:n}),i=document.createElement("div");return i.className=je.hitFooter,i.appendChild(r),i}}}]).on("autocomplete:selected",(function(e,t){let{document:{u:n,h:r},tokens:a}=t;p.current?.blur();let o=n;if(ye.vc&&a.length>0){const e=new URLSearchParams;for(const t of a)e.append(Be,t);o+=`?${e.toString()}`}r&&(o+=r),d.push(o)})).on("autocomplete:closed",(()=>{p.current?.blur()})),h.current.set(E,"done"),y(!1),m.current){const e=p.current;e.value&&x.current?.autocomplete.open(),e.focus()}}),[T,E,u,a,d]);(0,r.useEffect)((()=>{if(!ye.vc)return;const e=n?new URLSearchParams(f.search).getAll(Be):[];setTimeout((()=>{const t=document.querySelector("article");if(!t)return;const n=new ye.vc(t);n.unmark(),0!==e.length&&n.mark(e),w(e.join(" ")),x.current?.autocomplete.setVal(e.join(" "))}))}),[n,f.search,f.pathname]);const[L,N]=(0,r.useState)(!1),A=(0,r.useCallback)((()=>{m.current=!0,C(),N(!0),t?.(!0)}),[t,C]),O=(0,r.useCallback)((()=>{N(!1),t?.(!1)}),[t]),I=(0,r.useCallback)((()=>{C()}),[C]),j=(0,r.useCallback)((e=>{w(e.target.value),e.target.value&&v(!0)}),[]),R=!!n&&/mac/i.test(navigator.userAgentData?.platform??navigator.platform);(0,r.useEffect)((()=>{if(!ye.AY)return;const e=e=>{!(R?e.metaKey:e.ctrlKey)||"k"!==e.key&&"K"!==e.key||(e.preventDefault(),p.current?.focus(),A())};return document.addEventListener("keydown",e),()=>{document.removeEventListener("keydown",e)}}),[R,A]);const F=(0,r.useCallback)((()=>{const e=new URLSearchParams(f.search);e.delete(Be);const t=e.toString(),n=f.pathname+(""!=t?`?${t}`:"")+f.hash;n!=f.pathname+f.search+f.hash&&d.push(n),w(""),x.current?.autocomplete.setVal("")}),[f.pathname,f.search,f.hash,d]);return(0,c.jsxs)("div",{className:(0,be.Z)("navbar__search",je.searchBarContainer,{[je.searchIndexLoading]:g&&b,[je.focused]:L}),hidden:T,children:[(0,c.jsx)("input",{placeholder:(0,l.I)({id:"theme.SearchBar.label",message:"Search",description:"The ARIA label and placeholder for search button"}),"aria-label":"Search",className:"navbar__search-input",onMouseEnter:I,onFocus:A,onBlur:O,onChange:j,ref:p,value:k}),(0,c.jsx)(De.Z,{className:je.searchBarLoadingRing}),ye.AY&&ye.t_&&(""!==k?(0,c.jsx)("button",{className:je.searchClearButton,onClick:F,children:"\u2715"}):n&&(0,c.jsxs)("div",{className:je.searchHintContainer,children:[(0,c.jsx)("kbd",{className:je.searchHint,children:R?"\u2318":"ctrl"}),(0,c.jsx)("kbd",{className:je.searchHint,children:"K"})]}))]})},We={navbarSearchContainer:"navbarSearchContainer_Bca1"};function Ue(e){let{children:t,className:n}=e;return(0,c.jsx)("div",{className:(0,a.Z)(n,We.navbarSearchContainer),children:t})}var He=n(2802);const Qe=e=>e.docs.find((t=>t.id===e.mainDocId));const Ze={default:oe,localeDropdown:function(e){let{mobile:t,dropdownItemsBefore:n,dropdownItemsAfter:r,queryString:a="",...o}=e;const{i18n:{currentLocale:i,locales:u,localeConfigs:d}}=(0,le.Z)(),f=(0,he.l)(),{search:p,hash:h}=(0,s.TH)(),m=[...n,...u.map((e=>{const n=`${`pathname://${f.createUrl({locale:e,fullyQualified:!1})}`}${p}${h}${a}`;return{label:d[e].label,lang:d[e].htmlLang,to:n,target:"_self",autoAddBaseUrl:!1,className:e===i?t?"menu__link--active":"dropdown__link--active":""}})),...r],g=t?(0,l.I)({message:"Languages",id:"theme.navbar.mobileLanguageDropdown.label",description:"The label for the mobile language switcher dropdown"}):d[i].label;return(0,c.jsx)(pe,{...o,mobile:t,label:(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(me,{className:ge}),g]}),items:m})},search:function(e){let{mobile:t,className:n}=e;return t?null:(0,c.jsx)(Ue,{className:n,children:(0,c.jsx)($e,{})})},dropdown:pe,html:function(e){let{value:t,className:n,mobile:r=!1,isDropdownItem:o=!1}=e;const i=o?"li":"div";return(0,c.jsx)(i,{className:(0,a.Z)({navbar__item:!r&&!o,"menu__list-item":r},n),dangerouslySetInnerHTML:{__html:t}})},doc:function(e){let{docId:t,label:n,docsPluginId:r,...a}=e;const{activeDoc:o}=(0,ke.Iw)(r),i=(0,He.vY)(t,r),s=o?.path===i?.path;return null===i||i.unlisted&&!s?null:(0,c.jsx)(oe,{exact:!0,...a,isActive:()=>s||!!o?.sidebar&&o.sidebar===i.sidebar,label:n??i.id,to:i.path})},docSidebar:function(e){let{sidebarId:t,label:n,docsPluginId:r,...a}=e;const{activeDoc:o}=(0,ke.Iw)(r),i=(0,He.oz)(t,r).link;if(!i)throw new Error(`DocSidebarNavbarItem: Sidebar with ID "${t}" doesn't have anything to be linked to.`);return(0,c.jsx)(oe,{exact:!0,...a,isActive:()=>o?.sidebar===t,label:n??i.label,to:i.path})},docsVersion:function(e){let{label:t,to:n,docsPluginId:r,...a}=e;const o=(0,He.lO)(r)[0],i=t??o.label,s=n??(e=>e.docs.find((t=>t.id===e.mainDocId)))(o).path;return(0,c.jsx)(oe,{...a,label:i,to:s})},docsVersionDropdown:function(e){let{mobile:t,docsPluginId:n,dropdownActiveClassDisabled:r,dropdownItemsBefore:a,dropdownItemsAfter:o,...i}=e;const{search:u,hash:d}=(0,s.TH)(),f=(0,ke.Iw)(n),p=(0,ke.gB)(n),{savePreferredVersionName:h}=(0,ve.J)(n),m=[...a,...p.map((e=>{const t=f.alternateDocVersions[e.name]??Qe(e);return{label:e.label,to:`${t.path}${u}${d}`,isActive:()=>e===f.activeVersion,onClick:()=>h(e.name)}})),...o],g=(0,He.lO)(n)[0],y=t&&m.length>1?(0,l.I)({id:"theme.navbar.mobileVersionsDropdown.label",message:"Versions",description:"The label for the navbar versions dropdown on mobile view"}):g.label,b=t&&m.length>1?void 0:Qe(g).path;return m.length<=1?(0,c.jsx)(oe,{...i,mobile:t,label:y,to:b,isActive:r?()=>!1:void 0}):(0,c.jsx)(pe,{...i,mobile:t,label:y,to:b,items:m,isActive:r?()=>!1:void 0})}};function Ve(e){let{type:t,...n}=e;const r=function(e,t){return e&&"default"!==e?e:"items"in t?"dropdown":"default"}(t,n),a=Ze[r];if(!a)throw new Error(`No NavbarItem component found for type "${t}".`);return(0,c.jsx)(a,{...n})}function qe(){const e=(0,N.e)(),t=(0,k.L)().navbar.items;return(0,c.jsx)("ul",{className:"menu__list",children:t.map(((t,n)=>(0,r.createElement)(Ve,{mobile:!0,...t,onClick:()=>e.toggle(),key:n})))})}function Ge(e){return(0,c.jsx)("button",{...e,type:"button",className:"clean-btn navbar-sidebar__back",children:(0,c.jsx)(l.Z,{id:"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel",description:"The label of the back button to return to main menu, inside the mobile navbar sidebar secondary menu (notably used to display the docs sidebar)",children:"\u2190 Back to main menu"})})}function Ye(){const e=0===(0,k.L)().navbar.items.length,t=F();return(0,c.jsxs)(c.Fragment,{children:[!e&&(0,c.jsx)(Ge,{onClick:()=>t.hide()}),t.content]})}function Ke(){const e=(0,N.e)();var t;return void 0===(t=e.shown)&&(t=!0),(0,r.useEffect)((()=>(document.body.style.overflow=t?"hidden":"visible",()=>{document.body.style.overflow="visible"})),[t]),e.shouldRender?(0,c.jsx)(D,{header:(0,c.jsx)(Y,{}),primaryMenu:(0,c.jsx)(qe,{}),secondaryMenu:(0,c.jsx)(Ye,{})}):null}const Xe={navbarHideable:"navbarHideable_m1mJ",navbarHidden:"navbarHidden_jGov"};function Je(e){return(0,c.jsx)("div",{role:"presentation",...e,className:(0,a.Z)("navbar-sidebar__backdrop",e.className)})}function et(e){let{children:t}=e;const{navbar:{hideOnScroll:n,style:o}}=(0,k.L)(),i=(0,N.e)(),{navbarRef:s,isNavbarVisible:d}=function(e){const[t,n]=(0,r.useState)(e),a=(0,r.useRef)(!1),o=(0,r.useRef)(0),i=(0,r.useCallback)((e=>{null!==e&&(o.current=e.getBoundingClientRect().height)}),[]);return(0,A.RF)(((t,r)=>{let{scrollY:i}=t;if(!e)return;if(i=s?n(!1):i+u{if(!e)return;const r=t.location.hash;if(r?document.getElementById(r.substring(1)):void 0)return a.current=!0,void n(!1);n(!0)})),{navbarRef:i,isNavbarVisible:t}}(n);return(0,c.jsxs)("nav",{ref:s,"aria-label":(0,l.I)({id:"theme.NavBar.navAriaLabel",message:"Main",description:"The ARIA label for the main navigation"}),className:(0,a.Z)("navbar","navbar--fixed-top",n&&[Xe.navbarHideable,!d&&Xe.navbarHidden],{"navbar--dark":"dark"===o,"navbar--primary":"primary"===o,"navbar-sidebar--show":i.shown}),children:[t,(0,c.jsx)(Je,{onClick:i.toggle}),(0,c.jsx)(Ke,{})]})}var tt=n(9690);const nt="right";function rt(e){let{width:t=30,height:n=30,className:r,...a}=e;return(0,c.jsx)("svg",{className:r,width:t,height:n,viewBox:"0 0 30 30","aria-hidden":"true",...a,children:(0,c.jsx)("path",{stroke:"currentColor",strokeLinecap:"round",strokeMiterlimit:"10",strokeWidth:"2",d:"M4 7h22M4 15h22M4 23h22"})})}function at(){const{toggle:e,shown:t}=(0,N.e)();return(0,c.jsx)("button",{onClick:e,"aria-label":(0,l.I)({id:"theme.docs.sidebar.toggleSidebarButtonAriaLabel",message:"Toggle navigation bar",description:"The ARIA label for hamburger menu button of mobile navigation"}),"aria-expanded":t,className:"navbar__toggle clean-btn",type:"button",children:(0,c.jsx)(rt,{})})}const ot={colorModeToggle:"colorModeToggle_DEke"};function it(e){let{items:t}=e;return(0,c.jsx)(c.Fragment,{children:t.map(((e,t)=>(0,c.jsx)(tt.QW,{onError:t=>new Error(`A theme navbar item failed to render.\nPlease double-check the following navbar item (themeConfig.navbar.items) of your Docusaurus config:\n${JSON.stringify(e,null,2)}`,{cause:t}),children:(0,c.jsx)(Ve,{...e})},t)))})}function st(e){let{left:t,right:n}=e;return(0,c.jsxs)("div",{className:"navbar__inner",children:[(0,c.jsx)("div",{className:"navbar__items",children:t}),(0,c.jsx)("div",{className:"navbar__items navbar__items--right",children:n})]})}function lt(){const e=(0,N.e)(),t=(0,k.L)().navbar.items,[n,r]=function(e){function t(e){return"left"===(e.position??nt)}return[e.filter(t),e.filter((e=>!t(e)))]}(t),a=t.find((e=>"search"===e.type));return(0,c.jsx)(st,{left:(0,c.jsxs)(c.Fragment,{children:[!e.disabled&&(0,c.jsx)(at,{}),(0,c.jsx)(q,{}),(0,c.jsx)(it,{items:n})]}),right:(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(it,{items:r}),(0,c.jsx)(Z,{className:ot.colorModeToggle}),!a&&(0,c.jsx)(Ue,{children:(0,c.jsx)($e,{})})]})})}function ut(){return(0,c.jsx)(et,{children:(0,c.jsx)(lt,{})})}function ct(e){let{item:t}=e;const{to:n,href:r,label:a,prependBaseUrlToHref:o,...i}=t,s=(0,X.Z)(n),l=(0,X.Z)(r,{forcePrependBaseUrl:!0});return(0,c.jsxs)(K.Z,{className:"footer__link-item",...r?{href:o?l:r}:{to:s},...i,children:[a,r&&!(0,J.Z)(r)&&(0,c.jsx)(te.Z,{})]})}function dt(e){let{item:t}=e;return t.html?(0,c.jsx)("li",{className:"footer__item",dangerouslySetInnerHTML:{__html:t.html}}):(0,c.jsx)("li",{className:"footer__item",children:(0,c.jsx)(ct,{item:t})},t.href??t.to)}function ft(e){let{column:t}=e;return(0,c.jsxs)("div",{className:"col footer__col",children:[(0,c.jsx)("div",{className:"footer__title",children:t.title}),(0,c.jsx)("ul",{className:"footer__items clean-list",children:t.items.map(((e,t)=>(0,c.jsx)(dt,{item:e},t)))})]})}function pt(e){let{columns:t}=e;return(0,c.jsx)("div",{className:"row footer__links",children:t.map(((e,t)=>(0,c.jsx)(ft,{column:e},t)))})}function ht(){return(0,c.jsx)("span",{className:"footer__link-separator",children:"\xb7"})}function mt(e){let{item:t}=e;return t.html?(0,c.jsx)("span",{className:"footer__link-item",dangerouslySetInnerHTML:{__html:t.html}}):(0,c.jsx)(ct,{item:t})}function gt(e){let{links:t}=e;return(0,c.jsx)("div",{className:"footer__links text--center",children:(0,c.jsx)("div",{className:"footer__links",children:t.map(((e,n)=>(0,c.jsxs)(r.Fragment,{children:[(0,c.jsx)(mt,{item:e}),t.length!==n+1&&(0,c.jsx)(ht,{})]},n)))})})}function yt(e){let{links:t}=e;return function(e){return"title"in e[0]}(t)?(0,c.jsx)(pt,{columns:t}):(0,c.jsx)(gt,{links:t})}var bt=n(9965);const vt={footerLogoLink:"footerLogoLink_BH7S"};function kt(e){let{logo:t}=e;const{withBaseUrl:n}=(0,X.C)(),r={light:n(t.src),dark:n(t.srcDark??t.src)};return(0,c.jsx)(bt.Z,{className:(0,a.Z)("footer__logo",t.className),alt:t.alt,sources:r,width:t.width,height:t.height,style:t.style})}function wt(e){let{logo:t}=e;return t.href?(0,c.jsx)(K.Z,{href:t.href,className:vt.footerLogoLink,target:t.target,children:(0,c.jsx)(kt,{logo:t})}):(0,c.jsx)(kt,{logo:t})}function xt(e){let{copyright:t}=e;return(0,c.jsx)("div",{className:"footer__copyright",dangerouslySetInnerHTML:{__html:t}})}function St(e){let{style:t,links:n,logo:r,copyright:o}=e;return(0,c.jsx)("footer",{className:(0,a.Z)("footer",{"footer--dark":"dark"===t}),children:(0,c.jsxs)("div",{className:"container container-fluid",children:[n,(r||o)&&(0,c.jsxs)("div",{className:"footer__bottom text--center",children:[r&&(0,c.jsx)("div",{className:"margin-bottom--sm",children:r}),o]})]})})}function Et(){const{footer:e}=(0,k.L)();if(!e)return null;const{copyright:t,links:n,logo:r,style:a}=e;return(0,c.jsx)(St,{style:a,links:n&&n.length>0&&(0,c.jsx)(yt,{links:n}),logo:r&&(0,c.jsx)(wt,{logo:r}),copyright:t&&(0,c.jsx)(xt,{copyright:t})})}const _t=r.memo(Et),Tt=(0,P.Qc)([M.S,w.pl,A.OC,ve.L5,i.VC,function(e){let{children:t}=e;return(0,c.jsx)(O.n2,{children:(0,c.jsx)(N.M,{children:(0,c.jsx)(j,{children:t})})})}]);function Ct(e){let{children:t}=e;return(0,c.jsx)(Tt,{children:t})}var Lt=n(2503);function Nt(e){let{error:t,tryAgain:n}=e;return(0,c.jsx)("main",{className:"container margin-vert--xl",children:(0,c.jsx)("div",{className:"row",children:(0,c.jsxs)("div",{className:"col col--6 col--offset-3",children:[(0,c.jsx)(Lt.Z,{as:"h1",className:"hero__title",children:(0,c.jsx)(l.Z,{id:"theme.ErrorPageContent.title",description:"The title of the fallback page when the page crashed",children:"This page crashed."})}),(0,c.jsx)("div",{className:"margin-vert--lg",children:(0,c.jsx)(tt.Cw,{onClick:n,className:"button button--primary shadow--lw"})}),(0,c.jsx)("hr",{}),(0,c.jsx)("div",{className:"margin-vert--md",children:(0,c.jsx)(tt.aG,{error:t})})]})})})}const At={mainWrapper:"mainWrapper_z2l0"};function Pt(e){const{children:t,noFooter:n,wrapperClassName:r,title:s,description:l}=e;return(0,y.t)(),(0,c.jsxs)(Ct,{children:[(0,c.jsx)(i.d,{title:s,description:l}),(0,c.jsx)(v,{}),(0,c.jsx)(L,{}),(0,c.jsx)(ut,{}),(0,c.jsx)("div",{id:d,className:(0,a.Z)(g.k.wrapper.main,At.mainWrapper,r),children:(0,c.jsx)(o.Z,{fallback:e=>(0,c.jsx)(Nt,{...e}),children:t})}),!n&&(0,c.jsx)(_t,{})]})}},1327:(e,t,n)=>{"use strict";n.d(t,{Z:()=>c});n(7294);var r=n(9960),a=n(4996),o=n(2263),i=n(6668),s=n(9965),l=n(5893);function u(e){let{logo:t,alt:n,imageClassName:r}=e;const o={light:(0,a.Z)(t.src),dark:(0,a.Z)(t.srcDark||t.src)},i=(0,l.jsx)(s.Z,{className:t.className,sources:o,height:t.height,width:t.width,alt:n,style:t.style});return r?(0,l.jsx)("div",{className:r,children:i}):i}function c(e){const{siteConfig:{title:t}}=(0,o.Z)(),{navbar:{title:n,logo:s}}=(0,i.L)(),{imageClassName:c,titleClassName:d,...f}=e,p=(0,a.Z)(s?.href||"/"),h=n?"":t,m=s?.alt??h;return(0,l.jsxs)(r.Z,{to:p,...f,...s?.target&&{target:s.target},children:[s&&(0,l.jsx)(u,{logo:s,alt:m,imageClassName:c}),null!=n&&(0,l.jsx)("b",{className:d,children:n})]})}},197:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});n(7294);var r=n(5742),a=n(5893);function o(e){let{locale:t,version:n,tag:o}=e;const i=t;return(0,a.jsxs)(r.Z,{children:[t&&(0,a.jsx)("meta",{name:"docusaurus_locale",content:t}),n&&(0,a.jsx)("meta",{name:"docusaurus_version",content:n}),o&&(0,a.jsx)("meta",{name:"docusaurus_tag",content:o}),i&&(0,a.jsx)("meta",{name:"docsearch:language",content:i}),n&&(0,a.jsx)("meta",{name:"docsearch:version",content:n}),o&&(0,a.jsx)("meta",{name:"docsearch:docusaurus_tag",content:o})]})}},9965:(e,t,n)=>{"use strict";n.d(t,{Z:()=>c});var r=n(7294),a=n(512),o=n(2389),i=n(2949);const s={themedComponent:"themedComponent_mlkZ","themedComponent--light":"themedComponent--light_NVdE","themedComponent--dark":"themedComponent--dark_xIcU"};var l=n(5893);function u(e){let{className:t,children:n}=e;const u=(0,o.Z)(),{colorMode:c}=(0,i.I)();return(0,l.jsx)(l.Fragment,{children:(u?"dark"===c?["dark"]:["light"]:["light","dark"]).map((e=>{const o=n({theme:e,className:(0,a.Z)(t,s.themedComponent,s[`themedComponent--${e}`])});return(0,l.jsx)(r.Fragment,{children:o},e)}))})}function c(e){const{sources:t,className:n,alt:r,...a}=e;return(0,l.jsx)(u,{className:n,children:e=>{let{theme:n,className:o}=e;return(0,l.jsx)("img",{src:t[n],alt:r,className:o,...a})}})}},6043:(e,t,n)=>{"use strict";n.d(t,{u:()=>u,z:()=>y});var r=n(7294),a=n(412),o=n(469),i=n(1442),s=n(5893);const l="ease-in-out";function u(e){let{initialState:t}=e;const[n,a]=(0,r.useState)(t??!1),o=(0,r.useCallback)((()=>{a((e=>!e))}),[]);return{collapsed:n,setCollapsed:a,toggleCollapsed:o}}const c={display:"none",overflow:"hidden",height:"0px"},d={display:"block",overflow:"visible",height:"auto"};function f(e,t){const n=t?c:d;e.style.display=n.display,e.style.overflow=n.overflow,e.style.height=n.height}function p(e){let{collapsibleRef:t,collapsed:n,animation:a}=e;const o=(0,r.useRef)(!1);(0,r.useEffect)((()=>{const e=t.current;function r(){const t=e.scrollHeight,n=a?.duration??function(e){if((0,i.n)())return 1;const t=e/36;return Math.round(10*(4+15*t**.25+t/5))}(t);return{transition:`height ${n}ms ${a?.easing??l}`,height:`${t}px`}}function s(){const t=r();e.style.transition=t.transition,e.style.height=t.height}if(!o.current)return f(e,n),void(o.current=!0);return e.style.willChange="height",function(){const t=requestAnimationFrame((()=>{n?(s(),requestAnimationFrame((()=>{e.style.height=c.height,e.style.overflow=c.overflow}))):(e.style.display="block",requestAnimationFrame((()=>{s()})))}));return()=>cancelAnimationFrame(t)}()}),[t,n,a])}function h(e){if(!a.Z.canUseDOM)return e?c:d}function m(e){let{as:t="div",collapsed:n,children:a,animation:o,onCollapseTransitionEnd:i,className:l,disableSSRStyle:u}=e;const c=(0,r.useRef)(null);return p({collapsibleRef:c,collapsed:n,animation:o}),(0,s.jsx)(t,{ref:c,style:u?void 0:h(n),onTransitionEnd:e=>{"height"===e.propertyName&&(f(c.current,n),i?.(n))},className:l,children:a})}function g(e){let{collapsed:t,...n}=e;const[a,i]=(0,r.useState)(!t),[l,u]=(0,r.useState)(t);return(0,o.Z)((()=>{t||i(!0)}),[t]),(0,o.Z)((()=>{a&&u(t)}),[a,t]),a?(0,s.jsx)(m,{...n,collapsed:l}):null}function y(e){let{lazy:t,...n}=e;const r=t?g:m;return(0,s.jsx)(r,{...n})}},9689:(e,t,n)=>{"use strict";n.d(t,{nT:()=>m,pl:()=>h});var r=n(7294),a=n(2389),o=n(12),i=n(902),s=n(6668),l=n(5893);const u=(0,o.WA)("docusaurus.announcement.dismiss"),c=(0,o.WA)("docusaurus.announcement.id"),d=()=>"true"===u.get(),f=e=>u.set(String(e)),p=r.createContext(null);function h(e){let{children:t}=e;const n=function(){const{announcementBar:e}=(0,s.L)(),t=(0,a.Z)(),[n,o]=(0,r.useState)((()=>!!t&&d()));(0,r.useEffect)((()=>{o(d())}),[]);const i=(0,r.useCallback)((()=>{f(!0),o(!0)}),[]);return(0,r.useEffect)((()=>{if(!e)return;const{id:t}=e;let n=c.get();"annoucement-bar"===n&&(n="announcement-bar");const r=t!==n;c.set(t),r&&f(!1),!r&&d()||o(!1)}),[e]),(0,r.useMemo)((()=>({isActive:!!e&&!n,close:i})),[e,n,i])}();return(0,l.jsx)(p.Provider,{value:n,children:t})}function m(){const e=(0,r.useContext)(p);if(!e)throw new i.i6("AnnouncementBarProvider");return e}},2949:(e,t,n)=>{"use strict";n.d(t,{I:()=>y,S:()=>g});var r=n(7294),a=n(412),o=n(902),i=n(12),s=n(6668),l=n(5893);const u=r.createContext(void 0),c="theme",d=(0,i.WA)(c),f={light:"light",dark:"dark"},p=e=>e===f.dark?f.dark:f.light,h=e=>a.Z.canUseDOM?p(document.documentElement.getAttribute("data-theme")):p(e),m=e=>{d.set(p(e))};function g(e){let{children:t}=e;const n=function(){const{colorMode:{defaultMode:e,disableSwitch:t,respectPrefersColorScheme:n}}=(0,s.L)(),[a,o]=(0,r.useState)(h(e));(0,r.useEffect)((()=>{t&&d.del()}),[t]);const i=(0,r.useCallback)((function(t,r){void 0===r&&(r={});const{persist:a=!0}=r;t?(o(t),a&&m(t)):(o(n?window.matchMedia("(prefers-color-scheme: dark)").matches?f.dark:f.light:e),d.del())}),[n,e]);(0,r.useEffect)((()=>{document.documentElement.setAttribute("data-theme",p(a))}),[a]),(0,r.useEffect)((()=>{if(t)return;const e=e=>{if(e.key!==c)return;const t=d.get();null!==t&&i(p(t))};return window.addEventListener("storage",e),()=>window.removeEventListener("storage",e)}),[t,i]);const l=(0,r.useRef)(!1);return(0,r.useEffect)((()=>{if(t&&!n)return;const e=window.matchMedia("(prefers-color-scheme: dark)"),r=()=>{window.matchMedia("print").matches||l.current?l.current=window.matchMedia("print").matches:i(null)};return e.addListener(r),()=>e.removeListener(r)}),[i,t,n]),(0,r.useMemo)((()=>({colorMode:a,setColorMode:i,get isDarkTheme(){return a===f.dark},setLightTheme(){i(f.light)},setDarkTheme(){i(f.dark)}})),[a,i])}();return(0,l.jsx)(u.Provider,{value:n,children:t})}function y(){const e=(0,r.useContext)(u);if(null==e)throw new o.i6("ColorModeProvider","Please see https://docusaurus.io/docs/api/themes/configuration#use-color-mode.");return e}},373:(e,t,n)=>{"use strict";n.d(t,{J:()=>v,L5:()=>y});var r=n(7294),a=n(143),o=n(9935),i=n(6668),s=n(2802),l=n(902),u=n(12),c=n(5893);const d=e=>`docs-preferred-version-${e}`,f={save:(e,t,n)=>{(0,u.WA)(d(e),{persistence:t}).set(n)},read:(e,t)=>(0,u.WA)(d(e),{persistence:t}).get(),clear:(e,t)=>{(0,u.WA)(d(e),{persistence:t}).del()}},p=e=>Object.fromEntries(e.map((e=>[e,{preferredVersionName:null}])));const h=r.createContext(null);function m(){const e=(0,a._r)(),t=(0,i.L)().docs.versionPersistence,n=(0,r.useMemo)((()=>Object.keys(e)),[e]),[o,s]=(0,r.useState)((()=>p(n)));(0,r.useEffect)((()=>{s(function(e){let{pluginIds:t,versionPersistence:n,allDocsData:r}=e;function a(e){const t=f.read(e,n);return r[e].versions.some((e=>e.name===t))?{preferredVersionName:t}:(f.clear(e,n),{preferredVersionName:null})}return Object.fromEntries(t.map((e=>[e,a(e)])))}({allDocsData:e,versionPersistence:t,pluginIds:n}))}),[e,t,n]);return[o,(0,r.useMemo)((()=>({savePreferredVersion:function(e,n){f.save(e,t,n),s((t=>({...t,[e]:{preferredVersionName:n}})))}})),[t])]}function g(e){let{children:t}=e;const n=m();return(0,c.jsx)(h.Provider,{value:n,children:t})}function y(e){let{children:t}=e;return s.cE?(0,c.jsx)(g,{children:t}):(0,c.jsx)(c.Fragment,{children:t})}function b(){const e=(0,r.useContext)(h);if(!e)throw new l.i6("DocsPreferredVersionContextProvider");return e}function v(e){void 0===e&&(e=o.m);const t=(0,a.zh)(e),[n,i]=b(),{preferredVersionName:s}=n[e];return{preferredVersion:t.versions.find((e=>e.name===s))??null,savePreferredVersionName:(0,r.useCallback)((t=>{i.savePreferredVersion(e,t)}),[i,e])}}},1116:(e,t,n)=>{"use strict";n.d(t,{V:()=>u,b:()=>l});var r=n(7294),a=n(902),o=n(5893);const i=Symbol("EmptyContext"),s=r.createContext(i);function l(e){let{children:t,name:n,items:a}=e;const i=(0,r.useMemo)((()=>n&&a?{name:n,items:a}:null),[n,a]);return(0,o.jsx)(s.Provider,{value:i,children:t})}function u(){const e=(0,r.useContext)(s);if(e===i)throw new a.i6("DocsSidebarProvider");return e}},4477:(e,t,n)=>{"use strict";n.d(t,{E:()=>l,q:()=>s});var r=n(7294),a=n(902),o=n(5893);const i=r.createContext(null);function s(e){let{children:t,version:n}=e;return(0,o.jsx)(i.Provider,{value:n,children:t})}function l(){const e=(0,r.useContext)(i);if(null===e)throw new a.i6("DocsVersionProvider");return e}},2961:(e,t,n)=>{"use strict";n.d(t,{M:()=>p,e:()=>h});var r=n(7294),a=n(3102),o=n(7524),i=n(6550),s=n(902);function l(e){!function(e){const t=(0,i.k6)(),n=(0,s.zX)(e);(0,r.useEffect)((()=>t.block(((e,t)=>n(e,t)))),[t,n])}(((t,n)=>{if("POP"===n)return e(t,n)}))}var u=n(6668),c=n(5893);const d=r.createContext(void 0);function f(){const e=function(){const e=(0,a.HY)(),{items:t}=(0,u.L)().navbar;return 0===t.length&&!e.component}(),t=(0,o.i)(),n=!e&&"mobile"===t,[i,s]=(0,r.useState)(!1);l((()=>{if(i)return s(!1),!1}));const c=(0,r.useCallback)((()=>{s((e=>!e))}),[]);return(0,r.useEffect)((()=>{"desktop"===t&&s(!1)}),[t]),(0,r.useMemo)((()=>({disabled:e,shouldRender:n,toggle:c,shown:i})),[e,n,c,i])}function p(e){let{children:t}=e;const n=f();return(0,c.jsx)(d.Provider,{value:n,children:t})}function h(){const e=r.useContext(d);if(void 0===e)throw new s.i6("NavbarMobileSidebarProvider");return e}},3102:(e,t,n)=>{"use strict";n.d(t,{HY:()=>l,Zo:()=>u,n2:()=>s});var r=n(7294),a=n(902),o=n(5893);const i=r.createContext(null);function s(e){let{children:t}=e;const n=(0,r.useState)({component:null,props:null});return(0,o.jsx)(i.Provider,{value:n,children:t})}function l(){const e=(0,r.useContext)(i);if(!e)throw new a.i6("NavbarSecondaryMenuContentProvider");return e[0]}function u(e){let{component:t,props:n}=e;const o=(0,r.useContext)(i);if(!o)throw new a.i6("NavbarSecondaryMenuContentProvider");const[,s]=o,l=(0,a.Ql)(n);return(0,r.useEffect)((()=>{s({component:t,props:l})}),[s,t,l]),(0,r.useEffect)((()=>()=>s({component:null,props:null})),[s]),null}},9727:(e,t,n)=>{"use strict";n.d(t,{h:()=>a,t:()=>o});var r=n(7294);const a="navigation-with-keyboard";function o(){(0,r.useEffect)((()=>{function e(e){"keydown"===e.type&&"Tab"===e.key&&document.body.classList.add(a),"mousedown"===e.type&&document.body.classList.remove(a)}return document.addEventListener("keydown",e),document.addEventListener("mousedown",e),()=>{document.body.classList.remove(a),document.removeEventListener("keydown",e),document.removeEventListener("mousedown",e)}}),[])}},7524:(e,t,n)=>{"use strict";n.d(t,{i:()=>s});var r=n(7294),a=n(412);const o={desktop:"desktop",mobile:"mobile",ssr:"ssr"},i=996;function s(){const[e,t]=(0,r.useState)((()=>"ssr"));return(0,r.useEffect)((()=>{function e(){t(function(){if(!a.Z.canUseDOM)throw new Error("getWindowSize() should only be called after React hydration");return window.innerWidth>i?o.desktop:o.mobile}())}return e(),window.addEventListener("resize",e),()=>{window.removeEventListener("resize",e)}}),[]),e}},5281:(e,t,n)=>{"use strict";n.d(t,{k:()=>r});const r={page:{blogListPage:"blog-list-page",blogPostPage:"blog-post-page",blogTagsListPage:"blog-tags-list-page",blogTagPostListPage:"blog-tags-post-list-page",docsDocPage:"docs-doc-page",docsTagsListPage:"docs-tags-list-page",docsTagDocListPage:"docs-tags-doc-list-page",mdxPage:"mdx-page"},wrapper:{main:"main-wrapper",blogPages:"blog-wrapper",docsPages:"docs-wrapper",mdxPages:"mdx-wrapper"},common:{editThisPage:"theme-edit-this-page",lastUpdated:"theme-last-updated",backToTopButton:"theme-back-to-top-button",codeBlock:"theme-code-block",admonition:"theme-admonition",unlistedBanner:"theme-unlisted-banner",admonitionType:e=>`theme-admonition-${e}`},layout:{},docs:{docVersionBanner:"theme-doc-version-banner",docVersionBadge:"theme-doc-version-badge",docBreadcrumbs:"theme-doc-breadcrumbs",docMarkdown:"theme-doc-markdown",docTocMobile:"theme-doc-toc-mobile",docTocDesktop:"theme-doc-toc-desktop",docFooter:"theme-doc-footer",docFooterTagsRow:"theme-doc-footer-tags-row",docFooterEditMetaRow:"theme-doc-footer-edit-meta-row",docSidebarContainer:"theme-doc-sidebar-container",docSidebarMenu:"theme-doc-sidebar-menu",docSidebarItemCategory:"theme-doc-sidebar-item-category",docSidebarItemLink:"theme-doc-sidebar-item-link",docSidebarItemCategoryLevel:e=>`theme-doc-sidebar-item-category-level-${e}`,docSidebarItemLinkLevel:e=>`theme-doc-sidebar-item-link-level-${e}`},blog:{}}},1442:(e,t,n)=>{"use strict";function r(){return window.matchMedia("(prefers-reduced-motion: reduce)").matches}n.d(t,{n:()=>r})},2802:(e,t,n)=>{"use strict";n.d(t,{MN:()=>C,LM:()=>h,_F:()=>b,cE:()=>f,jA:()=>m,xz:()=>p,SN:()=>T,lO:()=>S,vY:()=>_,oz:()=>E,s1:()=>x,f:()=>k});var r=n(7294),a=n(6550),o=n(8790),i=n(143),s=n(373),l=n(4477),u=n(1116);function c(e){return Array.from(new Set(e))}var d=n(8596);const f=!!i._r;function p(e){const t=(0,l.E)();if(!e)return;const n=t.docs[e];if(!n)throw new Error(`no version doc found by id=${e}`);return n}function h(e){return"link"!==e.type||e.unlisted?"category"===e.type?function(e){if(e.href&&!e.linkUnlisted)return e.href;for(const t of e.items){const e=h(t);if(e)return e}}(e):void 0:e.href}function m(){const{pathname:e}=(0,a.TH)(),t=(0,u.V)();if(!t)throw new Error("Unexpected: cant find current sidebar in context");const n=w({sidebarItems:t.items,pathname:e,onlyCategories:!0}).slice(-1)[0];if(!n)throw new Error(`${e} is not associated with a category. useCurrentSidebarCategory() should only be used on category index pages.`);return n}const g=(e,t)=>void 0!==e&&(0,d.Mg)(e,t),y=(e,t)=>e.some((e=>b(e,t)));function b(e,t){return"link"===e.type?g(e.href,t):"category"===e.type&&(g(e.href,t)||y(e.items,t))}function v(e,t){switch(e.type){case"category":return b(e,t)||e.items.some((e=>v(e,t)));case"link":return!e.unlisted||b(e,t);default:return!0}}function k(e,t){return(0,r.useMemo)((()=>e.filter((e=>v(e,t)))),[e,t])}function w(e){let{sidebarItems:t,pathname:n,onlyCategories:r=!1}=e;const a=[];return function e(t){for(const o of t)if("category"===o.type&&((0,d.Mg)(o.href,n)||e(o.items))||"link"===o.type&&(0,d.Mg)(o.href,n)){return r&&"category"!==o.type||a.unshift(o),!0}return!1}(t),a}function x(){const e=(0,u.V)(),{pathname:t}=(0,a.TH)(),n=(0,i.gA)()?.pluginData.breadcrumbs;return!1!==n&&e?w({sidebarItems:e.items,pathname:t}):null}function S(e){const{activeVersion:t}=(0,i.Iw)(e),{preferredVersion:n}=(0,s.J)(e),a=(0,i.yW)(e);return(0,r.useMemo)((()=>c([t,n,a].filter(Boolean))),[t,n,a])}function E(e,t){const n=S(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.sidebars?Object.entries(e.sidebars):[])),r=t.find((t=>t[0]===e));if(!r)throw new Error(`Can't find any sidebar with id "${e}" in version${n.length>1?"s":""} ${n.map((e=>e.name)).join(", ")}".\nAvailable sidebar ids are:\n- ${t.map((e=>e[0])).join("\n- ")}`);return r[1]}),[e,n])}function _(e,t){const n=S(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.docs)),r=t.find((t=>t.id===e));if(!r){if(n.flatMap((e=>e.draftIds)).includes(e))return null;throw new Error(`Couldn't find any doc with id "${e}" in version${n.length>1?"s":""} "${n.map((e=>e.name)).join(", ")}".\nAvailable doc ids are:\n- ${c(t.map((e=>e.id))).join("\n- ")}`)}return r}),[e,n])}function T(e){let{route:t}=e;const n=(0,a.TH)(),r=(0,l.E)(),i=t.routes,s=i.find((e=>(0,a.LX)(n.pathname,e)));if(!s)return null;const u=s.sidebar,c=u?r.docsSidebars[u]:void 0;return{docElement:(0,o.H)(i),sidebarName:u,sidebarItems:c}}function C(e){return e.filter((e=>!("category"===e.type||"link"===e.type)||!!h(e)))}},9690:(e,t,n)=>{"use strict";n.d(t,{aG:()=>c,Ac:()=>u,Cw:()=>l,QW:()=>d});var r=n(7294),a=n(5999),o=n(8780);const i={errorBoundaryError:"errorBoundaryError_a6uf",errorBoundaryFallback:"errorBoundaryFallback_VBag"};var s=n(5893);function l(e){return(0,s.jsx)("button",{type:"button",...e,children:(0,s.jsx)(a.Z,{id:"theme.ErrorPageContent.tryAgain",description:"The label of the button to try again rendering when the React error boundary captures an error",children:"Try again"})})}function u(e){let{error:t,tryAgain:n}=e;return(0,s.jsxs)("div",{className:i.errorBoundaryFallback,children:[(0,s.jsx)("p",{children:t.message}),(0,s.jsx)(l,{onClick:n})]})}function c(e){let{error:t}=e;const n=(0,o.getErrorCausalChain)(t).map((e=>e.message)).join("\n\nCause:\n");return(0,s.jsx)("p",{className:i.errorBoundaryError,children:n})}class d extends r.Component{componentDidCatch(e,t){throw this.props.onError(e,t)}render(){return this.props.children}}},1944:(e,t,n)=>{"use strict";n.d(t,{FG:()=>p,d:()=>d,VC:()=>h});var r=n(7294),a=n(512),o=n(5742),i=n(226);function s(){const e=r.useContext(i._);if(!e)throw new Error("Unexpected: no Docusaurus route context found");return e}var l=n(4996),u=n(2263);var c=n(5893);function d(e){let{title:t,description:n,keywords:r,image:a,children:i}=e;const s=function(e){const{siteConfig:t}=(0,u.Z)(),{title:n,titleDelimiter:r}=t;return e?.trim().length?`${e.trim()} ${r} ${n}`:n}(t),{withBaseUrl:d}=(0,l.C)(),f=a?d(a,{absolute:!0}):void 0;return(0,c.jsxs)(o.Z,{children:[t&&(0,c.jsx)("title",{children:s}),t&&(0,c.jsx)("meta",{property:"og:title",content:s}),n&&(0,c.jsx)("meta",{name:"description",content:n}),n&&(0,c.jsx)("meta",{property:"og:description",content:n}),r&&(0,c.jsx)("meta",{name:"keywords",content:Array.isArray(r)?r.join(","):r}),f&&(0,c.jsx)("meta",{property:"og:image",content:f}),f&&(0,c.jsx)("meta",{name:"twitter:image",content:f}),i]})}const f=r.createContext(void 0);function p(e){let{className:t,children:n}=e;const i=r.useContext(f),s=(0,a.Z)(i,t);return(0,c.jsxs)(f.Provider,{value:s,children:[(0,c.jsx)(o.Z,{children:(0,c.jsx)("html",{className:s})}),n]})}function h(e){let{children:t}=e;const n=s(),r=`plugin-${n.plugin.name.replace(/docusaurus-(?:plugin|theme)-(?:content-)?/gi,"")}`;const o=`plugin-id-${n.plugin.id}`;return(0,c.jsx)(p,{className:(0,a.Z)(r,o),children:t})}},902:(e,t,n)=>{"use strict";n.d(t,{D9:()=>s,Qc:()=>c,Ql:()=>u,i6:()=>l,zX:()=>i});var r=n(7294),a=n(469),o=n(5893);function i(e){const t=(0,r.useRef)(e);return(0,a.Z)((()=>{t.current=e}),[e]),(0,r.useCallback)((function(){return t.current(...arguments)}),[])}function s(e){const t=(0,r.useRef)();return(0,a.Z)((()=>{t.current=e})),t.current}class l extends Error{constructor(e,t){super(),this.name="ReactContextError",this.message=`Hook ${this.stack?.split("\n")[1]?.match(/at (?:\w+\.)?(?\w+)/)?.groups.name??""} is called outside the <${e}>. ${t??""}`}}function u(e){const t=Object.entries(e);return t.sort(((e,t)=>e[0].localeCompare(t[0]))),(0,r.useMemo)((()=>e),t.flat())}function c(e){return t=>{let{children:n}=t;return(0,o.jsx)(o.Fragment,{children:e.reduceRight(((e,t)=>(0,o.jsx)(t,{children:e})),n)})}}},8596:(e,t,n)=>{"use strict";n.d(t,{Mg:()=>i,Ns:()=>s});var r=n(7294),a=n(723),o=n(2263);function i(e,t){const n=e=>(!e||e.endsWith("/")?e:`${e}/`)?.toLowerCase();return n(e)===n(t)}function s(){const{baseUrl:e}=(0,o.Z)().siteConfig;return(0,r.useMemo)((()=>function(e){let{baseUrl:t,routes:n}=e;function r(e){return e.path===t&&!0===e.exact}function a(e){return e.path===t&&!e.exact}return function e(t){if(0===t.length)return;return t.find(r)||e(t.filter(a).flatMap((e=>e.routes??[])))}(n)}({routes:a.Z,baseUrl:e})),[e])}},2466:(e,t,n)=>{"use strict";n.d(t,{Ct:()=>p,OC:()=>u,RF:()=>f});var r=n(7294),a=n(412),o=n(2389),i=(n(469),n(902)),s=n(5893);const l=r.createContext(void 0);function u(e){let{children:t}=e;const n=function(){const e=(0,r.useRef)(!0);return(0,r.useMemo)((()=>({scrollEventsEnabledRef:e,enableScrollEvents:()=>{e.current=!0},disableScrollEvents:()=>{e.current=!1}})),[])}();return(0,s.jsx)(l.Provider,{value:n,children:t})}function c(){const e=(0,r.useContext)(l);if(null==e)throw new i.i6("ScrollControllerProvider");return e}const d=()=>a.Z.canUseDOM?{scrollX:window.pageXOffset,scrollY:window.pageYOffset}:null;function f(e,t){void 0===t&&(t=[]);const{scrollEventsEnabledRef:n}=c(),a=(0,r.useRef)(d()),o=(0,i.zX)(e);(0,r.useEffect)((()=>{const e=()=>{if(!n.current)return;const e=d();o(e,a.current),a.current=e},t={passive:!0};return e(),window.addEventListener("scroll",e,t),()=>window.removeEventListener("scroll",e,t)}),[o,n,...t])}function p(){const e=(0,r.useRef)(null),t=(0,o.Z)()&&"smooth"===getComputedStyle(document.documentElement).scrollBehavior;return{startScroll:n=>{e.current=t?function(e){return window.scrollTo({top:e,behavior:"smooth"}),()=>{}}(n):function(e){let t=null;const n=document.documentElement.scrollTop>e;return function r(){const a=document.documentElement.scrollTop;(n&&a>e||!n&&at&&cancelAnimationFrame(t)}(n)},cancelScroll:()=>e.current?.()}}},3320:(e,t,n)=>{"use strict";n.d(t,{HX:()=>r,os:()=>a});n(2263);const r="default";function a(e,t){return`docs-${e}-${t}`}},12:(e,t,n)=>{"use strict";n.d(t,{WA:()=>l});n(7294);const r="localStorage";function a(e){let{key:t,oldValue:n,newValue:r,storage:a}=e;if(n===r)return;const o=document.createEvent("StorageEvent");o.initStorageEvent("storage",!1,!1,t,n,r,window.location.href,a),window.dispatchEvent(o)}function o(e){if(void 0===e&&(e=r),"undefined"==typeof window)throw new Error("Browser storage is not available on Node.js/Docusaurus SSR process.");if("none"===e)return null;try{return window[e]}catch(n){return t=n,i||(console.warn("Docusaurus browser storage is not available.\nPossible reasons: running Docusaurus in an iframe, in an incognito browser session, or using too strict browser privacy settings.",t),i=!0),null}var t}let i=!1;const s={get:()=>null,set:()=>{},del:()=>{},listen:()=>()=>{}};function l(e,t){if("undefined"==typeof window)return function(e){function t(){throw new Error(`Illegal storage API usage for storage key "${e}".\nDocusaurus storage APIs are not supposed to be called on the server-rendering process.\nPlease only call storage APIs in effects and event handlers.`)}return{get:t,set:t,del:t,listen:t}}(e);const n=o(t?.persistence);return null===n?s:{get:()=>{try{return n.getItem(e)}catch(t){return console.error(`Docusaurus storage error, can't get key=${e}`,t),null}},set:t=>{try{const r=n.getItem(e);n.setItem(e,t),a({key:e,oldValue:r,newValue:t,storage:n})}catch(r){console.error(`Docusaurus storage error, can't set ${e}=${t}`,r)}},del:()=>{try{const t=n.getItem(e);n.removeItem(e),a({key:e,oldValue:t,newValue:null,storage:n})}catch(t){console.error(`Docusaurus storage error, can't delete key=${e}`,t)}},listen:t=>{try{const r=r=>{r.storageArea===n&&r.key===e&&t(r)};return window.addEventListener("storage",r),()=>window.removeEventListener("storage",r)}catch(r){return console.error(`Docusaurus storage error, can't listen for changes of key=${e}`,r),()=>{}}}}}},4711:(e,t,n)=>{"use strict";n.d(t,{l:()=>i});var r=n(2263),a=n(6550),o=n(8780);function i(){const{siteConfig:{baseUrl:e,url:t,trailingSlash:n},i18n:{defaultLocale:i,currentLocale:s}}=(0,r.Z)(),{pathname:l}=(0,a.TH)(),u=(0,o.applyTrailingSlash)(l,{trailingSlash:n,baseUrl:e}),c=s===i?e:e.replace(`/${s}/`,"/"),d=u.replace(e,"");return{createUrl:function(e){let{locale:n,fullyQualified:r}=e;return`${r?t:""}${function(e){return e===i?`${c}`:`${c}${e}/`}(n)}${d}`}}}},5936:(e,t,n)=>{"use strict";n.d(t,{S:()=>i});var r=n(7294),a=n(6550),o=n(902);function i(e){const t=(0,a.TH)(),n=(0,o.D9)(t),i=(0,o.zX)(e);(0,r.useEffect)((()=>{n&&t!==n&&i({location:t,previousLocation:n})}),[i,t,n])}},6668:(e,t,n)=>{"use strict";n.d(t,{L:()=>a});var r=n(2263);function a(){return(0,r.Z)().siteConfig.themeConfig}},8802:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t){const{trailingSlash:n,baseUrl:r}=t;if(e.startsWith("#"))return e;if(void 0===n)return e;const[a]=e.split(/[#?]/),o="/"===a||a===r?a:(i=a,n?function(e){return e.endsWith("/")?e:`${e}/`}(i):function(e){return e.endsWith("/")?e.slice(0,-1):e}(i));var i;return e.replace(a,o)}},4143:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getErrorCausalChain=void 0,t.getErrorCausalChain=function e(t){return t.cause?[t,...e(t.cause)]:[t]}},8780:function(e,t,n){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.getErrorCausalChain=t.applyTrailingSlash=t.blogPostContainerID=void 0,t.blogPostContainerID="__blog-post-container";var a=n(8802);Object.defineProperty(t,"applyTrailingSlash",{enumerable:!0,get:function(){return r(a).default}});var o=n(4143);Object.defineProperty(t,"getErrorCausalChain",{enumerable:!0,get:function(){return o.getErrorCausalChain}})},311:(e,t,n)=>{"use strict";n.d(t,{Z:()=>i});n(7294);var r=n(1728);const a={loadingRing:"loadingRing_RJI3","loading-ring":"loading-ring_FB5o"};var o=n(5893);function i(e){let{className:t}=e;return(0,o.jsxs)("div",{className:(0,r.Z)(a.loadingRing,t),children:[(0,o.jsx)("div",{}),(0,o.jsx)("div",{}),(0,o.jsx)("div",{}),(0,o.jsx)("div",{})]})}},22:(e,t,n)=>{"use strict";n.d(t,{w:()=>s});var r=n(1336),a=n.n(r),o=n(1029);const i=new Map;function s(e,t){const n=`${e}${t}`;let r=i.get(n);return r||(r=async function(e,t){{const n=`${e}${o.J.replace("{dir}",t?`-${t.replace(/\//g,"-")}`:"")}`;if(new URL(n,location.origin).origin!==location.origin)throw new Error("Unexpected version url");const r=await(await fetch(n)).json(),i=r.map(((e,t)=>{let{documents:n,index:r}=e;return{type:t,documents:n,index:a().Index.load(r)}})),s=r.reduce(((e,t)=>{for(const n of t.index.invertedIndex)/\p{Unified_Ideograph}/u.test(n[0][0])&&e.add(n[0]);return e}),new Set);return{wrappedIndexes:i,zhDictionary:Array.from(s)}}return{wrappedIndexes:[],zhDictionary:[]}}(e,t),i.set(n,r)),r}},8202:(e,t,n)=>{"use strict";n.d(t,{v:()=>l});var r=n(1336),a=n.n(r);var o=n(1029);function i(e){return s(e).concat(s(e.filter((e=>{const t=e[e.length-1];return!t.trailing&&t.maybeTyping})),!0))}function s(e,t){return e.map((e=>({tokens:e.map((e=>e.value)),term:e.map((e=>({value:e.value,presence:a().Query.presence.REQUIRED,wildcard:(t?e.trailing||e.maybeTyping:e.trailing)?a().Query.wildcard.TRAILING:a().Query.wildcard.NONE})))})))}function l(e,t,n){return function(r,s){const l=function(e,t){if(1===t.length&&["ja","jp","th"].includes(t[0]))return a()[t[0]].tokenizer(e).map((e=>e.toString()));let n=/[^-\s]+/g;return t.includes("zh")&&(n=/\w+|\p{Unified_Ideograph}+/gu),e.toLowerCase().match(n)||[]}(r,o.dK);if(0===l.length)return void s([]);const u=function(e,t){const n=function(e,t){const n=[];return function e(r,a){if(0===r.length)return void n.push(a);const o=r[0];if(/\p{Unified_Ideograph}/u.test(o)){const n=function(e,t){const n=[];return function e(r,a){let o=0,i=!1;for(const s of t)if(r.substr(0,s.length)===s){const t={missed:a.missed,term:a.term.concat({value:s})};r.length>s.length?e(r.substr(s.length),t):n.push(t),i=!0}else for(let t=s.length-1;t>o;t-=1){const l=s.substr(0,t);if(r.substr(0,t)===l){o=t;const s={missed:a.missed,term:a.term.concat({value:l,trailing:!0})};r.length>t?e(r.substr(t),s):n.push(s),i=!0;break}}i||(r.length>0?e(r.substr(1),{missed:a.missed+1,term:a.term}):a.term.length>0&&n.push(a))}(e,{missed:0,term:[]}),n.sort(((e,t)=>{const n=e.missed>0?1:0,r=t.missed>0?1:0;return n!==r?n-r:e.term.length-t.term.length})).map((e=>e.term))}(o,t);for(const t of n){const n=a.concat(...t);e(r.slice(1),n)}}else{const t=a.concat({value:o});e(r.slice(1),t)}}(e,[]),n}(e,t);if(0===n.length)return[{tokens:e,term:e.map((e=>({value:e,presence:a().Query.presence.REQUIRED,wildcard:a().Query.wildcard.LEADING|a().Query.wildcard.TRAILING})))}];for(const a of n)a[a.length-1].maybeTyping=!0;const r=[];for(const i of o.dK)if("en"===i)o._k||r.unshift(a().stopWordFilter);else{const e=a()[i];e.stopWordFilter&&r.unshift(e.stopWordFilter)}let s;if(r.length>0){const e=e=>r.reduce(((e,t)=>e.filter((e=>t(e.value)))),e);s=[];const t=[];for(const r of n){const n=e(r);s.push(n),n.length0&&t.push(n)}n.push(...t)}else s=n.slice();const l=[];for(const a of s)if(a.length>2)for(let e=a.length-1;e>=0;e-=1)l.push(a.slice(0,e).concat(a.slice(e+1)));return i(n).concat(i(l))}(l,t),c=[];e:for(const{term:t,tokens:a}of u)for(const{documents:r,index:o,type:i}of e)if(c.push(...o.query((e=>{for(const n of t)e.term(n.value,{wildcard:n.wildcard,presence:n.presence})})).slice(0,n).filter((e=>!c.some((t=>t.document.i.toString()===e.ref)))).slice(0,n-c.length).map((t=>{const n=r.find((e=>e.i.toString()===t.ref));return{document:n,type:i,page:0!==i&&e[0].documents.find((e=>e.i===n.p)),metadata:t.matchData.metadata,tokens:a,score:t.score}}))),c.length>=n)break e;!function(e){e.forEach(((e,t)=>{e.index=t})),e.sort(((t,n)=>{let r=t.type>0&&t.page?e.findIndex((e=>e.document===t.page)):t.index,a=n.type>0&&n.page?e.findIndex((e=>e.document===n.page)):n.index;return-1===r&&(r=t.index),-1===a&&(a=n.index),r===a?0===t.type?-1:0===n.type?1:t.index-n.index:r-a}))}(c),function(e){e.forEach(((t,n)=>{n>0&&t.page&&e.some((e=>e.document===t.page))&&(n{"use strict";function r(e){return e.join(" \u203a ")}n.d(t,{e:()=>r})},1690:(e,t,n)=>{"use strict";function r(e){return e.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'")}n.d(t,{X:()=>r})},1073:(e,t,n)=>{"use strict";function r(e,t){const n=[];for(const r of Object.values(e))r[t]&&n.push(...r[t].position);return n.sort(((e,t)=>e[0]-t[0]||t[1]-e[1]))}n.d(t,{m:()=>r})},2539:(e,t,n)=>{"use strict";n.d(t,{C:()=>a});var r=n(1690);function a(e,t,n){const o=[];for(const i of t){const n=e.toLowerCase().indexOf(i);if(n>=0){n>0&&o.push(a(e.substr(0,n),t)),o.push(`${(0,r.X)(e.substr(n,i.length))}`);const s=n+i.length;s${(0,r.X)(e)}`:(0,r.X)(e):o.join("")}},726:(e,t,n)=>{"use strict";n.d(t,{o:()=>l});var r=n(1690),a=n(2539);const o=/\w+|\p{Unified_Ideograph}/u;function i(e){const t=[];let n=0,r=e;for(;r.length>0;){const a=r.match(o);if(!a){t.push(r);break}a.index>0&&t.push(r.substring(0,a.index)),t.push(a[0]),n+=a.index+a[0].length,r=e.substring(n)}return t}var s=n(1029);function l(e,t,n,o){void 0===o&&(o=s.Hk);const{chunkIndex:l,chunks:u}=function(e,t,n){const o=[];let s=0,l=0,u=-1;for(;sl){const t=i(e.substring(l,c)).map((e=>({html:(0,r.X)(e),textLength:e.length})));for(const e of t)o.push(e)}-1===u&&(u=o.length),l=c+d,o.push({html:(0,a.C)(e.substring(c,l),n,!0),textLength:d})}}if(l({html:(0,r.X)(e),textLength:e.length})));for(const e of t)o.push(e)}return{chunkIndex:u,chunks:o}}(e,t,n),c=u.slice(0,l),d=u[l],f=[d.html],p=u.slice(l+1);let h=d.textLength,m=0,g=0,y=!1,b=!1;for(;h0){const e=c.pop();h+e.textLength<=o?(f.unshift(e.html),m+=e.textLength,h+=e.textLength):(y=!0,c.length=0)}else{if(!(p.length>0))break;{const e=p.shift();h+e.textLength<=o?(f.push(e.html),g+=e.textLength,h+=e.textLength):(b=!0,p.length=0)}}return(y||c.length>0)&&f.unshift("\u2026"),(b||p.length>0)&&f.push("\u2026"),f.join("")}},51:(e,t,n)=>{"use strict";function r(e,t){if("string"==typeof e)return{label:e,path:e};{const{label:n,path:r}=e;return"string"==typeof n?{label:n,path:r}:Object.prototype.hasOwnProperty.call(n,t)?{label:n[t],path:r}:{label:r,path:r}}}n.d(t,{_:()=>r})},1029:(e,t,n)=>{"use strict";n.d(t,{vc:()=>o,gQ:()=>p,H6:()=>u,hG:()=>g,l9:()=>h,dK:()=>r,_k:()=>a,pu:()=>f,AY:()=>c,t_:()=>d,Kc:()=>m,J:()=>i,Hk:()=>l,qo:()=>s,pQ:()=>y});n(1336);const r=["en"],a=!1,o=null,i="search-index{dir}.json?_=822b430b",s=8,l=50,u=!1,c=!0,d=!0,f="right",p=void 0,h=!0,m=[{label:"Documents",path:"docs"},{label:"Blog",path:"blog"}],g=!0,y=!1},9318:(e,t,n)=>{"use strict";n.d(t,{lX:()=>k,q_:()=>T,ob:()=>p,PP:()=>L,Ep:()=>f});var r=n(7462);function a(e){return"/"===e.charAt(0)}function o(e,t){for(var n=t,r=n+1,a=e.length;r=0;f--){var p=i[f];"."===p?o(i,f):".."===p?(o(i,f),d++):d&&(o(i,f),d--)}if(!u)for(;d--;d)i.unshift("..");!u||""===i[0]||i[0]&&a(i[0])||i.unshift("");var h=i.join("/");return n&&"/"!==h.substr(-1)&&(h+="/"),h};var s=n(8776);function l(e){return"/"===e.charAt(0)?e:"/"+e}function u(e){return"/"===e.charAt(0)?e.substr(1):e}function c(e,t){return function(e,t){return 0===e.toLowerCase().indexOf(t.toLowerCase())&&-1!=="/?#".indexOf(e.charAt(t.length))}(e,t)?e.substr(t.length):e}function d(e){return"/"===e.charAt(e.length-1)?e.slice(0,-1):e}function f(e){var t=e.pathname,n=e.search,r=e.hash,a=t||"/";return n&&"?"!==n&&(a+="?"===n.charAt(0)?n:"?"+n),r&&"#"!==r&&(a+="#"===r.charAt(0)?r:"#"+r),a}function p(e,t,n,a){var o;"string"==typeof e?(o=function(e){var t=e||"/",n="",r="",a=t.indexOf("#");-1!==a&&(r=t.substr(a),t=t.substr(0,a));var o=t.indexOf("?");return-1!==o&&(n=t.substr(o),t=t.substr(0,o)),{pathname:t,search:"?"===n?"":n,hash:"#"===r?"":r}}(e),o.state=t):(void 0===(o=(0,r.Z)({},e)).pathname&&(o.pathname=""),o.search?"?"!==o.search.charAt(0)&&(o.search="?"+o.search):o.search="",o.hash?"#"!==o.hash.charAt(0)&&(o.hash="#"+o.hash):o.hash="",void 0!==t&&void 0===o.state&&(o.state=t));try{o.pathname=decodeURI(o.pathname)}catch(s){throw s instanceof URIError?new URIError('Pathname "'+o.pathname+'" could not be decoded. This is likely caused by an invalid percent-encoding.'):s}return n&&(o.key=n),a?o.pathname?"/"!==o.pathname.charAt(0)&&(o.pathname=i(o.pathname,a.pathname)):o.pathname=a.pathname:o.pathname||(o.pathname="/"),o}function h(){var e=null;var t=[];return{setPrompt:function(t){return e=t,function(){e===t&&(e=null)}},confirmTransitionTo:function(t,n,r,a){if(null!=e){var o="function"==typeof e?e(t,n):e;"string"==typeof o?"function"==typeof r?r(o,a):a(!0):a(!1!==o)}else a(!0)},appendListener:function(e){var n=!0;function r(){n&&e.apply(void 0,arguments)}return t.push(r),function(){n=!1,t=t.filter((function(e){return e!==r}))}},notifyListeners:function(){for(var e=arguments.length,n=new Array(e),r=0;rt?n.splice(t,n.length-t,a):n.push(a),d({action:r,location:a,index:t,entries:n})}}))},replace:function(e,t){var r="REPLACE",a=p(e,t,m(),k.location);c.confirmTransitionTo(a,r,n,(function(e){e&&(k.entries[k.index]=a,d({action:r,location:a}))}))},go:v,goBack:function(){v(-1)},goForward:function(){v(1)},canGo:function(e){var t=k.index+e;return t>=0&&t{"use strict";var r=n(9864),a={childContextTypes:!0,contextType:!0,contextTypes:!0,defaultProps:!0,displayName:!0,getDefaultProps:!0,getDerivedStateFromError:!0,getDerivedStateFromProps:!0,mixins:!0,propTypes:!0,type:!0},o={name:!0,length:!0,prototype:!0,caller:!0,callee:!0,arguments:!0,arity:!0},i={$$typeof:!0,compare:!0,defaultProps:!0,displayName:!0,propTypes:!0,type:!0},s={};function l(e){return r.isMemo(e)?i:s[e.$$typeof]||a}s[r.ForwardRef]={$$typeof:!0,render:!0,defaultProps:!0,displayName:!0,propTypes:!0},s[r.Memo]=i;var u=Object.defineProperty,c=Object.getOwnPropertyNames,d=Object.getOwnPropertySymbols,f=Object.getOwnPropertyDescriptor,p=Object.getPrototypeOf,h=Object.prototype;e.exports=function e(t,n,r){if("string"!=typeof n){if(h){var a=p(n);a&&a!==h&&e(t,a,r)}var i=c(n);d&&(i=i.concat(d(n)));for(var s=l(t),m=l(n),g=0;g{"use strict";e.exports=function(e,t,n,r,a,o,i,s){if(!e){var l;if(void 0===t)l=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var u=[n,r,a,o,i,s],c=0;(l=new Error(t.replace(/%s/g,(function(){return u[c++]})))).name="Invariant Violation"}throw l.framesToPop=1,l}}},5826:e=>{e.exports=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)}},1336:(e,t,n)=>{var r,a;!function(){var o,i,s,l,u,c,d,f,p,h,m,g,y,b,v,k,w,x,S,E,_,T,C,L,N,A,P,O,I,j,R=function(e){var t=new R.Builder;return t.pipeline.add(R.trimmer,R.stopWordFilter,R.stemmer),t.searchPipeline.add(R.stemmer),e.call(t,t),t.build()};R.version="2.3.9",R.utils={},R.utils.warn=(o=this,function(e){o.console&&console.warn&&console.warn(e)}),R.utils.asString=function(e){return null==e?"":e.toString()},R.utils.clone=function(e){if(null==e)return e;for(var t=Object.create(null),n=Object.keys(e),r=0;r0){var l=R.utils.clone(t)||{};l.position=[i,s],l.index=a.length,a.push(new R.Token(n.slice(i,o),l))}i=o+1}}return a},R.tokenizer.separator=/[\s\-]+/,R.Pipeline=function(){this._stack=[]},R.Pipeline.registeredFunctions=Object.create(null),R.Pipeline.registerFunction=function(e,t){t in this.registeredFunctions&&R.utils.warn("Overwriting existing registered function: "+t),e.label=t,R.Pipeline.registeredFunctions[e.label]=e},R.Pipeline.warnIfFunctionNotRegistered=function(e){e.label&&e.label in this.registeredFunctions||R.utils.warn("Function is not registered with pipeline. This may cause problems when serialising the index.\n",e)},R.Pipeline.load=function(e){var t=new R.Pipeline;return e.forEach((function(e){var n=R.Pipeline.registeredFunctions[e];if(!n)throw new Error("Cannot load unregistered function: "+e);t.add(n)})),t},R.Pipeline.prototype.add=function(){Array.prototype.slice.call(arguments).forEach((function(e){R.Pipeline.warnIfFunctionNotRegistered(e),this._stack.push(e)}),this)},R.Pipeline.prototype.after=function(e,t){R.Pipeline.warnIfFunctionNotRegistered(t);var n=this._stack.indexOf(e);if(-1==n)throw new Error("Cannot find existingFn");n+=1,this._stack.splice(n,0,t)},R.Pipeline.prototype.before=function(e,t){R.Pipeline.warnIfFunctionNotRegistered(t);var n=this._stack.indexOf(e);if(-1==n)throw new Error("Cannot find existingFn");this._stack.splice(n,0,t)},R.Pipeline.prototype.remove=function(e){var t=this._stack.indexOf(e);-1!=t&&this._stack.splice(t,1)},R.Pipeline.prototype.run=function(e){for(var t=this._stack.length,n=0;n1&&(oe&&(n=a),o!=e);)r=n-t,a=t+Math.floor(r/2),o=this.elements[2*a];return o==e||o>e?2*a:os?u+=2:i==s&&(t+=n[l+1]*r[u+1],l+=2,u+=2);return t},R.Vector.prototype.similarity=function(e){return this.dot(e)/this.magnitude()||0},R.Vector.prototype.toArray=function(){for(var e=new Array(this.elements.length/2),t=1,n=0;t0){var o,i=a.str.charAt(0);i in a.node.edges?o=a.node.edges[i]:(o=new R.TokenSet,a.node.edges[i]=o),1==a.str.length&&(o.final=!0),r.push({node:o,editsRemaining:a.editsRemaining,str:a.str.slice(1)})}if(0!=a.editsRemaining){if("*"in a.node.edges)var s=a.node.edges["*"];else{s=new R.TokenSet;a.node.edges["*"]=s}if(0==a.str.length&&(s.final=!0),r.push({node:s,editsRemaining:a.editsRemaining-1,str:a.str}),a.str.length>1&&r.push({node:a.node,editsRemaining:a.editsRemaining-1,str:a.str.slice(1)}),1==a.str.length&&(a.node.final=!0),a.str.length>=1){if("*"in a.node.edges)var l=a.node.edges["*"];else{l=new R.TokenSet;a.node.edges["*"]=l}1==a.str.length&&(l.final=!0),r.push({node:l,editsRemaining:a.editsRemaining-1,str:a.str.slice(1)})}if(a.str.length>1){var u,c=a.str.charAt(0),d=a.str.charAt(1);d in a.node.edges?u=a.node.edges[d]:(u=new R.TokenSet,a.node.edges[d]=u),1==a.str.length&&(u.final=!0),r.push({node:u,editsRemaining:a.editsRemaining-1,str:c+a.str.slice(2)})}}}return n},R.TokenSet.fromString=function(e){for(var t=new R.TokenSet,n=t,r=0,a=e.length;r=e;t--){var n=this.uncheckedNodes[t],r=n.child.toString();r in this.minimizedNodes?n.parent.edges[n.char]=this.minimizedNodes[r]:(n.child._str=r,this.minimizedNodes[r]=n.child),this.uncheckedNodes.pop()}},R.Index=function(e){this.invertedIndex=e.invertedIndex,this.fieldVectors=e.fieldVectors,this.tokenSet=e.tokenSet,this.fields=e.fields,this.pipeline=e.pipeline},R.Index.prototype.search=function(e){return this.query((function(t){new R.QueryParser(e,t).parse()}))},R.Index.prototype.query=function(e){for(var t=new R.Query(this.fields),n=Object.create(null),r=Object.create(null),a=Object.create(null),o=Object.create(null),i=Object.create(null),s=0;s1?1:e},R.Builder.prototype.k1=function(e){this._k1=e},R.Builder.prototype.add=function(e,t){var n=e[this._ref],r=Object.keys(this._fields);this._documents[n]=t||{},this.documentCount+=1;for(var a=0;a=this.length)return R.QueryLexer.EOS;var e=this.str.charAt(this.pos);return this.pos+=1,e},R.QueryLexer.prototype.width=function(){return this.pos-this.start},R.QueryLexer.prototype.ignore=function(){this.start==this.pos&&(this.pos+=1),this.start=this.pos},R.QueryLexer.prototype.backup=function(){this.pos-=1},R.QueryLexer.prototype.acceptDigitRun=function(){var e,t;do{t=(e=this.next()).charCodeAt(0)}while(t>47&&t<58);e!=R.QueryLexer.EOS&&this.backup()},R.QueryLexer.prototype.more=function(){return this.pos1&&(e.backup(),e.emit(R.QueryLexer.TERM)),e.ignore(),e.more())return R.QueryLexer.lexText},R.QueryLexer.lexEditDistance=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(R.QueryLexer.EDIT_DISTANCE),R.QueryLexer.lexText},R.QueryLexer.lexBoost=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(R.QueryLexer.BOOST),R.QueryLexer.lexText},R.QueryLexer.lexEOS=function(e){e.width()>0&&e.emit(R.QueryLexer.TERM)},R.QueryLexer.termSeparator=R.tokenizer.separator,R.QueryLexer.lexText=function(e){for(;;){var t=e.next();if(t==R.QueryLexer.EOS)return R.QueryLexer.lexEOS;if(92!=t.charCodeAt(0)){if(":"==t)return R.QueryLexer.lexField;if("~"==t)return e.backup(),e.width()>0&&e.emit(R.QueryLexer.TERM),R.QueryLexer.lexEditDistance;if("^"==t)return e.backup(),e.width()>0&&e.emit(R.QueryLexer.TERM),R.QueryLexer.lexBoost;if("+"==t&&1===e.width())return e.emit(R.QueryLexer.PRESENCE),R.QueryLexer.lexText;if("-"==t&&1===e.width())return e.emit(R.QueryLexer.PRESENCE),R.QueryLexer.lexText;if(t.match(R.QueryLexer.termSeparator))return R.QueryLexer.lexTerm}else e.escapeCharacter()}},R.QueryParser=function(e,t){this.lexer=new R.QueryLexer(e),this.query=t,this.currentClause={},this.lexemeIdx=0},R.QueryParser.prototype.parse=function(){this.lexer.run(),this.lexemes=this.lexer.lexemes;for(var e=R.QueryParser.parseClause;e;)e=e(this);return this.query},R.QueryParser.prototype.peekLexeme=function(){return this.lexemes[this.lexemeIdx]},R.QueryParser.prototype.consumeLexeme=function(){var e=this.peekLexeme();return this.lexemeIdx+=1,e},R.QueryParser.prototype.nextClause=function(){var e=this.currentClause;this.query.clause(e),this.currentClause={}},R.QueryParser.parseClause=function(e){var t=e.peekLexeme();if(null!=t)switch(t.type){case R.QueryLexer.PRESENCE:return R.QueryParser.parsePresence;case R.QueryLexer.FIELD:return R.QueryParser.parseField;case R.QueryLexer.TERM:return R.QueryParser.parseTerm;default:var n="expected either a field or a term, found "+t.type;throw t.str.length>=1&&(n+=" with value '"+t.str+"'"),new R.QueryParseError(n,t.start,t.end)}},R.QueryParser.parsePresence=function(e){var t=e.consumeLexeme();if(null!=t){switch(t.str){case"-":e.currentClause.presence=R.Query.presence.PROHIBITED;break;case"+":e.currentClause.presence=R.Query.presence.REQUIRED;break;default:var n="unrecognised presence operator'"+t.str+"'";throw new R.QueryParseError(n,t.start,t.end)}var r=e.peekLexeme();if(null==r){n="expecting term or field, found nothing";throw new R.QueryParseError(n,t.start,t.end)}switch(r.type){case R.QueryLexer.FIELD:return R.QueryParser.parseField;case R.QueryLexer.TERM:return R.QueryParser.parseTerm;default:n="expecting term or field, found '"+r.type+"'";throw new R.QueryParseError(n,r.start,r.end)}}},R.QueryParser.parseField=function(e){var t=e.consumeLexeme();if(null!=t){if(-1==e.query.allFields.indexOf(t.str)){var n=e.query.allFields.map((function(e){return"'"+e+"'"})).join(", "),r="unrecognised field '"+t.str+"', possible fields: "+n;throw new R.QueryParseError(r,t.start,t.end)}e.currentClause.fields=[t.str];var a=e.peekLexeme();if(null==a){r="expecting term, found nothing";throw new R.QueryParseError(r,t.start,t.end)}if(a.type===R.QueryLexer.TERM)return R.QueryParser.parseTerm;r="expecting term, found '"+a.type+"'";throw new R.QueryParseError(r,a.start,a.end)}},R.QueryParser.parseTerm=function(e){var t=e.consumeLexeme();if(null!=t){e.currentClause.term=t.str.toLowerCase(),-1!=t.str.indexOf("*")&&(e.currentClause.usePipeline=!1);var n=e.peekLexeme();if(null!=n)switch(n.type){case R.QueryLexer.TERM:return e.nextClause(),R.QueryParser.parseTerm;case R.QueryLexer.FIELD:return e.nextClause(),R.QueryParser.parseField;case R.QueryLexer.EDIT_DISTANCE:return R.QueryParser.parseEditDistance;case R.QueryLexer.BOOST:return R.QueryParser.parseBoost;case R.QueryLexer.PRESENCE:return e.nextClause(),R.QueryParser.parsePresence;default:var r="Unexpected lexeme type '"+n.type+"'";throw new R.QueryParseError(r,n.start,n.end)}else e.nextClause()}},R.QueryParser.parseEditDistance=function(e){var t=e.consumeLexeme();if(null!=t){var n=parseInt(t.str,10);if(isNaN(n)){var r="edit distance must be numeric";throw new R.QueryParseError(r,t.start,t.end)}e.currentClause.editDistance=n;var a=e.peekLexeme();if(null!=a)switch(a.type){case R.QueryLexer.TERM:return e.nextClause(),R.QueryParser.parseTerm;case R.QueryLexer.FIELD:return e.nextClause(),R.QueryParser.parseField;case R.QueryLexer.EDIT_DISTANCE:return R.QueryParser.parseEditDistance;case R.QueryLexer.BOOST:return R.QueryParser.parseBoost;case R.QueryLexer.PRESENCE:return e.nextClause(),R.QueryParser.parsePresence;default:r="Unexpected lexeme type '"+a.type+"'";throw new R.QueryParseError(r,a.start,a.end)}else e.nextClause()}},R.QueryParser.parseBoost=function(e){var t=e.consumeLexeme();if(null!=t){var n=parseInt(t.str,10);if(isNaN(n)){var r="boost must be numeric";throw new R.QueryParseError(r,t.start,t.end)}e.currentClause.boost=n;var a=e.peekLexeme();if(null!=a)switch(a.type){case R.QueryLexer.TERM:return e.nextClause(),R.QueryParser.parseTerm;case R.QueryLexer.FIELD:return e.nextClause(),R.QueryParser.parseField;case R.QueryLexer.EDIT_DISTANCE:return R.QueryParser.parseEditDistance;case R.QueryLexer.BOOST:return R.QueryParser.parseBoost;case R.QueryLexer.PRESENCE:return e.nextClause(),R.QueryParser.parsePresence;default:r="Unexpected lexeme type '"+a.type+"'";throw new R.QueryParseError(r,a.start,a.end)}else e.nextClause()}},void 0===(a="function"==typeof(r=function(){return R})?r.call(t,n,t,e):r)||(e.exports=a)}()},2497:(e,t,n)=>{"use strict";n.r(t)},2295:(e,t,n)=>{"use strict";n.r(t)},4865:function(e,t,n){var r,a;r=function(){var e,t,n={version:"0.2.0"},r=n.settings={minimum:.08,easing:"ease",positionUsing:"",speed:200,trickle:!0,trickleRate:.02,trickleSpeed:800,showSpinner:!0,barSelector:'[role="bar"]',spinnerSelector:'[role="spinner"]',parent:"body",template:'
'};function a(e,t,n){return en?n:e}function o(e){return 100*(-1+e)}function i(e,t,n){var a;return(a="translate3d"===r.positionUsing?{transform:"translate3d("+o(e)+"%,0,0)"}:"translate"===r.positionUsing?{transform:"translate("+o(e)+"%,0)"}:{"margin-left":o(e)+"%"}).transition="all "+t+"ms "+n,a}n.configure=function(e){var t,n;for(t in e)void 0!==(n=e[t])&&e.hasOwnProperty(t)&&(r[t]=n);return this},n.status=null,n.set=function(e){var t=n.isStarted();e=a(e,r.minimum,1),n.status=1===e?null:e;var o=n.render(!t),u=o.querySelector(r.barSelector),c=r.speed,d=r.easing;return o.offsetWidth,s((function(t){""===r.positionUsing&&(r.positionUsing=n.getPositioningCSS()),l(u,i(e,c,d)),1===e?(l(o,{transition:"none",opacity:1}),o.offsetWidth,setTimeout((function(){l(o,{transition:"all "+c+"ms linear",opacity:0}),setTimeout((function(){n.remove(),t()}),c)}),c)):setTimeout(t,c)})),this},n.isStarted=function(){return"number"==typeof n.status},n.start=function(){n.status||n.set(0);var e=function(){setTimeout((function(){n.status&&(n.trickle(),e())}),r.trickleSpeed)};return r.trickle&&e(),this},n.done=function(e){return e||n.status?n.inc(.3+.5*Math.random()).set(1):this},n.inc=function(e){var t=n.status;return t?("number"!=typeof e&&(e=(1-t)*a(Math.random()*t,.1,.95)),t=a(t+e,0,.994),n.set(t)):n.start()},n.trickle=function(){return n.inc(Math.random()*r.trickleRate)},e=0,t=0,n.promise=function(r){return r&&"resolved"!==r.state()?(0===t&&n.start(),e++,t++,r.always((function(){0==--t?(e=0,n.done()):n.set((e-t)/e)})),this):this},n.render=function(e){if(n.isRendered())return document.getElementById("nprogress");c(document.documentElement,"nprogress-busy");var t=document.createElement("div");t.id="nprogress",t.innerHTML=r.template;var a,i=t.querySelector(r.barSelector),s=e?"-100":o(n.status||0),u=document.querySelector(r.parent);return l(i,{transition:"all 0 linear",transform:"translate3d("+s+"%,0,0)"}),r.showSpinner||(a=t.querySelector(r.spinnerSelector))&&p(a),u!=document.body&&c(u,"nprogress-custom-parent"),u.appendChild(t),t},n.remove=function(){d(document.documentElement,"nprogress-busy"),d(document.querySelector(r.parent),"nprogress-custom-parent");var e=document.getElementById("nprogress");e&&p(e)},n.isRendered=function(){return!!document.getElementById("nprogress")},n.getPositioningCSS=function(){var e=document.body.style,t="WebkitTransform"in e?"Webkit":"MozTransform"in e?"Moz":"msTransform"in e?"ms":"OTransform"in e?"O":"";return t+"Perspective"in e?"translate3d":t+"Transform"in e?"translate":"margin"};var s=function(){var e=[];function t(){var n=e.shift();n&&n(t)}return function(n){e.push(n),1==e.length&&t()}}(),l=function(){var e=["Webkit","O","Moz","ms"],t={};function n(e){return e.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,(function(e,t){return t.toUpperCase()}))}function r(t){var n=document.body.style;if(t in n)return t;for(var r,a=e.length,o=t.charAt(0).toUpperCase()+t.slice(1);a--;)if((r=e[a]+o)in n)return r;return t}function a(e){return e=n(e),t[e]||(t[e]=r(e))}function o(e,t,n){t=a(t),e.style[t]=n}return function(e,t){var n,r,a=arguments;if(2==a.length)for(n in t)void 0!==(r=t[n])&&t.hasOwnProperty(n)&&o(e,n,r);else o(e,a[1],a[2])}}();function u(e,t){return("string"==typeof e?e:f(e)).indexOf(" "+t+" ")>=0}function c(e,t){var n=f(e),r=n+t;u(n,t)||(e.className=r.substring(1))}function d(e,t){var n,r=f(e);u(e,t)&&(n=r.replace(" "+t+" "," "),e.className=n.substring(1,n.length-1))}function f(e){return(" "+(e.className||"")+" ").replace(/\s+/gi," ")}function p(e){e&&e.parentNode&&e.parentNode.removeChild(e)}return n},void 0===(a="function"==typeof r?r.call(t,n,t,e):r)||(e.exports=a)},4779:(e,t,n)=>{var r=n(5826);e.exports=p,e.exports.parse=o,e.exports.compile=function(e,t){return s(o(e,t),t)},e.exports.tokensToFunction=s,e.exports.tokensToRegExp=f;var a=new RegExp(["(\\\\.)","([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?|(\\*))"].join("|"),"g");function o(e,t){for(var n,r=[],o=0,i=0,s="",c=t&&t.delimiter||"/";null!=(n=a.exec(e));){var d=n[0],f=n[1],p=n.index;if(s+=e.slice(i,p),i=p+d.length,f)s+=f[1];else{var h=e[i],m=n[2],g=n[3],y=n[4],b=n[5],v=n[6],k=n[7];s&&(r.push(s),s="");var w=null!=m&&null!=h&&h!==m,x="+"===v||"*"===v,S="?"===v||"*"===v,E=n[2]||c,_=y||b;r.push({name:g||o++,prefix:m||"",delimiter:E,optional:S,repeat:x,partial:w,asterisk:!!k,pattern:_?u(_):k?".*":"[^"+l(E)+"]+?"})}}return i{!function(e){var t="\\b(?:BASH|BASHOPTS|BASH_ALIASES|BASH_ARGC|BASH_ARGV|BASH_CMDS|BASH_COMPLETION_COMPAT_DIR|BASH_LINENO|BASH_REMATCH|BASH_SOURCE|BASH_VERSINFO|BASH_VERSION|COLORTERM|COLUMNS|COMP_WORDBREAKS|DBUS_SESSION_BUS_ADDRESS|DEFAULTS_PATH|DESKTOP_SESSION|DIRSTACK|DISPLAY|EUID|GDMSESSION|GDM_LANG|GNOME_KEYRING_CONTROL|GNOME_KEYRING_PID|GPG_AGENT_INFO|GROUPS|HISTCONTROL|HISTFILE|HISTFILESIZE|HISTSIZE|HOME|HOSTNAME|HOSTTYPE|IFS|INSTANCE|JOB|LANG|LANGUAGE|LC_ADDRESS|LC_ALL|LC_IDENTIFICATION|LC_MEASUREMENT|LC_MONETARY|LC_NAME|LC_NUMERIC|LC_PAPER|LC_TELEPHONE|LC_TIME|LESSCLOSE|LESSOPEN|LINES|LOGNAME|LS_COLORS|MACHTYPE|MAILCHECK|MANDATORY_PATH|NO_AT_BRIDGE|OLDPWD|OPTERR|OPTIND|ORBIT_SOCKETDIR|OSTYPE|PAPERSIZE|PATH|PIPESTATUS|PPID|PS1|PS2|PS3|PS4|PWD|RANDOM|REPLY|SECONDS|SELINUX_INIT|SESSION|SESSIONTYPE|SESSION_MANAGER|SHELL|SHELLOPTS|SHLVL|SSH_AUTH_SOCK|TERM|UID|UPSTART_EVENTS|UPSTART_INSTANCE|UPSTART_JOB|UPSTART_SESSION|USER|WINDOWID|XAUTHORITY|XDG_CONFIG_DIRS|XDG_CURRENT_DESKTOP|XDG_DATA_DIRS|XDG_GREETER_DATA_DIR|XDG_MENU_PREFIX|XDG_RUNTIME_DIR|XDG_SEAT|XDG_SEAT_PATH|XDG_SESSION_DESKTOP|XDG_SESSION_ID|XDG_SESSION_PATH|XDG_SESSION_TYPE|XDG_VTNR|XMODIFIERS)\\b",n={pattern:/(^(["']?)\w+\2)[ \t]+\S.*/,lookbehind:!0,alias:"punctuation",inside:null},r={bash:n,environment:{pattern:RegExp("\\$"+t),alias:"constant"},variable:[{pattern:/\$?\(\([\s\S]+?\)\)/,greedy:!0,inside:{variable:[{pattern:/(^\$\(\([\s\S]+)\)\)/,lookbehind:!0},/^\$\(\(/],number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee]-?\d+)?/,operator:/--|\+\+|\*\*=?|<<=?|>>=?|&&|\|\||[=!+\-*/%<>^&|]=?|[?~:]/,punctuation:/\(\(?|\)\)?|,|;/}},{pattern:/\$\((?:\([^)]+\)|[^()])+\)|`[^`]+`/,greedy:!0,inside:{variable:/^\$\(|^`|\)$|`$/}},{pattern:/\$\{[^}]+\}/,greedy:!0,inside:{operator:/:[-=?+]?|[!\/]|##?|%%?|\^\^?|,,?/,punctuation:/[\[\]]/,environment:{pattern:RegExp("(\\{)"+t),lookbehind:!0,alias:"constant"}}},/\$(?:\w+|[#?*!@$])/],entity:/\\(?:[abceEfnrtv\\"]|O?[0-7]{1,3}|U[0-9a-fA-F]{8}|u[0-9a-fA-F]{4}|x[0-9a-fA-F]{1,2})/};e.languages.bash={shebang:{pattern:/^#!\s*\/.*/,alias:"important"},comment:{pattern:/(^|[^"{\\$])#.*/,lookbehind:!0},"function-name":[{pattern:/(\bfunction\s+)[\w-]+(?=(?:\s*\(?:\s*\))?\s*\{)/,lookbehind:!0,alias:"function"},{pattern:/\b[\w-]+(?=\s*\(\s*\)\s*\{)/,alias:"function"}],"for-or-select":{pattern:/(\b(?:for|select)\s+)\w+(?=\s+in\s)/,alias:"variable",lookbehind:!0},"assign-left":{pattern:/(^|[\s;|&]|[<>]\()\w+(?:\.\w+)*(?=\+?=)/,inside:{environment:{pattern:RegExp("(^|[\\s;|&]|[<>]\\()"+t),lookbehind:!0,alias:"constant"}},alias:"variable",lookbehind:!0},parameter:{pattern:/(^|\s)-{1,2}(?:\w+:[+-]?)?\w+(?:\.\w+)*(?=[=\s]|$)/,alias:"variable",lookbehind:!0},string:[{pattern:/((?:^|[^<])<<-?\s*)(\w+)\s[\s\S]*?(?:\r?\n|\r)\2/,lookbehind:!0,greedy:!0,inside:r},{pattern:/((?:^|[^<])<<-?\s*)(["'])(\w+)\2\s[\s\S]*?(?:\r?\n|\r)\3/,lookbehind:!0,greedy:!0,inside:{bash:n}},{pattern:/(^|[^\\](?:\\\\)*)"(?:\\[\s\S]|\$\([^)]+\)|\$(?!\()|`[^`]+`|[^"\\`$])*"/,lookbehind:!0,greedy:!0,inside:r},{pattern:/(^|[^$\\])'[^']*'/,lookbehind:!0,greedy:!0},{pattern:/\$'(?:[^'\\]|\\[\s\S])*'/,greedy:!0,inside:{entity:r.entity}}],environment:{pattern:RegExp("\\$?"+t),alias:"constant"},variable:r.variable,function:{pattern:/(^|[\s;|&]|[<>]\()(?:add|apropos|apt|apt-cache|apt-get|aptitude|aspell|automysqlbackup|awk|basename|bash|bc|bconsole|bg|bzip2|cal|cargo|cat|cfdisk|chgrp|chkconfig|chmod|chown|chroot|cksum|clear|cmp|column|comm|composer|cp|cron|crontab|csplit|curl|cut|date|dc|dd|ddrescue|debootstrap|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|docker|docker-compose|du|egrep|eject|env|ethtool|expand|expect|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|git|gparted|grep|groupadd|groupdel|groupmod|groups|grub-mkconfig|gzip|halt|head|hg|history|host|hostname|htop|iconv|id|ifconfig|ifdown|ifup|import|install|ip|java|jobs|join|kill|killall|less|link|ln|locate|logname|logrotate|look|lpc|lpr|lprint|lprintd|lprintq|lprm|ls|lsof|lynx|make|man|mc|mdadm|mkconfig|mkdir|mke2fs|mkfifo|mkfs|mkisofs|mknod|mkswap|mmv|more|most|mount|mtools|mtr|mutt|mv|nano|nc|netstat|nice|nl|node|nohup|notify-send|npm|nslookup|op|open|parted|passwd|paste|pathchk|ping|pkill|pnpm|podman|podman-compose|popd|pr|printcap|printenv|ps|pushd|pv|quota|quotacheck|quotactl|ram|rar|rcp|reboot|remsync|rename|renice|rev|rm|rmdir|rpm|rsync|scp|screen|sdiff|sed|sendmail|seq|service|sftp|sh|shellcheck|shuf|shutdown|sleep|slocate|sort|split|ssh|stat|strace|su|sudo|sum|suspend|swapon|sync|sysctl|tac|tail|tar|tee|time|timeout|top|touch|tr|traceroute|tsort|tty|umount|uname|unexpand|uniq|units|unrar|unshar|unzip|update-grub|uptime|useradd|userdel|usermod|users|uudecode|uuencode|v|vcpkg|vdir|vi|vim|virsh|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yarn|yes|zenity|zip|zsh|zypper)(?=$|[)\s;|&])/,lookbehind:!0},keyword:{pattern:/(^|[\s;|&]|[<>]\()(?:case|do|done|elif|else|esac|fi|for|function|if|in|select|then|until|while)(?=$|[)\s;|&])/,lookbehind:!0},builtin:{pattern:/(^|[\s;|&]|[<>]\()(?:\.|:|alias|bind|break|builtin|caller|cd|command|continue|declare|echo|enable|eval|exec|exit|export|getopts|hash|help|let|local|logout|mapfile|printf|pwd|read|readarray|readonly|return|set|shift|shopt|source|test|times|trap|type|typeset|ulimit|umask|unalias|unset)(?=$|[)\s;|&])/,lookbehind:!0,alias:"class-name"},boolean:{pattern:/(^|[\s;|&]|[<>]\()(?:false|true)(?=$|[)\s;|&])/,lookbehind:!0},"file-descriptor":{pattern:/\B&\d\b/,alias:"important"},operator:{pattern:/\d?<>|>\||\+=|=[=~]?|!=?|<<[<-]?|[&\d]?>>|\d[<>]&?|[<>][&=]?|&[>&]?|\|[&|]?/,inside:{"file-descriptor":{pattern:/^\d/,alias:"important"}}},punctuation:/\$?\(\(?|\)\)?|\.\.|[{}[\];\\]/,number:{pattern:/(^|\s)(?:[1-9]\d*|0)(?:[.,]\d+)?\b/,lookbehind:!0}},n.inside=e.languages.bash;for(var a=["comment","function-name","for-or-select","assign-left","parameter","string","environment","function","keyword","builtin","boolean","file-descriptor","operator","punctuation","number"],o=r.variable[1].inside,i=0;i{Prism.languages.json={property:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?=\s*:)/,lookbehind:!0,greedy:!0},string:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?!\s*:)/,lookbehind:!0,greedy:!0},comment:{pattern:/\/\/.*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},number:/-?\b\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,punctuation:/[{}[\],]/,operator:/:/,boolean:/\b(?:false|true)\b/,null:{pattern:/\bnull\b/,alias:"keyword"}},Prism.languages.webmanifest=Prism.languages.json},6854:()=>{!function(e){function t(e,t){return"___"+e.toUpperCase()+t+"___"}Object.defineProperties(e.languages["markup-templating"]={},{buildPlaceholders:{value:function(n,r,a,o){if(n.language===r){var i=n.tokenStack=[];n.code=n.code.replace(a,(function(e){if("function"==typeof o&&!o(e))return e;for(var a,s=i.length;-1!==n.code.indexOf(a=t(r,s));)++s;return i[s]=e,a})),n.grammar=e.languages.markup}}},tokenizePlaceholders:{value:function(n,r){if(n.language===r&&n.tokenStack){n.grammar=e.languages[r];var a=0,o=Object.keys(n.tokenStack);!function i(s){for(var l=0;l=o.length);l++){var u=s[l];if("string"==typeof u||u.content&&"string"==typeof u.content){var c=o[a],d=n.tokenStack[c],f="string"==typeof u?u:u.content,p=t(r,c),h=f.indexOf(p);if(h>-1){++a;var m=f.substring(0,h),g=new e.Token(r,e.tokenize(d,n.grammar),"language-"+r,d),y=f.substring(h+p.length),b=[];m&&b.push.apply(b,i([m])),b.push(g),y&&b.push.apply(b,i([y])),"string"==typeof u?s.splice.apply(s,[l,1].concat(b)):u.content=b}}else u.content&&i(u.content)}return s}(n.tokens)}}}})}(Prism)},3358:()=>{!function(e){var t=/[*&][^\s[\]{},]+/,n=/!(?:<[\w\-%#;/?:@&=+$,.!~*'()[\]]+>|(?:[a-zA-Z\d-]*!)?[\w\-%#;/?:@&=+$.~*'()]+)?/,r="(?:"+n.source+"(?:[ \t]+"+t.source+")?|"+t.source+"(?:[ \t]+"+n.source+")?)",a=/(?:[^\s\x00-\x08\x0e-\x1f!"#%&'*,\-:>?@[\]`{|}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]|[?:-])(?:[ \t]*(?:(?![#:])|:))*/.source.replace(//g,(function(){return/[^\s\x00-\x08\x0e-\x1f,[\]{}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]/.source})),o=/"(?:[^"\\\r\n]|\\.)*"|'(?:[^'\\\r\n]|\\.)*'/.source;function i(e,t){t=(t||"").replace(/m/g,"")+"m";var n=/([:\-,[{]\s*(?:\s<>[ \t]+)?)(?:<>)(?=[ \t]*(?:$|,|\]|\}|(?:[\r\n]\s*)?#))/.source.replace(/<>/g,(function(){return r})).replace(/<>/g,(function(){return e}));return RegExp(n,t)}e.languages.yaml={scalar:{pattern:RegExp(/([\-:]\s*(?:\s<>[ \t]+)?[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)\S[^\r\n]*(?:\2[^\r\n]+)*)/.source.replace(/<>/g,(function(){return r}))),lookbehind:!0,alias:"string"},comment:/#.*/,key:{pattern:RegExp(/((?:^|[:\-,[{\r\n?])[ \t]*(?:<>[ \t]+)?)<>(?=\s*:\s)/.source.replace(/<>/g,(function(){return r})).replace(/<>/g,(function(){return"(?:"+a+"|"+o+")"}))),lookbehind:!0,greedy:!0,alias:"atrule"},directive:{pattern:/(^[ \t]*)%.+/m,lookbehind:!0,alias:"important"},datetime:{pattern:i(/\d{4}-\d\d?-\d\d?(?:[tT]|[ \t]+)\d\d?:\d{2}:\d{2}(?:\.\d*)?(?:[ \t]*(?:Z|[-+]\d\d?(?::\d{2})?))?|\d{4}-\d{2}-\d{2}|\d\d?:\d{2}(?::\d{2}(?:\.\d*)?)?/.source),lookbehind:!0,alias:"number"},boolean:{pattern:i(/false|true/.source,"i"),lookbehind:!0,alias:"important"},null:{pattern:i(/null|~/.source,"i"),lookbehind:!0,alias:"important"},string:{pattern:i(o),lookbehind:!0,greedy:!0},number:{pattern:i(/[+-]?(?:0x[\da-f]+|0o[0-7]+|(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?|\.inf|\.nan)/.source,"i"),lookbehind:!0},tag:n,important:t,punctuation:/---|[:[\]{}\-,|>?]|\.\.\./},e.languages.yml=e.languages.yaml}(Prism)},9929:(e,t,n)=>{var r={"./prism-bash":7874,"./prism-json":4277,"./prism-yaml":3358};function a(e){var t=o(e);return n(t)}function o(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}a.keys=function(){return Object.keys(r)},a.resolve=o,e.exports=a,a.id=9929},2703:(e,t,n)=>{"use strict";var r=n(414);function a(){}function o(){}o.resetWarningCache=a,e.exports=function(){function e(e,t,n,a,o,i){if(i!==r){var s=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw s.name="Invariant Violation",s}}function t(){return e}e.isRequired=e;var n={array:e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:o,resetWarningCache:a};return n.PropTypes=n,n}},5697:(e,t,n)=>{e.exports=n(2703)()},414:e=>{"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},4448:(e,t,n)=>{"use strict";var r=n(7294),a=n(3840);function o(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n