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
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ flowchart LR
</details>

- **The shell** (`crates/shell`, one process) hosts the window manager, the native modules (App Hub, Rinx), App Hub's Card runner (every script app in its own isolate), the system chat, the approval router, the host-tool relay and [`crates/ai-host`](crates/ai-host/README.md), whose [app-peers broker](crates/app-peers/README.md) is the kernel's host connection.
- **The octos kernel** ([`crates/kernel`](crates/kernel/README.md)) starts on first use: a child process speaking OUP over stdio on the desktop (`OCTOS_APP_CORE_BIN`) and Android (`liboctos.so`), an in-process task on OpenHarmony, none on iOS. It exits with the shell.
- **The octos kernel** ([`crates/kernel`](crates/kernel/README.md)) starts on first use: a child process speaking OUP over stdio on the desktop (the packaged `octos-kernel` beside the shell, or `OCTOS_APP_CORE_BIN`) and Android (`liboctos.so`), an in-process task on OpenHarmony, none on iOS. It exits with the shell.
- **Process apps**: on the desktop the Terminal runs as its own process, attached over the shell's hub (frames and the AI bus), in an OS sandbox built from its `native-apps.json` entry (Seatbelt on macOS, Landlock and seccomp on Linux, not yet on Windows). A process app reaches its own agent over the **peer link**; the shell side is on `main`, but the Terminal is not granted an agent, so no process app uses it yet.
- **External clients**: Talk to Octos (opt-in) lets a web or terminal client use the system conversation with a limited external token: an allowlist of methods, no `peer/*` method, no app agent's session, no host-routed tools.

