Compare commits

...

16 Commits

Author SHA1 Message Date
shy
a485983fff opt some 2025-03-11 11:22:33 +08:00
shy
506b87b3e8 add some 2025-02-27 18:05:19 +08:00
shy
7ff2d416e3 add some 2025-02-27 14:38:00 +08:00
shy
7d797f1fb3 opt some 2025-02-27 08:55:56 +08:00
shy
3dec9b3ea0 opt some 2025-02-14 09:32:24 +08:00
root
d821a27d9d add some 2025-02-10 08:30:21 +08:00
root
ac45330965 add some 2025-02-09 23:08:08 +08:00
root
ba9fe9ef4b add showdown 2025-02-09 11:05:38 +08:00
root
69951ada84 add some 2025-02-09 10:00:19 +08:00
root
1cfc1a6ef1 add some 2025-02-09 09:44:56 +08:00
root
c63224054c add some 2025-02-08 23:29:02 +08:00
shy
3a49081a05 opt some 2025-02-08 18:51:09 +08:00
root
4685812585 add some 2025-02-08 17:43:13 +08:00
root
45956c5aae add some 2025-02-08 15:24:06 +08:00
root
097c07c945 add some 2025-02-08 15:00:05 +08:00
shy
f8eb8a226d opt some 2025-02-08 12:14:19 +08:00
15 changed files with 171 additions and 120 deletions

View File

@ -5,7 +5,7 @@ flags = -ldflags "-w -s" -v
all: def all: def
@date +"%Y-%m-%d %H:%M:%S" @date +"%Y-%m-%d %H:%M:%S"
go build ${flags} -o ${binarys} src/main.go ${version} ${binpack} && ./${binarys} forever restart &>/dev/null go build ${flags} -o ${binarys} src/main.go src/option.go ${version} ${binpack} && ./${binarys} forever restart &>/dev/null
def: def:
@[ -f ${version} ] || echo "package main">${version} @[ -f ${version} ] || echo "package main">${version}

View File

@ -1,19 +1,26 @@
# ContextOS # ollama-story
ContextOS 通过集群化、模块化、自动化的方式,只用一个 20M 大小的程序文件,就可以在各种设备上,一键启动完整的云计算服务与云研发环境 基于 ContextOS 开发的 ollama 部署工具与应用界面
## 源码安装 ## 安装 ContextOS
### 克隆编译 首先安装 ContextOS 云操作系统。
```sh ```sh
git clone https://shylinux.com/x/ContextOS https://shylinux.com
cd ContextOS; source etc/miss.sh
``` ```
### 启动服务 ## 安装 ollama-story
打开 ContextOS 的应用商店,下载 `20250208-ollama-story`
```sh ```sh
ish_miss_serve http://localhost:9020/c/store#2025-ContextOS
``` ```
### 访问网页 ## 使用 ollama-story
打开 `web.chat.ollama.chat` 的应用。
```sh ```sh
open http://localhost:9020 http://localhost:9020/s/20250208-ollama-story/c/web.chat.ollama.chat
```
## 查看 ollama-story
打开 `web.chat.ollama.chat` 的源码。
```sh
http://localhost:9020/s/20250208-ollama-story/c/vimer?path=src/&file=client/chat.go
``` ```

7
go.mod
View File

@ -3,6 +3,9 @@ module shylinux.com/x/ollama-story
go 1.13 go 1.13
require ( require (
shylinux.com/x/ice v1.5.59 shylinux.com/x/ice v1.5.73
shylinux.com/x/icebergs v1.9.59 shylinux.com/x/icebergs v1.9.75
shylinux.com/x/toolkits v1.0.19
) )
require github.com/gomarkdown/markdown v0.0.0-20250207164621-7a1f277a159e // indirect

14
go.sum
View File

