diff --git a/apps/README.md b/apps/README.md index 9a3c262a..6eaeea54 100644 --- a/apps/README.md +++ b/apps/README.md @@ -356,7 +356,7 @@ octos UI Protocol v1. kernel, a WebSocket or REST) and `octos-app-render` (streaming-markdown renderer). - **octos**: every octos crate comes from git `octos-org/octos` at the one - rev in the root `Cargo.toml` `[workspace.dependencies]` (today `e045c727`, + rev in the root `Cargo.toml` `[workspace.dependencies]` (today `fe08d8e6`, octos `main`), shared with `crates/kernel` and the shells. AppCard starts no kernel of its own: it connects to the shell's ([The octos kernel](#the-octos-kernel)). - **Makepad**: not vendored. Makepad, Octoscript and Octoscript-Makepad are @@ -440,7 +440,7 @@ plus an entry in each shell's `system-apps.json`. | [OctoScript-App-Design-Flow](https://github.com/OctoSense-org/OctoScript-App-Design-Flow) | how to design, build, check and publish an app | | [OctoScript](https://github.com/OctoSense-org/OctoScript), [OctoScript-Makepad](https://github.com/OctoSense-org/OctoScript-Makepad), [makepad](https://github.com/OctoSense-org/makepad) | the language and runtime | | [Rinx](https://github.com/hagency-org/Rinx) | Matrix chats and mini apps, a native module; reaches the assistant through `crates/app-peers` | -| [octos](https://github.com/octos-org/octos) | the agent kernel: run as a shell service by `crates/kernel`, configured by AI providers, used by AppCard and other consumers (one rev, `e045c727`) | +| [octos](https://github.com/octos-org/octos) | the agent kernel: run as a shell service by `crates/kernel`, configured by AI providers, used by AppCard and other consumers (one rev, `fe08d8e6`) | ## Contributing diff --git a/apps/README.zh-CN.md b/apps/README.zh-CN.md index 65e71b6c..60991709 100644 --- a/apps/README.zh-CN.md +++ b/apps/README.zh-CN.md @@ -314,7 +314,7 @@ octos UI Protocol v1 与 octos 通信。 `octos-app-render`(流式 markdown 渲染)。 - **octos**:所有 octos crate 都来自 git `octos-org/octos`,版本为根目录 `Cargo.toml` 的 `[workspace.dependencies]` 中唯一的 rev(目前是 octos `main` 上的 - `e045c727`),与 `crates/kernel` 和 Shell 共用。AppCard 不再自己启动内核,而是连接 Shell 的内核 + `fe08d8e6`),与 `crates/kernel` 和 Shell 共用。AppCard 不再自己启动内核,而是连接 Shell 的内核 (见 [octos 内核](#octos-内核))。 - **Makepad**:不内置。Makepad、Octoscript 和 Octoscript-Makepad 是仓库根目录下 `.sources/` 中由 `tools/setup.py` 准备的检出,版本由 `native-runtime.lock.json` @@ -387,7 +387,7 @@ Shell 的 `system-apps.json` 中加入它。 | [OctoScript-App-Design-Flow](https://github.com/OctoSense-org/OctoScript-App-Design-Flow) | 如何设计、构建、检查和发布应用 | | [OctoScript](https://github.com/OctoSense-org/OctoScript)、[OctoScript-Makepad](https://github.com/OctoSense-org/OctoScript-Makepad)、[makepad](https://github.com/OctoSense-org/makepad) | 语言与运行时 | | [Rinx](https://github.com/hagency-org/Rinx) | Matrix 聊天与小程序,原生模块;通过 `crates/app-peers` 访问助手 | -| [octos](https://github.com/octos-org/octos) | Agent 内核:由 `crates/kernel` 作为 Shell 服务运行,由 AI providers 配置,供 AppCard 等使用方使用(只用一个版本 `e045c727`) | +| [octos](https://github.com/octos-org/octos) | Agent 内核:由 `crates/kernel` 作为 Shell 服务运行,由 AI providers 配置,供 AppCard 等使用方使用(只用一个版本 `fe08d8e6`) | ## 参与贡献 diff --git a/apps/appcard/README.md b/apps/appcard/README.md index 2caada61..2bbad3a8 100644 --- a/apps/appcard/README.md +++ b/apps/appcard/README.md @@ -42,7 +42,7 @@ docs/ Architecture, protocol, build and review notes. Every octos crate (`octos-core`, and on OpenHarmony `octos-cli` with the ~20 crates it pulls in) comes from **one** source: git `https://github.com/octos-org/octos.git` at the single rev in the repository's -root `Cargo.toml` `[workspace.dependencies]` (today `e045c727`, octos main), +root `Cargo.toml` `[workspace.dependencies]` (today `fe08d8e6`, octos main), shared with `crates/kernel` and both shells. octos's OpenHarmony-safe `nix` is patched in the root `[patch.crates-io]` (from octos `18fcd3f1`). There is no octos submodule; check the graph keeps one octos with diff --git a/apps/appcard/README.zh-CN.md b/apps/appcard/README.zh-CN.md index e06c26db..31aa0b76 100644 --- a/apps/appcard/README.zh-CN.md +++ b/apps/appcard/README.zh-CN.md @@ -39,7 +39,7 @@ docs/ 架构、协议、构建与评审笔记。 所有 octos crate(`octos-core`,以及 OpenHarmony 上的 `octos-cli` 和它引入的约 20 个 crate)都来自**同一个**来源:git `https://github.com/octos-org/octos.git`, 版本为仓库根目录 `Cargo.toml` 的 `[workspace.dependencies]` 中唯一的 rev(目前是 -octos main 上的 `e045c727`),与 `crates/kernel` 和两个 Shell 共用。octos 中适配 +octos main 上的 `fe08d8e6`),与 `crates/kernel` 和两个 Shell 共用。octos 中适配 OpenHarmony 的 `nix` 在根目录的 `[patch.crates-io]` 中 patch(来自 octos `18fcd3f1`)。 没有 octos submodule;可用 `cargo tree --locked -p octos-app -i octos-core --target all --depth 0` 检查依赖图中只有一份 octos。 diff --git a/crates/app-peers/tests/real_kernel.rs b/crates/app-peers/tests/real_kernel.rs index 1ac0c3ea..85885365 100644 --- a/crates/app-peers/tests/real_kernel.rs +++ b/crates/app-peers/tests/real_kernel.rs @@ -1064,17 +1064,14 @@ fn the_person_and_the_system_agent_talk_in_parallel_lanes_that_share_history() { let _ = std::fs::remove_dir_all(&dir); } -/// octos at the pin (e045c727) writes a turn's rows to its transcript only -/// when the turn ENDS, and the other lane's `` block is read -/// from that transcript. So while the system agent's turn on the peer is -/// running (here parked on a question nobody answers; in the two-lane -/// scenario, on an approval), the person's lane is shown nothing of it: not -/// even the system agent's request. Found by the shell's two-lane scenario -/// (`crates/shell/src/host_tools/scenario_tests.rs`); reported to octos. -/// Ignored until octos shows a running turn's prompt; run it with -/// `--ignored` to reproduce. +/// A turn still running in one lane is shown to the other (octos#2644, in +/// the pin; on top of octos#2636's shared history): its request, with its origin +/// marker, and a `[turn status]` line saying what it waits on, after the +/// finished rows. Here the system agent's turn on the peer is parked on a +/// question nobody answers (in the two-lane scenario, on an approval), and +/// the person's lane sees it while it runs. Found by the shell's two-lane +/// scenario (`crates/shell/src/host_tools/scenario_tests.rs`). #[test] -#[ignore = "octos e045c727 shares a lane's rows only after its turn ends"] fn a_running_turns_request_is_shown_to_the_other_lane() { let Some(program) = kernel() else { return }; let script = Path::new(env!("CARGO_MANIFEST_DIR")).join("tests/fixtures/mock_agent_llm.py"); @@ -1123,5 +1120,13 @@ fn a_running_turns_request_is_shown_to_the_other_lane() { drop(rinx); core.shutdown_within(Duration::from_secs(5)); let _ = std::fs::remove_dir_all(&dir); - assert!(shown.contains("[from the system agent] QUESTION_HOLD"), "the running turn's request is not shown to the person's lane: {shown}"); + assert!(shown.starts_with("SHARED - "), "the person's lane is shown the system agent's: {shown}"); + let rows: Vec<&str> = shown["SHARED ".len()..].split(" | ").map(|row| row.splitn(3, ' ').nth(2).unwrap_or(row)).collect(); + // The running turn comes last: its request, then its status (the + // question it asked is a tool call, so it streamed no text). + assert_eq!( + rows[rows.len().saturating_sub(2)..], + ["[from the system agent] QUESTION_HOLD", "[turn status] still running, waiting for an answer"], + "the running turn's request and status are shown to the person's lane: {shown}" + ); } diff --git a/crates/shell/src/host_tools/real_kernel_tests.rs b/crates/shell/src/host_tools/real_kernel_tests.rs index 146559c7..e79ebdb7 100644 --- a/crates/shell/src/host_tools/real_kernel_tests.rs +++ b/crates/shell/src/host_tools/real_kernel_tests.rs @@ -281,7 +281,9 @@ fn real_kernel_an_allowed_apps_agent_is_prepared_listed_and_shares_its_conversat loop { super::pump(); let sys_lane = seen.lock().unwrap().iter().filter(|d| d["lane"] == "system_agent").map(|d| d.to_string()).collect::>().join("\n"); - if sys_lane.contains("SHARED") { + // The model's answer ("SHARED - " or "SHARED NONE"), not the + // turn's own request ("SHOW_SHARED"), which arrives first. + if sys_lane.contains("SHARED -") || sys_lane.contains("SHARED NONE") { assert!(sys_lane.contains("focus the digest on technology"), "News's agent, asked by the system agent, sees the person's turn: {sys_lane}"); break; } diff --git a/crates/shell/src/host_tools/scenario_tests.rs b/crates/shell/src/host_tools/scenario_tests.rs index 44553c48..f91ae4a7 100644 --- a/crates/shell/src/host_tools/scenario_tests.rs +++ b/crates/shell/src/host_tools/scenario_tests.rs @@ -39,10 +39,11 @@ //! whole seconds, could deny an approval as expired just before the //! broker's own deadline, which then took it for an answer and never freed //! the stuck turn (an expiry deny is now marked as one, -//! `ApprovalAnswer::expired`). Not fixed here, octos's: a lane's rows are -//! shared with the other lane only once its turn ends +//! `ApprovalAnswer::expired`). Fixed in octos (octos#2644): a lane's rows +//! were shared with the other lane only once its turn ended; a running +//! turn's request and status are now shown too //! (`crates/app-peers/tests/real_kernel.rs`, -//! `a_running_turns_request_is_shown_to_the_other_lane`, ignored). +//! `a_running_turns_request_is_shown_to_the_other_lane`, and 3c below). //! //! What is not the real thing, and why: //! - the person's taps go through the approval surface's press handler, not @@ -552,13 +553,17 @@ fn the_system_agent_and_the_person_work_with_one_app_agent_at_once() { assert_eq!(question.options(), ["Team", "Everyone"]); assert!(crate::questions::open(&Conversation::SystemChat).iter().all(|q| q.app != APP), "not in the system chat"); - // The system agent's turn is still running, so octos (e045c727) has - // not written its rows yet: the person's lane is shown nothing of it. - // octos shares a lane's rows once its turn ends (reported with the PR); - // 3b below checks the sharing both ways on ended turns. + // The system agent's turn is still running (parked on the approval), so + // its rows are not in its transcript yet; octos shows the person's lane + // the running turn instead (octos#2644): its request and what it waits + // on (the tool's name only). 3b below checks the sharing both ways on + // ended turns. let requests = s.requests(); let asked = requests.iter().find(|r| r["own"].as_str().is_some_and(|u| u.contains("SCN_ASK"))).expect("the person's model request"); - eprintln!("[main] the person's lane was shown, while the system agent's turn ran: {}", asked["shared"]); + let running = asked["shared"].to_string(); + assert!(running.contains("lane=\\\"system_agent\\\"") && running.contains("[from the system agent] SCN_TASK"), "{running}"); + assert!(running.contains("[turn status] still running, waiting for approval: news_share"), "{running}"); + assert!(!running.contains("Quarterly numbers"), "no tool arguments: {running}"); // 4. The person answers in the shell's "Ask News" panel (G11: the // question of the app's conversation is shown there, not in the system diff --git a/crates/toolbox/README.md b/crates/toolbox/README.md index 0ebbf272..ca5debb6 100644 --- a/crates/toolbox/README.md +++ b/crates/toolbox/README.md @@ -166,7 +166,7 @@ Backends: - no cookies, credentials or proxies, and 401/402/403 are failures, so there is no paywall or login bypass; - **SSRF blocking** on every fetch and every redirect hop. Loopback, private, link-local (including cloud-metadata 169.254.169.254 and `fd00:ec2::254`), unique-local, shared (CGNAT), multicast, reserved and IPv4-mapped forms are refused, both as URL literals and in DNS answers. A resolver filters the addresses the connection actually uses, so DNS rebinding cannot get past the check. `localhost` names are refused. - **Licenses**: `dom_smoothie`, `dom_query`, `gjson`, `html-escape` (MIT), `flagset` (Apache-2.0), `quick-xml` (MIT), and Mozilla's `cssparser` and `selectors` (MPL-2.0, unmodified; the workspace already links them through `scraper`). All of these are behind the `live` feature. -- **The octos research engine** (`research::octos::OctosResearch`, feature `octos-engine`). It depends on `octos-research` through the workspace's one octos pin, and needs octos#2568 (reader), #2582 (metasearch), #2585 (`octos_research::toolbox`), #2590 (read-failure reasons, posts marked as posts) and #2594 (stub and consent pages, whole-topic feed matching, a soft deadline for slow engines), all in the pin (octos e045c727, which contains 3b5d17a4). It only finds and reads; everything under "The policy" above stays in the host unchanged. +- **The octos research engine** (`research::octos::OctosResearch`, feature `octos-engine`). It depends on `octos-research` through the workspace's one octos pin, and needs octos#2568 (reader), #2582 (metasearch), #2585 (`octos_research::toolbox`), #2590 (read-failure reasons, posts marked as posts) and #2594 (stub and consent pages, whole-topic feed matching, a soft deadline for slow engines), all in the pin (octos fe08d8e6, which contains 3b5d17a4). It only finds and reads; everything under "The policy" above stays in the host unchanged. - **One definition of an app's reach.** The app's grant **is** `octos_research::toolbox::Scope`; nothing is mapped. Each search is narrowed by octos's `Scope::search_args`, in the host (above) and again here, so a language, region, category or domain outside the grant is refused there and the recency is clamped. The search asks the engines for a candidate pool of three times the app's `limit` (at most 30, `candidate_pool`) so the host's filters still leave `limit`; `max_results` bounds what the app gets, not the pool. Each read is checked with `Scope::check_domain` twice: the link, then the page the browser ended on, the publisher for a Google News link. - **Search** is the octos metasearch (`octos_research::metasearch`), category `news`: Google News in the language's own edition, GDELT, publisher feeds, Hacker News and Mastodon, plus keyed engines when their keys are set. - Octos fans the query out under a 15 s deadline, then merges, deduplicates and ranks the results. It spaces requests per host, honours `Retry-After`, caches with ETags, and suspends a failing engine with doubling backoff. That backoff is how GDELT's 429s are handled. diff --git a/docs/adr/0004-native-apps-hosting-and-peers.md b/docs/adr/0004-native-apps-hosting-and-peers.md index 890b024b..d2bb89f2 100644 --- a/docs/adr/0004-native-apps-hosting-and-peers.md +++ b/docs/adr/0004-native-apps-hosting-and-peers.md @@ -3,7 +3,7 @@ - **Date:** 2026-09-28 - **Status:** Accepted (2026-09-28); amended 2026-09-29 (section 6: `host.ask` dropped for octos's `ask_user_question`; sections 10 and 12: `terminal.run` only where the Terminal runs as a process; factual corrections from the gap review, marked where made; sections 4 and 8: interactive app cards; section 6: one shared conversation per app agent, then the same day two parallel lanes that share history; follow-ups from the 2026-09-29 code review; section 4: which apps have an agent, peers prepared at consent, the shell's "Ask " panel); **Implemented** (2026-09-29): every plan step and every gap from the 2026-09-28 review is on `main`, and the full CI (Desktop, Phone, Apps and services, ROM) passed on `74e1d713`. The follow-ups below remain open work, not part of this decision's implementation. - **Scope:** How OctoSense declares, links, hosts, isolates and trusts its bundled native Rust apps on each target; where every app keeps its data and what its agent may read; how every bundled app, native or script, owns an octos app agent; how the system agent and app agents work across apps; and how the person approves what they do, live or in advance. -- **Relates to:** [ADR 0001](0001-one-octosense-repository.md); [ADR 0002](0002-event-driven-app-agents.md) (app agents; amended by this ADR); [Home ADR 0002](home/0002-agentic-app-security-model.md) and [Home ADR 0004](home/0004-system-apps-are-contained-script-apps.md) (amended); Rinx [ADR 0007](https://github.com/hagency-org/Rinx/blob/main/docs/adr/0007-host-owned-octos-app-peers.md); octos UPCR-2026-034 (host-owned app peers, merged), UPCR-2026-035 ([octos#2567](https://github.com/octos-org/octos/pull/2567), host tools per app peer, merged; OctoSense pins its follow-ups, now octos e045c727 with octos#2621 and #2626) and UPCR-2026-036 (`serve --host-managed`, [octos#2591](https://github.com/octos-org/octos/pull/2591), merged); [octos#2601](https://github.com/octos-org/octos/pull/2601) (tool origin, per-connection ownership); [ADR 0003](0003-shared-octos-client-access.md) (Talk to Octos, OctoSense [#98](https://github.com/OctoSense-org/OctoSense/pull/98): external clients never reach app agents). +- **Relates to:** [ADR 0001](0001-one-octosense-repository.md); [ADR 0002](0002-event-driven-app-agents.md) (app agents; amended by this ADR); [Home ADR 0002](home/0002-agentic-app-security-model.md) and [Home ADR 0004](home/0004-system-apps-are-contained-script-apps.md) (amended); Rinx [ADR 0007](https://github.com/hagency-org/Rinx/blob/main/docs/adr/0007-host-owned-octos-app-peers.md); octos UPCR-2026-034 (host-owned app peers, merged), UPCR-2026-035 ([octos#2567](https://github.com/octos-org/octos/pull/2567), host tools per app peer, merged; OctoSense pins its follow-ups, now octos fe08d8e6 with octos#2621, #2626, #2636 and #2644) and UPCR-2026-036 (`serve --host-managed`, [octos#2591](https://github.com/octos-org/octos/pull/2591), merged); [octos#2601](https://github.com/octos-org/octos/pull/2601) (tool origin, per-connection ownership); [ADR 0003](0003-shared-octos-client-access.md) (Talk to Octos, OctoSense [#98](https://github.com/OctoSense-org/OctoSense/pull/98): external clients never reach app agents). ## Context @@ -43,7 +43,7 @@ ### What octos provides (octos `main` e6223ef, verified) -Verified at e6223ef when this ADR was written. OctoSense now pins octos e045c727 (the merge of octos#2636, the parallel person context with shared history; after #2626, the shared peer conversation, #2630, `peer_gather` accepting the kernel's own `result.md`, #2621, `peer/input/reject`, and #2616, the #2567 follow-ups); the corrections dated 2026-09-29 below were checked against c608384d, the pin before it. +Verified at e6223ef when this ADR was written. OctoSense now pins octos fe08d8e6 (the merge of octos#2645; it holds #2644, a running turn shown in the other lane's shared history, and #2636, the parallel person context with shared history; after #2626, the shared peer conversation, #2630, `peer_gather` accepting the kernel's own `result.md`, #2621, `peer/input/reject`, and #2616, the #2567 follow-ups); the corrections dated 2026-09-29 below were checked against c608384d, the pin before it. - **Peers are sessions, not processes.** One kernel process per shell; every peer is a session in it (tokio tasks) with its own workspace, memory namespace, transcript and model lane. Tools such as the shell run as short child processes in the peer's workspace. - **No 8-peer ceiling.** `peer/prepare` stages 1–8 peers **per call** (`n`); the only total is a soft cap of 8192 live peer registrations. The model's `peer_handoff` tool is limited to 4 per turn; host-owned app peers are not created through it. OctoSense's broker prepares one peer per call. @@ -165,7 +165,7 @@ The shell stamps the app's identity from the socket, enforces #2567's host oblig - **Two parallel lanes that share history, per app agent (decided 2026-09-29).** Each app agent (a host-owned app peer) has two sessions that run **in parallel** and **share history read-only**. *(This supersedes, the same day, the single shared conversation of OctoSense [#166](https://github.com/OctoSense-org/OctoSense/pull/166) and octos [#2626](https://github.com/octos-org/octos/pull/2626): one peer session that the person's turns and the system agent's `peer/input`s both drove, queued one turn at a time. The system agent's long work blocked the person, and the person's chat blocked the system agent.)* - **The system agent's lane** is the peer's own session (`…#peer-`), driven by `peer/input` (the system agent's `peer_send_input`) as before, with its own queue. - **The person's lane** is a request context (`…#peerctx-.`) that the app opens with `share_history` (octos UPCR-2026-034, "Parallel person context with shared history", [#2636](https://github.com/octos-org/octos/pull/2636), pinned e045c727). A native module opens it with `OctosAppService::open_conversation`, a process app with `octos.session.open` over the peer link, and a script app or card with `host.request("octos.session.open")`. No system agent is involved. The broker opens a new context id for every handle (a closed id is never reopened) and starts the person's message there with `origin: {kind: "person", label: }`, or `app` when the app says it started the run itself (G2's `trigger: app | schedule | background | incoming`). G2's trigger stays the authority for approval rules: an unsaid turn is `person` for the label and `Unknown` for rules. A person-said turn keeps its `Person` trigger, so its questions go to the app's conversation. A person's turn waits only for its own context's previous turn. - - **Shared history, read-only.** At the start of each turn in one lane, the kernel shows the model the other lane's last N user and assistant text rows as a labelled, read-only block: "Recent turns in the system agent's conversation with this app" or "Recent turns in the person's conversation with this app". The defaults are N = 20 (at most 50) within 16 KiB. The block is read under the other session's persist lock, drops tool rows, names each row's speaker and is never written into the reader's transcript. **No shared transcript**: two writers on one transcript are rejected, because they break tool-call pairing and compaction. + - **Shared history, read-only.** At the start of each turn in one lane, the kernel shows the model the other lane's last N user and assistant text rows as a labelled, read-only block: "Recent turns in the system agent's conversation with this app" or "Recent turns in the person's conversation with this app". The defaults are N = 20 (at most 50) within 16 KiB. The block is read under the other session's persist lock, drops tool rows, names each row's speaker and is never written into the reader's transcript. A turn still running in the other lane is shown too, after the finished rows (octos [#2644](https://github.com/octos-org/octos/pull/2644)): its request with its speaker, the text it has streamed so far (`[the app agent] (in progress) …`) and a `[turn status]` line (`still running`, `waiting for approval: ` or `waiting for an answer`, never tool arguments). **No shared transcript**: two writers on one transcript are rejected, because they break tool-call pairing and compaction. - **What the system agent sees.** Each of the person's turns also leaves a round on the peer's blackboard (`result-.md` with `origin: person` and `context: `), so `peer_gather` shows it. A person's round alone never fires a fleet synthesis. - **Who speaks, and what the app sees.** #166's speaker labels stay. The kernel's `[from the person: Rinx] …` or `[from the system agent] …` marker leads the user message. The app's follower (`OctosContext::subscribe`, or `conversation` frames on the peer link) gets both lanes' events: its own context's and the system agent's turns on the peer session. Each event carries its `lane` (`person` or `system_agent`), its `speaker`, and a user message's `display_text`; a turn's caller hears only its own turn. `octos.session.history` returns both transcripts merged by `persisted_at`, each row with `lane` and, for a marked user message, `speaker` and `display_text`. Approvals and questions keep going to the shell's router and request model, routed by the turn's origin: the person's and the app's turns to the app's conversation, the system agent's to the system chat. - **Which API opens which.** `open_conversation` opens the person's lane. `open_context(client)` stays a plain request context, with no shared history, no origin and no blackboard round: Rinx's mini apps, and `octos.session.open` with a `client`. diff --git a/docs/ai-services.md b/docs/ai-services.md index 7be68ab8..e6f9f3d6 100644 --- a/docs/ai-services.md +++ b/docs/ai-services.md @@ -219,7 +219,7 @@ The tracking issue is [#68](https://github.com/OctoSense-org/OctoSense/issues/68 ### Desktop, with a throwaway kernel and profile -1. Build octos at the revision the root `Cargo.toml` pins (`e045c727`), in a checkout of [octos-org/octos](https://github.com/octos-org/octos) (the flags are `tools/kernel-artifact.py`'s; **unverified** at this revision in this page's refresh): +1. Build octos at the revision the root `Cargo.toml` pins (`fe08d8e6`), in a checkout of [octos-org/octos](https://github.com/octos-org/octos) (the flags are `tools/kernel-artifact.py`'s; **unverified** at this revision in this page's refresh): ```sh git checkout fe08d8e6b3b32e672b0f956a2b692c3c8205b167 diff --git a/docs/ai-services.zh-CN.md b/docs/ai-services.zh-CN.md index 3ebb9ffc..aaa48fd0 100644 --- a/docs/ai-services.zh-CN.md +++ b/docs/ai-services.zh-CN.md @@ -219,7 +219,7 @@ manifest 的 `agent` 字段(权限档位、通用工具、迭代和 token 上 ### 桌面端:使用临时的内核与配置 -1. 在 [octos-org/octos](https://github.com/octos-org/octos) 的检出中,构建根 `Cargo.toml` 锁定的版本(`e045c727`;参数与 `tools/kernel-artifact.py` 相同;本次更新未在此版本上运行,**unverified**): +1. 在 [octos-org/octos](https://github.com/octos-org/octos) 的检出中,构建根 `Cargo.toml` 锁定的版本(`fe08d8e6`;参数与 `tools/kernel-artifact.py` 相同;本次更新未在此版本上运行,**unverified**): ```sh git checkout fe08d8e6b3b32e672b0f956a2b692c3c8205b167