Expand Down Expand Up @@ -314,14 +314,14 @@ Pinned exactly once, in the root `Cargo.toml` and the runtime locks:
| [makepad (OctoSense fork)](https://github.com/OctoSense-org/makepad) | The UI framework and the `cargo-makepad` packager. Checked out in `.sources/makepad`, plus the reviewed runtime patch. |
| [OctoScript-Makepad](https://github.com/OctoSense-org/OctoScript-Makepad), [OctoScript](https://github.com/OctoSense-org/OctoScript) | The runtime release that names the Makepad and OctoScript revisions (`native-runtime.lock.json`). |
| [OctoSense-App-Hub](https://github.com/OctoSense-org/OctoSense-App-Hub) | The signed catalog, the store, the Card runner that contains every app (`octosense-app-hub-app`). |
| [octos](https://github.com/octos-org/octos) | The agent kernel. On Android the APK bundles it as `liboctos.so`; on a desktop the kernel service runs the binary named by `OCTOS_APP_CORE_BIN`. |
| [octos](https://github.com/octos-org/octos) | The agent kernel. On Android the APK bundles it as `liboctos.so`; on a desktop the kernel service runs the packaged `octos-kernel` beside the shell, checked against this revision (`tools/kernel-artifact.py --host --stage` builds it); `OCTOS_APP_CORE_BIN` overrides it. |
| [Rinx](https://github.com/hagency-org/Rinx) | Matrix chats and mini apps, hosted as a native module. |

Related, not build inputs: [OctoScript-App-Design-Flow](https://github.com/OctoSense-org/OctoScript-App-Design-Flow) (how apps are built and published), [OctoScript-Android](https://github.com/OctoSense-org/OctoScript-Android) and [OctoScript-OH](https://github.com/OctoSense-org/OctoScript-OH) (other renderers), the [OctoSense website](https://github.com/OctoSense-org/octosense-org.github.io).

## AI services (octos)

Each shell runs one [octos](https://github.com/octos-org/octos) agent kernel, started on first use: the APK's `liboctos.so` on Android, in process on OpenHarmony, the binary `OCTOS_APP_CORE_BIN` names on a desktop, none on iOS. The person chooses its models and types keys in the **AI providers** system app, on host sheets; keys stay in the platform's secret store and never reach an app. [`crates/ai-host`](crates/ai-host/README.md) is the shells' one entry point, and [`crates/app-peers`](crates/app-peers/README.md) gives each granted native app its own octos peer (private contexts, workspace and memory `app/<app>/acct-<hash>`), owned by the shell's system agent. Peer tool approvals use the shell router: developer mode, eligible standing rules or a person on the owning app/Shell confirmation sheet. The system agent cannot answer them.
Each shell runs one [octos](https://github.com/octos-org/octos) agent kernel, started on first use: the APK's `liboctos.so` on Android, in process on OpenHarmony, on a desktop the packaged `octos-kernel` beside the shell (or the binary `OCTOS_APP_CORE_BIN` names), none on iOS. The person chooses its models and types keys in the **AI providers** system app, on host sheets; keys stay in the platform's secret store and never reach an app. [`crates/ai-host`](crates/ai-host/README.md) is the shells' one entry point, and [`crates/app-peers`](crates/app-peers/README.md) gives each granted native app its own octos peer (private contexts, workspace and memory `app/<app>/acct-<hash>`), owned by the shell's system agent. Peer tool approvals use the shell router: developer mode, eligible standing rules or a person on the owning app/Shell confirmation sheet. The system agent cannot answer them.

What works today: native modules (Rinx) use their peer; AppCard (opt-in) uses the kernel directly. Contained script apps, system or store, reach it through the `octos` host service in a shell that hosts a kernel: each app gets its own host-owned peer (`card.<app id>`), and its tool approvals go to the shell's approval sheets like every other app agent's ([#155](https://github.com/OctoSense-org/OctoSense/pull/155)). The `llm` service manages providers for `os.*` apps only. An app's own agent (`tools.json`, `AGENT.md`, skills, triggers, glance cards) is [ADR 0002](docs/adr/0002-event-driven-app-agents.md); host-service-backed `tools.json` tools reach their agents through the shell relay since [#160](https://github.com/OctoSense-org/OctoSense/pull/160). Tools marked `implemented_by: "app"` still lack a Card-runner executor; declaring a tool does not implement it.

Expand Down Expand Up @@ -367,6 +367,8 @@ cargo check --locked -p octosense --features mobile-apps
cargo check --locked -p octosense -p octosense-appcard --features mobile-apps,app-appcard
```

The assistant needs the octos kernel beside the shell: `python3 tools/kernel-artifact.py --host --stage target/release` builds the pinned revision and stages it, once per octos pin; the desktop refuses a staged kernel of another revision and says so ([Build and run](desktop/README.md#build-and-run)). Without one the desktop runs without an assistant.

**Phone** (from `phone/`, which selects the phone's system apps; details in [phone/README.md](phone/README.md)):

```sh
Expand Down
8 changes: 5 additions & 3 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ flowchart LR
</details>

- **Shell**(`crates/shell`,一个进程)承载窗口管理器、原生模块(App Hub、Rinx)、App Hub 的 Card runner(每个脚本应用都在自己的隔离环境中)、系统对话、审批路由、宿主工具中转,以及 [`crates/ai-host`](crates/ai-host/README.md);其中的 [app-peers 代理](crates/app-peers/README.md)就是内核的宿主连接。
- **octos 内核**([`crates/kernel`](crates/kernel/README.zh-CN.md))首次使用时启动:桌面端(`OCTOS_APP_CORE_BIN`)和 Android(`liboctos.so`)上是通过 stdio 讲 OUP 的子进程,OpenHarmony 上是进程内的任务,iOS 上没有。它随 Shell 一起退出。
- **octos 内核**([`crates/kernel`](crates/kernel/README.zh-CN.md))首次使用时启动:桌面端(Shell 旁随附的 `octos-kernel`,或 `OCTOS_APP_CORE_BIN`)和 Android(`liboctos.so`)上是通过 stdio 讲 OUP 的子进程,OpenHarmony 上是进程内的任务,iOS 上没有。它随 Shell 一起退出。
- **进程应用**:桌面端的 Terminal 作为独立进程运行,通过 Shell 的 hub 连接(画面和 AI bus),运行在按其 `native-apps.json` 条目构建的系统沙箱中(macOS 上是 Seatbelt,Linux 上是 Landlock 和 seccomp,Windows 上尚未实现)。进程应用通过 **peer link** 使用自己的 Agent;Shell 一侧已在 `main` 上,但 Terminal 没有被授予 Agent,所以目前还没有进程应用使用它。
- **外部客户端**:Talk to Octos(需手动开启)让网页或终端客户端以受限的外部 token 使用系统对话:只有一份方法白名单,不能调用任何 `peer/*` 方法,不能进入任何应用 Agent 的会话,也拿不到宿主路由的工具。

Expand Down Expand Up @@ -314,14 +314,14 @@ Shell 只有一份,位于 `crates/shell`([ADR 0001(英文)](docs/adr/000
| [makepad(OctoSense fork)](https://github.com/OctoSense-org/makepad) | UI 框架和 `cargo-makepad` 打包工具。检出到 `.sources/makepad`,并应用经审查的运行时补丁。 |
| [OctoScript-Makepad](https://github.com/OctoSense-org/OctoScript-Makepad)、[OctoScript](https://github.com/OctoSense-org/OctoScript) | 指定 Makepad 和 OctoScript 版本的运行时发行版(`native-runtime.lock.json`)。 |
| [OctoSense-App-Hub](https://github.com/OctoSense-org/OctoSense-App-Hub) | 签名目录、商店,以及隔离运行每个应用的 Card runner(`octosense-app-hub-app`)。 |
| [octos](https://github.com/octos-org/octos) | Agent 内核。在 Android 上 APK 以 `liboctos.so` 形式内置它;在桌面上内核服务运行 `OCTOS_APP_CORE_BIN` 指定的程序。 |
| [octos](https://github.com/octos-org/octos) | Agent 内核。在 Android 上 APK 以 `liboctos.so` 形式内置它;在桌面上内核服务运行 Shell 旁随附的 `octos-kernel`,并核对其版本与此处固定的一致(由 `tools/kernel-artifact.py --host --stage` 构建);`OCTOS_APP_CORE_BIN` 可覆盖它。 |
| [Rinx](https://github.com/hagency-org/Rinx) | Matrix 聊天与小程序,作为原生模块托管。 |

相关但不参与构建:[OctoScript-App-Design-Flow](https://github.com/OctoSense-org/OctoScript-App-Design-Flow)(如何构建和发布应用)、[OctoScript-Android](https://github.com/OctoSense-org/OctoScript-Android) 和 [OctoScript-OH](https://github.com/OctoSense-org/OctoScript-OH)(其他渲染后端)、[OctoSense 网站](https://github.com/OctoSense-org/octosense-org.github.io)。

## AI 服务(octos)

每个 Shell 运行一个 [octos](https://github.com/octos-org/octos) Agent 内核,首次使用时启动:Android 上是 APK 中的 `liboctos.so`,OpenHarmony 上在进程内运行,桌面端运行 `OCTOS_APP_CORE_BIN` 指定的二进制,iOS 上没有。用户在系统应用 **AI providers** 中、在宿主面板上选择模型并输入密钥;密钥保存在平台的密钥存储中,永远不会到达应用。[`crates/ai-host`](crates/ai-host/README.md) 是两个 Shell 的统一入口,[`crates/app-peers`](crates/app-peers/README.md) 为每个获授权的原生应用分配自己的 octos peer(私有的上下文、工作区和记忆 `app/<app>/acct-<hash>`),归 Shell 的系统 Agent 所有。Peer 工具审批经 Shell 路由,由开发者模式、符合条件的常设规则,或用户在所属应用/Shell 确认面板上决定。系统 Agent 无法代答。
每个 Shell 运行一个 [octos](https://github.com/octos-org/octos) Agent 内核,首次使用时启动:Android 上是 APK 中的 `liboctos.so`,OpenHarmony 上在进程内运行,桌面端运行 Shell 旁随附的 `octos-kernel`(或 `OCTOS_APP_CORE_BIN` 指定的二进制),iOS 上没有。用户在系统应用 **AI providers** 中、在宿主面板上选择模型并输入密钥;密钥保存在平台的密钥存储中,永远不会到达应用。[`crates/ai-host`](crates/ai-host/README.md) 是两个 Shell 的统一入口,[`crates/app-peers`](crates/app-peers/README.md) 为每个获授权的原生应用分配自己的 octos peer(私有的上下文、工作区和记忆 `app/<app>/acct-<hash>`),归 Shell 的系统 Agent 所有。Peer 工具审批经 Shell 路由,由开发者模式、符合条件的常设规则,或用户在所属应用/Shell 确认面板上决定。系统 Agent 无法代答。

目前可用的:原生模块(Rinx)使用自己的 peer;AppCard(需主动开启)直接使用内核。隔离运行的脚本应用,无论系统应用还是商店应用,在托管了内核的 Shell 中通过 `octos` 宿主服务使用助手:每个应用有自己的、由宿主拥有的 peer(`card.<应用 id>`),它的工具审批和其他应用 Agent 一样交给 Shell 的审批面板([#155](https://github.com/OctoSense-org/OctoSense/pull/155))。`llm` 服务只为 `os.*` 应用管理提供方。应用自己的 Agent(`tools.json`、`AGENT.md`、skills、触发器、glance 卡片)见 [ADR 0002](docs/adr/0002-event-driven-app-agents.md);自 [#160](https://github.com/OctoSense-org/OctoSense/pull/160) 起,应用 `tools.json` 中由宿主服务实现的工具已通过 Shell relay 提供给其 Agent。标为 `implemented_by: "app"` 的工具仍缺少 Card runner 执行器;声明不等于实现。

Expand Down Expand Up @@ -367,6 +367,8 @@ cargo check --locked -p octosense --features mobile-apps
cargo check --locked -p octosense -p octosense-appcard --features mobile-apps,app-appcard
```

助手需要 Shell 旁的 octos 内核:`python3 tools/kernel-artifact.py --host --stage target/release` 构建固定版本并放到该处,每个 octos 固定版本做一次;桌面会拒绝版本不符的内核并说明原因([构建与运行](desktop/README.zh-CN.md#构建与运行))。没有内核时桌面在没有助手的情况下运行。

**手机端**(在 `phone/` 中运行,它会选择手机端的系统应用;详见 [phone/README.zh-CN.md](phone/README.zh-CN.md)):

```sh
Expand Down
3 changes: 2 additions & 1 deletion crates/ai-host/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ ai_host::shutdown();
```

`Host` fields: `data_dir`; `kernel: KernelSource` (`Bundled` on Android,
`InProcess` on OpenHarmony, `Env` = `$OCTOS_APP_CORE_BIN` on a desktop,
`InProcess` on OpenHarmony, `Env` = `$OCTOS_APP_CORE_BIN` or the packaged
`octos-kernel` on a desktop,
`Program(path)`, `None`; `KernelSource::platform()` picks); `qr_import:
QrImport` (`platform()` or `paste_only()`); `policy: Policy`
(`Policy::shipped()` grants Rinx the `octos.*` services).
Expand Down
7 changes: 5 additions & 2 deletions crates/ai-host/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,9 @@ pub enum KernelSource {
Bundled,
/// OpenHarmony: the canonical core linked in-process.
InProcess,
/// Desktop: the binary `$OCTOS_APP_CORE_BIN` names; none without it (a
/// Desktop: the binary `$OCTOS_APP_CORE_BIN` names, else the packaged
/// `octos-kernel` beside the shell when its receipt names the pinned
/// octos revision (`octosense_kernel::launch`); none without either (a
/// developer's own `octos serve` is never touched).
Env,
/// Desktop or Android: this binary.
Expand All @@ -105,7 +107,8 @@ pub enum KernelSource {

impl KernelSource {
/// This platform's kernel: bundled on Android, in-process on
/// OpenHarmony, `$OCTOS_APP_CORE_BIN` on a desktop, none on iOS.
/// OpenHarmony, `$OCTOS_APP_CORE_BIN` or the packaged kernel on a
/// desktop, none on iOS.
pub fn platform() -> Self {
if cfg!(target_os = "android") {
KernelSource::Bundled
Expand Down
5 changes: 5 additions & 0 deletions crates/kernel/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ octos-core = { workspace = true }
octos-cli = { workspace = true, features = ["api", "git", "ast"] }
tracing-subscriber = { version = "0.3", features = ["env-filter"] }

# A desktop checks its packaged `octos-kernel` against the receipt's SHA-256
# before running it (`launch::verify_packaged`).
[target.'cfg(not(any(target_env = "ohos", target_os = "ios", target_os = "android")))'.dependencies]
sha2 = "0.10"

# Passing the kept Talk to Octos listener to the kernel (`dup2` between fork
# and exec).
[target.'cfg(unix)'.dependencies]
Expand Down
13 changes: 11 additions & 2 deletions crates/kernel/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,17 @@ How it starts, per platform (`src/launch.rs`):
with 8 MiB worker stacks (HAP native libraries may not exec).
- **Desktop**: `<program> serve --stdio --data-dir <core_dir>` (plus
`--config <core_dir>/config.json` when that file exists) with
`OCTOS_HOME=<core_dir>`; the program is the shell's `Options::program` or
`$OCTOS_APP_CORE_BIN`. With neither there is no kernel: a developer's own
`OCTOS_HOME=<core_dir>`; the program is the shell's `Options::program`,
`$OCTOS_APP_CORE_BIN`, or the packaged `octos-kernel[.exe]` beside the
shell executable (in a macOS `.app`, `Contents/MacOS` or
`Contents/Resources`), in that order. The packaged kernel runs only when
its receipt `octos-kernel.json` (beside it, in the `.app`'s
`Contents/Resources`, or a Linux package's `usr/lib/octosense`) names the
octos revision this build pins (`build.rs` reads it from `Cargo.lock`) and
its SHA-256 matches; otherwise the connection fails with the reason.
`tools/kernel-artifact.py --host --stage <dir>` builds and stages it;
`OCTOSENSE_KERNEL_ANY_REVISION=1` accepts another revision while
developing. No `PATH` search, no working directory, and a developer's own
`octos serve` is never touched.
- **iOS**: no kernel.
- **Talk to Octos on** (desktop and Android): the same command with
Expand Down
10 changes: 8 additions & 2 deletions crates/kernel/README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,14 @@ Shell(`phone/` 中的 Home、`desktop/` 中的桌面)拥有它;**AI provid
运行在本 crate 的运行时上,工作线程栈 8 MiB(HAP 原生库不能 exec)。
- **桌面**:`<program> serve --stdio --data-dir <core_dir>`(`<core_dir>/config.json`
存在时再加 `--config <core_dir>/config.json`),`OCTOS_HOME=<core_dir>`;程序为 Shell 的
`Options::program` 或 `$OCTOS_APP_CORE_BIN`。两者都没有时就没有内核:绝不会动开发者
自己的 `octos serve`。
`Options::program`、`$OCTOS_APP_CORE_BIN`,或 Shell 可执行文件旁随附的
`octos-kernel[.exe]`(macOS `.app` 中为 `Contents/MacOS` 或 `Contents/Resources`),
依次选用。随附内核只有在其收据 `octos-kernel.json`(在它旁边、`.app` 的
`Contents/Resources` 或 Linux 包的 `usr/lib/octosense` 中)记录的版本与本次构建固定的
octos 版本一致(`build.rs` 从 `Cargo.lock` 读取),且 SHA-256 相符时才运行;否则连接
失败并给出原因。`tools/kernel-artifact.py --host --stage <目录>` 负责构建和放置;开发时
`OCTOSENSE_KERNEL_ANY_REVISION=1` 可接受其他版本。不在 `PATH` 或工作目录中查找,绝不会
动开发者自己的 `octos serve`。
- **iOS**:没有内核。
- **开启 Talk to Octos 时**(桌面和 Android):同一命令,以 `--host 127.0.0.1 --host-managed`
代替 `--stdio`,并把本进程保留的监听套接字作为描述符 3 传入(`--listen-fd 3`,Unix)。
Expand Down
Loading
Loading