Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions lib/byteseek/llm.kv
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,34 @@ lib llm {
"byteseek/session/" + name + "·init" -> entry
if (print != "0") { println("[llm] 入口:", entry) }
}

// llm·raw(sys, user) -> text:裸 LLM 调用,返回 assistant 文本(不生成/不执行 kv 代码)。
// 供 memgen 等需要「LLM 直接产出一段文本」的元能力复用。
rwfunc raw(sys:[]char/utf32, user:[]char/utf32) -> (text:[]char/utf32) {
kv·get("/byteseek/llm.key") -> key
if (key == "") {
"error: 未设置 DEEPSEEK_API_KEY" -> text
return
}
kv·get("/byteseek/llm.api") -> url
sys -> /tmp/esc·sys
json·to(/tmp/esc·sys) -> sys_j
user -> /tmp/esc·user
json·to(/tmp/esc·user) -> user_j
"{\"model\":\"deepseek-v4-flash\",\"messages\":[{\"role\":\"system\",\"content\":" + sys_j + "},{\"role\":\"user\",\"content\":" + user_j + "}],\"temperature\":0.2,\"top_p\":1.0,\"max_tokens\":1024,\"stream\":false}" -> body
"Content-Type: application/json\nAuthorization: Bearer " + key -> header
http·call("POST", header, url, body) -> resp
string·find(resp, "choices") -> has_choices
if (has_choices < 0) {
"error: LLM 响应异常: " + resp -> text
return
}
json·from(resp) -> /tmp/llmresp
kv·get("/tmp/llmresp·choices·[0]·message·content") -> content
if (content == "") {
"error: LLM 响应无内容: " + resp -> text
return
}
content -> text
}
}
7 changes: 5 additions & 2 deletions lib/byteseek/main.kv
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,21 @@ lib byteseek {
}

