更新日志¶
这里只记录对用户可见的变化。完整 commit 历史见 gitea 仓库(内部) 或公开发布对应的 GitHub 镜像。
v0.21.1 — 子代理级 LLM 覆盖、KB 来源分层生命周期、NetBox CSV 同步¶
状态:进行中(rc4 之后,准备打 tag)。
新增¶
- 子代理级 LLM 覆盖。 每个
SKILL.md/AGENT.md现在可以带一个 可选的llm:块,字段任选model、temperature、max_tokens、base_url、model_provider、num_ctx、num_predict。缺省字段 回退到全局api.json.llm.*。不引入 profile 中间层 —— 单条 fall-through 链。仓内消费者: sim、investigate、learner→temperature: 0.0(确定性输出)core/memory_curator→max_tokens: 4096(R102 HITL 消息很短)analyzer(不覆盖)— 继承全局 32K- 全局
max_tokens由 16000 提到 32768。 gemma4:31b nothink 现在 能生成长结构化表格 / 报告而不被截断。若不需要可在 skill 层单独 覆盖(memory_curator 就是反过来的例子)。 - 来源分层 KB 生命周期(见
dev_docs/79)。 每个*.guide.yaml都带一个source_tier字段(vendor/platform/team/user)。优先级 + 检索权重由 tier 推导,不再是手设整数。 - R102 对话注入落在
source_tier: user(priority 3,weight 0.83) —— 操作员临时口述规则不会误盖架构性 invariant - 旧 schema v1 仍能加载(默认 =
usertier,向后兼容已显式声明的priority:字段) - 新 CLI:
olav kb remove <intent> --reason "..."(写 tombstone YAML + 删 LanceDB 行 +kb_audit/<ts>_remove_<intent>.yaml审计行)、olav kb show <intent>、olav kb list-guides --tier <name> kb_audit/git-可追踪审计链。 每次 KB 写操作(R102 commit、kb remove、NetBox push)都会落一行kb_audit/<iso-ts>_<verb>_<intent>.yaml,含action / intent / actor / timestamp / body_sha256+ 结果计数。 跟audit.duckdb互补 —— git 跟踪,独立于运行时 DB 存活。olav userCLI。olav admin add-user/...的友好别名。olav user create <name>默认要求该 Linux 用户已存在 (pwd.getpwnam(name))—— OLAV 用户模型对齐操作系统,不引入 平行身份。token 以 hash + salt 存储,明文只在 create 时显示一次。 容器场景可用--no-verify跳过 Linux 检查。- 采集时凭证脱敏(
olav.core.redaction.scrub,ADR-0008)。 两层脱敏管道在网络配置进入audit.duckdb或导出数据集之前去除 密码 / SNMP community / BGP MD5 key / IPSec PSK / TACACS / RADIUS 共享密钥,同时保留 IP / 主机名 / ASN / 拓扑关系,使 diff 和故障 诊断逻辑仍可正常工作。 - 采集层:
olav.core.redaction.scrub封装 netconan(Batfish 团队 出品,~50KB 纯 Python;内置 55 条敏感项 regex + 5213 个保留词; 每个 workspace 独立.redaction_salt文件 chmod 600)。接入netops_init/run.py:_collect_cmd(采集边界)和AuditEventRecorder.record_message(chat / LLM 文本的纵深防御)。 替换标记netconanRemovedN。 - 企业网关层:
audit_recorder.redact_sensitive(5 条 regex 产出[REDACTED])驱动audit_dataset_export.redact_audit_run的 Layer 1,并在 gate-check 阶段再次运行作为最终逃逸检测器。 - 配置:
api.json.redaction.{enabled, anon_ip, extra_sensitive_words, extra_reserved_words}+OLAV_REDACTION=0环境变量总开关。通过pip install 'olav[redaction]'安装拉取netconan>=0.13; 未安装时 OLAV 仍可运行,Layer 1 默认 fail-open 并打 WARNING。 tests/governance/test_redaction.py16 条治理测试覆盖 Cisco / Junos / salt 管理 / fail-open 语义 / 幂等性。- NetBox CSV 同步链(
dev_docs/71Ch10)。读(netops)与写 (services)解耦的三阶段工作流,CSV 文件作为中间契约: olav --agent netops "/export_netbox_csv"—— 从netops.devices导出 NetBox-import-shape 的 CSV (列映射见netops/guides/netbox_csv_export.guide.yaml)olav --agent services "/import_netbox_csv"—— 干跑校验 CSV 形状,写exports/reports/netbox_import_dry_run.mdolav --agent services "/import_netbox_csv --write --endpoint ... --token ..."—— 真正向运行中的 NetBox 推送, 5 步幂等 lookup-or-create 链(site → manufacturer → device-type → device-role → platform → device),每次写 入都落一行kb_audit/审计
修复¶
- CLI 重新写入 audit 表。 v0.20.3 把
OLAV_MIDDLEWARE_MODE默认翻为middleware;CLI 调用路径 从未把OlavRunContextbind 到astream_events,导致AuditMiddleware._get_context()永远返回 None,每次工具调用 都静默 no-op。record_run_start又没传thread_id,sessionsUPSERT 守卫永远失败。两条都修:CLI 镜像 API server 的 context-bind 模式,并把thread_id=session_id or run_id串到每个 turn。结果:audit_runs / sessions / audit_events / audit_messages / audit_tool_calls在单次工具调用后全部正常写入。 - 不再发
reasoning_effort: minimal。 Ollama OpenAI-compat 严格 校验该字段,只接受high / medium / low / max / none。删除 ——chat_template_kwargs.enable_thinking=false已经覆盖 qwen3 / gemma4 nothink 路径。 olav skill install拒绝覆盖平台 workspace。 领域包安装 (如olav-netops)若携带了audit/的 dev-mirror,过去olav skill install会静默盖掉平台 bundled audit/。现在_PLATFORM_OWNED = {core, audit, services}命中已存在路径 直接跳过 + 警告,逃生口--force-overwrite。/netops_initingest 门控。 Stage 4 现在区分 "SSH 已收集" 和 "DB 已 ingest",当 ingest 录入 0 行但 SSH 收集成功时 打印❌ FAILED at the ingest stage+ 非零退出。之前 即使 ingest 报错也照样✅ Network initialization complete。- 5 个 SQL view schema guide 出厂
(
netops/guides/sql_schema_*.guide.yaml)— 记录 BGP / OSPF / interface / route / device-and-topology 各 view 的精确列名 + 可运行示例。AutoRecall 在 schema 探索查询时召 回;gemma4 nothink 首次 SQL 即可命中正确列,不再列名 trial- and-error。 olav usersubparser 新增。 CLI 此前只能走更啰嗦的olav admin add-user;olav user create / list / token / revoke现在是用户面 canonical 形式。- 平台 audit workspace 打入 wheel。 v0.21.1 前
pip install olav==0.19.0 && olav init只出 2 个 agent (core+services)—— audit/ 存在于 dev 仓但未进 wheel 的 data 路径。fresh install 现在出 3 个平台 agent (audit / core / services)。
迁移¶
- 无 flag-day。 schema v1
*.guide.yaml继续可加载,priming 时 按source_tier: user处理 + 一行 deprecation 警告。按需迁移即可; v2 形态 =schema_version: 2+ 显式source_tier:字段。 - R102 commit 降级到
usertier。 之前若依赖操作员口述规则 压过平台 guide,这条路径不再走通。要升级,请走 git PR 改 YAMLsource_tier: team并合入主线 review。 - Lab / CAB 内容已外迁。
lab/子代理 + CAB 流程 + TCF schema demo + fault-injection 脚本已搬到olav-ent。平台基 runsheet (dev_docs/71)删除旧 Ch7 + Ch8;企业 runsheet 接收它们。
v0.21.0 — Web UI agent 路由 + 服务生命周期硬化¶
状态:进行中(本文撰写时最新为 rc4)。
修复¶
- Web UI:左下角 agent dropdown 真的会切换运行的 graph。
rc2 之前,FastAPI server 用一个全局
_agent_instance单例; 你在 dropdown 里点 "ops" 只改了 audit 事件的 tag,背后跑的还是 core 的 graph。get_agent()现在是按assistant_id分键的 cache, 5 个 agent 可以各跑各的、互不污染。 POST /reload再次返回 200。 rc2 把单例换成 cache dict 时 忘了更新/reloadhandler,每次 reload 都抛NameError。 现在 handler 会遍历 cache、逐个 best-effort-close,然后清空。- Middleware 模式下 audit 能看到 run_id。 v0.20.3 把
OLAV_MIDDLEWARE_MODE默认改成middleware;但 web server 从没 给astream_events附带OlavRunContext,导致AuditMiddleware拿不到run_id— 每次 web 请求都没被审计。 现在两种模式都正确传 context。 - 刷新浏览器不丢 thread + agent 绑定。 WebUI 把
currentThreadId和每个 thread 的agentId都写进localStorage;F5 之后状态完整恢复。 core在/agents响应里强制置顶。 装了 olav-netops 后 多了 4 个按字母排在core前面的 workspace,导致 WebUI 默认 agent 变成了audit。server 端现在把core钉在 index 0。- 服务进程被钉到正确的 workspace。 rc4 之前,
uvicorn/ agent daemon / syslog receiver 从一个在模块 import 时冻结的PROJECT_ROOT常量推导 PID/log 路径。如果从带pyproject.toml的另一个仓库目录启 olav,spawned 进程会 silently 继承错误的 cwd、读错users.duckdb—— 所有登录都 401。现在改为基于.olav/标记、每次调用重算的 cwd,且Popen(..., cwd=...)显式传。 - 全新 wheel 安装下
olav service start --all跑得通。 其实 不是 bug —— 参数顺序是olav service <action> --all,从来 就对 —— 但 runsheet 示例已经重新验过。 olav skill install <path>仍然可用,通过 v0.21.0-rc4 的 deprecation shim。单数的skill分发器在 v0.20.3 已删;shim 原样转发给olav agent install并打印一行黄色 warning。 详见 CLI 参考 的迁移说明。
rc4 新增¶
scripts/sync_netops_workspace.py— 同步平台 vendored 的.olav/workspace/ops/与 olav-netops 的权威副本olav-netops/.olav/workspace/ops/。默认方向: root → olav-netops;--reverse反向;--check是 CI 漂移守护。
v0.20.3 — deepagents 迁移收官(P7 final)¶
- 移除
olav skill install子命令。 用olav agent install。 (v0.21.0-rc4 加了 deprecation shim 保留兼容,见上。) OLAV_MIDDLEWARE_MODE默认翻到middleware。 老的 callback plugin 仍可通过OLAV_MIDDLEWARE_MODE=callback使用,给AuditMiddleware留一个完整 release 的验证期。parse_subcommand_args渗透到 7 个 verb。 共享 helper 处理 argparse 的引号/空参/--边界。workspace_discovery.py合并。 三处重复的扫描器合成一处; CLI、web/agents、TUI 都走同一代码路径。
v0.20.2 — P1 + P2 + P6 cutover¶
- Native TUI(走
langgraph dev子进程)成为默认,替换 原先的 in-process overlay。OLAV_TUI_MODE=overlay可回退到 v0.19.x 路径紧急使用。 - Tool-loader 启动时自动发现
.deepagents/agents/<name>/tools/*.py和.deepagents/agents/<name>/skills/<skill>/tools/*.py。 - v0.20 workspace 布局迁移 通过
olav migrate v0_20_layout提供(幂等 +--dry-run)。
v0.20.1 — P3 middleware 迁移¶
AgentMiddleware子类 用于 audit / guardrails / memory-capture / memory-recall / uks-capture,与 callback plugin 路径并存。OLAV_MIDDLEWARE_MODE环境变量切换两条路径。
v0.20.0 — P5 graph 工厂 + olav agent install¶
olav agent install <path>作为公开安装 verb 出现。olav skill install还能用(两者共享底层 dispatcher);这个 release 是重命名的起点。graph_factory.build_graph()内部 API,按assistant_id构造 LangGraph — 为 v0.21.0-rc2 的 per-id cache 打基础。
v0.19.0 — deepagents 之前的最后一个版本¶
见 DEMO_RUNSHEET(历史存档)。