Jan 的 tauri-plugin-llamacpp 权限体系详解:47 个本地 LLM 推理权限的完整参考与生成机制
【免费下载链接】janJan is an open source alternative to ChatGPT that runs 100% offline on your computer.项目地址: https://gitcode.com/GitHub_Trending/ja/jan
本文基于 Jan 仓库中src-tauri/plugins/tauri-plugin-llamacpp/permissions/autogenerated/reference.md这份自动生成的权限参考文档展开,系统梳理 llamacpp 插件的全部 47 个默认权限、allow/deny 成对授权的命名规范,并对照 build.rs、lib.rs 与能力配置(capabilities)说明这些权限是如何被生成、注册并下发给各窗口的。读完后你可以精确掌握 Jan 本地推理层前端调用后端命令的授权边界,以及如何在 Tauri 插件中排查“命令 not allowed”类运行时问题。
一、这份权限参考文档定位在哪一层
Jan 是一个完全在本地运行的离线聊天应用,其本地 LLM 推理能力由 Tauri 插件tauri-plugin-llamacpp提供:前端 web-app 通过invoke调用 Rust 侧命令,完成 llama.cpp 后端进程的加载/卸载、推理服务路由(router)管理、GGUF 模型元数据解析以及推理后端(backend)的安装、校验与更新。
由于 Tauri 的安全模型要求「每条命令默认不可达,除非被能力文件显式授权」,插件必须为每个可调用命令生成一组权限标识符(permission identifier)。reference.md正是 Tauri 插件构建脚本自动生成(文件头部标注Automatically generated风格的产物,位于 permissions/autogenerated/reference.md)的权限清单,它回答三个问题:
- 默认权限集(
llamacpp:default)包含哪些权限; - 每个权限标识符(如
llamacpp:allow-load-llama-model)对应哪条 Rust 命令、语义是什么; - allow 与 deny 的成对关系:每个命令恰好对应一个
allow-*和一个deny-*标识符。
二、Default Permission:默认权限集完整清单
参考文档开头的 “Default Permission” 一节声明:llamacpp插件的默认权限集(即llamacpp:default)包含 47 个权限。与默认集一一对应的源文件是 permissions/default.toml,其中按功能分为五组,注释即分组依据:
2.1 进程清理组(Cleanup)
| 权限标识符 | 对应命令 | 作用 |
|---|---|---|
llamacpp:allow-cleanup-llama-processes | cleanup_llama_processes | 清理残留的 llama 进程 |
该命令实现位于 src/cleanup.rs,并在 lib.rs 中通过pub use cleanup::cleanup_llama_processes;对外导出,供应用主进程复用。
2.2 LlamaCpp 服务与 Router 组(20 个)
这一组是插件的核心运行时能力,覆盖推理会话的加载、路由管理与进程探活:
| 权限标识符 | 对应命令 | 作用 |
|---|---|---|
llamacpp:allow-load-llama-model | load_llama_model | 加载 GGUF 模型并启动/接入推理会话 |
llamacpp:allow-unload-llama-model | unload_llama_model | 卸载模型、释放会话 |
llamacpp:allow-start-router | start_router | 启动 router 模式推理服务 |
llamacpp:allow-stop-router | stop_router | 停止 router |
llamacpp:allow-try-graceful-stop-router | try_graceful_stop_router | 尝试优雅停止 router |
llamacpp:allow-force-kill-router-tree | force_kill_router_tree | 强杀 router 进程树 |
llamacpp:allow-get-router-info | get_router_info | 获取 router 运行信息 |
llamacpp:allow-reload-router-models | reload_router_models | 重新加载 router 上的模型列表 |
llamacpp:allow-router-slots-idle | router_slots_idle | 查询 router 空闲 slot |
llamacpp:allow-router-health | router_health | 探活 router 健康状态 |
llamacpp:allow-adopt-router | adopt_router | 接管一个已存在的 router 实例 |
llamacpp:allow-get-devices | get_devices | 枚举 GPU/CPU 设备信息 |
llamacpp:allow-generate-api-key | generate_api_key | 生成本地推理服务的 API Key |
llamacpp:allow-is-process-running | is_process_running | 判断指定进程是否在运行 |
llamacpp:allow-ensure-session-ready | ensure_session_ready | 确保目标模型所在会话就绪 |
llamacpp:allow-get-random-port | get_random_port | 获取随机可用端口 |
llamacpp:allow-find-session-by-model | find_session_by_model | 按模型查找会话 |
llamacpp:allow-get-loaded-models | get_loaded_models | 列出已加载模型 |
llamacpp:allow-get-all-sessions | get_all_sessions | 列出全部会话 |
llamacpp:allow-get-session-by-model | get_session_by_model | 按模型名取会话 |
router 相关命令的实现在 src/router.rs 与 src/commands.rs 中(build.rs 的注释将其标注为 “Router-mode commands (Phase 1)”)。
2.3 GGUF 模型元数据组(4 个)
| 权限标识符 | 对应命令 | 作用 |
|---|---|---|
llamacpp:allow-read-gguf-metadata | read_gguf_metadata | 读取 GGUF 文件的元数据(张量、架构等) |
llamacpp:allow-estimate-kv-cache-size | estimate_kv_cache_size | 估算 KV Cache 内存占用,用于显存/内存规划 |
llamacpp:allow-get-model-size | get_model_size | 获取模型文件大小 |
llamacpp:allow-is-model-supported | is_model_supported | 判断当前后端是否支持该模型 |
这组命令位于 src/gguf/commands.rs,在 lib.rs 中以gguf::commands::前缀注册。
2.4 后端管理组(Backend Management,14 个)
| 权限标识符 | 对应命令 | 作用 |
|---|---|---|
llamacpp:allow-map-old-backend-to-new | map_old_backend_to_new | 将旧版后端标识映射为新标识 |
llamacpp:allow-get-local-installed-backends | get_local_installed_backends | 列出本机已安装的后端 |
llamacpp:allow-list-supported-backends | list_supported_backends | 列出受支持的后端清单 |
llamacpp:allow-determine-supported-backends | determine_supported_backends | 根据当前机器环境判定可用后端 |
llamacpp:allow-get-supported-features | get_supported_features | 获取后端支持的特性(如 flash attention 等) |
llamacpp:allow-is-cuda-installed | is_cuda_installed | 检测 CUDA 是否安装 |
llamacpp:allow-find-latest-version-for-backend | find_latest_version_for_backend | 查找某后端的最新版本 |
llamacpp:allow-prioritize-backends | prioritize_backends | 对候选后端排序/定优先级 |
llamacpp:allow-parse-backend-version | parse_backend_version | 解析后端版本字符串 |
llamacpp:allow-check-backend-for-updates | check_backend_for_updates | 检查后端是否有更新 |
llamacpp:allow-remove-old-backend-versions | remove_old_backend_versions | 移除旧版本后端 |
llamacpp:allow-validate-backend-string | validate_backend_string | 校验version/backend字符串格式 |
llamacpp:allow-should-migrate-backend | should_migrate_backend | 判定是否需要迁移后端 |
llamacpp:allow-handle-setting-update | handle_setting_update | 处理设置变更并触发的后端联动 |
这些命令集中在 src/backend.rs。与之配合的依赖分析逻辑(例如运行时库校验)位于 src/deps_analyzer.rs。
2.5 后端路径与下载组(Backend Path & Download,8 个)
| 权限标识符 | 对应命令 | 作用 |
|---|---|---|
llamacpp:allow-get-backend-dir | get_backend_dir | 获取后端的安装目录 |
llamacpp:allow-get-backend-exe-path | get_backend_exe_path | 获取后端可执行文件路径 |
llamacpp:allow-check-backend-installed | check_backend_installed | 检查后端是否已安装 |
llamacpp:allow-verify-backend-installation | verify_backend_installation | 校验后端安装的完整性 |
llamacpp:allow-fetch-remote-supported-backends | fetch_remote_supported_backends | 拉取远端受支持后端清单 |
llamacpp:allow-build-backend-download-items | build_backend_download_items | 构造后端下载任务项 |
llamacpp:allow-fetch-backend-checksums | fetch_backend_checksums | 获取后端包的校验和 |
llamacpp:allow-verify-file-sha512 | verify_file_sha512 | 校验下载文件的 SHA-512 指纹 |
其中fetch_backend_checksums与verify_file_sha512是下载完整性链路的最后两道关口:先拉取远端公布的校验和,再对本地文件做 SHA-512 比对,防止损坏或被篡改的后端包被执行。
三、Permission Table:allow / deny 成对授权规范
参考文档的 “Permission Table” 一节(约 94 行表格)逐条给出每个权限的 Identifier 与 Description。其模式高度规整:
- 命名规范:
llamacpp:<allow|deny>-<snake_case 命令名转 kebab-case>。例如命令check_backend_for_updates对应llamacpp:allow-check-backend-for-updates与llamacpp:deny-check-backend-for-updates两个标识符; - 语义:
allow-*表示“无预置 scope 地启用该命令”,deny-*表示“无预置 scope 地拒绝该命令”。由于本插件的命令均不涉及作用域(scope)参数,权限粒度就是“整条命令开或关”; - 与 Rust 命令一一对应:47 个命令 × 2 = 94 个权限标识符,与表格行数一致。
这一规整性来自 Tauri 插件的生成机制,每条权限同时落盘为独立的 TOML 文件。以 permissions/autogenerated/commands/load_llama_model.toml 为例,其内容为:
"$schema" = "../../schemas/schema.json" [[permission]] identifier = "allow-load-llama-model" description = "Enables the load_llama_model command without any pre-configured scope." commands.allow = ["load_llama_model"] [[permission]] identifier = "deny-load-llama-model" description = "Denies the load_llama_model command without any pre-configured scope." commands.deny = ["load_llama_model"][permissions/autogenerated/commands/](https://link.gitcode.com/i/e922d0e46858851d5c23b9ca0538d5a1)目录下共有 29 个这样的文件(每文件覆盖该目录下命令的 allow/deny 对),配合 permissions/schemas/schema.json 供编辑器做 schema 校验。
四、生成机制:COMMANDS 名单、命令注册与三重一致性守卫
理解这份参考文档的可靠性,关键在 build.rs。它维护一份COMMANDS: &[&str]名单(47 条,分组注释与 default.toml 完全一致),然后交给 Tauri 插件构建器:
fn main() { tauri_plugin::Builder::new(COMMANDS).build(); }tauri_plugin::Builder会在构建期自动生成permissions/autogenerated/下的命令 TOML、reference.md参考文档与 schema——这就是为什么参考文档标题声明“自动生成的默认权限集”,手工编辑它没有意义,正确做法是修改build.rs与default.toml。
命令真正对外暴露则在 src/lib.rs:init()函数用Builder::new("llamacpp")构建插件,invoke_handler(tauri::generate_handler![...])中按cleanup::、commands::、backend::、gguf::commands::四个模块前缀登记全部 47 个命令,并在setup阶段把LlamacppState注入应用状态管理。
更值得注意的是 lib.rs 末尾的permission_tests模块,它把“文档/权限/注册三方一致”做成了编译期可执行的测试:
every_registered_command_has_a_permission:解析generate_handler[,断言每条命令的allow-*条目都在默认权限集中(标识符通过allow-+ 下划线转连字符构造,如allow-verify-file-sha512);- 两份名单均用
include_str!直接内嵌源码文本做静态比对,无需启动应用即可在cargo test中运行。
从源码结构看,这三处名单(generate_handler!、build.rs COMMANDS、default.toml)与本文第二部分列出的 47 项完全锁步,reference.md只是它们的文档化投影。
五、权限如何落地到窗口:capabilities 能力文件
Tauri 中“插件有权限”不等于“某个窗口能用”,最终授权由能力(capability)文件完成。Jan 主应用在 src-tauri/capabilities/ 下按窗口拆分授权:
- capabilities/default.json(作用于
main窗口)与 capabilities/desktop.json 都整体引用"llamacpp:default",即一次性授予上文的完整 47 项默认权限集,保证主界面可以做模型加载、router 管理、后端更新等全部本地推理操作; - capabilities/system-monitor-window.json(系统监控窗口)则只做最小化选授:
"llamacpp:allow-get-devices"与"llamacpp:allow-read-gguf-metadata"两条——监控窗口只需要设备信息和模型元数据,不应触碰进程清理或后端下载类权限。
这正是 Tauri 权限体系的用武之地:同一个插件,主窗口拿默认全集,辅助窗口拿只读子集,攻击面随窗口职责收窄。前端侧的调用入口在 guest-js/index.ts,它从@tauri-apps/api/core导入invoke封装各命令调用,并附带normalizeLlamacppConfig等参数规范化逻辑(例如check_for_updates缺省为true、timeout缺省 600 秒、models_max缺省 1),与插件 npm 包 package.json 中声明的@janhq/tauri-plugin-llamacpp-api(依赖@tauri-apps/api >=2.0.0-beta.6)共同构成前端 API 层。
六、检索与维护视角:如何使用这份参考文档
对开发者而言,这份reference.md有三个实用入口:
- 排查权限错误:当 web-app 侧调用抛出
not allowed或Command not found时,先在本表中反查命令对应的allow-*标识符,再确认目标窗口的 capability 文件(如 capabilities/default.json)是否包含llamacpp:default或对应的单条权限; - 审计最小权限:核对某窗口实际被授了哪些
llamacpp:*权限,判断是否存在“监控窗口能强杀 router”这类越权配置(当前仓库中 system-monitor-window 只授了只读两项,符合最小化原则); - 理解命令边界:每个
allow-*行的 Description 直接指出其绑定的 Rust 命令名,可据此跳转 src/ 下对应模块(commands.rs、backend.rs、gguf/、router.rs、process.rs、device.rs)阅读实现,例如ensure_session_ready与router_health的探活/就绪语义、estimate_kv_cache_size的内存估算逻辑等,均能在此找到对应源码。
需要说明的是:本文所有权限标识符、命令名与分组均以当前仓库中的 permissions/autogenerated/reference.md、permissions/default.toml 与 build.rs 为准;该插件为 Tauri v2 架构(@tauri-apps/api >=2.0.0-beta.6),其权限模型(default 集 + 按命令 allow/deny 成对 + capability 按窗口授权)与仓库中其他插件(tauri-plugin-hardware、tauri-plugin-rag、tauri-plugin-vector-db等)保持同一范式,可参照同一方法阅读各自的权限文档。
【免费下载链接】janJan is an open source alternative to ChatGPT that runs 100% offline on your computer.项目地址: https://gitcode.com/GitHub_Trending/ja/jan
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考