routes.go 34 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432
  1. package server
  2. import (
  3. "context"
  4. "encoding/json"
  5. "errors"
  6. "fmt"
  7. "io"
  8. "io/fs"
  9. "log/slog"
  10. "math"
  11. "net"
  12. "net/http"
  13. "net/netip"
  14. "os"
  15. "os/signal"
  16. "path/filepath"
  17. "reflect"
  18. "runtime"
  19. "strconv"
  20. "strings"
  21. "sync"
  22. "syscall"
  23. "time"
  24. "github.com/gin-contrib/cors"
  25. "github.com/gin-gonic/gin"
  26. "golang.org/x/exp/slices"
  27. "github.com/ollama/ollama/api"
  28. "github.com/ollama/ollama/gpu"
  29. "github.com/ollama/ollama/llm"
  30. "github.com/ollama/ollama/openai"
  31. "github.com/ollama/ollama/parser"
  32. "github.com/ollama/ollama/version"
  33. )
  34. var mode string = gin.DebugMode
  35. type Server struct {
  36. addr net.Addr
  37. }
  38. func init() {
  39. switch mode {
  40. case gin.DebugMode:
  41. case gin.ReleaseMode:
  42. case gin.TestMode:
  43. default:
  44. mode = gin.DebugMode
  45. }
  46. gin.SetMode(mode)
  47. }
  48. var loaded struct {
  49. mu sync.Mutex
  50. llama *llm.LlamaServer
  51. expireTimer *time.Timer
  52. model string
  53. adapters []string
  54. projectors []string
  55. *api.Options
  56. }
  57. var defaultSessionDuration = 5 * time.Minute
  58. func unload() {
  59. if loaded.llama != nil {
  60. loaded.llama.Close()
  61. }
  62. loaded.llama = nil
  63. loaded.model = ""
  64. loaded.adapters = nil
  65. loaded.projectors = nil
  66. loaded.Options = nil
  67. }
  68. // load a model into memory if it is not already loaded, it is up to the caller to lock loaded.mu before calling this function
  69. func load(c *gin.Context, model *Model, opts api.Options, sessionDuration time.Duration) error {
  70. ctx, cancel := context.WithTimeout(c, 10*time.Second)
  71. defer cancel()
  72. needLoad := loaded.llama == nil || // is there a model loaded?
  73. loaded.model != model.ModelPath || // has the base model changed?
  74. !reflect.DeepEqual(loaded.adapters, model.AdapterPaths) || // have the adapters changed?
  75. !reflect.DeepEqual(loaded.projectors, model.ProjectorPaths) || // have the adapters changed?
  76. !reflect.DeepEqual(loaded.Options.Runner, opts.Runner) || // have the runner options changed?
  77. loaded.llama.Ping(ctx) != nil
  78. if needLoad {
  79. if loaded.llama != nil {
  80. slog.Info("changing loaded model")
  81. unload()
  82. }
  83. llama, err := llm.NewLlamaServer(model.ModelPath, model.AdapterPaths, model.ProjectorPaths, opts)
  84. if err != nil {
  85. // some older models are not compatible with newer versions of llama.cpp
  86. // show a generalized compatibility error until there is a better way to
  87. // check for model compatibility
  88. if errors.Is(llm.ErrUnsupportedFormat, err) || strings.Contains(err.Error(), "failed to load model") {
  89. err = fmt.Errorf("%v: this model may be incompatible with your version of Ollama. If you previously pulled this model, try updating it by running `ollama pull %s`", err, model.ShortName)
  90. }
  91. return err
  92. }
  93. loaded.model = model.ModelPath
  94. loaded.adapters = model.AdapterPaths
  95. loaded.projectors = model.ProjectorPaths
  96. loaded.llama = llama
  97. loaded.Options = &opts
  98. if err = llama.WaitUntilRunning(); err != nil {
  99. slog.Error("error loading llama server", "error", err)
  100. unload()
  101. return err
  102. }
  103. }
  104. if loaded.expireTimer == nil {
  105. loaded.expireTimer = time.AfterFunc(sessionDuration, func() {
  106. loaded.mu.Lock()
  107. defer loaded.mu.Unlock()
  108. unload()
  109. })
  110. }
  111. loaded.expireTimer.Reset(sessionDuration)
  112. return nil
  113. }
  114. func modelOptions(model *Model, requestOpts map[string]interface{}) (api.Options, error) {
  115. opts := api.DefaultOptions()
  116. if err := opts.FromMap(model.Options); err != nil {
  117. return api.Options{}, err
  118. }
  119. if err := opts.FromMap(requestOpts); err != nil {
  120. return api.Options{}, err
  121. }
  122. return opts, nil
  123. }
  124. func isSupportedImageType(image []byte) bool {
  125. contentType := http.DetectContentType(image)
  126. allowedTypes := []string{"image/jpeg", "image/jpg", "image/png"}
  127. return slices.Contains(allowedTypes, contentType)
  128. }
  129. func GenerateHandler(c *gin.Context) {
  130. loaded.mu.Lock()
  131. defer loaded.mu.Unlock()
  132. checkpointStart := time.Now()
  133. var req api.GenerateRequest
  134. err := c.ShouldBindJSON(&req)
  135. switch {
  136. case errors.Is(err, io.EOF):
  137. c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "missing request body"})
  138. return
  139. case err != nil:
  140. c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": err.Error()})
  141. return
  142. }
  143. // validate the request
  144. switch {
  145. case req.Model == "":
  146. c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "model is required"})
  147. return
  148. case len(req.Format) > 0 && req.Format != "json":
  149. c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "format must be json"})
  150. return
  151. case req.Raw && (req.Template != "" || req.System != "" || len(req.Context) > 0):
  152. c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "raw mode does not support template, system, or context"})
  153. return
  154. }
  155. for _, img := range req.Images {
  156. if !isSupportedImageType(img) {
  157. c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "unsupported image format"})
  158. return
  159. }
  160. }
  161. model, err := GetModel(req.Model)
  162. if err != nil {
  163. var pErr *fs.PathError
  164. if errors.As(err, &pErr) {
  165. c.JSON(http.StatusNotFound, gin.H{"error": fmt.Sprintf("model '%s' not found, try pulling it first", req.Model)})
  166. return
  167. }
  168. c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
  169. return
  170. }
  171. if model.IsEmbedding() {
  172. c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "embedding models do not support generate"})
  173. return
  174. }
  175. opts, err := modelOptions(model, req.Options)
  176. if err != nil {
  177. if errors.Is(err, api.ErrInvalidOpts) {
  178. c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
  179. return
  180. }
  181. c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
  182. return
  183. }
  184. var sessionDuration time.Duration
  185. if req.KeepAlive == nil {
  186. sessionDuration = getDefaultSessionDuration()
  187. } else {
  188. sessionDuration = req.KeepAlive.Duration
  189. }
  190. if err := load(c, model, opts, sessionDuration); err != nil {
  191. c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
  192. return
  193. }
  194. // an empty request loads the model
  195. // note: for a short while template was used in lieu
  196. // of `raw` mode so we need to check for it too
  197. if req.Prompt == "" && req.Template == "" && req.System == "" {
  198. c.JSON(http.StatusOK, api.GenerateResponse{
  199. CreatedAt: time.Now().UTC(),
  200. Model: req.Model,
  201. Done: true,
  202. DoneReason: "load",
  203. })
  204. return
  205. }
  206. checkpointLoaded := time.Now()
  207. var prompt string
  208. switch {
  209. case req.Raw:
  210. prompt = req.Prompt
  211. case req.Prompt != "":
  212. if req.Template == "" {
  213. req.Template = model.Template
  214. }
  215. if req.System == "" {
  216. req.System = model.System
  217. }
  218. slog.Debug("generate handler", "prompt", req.Prompt)
  219. slog.Debug("generate handler", "template", req.Template)
  220. slog.Debug("generate handler", "system", req.System)
  221. var sb strings.Builder
  222. for i := range req.Images {
  223. fmt.Fprintf(&sb, "[img-%d] ", i)
  224. }
  225. sb.WriteString(req.Prompt)
  226. p, err := Prompt(req.Template, req.System, sb.String(), "", true)
  227. if err != nil {
  228. c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
  229. return
  230. }
  231. sb.Reset()
  232. if req.Context != nil {
  233. prev, err := loaded.llama.Detokenize(c.Request.Context(), req.Context)
  234. if err != nil {
  235. c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
  236. return
  237. }
  238. sb.WriteString(prev)
  239. }
  240. sb.WriteString(p)
  241. prompt = sb.String()
  242. }
  243. tokens, err := loaded.llama.Tokenize(c.Request.Context(), prompt)
  244. if err != nil {
  245. c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
  246. return
  247. }
  248. opts.NumPredict = max(opts.NumCtx-len(tokens), 0)
  249. slog.Debug("generate handler", "prompt", prompt)
  250. ch := make(chan any)
  251. var generated strings.Builder
  252. go func() {
  253. defer close(ch)
  254. fn := func(r llm.CompletionResponse) {
  255. // Update model expiration
  256. loaded.expireTimer.Reset(sessionDuration)
  257. // Build up the full response
  258. if _, err := generated.WriteString(r.Content); err != nil {
  259. ch <- gin.H{"error": err.Error()}
  260. return
  261. }
  262. resp := api.GenerateResponse{
  263. Model: req.Model,
  264. CreatedAt: time.Now().UTC(),
  265. Done: r.Done,
  266. DoneReason: r.DoneReason,
  267. Response: r.Content,
  268. Metrics: api.Metrics{
  269. PromptEvalCount: r.PromptEvalCount,
  270. PromptEvalDuration: r.PromptEvalDuration,
  271. EvalCount: r.EvalCount,
  272. EvalDuration: r.EvalDuration,
  273. },
  274. }
  275. if r.Done {
  276. resp.TotalDuration = time.Since(checkpointStart)
  277. resp.LoadDuration = checkpointLoaded.Sub(checkpointStart)
  278. if !req.Raw {
  279. p, err := Prompt(req.Template, req.System, req.Prompt, generated.String(), false)
  280. if err != nil {
  281. c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
  282. return
  283. }
  284. // TODO (jmorganca): encode() should not strip special tokens
  285. tokens, err := loaded.llama.Tokenize(c.Request.Context(), p)
  286. if err != nil {
  287. ch <- gin.H{"error": err.Error()}
  288. return
  289. }
  290. resp.Context = append(req.Context, tokens...)
  291. }
  292. }
  293. ch <- resp
  294. }
  295. var images []llm.ImageData
  296. for i := range req.Images {
  297. images = append(images, llm.ImageData{
  298. ID: i,
  299. Data: req.Images[i],
  300. })
  301. }
  302. // Start prediction
  303. req := llm.CompletionRequest{
  304. Prompt: prompt,
  305. Format: req.Format,
  306. Images: images,
  307. Options: opts,
  308. }
  309. if err := loaded.llama.Completion(c.Request.Context(), req, fn); err != nil {
  310. ch <- gin.H{"error": err.Error()}
  311. }
  312. }()
  313. if req.Stream != nil && !*req.Stream {
  314. // Accumulate responses into the final response
  315. var final api.GenerateResponse
  316. var sb strings.Builder
  317. for resp := range ch {
  318. switch r := resp.(type) {
  319. case api.GenerateResponse:
  320. sb.WriteString(r.Response)
  321. final = r
  322. case gin.H:
  323. if errorMsg, ok := r["error"].(string); ok {
  324. c.JSON(http.StatusInternalServerError, gin.H{"error": errorMsg})
  325. return
  326. } else {
  327. c.JSON(http.StatusInternalServerError, gin.H{"error": "unexpected error format in response"})
  328. return
  329. }
  330. default:
  331. c.JSON(http.StatusInternalServerError, gin.H{"error": "unexpected error"})
  332. return
  333. }
  334. }
  335. final.Response = sb.String()
  336. c.JSON(http.StatusOK, final)
  337. return
  338. }
  339. streamResponse(c, ch)
  340. }
  341. func getDefaultSessionDuration() time.Duration {
  342. if t, exists := os.LookupEnv("OLLAMA_KEEP_ALIVE"); exists {
  343. v, err := strconv.Atoi(t)
  344. if err != nil {
  345. d, err := time.ParseDuration(t)
  346. if err != nil {
  347. return defaultSessionDuration
  348. }
  349. if d < 0 {
  350. return time.Duration(math.MaxInt64)
  351. }
  352. return d
  353. }
  354. d := time.Duration(v) * time.Second
  355. if d < 0 {
  356. return time.Duration(math.MaxInt64)
  357. }
  358. return d
  359. }
  360. return defaultSessionDuration
  361. }
  362. func EmbeddingsHandler(c *gin.Context) {
  363. loaded.mu.Lock()
  364. defer loaded.mu.Unlock()
  365. var req api.EmbeddingRequest
  366. err := c.ShouldBindJSON(&req)
  367. switch {
  368. case errors.Is(err, io.EOF):
  369. c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "missing request body"})
  370. return
  371. case err != nil:
  372. c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": err.Error()})
  373. return
  374. }
  375. if req.Model == "" {
  376. c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "model is required"})
  377. return
  378. }
  379. model, err := GetModel(req.Model)
  380. if err != nil {
  381. var pErr *fs.PathError
  382. if errors.As(err, &pErr) {
  383. c.JSON(http.StatusNotFound, gin.H{"error": fmt.Sprintf("model '%s' not found, try pulling it first", req.Model)})
  384. return
  385. }
  386. c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
  387. return
  388. }
  389. opts, err := modelOptions(model, req.Options)
  390. if err != nil {
  391. if errors.Is(err, api.ErrInvalidOpts) {
  392. c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
  393. return
  394. }
  395. c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
  396. return
  397. }
  398. var sessionDuration time.Duration
  399. if req.KeepAlive == nil {
  400. sessionDuration = getDefaultSessionDuration()
  401. } else {
  402. sessionDuration = req.KeepAlive.Duration
  403. }
  404. if err := load(c, model, opts, sessionDuration); err != nil {
  405. c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
  406. return
  407. }
  408. // an empty request loads the model
  409. if req.Prompt == "" {
  410. c.JSON(http.StatusOK, api.EmbeddingResponse{Embedding: []float64{}})
  411. return
  412. }
  413. embedding, err := loaded.llama.Embedding(c.Request.Context(), req.Prompt)
  414. if err != nil {
  415. slog.Info(fmt.Sprintf("embedding generation failed: %v", err))
  416. c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to generate embedding"})
  417. return
  418. }
  419. resp := api.EmbeddingResponse{
  420. Embedding: embedding,
  421. }
  422. c.JSON(http.StatusOK, resp)
  423. }
  424. func PullModelHandler(c *gin.Context) {
  425. var req api.PullRequest
  426. err := c.ShouldBindJSON(&req)
  427. switch {
  428. case errors.Is(err, io.EOF):
  429. c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "missing request body"})
  430. return
  431. case err != nil:
  432. c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": err.Error()})
  433. return
  434. }
  435. var model string
  436. if req.Model != "" {
  437. model = req.Model
  438. } else if req.Name != "" {
  439. model = req.Name
  440. } else {
  441. c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "model is required"})
  442. return
  443. }
  444. ch := make(chan any)
  445. go func() {
  446. defer close(ch)
  447. fn := func(r api.ProgressResponse) {
  448. ch <- r
  449. }
  450. regOpts := &registryOptions{
  451. Insecure: req.Insecure,
  452. }
  453. ctx, cancel := context.WithCancel(c.Request.Context())
  454. defer cancel()
  455. if err := PullModel(ctx, model, regOpts, fn); err != nil {
  456. ch <- gin.H{"error": err.Error()}
  457. }
  458. }()
  459. if req.Stream != nil && !*req.Stream {
  460. waitForStream(c, ch)
  461. return
  462. }
  463. streamResponse(c, ch)
  464. }
  465. func PushModelHandler(c *gin.Context) {
  466. var req api.PushRequest
  467. err := c.ShouldBindJSON(&req)
  468. switch {
  469. case errors.Is(err, io.EOF):
  470. c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "missing request body"})
  471. return
  472. case err != nil:
  473. c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": err.Error()})
  474. return
  475. }
  476. var model string
  477. if req.Model != "" {
  478. model = req.Model
  479. } else if req.Name != "" {
  480. model = req.Name
  481. } else {
  482. c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "model is required"})
  483. return
  484. }
  485. ch := make(chan any)
  486. go func() {
  487. defer close(ch)
  488. fn := func(r api.ProgressResponse) {
  489. ch <- r
  490. }
  491. regOpts := &registryOptions{
  492. Insecure: req.Insecure,
  493. }
  494. ctx, cancel := context.WithCancel(c.Request.Context())
  495. defer cancel()
  496. if err := PushModel(ctx, model, regOpts, fn); err != nil {
  497. ch <- gin.H{"error": err.Error()}
  498. }
  499. }()
  500. if req.Stream != nil && !*req.Stream {
  501. waitForStream(c, ch)
  502. return
  503. }
  504. streamResponse(c, ch)
  505. }
  506. func CreateModelHandler(c *gin.Context) {
  507. var req api.CreateRequest
  508. err := c.ShouldBindJSON(&req)
  509. switch {
  510. case errors.Is(err, io.EOF):
  511. c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "missing request body"})
  512. return
  513. case err != nil:
  514. c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": err.Error()})
  515. return
  516. }
  517. var model string
  518. if req.Model != "" {
  519. model = req.Model
  520. } else if req.Name != "" {
  521. model = req.Name
  522. } else {
  523. c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "model is required"})
  524. return
  525. }
  526. if err := ParseModelPath(model).Validate(); err != nil {
  527. c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": err.Error()})
  528. return
  529. }
  530. if req.Path == "" && req.Modelfile == "" {
  531. c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "path or modelfile are required"})
  532. return
  533. }
  534. var modelfile io.Reader = strings.NewReader(req.Modelfile)
  535. if req.Path != "" && req.Modelfile == "" {
  536. mf, err := os.Open(req.Path)
  537. if err != nil {
  538. c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": fmt.Sprintf("error reading modelfile: %s", err)})
  539. return
  540. }
  541. defer mf.Close()
  542. modelfile = mf
  543. }
  544. commands, err := parser.Parse(modelfile)
  545. if err != nil {
  546. c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": err.Error()})
  547. return
  548. }
  549. ch := make(chan any)
  550. go func() {
  551. defer close(ch)
  552. fn := func(resp api.ProgressResponse) {
  553. ch <- resp
  554. }
  555. ctx, cancel := context.WithCancel(c.Request.Context())
  556. defer cancel()
  557. if err := CreateModel(ctx, model, filepath.Dir(req.Path), req.Quantization, commands, fn); err != nil {
  558. ch <- gin.H{"error": err.Error()}
  559. }
  560. }()
  561. if req.Stream != nil && !*req.Stream {
  562. waitForStream(c, ch)
  563. return
  564. }
  565. streamResponse(c, ch)
  566. }
  567. func DeleteModelHandler(c *gin.Context) {
  568. var req api.DeleteRequest
  569. err := c.ShouldBindJSON(&req)
  570. switch {
  571. case errors.Is(err, io.EOF):
  572. c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "missing request body"})
  573. return
  574. case err != nil:
  575. c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": err.Error()})
  576. return
  577. }
  578. var model string
  579. if req.Model != "" {
  580. model = req.Model
  581. } else if req.Name != "" {
  582. model = req.Name
  583. } else {
  584. c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "model is required"})
  585. return
  586. }
  587. if err := DeleteModel(model); err != nil {
  588. if os.IsNotExist(err) {
  589. c.JSON(http.StatusNotFound, gin.H{"error": fmt.Sprintf("model '%s' not found", model)})
  590. } else {
  591. c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
  592. }
  593. return
  594. }
  595. manifestsPath, err := GetManifestPath()
  596. if err != nil {
  597. c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
  598. return
  599. }
  600. if err := PruneDirectory(manifestsPath); err != nil {
  601. c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
  602. return
  603. }
  604. c.JSON(http.StatusOK, nil)
  605. }
  606. func ShowModelHandler(c *gin.Context) {
  607. var req api.ShowRequest
  608. err := c.ShouldBindJSON(&req)
  609. switch {
  610. case errors.Is(err, io.EOF):
  611. c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "missing request body"})
  612. return
  613. case err != nil:
  614. c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": err.Error()})
  615. return
  616. }
  617. if req.Model != "" {
  618. // noop
  619. } else if req.Name != "" {
  620. req.Model = req.Name
  621. } else {
  622. c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "model is required"})
  623. return
  624. }
  625. resp, err := GetModelInfo(req)
  626. if err != nil {
  627. if os.IsNotExist(err) {
  628. c.JSON(http.StatusNotFound, gin.H{"error": fmt.Sprintf("model '%s' not found", req.Model)})
  629. } else {
  630. c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
  631. }
  632. return
  633. }
  634. c.JSON(http.StatusOK, resp)
  635. }
  636. func GetModelInfo(req api.ShowRequest) (*api.ShowResponse, error) {
  637. model, err := GetModel(req.Model)
  638. if err != nil {
  639. return nil, err
  640. }
  641. modelDetails := api.ModelDetails{
  642. ParentModel: model.ParentModel,
  643. Format: model.Config.ModelFormat,
  644. Family: model.Config.ModelFamily,
  645. Families: model.Config.ModelFamilies,
  646. ParameterSize: model.Config.ModelType,
  647. QuantizationLevel: model.Config.FileType,
  648. }
  649. if req.System != "" {
  650. model.System = req.System
  651. }
  652. if req.Template != "" {
  653. model.Template = req.Template
  654. }
  655. msgs := make([]api.Message, 0)
  656. for _, msg := range model.Messages {
  657. msgs = append(msgs, api.Message{Role: msg.Role, Content: msg.Content})
  658. }
  659. resp := &api.ShowResponse{
  660. License: strings.Join(model.License, "\n"),
  661. System: model.System,
  662. Template: model.Template,
  663. Details: modelDetails,
  664. Messages: msgs,
  665. }
  666. var params []string
  667. cs := 30
  668. for k, v := range model.Options {
  669. switch val := v.(type) {
  670. case []interface{}:
  671. for _, nv := range val {
  672. params = append(params, fmt.Sprintf("%-*s %#v", cs, k, nv))
  673. }
  674. default:
  675. params = append(params, fmt.Sprintf("%-*s %#v", cs, k, v))
  676. }
  677. }
  678. resp.Parameters = strings.Join(params, "\n")
  679. for k, v := range req.Options {
  680. if _, ok := req.Options[k]; ok {
  681. model.Options[k] = v
  682. }
  683. }
  684. mf, err := ShowModelfile(model)
  685. if err != nil {
  686. return nil, err
  687. }
  688. resp.Modelfile = mf
  689. return resp, nil
  690. }
  691. func ListModelsHandler(c *gin.Context) {
  692. models := make([]api.ModelResponse, 0)
  693. manifestsPath, err := GetManifestPath()
  694. if err != nil {
  695. c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
  696. return
  697. }
  698. modelResponse := func(modelName string) (api.ModelResponse, error) {
  699. model, err := GetModel(modelName)
  700. if err != nil {
  701. return api.ModelResponse{}, err
  702. }
  703. modelDetails := api.ModelDetails{
  704. Format: model.Config.ModelFormat,
  705. Family: model.Config.ModelFamily,
  706. Families: model.Config.ModelFamilies,
  707. ParameterSize: model.Config.ModelType,
  708. QuantizationLevel: model.Config.FileType,
  709. }
  710. return api.ModelResponse{
  711. Model: model.ShortName,
  712. Name: model.ShortName,
  713. Size: model.Size,
  714. Digest: model.Digest,
  715. Details: modelDetails,
  716. }, nil
  717. }
  718. walkFunc := func(path string, info os.FileInfo, _ error) error {
  719. if !info.IsDir() {
  720. path, tag := filepath.Split(path)
  721. model := strings.Trim(strings.TrimPrefix(path, manifestsPath), string(os.PathSeparator))
  722. modelPath := strings.Join([]string{model, tag}, ":")
  723. canonicalModelPath := strings.ReplaceAll(modelPath, string(os.PathSeparator), "/")
  724. resp, err := modelResponse(canonicalModelPath)
  725. if err != nil {
  726. slog.Info(fmt.Sprintf("skipping file: %s", canonicalModelPath))
  727. // nolint: nilerr
  728. return nil
  729. }
  730. resp.ModifiedAt = info.ModTime()
  731. models = append(models, resp)
  732. }
  733. return nil
  734. }
  735. if err := filepath.Walk(manifestsPath, walkFunc); err != nil {
  736. c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
  737. return
  738. }
  739. c.JSON(http.StatusOK, api.ListResponse{Models: models})
  740. }
  741. func CopyModelHandler(c *gin.Context) {
  742. var req api.CopyRequest
  743. err := c.ShouldBindJSON(&req)
  744. switch {
  745. case errors.Is(err, io.EOF):
  746. c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "missing request body"})
  747. return
  748. case err != nil:
  749. c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": err.Error()})
  750. return
  751. }
  752. if req.Source == "" || req.Destination == "" {
  753. c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "source add destination are required"})
  754. return
  755. }
  756. if err := ParseModelPath(req.Destination).Validate(); err != nil {
  757. c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": err.Error()})
  758. return
  759. }
  760. if err := CopyModel(req.Source, req.Destination); err != nil {
  761. if os.IsNotExist(err) {
  762. c.JSON(http.StatusNotFound, gin.H{"error": fmt.Sprintf("model '%s' not found", req.Source)})
  763. } else {
  764. c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
  765. }
  766. return
  767. }
  768. }
  769. func HeadBlobHandler(c *gin.Context) {
  770. path, err := GetBlobsPath(c.Param("digest"))
  771. if err != nil {
  772. c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": err.Error()})
  773. return
  774. }
  775. if _, err := os.Stat(path); err != nil {
  776. c.AbortWithStatusJSON(http.StatusNotFound, gin.H{"error": fmt.Sprintf("blob %q not found", c.Param("digest"))})
  777. return
  778. }
  779. c.Status(http.StatusOK)
  780. }
  781. func CreateBlobHandler(c *gin.Context) {
  782. path, err := GetBlobsPath(c.Param("digest"))
  783. if err != nil {
  784. c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": err.Error()})
  785. return
  786. }
  787. _, err = os.Stat(path)
  788. switch {
  789. case errors.Is(err, os.ErrNotExist):
  790. // noop
  791. case err != nil:
  792. c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
  793. return
  794. default:
  795. c.Status(http.StatusOK)
  796. return
  797. }
  798. layer, err := NewLayer(c.Request.Body, "")
  799. if err != nil {
  800. c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
  801. return
  802. }
  803. if layer.Digest != c.Param("digest") {
  804. c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": fmt.Sprintf("digest mismatch, expected %q, got %q", c.Param("digest"), layer.Digest)})
  805. return
  806. }
  807. if _, err := layer.Commit(); err != nil {
  808. c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
  809. return
  810. }
  811. c.Status(http.StatusCreated)
  812. }
  813. var defaultAllowOrigins = []string{
  814. "localhost",
  815. "127.0.0.1",
  816. "0.0.0.0",
  817. }
  818. func isLocalIP(ip netip.Addr) bool {
  819. if interfaces, err := net.Interfaces(); err == nil {
  820. for _, iface := range interfaces {
  821. addrs, err := iface.Addrs()
  822. if err != nil {
  823. continue
  824. }
  825. for _, a := range addrs {
  826. if parsed, _, err := net.ParseCIDR(a.String()); err == nil {
  827. if parsed.String() == ip.String() {
  828. return true
  829. }
  830. }
  831. }
  832. }
  833. }
  834. return false
  835. }
  836. func allowedHost(host string) bool {
  837. if host == "" || host == "localhost" {
  838. return true
  839. }
  840. if hostname, err := os.Hostname(); err == nil && host == hostname {
  841. return true
  842. }
  843. var tlds = []string{
  844. "localhost",
  845. "local",
  846. "internal",
  847. }
  848. // check if the host is a local TLD
  849. for _, tld := range tlds {
  850. if strings.HasSuffix(host, "."+tld) {
  851. return true
  852. }
  853. }
  854. return false
  855. }
  856. func allowedHostsMiddleware(addr net.Addr) gin.HandlerFunc {
  857. return func(c *gin.Context) {
  858. if addr == nil {
  859. c.Next()
  860. return
  861. }
  862. if addr, err := netip.ParseAddrPort(addr.String()); err == nil && !addr.Addr().IsLoopback() {
  863. c.Next()
  864. return
  865. }
  866. host, _, err := net.SplitHostPort(c.Request.Host)
  867. if err != nil {
  868. host = c.Request.Host
  869. }
  870. if addr, err := netip.ParseAddr(host); err == nil {
  871. if addr.IsLoopback() || addr.IsPrivate() || addr.IsUnspecified() || isLocalIP(addr) {
  872. c.Next()
  873. return
  874. }
  875. }
  876. if allowedHost(host) {
  877. c.Next()
  878. return
  879. }
  880. c.AbortWithStatus(http.StatusForbidden)
  881. }
  882. }
  883. func (s *Server) GenerateRoutes() http.Handler {
  884. config := cors.DefaultConfig()
  885. config.AllowWildcard = true
  886. config.AllowBrowserExtensions = true
  887. if allowedOrigins := strings.Trim(os.Getenv("OLLAMA_ORIGINS"), "\"'"); allowedOrigins != "" {
  888. config.AllowOrigins = strings.Split(allowedOrigins, ",")
  889. }
  890. for _, allowOrigin := range defaultAllowOrigins {
  891. config.AllowOrigins = append(config.AllowOrigins,
  892. fmt.Sprintf("http://%s", allowOrigin),
  893. fmt.Sprintf("https://%s", allowOrigin),
  894. fmt.Sprintf("http://%s:*", allowOrigin),
  895. fmt.Sprintf("https://%s:*", allowOrigin),
  896. )
  897. }
  898. r := gin.Default()
  899. r.Use(
  900. cors.New(config),
  901. allowedHostsMiddleware(s.addr),
  902. )
  903. r.POST("/api/pull", PullModelHandler)
  904. r.POST("/api/generate", GenerateHandler)
  905. r.POST("/api/chat", ChatHandler)
  906. r.POST("/api/embeddings", EmbeddingsHandler)
  907. r.POST("/api/create", CreateModelHandler)
  908. r.POST("/api/push", PushModelHandler)
  909. r.POST("/api/copy", CopyModelHandler)
  910. r.DELETE("/api/delete", DeleteModelHandler)
  911. r.POST("/api/show", ShowModelHandler)
  912. r.POST("/api/blobs/:digest", CreateBlobHandler)
  913. r.HEAD("/api/blobs/:digest", HeadBlobHandler)
  914. // Compatibility endpoints
  915. r.POST("/v1/chat/completions", openai.Middleware(), ChatHandler)
  916. for _, method := range []string{http.MethodGet, http.MethodHead} {
  917. r.Handle(method, "/", func(c *gin.Context) {
  918. c.String(http.StatusOK, "Ollama is running")
  919. })
  920. r.Handle(method, "/api/tags", ListModelsHandler)
  921. r.Handle(method, "/api/version", func(c *gin.Context) {
  922. c.JSON(http.StatusOK, gin.H{"version": version.Version})
  923. })
  924. }
  925. return r
  926. }
  927. func Serve(ln net.Listener) error {
  928. level := slog.LevelInfo
  929. if debug := os.Getenv("OLLAMA_DEBUG"); debug != "" {
  930. level = slog.LevelDebug
  931. }
  932. handler := slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{
  933. Level: level,
  934. AddSource: true,
  935. ReplaceAttr: func(_ []string, attr slog.Attr) slog.Attr {
  936. if attr.Key == slog.SourceKey {
  937. source := attr.Value.Any().(*slog.Source)
  938. source.File = filepath.Base(source.File)
  939. }
  940. return attr
  941. },
  942. })
  943. slog.SetDefault(slog.New(handler))
  944. blobsDir, err := GetBlobsPath("")
  945. if err != nil {
  946. return err
  947. }
  948. if err := fixBlobs(blobsDir); err != nil {
  949. return err
  950. }
  951. if noprune := os.Getenv("OLLAMA_NOPRUNE"); noprune == "" {
  952. // clean up unused layers and manifests
  953. if err := PruneLayers(); err != nil {
  954. return err
  955. }
  956. manifestsPath, err := GetManifestPath()
  957. if err != nil {
  958. return err
  959. }
  960. if err := PruneDirectory(manifestsPath); err != nil {
  961. return err
  962. }
  963. }
  964. s := &Server{addr: ln.Addr()}
  965. r := s.GenerateRoutes()
  966. slog.Info(fmt.Sprintf("Listening on %s (version %s)", ln.Addr(), version.Version))
  967. srvr := &http.Server{
  968. Handler: r,
  969. }
  970. // listen for a ctrl+c and stop any loaded llm
  971. signals := make(chan os.Signal, 1)
  972. signal.Notify(signals, syscall.SIGINT, syscall.SIGTERM)
  973. go func() {
  974. <-signals
  975. unload()
  976. gpu.Cleanup()
  977. os.Exit(0)
  978. }()
  979. if err := llm.Init(); err != nil {
  980. return fmt.Errorf("unable to initialize llm library %w", err)
  981. }
  982. if runtime.GOOS == "linux" { // TODO - windows too
  983. // check compatibility to log warnings
  984. if _, err := gpu.CheckVRAM(); err != nil {
  985. slog.Info(err.Error())
  986. }
  987. }
  988. return srvr.Serve(ln)
  989. }
  990. func waitForStream(c *gin.Context, ch chan interface{}) {
  991. c.Header("Content-Type", "application/json")
  992. for resp := range ch {
  993. switch r := resp.(type) {
  994. case api.ProgressResponse:
  995. if r.Status == "success" {
  996. c.JSON(http.StatusOK, r)
  997. return
  998. }
  999. case gin.H:
  1000. if errorMsg, ok := r["error"].(string); ok {
  1001. c.JSON(http.StatusInternalServerError, gin.H{"error": errorMsg})
  1002. return
  1003. } else {
  1004. c.JSON(http.StatusInternalServerError, gin.H{"error": "unexpected error format in progress response"})
  1005. return
  1006. }
  1007. default:
  1008. c.JSON(http.StatusInternalServerError, gin.H{"error": "unexpected progress response"})
  1009. return
  1010. }
  1011. }
  1012. c.JSON(http.StatusInternalServerError, gin.H{"error": "unexpected end of progress response"})
  1013. }
  1014. func streamResponse(c *gin.Context, ch chan any) {
  1015. c.Header("Content-Type", "application/x-ndjson")
  1016. c.Stream(func(w io.Writer) bool {
  1017. val, ok := <-ch
  1018. if !ok {
  1019. return false
  1020. }
  1021. bts, err := json.Marshal(val)
  1022. if err != nil {
  1023. slog.Info(fmt.Sprintf("streamResponse: json.Marshal failed with %s", err))
  1024. return false
  1025. }
  1026. // Delineate chunks with new-line delimiter
  1027. bts = append(bts, '\n')
  1028. if _, err := w.Write(bts); err != nil {
  1029. slog.Info(fmt.Sprintf("streamResponse: w.Write failed with %s", err))
  1030. return false
  1031. }
  1032. return true
  1033. })
  1034. }
  1035. // ChatPrompt builds up a prompt from a series of messages for the currently `loaded` model
  1036. func chatPrompt(ctx context.Context, template string, messages []api.Message, numCtx int) (string, int, error) {
  1037. encode := func(s string) ([]int, error) {
  1038. return loaded.llama.Tokenize(ctx, s)
  1039. }
  1040. prompt, tokens, err := ChatPrompt(template, messages, numCtx, encode)
  1041. if err != nil {
  1042. return "", 0, err
  1043. }
  1044. return prompt, tokens, nil
  1045. }
  1046. func ChatHandler(c *gin.Context) {
  1047. loaded.mu.Lock()
  1048. defer loaded.mu.Unlock()
  1049. checkpointStart := time.Now()
  1050. var req api.ChatRequest
  1051. err := c.ShouldBindJSON(&req)
  1052. switch {
  1053. case errors.Is(err, io.EOF):
  1054. c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "missing request body"})
  1055. return
  1056. case err != nil:
  1057. c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": err.Error()})
  1058. return
  1059. }
  1060. // validate the request
  1061. switch {
  1062. case req.Model == "":
  1063. c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "model is required"})
  1064. return
  1065. case len(req.Format) > 0 && req.Format != "json":
  1066. c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "format must be json"})
  1067. return
  1068. }
  1069. model, err := GetModel(req.Model)
  1070. if err != nil {
  1071. var pErr *fs.PathError
  1072. if errors.As(err, &pErr) {
  1073. c.JSON(http.StatusNotFound, gin.H{"error": fmt.Sprintf("model '%s' not found, try pulling it first", req.Model)})
  1074. return
  1075. }
  1076. c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
  1077. return
  1078. }
  1079. if model.IsEmbedding() {
  1080. c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "embedding models do not support chat"})
  1081. return
  1082. }
  1083. opts, err := modelOptions(model, req.Options)
  1084. if err != nil {
  1085. if errors.Is(err, api.ErrInvalidOpts) {
  1086. c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
  1087. return
  1088. }
  1089. c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
  1090. return
  1091. }
  1092. var sessionDuration time.Duration
  1093. if req.KeepAlive == nil {
  1094. sessionDuration = getDefaultSessionDuration()
  1095. } else {
  1096. sessionDuration = req.KeepAlive.Duration
  1097. }
  1098. if err := load(c, model, opts, sessionDuration); err != nil {
  1099. c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
  1100. return
  1101. }
  1102. checkpointLoaded := time.Now()
  1103. // if the first message is not a system message, then add the model's default system message
  1104. if len(req.Messages) > 0 && req.Messages[0].Role != "system" {
  1105. req.Messages = append([]api.Message{
  1106. {
  1107. Role: "system",
  1108. Content: model.System,
  1109. },
  1110. }, req.Messages...)
  1111. }
  1112. prompt, tokens, err := chatPrompt(c.Request.Context(), model.Template, req.Messages, opts.NumCtx)
  1113. if err != nil {
  1114. c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
  1115. return
  1116. }
  1117. opts.NumPredict = max(opts.NumCtx-tokens, 0)
  1118. // an empty request loads the model
  1119. if len(req.Messages) == 0 || prompt == "" {
  1120. resp := api.ChatResponse{
  1121. CreatedAt: time.Now().UTC(),
  1122. Model: req.Model,
  1123. Done: true,
  1124. DoneReason: "load",
  1125. Message: api.Message{Role: "assistant"},
  1126. }
  1127. c.JSON(http.StatusOK, resp)
  1128. return
  1129. }
  1130. // only send images that are in the prompt
  1131. var i int
  1132. var images []llm.ImageData
  1133. for _, m := range req.Messages {
  1134. for _, img := range m.Images {
  1135. if !isSupportedImageType(img) {
  1136. c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "unsupported image format"})
  1137. return
  1138. }
  1139. if strings.Contains(prompt, fmt.Sprintf("[img-%d]", i)) {
  1140. images = append(images, llm.ImageData{Data: img, ID: i})
  1141. }
  1142. i += 1
  1143. }
  1144. }
  1145. slog.Debug("chat handler", "prompt", prompt, "images", len(images))
  1146. ch := make(chan any)
  1147. go func() {
  1148. defer close(ch)
  1149. fn := func(r llm.CompletionResponse) {
  1150. // Update model expiration
  1151. loaded.expireTimer.Reset(sessionDuration)
  1152. resp := api.ChatResponse{
  1153. Model: req.Model,
  1154. CreatedAt: time.Now().UTC(),
  1155. Message: api.Message{Role: "assistant", Content: r.Content},
  1156. Done: r.Done,
  1157. DoneReason: r.DoneReason,
  1158. Metrics: api.Metrics{
  1159. PromptEvalCount: r.PromptEvalCount,
  1160. PromptEvalDuration: r.PromptEvalDuration,
  1161. EvalCount: r.EvalCount,
  1162. EvalDuration: r.EvalDuration,
  1163. },
  1164. }
  1165. if r.Done {
  1166. resp.TotalDuration = time.Since(checkpointStart)
  1167. resp.LoadDuration = checkpointLoaded.Sub(checkpointStart)
  1168. }
  1169. ch <- resp
  1170. }
  1171. if err := loaded.llama.Completion(c.Request.Context(), llm.CompletionRequest{
  1172. Prompt: prompt,
  1173. Format: req.Format,
  1174. Images: images,
  1175. Options: opts,
  1176. }, fn); err != nil {
  1177. ch <- gin.H{"error": err.Error()}
  1178. }
  1179. }()
  1180. if req.Stream != nil && !*req.Stream {
  1181. // Accumulate responses into the final response
  1182. var final api.ChatResponse
  1183. var sb strings.Builder
  1184. for resp := range ch {
  1185. switch r := resp.(type) {
  1186. case api.ChatResponse:
  1187. sb.WriteString(r.Message.Content)
  1188. final = r
  1189. case gin.H:
  1190. if errorMsg, ok := r["error"].(string); ok {
  1191. c.JSON(http.StatusInternalServerError, gin.H{"error": errorMsg})
  1192. return
  1193. } else {
  1194. c.JSON(http.StatusInternalServerError, gin.H{"error": "unexpected error format in response"})
  1195. return
  1196. }
  1197. default:
  1198. c.JSON(http.StatusInternalServerError, gin.H{"error": "unexpected error"})
  1199. return
  1200. }
  1201. }
  1202. final.Message = api.Message{Role: "assistant", Content: sb.String()}
  1203. c.JSON(http.StatusOK, final)
  1204. return
  1205. }
  1206. streamResponse(c, ch)
  1207. }