PageSourceSearch

https://vllm-sr.ai/assets/js/06806960.3489ea2d.js

js vllm-sr.ai collected 2026-10-04 01:30:55 UTC 11,222 bytes, 1 lines download raw bytes

1"use strict";(self.webpackChunksemantic_router_docs=self.webpackChunksemantic_router_docs||[]).push([[3524],{5145(e,n,s){s.r(n),s.d(n,{assets:()=>d,contentTitle:()=>l,default:()=>h,frontMatter:()=>i,metadata:()=>t,toc:()=>a});const t=JSON.parse('{"id":"tutorials/intelligent-route/router-memory","title":"Multi Turn Conversations","description":"Router Memory enables stateful conversations via the OpenAI Response API, supporting conversation chaining with previousresponseid.","source":"@site/versioned_docs/version-v0.2/tutorials/intelligent-route/router-memory.md","sourceDirName":"tutorials/intelligent-route","slug":"/tutorials/intelligent-route/router-memory","permalink":"/docs/v0.2/tutorials/intelligent-route/router-memory","draft":false,"unlisted":false,"editUrl":"https://github.com/vllm-project/semantic-router/edit/main/website/docs/tutorials/intelligent-route/router-memory.md","tags":[],"version":"v0.2","frontMatter":{},"sidebar":"tutorialSidebar","previous":{"title":"Intelligent LoRA Routing","permalink":"/docs/v0.2/tutorials/intelligent-route/lora-routing"},"next":{"title":"Model Selection Overview","permalink":"/docs/v0.2/tutorials/intelligent-route/model-selection/overview"}}');var r=s(74848),o=s(28453);const i={},l="Multi Turn Conversations",d={},a=[{value:"Overview",id:"overview",level:2},{value:"Request Flow",id:"request-flow",level:2},{value:"Endpoints",id:"endpoints",level:2},{value:"Configuration",id:"configuration",level:2},{value:"Usage",id:"usage",level:2},{value:"1. Create Response",id:"1-create-response",level:3},{value:"2. Continue Conversation",id:"2-continue-conversation",level:3},{value:"3. Get Response",id:"3-get-response",level:3},{value:"4. List Input Items",id:"4-list-input-items",level:3},{value:"5. Delete Response",id:"5-delete-response",level:3},{value:"API Translation",id:"api-translation",level:2},{value:"Reference",id:"reference",level:2}];function c(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",mermaid:"mermaid",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"multi-turn-conversations",children:"Multi Turn Conversations"})}),"\n",(0,r.jsxs)(n.p,{children:["Router Memory enables stateful conversations via the ",(0,r.jsx)(n.a,{href:"https://platform.openai.com/docs/api-reference/responses",children:"OpenAI Response API"}),", supporting conversation chaining with ",(0,r.jsx)(n.code,{children:"previous_response_id"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"overview",children:"Overview"}),"\n",(0,r.jsxs)(n.p,{children:["Semantic Router acts as the ",(0,r.jsx)(n.strong,{children:"unified brain"})," for multiple LLM backends that only support the Chat Completions API. It provides:"]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Cross-Model Stateful Conversations"}),": Maintain conversation history across different models"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Unified Response API"}),": Single API interface regardless of backend model"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Transparent Translation"}),": Automatic conversion between Response API and Chat Completions"]}),"\n"]}),"\n",(0,r.jsx)(n.mermaid,{value:'flowchart TB\n    subgraph Clients\n        C1[Agent A]\n        C2[Agent B]\n    end\n\n    subgraph SR["Semantic Router"]\n        API[Response API]\n        Store[(Conversation<br/>Store)]\n    end\n\n    subgraph Backends["LLM Backends (Chat Completions Only)"]\n        M1[GPT-4o]\n        M2[Claude]\n        M3[Qwen]\n        M4[Llama]\n    end\n\n    C1 & C2 --\x3e API\n    API <--\x3e Store\n    API --\x3e M1 & M2 & M3 & M4'}),"\n",(0,r.jsx)(n.p,{children:"With Router Memory, you can start a conversation with one model and continue it with another\u2014the conversation history is preserved in the router, not in any single backend."}),"\n",(0,r.jsx)(n.h2,{id:"request-flow",children:"Request Flow"}),"\n",(0,r.jsx)(n.mermaid,{value:'flowchart TB\n    subgraph Client\n        A1[POST /v1/responses]\n    end\n\n    subgraph Router["Semantic Router (extproc)"]\n        B1[Receive Request]\n        B2{Has previous_response_id?}\n        B3[Load Conversation Chain]\n        B4[Translate to Chat Completions]\n        B5[Translate to Response API]\n        B6[Store Response]\n    end\n\n    subgraph Store["Response Store"]\n        C1[(Memory)]\n    end\n\n    subgraph Backend["Backend LLM"]\n        D1[POST /v1/chat/completions]\n    end\n\n    A1 --\x3e B1\n    B1 --\x3e B2\n    B2 --\x3e|Yes| B3\n    B2 --\x3e|No| B4\n    B3 --\x3e C1\n    C1 --\x3e B4\n    B4 --\x3e D1\n    D1 --\x3e B5\n    B5 --\x3e B6\n    B6 --\x3e C1\n    B6 --\x3e A1'}),"\n",(0,r.jsx)(n.h2,{id:"endpoints",children:"Endpoints"}),"\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Endpoint"}),(0,r.jsx)(n.th,{children:"Method"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"/v1/responses"})}),(0,r.jsx)(n.td,{children:"POST"}),(0,r.jsx)(n.td,{children:"Create a new response"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"/v1/responses/{id}"})}),(0,r.jsx)(n.td,{children:"GET"}),(0,r.jsx)(n.td,{children:"Retrieve a stored response"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"/v1/responses/{id}"})}),(0,r.jsx)(n.td,{children:"DELETE"}),(0,r.jsx)(n.td,{children:"Delete a stored response"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"/v1/responses/{id}/input_items"})}),(0,r.jsx)(n.td,{children:"GET"}),(0,r.jsx)(n.td,{children:"List input items for a response"})]})]})]}),"\n",(0,r.jsx)(n.h2,{id:"configuration",children:"Configuration"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:'response_api:\n  enabled: true\n  store_backend: "memory"   # Currently only "memory" is supported\n  ttl_seconds: 86400        # Default: 30 days\n  max_responses: 1000\n'})}),"\n",(0,r.jsx)(n.h2,{id:"usage",children:"Usage"}),"\n",(0,r.jsx)(n.h3,{id:"1-create-response",children:"1. Create Response"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:'curl -X POST http://localhost:8801/v1/responses \\\n  -H "Content-Type: application/json" \\\n  -d \'{\n    "model": "openai/gpt-oss-120b",\n    "input": "Tell me a joke.",\n    "instructions": "Remember my name is Xunzhuo. Then I will ask you!",\n    "temperature": 0.7,\n    "max_output_tokens": 100\n  }\'\n'})}),"\n",(0,r.jsx)(n.p,{children:"Response:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-json",children:'{\n  "id": "resp_7cb437001e1ad5b84b6dd8ef",\n  "object": "response",\n  "status": "completed",\n  "output": [{\n    "type": "message",\n    "role": "assistant",\n    "content": [{"type": "output_text", "text": "Sure thing, Xunzhuo! Why don\'t scientists trust atoms? Because they make up everything! \ud83d\ude04"}]\n  }
1],\n  "usage": {"input_tokens": 94, "output_tokens": 75, "total_tokens": 169}\n}\n'})}),"\n",(0,r.jsx)(n.h3,{id:"2-continue-conversation",children:"2. Continue Conversation"}),"\n",(0,r.jsxs)(n.p,{children:["Use ",(0,r.jsx)(n.code,{children:"previous_response_id"})," to chain conversations:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:'curl -X POST http://localhost:8801/v1/responses \\\n  -H "Content-Type: application/json" \\\n  -d \'{\n    "model": "openai/gpt-oss-120b",\n    "input": "What is my name?",\n    "previous_response_id": "resp_7cb437001e1ad5b84b6dd8ef",\n    "max_output_tokens": 100\n  }\'\n'})}),"\n",(0,r.jsx)(n.p,{children:"Response:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-json",children:'{\n  "id": "resp_ec2822df62e390dcb87aa61d",\n  "status": "completed",\n  "output": [{\n    "type": "message",\n    "role": "assistant",\n    "content": [{"type": "output_text", "text": "Your name is Xunzhuo."}]\n  }],\n  "previous_response_id": "resp_7cb437001e1ad5b84b6dd8ef"\n}\n'})}),"\n",(0,r.jsx)(n.h3,{id:"3-get-response",children:"3. Get Response"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"curl http://localhost:8801/v1/responses/resp_7cb437001e1ad5b84b6dd8ef\n"})}),"\n",(0,r.jsx)(n.h3,{id:"4-list-input-items",children:"4. List Input Items"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"curl http://localhost:8801/v1/responses/resp_7cb437001e1ad5b84b6dd8ef/input_items\n"})}),"\n",(0,r.jsx)(n.p,{children:"Response:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-json",children:'{\n  "object": "list",\n  "data": [{\n    "type": "message",\n    "role": "system",\n    "content": [{"type": "input_text", "text": "Remember my name is Xunzhuo."}]\n  }],\n  "has_more": false\n}\n'})}),"\n",(0,r.jsx)(n.h3,{id:"5-delete-response",children:"5. Delete Response"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"curl -X DELETE http://localhost:8801/v1/responses/resp_7cb437001e1ad5b84b6dd8ef\n"})}),"\n",(0,r.jsx)(n.h2,{id:"api-translation",children:"API Translation"}),"\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Response API"}
1),(0,r.jsx)(n.th,{children:"Chat Completions"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"input"})}),(0,r.jsxs)(n.td,{children:[(0,r.jsx)(n.code,{children:"messages[].content"})," (role: user)"]})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"instructions"})}),(0,r.jsxs)(n.td,{children:[(0,r.jsx)(n.code,{children:"messages[0]"})," (role: system)"]})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"previous_response_id"})}),(0,r.jsxs)(n.td,{children:["Expanded to full ",(0,r.jsx)(n.code,{children:"messages"})," array"]})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"max_output_tokens"})}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"max_tokens"})})]})]})]}),"\n",(0,r.jsx)(n.h2,{id:"reference",children:"Reference"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"https://platform.openai.com/docs/api-reference/responses",children:"OpenAI Response API"})}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(c,{...e})}):c(e)}},28453(e,n,s){s.d(n,{R:()=>i,x:()=>l});var t=s(96540);const r={},o=t.createContext(r);function i(e){const n=t.useContext(o);return t.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),t.createElement(o.Provider,{value:n},e.children)}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.