资源管理
资源是智能体可以引用的外部知识。本模块提供资源的添加、导入/导出、临时文件上传等功能。
核心概念
资源类型
OpenViking 支持多种资源类型,按照功能分类如下:
文档类
| 类型 | 扩展名 | 说明 |
|---|---|---|
.pdf | 支持本地解析和 MinerU API 转换 | |
| Markdown | .md, .markdown, .mdown, .mkd | 原生支持,会提取结构并分段存储 |
| HTML | .html, .htm | 清理导航/广告后提取内容,转换为 Markdown |
| Word | .docx | 提取文本、标题、表格并转换为 Markdown |
| 纯文本 | .txt, .text | 直接导入处理 |
| EPUB | .epub | 电子书格式,支持 ebooklib 或手动提取 |
表格类
| 类型 | 扩展名 | 说明 |
|---|---|---|
| Excel | .xlsx, .xls, .xlsm | 支持新版和老版 Excel,按工作表转换为 Markdown 表格 |
| PowerPoint | .pptx | 按幻灯片提取内容,支持提取备注 |
代码类
| 类型 | 资源名 | 说明 |
|---|---|---|
| 代码文件 | *.py, *.js, ... | 支持常见编程语言(Python, JavaScript, Go, Rust, Java 等) |
| Git 协议代码仓库 | git://... | Git URL, 本地目录, .zip 包,遵循 .gitignore 并自动过滤 .git, node_modules 等目录 |
| Git 代码托管平台 | https://github.com/{org}/{repo} | GitHub, GitLab, Bitbucket 等代码托管平台的 URL |
| Git 代码托管平台上的 raw 文件 | https://github.com/{org}/{repo}/raw/{branch}/{path} | GitHub, GitLab, Bitbucket 等代码托管平台的 raw 文件下载 URL |
媒体类
| 类型 | 资源名 | 说明 |
|---|---|---|
| 图片 | *.jpg, *.jpeg, *.png, *.gif ... | 多种图片格式,通过 VLM 生成描述(实验特性) |
| 视频 | *.mp4, *.avi, *.mov ... | 提取关键帧后使用 VLM 分析(规划) |
| 音频 | *.mp3, *.wav, *.m4a ... | 进行语音转录处理(规划) |
云文档类
| 类型 | 说明 |
|---|---|
| 飞书/Lark | URL 方式,支持 docx, wiki, sheets, bitable。默认使用 FEISHU_APP_ID 和 FEISHU_APP_SECRET 应用凭证;用户 token 导入可传 args.feishu_access_token,用户 token watch 还需传 args.feishu_refresh_token |
网页类(递归网页爬虫)
| 类型 | 资源名 | 说明 |
|---|---|---|
| 单页 / 递归抓取 | https://host/path | 默认仅抓入口页;设置 args.depth > 0 后,沿同域链接 BFS 递归展开,args.max_pages 只限制最多收集的页面数。每页用 trafilatura 抽成 Markdown。可选 args:depth、max_pages、include_paths、exclude_paths、allow_external_links、skip_download_links。页面中发现的下载链接默认跳过(skip_download_links=true),避免导入 llms.txt 等 sidecar 文件造成重复;设为 false 时会下载同域文件链接,并计入 max_pages。include_paths/exclude_paths 按路径前缀匹配(例如 /docs/ 仅匹配以 /docs/ 开头的路径,不会误命中 /blog/docs-tips)。 |
路由说明:
https://host/sitemap.xml、https://host/feed.xml、*.atom等 sitemap-looking URL 和显式args.site=true让出给下表的整站导入;https://github.com/{org}/{repo}等 Git 托管平台 URL 让出给上文的代码导入。
网站类(sitemap / RSS / Atom 整站导入)
| 类型 | 资源名 | 说明 |
|---|---|---|
| 站点地图 Sitemap | https://host/sitemap.xml、https://host/sitemap-index.xml | 解析 sitemap,将站点所有页面抓取为一棵资源树(每页一个子节点),支持嵌套 <sitemapindex> 递归。整站只生成一个资源,落在 viking://resources/<host>。 |
| RSS / Atom 订阅源 | https://host/rss.xml、https://host/atom.xml、https://host/feed | 解析 RSS 2.0 / Atom,逐条把文章正文抓成树节点(feed 内含全文则直接使用,省一次抓取)。 |
| 整站自动发现 | https://host + args.site=true | 对裸域名/普通页面强制整站导入:自动通过 robots.txt、HTML <link rel="alternate"> autodiscovery、常见路径发现 sitemap/RSS,再整站抓取。 |
抓取有界、非递归(不会超出所列页面继续爬),受 parsers.webfeed 配置约束(max_pages、max_concurrency、politeness_delay、same_host_only、respect_robots、max_depth),并遵守 robots.txt。对 sitemap/feed URL 设置 watch_interval 即可让整站周期刷新:每次运行自动纳入新增页面、移除已删除页面。添加单个首页(未带 args.site)时,返回信息可能附带一行"整站导入"提示——只提示,绝不自动爬全站。
资源处理流程
资源添加经过以下处理阶段:
源输入 → 解析 → 资源树构建 → 持久化 → 语义处理
↓ ↓ ↓ ↓ ↓
URL/文件 Parser TreeBuilder AGFS Summarizer/Vector阶段 1:源解析 (Parse)
- 使用
UnifiedResourceProcessor根据资源类型解析内容 - 支持多种格式:文档(PDF/Markdown/Word)、表格(Excel/PPT)、代码、媒体文件等
- 解析结果写入临时 VikingFS 目录
- 媒体文件通过 VLM(视觉语言模型)生成描述
阶段 2:资源树构建 (TreeBuilder)
TreeBuilder.finalize_from_temp()扫描临时目录结构- 构建资源树节点,处理 URI 冲突(自动重命名)
- 建立目录与资源的关联关系
阶段 3:持久化存储 (Persist)
- 检查目标 URI 是否已存在
- 新资源:移动临时文件到正式 AGFS 位置
- 已存在资源:保留临时树用于后续差异比较
- 获取生命周期锁防止并发修改
- 清理临时目录
阶段 4:语义处理 (Semantic Processing)
- 摘要生成:
Summarizer生成 L0(摘要)和 L1(概述) - 向量索引:将内容向量化用于语义搜索
- 通过
SemanticQueue异步处理,可通过wait=True等待完成
非等待 Git 仓库导入
- 对 Git 仓库来源使用
wait=false时,OpenViking 会先校验仓库、解析目标 URI、预占最终root_uri,然后在 clone/parse/finalize 完成前返回。 - 立即响应包含
status、root_uri和task_id;抓取、解析、finalize 以及队列等待会在持久化后台任务中继续执行。 - 可通过
GET /api/v1/tasks/{task_id}查询任务状态。Git 资源导入任务的阶段包括queued、fetching、parsing、finalizing、processing_queue。 - 其他资源来源使用
wait=false时,会在响应前完成抓取/解析/finalize;返回的task_id只用于跟踪 semantic 和 embedding 队列完成情况。
资源的增量更新
资源增量更新通过监控任务 (Watch Task) 机制实现:
监控任务创建
- 调用
add_resource时,为 URL、sitemap、RSS 等可重新读取的来源设置watch_interval > 0(单位:分钟),即可创建监控任务 temp_file_id引用的上传内容只会作为一次性快照处理,不能创建监控任务;本地来源变化后请重新添加- 可指定
to参数确定目标 URI;未指定时,系统会使用本次导入返回的root_uri作为监控目标 - 把监控对象设为 sitemap/RSS/Atom URL,即可让整站保持同步:每次刷新重新读取 feed 并重建资源树,新发布的页面自动入库、已删除的页面自动移除
WatchManager负责任务持久化存储- 支持多租户权限控制(ROOT/ADMIN/USER 权限分级)
任务调度执行
WatchScheduler每 60 秒检查到期任务- 默认并发控制,避免重复执行
- 到期任务自动重新调用
add_resource处理 - 更新任务的最后执行时间和下次执行时间
任务管理操作
- 创建:
watch_interval > 0时创建新任务或重新激活已停用任务 - 更新:对同一目标 URI 重新设置参数
- 取消:对同一目标 URI 设置
watch_interval <= 0时停用任务 - 查询:通过任务 ID 或目标 URI 查询任务状态
API 参考
add_resource
向知识库添加资源,支持本地文件/目录、URL 等多种来源。通过 temp_file_id 引用的上传内容是一次性快照,因此不能与 watch_interval > 0 组合使用。
1. API 实现介绍
此接口是资源管理的核心入口,支持多种来源的资源添加,并可选择等待语义处理完成。SDK 可直接处理本地文件/目录、URL 等来源;直接 HTTP 调用只通过 path 接受远程 URL,或通过 temp_file_id 引用先上传的本地文件。
处理流程:
- 识别并校验资源来源(URL 或上传的临时文件)
- 解析目标 URI
- 调用对应 Parser 解析内容
- 构建目录树并写入 AGFS
- 按
processing_mode执行入库后的处理:semantic_and_vectors生成语义产物和向量;vectors_only跳过语义理解,只提交文件向量化 wait=true时等待语义处理/向量化完成;wait=false时返回task_id用于队列跟踪- 如果
reason非空,将其追加到固定的资源 reason session 并 commit,复用常规记忆抽取链路,让合适的用户记忆引用该资源 URI - 如指定
--watch-interval,设置定时更新任务
代码入口:
openviking/client/local.py:LocalClient.add_resource- SDK 入口(嵌入式)openviking_cli/client/http.py:AsyncHTTPClient.add_resource- SDK 入口(HTTP)openviking/server/routers/resources.py:add_resource- HTTP 路由openviking/service/resource_service.py- 核心服务实现crates/ov_cli/src/handlers.rs:handle_add_resource- CLI 处理
2. 接口和参数说明
参数
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| path | string | 否 | - | 远程资源 URL(HTTP/HTTPS/Git)。与 temp_file_id 二选一 |
| temp_file_id | string | 否 | - | 临时上传文件 ID。与 path 二选一 |
| to | string | 否 | - | 目标 Viking URI(精确位置)。与 parent 互斥 |
| parent | string | 否 | - | 父级 Viking URI(资源放入此目录下)。与 to 互斥 |
| create_parent | bool | 否 | False | 如果父目录不存在,自动创建父目录(服务端标志) |
| reason | string | 否 | "" | 添加资源的原因;非空时会随资源 URI 进入常规 session 记忆抽取链路,并在生成的记忆中记录资源引用 |
| instruction | string | 否 | "" | 语义提取的处理指令(实验特性) |
| wait | bool | 否 | False | 是否等待语义处理和向量化完成才返回 |
| timeout | float | 否 | None | 超时时间(秒),仅 wait=true 时生效 |
| strict | bool | 否 | False | 是否使用严格模式 |
| ignore_dirs | string | 否 | None | 要忽略的目录名(逗号分隔) |
| include | string | 否 | None | 包含的文件模式(glob) |
| exclude | string | 否 | None | 排除的文件模式(glob) |
| directly_upload_media | bool | 否 | True | 是否直接上传媒体文件 |
| preserve_structure | bool | 否 | None | 是否保留目录结构 |
| args | object | 否 | {} | 传给特定 parser/accessor 的导入参数。例如 args.site=true/false 强制/禁用整站(sitemap/RSS)导入,args.max_pages 等可覆盖 webfeed 配置;递归网页爬虫支持 args.depth、args.max_pages、args.include_paths、args.exclude_paths、args.allow_external_links、args.skip_download_links;飞书用户 token 导入传 args.feishu_access_token。path、to、watch_interval、include、exclude 等 add_resource 核心字段不能放入 args |
| watch_interval | float | 否 | 0 | 定时更新间隔(分钟)。>0 为 URL/sitemap/RSS 等可重新读取的来源创建任务;通过 temp_file_id 上传的内容是一次性快照,变化后需重新添加。≤0 取消任务;显式 to 优先,否则绑定本次导入的 root_uri |
| processing_mode | string | 否 | semantic_and_vectors | 入库后的处理模式。semantic_and_vectors 是默认流程:生成语义产物(.abstract.md、.overview.md)并生成向量。vectors_only 跳过语义理解/VLM 总结,只对当前资源文件生成向量 |
| telemetry | TelemetryRequest | 否 | False | 是否返回遥测数据 |
补充说明:
to和parent不能同时使用;如果使用parent且希望父目录不存在时自动创建,请传create_parent=true。指定to且目标已存在时,触发增量更新。- 如果同时省略
to和parent,服务端会先尝试使用当前用户的add_targets.resource_uri覆盖配置,再使用server.user_config_defaults.add_targets.resource_uri。两者都没有配置时,保持旧的目标解析行为。 - 资源目标可以使用公共
viking://resources/...、当前用户短写viking://user/resources/...、显式用户viking://user/{user_id}/resources/...,或 peer 级viking://user/{user_id}/peers/{peer_id}/resources/...。当前用户短写会按请求身份 canonicalize。 user_id和peer_id路径片段必须是安全的单段标识,例如alice或web-visitor-alice。包含路径分隔符、.、..、:或+的值会被拒绝。path和temp_file_id不能同时指定,上传本地文件需要先通过 temp_upload 上传获取temp_file_id,在 SDK 和 CLI 中已经封装好。- 只有 Git 仓库来源在
wait=false时使用完整后台导入;OpenViking 会先完成仓库 preflight 和目标规划,再返回task_id。 reason触发的记忆生成复用session.commit的抽取链路,只使用reason、资源 URI、可用的资源名称和目录摘要,不会读取或展开完整资源正文;系统会写入entities、events、preferences等已有记忆类型,不创建独立的资源记忆目录。- 删除资源时,系统会在删除前扫描本次上下文对应的 self 或 peer 记忆中的
resource_refs,清理对应资源 URI 和由该reason引入的内容,并重新刷新相关记忆的语义索引。 - 其他来源在
wait=false时会在响应前完成来源解析、目标解析和 AGFS 写入,仅 semantic 与 embedding 队列继续异步处理。 processing_mode=vectors_only不调用 VLM 语义理解阶段,也不会生成或刷新.abstract.md/.overview.md。对已存在目标,它会保留旧的语义产物和旧的语义向量;仍会更新资源树,在build_index=true时向量化当前非隐藏文件,并清理由本次刷新删除的文件 detail 向量。processing_mode只属于add_resource。管理员维护已有数据时,reindexAPI/CLI 仍使用mode(vectors_only、semantic_and_vectors、prune_orphans)。watch_interval > 0时,如果指定了to,监控任务绑定该目标;如果未指定to,监控任务绑定本次导入返回的root_uri。如果无法得到稳定root_uri,请求会报错并要求显式传to。- 飞书/Lark 应用 token 导入不传
args.feishu_access_token。OpenViking 保持原有应用凭证流程,由 SDK 使用app_id和app_secret自动获取 app/tenant token。该模式支持一次性导入和watch_interval > 0。 - 飞书/Lark 一次性用户 token 导入通过
args={"feishu_access_token": "u-..."}传入,且watch_interval <= 0。OpenViking 只在本次导入使用该用户 token,不保存。 - 飞书/Lark 用户 token watch 通过
args={"feishu_access_token": "u-...", "feishu_refresh_token": "r-..."}传入,且watch_interval > 0。OpenViking 会把 token 状态保存在 watch task 私有状态里,用配置的飞书应用凭证刷新,并在后续 watch 重跑中使用刷新后的用户 token。 - 飞书/Lark 用户 token watch 需要
FEISHU_APP_ID和FEISHU_APP_SECRET,或ov.conf中的feishu.app_id和feishu.app_secret。飞书 refresh token 绑定签发它的应用,因此传入的用户 token 必须来自 OpenViking 当前配置的同一个飞书应用。 - Watch task 的 token 状态保存在内部控制文件
viking://resources/.watch_tasks.json中,不会出现在 watch API/MCP/CLI 返回里。若启用了 VikingFS 文件加密,该控制文件会静态加密;否则服务端控制文件中会包含明文 token 状态。 - 本地目录输入会遵循
.gitignore(根目录和子目录,标准 Git 语义);ignore_dirs、include、exclude会在此基础上进一步过滤。 - 如果要直接创建或更新纯文本内容,请使用 content/write,不要使用
add_resource。资源导入和内容写入后都会自动刷新语义与 embedding。
3. 使用示例
HTTP API
POST /api/v1/resources
Content-Type: application/json# 从 URL 添加资源
curl -X POST http://localhost:1933/api/v1/resources \
-H "Content-Type: application/json" \
-H "X-API-Key: your-key" \
-d '{
"path": "https://example.com/guide.md",
"reason": "User guide documentation",
"wait": true
}'
# 添加资源但只生成向量,不走 VLM 语义理解
curl -X POST http://localhost:1933/api/v1/resources \
-H "Content-Type: application/json" \
-H "X-API-Key: your-key" \
-d '{
"path": "https://example.com/guide.md",
"to": "viking://resources/guide",
"processing_mode": "vectors_only",
"wait": true
}'
# 递归抓取网页:从入口页沿同域链接展开,depth 控制层数,max_pages 限制页数
curl -X POST http://localhost:1933/api/v1/resources \
-H "Content-Type: application/json" \
-H "X-API-Key: your-key" \
-d '{
"path": "https://docs.openviking.ai/zh/getting-started/01-introduction",
"wait": true,
"timeout": 60,
"args": { "depth": 1, "max_pages": 10 }
}'
# 从本地文件添加(需先使用 temp_upload 上传)
TEMP_FILE_ID=$(
curl -s -X POST http://localhost:1933/api/v1/resources/temp_upload \
-H "X-API-Key: your-key" \
-F "file=@./documents/guide.md" \
| jq -r '.result.temp_file_id'
)
curl -X POST http://localhost:1933/api/v1/resources \
-H "Content-Type: application/json" \
-H "X-API-Key: your-key" \
-d "{
\"temp_file_id\": \"$TEMP_FILE_ID\",
\"to\": \"viking://resources/guide.md\",
\"reason\": \"User guide\"
}"
# 添加到当前用户私有资源根
curl -X POST http://localhost:1933/api/v1/resources \
-H "Content-Type: application/json" \
-H "X-API-Key: your-key" \
-d "{
\"temp_file_id\": \"$TEMP_FILE_ID\",
\"parent\": \"viking://user/resources/docs\",
\"create_parent\": true
}"
# 使用一次性用户 access token 添加飞书文档
curl -X POST http://localhost:1933/api/v1/resources \
-H "Content-Type: application/json" \
-H "X-API-Key: your-key" \
-d '{
"path": "https://example.feishu.cn/docx/doc_token",
"args": {
"feishu_access_token": "u-..."
}
}'
# 使用用户 token 自动刷新添加飞书文档
curl -X POST http://localhost:1933/api/v1/resources \
-H "Content-Type: application/json" \
-H "X-API-Key: your-key" \
-d '{
"path": "https://example.feishu.cn/docx/doc_token",
"to": "viking://resources/feishu/doc",
"watch_interval": 1440,
"args": {
"feishu_access_token": "u-...",
"feishu_refresh_token": "r-..."
}
}'Python SDK
import openviking as ov
# 使用嵌入式模式(以后不再推荐和详细介绍)
client = ov.OpenViking(path="./data")
client.initialize()
# 使用 HTTP 客户端模式
client = ov.SyncHTTPClient(url="http://localhost:1933", api_key="your-key")
client.initialize()
## 添加本地文件
result = client.add_resource(
"./documents/guide.md",
reason="User guide documentation"
)
print(f"Added: {result['root_uri']}")
## 从 URL 添加到指定位置
result = client.add_resource(
"https://example.com/api-docs.md",
to="viking://resources/external/api-docs.md",
reason="External API docs"
)
## 递归抓取网页(同域 BFS,depth 层数、max_pages 页数上限)
result = client.add_resource(
"https://docs.openviking.ai/zh/getting-started/01-introduction",
wait=True,
timeout=180,
args={"depth": 1, "max_pages": 10},
)
## 递归抓取并按路径前缀过滤,同时下载页面中的文件链接
result = client.add_resource(
"https://docs.openviking.ai/",
args={
"depth": 2,
"max_pages": 50,
"include_paths": ["/zh/"],
"exclude_paths": ["/changelog"],
"skip_download_links": False,
},
)
## 添加到当前用户私有资源根
result = client.add_resource(
"./documents/guide.md",
parent="viking://user/resources/docs",
create_parent=True,
)
## 等待处理完成
client.wait_processed()
## 开启定时更新
client.add_resource(
"./documents/guide.md",
to="viking://resources/guide.md",
watch_interval=60 # 每60分钟更新一次
)
# 使用一次性用户 access token 添加飞书文档
client.add_resource(
"https://example.feishu.cn/docx/doc_token",
args={"feishu_access_token": "u-..."},
)
# 使用用户 token 自动刷新添加飞书文档
client.add_resource(
"https://example.feishu.cn/docx/doc_token",
to="viking://resources/feishu/doc",
watch_interval=1440,
args={
"feishu_access_token": "u-...",
"feishu_refresh_token": "r-...",
},
)TypeScript SDK
const task = await client.addResource("https://example.com/docs", {
to: "viking://resources/docs/",
wait: true,
});
console.log(task);Go SDK
result, err := client.AddResource(ctx, "./documents/guide.md", &openviking.AddResourceOptions{
Reason: "User guide documentation",
Wait: true,
})
if err != nil {
return err
}
fmt.Println(result["root_uri"])CLI
# 添加本地文件
ov add-resource ./documents/guide.md --reason "User guide"
# 从 URL 添加
ov add-resource https://example.com/guide.md --to viking://resources/guide.md
# 递归抓取网页:默认只抓入口页,depth>0 才沿同域链接展开
ov add-resource "https://docs.openviking.ai/zh/getting-started/01-introduction" \
--args="depth:1,max_pages:10"
# 递归抓取并按路径前缀过滤(只抓 /zh/,排除 changelog)
ov add-resource "https://docs.openviking.ai/" \
--args='{"depth":2,"max_pages":50,"include_paths":["/zh/"],"exclude_paths":["/changelog"]}'
# 默认跳过页面里的下载链接;如需一并下载 PDF/TXT/MD 等,显式关闭跳过
ov add-resource "https://example.com/docs" \
--args="depth:1,max_pages:20,skip_download_links:false"
# 等待处理完成
ov add-resource ./documents/guide.md --wait
# 开启定时更新(每60分钟检测一次)
ov add-resource https://github.com/example/repo.git --to viking://resources/my_repo --watch-interval 60
# 开启定时更新并自动绑定本次导入生成的 URI
ov add-resource https://github.com/example/repo.git --watch-interval 60
# 取消定时更新
ov add-resource https://github.com/example/repo.git --to viking://resources/my_repo --watch-interval 0
# 使用一次性用户 access token 添加飞书文档
ov add-resource https://example.feishu.cn/docx/doc_token --args feishu_access_token:u-...
# 使用用户 token 自动刷新添加飞书文档
ov add-resource https://example.feishu.cn/docx/doc_token \
--to viking://resources/feishu/doc \
--watch-interval 1440 \
--args feishu_access_token:u-... \
--args feishu_refresh_token:r-...
# 添加到指定父目录(父目录必须存在)
ov add-resource ./documents/guide.md --parent viking://resources/docs
# 添加到当前用户私有资源根
ov add-resource ./documents/guide.md --parent viking://user/resources/docs
# 添加到指定 peer 的私有资源根
ov add-resource ./documents/guide.md \
--parent viking://user/alice/peers/web-visitor-alice/resources/docs
# 添加到指定父目录(父目录不存在时自动创建)
ov add-resource ./documents/guide.md -p viking://resources/docs/2026/05/07
# 或使用完整参数名
ov add-resource ./documents/guide.md --parent-auto-create viking://resources/docs/2026/05/07
# 使用路径变量配合自动创建父目录
ov add-resource ./documents/guide.md -p viking://resources/docs/{calendar:today}4. 响应示例
HTTP API 响应 (JSON, wait=true)
{
"status": "ok",
"result": {
"status": "success",
"root_uri": "viking://resources/guide.md",
"temp_uri": "viking://temp/username/04291108_b62dc7/guide.md",
"source_path": "./documents/guide.md",
"meta": {},
"errors": [],
"queue_status": {
"pending": 5,
"processing": 2,
"completed": 10
}
},
"telemetry": {
"operation_id": "550e8400-e29b-41d4-a716-446655440000"
}
}HTTP API 响应 (JSON, 非 Git wait=false)
{
"status": "ok",
"result": {
"status": "success",
"root_uri": "viking://resources/guide",
"temp_uri": "viking://temp/username/04291108_b62dc7/guide",
"source_path": "./documents/guide.md",
"meta": {},
"errors": [],
"task_id": "uuid-xxx"
}
}使用返回的 task_id 轮询 /api/v1/tasks/{task_id} 可查看队列完成情况。对于 wait=false 的 Git 仓库来源,同一个端点会跟踪完整后台导入,任务完成后的 result 会包含完整导入结果,包括 queue_status。
CLI 响应 (默认表格格式)
Note: Resource is being processed in the background.
Use 'ov wait' to wait for completion, or 'ov observer queue' to check status.
status success
root_uri viking://resources/01-overview
task_id uuid-xxxCLI 响应 (JSON 格式,使用 -o json)
{
"status": "success",
"root_uri": "viking://resources/01-overview",
"task_id": "uuid-xxx"
}字段说明
| 字段 | 类型 | 说明 |
|---|---|---|
status | string | 处理状态:"success" 成功,"error" 失败 |
root_uri | string | 资源在 OpenViking 中的最终 URI |
task_id | string | (可选,仅当 wait=false 时)可轮询 /api/v1/tasks/{task_id} 的任务 ID。非 Git 导入用于队列跟踪;Git 仓库导入用于完整后台导入跟踪。 |
temp_uri | string | 导入过程中生成的临时 URI |
source_path | string | 原始源文件路径或 URL |
meta | object | 资源解析过程中的元数据(如文件类型、大小等) |
errors | array | 处理过程中的错误列表 |
warnings | array | (可选)处理过程中的警告列表(仅在 strict=False 时可能出现) |
queue_status | object | (可选,仅当 wait=true 时)队列处理状态,包含 pending、processing、completed 计数 |
memory_linking | object | (可选,仅当 reason 触发记忆生成时)本次资源 URI 与用户记忆的关联结果 |
对于 wait=false 的 Git 仓库来源,后台任务的 task_type="add_resource",resource_id 等于返回的 root_uri。运行中的任务记录可能包含 stage;完成后的任务 result 会包含带有 semantic 和 embedding 汇总的 queue_status。
temp_upload
上传临时文件,用于后续通过 add_resource 或 add_skill 导入本地文件。
1. API 实现介绍
此接口用于把本地文件上传到服务端托管的临时存储中,返回 temp_file_id 供后续 API 使用。这是一个辅助接口,通常不直接调用,而是通过 SDK 或 CLI 自动使用。
处理流程:
- 接收上传的文件
- 根据
upload_mode选择临时上传后端 - 保存文件并记录原始文件名
- 返回临时文件 ID
代码入口:
openviking/server/routers/resources.py:temp_upload- HTTP 路由openviking/service/resource_service.py- 服务实现
2. 接口和参数说明
参数
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| file | UploadFile | 是 | - | 上传的文件(multipart/form-data) |
| telemetry | bool | 否 | False | 是否返回遥测数据 |
| upload_mode | string | 否 | "local" | 临时上传模式。local 保持现有单机行为;shared 将文件上传到共享临时存储,适用于分布式部署。 |
说明:
- 默认值是
local,所以现有客户端在不改动的情况下仍保持原有行为。 - 只有在你明确需要分布式共享临时上传时,才应显式使用
upload_mode=shared。 shared模式下返回的一次性temp_file_id形如shared_<upload_id>。- shared 上传对象存放在内部
viking://upload/...命名空间下,不属于普通文件系统浏览空间。
3. 使用示例
HTTP API
POST /api/v1/resources/temp_upload
Content-Type: multipart/form-datacurl -X POST http://localhost:1933/api/v1/resources/temp_upload \
-H "X-API-Key: your-key" \
-F "file=@./documents/guide.md"分布式 / shared 上传:
curl -X POST http://localhost:1933/api/v1/resources/temp_upload \
-H "X-API-Key: your-key" \
-F "file=@./documents/guide.md" \
-F "upload_mode=shared"Python SDK
Python SDK 中的 add_resource、add_skill 等接口会自动处理本地文件上传,无需手动调用此接口。在 Python HTTP client 模式下,如果要启用分布式 shared 临时上传,可以在 ovcli.conf 中设置 upload.mode = "shared"。
Go SDK
client.AddResource、client.AddSkill、client.ImportOVPack 和 client.RestoreOVPack 会为本地文件自动调用 temp_upload。如需 shared 临时上传,设置 openviking.Config{UploadMode: "shared"}。
CLI
CLI 命令也会自动处理本地文件上传,无需手动调用此接口。
响应示例
{
"status": "ok",
"result": {
"temp_file_id": "upload_abc123def456.md"
},
"telemetry": {
"operation_id": "550e8400-e29b-41d4-a716-446655440000"
}
}shared 模式的响应示例:
{
"status": "ok",
"result": {
"temp_file_id": "shared_7f3c1b8d4f2e4b1bb0f6e8b2d9a4c123"
}
}