{ "cells": [ { "cell_type": "code", "execution_count": 125, "metadata": {}, "outputs": [], "source": [ "import tiktoken\n", "def num_tokens_from_messages(messages, model=\"gpt-4\"):\n", " \"\"\"Returns the number of tokens used by a list of messages.\"\"\"\n", " try:\n", " encoding = tiktoken.encoding_for_model(model)\n", " except KeyError:\n", " encoding = tiktoken.get_encoding(\"cl100k_base\")\n", " if model == \"gpt-3.5-turbo-0301\" or model == \"gpt-4\": # note: future models may deviate from this\n", " num_tokens = 0\n", " for message in messages:\n", " num_tokens += 4 # every message follows {role/name}\\n{content}\\n\n", " for key, value in message.items():\n", " num_tokens += len(encoding.encode(value))\n", " if key == \"name\": # if there's a name, the role is omitted\n", " num_tokens += -1 # role is always required and always 1 token\n", " num_tokens += 2 # every reply is primed with assistant\n", " return num_tokens\n", " else:\n", " raise NotImplementedError(f\"\"\"num_tokens_from_messages() is not presently implemented for model {model}.\n", " See https://github.com/openai/openai-python/blob/main/chatml.md for information on how messages are converted to tokens.\"\"\")" ] }, { "cell_type": "code", "execution_count": 188, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "899" ] }, "execution_count": 188, "metadata": {}, "output_type": "execute_result" } ], "source": [ "num_tokens_from_messages(context, model=\"gpt-4\")" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "## Settings" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "from notebook.services.config import ConfigManager\n", "cm = ConfigManager().update('notebook', {'limit_output': 100000})" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "import warnings\n", "warnings.filterwarnings('ignore')" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "scrolled": true }, "outputs": [], "source": [ "import openai" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "scrolled": true }, "outputs": [], "source": [ "OPENAI_API_KEY = \"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\"\n", "openai.organization = \"org-a8FR39HtlLqV8bNb0TxpF008\"\n", "openai.api_key = OPENAI_API_KEY" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "import time\n", "import copy" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "## Streaming" ] }, { "cell_type": "code", "execution_count": 130, "metadata": {}, "outputs": [], "source": [ "context = [ {'role':'system', 'content':\"\"\"\n", "너는 맥도날드에서 주문을 받는 봇이다.\\\n", "먼저 고객을 맞이한 다음 주문을 받는다. \\\n", "전체 주문을 받은 다음 주문을 요약하고, 고객이 추가할 사항이 있는지 최종적으로 확인한다. \\\n", "마지막으로 결제를 진행한다. 결제는 카드, 현금, 휴대폰으로 진행할 수 있다.\\\n", "모든 대답은 짧고, 친근한 대화 스타일로 한다.\\\n", "제공할 수 없는 정보는 제공할 수 없다는 말과 함께 사과한다.\\\n", "메뉴는 아래와 같다. 모든 햄버거 메뉴는 일반 세트와 라지 세트가 존재한다. \\\n", "일반 세트에는 후렌치 후라이 미디움와 음료 미디움이 포함되어 있고, 라지 세트에는 후렌치 후라이 라지와 음료 라지가 포함되어 있다. \\\n", "일반 세트의 가격은 햄버거 단품의 가격에 1900원을 더한 가격이고, 라지 세트의 가격은 햄버거 단품의 가격에 2600원을 더한 가격이다. \\\n", "햄버거 메뉴: \\\n", "더블 빅맥 9000 \\\n", "빅맥 BLT 7800 \\\n", "맥크리스피 디럭스 버거 7600 \\\n", "맥클리스피 클래식 버거 6700 \\\n", "트리플 치즈버거 6600 \\\n", "슈비버거 6600 \\\n", "슈슈버거 5500 \\\n", "1955 버거 7200 \\\n", "맥치킨 4300 \\\n", "맥치킨 모짜렐라 5800 \\\n", "빅맥 6000 \\\n", "맥스파이시 상하이 버거 6000 \\\n", "더블 불고기 버거 5300 \\\n", "에그 불고기 버거 4300 \\\n", "불고기 버거 3600 \\\n", "베이컨 토마토 디럭스 6600 \\\n", "더블 쿼터파운더 치즈 8200 \\\n", "쿼터파운더 치즈 6300 \\\n", "치즈버거 3500 \\\n", "햄버거 3300 \\\n", "스낵 & 사이드: \\\n", "맥윙 2조각 4000 \\\n", "맥윙 4조각 6700 \\\n", "맥윙 8조각 12300 \\\n", "콤보 맥윙 2조각 4800 \\\n", "콤보 맥윙 4조각 7500 \\\n", "슈림프 스낵랩 3100 \\\n", "코울슬로 2700 \\\n", "골든 모짜렐라 치즈스틱 2조각 3300 \\\n", "골든 모짜렐라 치즈스틱 4조각 5000 \\\n", "맥너겟 4조각 3300 \\\n", "상하이 치킨 스낵랩 3500 \\\n", "후렌치 후라이 2100, 2800, 3500 \\\n", "디저트:\n", "오레오 맥플러리 3700 \\\n", "딸기 선데이 아이스크림 2800 \\\n", "초코 선데이 아이스크림 2800 \\\n", "바닐라 선데이 아이스크림 2800 \\\n", "해피밀:\n", "해피밀 맥너겟 4조각 5500 \\\n", "해피밀 햄버거 5500 \\\n", "해피밀 불고기버거 5500 \\\n", "음료: (가격은 스몰,미디움,라지 또는 미디움,라지)\\\n", "자두 천도복숭아 칠러 2900, 3700, 4700 \\\n", "제주 한라봉 칠러 2900, 3700, 4700 \\\n", "바닐라 라떼 4500, 5000\n", "아이스 바닐라 라떼 4500, 5000 \\\n", "코카콜라 2400, 2900 \\\n", "제로 콜라 2400, 2900 \\\n", "환타 오렌지 2400, 2900 \\\n", "스프라이트 2400, 2900 \\\n", "카페라떼 4000, 4500 \\\n", "카푸치노 4000, 4500 \\\n", "아메리카노 3300, 3800 \\\n", "드립커피 2700, 3200 \\\n", "아이스 드립커피 2500, 3000 \\\n", "아이스 아메리카노 3300, 3800 \\\n", "아이스 카페라떼 4000, 4500 \\\n", "딸기 쉐이크 미디움 3500 \\\n", "초코 쉐이크 미디움 3500 \\\n", "바닐라 쉐이크 미디움 3500 \\\n", "다른 정보:\n", "화장실: 화장실 위치는 정문에서 나가서 오른쪽 코너를 돌면 바로 있다. 화장실 비밀번호는 1223*이다.\n", "와이파이: 와이파이 id는 맥도날드, 비밀번호는 123456789*이다.\n", "\"\"\"} ] # accumulate messages" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [], "source": [ "context = [{'role':'system', 'content':\"\"\"\n", "너는 와인 매장에서 주문을 받는 봇이다.\\\n", "고객이 와인을 추천해달라고 할 때는 질문을 통해서 고객이 원하는 와인을 유추하고, 그에 맞는 와인을 추천한다.\\\n", "질문은 어떤 특별한 이벤트가 있는 것인지, 와인의 종류, 선호하는 맛에 대한 질문이 있다.\n", "질문을 할 때는 단 한개의 질문만한다.\\\n", "먼저 고객을 맞이한 다음 주문을 받는다. \\\n", "전체 주문을 받은 다음 주문을 요약하고, 고객이 추가할 사항이 있는지 최종적으로 확인한다. \\\n", "마지막으로 결제를 진행한다. 결제는 카드, 현금, 휴대폰으로 진행할 수 있다.\\\n", "모든 대답은 짧고, 친근한 대화 스타일로 한다.\\\n", "제공할 수 없는 정보는 제공할 수 없다는 말과 함께 사과한다.\\\n", "\"\"\"}]" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "scrolled": false }, "outputs": [ { "data": { "application/javascript": "(function(root) {\n function now() {\n return new Date();\n }\n\n var force = true;\n var py_version = '3.1.1'.replace('rc', '-rc.');\n var is_dev = py_version.indexOf(\"+\") !== -1 || py_version.indexOf(\"-\") !== -1;\n var reloading = false;\n var Bokeh = root.Bokeh;\n var bokeh_loaded = Bokeh != null && (Bokeh.version === py_version || (Bokeh.versions !== undefined && Bokeh.versions.has(py_version)));\n\n if (typeof (root._bokeh_timeout) === \"undefined\" || force) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks;\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, js_modules, js_exports, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n if (js_modules == null) js_modules = [];\n if (js_exports == null) js_exports = {};\n\n root._bokeh_onload_callbacks.push(callback);\n\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls.length === 0 && js_modules.length === 0 && Object.keys(js_exports).length === 0) {\n run_callbacks();\n return null;\n }\n if (!reloading) {\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n }\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n window._bokeh_on_load = on_load\n\n function on_error() {\n console.error(\"failed to load \" + url);\n }\n\n var skip = [];\n if (window.requirejs) {\n window.requirejs.config({'packages': {}, 'paths': {'jspanel': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/jspanel', 'jspanel-modal': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/modal/jspanel.modal', 'jspanel-tooltip': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/tooltip/jspanel.tooltip', 'jspanel-hint': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/hint/jspanel.hint', 'jspanel-layout': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/layout/jspanel.layout', 'jspanel-contextmenu': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/contextmenu/jspanel.contextmenu', 'jspanel-dock': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/dock/jspanel.dock', 'gridstack': 'https://cdn.jsdelivr.net/npm/gridstack@7.2.3/dist/gridstack-all', 'notyf': 'https://cdn.jsdelivr.net/npm/notyf@3/notyf.min'}, 'shim': {'jspanel': {'exports': 'jsPanel'}, 'gridstack': {'exports': 'GridStack'}}});\n require([\"jspanel\"], function(jsPanel) {\n\twindow.jsPanel = jsPanel\n\ton_load()\n })\n require([\"jspanel-modal\"], function() {\n\ton_load()\n })\n require([\"jspanel-tooltip\"], function() {\n\ton_load()\n })\n require([\"jspanel-hint\"], function() {\n\ton_load()\n })\n require([\"jspanel-layout\"], function() {\n\ton_load()\n })\n require([\"jspanel-contextmenu\"], function() {\n\ton_load()\n })\n require([\"jspanel-dock\"], function() {\n\ton_load()\n })\n require([\"gridstack\"], function(GridStack) {\n\twindow.GridStack = GridStack\n\ton_load()\n })\n require([\"notyf\"], function() {\n\ton_load()\n })\n root._bokeh_is_loading = css_urls.length + 9;\n } else {\n root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length + Object.keys(js_exports).length;\n }\n\n var existing_stylesheets = []\n var links = document.getElementsByTagName('link')\n for (var i = 0; i < links.length; i++) {\n var link = links[i]\n if (link.href != null) {\n\texisting_stylesheets.push(link.href)\n }\n }\n for (var i = 0; i < css_urls.length; i++) {\n var url = css_urls[i];\n if (existing_stylesheets.indexOf(url) !== -1) {\n\ton_load()\n\tcontinue;\n }\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n } if (((window['jsPanel'] !== undefined) && (!(window['jsPanel'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/1.0.3/dist/bundled/floatpanel/jspanel4@4.12.0/dist/jspanel.js', 'https://cdn.holoviz.org/panel/1.0.3/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/modal/jspanel.modal.js', 'https://cdn.holoviz.org/panel/1.0.3/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/tooltip/jspanel.tooltip.js', 'https://cdn.holoviz.org/panel/1.0.3/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/hint/jspanel.hint.js', 'https://cdn.holoviz.org/panel/1.0.3/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/layout/jspanel.layout.js', 'https://cdn.holoviz.org/panel/1.0.3/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/contextmenu/jspanel.contextmenu.js', 'https://cdn.holoviz.org/panel/1.0.3/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/dock/jspanel.dock.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['GridStack'] !== undefined) && (!(window['GridStack'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/1.0.3/dist/bundled/gridstack/gridstack@7.2.3/dist/gridstack-all.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['Notyf'] !== undefined) && (!(window['Notyf'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/1.0.3/dist/bundled/notificationarea/notyf@3/notyf.min.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } var existing_scripts = []\n var scripts = document.getElementsByTagName('script')\n for (var i = 0; i < scripts.length; i++) {\n var script = scripts[i]\n if (script.src != null) {\n\texisting_scripts.push(script.src)\n }\n }\n for (var i = 0; i < js_urls.length; i++) {\n var url = js_urls[i];\n if (skip.indexOf(url) !== -1 || existing_scripts.indexOf(url) !== -1) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (var i = 0; i < js_modules.length; i++) {\n var url = js_modules[i];\n if (skip.indexOf(url) !== -1 || existing_scripts.indexOf(url) !== -1) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (const name in js_exports) {\n var url = js_exports[name];\n if (skip.indexOf(url) >= 0 || root[name] != null) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onerror = on_error;\n element.async = false;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n element.textContent = `\n import ${name} from \"${url}\"\n window.${name} = ${name}\n window._bokeh_on_load()\n `\n document.head.appendChild(element);\n }\n if (!js_urls.length && !js_modules.length) {\n on_load()\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n var js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-3.1.1.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.1.1.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.1.1.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.1.1.min.js\", \"https://cdn.holoviz.org/panel/1.0.3/dist/panel.min.js\"];\n var js_modules = [];\n var js_exports = {};\n var css_urls = [];\n var inline_js = [ function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\nfunction(Bokeh) {} // ensure no trailing comma for IE\n ];\n\n function run_inline_js() {\n if ((root.Bokeh !== undefined) || (force === true)) {\n for (var i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }\n // Cache old bokeh versions\n if (Bokeh != undefined && !reloading) {\n\tvar NewBokeh = root.Bokeh;\n\tif (Bokeh.versions === undefined) {\n\t Bokeh.versions = new Map();\n\t}\n\tif (NewBokeh.version !== Bokeh.version) {\n\t Bokeh.versions.set(NewBokeh.version, NewBokeh)\n\t}\n\troot.Bokeh = Bokeh;\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n }\n root._bokeh_is_initializing = false\n }\n\n function load_or_wait() {\n // Implement a backoff loop that tries to ensure we do not load multiple\n // versions of Bokeh and its dependencies at the same time.\n // In recent versions we use the root._bokeh_is_initializing flag\n // to determine whether there is an ongoing attempt to initialize\n // bokeh, however for backward compatibility we also try to ensure\n // that we do not start loading a newer (Panel>=1.0 and Bokeh>3) version\n // before older versions are fully initialized.\n if (root._bokeh_is_initializing && Date.now() > root._bokeh_timeout) {\n root._bokeh_is_initializing = false;\n root._bokeh_onload_callbacks = undefined;\n console.log(\"Bokeh: BokehJS was loaded multiple times but one version failed to initialize.\");\n load_or_wait();\n } else if (root._bokeh_is_initializing || (typeof root._bokeh_is_initializing === \"undefined\" && root._bokeh_onload_callbacks !== undefined)) {\n setTimeout(load_or_wait, 100);\n } else {\n Bokeh = root.Bokeh;\n bokeh_loaded = Bokeh != null && (Bokeh.version === py_version || (Bokeh.versions !== undefined && Bokeh.versions.has(py_version)));\n root._bokeh_is_initializing = true\n root._bokeh_onload_callbacks = []\n if (!reloading && (!bokeh_loaded || is_dev)) {\n\troot.Bokeh = undefined;\n }\n load_libs(css_urls, js_urls, js_modules, js_exports, function() {\n\tconsole.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n\trun_inline_js();\n });\n }\n }\n // Give older versions of the autoload script a head-start to ensure\n // they initialize before we start loading newer version.\n setTimeout(load_or_wait, 100)\n}(window));", "application/vnd.holoviews_load.v0+json": "" }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/javascript": "\nif ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n}\n\n\n function JupyterCommManager() {\n }\n\n JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n comm_manager.register_target(comm_id, function(comm) {\n comm.on_msg(msg_handler);\n });\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n comm.onMsg = msg_handler;\n });\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n console.log(message)\n var content = {data: message.data, comm_id};\n var buffers = []\n for (var buffer of message.buffers || []) {\n buffers.push(new DataView(buffer))\n }\n var metadata = message.metadata || {};\n var msg = {content, buffers, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n })\n }\n }\n\n JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n if (comm_id in window.PyViz.comms) {\n return window.PyViz.comms[comm_id];\n } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n if (msg_handler) {\n comm.on_msg(msg_handler);\n }\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n comm.open();\n if (msg_handler) {\n comm.onMsg = msg_handler;\n }\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n var comm_promise = google.colab.kernel.comms.open(comm_id)\n comm_promise.then((comm) => {\n window.PyViz.comms[comm_id] = comm;\n if (msg_handler) {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n var content = {data: message.data};\n var metadata = message.metadata || {comm_id};\n var msg = {content, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n }\n }) \n var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n return comm_promise.then((comm) => {\n comm.send(data, metadata, buffers, disposeOnDone);\n });\n };\n var comm = {\n send: sendClosure\n };\n }\n window.PyViz.comms[comm_id] = comm;\n return comm;\n }\n window.PyViz.comm_manager = new JupyterCommManager();\n \n\n\nvar JS_MIME_TYPE = 'application/javascript';\nvar HTML_MIME_TYPE = 'text/html';\nvar EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\nvar CLASS_NAME = 'output';\n\n/**\n * Render data to the DOM node\n */\nfunction render(props, node) {\n var div = document.createElement(\"div\");\n var script = document.createElement(\"script\");\n node.appendChild(div);\n node.appendChild(script);\n}\n\n/**\n * Handle when a new output is added\n */\nfunction handle_add_output(event, handle) {\n var output_area = handle.output_area;\n var output = handle.output;\n if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n return\n }\n var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n if (id !== undefined) {\n var nchildren = toinsert.length;\n var html_node = toinsert[nchildren-1].children[0];\n html_node.innerHTML = output.data[HTML_MIME_TYPE];\n var scripts = [];\n var nodelist = html_node.querySelectorAll(\"script\");\n for (var i in nodelist) {\n if (nodelist.hasOwnProperty(i)) {\n scripts.push(nodelist[i])\n }\n }\n\n scripts.forEach( function (oldScript) {\n var newScript = document.createElement(\"script\");\n var attrs = [];\n var nodemap = oldScript.attributes;\n for (var j in nodemap) {\n if (nodemap.hasOwnProperty(j)) {\n attrs.push(nodemap[j])\n }\n }\n attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n oldScript.parentNode.replaceChild(newScript, oldScript);\n });\n if (JS_MIME_TYPE in output.data) {\n toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n }\n output_area._hv_plot_id = id;\n if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n window.PyViz.plot_index[id] = Bokeh.index[id];\n } else {\n window.PyViz.plot_index[id] = null;\n }\n } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n var bk_div = document.createElement(\"div\");\n bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n var script_attrs = bk_div.children[0].attributes;\n for (var i = 0; i < script_attrs.length; i++) {\n toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n }\n // store reference to server id on output_area\n output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n }\n}\n\n/**\n * Handle when an output is cleared or removed\n */\nfunction handle_clear_output(event, handle) {\n var id = handle.cell.output_area._hv_plot_id;\n var server_id = handle.cell.output_area._bokeh_server_id;\n if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n if (server_id !== null) {\n comm.send({event_type: 'server_delete', 'id': server_id});\n return;\n } else if (comm !== null) {\n comm.send({event_type: 'delete', 'id': id});\n }\n delete PyViz.plot_index[id];\n if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n var doc = window.Bokeh.index[id].model.document\n doc.clear();\n const i = window.Bokeh.documents.indexOf(doc);\n if (i > -1) {\n window.Bokeh.documents.splice(i, 1);\n }\n }\n}\n\n/**\n * Handle kernel restart event\n */\nfunction handle_kernel_cleanup(event, handle) {\n delete PyViz.comms[\"hv-extension-comm\"];\n window.PyViz.plot_index = {}\n}\n\n/**\n * Handle update_display_data messages\n */\nfunction handle_update_output(event, handle) {\n handle_clear_output(event, {cell: {output_area: handle.output_area}})\n handle_add_output(event, handle)\n}\n\nfunction register_renderer(events, OutputArea) {\n function append_mime(data, metadata, element) {\n // create a DOM node to render to\n var toinsert = this.create_output_subarea(\n metadata,\n CLASS_NAME,\n EXEC_MIME_TYPE\n );\n this.keyboard_manager.register_events(toinsert);\n // Render to node\n var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n render(props, toinsert[0]);\n element.append(toinsert);\n return toinsert\n }\n\n events.on('output_added.OutputArea', handle_add_output);\n events.on('output_updated.OutputArea', handle_update_output);\n events.on('clear_output.CodeCell', handle_clear_output);\n events.on('delete.Cell', handle_clear_output);\n events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n\n OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n safe: true,\n index: 0\n });\n}\n\nif (window.Jupyter !== undefined) {\n try {\n var events = require('base/js/events');\n var OutputArea = require('notebook/js/outputarea').OutputArea;\n if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n register_renderer(events, OutputArea);\n }\n } catch(err) {\n }\n}\n", "application/vnd.holoviews_load.v0+json": "" }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/vnd.holoviews_exec.v0+json": "", "text/html": [ "
\n", "
\n", "
\n", "" ] }, "metadata": { "application/vnd.holoviews_exec.v0+json": { "id": "33eafd87-7694-4df2-8d1e-e4662adbf3c7" } }, "output_type": "display_data" }, { "data": {}, "metadata": {}, "output_type": "display_data" }, { "data": { "application/vnd.holoviews_exec.v0+json": "", "text/html": [ "
\n", "
\n", "
\n", "" ], "text/plain": [ "Column\n", " [0] TextInput(placeholder='텍스트를 입력해주세요')\n", " [1] Row\n", " [0] Button(name='Chat!')\n", " [2] ParamFunction(function, _pane=Column, height=3000)" ] }, "execution_count": 14, "metadata": { "application/vnd.holoviews_exec.v0+json": { "id": "99c2dae9-c109-40e7-b282-92349f9986f3" } }, "output_type": "execute_result" } ], "source": [ "import param\n", "import time\n", "import panel as pn\n", "import openai\n", "\n", "pn.extension()\n", "\n", "# Define a class to hold the response part\n", "class Params(param.Parameterized):\n", " response_part = param.String(default=\"\")\n", "\n", "params = Params()\n", "\n", "def get_completion_from_messages(messages, model=\"gpt-4\", temperature=0):\n", " response = openai.ChatCompletion.create(\n", " model=model,\n", " messages=messages,\n", " temperature=temperature, \n", " stream=True\n", " )\n", " completion_text = ''\n", " start_time = time.time()\n", " for event in response:\n", " event_time = time.time() - start_time \n", " try:\n", " event_text = event['choices'][0]['delta']['content'] \n", " completion_text += event_text\n", "\n", " # Update the response_part parameter each time a new part of the response is received\n", " params.response_part = completion_text\n", "\n", " except:\n", " pass\n", "\n", "# print(f\"Full response received {event_time:.2f} seconds after request\")\n", "# print(f\"Full text received: {completion_text}\")\n", " return completion_text\n", "\n", "response_display = pn.Row('Assistant:', pn.bind(lambda text: pn.pane.Markdown(text, width=600, styles={'background-color': '#F6F6F6'}), params.param.response_part))\n", "panels = [response_display]\n", "\n", "def collect_messages(event):\n", " prompt = inp.value_input\n", " inp.value = ''\n", " context.append({'role':'user', 'content':f\"{prompt}\"})\n", " panels.append(\n", " pn.Row('User:', pn.pane.Markdown(prompt, width=600)))\n", "\n", " # Create a reactive panel linked to the response_part parameter\n", "# response_display = pn.bind(lambda text: pn.pane.Markdown(text, width=600, styles={'background-color': '#F6F6F6'}), params.param.response_part)\n", " \n", "\n", " # Get the full response\n", " response = get_completion_from_messages(context)\n", " context.append({'role':'assistant', 'content':f\"{response}\"})\n", " panels.append(pn.Row('Assistant:', pn.pane.Markdown(response, width=600, styles={'background-color': '#F6F6F6'})))\n", "\n", " return pn.Column(*panels)\n", "\n", "inp = pn.widgets.TextInput(value=\"안녕하세요\", placeholder='텍스트를 입력해주세요')\n", "button_conversation = pn.widgets.Button(name=\"Chat!\")\n", "\n", "interactive_conversation = pn.bind(collect_messages, button_conversation)\n", "\n", "dashboard = pn.Column(\n", " inp,\n", " pn.Row(button_conversation),\n", " pn.panel(interactive_conversation, height=3000),\n", ")\n", "\n", "dashboard\n" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "### Streaming" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "scrolled": false }, "outputs": [ { "data": { "application/javascript": "(function(root) {\n function now() {\n return new Date();\n }\n\n var force = true;\n var py_version = '3.1.1'.replace('rc', '-rc.');\n var is_dev = py_version.indexOf(\"+\") !== -1 || py_version.indexOf(\"-\") !== -1;\n var reloading = false;\n var Bokeh = root.Bokeh;\n var bokeh_loaded = Bokeh != null && (Bokeh.version === py_version || (Bokeh.versions !== undefined && Bokeh.versions.has(py_version)));\n\n if (typeof (root._bokeh_timeout) === \"undefined\" || force) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks;\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, js_modules, js_exports, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n if (js_modules == null) js_modules = [];\n if (js_exports == null) js_exports = {};\n\n root._bokeh_onload_callbacks.push(callback);\n\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls.length === 0 && js_modules.length === 0 && Object.keys(js_exports).length === 0) {\n run_callbacks();\n return null;\n }\n if (!reloading) {\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n }\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n window._bokeh_on_load = on_load\n\n function on_error() {\n console.error(\"failed to load \" + url);\n }\n\n var skip = [];\n if (window.requirejs) {\n window.requirejs.config({'packages': {}, 'paths': {'jspanel': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/jspanel', 'jspanel-modal': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/modal/jspanel.modal', 'jspanel-tooltip': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/tooltip/jspanel.tooltip', 'jspanel-hint': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/hint/jspanel.hint', 'jspanel-layout': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/layout/jspanel.layout', 'jspanel-contextmenu': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/contextmenu/jspanel.contextmenu', 'jspanel-dock': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/dock/jspanel.dock', 'gridstack': 'https://cdn.jsdelivr.net/npm/gridstack@7.2.3/dist/gridstack-all', 'notyf': 'https://cdn.jsdelivr.net/npm/notyf@3/notyf.min'}, 'shim': {'jspanel': {'exports': 'jsPanel'}, 'gridstack': {'exports': 'GridStack'}}});\n require([\"jspanel\"], function(jsPanel) {\n\twindow.jsPanel = jsPanel\n\ton_load()\n })\n require([\"jspanel-modal\"], function() {\n\ton_load()\n })\n require([\"jspanel-tooltip\"], function() {\n\ton_load()\n })\n require([\"jspanel-hint\"], function() {\n\ton_load()\n })\n require([\"jspanel-layout\"], function() {\n\ton_load()\n })\n require([\"jspanel-contextmenu\"], function() {\n\ton_load()\n })\n require([\"jspanel-dock\"], function() {\n\ton_load()\n })\n require([\"gridstack\"], function(GridStack) {\n\twindow.GridStack = GridStack\n\ton_load()\n })\n require([\"notyf\"], function() {\n\ton_load()\n })\n root._bokeh_is_loading = css_urls.length + 9;\n } else {\n root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length + Object.keys(js_exports).length;\n }\n\n var existing_stylesheets = []\n var links = document.getElementsByTagName('link')\n for (var i = 0; i < links.length; i++) {\n var link = links[i]\n if (link.href != null) {\n\texisting_stylesheets.push(link.href)\n }\n }\n for (var i = 0; i < css_urls.length; i++) {\n var url = css_urls[i];\n if (existing_stylesheets.indexOf(url) !== -1) {\n\ton_load()\n\tcontinue;\n }\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n } if (((window['jsPanel'] !== undefined) && (!(window['jsPanel'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/1.0.3/dist/bundled/floatpanel/jspanel4@4.12.0/dist/jspanel.js', 'https://cdn.holoviz.org/panel/1.0.3/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/modal/jspanel.modal.js', 'https://cdn.holoviz.org/panel/1.0.3/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/tooltip/jspanel.tooltip.js', 'https://cdn.holoviz.org/panel/1.0.3/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/hint/jspanel.hint.js', 'https://cdn.holoviz.org/panel/1.0.3/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/layout/jspanel.layout.js', 'https://cdn.holoviz.org/panel/1.0.3/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/contextmenu/jspanel.contextmenu.js', 'https://cdn.holoviz.org/panel/1.0.3/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/dock/jspanel.dock.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['GridStack'] !== undefined) && (!(window['GridStack'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/1.0.3/dist/bundled/gridstack/gridstack@7.2.3/dist/gridstack-all.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['Notyf'] !== undefined) && (!(window['Notyf'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/1.0.3/dist/bundled/notificationarea/notyf@3/notyf.min.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } var existing_scripts = []\n var scripts = document.getElementsByTagName('script')\n for (var i = 0; i < scripts.length; i++) {\n var script = scripts[i]\n if (script.src != null) {\n\texisting_scripts.push(script.src)\n }\n }\n for (var i = 0; i < js_urls.length; i++) {\n var url = js_urls[i];\n if (skip.indexOf(url) !== -1 || existing_scripts.indexOf(url) !== -1) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (var i = 0; i < js_modules.length; i++) {\n var url = js_modules[i];\n if (skip.indexOf(url) !== -1 || existing_scripts.indexOf(url) !== -1) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (const name in js_exports) {\n var url = js_exports[name];\n if (skip.indexOf(url) >= 0 || root[name] != null) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onerror = on_error;\n element.async = false;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n element.textContent = `\n import ${name} from \"${url}\"\n window.${name} = ${name}\n window._bokeh_on_load()\n `\n document.head.appendChild(element);\n }\n if (!js_urls.length && !js_modules.length) {\n on_load()\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n var js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-3.1.1.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.1.1.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.1.1.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.1.1.min.js\", \"https://cdn.holoviz.org/panel/1.0.3/dist/panel.min.js\"];\n var js_modules = [];\n var js_exports = {};\n var css_urls = [];\n var inline_js = [ function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\nfunction(Bokeh) {} // ensure no trailing comma for IE\n ];\n\n function run_inline_js() {\n if ((root.Bokeh !== undefined) || (force === true)) {\n for (var i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }\n // Cache old bokeh versions\n if (Bokeh != undefined && !reloading) {\n\tvar NewBokeh = root.Bokeh;\n\tif (Bokeh.versions === undefined) {\n\t Bokeh.versions = new Map();\n\t}\n\tif (NewBokeh.version !== Bokeh.version) {\n\t Bokeh.versions.set(NewBokeh.version, NewBokeh)\n\t}\n\troot.Bokeh = Bokeh;\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n }\n root._bokeh_is_initializing = false\n }\n\n function load_or_wait() {\n // Implement a backoff loop that tries to ensure we do not load multiple\n // versions of Bokeh and its dependencies at the same time.\n // In recent versions we use the root._bokeh_is_initializing flag\n // to determine whether there is an ongoing attempt to initialize\n // bokeh, however for backward compatibility we also try to ensure\n // that we do not start loading a newer (Panel>=1.0 and Bokeh>3) version\n // before older versions are fully initialized.\n if (root._bokeh_is_initializing && Date.now() > root._bokeh_timeout) {\n root._bokeh_is_initializing = false;\n root._bokeh_onload_callbacks = undefined;\n console.log(\"Bokeh: BokehJS was loaded multiple times but one version failed to initialize.\");\n load_or_wait();\n } else if (root._bokeh_is_initializing || (typeof root._bokeh_is_initializing === \"undefined\" && root._bokeh_onload_callbacks !== undefined)) {\n setTimeout(load_or_wait, 100);\n } else {\n Bokeh = root.Bokeh;\n bokeh_loaded = Bokeh != null && (Bokeh.version === py_version || (Bokeh.versions !== undefined && Bokeh.versions.has(py_version)));\n root._bokeh_is_initializing = true\n root._bokeh_onload_callbacks = []\n if (!reloading && (!bokeh_loaded || is_dev)) {\n\troot.Bokeh = undefined;\n }\n load_libs(css_urls, js_urls, js_modules, js_exports, function() {\n\tconsole.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n\trun_inline_js();\n });\n }\n }\n // Give older versions of the autoload script a head-start to ensure\n // they initialize before we start loading newer version.\n setTimeout(load_or_wait, 100)\n}(window));", "application/vnd.holoviews_load.v0+json": "" }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/javascript": "\nif ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n}\n\n\n function JupyterCommManager() {\n }\n\n JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n comm_manager.register_target(comm_id, function(comm) {\n comm.on_msg(msg_handler);\n });\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n comm.onMsg = msg_handler;\n });\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n console.log(message)\n var content = {data: message.data, comm_id};\n var buffers = []\n for (var buffer of message.buffers || []) {\n buffers.push(new DataView(buffer))\n }\n var metadata = message.metadata || {};\n var msg = {content, buffers, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n })\n }\n }\n\n JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n if (comm_id in window.PyViz.comms) {\n return window.PyViz.comms[comm_id];\n } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n if (msg_handler) {\n comm.on_msg(msg_handler);\n }\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n comm.open();\n if (msg_handler) {\n comm.onMsg = msg_handler;\n }\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n var comm_promise = google.colab.kernel.comms.open(comm_id)\n comm_promise.then((comm) => {\n window.PyViz.comms[comm_id] = comm;\n if (msg_handler) {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n var content = {data: message.data};\n var metadata = message.metadata || {comm_id};\n var msg = {content, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n }\n }) \n var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n return comm_promise.then((comm) => {\n comm.send(data, metadata, buffers, disposeOnDone);\n });\n };\n var comm = {\n send: sendClosure\n };\n }\n window.PyViz.comms[comm_id] = comm;\n return comm;\n }\n window.PyViz.comm_manager = new JupyterCommManager();\n \n\n\nvar JS_MIME_TYPE = 'application/javascript';\nvar HTML_MIME_TYPE = 'text/html';\nvar EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\nvar CLASS_NAME = 'output';\n\n/**\n * Render data to the DOM node\n */\nfunction render(props, node) {\n var div = document.createElement(\"div\");\n var script = document.createElement(\"script\");\n node.appendChild(div);\n node.appendChild(script);\n}\n\n/**\n * Handle when a new output is added\n */\nfunction handle_add_output(event, handle) {\n var output_area = handle.output_area;\n var output = handle.output;\n if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n return\n }\n var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n if (id !== undefined) {\n var nchildren = toinsert.length;\n var html_node = toinsert[nchildren-1].children[0];\n html_node.innerHTML = output.data[HTML_MIME_TYPE];\n var scripts = [];\n var nodelist = html_node.querySelectorAll(\"script\");\n for (var i in nodelist) {\n if (nodelist.hasOwnProperty(i)) {\n scripts.push(nodelist[i])\n }\n }\n\n scripts.forEach( function (oldScript) {\n var newScript = document.createElement(\"script\");\n var attrs = [];\n var nodemap = oldScript.attributes;\n for (var j in nodemap) {\n if (nodemap.hasOwnProperty(j)) {\n attrs.push(nodemap[j])\n }\n }\n attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n oldScript.parentNode.replaceChild(newScript, oldScript);\n });\n if (JS_MIME_TYPE in output.data) {\n toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n }\n output_area._hv_plot_id = id;\n if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n window.PyViz.plot_index[id] = Bokeh.index[id];\n } else {\n window.PyViz.plot_index[id] = null;\n }\n } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n var bk_div = document.createElement(\"div\");\n bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n var script_attrs = bk_div.children[0].attributes;\n for (var i = 0; i < script_attrs.length; i++) {\n toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n }\n // store reference to server id on output_area\n output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n }\n}\n\n/**\n * Handle when an output is cleared or removed\n */\nfunction handle_clear_output(event, handle) {\n var id = handle.cell.output_area._hv_plot_id;\n var server_id = handle.cell.output_area._bokeh_server_id;\n if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n if (server_id !== null) {\n comm.send({event_type: 'server_delete', 'id': server_id});\n return;\n } else if (comm !== null) {\n comm.send({event_type: 'delete', 'id': id});\n }\n delete PyViz.plot_index[id];\n if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n var doc = window.Bokeh.index[id].model.document\n doc.clear();\n const i = window.Bokeh.documents.indexOf(doc);\n if (i > -1) {\n window.Bokeh.documents.splice(i, 1);\n }\n }\n}\n\n/**\n * Handle kernel restart event\n */\nfunction handle_kernel_cleanup(event, handle) {\n delete PyViz.comms[\"hv-extension-comm\"];\n window.PyViz.plot_index = {}\n}\n\n/**\n * Handle update_display_data messages\n */\nfunction handle_update_output(event, handle) {\n handle_clear_output(event, {cell: {output_area: handle.output_area}})\n handle_add_output(event, handle)\n}\n\nfunction register_renderer(events, OutputArea) {\n function append_mime(data, metadata, element) {\n // create a DOM node to render to\n var toinsert = this.create_output_subarea(\n metadata,\n CLASS_NAME,\n EXEC_MIME_TYPE\n );\n this.keyboard_manager.register_events(toinsert);\n // Render to node\n var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n render(props, toinsert[0]);\n element.append(toinsert);\n return toinsert\n }\n\n events.on('output_added.OutputArea', handle_add_output);\n events.on('output_updated.OutputArea', handle_update_output);\n events.on('clear_output.CodeCell', handle_clear_output);\n events.on('delete.Cell', handle_clear_output);\n events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n\n OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n safe: true,\n index: 0\n });\n}\n\nif (window.Jupyter !== undefined) {\n try {\n var events = require('base/js/events');\n var OutputArea = require('notebook/js/outputarea').OutputArea;\n if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n register_renderer(events, OutputArea);\n }\n } catch(err) {\n }\n}\n", "application/vnd.holoviews_load.v0+json": "" }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/vnd.holoviews_exec.v0+json": "", "text/html": [ "
\n", "
\n", "
\n", "" ] }, "metadata": { "application/vnd.holoviews_exec.v0+json": { "id": "d11b199c-386b-4642-aadd-4291113e0d78" } }, "output_type": "display_data" }, { "data": {}, "metadata": {}, "output_type": "display_data" }, { "data": { "application/vnd.holoviews_exec.v0+json": "", "text/html": [ "
\n", "
\n", "
\n", "" ], "text/plain": [ "Column\n", " [0] TextInput(placeholder='텍스트를 입력해주세요')\n", " [1] Row\n", " [0] Button(name='Chat!')\n", " [2] ParamFunction(function, _pane=Column, height=3000)" ] }, "execution_count": 14, "metadata": { "application/vnd.holoviews_exec.v0+json": { "id": "5b38265f-f52c-4db6-b599-c2ba4db7badf" } }, "output_type": "execute_result" } ], "source": [ "import param\n", "import time\n", "import panel as pn\n", "\n", "pn.extension()\n", "\n", "context = [ {'role':'system', 'content':\"\"\"\n", "너는 맥도날드에서 주문을 받는 봇이다.\\\n", "먼저 고객을 맞이한 다음 주문을 받는다. \\\n", "전체 주문을 받은 다음 주문을 요약하고, 고객이 추가할 사항이 있는지 최종적으로 확인한다. \\\n", "마지막으로 결제를 진행한다. 결제는 카드, 현금, 휴대폰으로 진행할 수 있다.\\\n", "모든 대답은 짧고, 친근한 대화 스타일로 한다.\\\n", "제공할 수 없는 정보는 제공할 수 없다는 말과 함께 사과한다.\n", "\"\"\"}]\n", "\n", "db_context, act_context = \"\", \"\"\n", "prompt, response = \"\", \"\"\n", "\n", "# Define a class to hold the response part\n", "class Params(param.Parameterized):\n", " response_part = param.String(default=\"\")\n", "\n", "db_response_params = Params()\n", "response_params = Params()\n", "act_response_params = Params()\n", "\n", "def get_completion_from_messages(messages, model=\"gpt-4\", temperature=0):\n", " response = openai.ChatCompletion.create(\n", " model=model,\n", " messages=messages,\n", " temperature=temperature, \n", " stream=True\n", " )\n", " completion_text = ''\n", " start_time = time.time()\n", " for event in response:\n", " event_time = time.time() - start_time \n", " try:\n", " event_text = event['choices'][0]['delta']['content'] \n", " completion_text += event_text\n", "\n", " # Update the response_part parameter each time a new part of the response is received\n", " response_params.response_part = completion_text\n", " except:\n", " pass\n", " \n", " return completion_text\n", "\n", "def get_db_response_from_messages(assistant, user, model=\"gpt-3.5-turbo\", temperature=0):\n", " global db_context\n", " prompt = f\"\"\"\n", " Follow the steps below to express the user's intention as a query.\n", "\n", " step1. Read the user's saying in korean, which is delimited by triple backticks, and predict the user's intent.\n", " step2. Create an API query to provide information based on the user's intent.\n", "\n", " If there is no appropriate query, nothing is returned.\n", " The query consists of (function, value). The value depends on the function.\n", " \n", " Below is the list of query functions.\n", " List of query functions: [메뉴정보제공, 정보제공, 메뉴추천, 메뉴확인]\n", " \n", " Below is 4 examples API query correspoding user saying\n", " Example1\n", " assistant: 주문하실 메뉴가 있을까요?\n", " user: 빅맥 세트 하나 주세요\n", " API query: []\n", " \n", " Example2\n", " assistant: \n", " user: \n", " API query: []\n", " \n", " Example3\n", " assistant: 주문하실 메뉴가 있으신가요?\n", " user: 어떤 햄버거 메뉴가 잘나가요?\n", " API query: [메뉴추천, (햄버거)]\n", " \n", " Example4\n", " assistant: 불고기 버거 세트 하나 접수했습니다. 어떤 음료를 드릴까요?\n", " user: 콜라로 주세요\n", " API query: []\n", " \n", " Now, create an API query based on the below user saying in korean, which is delimited by triple backticks.\n", " If the user didn't say anything, return nothing.\n", " Question:\n", " user: '''{user}'''\n", " API query: \n", " \"\"\"\n", " db_context = prompt\n", " messages = [{\"role\": \"user\", \"content\": prompt}]\n", " response = openai.ChatCompletion.create(\n", " model=model,\n", " messages=messages,\n", " temperature=temperature, \n", " stream=True\n", " )\n", " completion_text = ''\n", " start_time = time.time()\n", " for event in response:\n", " event_time = time.time() - start_time \n", " try:\n", " event_text = event['choices'][0]['delta']['content'] \n", " completion_text += event_text\n", "\n", " # Update the response_part parameter each time a new part of the response is received\n", " db_response_params.response_part = completion_text\n", " except:\n", " pass\n", " \n", " return completion_text\n", "\n", "def get_act_response_from_messages(user, assistant, model=\"gpt-3.5-turbo\", temperature=0):\n", " global act_context\n", " prompt = f\"\"\"\n", " Follow the steps below to express the assistant's intention as a query.\n", "\n", " step1. Read the assistant's saying in korean, which is delimited by triple backticks, and predict the assistant's intent.\n", " step2. Create an API query based on the assistant's intent.\n", " \n", " If there is no appropriate query, nothing is returned.\n", " The query consists of (function, value). The value depends on the function.\n", " \n", " Below is the list of query functions.\n", " List of query functions: [메뉴정보제공, 정보제공, 메뉴추천, 메뉴확인, 환영, 결제]\n", " \n", " Below is 4 examples API query correspoding assistant saying.\n", " Example1:\n", " user: 빅맥세트 하나 주세요.\n", " assistant: 넵, 알겠습니다. 일반 세트로 드릴까요? 라지 세트로 드릴까요?\n", " API query: [메뉴확인, (빅맥세트)]\n", " \n", " Example2:\n", " user: \n", " assistant: 안녕하세요! 주문하실 메뉴가 있으신가요?\n", " API query: [환영, ()]\n", " \n", " Example3:\n", " user: 어떤 사이드 메뉴가 인기있나요?\n", " assistant: 물론이죠. 사이드 메뉴 중 인기 있는 것들은 맥너겟이 있습니다.\n", " API query: [메뉴추천, (맥너겟)]\n", " \n", " Example4:\n", " user: 현금으로 할게요\n", " assistant: 현금결제 진행하도록 하겠습니다. 조금만 기다려주세요.\n", " API query: [결제, (현금)]\n", " \n", " Now, Categorize API query based on the below assistant saying in korean, which is delimited by triple backticks.\n", " Question:\n", " user: {user}\n", " assistant: '''{assistant}'''\n", " API query: \n", " \"\"\"\n", " act_context = prompt\n", " messages = [{\"role\": \"user\", \"content\": prompt}]\n", " response = openai.ChatCompletion.create(\n", " model=model,\n", " messages=messages,\n", " temperature=temperature, \n", " stream=True\n", " )\n", " completion_text = ''\n", " start_time = time.time()\n", " for event in response:\n", " event_time = time.time() - start_time \n", " try:\n", " event_text = event['choices'][0]['delta']['content'] \n", " completion_text += event_text\n", "\n", " # Update the response_part parameter each time a new part of the response is received\n", " act_response_params.response_part = completion_text\n", " except:\n", " pass\n", " \n", " return completion_text\n", "db_context, act_context = '', ''\n", "db_assistant_act = pn.Row('db query:', pn.bind(lambda text: pn.pane.Markdown(text, width=600, styles={'background-color': '#F6F6F6'}), db_response_params.param.response_part))\n", "response_display = pn.Row('Assistant:', pn.bind(lambda text: pn.pane.Markdown(text, width=600, styles={'background-color': '#F6F6F6'}), response_params.param.response_part))\n", "act_response_display = pn.Row('act query:', pn.bind(lambda text: pn.pane.Markdown(text, width=600, styles={'background-color': '#F6F6F6'}), act_response_params.param.response_part))\n", "\n", "panels = [db_assistant_act, response_display, act_response_display]\n", "\n", "def collect_messages(_):\n", " global prompt, response\n", " prompt = inp.value_input\n", " inp.value = ''\n", " context.append({'role':'user', 'content':f\"{prompt}\"})\n", " db_response = get_db_response_from_messages(response, prompt)\n", " response_context = context\n", " response_context.append({'role':'system', 'content':f\"{db_response}\"})\n", " response = get_completion_from_messages(response_context)\n", " context.append({'role':'assistant', 'content':f\"{response}\"})\n", " act_response = get_act_response_from_messages(prompt, response)\n", " panels.append(\n", " pn.Row('User:', pn.pane.Markdown(prompt, width=600)))\n", " panels.append(\n", " pn.Row('Assistant:', pn.pane.Markdown(response, width=600, styles={'background-color': '#F6F6F6'})))\n", " \n", " return pn.Column(*panels)\n", "\n", "inp = pn.widgets.TextInput(value=\"안녕하세요\", placeholder='텍스트를 입력해주세요')\n", "button_conversation = pn.widgets.Button(name=\"Chat!\")\n", "\n", "interactive_conversation = pn.bind(collect_messages, button_conversation)\n", "\n", "dashboard = pn.Column(\n", " inp,\n", " pn.Row(button_conversation),\n", " pn.panel(interactive_conversation, height=3000),\n", ")\n", "\n", "dashboard" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "### Get Act First" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "application/javascript": "(function(root) {\n function now() {\n return new Date();\n }\n\n var force = true;\n var py_version = '3.1.1'.replace('rc', '-rc.');\n var is_dev = py_version.indexOf(\"+\") !== -1 || py_version.indexOf(\"-\") !== -1;\n var reloading = false;\n var Bokeh = root.Bokeh;\n var bokeh_loaded = Bokeh != null && (Bokeh.version === py_version || (Bokeh.versions !== undefined && Bokeh.versions.has(py_version)));\n\n if (typeof (root._bokeh_timeout) === \"undefined\" || force) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks;\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, js_modules, js_exports, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n if (js_modules == null) js_modules = [];\n if (js_exports == null) js_exports = {};\n\n root._bokeh_onload_callbacks.push(callback);\n\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls.length === 0 && js_modules.length === 0 && Object.keys(js_exports).length === 0) {\n run_callbacks();\n return null;\n }\n if (!reloading) {\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n }\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n window._bokeh_on_load = on_load\n\n function on_error() {\n console.error(\"failed to load \" + url);\n }\n\n var skip = [];\n if (window.requirejs) {\n window.requirejs.config({'packages': {}, 'paths': {'jspanel': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/jspanel', 'jspanel-modal': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/modal/jspanel.modal', 'jspanel-tooltip': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/tooltip/jspanel.tooltip', 'jspanel-hint': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/hint/jspanel.hint', 'jspanel-layout': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/layout/jspanel.layout', 'jspanel-contextmenu': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/contextmenu/jspanel.contextmenu', 'jspanel-dock': 'https://cdn.jsdelivr.net/npm/jspanel4@4.12.0/dist/extensions/dock/jspanel.dock', 'gridstack': 'https://cdn.jsdelivr.net/npm/gridstack@7.2.3/dist/gridstack-all', 'notyf': 'https://cdn.jsdelivr.net/npm/notyf@3/notyf.min'}, 'shim': {'jspanel': {'exports': 'jsPanel'}, 'gridstack': {'exports': 'GridStack'}}});\n require([\"jspanel\"], function(jsPanel) {\n\twindow.jsPanel = jsPanel\n\ton_load()\n })\n require([\"jspanel-modal\"], function() {\n\ton_load()\n })\n require([\"jspanel-tooltip\"], function() {\n\ton_load()\n })\n require([\"jspanel-hint\"], function() {\n\ton_load()\n })\n require([\"jspanel-layout\"], function() {\n\ton_load()\n })\n require([\"jspanel-contextmenu\"], function() {\n\ton_load()\n })\n require([\"jspanel-dock\"], function() {\n\ton_load()\n })\n require([\"gridstack\"], function(GridStack) {\n\twindow.GridStack = GridStack\n\ton_load()\n })\n require([\"notyf\"], function() {\n\ton_load()\n })\n root._bokeh_is_loading = css_urls.length + 9;\n } else {\n root._bokeh_is_loading = css_urls.length + js_urls.length + js_modules.length + Object.keys(js_exports).length;\n }\n\n var existing_stylesheets = []\n var links = document.getElementsByTagName('link')\n for (var i = 0; i < links.length; i++) {\n var link = links[i]\n if (link.href != null) {\n\texisting_stylesheets.push(link.href)\n }\n }\n for (var i = 0; i < css_urls.length; i++) {\n var url = css_urls[i];\n if (existing_stylesheets.indexOf(url) !== -1) {\n\ton_load()\n\tcontinue;\n }\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n } if (((window['jsPanel'] !== undefined) && (!(window['jsPanel'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/1.0.3/dist/bundled/floatpanel/jspanel4@4.12.0/dist/jspanel.js', 'https://cdn.holoviz.org/panel/1.0.3/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/modal/jspanel.modal.js', 'https://cdn.holoviz.org/panel/1.0.3/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/tooltip/jspanel.tooltip.js', 'https://cdn.holoviz.org/panel/1.0.3/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/hint/jspanel.hint.js', 'https://cdn.holoviz.org/panel/1.0.3/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/layout/jspanel.layout.js', 'https://cdn.holoviz.org/panel/1.0.3/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/contextmenu/jspanel.contextmenu.js', 'https://cdn.holoviz.org/panel/1.0.3/dist/bundled/floatpanel/jspanel4@4.12.0/dist/extensions/dock/jspanel.dock.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['GridStack'] !== undefined) && (!(window['GridStack'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/1.0.3/dist/bundled/gridstack/gridstack@7.2.3/dist/gridstack-all.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } if (((window['Notyf'] !== undefined) && (!(window['Notyf'] instanceof HTMLElement))) || window.requirejs) {\n var urls = ['https://cdn.holoviz.org/panel/1.0.3/dist/bundled/notificationarea/notyf@3/notyf.min.js'];\n for (var i = 0; i < urls.length; i++) {\n skip.push(urls[i])\n }\n } var existing_scripts = []\n var scripts = document.getElementsByTagName('script')\n for (var i = 0; i < scripts.length; i++) {\n var script = scripts[i]\n if (script.src != null) {\n\texisting_scripts.push(script.src)\n }\n }\n for (var i = 0; i < js_urls.length; i++) {\n var url = js_urls[i];\n if (skip.indexOf(url) !== -1 || existing_scripts.indexOf(url) !== -1) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (var i = 0; i < js_modules.length; i++) {\n var url = js_modules[i];\n if (skip.indexOf(url) !== -1 || existing_scripts.indexOf(url) !== -1) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n for (const name in js_exports) {\n var url = js_exports[name];\n if (skip.indexOf(url) >= 0 || root[name] != null) {\n\tif (!window.requirejs) {\n\t on_load();\n\t}\n\tcontinue;\n }\n var element = document.createElement('script');\n element.onerror = on_error;\n element.async = false;\n element.type = \"module\";\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n element.textContent = `\n import ${name} from \"${url}\"\n window.${name} = ${name}\n window._bokeh_on_load()\n `\n document.head.appendChild(element);\n }\n if (!js_urls.length && !js_modules.length) {\n on_load()\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n var js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-3.1.1.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.1.1.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.1.1.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.1.1.min.js\", \"https://cdn.holoviz.org/panel/1.0.3/dist/panel.min.js\"];\n var js_modules = [];\n var js_exports = {};\n var css_urls = [];\n var inline_js = [ function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\nfunction(Bokeh) {} // ensure no trailing comma for IE\n ];\n\n function run_inline_js() {\n if ((root.Bokeh !== undefined) || (force === true)) {\n for (var i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }\n // Cache old bokeh versions\n if (Bokeh != undefined && !reloading) {\n\tvar NewBokeh = root.Bokeh;\n\tif (Bokeh.versions === undefined) {\n\t Bokeh.versions = new Map();\n\t}\n\tif (NewBokeh.version !== Bokeh.version) {\n\t Bokeh.versions.set(NewBokeh.version, NewBokeh)\n\t}\n\troot.Bokeh = Bokeh;\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n }\n root._bokeh_is_initializing = false\n }\n\n function load_or_wait() {\n // Implement a backoff loop that tries to ensure we do not load multiple\n // versions of Bokeh and its dependencies at the same time.\n // In recent versions we use the root._bokeh_is_initializing flag\n // to determine whether there is an ongoing attempt to initialize\n // bokeh, however for backward compatibility we also try to ensure\n // that we do not start loading a newer (Panel>=1.0 and Bokeh>3) version\n // before older versions are fully initialized.\n if (root._bokeh_is_initializing && Date.now() > root._bokeh_timeout) {\n root._bokeh_is_initializing = false;\n root._bokeh_onload_callbacks = undefined;\n console.log(\"Bokeh: BokehJS was loaded multiple times but one version failed to initialize.\");\n load_or_wait();\n } else if (root._bokeh_is_initializing || (typeof root._bokeh_is_initializing === \"undefined\" && root._bokeh_onload_callbacks !== undefined)) {\n setTimeout(load_or_wait, 100);\n } else {\n Bokeh = root.Bokeh;\n bokeh_loaded = Bokeh != null && (Bokeh.version === py_version || (Bokeh.versions !== undefined && Bokeh.versions.has(py_version)));\n root._bokeh_is_initializing = true\n root._bokeh_onload_callbacks = []\n if (!reloading && (!bokeh_loaded || is_dev)) {\n\troot.Bokeh = undefined;\n }\n load_libs(css_urls, js_urls, js_modules, js_exports, function() {\n\tconsole.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n\trun_inline_js();\n });\n }\n }\n // Give older versions of the autoload script a head-start to ensure\n // they initialize before we start loading newer version.\n setTimeout(load_or_wait, 100)\n}(window));", "application/vnd.holoviews_load.v0+json": "" }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/javascript": "\nif ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n}\n\n\n function JupyterCommManager() {\n }\n\n JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n comm_manager.register_target(comm_id, function(comm) {\n comm.on_msg(msg_handler);\n });\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n comm.onMsg = msg_handler;\n });\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n console.log(message)\n var content = {data: message.data, comm_id};\n var buffers = []\n for (var buffer of message.buffers || []) {\n buffers.push(new DataView(buffer))\n }\n var metadata = message.metadata || {};\n var msg = {content, buffers, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n })\n }\n }\n\n JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n if (comm_id in window.PyViz.comms) {\n return window.PyViz.comms[comm_id];\n } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n if (msg_handler) {\n comm.on_msg(msg_handler);\n }\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n comm.open();\n if (msg_handler) {\n comm.onMsg = msg_handler;\n }\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n var comm_promise = google.colab.kernel.comms.open(comm_id)\n comm_promise.then((comm) => {\n window.PyViz.comms[comm_id] = comm;\n if (msg_handler) {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n var content = {data: message.data};\n var metadata = message.metadata || {comm_id};\n var msg = {content, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n }\n }) \n var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n return comm_promise.then((comm) => {\n comm.send(data, metadata, buffers, disposeOnDone);\n });\n };\n var comm = {\n send: sendClosure\n };\n }\n window.PyViz.comms[comm_id] = comm;\n return comm;\n }\n window.PyViz.comm_manager = new JupyterCommManager();\n \n\n\nvar JS_MIME_TYPE = 'application/javascript';\nvar HTML_MIME_TYPE = 'text/html';\nvar EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\nvar CLASS_NAME = 'output';\n\n/**\n * Render data to the DOM node\n */\nfunction render(props, node) {\n var div = document.createElement(\"div\");\n var script = document.createElement(\"script\");\n node.appendChild(div);\n node.appendChild(script);\n}\n\n/**\n * Handle when a new output is added\n */\nfunction handle_add_output(event, handle) {\n var output_area = handle.output_area;\n var output = handle.output;\n if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n return\n }\n var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n if (id !== undefined) {\n var nchildren = toinsert.length;\n var html_node = toinsert[nchildren-1].children[0];\n html_node.innerHTML = output.data[HTML_MIME_TYPE];\n var scripts = [];\n var nodelist = html_node.querySelectorAll(\"script\");\n for (var i in nodelist) {\n if (nodelist.hasOwnProperty(i)) {\n scripts.push(nodelist[i])\n }\n }\n\n scripts.forEach( function (oldScript) {\n var newScript = document.createElement(\"script\");\n var attrs = [];\n var nodemap = oldScript.attributes;\n for (var j in nodemap) {\n if (nodemap.hasOwnProperty(j)) {\n attrs.push(nodemap[j])\n }\n }\n attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n oldScript.parentNode.replaceChild(newScript, oldScript);\n });\n if (JS_MIME_TYPE in output.data) {\n toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n }\n output_area._hv_plot_id = id;\n if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n window.PyViz.plot_index[id] = Bokeh.index[id];\n } else {\n window.PyViz.plot_index[id] = null;\n }\n } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n var bk_div = document.createElement(\"div\");\n bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n var script_attrs = bk_div.children[0].attributes;\n for (var i = 0; i < script_attrs.length; i++) {\n toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n }\n // store reference to server id on output_area\n output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n }\n}\n\n/**\n * Handle when an output is cleared or removed\n */\nfunction handle_clear_output(event, handle) {\n var id = handle.cell.output_area._hv_plot_id;\n var server_id = handle.cell.output_area._bokeh_server_id;\n if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n if (server_id !== null) {\n comm.send({event_type: 'server_delete', 'id': server_id});\n return;\n } else if (comm !== null) {\n comm.send({event_type: 'delete', 'id': id});\n }\n delete PyViz.plot_index[id];\n if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n var doc = window.Bokeh.index[id].model.document\n doc.clear();\n const i = window.Bokeh.documents.indexOf(doc);\n if (i > -1) {\n window.Bokeh.documents.splice(i, 1);\n }\n }\n}\n\n/**\n * Handle kernel restart event\n */\nfunction handle_kernel_cleanup(event, handle) {\n delete PyViz.comms[\"hv-extension-comm\"];\n window.PyViz.plot_index = {}\n}\n\n/**\n * Handle update_display_data messages\n */\nfunction handle_update_output(event, handle) {\n handle_clear_output(event, {cell: {output_area: handle.output_area}})\n handle_add_output(event, handle)\n}\n\nfunction register_renderer(events, OutputArea) {\n function append_mime(data, metadata, element) {\n // create a DOM node to render to\n var toinsert = this.create_output_subarea(\n metadata,\n CLASS_NAME,\n EXEC_MIME_TYPE\n );\n this.keyboard_manager.register_events(toinsert);\n // Render to node\n var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n render(props, toinsert[0]);\n element.append(toinsert);\n return toinsert\n }\n\n events.on('output_added.OutputArea', handle_add_output);\n events.on('output_updated.OutputArea', handle_update_output);\n events.on('clear_output.CodeCell', handle_clear_output);\n events.on('delete.Cell', handle_clear_output);\n events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n\n OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n safe: true,\n index: 0\n });\n}\n\nif (window.Jupyter !== undefined) {\n try {\n var events = require('base/js/events');\n var OutputArea = require('notebook/js/outputarea').OutputArea;\n if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n register_renderer(events, OutputArea);\n }\n } catch(err) {\n }\n}\n", "application/vnd.holoviews_load.v0+json": "" }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/vnd.holoviews_exec.v0+json": "", "text/html": [ "
\n", "
\n", "
\n", "" ] }, "metadata": { "application/vnd.holoviews_exec.v0+json": { "id": "fbe2eddb-9c7d-4f81-ad7f-961daf9587d3" } }, "output_type": "display_data" }, { "data": {}, "metadata": {}, "output_type": "display_data" }, { "data": { "application/vnd.holoviews_exec.v0+json": "", "text/html": [ "
\n", "
\n", "
\n", "" ], "text/plain": [ "Column\n", " [0] TextInput(placeholder='텍스트를 입력해주세요')\n", " [1] Row\n", " [0] Button(name='Chat!')\n", " [2] ParamFunction(function, _pane=Column, height=3000)" ] }, "execution_count": 15, "metadata": { "application/vnd.holoviews_exec.v0+json": { "id": "d442b3c6-77a3-42a5-8e2d-2b218508076f" } }, "output_type": "execute_result" } ], "source": [ "### import param\n", "import time\n", "import panel as pn\n", "\n", "pn.extension()\n", "\n", "context = [ {'role':'system', 'content':\"\"\"\n", "너는 맥도날드에서 주문을 받는 봇이다.\\\n", "먼저 고객을 맞이한 다음 주문을 받는다. \\\n", "전체 주문을 받은 다음 주문을 요약하고, 고객이 추가할 사항이 있는지 최종적으로 확인한다. \\\n", "마지막으로 결제를 진행한다. 결제는 카드, 현금, 휴대폰으로 진행할 수 있다.\\\n", "모든 대답은 짧고, 친근한 대화 스타일로 한다.\\\n", "제공할 수 없는 정보는 제공할 수 없다는 말과 함께 사과한다.\n", "\"\"\"}]\n", "\n", "db_context, act_context, response_context = \"\", \"\", \"\"\n", "prompt, response = \"\", \"\"\n", "\n", "# Define a class to hold the response part\n", "class Params(param.Parameterized):\n", " response_part = param.String(default=\"\")\n", "\n", "db_response_params = Params()\n", "act_response_params = Params()\n", "response_params = Params()\n", "\n", "def get_act_response_from_messages(context, model=\"gpt-4\", temperature=0):\n", " prompt = f\"\"\"\n", " User is a customer at McDonald's, and assistant is a McDonald's worker.\n", " Choose the most appropriate assistant behavior for the assistant to take next following conversation.\n", " \n", " List of actions: [메뉴정보제공, 정보제공, 메뉴추천, 메뉴확인, 환영, 결제]\n", " \n", " Below is 4 examples of assistant behavior correspoding conversations.\n", " Example1:\n", " user: 안녕하세요.\n", " assistant behavior: [환영, ()]\n", " \n", " Example2:\n", " user:\n", " assistant: 어서오세요. 맥도날드에 오신것을 환영합니다. 주문도와드릴까요?\n", " user: 어떤 햄버거 메뉴가 잘나가나요?\n", " assistant behavior: [메뉴추천, (햄버거)]\n", " \n", " Example3\n", " user: \n", " assistant: 어서오세요. 맥도날드에 오신것을 환영합니다. \n", " user: 불고기버거 세트 하나 주세요.\n", " assistant: 불고기 버거 세트 주문되었습니다. 추가로 주문하실 사항 있으신가요?\n", " user: 아니요. 없습니다.\n", " assistant behavior: [결제요청, (카드, 현금, 휴대폰)]\n", " \n", " Now, Choose the most appropriate assistant behavior based on the below conversation.\n", " \"\"\"\n", " for context_dict in context:\n", " if context_dict['role'] == 'user':\n", " prompt += f\"user: {context_dict['content']}\\n\"\n", " elif context_dict['role'] == 'assistant':\n", " prompt += f\"assistant: {context_dict['content']}\\n\"\n", " else:\n", " pass\n", "# prompt += \"user intent:\"\n", " prompt += \"assistant behavior: \"\n", " \n", " act_context = prompt\n", " messages = [{\"role\": \"user\", \"content\": prompt}]\n", " response = openai.ChatCompletion.create(\n", " model=model,\n", " messages=messages,\n", " temperature=temperature, \n", " stream=True\n", " )\n", " completion_text = ''\n", " start_time = time.time()\n", " for event in response:\n", " event_time = time.time() - start_time \n", " try:\n", " event_text = event['choices'][0]['delta']['content'] \n", " completion_text += event_text\n", "\n", " # Update the response_part parameter each time a new part of the response is received\n", " act_response_params.response_part = completion_text\n", " except:\n", " pass\n", " \n", " return completion_text\n", "\n", "def get_db_response_from_messages(assistant, user, model=\"gpt-3.5-turbo\", temperature=0):\n", " global db_context\n", " prompt = f\"\"\"\n", " Follow the steps below to express the user's intention as a query.\n", "\n", " step1. Read the user's saying in korean, which is delimited by triple backticks, and predict the user's intent.\n", " step2. Create an API query to provide information based on the user's intent.\n", "\n", " If there is no appropriate query, nothing is returned.\n", " The query consists of (function, value). The value depends on the function.\n", " \n", " Below is the list of query functions.\n", " List of query functions: [메뉴정보제공, 정보제공, 메뉴추천, 메뉴확인]\n", " \n", " Below is 4 examples API query correspoding user saying\n", " Example1\n", " assistant: 주문하실 메뉴가 있을까요?\n", " user: 빅맥 세트 하나 주세요\n", " API query: []\n", " \n", " Example2\n", " assistant: \n", " user: \n", " API query: []\n", " \n", " Example3\n", " assistant: 주문하실 메뉴가 있으신가요?\n", " user: 어떤 햄버거 메뉴가 잘나가요?\n", " API query: [메뉴추천, (햄버거)]\n", " \n", " Example4\n", " assistant: 불고기 버거 세트 하나 접수했습니다. 어떤 음료를 드릴까요?\n", " user: 콜라로 주세요\n", " API query: []\n", " \n", " Now, create an API query based on the below user saying in korean, which is delimited by triple backticks.\n", " If the user didn't say anything, return nothing.\n", " Question:\n", " assistant: {assistant}\n", " user: '''{user}'''\n", " API query: \n", " \"\"\"\n", " db_context = prompt\n", " messages = [{\"role\": \"user\", \"content\": prompt}]\n", " response = openai.ChatCompletion.create(\n", " model=model,\n", " messages=messages,\n", " temperature=temperature, \n", " stream=True\n", " )\n", " completion_text = ''\n", " start_time = time.time()\n", " for event in response:\n", " event_time = time.time() - start_time \n", " try:\n", " event_text = event['choices'][0]['delta']['content'] \n", " completion_text += event_text\n", "\n", " # Update the response_part parameter each time a new part of the response is received\n", " db_response_params.response_part = completion_text\n", " except:\n", " pass\n", " \n", " return completion_text\n", "\n", "def get_response_from_messages(user, system, act, model=\"gpt-4\", temperature=0):\n", " global act_context\n", " prompt = f\"\"\"\n", " Generate an appropriate response of assistant based on the behavior given by the system.\n", " Keep all answers short and in a friendly, conversational style.\n", " \n", " Below is 3 examples API query correspoding user saying.\n", " Example1:\n", " user:\n", " system: []\n", " assistant behavior: [환영, ()]\n", " assistant: 어서오세요. 맥도날드에 오신것을 환영합니다. 주문 도와드리겠습니다.\n", " \n", " Example2:\n", " user: 콜라주세요.\n", " system: []\n", " assistant behavior: [주문접수, (콜라)]\n", " assistant: 콜라 접수했습니다. 추가로 필요하신게 있으신가요?\n", " \n", " Example3:\n", " user: 더 필요한건 없습니다.\n", " system: []\n", " assistant behavior: [결제수단요청, (카드, 현금, 휴대폰)]\n", " assistant: 결제 도와드리겠습니다. 어떤 것으로 결제해드릴까요? 카드, 현금, 휴대폰이 있습니다.\n", " \n", " Example4:\n", " user: 불고기 버거 가격은 얼마인가요?\n", " system: [메뉴정보요청, (불고기버거, 가격)]\n", " assistant behavior: [메뉴정보제공, (불고기버거, 가격)]\n", " assistant: 불고기버거 가격은 3300원 입니다.\n", " \n", " Now, generate an appropriate response of assistant based on the below behavior, which is delimited by triple backticks.\n", " user: {user}\n", " system: {system}\n", " assistant behavior: '''{act}'''\n", " assistant: \n", " \"\"\"\n", " act_context = prompt\n", " messages = [{\"role\": \"user\", \"content\": prompt}]\n", " response = openai.ChatCompletion.create(\n", " model=model,\n", " messages=messages,\n", " temperature=temperature, \n", " stream=True\n", " )\n", " completion_text = ''\n", " start_time = time.time()\n", " for event in response:\n", " event_time = time.time() - start_time \n", " try:\n", " event_text = event['choices'][0]['delta']['content'] \n", " completion_text += event_text\n", "\n", " # Update the response_part parameter each time a new part of the response is received\n", " response_params.response_part = completion_text\n", " except:\n", " pass\n", " \n", " return completion_text\n", "db_context, act_context = '', ''\n", "db_assistant_act = pn.Row('db query:', pn.bind(lambda text: pn.pane.Markdown(text, width=600, styles={'background-color': '#F6F6F6'}), db_response_params.param.response_part))\n", "act_response_display = pn.Row('act query:', pn.bind(lambda text: pn.pane.Markdown(text, width=600, styles={'background-color': '#F6F6F6'}), act_response_params.param.response_part))\n", "response_display = pn.Row('Assistant:', pn.bind(lambda text: pn.pane.Markdown(text, width=600, styles={'background-color': '#F6F6F6'}), response_params.param.response_part))\n", "panels = [db_assistant_act, act_response_display, response_display]\n", "\n", "def collect_messages(_):\n", " global prompt, response\n", " prompt = inp.value_input\n", " inp.value = ''\n", " context.append({'role':'user', 'content':f\"{prompt}\"})\n", " db_response = get_db_response_from_messages(response, prompt)\n", " act_response = get_act_response_from_messages(context)\n", " response = get_response_from_messages(prompt, db_response, act_response, model=\"gpt-4\", temperature=0)\n", " context.append({'role':'assistant', 'content':f\"{response}\"})\n", " panels.append(\n", " pn.Row('User:', pn.pane.Markdown(prompt, width=600)))\n", " panels.append(\n", " pn.Row('Assistant:', pn.pane.Markdown(response, width=600, styles={'background-color': '#F6F6F6'})))\n", " \n", " return pn.Column(*panels)\n", "\n", "inp = pn.widgets.TextInput(value=\"안녕하세요\", placeholder='텍스트를 입력해주세요')\n", "button_conversation = pn.widgets.Button(name=\"Chat!\")\n", "\n", "interactive_conversation = pn.bind(collect_messages, button_conversation)\n", "\n", "dashboard = pn.Column(\n", " inp,\n", " pn.Row(button_conversation),\n", " pn.panel(interactive_conversation, height=3000),\n", ")\n", "\n", "dashboard" ] }, { "cell_type": "code", "execution_count": 181, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "\"\\n Follow the steps below to express the user's intention as a query.\\n\\n step1. Read the user's saying in korean, which is delimited by triple backticks, and predict the user's intent.\\n step2. Create an API query to provide information based on the user's intent.\\n\\n If there is no appropriate query, nothing is returned.\\n The query consists of (function, value). The value depends on the function.\\n Below is the list of query functions and correspoding values.\\n\\n List of query functions: [메뉴정보제공, 정보제공, 메뉴추천, 메뉴확인]\\n List of values corresponding the function: \\n 메뉴정보제공: [정보를 제공해야할 메뉴 리스트] \\n 정보제공:[정보를 제공할 항목 리스트]\\n 메뉴추천:[추천하는 메뉴 리스트]\\n \\n Below is 3 examples for help you\\n Example1\\n user: 빅맥 세트 하나 주세요\\n API query: []\\n \\n Example2\\n user: \\n API query: []\\n \\n Example3\\n user: 어떤 햄버거 메뉴가 잘나가요?\\n API query: [메뉴추천, (햄버거)]\\n \\n Now, create an API query based on the below user's saying, which is delimited by triple backticks.\\n Question:\\n user: ''''''\\n \"" ] }, "execution_count": 181, "metadata": {}, "output_type": "execute_result" } ], "source": [ "db_context" ] }, { "cell_type": "code", "execution_count": 179, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "\"\\n Follow the steps below to express the assistant's intention as a query.\\n\\n step1. Read the assistant's words in korean, which is delimited by triple backticks, and predict the user's intent.\\n step2. Create an API query based on the assistant's intent.\\n \\n If there is no appropriate query, nothing is returned.\\n The query consists of (function, value). The value depends on the function.\\n Below is the list of query functions and correspoding values.\\n\\n List of query functions: [메뉴정보제공, 정보제공, 메뉴추천, 메뉴확인, 환영]\\n List of value corresponding the function:\\n 메뉴정보제공: [정보를 제공해야할 메뉴 리스트] \\n 정보제공:[정보를 제공할 항목 리스트]\\n 메뉴추천:[추천하는 메뉴 리스트]\\n 메뉴확인:[주문한 메뉴 리스트]\\n 계산:[주문한 메뉴 리스트]\\n 환영: []\\n\\n Example1:\\n assistant: 넵, 알겠습니다. 일반 세트로 드릴까요? 라지 세트로 드릴까요?\\n API query: [메뉴확인, (빅맥세트)]\\n \\n Example2:\\n assistant: 안녕하세요! 주문하실 메뉴가 있으신가요?\\n API query: [환영, ()]\\n \\n Example3:\\n assistant: 물론이죠. 사이드 메뉴 중 인기 있는 것들은 맥너겟이 있습니다.\\n API query: [메뉴추천, (맥너겟)]\\n \\n Question:\\n assistant: '''빅맥 세트 하나 주문하겠습니다! 음료는 어떤 것으로 드릴까요?'''\\n \"" ] }, "execution_count": 179, "metadata": {}, "output_type": "execute_result" } ], "source": [ "act_context" ] }, { "cell_type": "code", "execution_count": 82, "metadata": {}, "outputs": [], "source": [ "a = {\n", " '메뉴': {\n", " '햄버거': [['더블 빅맥', 9000],\n", " ['빅맥 BLT', 7800],\n", " ['맥크리스피 디럭스 버거', 7600],\n", " ['맥클리스피 클래식 버거', 6700],\n", " ['트리플 치즈버거', 6600],\n", " ['슈비버거', 6600],\n", " ['슈슈버거', 5500],\n", " ['1955 버거', 7200],\n", " ['맥치킨', 4300],\n", " ['맥치킨 모짜렐라', 5800],\n", " ['빅맥', 6000],\n", " ['맥스파이시 상하이 버거', 6000],\n", " ['더블 불고기 버거', 5300],\n", " ['에그 불고기 버거', 4300],\n", " ['불고기 버거', 3600],\n", " ['베이컨 토마토 디럭스', 6600],\n", " ['더블 쿼터파운더 치즈', 8200],\n", " ['쿼터파운더 치즈', 6300],\n", " ['치즈버거', 3500],\n", " ['햄버거', 3300]],\n", " '스낵&사이드': [['맥윙 2조각', 4000],\n", " ['맥윙 4조각', 6700],\n", " ['맥윙 8조각', 12300],\n", " ['콤보 맥윙 2조각', 4800],\n", " ['콤보 맥윙 4조각', 7500],\n", " ['슈림프 스낵랩', 3100],\n", " ['코울슬로', 2700],\n", " ['골든 모짜렐라 치즈스틱 2조각', 3300],\n", " ['골든 모짜렐라 치즈스틱 4조각', 5000],\n", " ['맥너겟 4조각', 3300],\n", " ['상하이 치킨 스낵랩', 3500],\n", " ['후렌치 후라이', [2100, 2800, 3500]]],\n", " '디저트': [['오레오 맥플러리', 3700],\n", " ['딸기 선데이 아이스크림', 2800],\n", " ['초코 선데이 아이스크림', 2800],\n", " ['바닐라 선데이 아이스크림', 2800]],\n", " '해피밀': [['해피밀 맥너겟 4조각', 5500],\n", " ['해피밀 햄버거', 5500],\n", " ['해피밀 불고기버거', 5500]],\n", " '음료': [['자두 천도복숭아 칠러', [2900, 3700, 4700]],\n", " ['제주 한라봉 칠러', [2900, 3700, 4700]],\n", " ['바닐라 라떼', [4500, 5000]],\n", " ['아이스 바닐라 라떼', [4500, 5000]],\n", " ['코카콜라', [2400, 2900]],\n", " ['제로 콜라', [2400, 2900]],\n", " ['환타 오렌지', [2400, 2900]],\n", " ['스프라이트', [2400, 2900]],\n", " ['카페라떼', [4000, 4500]],\n", " ['카푸치노', [4000, 4500]],\n", " ['아메리카노', [3300, 3800]],\n", " ['드립커피', [2700, 3200]],\n", " ['아이스 드립커피', [2500, 3000]],\n", " ['아이스 아메리카노', [3300, 3800]],\n", " ['아이스 카페라떼', [4000, 4500]],\n", " ['딸기 쉐이크 미디움', 3500],\n", " ['초코 쉐이크 미디움', 3500],\n", " ['바닐라 쉐이크 미디움', 3500]]\n", " },\n", " '기타':{\n", " '화장실': '정문으로 나가 오른쪽 코너를 돌면 있다. 비밀번호는 1223*이다'\n", " '와이파이': '와이파이 이름은 맥도날드이고, 와이파이 비밀번호는 123456789*이다'\n", " }\n", "\n", "\n", "}" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "### Store Nemo ASR model to huggingface" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "beebc8f1fad84f53b17e9792b6225e63", "version_major": 2, "version_minor": 0 }, "text/plain": [ "VBox(children=(HTML(value='
is experimental, not ready for production and is not fully supported. Use at your own risk.\n" ] } ], "source": [ "import nemo.collections.asr as nemo_asr # use any domain's models !" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "MODEL_NAME = \"stt_kr_conformer_ctc_medium\"" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[NeMo I 2023-06-04 23:59:45 mixins:170] Tokenizer SentencePieceTokenizer initialized with 2048 tokens\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "[NeMo W 2023-06-04 23:59:47 modelPT:161] If you intend to do training or fine-tuning, please call the ModelPT.setup_training_data() method and provide a valid configuration file to setup the train data loader.\n", " Train config : \n", " manifest_filepath: /home/work/audrey3/dataset/train_manifest.json\n", " sample_rate: 16000\n", " batch_size: 16\n", " shuffle: true\n", " num_workers: 7\n", " pin_memory: true\n", " max_duration: 20.0\n", " min_duration: 0.1\n", " is_tarred: false\n", " tarred_audio_filepaths: null\n", " shuffle_n: 2048\n", " bucketing_strategy: synced_randomized\n", " bucketing_batch_size: null\n", " \n", "[NeMo W 2023-06-04 23:59:47 modelPT:168] If you intend to do validation, please call the ModelPT.setup_validation_data() or ModelPT.setup_multiple_validation_data() method and provide a valid configuration file to setup the validation data loader(s). \n", " Validation config : \n", " manifest_filepath: /home/work/audrey3/dataset/test_manifest.json\n", " sample_rate: 16000\n", " batch_size: 16\n", " shuffle: false\n", " use_start_end_token: false\n", " num_workers: 7\n", " pin_memory: true\n", " \n", "[NeMo W 2023-06-04 23:59:47 modelPT:174] Please call the ModelPT.setup_test_data() or ModelPT.setup_multiple_test_data() method and provide a valid configuration file to setup the test data loader(s).\n", " Test config : \n", " manifest_filepath: null\n", " sample_rate: 16000\n", " batch_size: 16\n", " shuffle: false\n", " use_start_end_token: false\n", " num_workers: 7\n", " pin_memory: true\n", " \n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "[NeMo I 2023-06-04 23:59:47 features:291] PADDING: 0\n", "[NeMo I 2023-06-04 23:59:53 save_restore_connector:249] Model EncDecCTCModelBPE was successfully restored from C:\\Users\\chois\\Desktop\\Audrey\\models\\ASR\\checkpoint\\stt_kr_conformer_ctc_medium.nemo.\n" ] } ], "source": [ "model = nemo_asr.models.EncDecCTCModelBPE.restore_from(\"C:/Users/chois/Desktop/Audrey/models/ASR/checkpoint/stt_kr_conformer_ctc_medium.nemo\", map_location='cpu')" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "from huggingface_hub import HfApi\n", "api = HfApi()\n", "username = api.whoami()['name']" ] }, { "cell_type": "code", "execution_count": 197, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Repository is possibly already created. Refer to error here - \n", "\n", " 409 Client Error: Conflict for url: https://huggingface.co/api/repos/create (Request ID: Root=1-647c9d4b-6a9e6fbc0ff71c083d83eb25)\n", "\n", "You already created this model repo\n" ] } ], "source": [ "try:\n", " api.create_repo(repo_id=MODEL_NAME)\n", " print(\"Successfully created repository !\")\n", "except Exception as e:\n", " print(\"Repository is possibly already created. Refer to error here - \\n\\n\", e)" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "from huggingface_hub import Repository" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "C:\\Users\\chois\\Desktop\\Audrey\\models\\ASR\\checkpoint\n" ] } ], "source": [ "%cd ../ASR/checkpoint" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "C:\\Users\\chois\\Desktop\\Audrey\\models\\ASR\\checkpoint\\model-stt_kr_conformer_ctc_medium/ is already a clone of https://huggingface.co/SungBeom/stt_kr_conformer_ctc_medium. Make sure you pull the latest changes with `repo.git_pull()`.\n", "Pulling changes ...\n", "Several commits (2) will be pushed upstream.\n", "The progress bars may be unreliable.\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "63d6f6e97def4946a5790ac879da03f4", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Upload file model-stt_kr_conformer_ctc_medium/stt_kr_conformer_ctc_medium.nemo: 0%| | 1.00/468M [00…" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stderr", "output_type": "stream", "text": [ "To https://huggingface.co/SungBeom/stt_kr_conformer_ctc_medium\n", " 4b06449..197080a main -> main\n", "\n" ] } ], "source": [ "local_dir = f'model-{MODEL_NAME}/'\n", "hf_model_name = f'{username}/{MODEL_NAME}'\n", "\n", "commit_message = \"Upload model\"\n", "model_filename = f'{MODEL_NAME}.nemo'\n", "\n", "with Repository(local_dir=local_dir, clone_from=hf_model_name, repo_type='model').commit(commit_message):\n", " model.save_to(local_dir+model_filename)" ] } ], "metadata": { "kernelspec": { "display_name": "nemo", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.10" } }, "nbformat": 4, "nbformat_minor": 2 }