Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions apps/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand Down
4 changes: 2 additions & 2 deletions apps/README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`
Expand Down Expand Up @@ -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`) |

## 参与贡献

Expand Down
2 changes: 1 addition & 1 deletion apps/appcard/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion apps/appcard/README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -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。
Expand Down
27 changes: 16 additions & 11 deletions crates/app-peers/tests/real_kernel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 `<shared_history>` 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");
Expand Down Expand Up @@ -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}"
);
}
4 changes: 3 additions & 1 deletion crates/shell/src/host_tools/real_kernel_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::<Vec<_>>().join("\n");
if sys_lane.contains("SHARED") {
// The model's answer ("SHARED - <rows>" 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;
}
Expand Down
21 changes: 13 additions & 8 deletions crates/shell/src/host_tools/scenario_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion crates/toolbox/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
Loading
Loading