@ -1,13 +1,15 @@
github.com/gomarkdown/markdown v0.0.0-20250207164621-7a1f277a159e h1:ESHlT0RVZphh4JGBz49I5R6nTdC8Qyc08vU25GQHzzQ=
github.com/gomarkdown/markdown v0.0.0-20250207164621-7a1f277a159e/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA=
shylinux.com/x/go-git/v5 v5.6.7 h1:WD5QSco7m3QooPCgdvQ6/GyGIFPun8C+hex5N41LYlk= shylinux.com/x/go-git/v5 v5.6.7 h1:WD5QSco7m3QooPCgdvQ6/GyGIFPun8C+hex5N41LYlk=
shylinux.com/x/go-git/v5 v5.6.7/go.mod h1:Qb0lA+uIrofZg8NQerhYcJHgGWixFqvS6p3aJ/L5Nlk= shylinux.com/x/go-git/v5 v5.6.7/go.mod h1:Qb0lA+uIrofZg8NQerhYcJHgGWixFqvS6p3aJ/L5Nlk=
shylinux.com/x/go-qrcode v0.0.3 h1:RMo+Vidbgq3HatLBj7DDXcTbTLFUwzis5K7TqBkD38U= shylinux.com/x/go-qrcode v0.0.3 h1:RMo+Vidbgq3HatLBj7DDXcTbTLFUwzis5K7TqBkD38U=
shylinux.com/x/go-qrcode v0.0.3/go.mod h1:KAbtU+KwiiABMZ/CJ0zh9PI2AX82Uf9rRYcQ4ODm4po= shylinux.com/x/go-qrcode v0.0.3/go.mod h1:KAbtU+KwiiABMZ/CJ0zh9PI2AX82Uf9rRYcQ4ODm4po=
shylinux.com/x/ice v1.5.59 h1:9TugxrDR5rlH+fMnm1L3sLtxoZXY5j0sR4SRLQyqcgg= shylinux.com/x/ice v1.5.73 h1:wp+KeQ14hLOdxxSou/Y0zHi48Jm4nLx1rFOwGz8ix04=
shylinux.com/x/ice v1.5.59/go.mod h1:/jZUXZGsBpTdHy/c8JkpWtVPGg6uPHOghlUULzg4R7o= shylinux.com/x/ice v1.5.73/go.mod h1:uGI73gYkk+FiJt5qmy/aYhoKRJ4wobcJk3WrPGh8Waw=
shylinux.com/x/icebergs v1.9.59 h1:fNEnFxyTJB2chG4zUeNpgfH8gXAiwUJOJvYFPJGDsek= shylinux.com/x/icebergs v1.9.75 h1:9zAm0ppwUWl0As/vqfQG/QR/vwXa5zmfdIGE/gmvErQ=
shylinux.com/x/icebergs v1.9.59/go.mod h1:d8sN77l5UZA+h8/swZ9OzqRCruoSYHWYjg5qKWnQI2s= shylinux.com/x/icebergs v1.9.75/go.mod h1:3Bdp3tjzw+hUKJF+kR8pfsrbjAf72DVZmCaE8/MPFtk=
shylinux.com/x/toolkits v0.7.10/go.mod h1:CHDJarGlDkg60kVsvMLYL/a5hAnRLEOShiEsMOuEp0Q= shylinux.com/x/toolkits v0.7.10/go.mod h1:CHDJarGlDkg60kVsvMLYL/a5hAnRLEOShiEsMOuEp0Q=
shylinux.com/x/toolkits v1.0.16 h1:7Oh454uAyBLfflIFEQooLNzml4pqXIReiaxEVA/YXaU= shylinux.com/x/toolkits v1.0.19 h1:Nrx0xYRc5ph1WS66EZ1hJUCe+2FdSWQ4QP6tBlguikQ=
shylinux.com/x/toolkits v1.0.16/go.mod h1:CHDJarGlDkg60kVsvMLYL/a5hAnRLEOShiEsMOuEp0Q= shylinux.com/x/toolkits v1.0.19/go.mod h1:CHDJarGlDkg60kVsvMLYL/a5hAnRLEOShiEsMOuEp0Q=
shylinux.com/x/websocket v0.0.4 h1:AJpwblePoOpiE6C8NrvgNYpKTotXMLrDDX2chTvx44Q= shylinux.com/x/websocket v0.0.4 h1:AJpwblePoOpiE6C8NrvgNYpKTotXMLrDDX2chTvx44Q=
shylinux.com/x/websocket v0.0.4/go.mod h1:3UGWkjTu3ie5NAZen7J+uLPBrO7DFeKloj6Jxo13Oiw= shylinux.com/x/websocket v0.0.4/go.mod h1:3UGWkjTu3ie5NAZen7J+uLPBrO7DFeKloj6Jxo13Oiw=