rwfunc mainbrain() -> () {
byteseek/memgen·build()
running = 1
while (running == 1) {
input("byteseek> ") -> userinput
string·cmp(userinput, "exit") -> q
if (q == 0) {
running = 0
} else {
byteseek/memory·classify(userinput) -> cat
byteseek/memory·ensure_category(cat)
byteseek/memory·recall(userinput) -> mem
if (mem == "") {
userinput -> prompt
userinput + "\n\n[类别] " + cat -> prompt
} else {
userinput + "\n\n[相关记忆]\n" + mem -> prompt
userinput + "\n\n[类别] " + cat + "\n\n[相关记忆]\n" + mem -> prompt
}
llm·call(prompt) -> entry
byteseek·run(entry)
Expand Down
58 changes: 58 additions & 0 deletions lib/byteseek/memgen.kv
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// byteseek 能力记忆生成器(全 kvlang):把 /lib 下各目录的能力浓缩成一条 ·mem 记忆 key。
// 后缀约定:目录 /lib/<name> 的能力记忆存在 key /lib/<name>.mem。
// fnlist(name) —— 枚举 /lib/<name>· 下的函数/常量名(.src 条目去后缀,目录条目跳过)。
// summarize(name) —— 若 /lib/<name>·mem 不存在,用 LLM 生成中文能力记忆并写入该 key。
// build() —— 对 kvlang stdlib 的目录递归概括一次(幂等:已有 ·mem 即跳过)。
lib byteseek {
lib memgen {
rwfunc fnlist(name:[]char/utf32) -> (listing:[]char/utf32) {
"" -> listing
"/lib/" + name + "·" -> mdir
kv·listlen(mdir) -> n
i = 0
while (i < n) {
kv·listn(mdir, i) -> entry
char/utf32(entry) -> entry
string·len(entry) -> elen
string·find(entry, ".src") -> p
if (p >= 0) {
elen - 4 -> cut
string·slice(entry, 0, cut) -> fn
if (listing == "") { fn -> listing } else { listing + ", " + fn -> listing }
} else {
elen - 1 -> last
string·char(entry, last) -> tail
if (tail != "/") {
if (listing == "") { entry -> listing } else { listing + ", " + entry -> listing }
}
}
i + 1 -> i
}
}

rwfunc summarize(name:[]char/utf32) -> () {
kv·has("/lib/" + name + ".mem") -> exists
if (exists == true) { return }
fnlist(name) -> listing
"你是 kvlang 能力记忆生成器。kvspace 目录 /lib/" + name + " 提供以下能力:" + listing + "。请用中文写一段不超过 200 字的紧凑能力记忆:用 · 分隔,每个能力名后跟一句话用途。只输出记忆文本本身,不要代码、不要解释、不要 markdown。" -> user
llm·raw("你是 kvlang 能力记忆生成器。只输出简洁的中文记忆文本。", user) -> text
string·find(text, "error") -> iserr
if (iserr == 0) {
println("[memgen] 概括失败:", name, text)
return
}
kv·set("/lib/" + name + ".mem", text)
println("[memgen] 已生成:", "/lib/" + name + ".mem")
}

rwfunc build() -> () {
byteseek/memgen·summarize("math")
byteseek/memgen·summarize("string")
byteseek/memgen·summarize("kv")
byteseek/memgen·summarize("xv")
byteseek/memgen·summarize("http")
byteseek/memgen·summarize("time")
byteseek/memgen·summarize("time/duration")
}
}
}
61 changes: 42 additions & 19 deletions lib/byteseek/memory.kv
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
// byteseek 记忆库(全 kvlang):记忆都活在 /byteseek/memory/<key> 的 kvspace 树里。
// byteseek 记忆库(全 kvlang):记忆都活在 /byteseek/memory/ 的 kvspace 树里。
// remember(key, value) —— 写一条记忆到 /byteseek/memory/<key>。
// recall(query) —— 记忆检查:扫描 /byteseek/memory/ 子树,自动滤出与 query 相关的关键树路径,
// 返回多行 "key = value",供 mainbrain 注入 LLM 上下文。
// classify(msg) —— 用 LLM 把消息归入一个简短类别。
// ensure_category(cat) —— 若类别不存在,则在 /byteseek/memory/cat/<cat> 新建。
// 匹配规则:query 与 key 互相包含,或 query 与 value 互相包含(子串匹配,大小写敏感)。
lib byteseek {
lib memory {
Expand All @@ -17,28 +19,49 @@ lib byteseek {
while (i < n) {
kv·listn("/byteseek/memory/", i) -> key
char/utf32(key) -> key
"/byteseek/memory/" + key -> path
kv·get(path) -> value
hit = 0
string·find(query, key) -> a
if (a != -1) { hit = 1 }
string·find(key, query) -> b
if (b != -1) { hit = 1 }
if (value != "") {
string·find(value, query) -> c
if (c != -1) { hit = 1 }
string·find(query, value) -> d
if (d != -1) { hit = 1 }
}
if (hit == 1) {
if (ctx == "") {
key + " = " + value -> ctx
} else {
ctx + "\n" + key + " = " + value -> ctx
if (key != "cat") {
"/byteseek/memory/" + key -> path
kv·get(path) -> value
hit = 0
string·find(query, key) -> a
if (a != -1) { hit = 1 }
string·find(key, query) -> b
if (b != -1) { hit = 1 }
if (value != "") {
string·find(value, query) -> c
if (c != -1) { hit = 1 }
string·find(query, value) -> d
if (d != -1) { hit = 1 }
}
if (hit == 1) {
if (ctx == "") {
key + " = " + value -> ctx
} else {
ctx + "\n" + key + " = " + value -> ctx
}
}
}
i + 1 -> i
}
}

rwfunc classify(msg:[]char/utf32) -> (cat:[]char/utf32) {
"请把下面这条用户消息归入一个简短中文类别(2-6字,如:编程、文件、shell、数学、闲聊)。只输出类别名本身,不要任何空格、换行、标点或解释。\n\n消息:" + msg -> user
llm·raw("你是消息分类器。只输出一个简短中文类别名。", user) -> cat
string·find(cat, "error") -> e
if (e == 0) {
"未分类" -> cat
}
}

rwfunc ensure_category(cat:[]char/utf32) -> () {
if (cat == "") { return }
"/byteseek/memory/cat/" + cat -> path
kv·has(path) -> exists
if (exists == false) {
kv·set(path, "1")
println("[memory] 新类别:", cat)
}
}
}
}
Loading