Files
Arcrun/registry/components/kbdb_ingest/main.go
T
Leo 519423cb0d feat(arcrun): mira wiki page with tag filter + accumulated WIP
- landing/app/mira/wiki: tag=mira-wiki list now shows all wiki paragraphs
  (depends on KBDB tag filter exposed in matrix/kbdb commit, separate repo)
- landing: app/mira hub + feed split + various WIP from prior sessions
- registry/components: claude_api / kbdb_create_block / kbdb_get / km_writer /
  platform_crypto / auth_oauth2 contracts + main.go (accumulated)
- .component-builds: pkg-lock updates + index.ts adjustments (WIP)
- .agents/specs/arcrun/frontend-redesign: design notes
- docs/test_credentials, docs/user_requirements/arcrun-landing-page: WIP docs
- cypher-executor: auth-dispatcher / wasi-shim adjustments (WIP)

Includes accumulated work from prior sessions plus the wiki UI tag-filter
update that surfaces the AI-generated wiki paragraphs at /mira/wiki.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-07 16:52:01 +08:00

156 lines
3.9 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// kbdb_ingest — 把 input 寫入 KBDBPOST /blocks/ingest
// thin wrapper:透過 host function http_request 呼叫 KBDB API
//
//go:build tinygo
package main
import (
"encoding/json"
"io"
"os"
"unsafe"
)
//go:wasmimport u6u http_request
func hostHttpRequest(
urlPtr uintptr, urlLen uint32,
methodPtr uintptr, methodLen uint32,
headersPtr uintptr, headersLen uint32,
bodyPtr uintptr, bodyLen uint32,
outPtr uintptr, outLenPtr uintptr,
) uint32
type Input struct {
KBDBUrl string `json:"kbdb_url"` // optional, default https://kbdb.finally.click
APIKey string `json:"api_key"` // 必填(pk_live_xxx 或 ak_xxx
Text string `json:"text"` // 必填(block 內容)
UserID string `json:"user_id"` // 必填(namespace prefix 對應)
Source string `json:"source"` // optional
PageName string `json:"page_name"` // optional
// 註:本零件硬編碼 skip_llm=truemira 場景定型貼文,不需 KBDB triplet 抽取)。
// 若需 LLM 抽取,未來另建 kbdb_ingest_with_llm 零件。
}
var dummy [1]byte
func safePtr(b []byte) (uintptr, uint32) {
if len(b) == 0 {
return uintptr(unsafe.Pointer(&dummy[0])), 0
}
return uintptr(unsafe.Pointer(&b[0])), uint32(len(b))
}
func main() {
raw, err := io.ReadAll(os.Stdin)
if err != nil {
writeError("failed to read stdin: " + err.Error())
return
}
var input Input
if err := json.Unmarshal(raw, &input); err != nil {
writeError("invalid input JSON: " + err.Error())
return
}
if input.APIKey == "" {
writeError("api_key 必填")
return
}
if input.Text == "" {
writeError("text 必填")
return
}
if input.UserID == "" {
writeError("user_id 必填")
return
}
kbdbURL := input.KBDBUrl
if kbdbURL == "" {
kbdbURL = "https://kbdb.finally.click"
}
// 構造 KBDB ingest 的 body(只含 KBDB 認得的欄位)
type ingestBody struct {
Text string `json:"text"`
UserID string `json:"user_id"`
Source string `json:"source,omitempty"`
PageName string `json:"page_name,omitempty"`
SkipLLM *bool `json:"skip_llm,omitempty"`
}
skipLLM := true
body := ingestBody{
Text: input.Text,
UserID: input.UserID,
Source: input.Source,
PageName: input.PageName,
SkipLLM: &skipLLM,
}
bodyBytes, _ := json.Marshal(body)
headers := map[string]string{
"Content-Type": "application/json",
"Authorization": "Bearer " + input.APIKey,
}
headersBytes, _ := json.Marshal(headers)
url := kbdbURL + "/blocks/ingest"
method := "POST"
urlBytes := []byte(url)
methodBytes := []byte(method)
outBuf := make([]byte, 65536)
var outLen uint32
urlPtr, urlLen := safePtr(urlBytes)
methodPtr, methodLen := safePtr(methodBytes)
headersPtr, headersLen := safePtr(headersBytes)
bodyPtr, bodyLenU := safePtr(bodyBytes)
result := hostHttpRequest(
urlPtr, urlLen,
methodPtr, methodLen,
headersPtr, headersLen,
bodyPtr, bodyLenU,
uintptr(unsafe.Pointer(&outBuf[0])), uintptr(unsafe.Pointer(&outLen)),
)
if result != 0 {
writeError("KBDB ingest request failed (host_http_request returned non-zero)")
return
}
// KBDB 回傳格式:{"blocks_injected": N, "triplets_injected": M, ...}
respStr := string(outBuf[:outLen])
// 嘗試 parse 確認是 JSON(若 KBDB 回 error 也透傳)
var kbdbResp map[string]interface{}
if err := json.Unmarshal([]byte(respStr), &kbdbResp); err != nil {
writeError("KBDB returned non-JSON: " + respStr)
return
}
// 若 KBDB 回 error 欄位(401/400 etc.),透傳
if _, hasErr := kbdbResp["error"]; hasErr {
out, _ := json.Marshal(map[string]interface{}{
"success": false,
"error": kbdbResp["error"],
})
os.Stdout.Write(out)
return
}
out, _ := json.Marshal(map[string]interface{}{
"success": true,
"data": kbdbResp,
})
os.Stdout.Write(out)
}
func writeError(msg string) {
out, _ := json.Marshal(map[string]interface{}{"success": false, "error": msg})
os.Stdout.Write(out)
}