View File

@ -1,5 +1,6 @@
$output>div.message { padding:20px; overflow:auto; } $content { padding:10px 20px; }
$output>div.message>div.request { background-color:#94ec69; padding:10px; float:right; } $content>div.request { background-color:#94ec69; color:black; padding:10px; float:right; }
$output>div.message>div.request>span { float:right; } $content>div.response { clear:both; }
$output>div.message>div.response { white-space:break-spaces; padding:0px; clear:both; } $content>div.response p { margin:5px 0; }
$output>div.request { padding:20px; } $display { background-color:var(--plugin-bg-color); height:120px; }
$display textarea { margin:10px; width:calc(100% - 20px); }

View File

@ -9,19 +9,18 @@ import (
) )
type chat struct { type chat struct {
list string `name:"list name auto" help:"大模型对话"` client client
request string `name:"request model* role* content* which*"`
list string `name:"list list" help:"大模型对话" icon:"src/main.png"`
} }
func (s chat) Request(m *ice.Message, arg ...string) { func (s chat) Request(m *ice.Message, arg ...string) {
m.Optionv(web.SPIDE_STREAM, func(text string) { web.PushNoticeGrow(m.Message, text) }) m.Cmdy(web.SPIDE, OLLAMA, web.SPIDE_STREAM, http.MethodPost, "/api/chat", web.SPIDE_DATA, kit.Format(kit.Dict(
m.Cmdy(web.SPIDE, ice.DEV, web.SPIDE_STREAM, http.MethodPost, "http://localhost:11434/api/chat", m.OptionSimple("model"), "stream", true, "messages", kit.List(kit.Dict(m.OptionSimple("role", "content"))),
web.SPIDE_DATA, kit.Format(kit.Dict("model", "deepseek-r1", "stream", true, )))
"messages", kit.List(kit.Dict("role", "user", "content", arg[0])),
)),
)
} }
func (s chat) List(m *ice.Message, arg ...string) { func (s chat) List(m *ice.Message, arg ...string) {
m.Display("").DisplayCSS("") m.Cmdy(s.client).Display("").DisplayCSS("")
} }
func init() { ice.CodeModCmd(chat{}) } func init() { ice.ChatModCmd(chat{}) }

View File

@ -1,28 +1,40 @@
Volcanos(chat.ONIMPORT, { Volcanos(chat.ONIMPORT, {
_init: function(can, msg) { _init: function(can, msg) { can.require(["https://unpkg.com/showdown/dist/showdown.min.js"])
can.ui = can.page.Append(can, can._output, [ can.ui = can.onappend.layout(can), can.ui.responseList = [], can.onmotion.toggle(can, can.ui.display, true)
{view: "message"}, msg.Table(function(value) { can.onimport.item(can, {
{view: "request", list: [ name: value.NAME, nick: value.NAME+" ("+value.SIZE+")",
{type: "textarea", onkeydown: function(event) { }, function(event, item, show, target) {
if (event.key == "Enter") { can.onimport.tabsCache(can, item, target, function() { can.onimport.content(can, target) })
can.onappend._status(can, msg), can.onimport.layout(can)
}) })
},
content: function(can, target) {
can.page.Append(can, can.ui.content, [
{view: chat.RESPONSE, list: [
{text: can.user.trans(can, "Please Ask Anything!", "有什么问题尽管问吧!")},
]},
])
can.page.Append(can, can.ui.display, [
{type: html.TEXTAREA, placeholder: can.user.trans(can, "Please Input Your Question!", "请输入的您的问题!"), onkeydown: function(event) {
if (event.key == code.ENTER) {
can.onaction.request(event, can, event.target.value), event.target.value = "", can.onkeymap.prevent(event) can.onaction.request(event, can, event.target.value), event.target.value = "", can.onkeymap.prevent(event)
} }
}}, }},
]},
]) ])
can.ui.response = can.page.Append(can, can.ui.message, [{view: "response", list: [{text: "有什么问题尽管问吧!"}]}])._target
}, },
_grow: function(can, msg, text) { var data = JSON.parse(text) _grow: function(can, msg, which, text) {
can.page.Append(can, can.ui.response, [{text: data.message.content}]), can.ui.message.scrollBy(0, 1000) var target = can.ui.responseList[parseInt(which)-1], data = JSON.parse(text)
if (window.showdown) { target._text = (target._text||"")+data.message.content
var converter = new showdown.Converter(); target.innerHTML = converter.makeHtml(target._text)
} else {
can.page.Append(can, target, [{text: data.message.content}])
} can.ui.content.scrollBy(0, 1000)
}, },
layout: function(can) {
can.page.style(can, can.ui.message, html.MAX_HEIGHT, can.ConfHeight()-140)
}
}) })
Volcanos(chat.ONACTION, { Volcanos(chat.ONACTION, {
request: function(event, can, text) { request: function(event, can, text) { can.page.Append(can, can.ui.content, [{view: chat.REQUEST, list: [{text: text}]}])
can.page.Append(can, can.ui.message, [{view: "request", list: [{text: text}]}]) var response = can.page.Append(can, can.ui.content, [{view: chat.RESPONSE}])._target; can.ui.responseList.push(response)
can.ui.response = can.page.Append(can, can.ui.message, [{view: "response"}])._target can.request(event, {model: can.db.value.name, role: "user", content: text, which: ""+can.ui.responseList.length})
can.runAction(event, "request", [text], function(msg) {}) can.runAction(event, chat.REQUEST, [], function(msg) {})
}, },
}) })

View File

@ -3,21 +3,32 @@ package client
import ( import (
"shylinux.com/x/ice" "shylinux.com/x/ice"
"shylinux.com/x/icebergs/base/cli" "shylinux.com/x/icebergs/base/cli"
"shylinux.com/x/icebergs/base/mdb"
"shylinux.com/x/icebergs/base/nfs"
"shylinux.com/x/icebergs/base/web"
)
const (
OLLAMA = "ollama"
) )
type client struct { type client struct {
list string `name:"list NAME auto" help:"大模型"` list string `name:"list NAME auto" help:"大模型"`
} }
func (s client) Init(m *ice.Message, arg ...string) {
m.Cmd(web.SPIDE, mdb.CREATE, "http://localhost:11434/api/chat", OLLAMA, nfs.SRC_MAIN_PNG)
}
func (s client) List(m *ice.Message, arg ...string) { func (s client) List(m *ice.Message, arg ...string) {
if len(arg) == 0 { if len(arg) == 0 {
m.SplitIndex(s.cmdx(m, "list")) m.SplitIndex(s.cmdx(m, ice.LIST))
} else if len(arg) == 1 { } else {
m.Echo(s.cmdx(m, "show", arg[0])) m.Echo(s.cmdx(m, ice.SHOW, arg[0]))
} }
} }
func (s client) cmdx(m *ice.Message, arg ...string) string {
return m.Cmdx(cli.SYSTEM, "ollama", arg)
}
func init() { ice.Cmd("web.chat.ollama.client", client{}) } func init() { ice.ChatModCmd(client{}) }
func (s client) cmdx(m *ice.Message, arg ...string) string {
return m.Cmdx(cli.SYSTEM, OLLAMA, arg)
}

View File

@ -1,7 +1,9 @@
package main package main
import "shylinux.com/x/ice" import (
import _ "shylinux.com/x/ollama-story/src/server" "shylinux.com/x/ice"
import _ "shylinux.com/x/ollama-story/src/client" _ "shylinux.com/x/ollama-story/src/client"
_ "shylinux.com/x/ollama-story/src/server"
)
func main() { print(ice.Run()) } func main() { print(ice.Run()) }

BIN
src/main.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

View File

@ -1,53 +1,60 @@
title "ContextOS" title "ollama-story"
refer `
chapter "实践" 官网 https://ollama.com/
label ` 源码 https://github.com/ollama/ollama
code wiki chat team mall 模型 https://ollama.com/library/deepseek-r1
linux nginx docker redis mysql 应用 https://feizhuke.com/
bash git golang vim tmux
` `
chapter "理论" chapter "应用"
label `集群化 模块化 自动化` refer `
源码 https://github.com/shylinux/ollama-story
帖子 https://bbs.shylinux.com/forum.php?mod=viewthread&tid=6&extra=page%3D1
showdown https://igithub.com/showdownjs/showdown
nodejs https://nodejs.org/en
`
field web.chat.ollama.chat
chapter "项目" chapter "常用模型"
label ` refer `
matrix release program 硅基流动 https://siliconflow.cn/
intshell icebergs volcanos 深度求索 https://www.deepseek.com/
contexts toolkits learning 字节豆包 https://www.doubao.com/
腾讯元宝 https://yuanbao.tencent.com/
通义千问 https://tongyi.aliyun.com/
文心一言 https://yiyan.baidu.com/
月之暗面 https://kimi.moonshot.cn/
` `
section "火山架" chapter "常用工具"
field "趋势图" web.code.git.trends args `volcanos` section "AnythingLLM"
field "架构图" web.code.git.spides args `volcanos` refer `
官网 https://anythingllm.com/
section "冰山架" 文档 https://docs.anythingllm.com/
field "趋势图" web.code.git.trends args `icebergs` 源码 https://github.com/Mintplex-Labs/anything-llm
field "架构图" web.code.git.spides args `icebergs`
label `
ctx mdb web aaa
lex yac ssh gdb
tcp nfs cli log
` `
chain ` section "Cherry Studio"
web refer `
code 官网 https://cherry-ai.com/
wiki 文档 https://docs.cherry-ai.com/
chart 源码 https://github.com/CherryHQ/cherry-studio
chat `
macos section "OBS Studio"
oauth refer `
location 官网 https://obsproject.com/
team 文档 https://obsproject.com/kb/quick-start-guide
mall 源码 https://github.com/obsproject/obs-studio
`
section "community"
refer `
https://x.com/
https://discord.com/
https://telegram.org/
https://www.facebook.com/
https://www.youtube.com/
https://mail.google.com/
https://www.bilibili.com/
https://www.xiaohongshu.com/
https://www.douyin.com/
https://weibo.com/
` `
label `
websocket webview qrcode xterm ssh git
vim bash tmux alpha input lex yac
node java coder github chrome
wx lark wework
` compact true
section "神农架"
field "趋势图" web.code.git.trends args `intshell`
field "架构图" web.code.git.spides args `intshell`

6
src/option.go Normal file
View File

@ -0,0 +1,6 @@
package main
import (
_ "shylinux.com/x/ice/devops"
_ "shylinux.com/x/icebergs/misc/md"
)

View File

@ -4,12 +4,11 @@ import "shylinux.com/x/ice"
type server struct { type server struct {
ice.Hash ice.Hash
list string `name:"list hash auto" help:"大模型"`
list string `name:"list hash auto" help:"server"`
} }
func (s server) List(m *ice.Message, arg ...string) { func (s server) List(m *ice.Message, arg ...string) {
s.Hash.List(m, arg...) s.Hash.List(m, arg...)
} }
func init() { ice.Cmd("web.chat.ollama.server", server{}) } func init() { ice.ChatModCmd(server{}) }

View File

@ -1,6 +0,0 @@
title "ollama"
refer `
官网 https://ollama.com/
源码 https://github.com/ollama/ollama
简介 https://blog.csdn.net/qq_40999403/article/details/139320266
`

View File

@ -7,6 +7,14 @@
"time": "2025-02-08 09:20:30.381" "time": "2025-02-08 09:20:30.381"
} }
}, },
"937681425ca043f9908761fbcdf3c813": {
"meta": {
"icon": "src/main.png",
"index": "web.chat.ollama.chat",
"name": "chat",
"time": "2025-02-08 15:27:08.564"
}
},
"adf694a4d378bcc855218c464fecb7d9": { "adf694a4d378bcc855218c464fecb7d9": {
"meta": { "meta": {
"icon": "usr/icons/Messages.png", "icon": "usr/icons/Messages.png",