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
2 changes: 2 additions & 0 deletions crates/trios-a2a/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ members = [
"rings/SR-00",
"rings/SR-01",
"rings/SR-02",
"rings/SR-03",
"rings/BR-OUTPUT",
]

Expand All @@ -26,6 +27,7 @@ repository = "https://github.com/gHashTag/trios"
trios-a2a-sr00 = { path = "rings/SR-00" }
trios-a2a-sr01 = { path = "rings/SR-01" }
trios-a2a-sr02 = { path = "rings/SR-02" }
trios-a2a-sr03 = { path = "rings/SR-03" }
trios-a2a-br-output = { path = "rings/BR-OUTPUT" }

[workspace.dependencies]
Expand Down
42 changes: 26 additions & 16 deletions crates/trios-a2a/rings/SR-00/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ pub enum Capability {
LLM,
/// Can manage other agents
Orchestrator,
/// Can control browser tabs and navigation (BrowserOS)
BrowserControl,
/// Can read DOM content from browser pages
DomRead,
/// Can write/inject into browser DOM
DomWrite,
/// Custom capability
Custom(String),
}
Expand All @@ -58,18 +64,13 @@ pub struct AgentCard {
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum AgentStatus {
/// Agent is available for tasks
Idle,
/// Agent is working on a task
Busy,
/// Agent is disconnected
Offline,
/// Agent encountered an error
Error,
}

impl AgentCard {
/// Create a new agent card.
pub fn new(id: impl Into<String>, name: impl Into<String>) -> Self {
Self {
id: AgentId::new(id),
Expand All @@ -80,21 +81,29 @@ impl AgentCard {
}
}

/// Add a capability.
pub fn with_capability(mut self, cap: Capability) -> Self {
self.capabilities.push(cap);
self
}

/// Check if agent has a specific capability.
pub fn has_capability(&self, cap: &Capability) -> bool {
self.capabilities.contains(cap)
}

/// Check if agent is available for work.
pub fn is_available(&self) -> bool {
self.status == AgentStatus::Idle
}

/// Create a BrowserOS agent card.
pub fn browser_agent(tab_id: u32) -> Self {
Self::new(
format!("browser-agent-{}", tab_id),
format!("BrowserOS Agent (tab {})", tab_id),
)
.with_capability(Capability::BrowserControl)
.with_capability(Capability::DomRead)
.with_capability(Capability::DomWrite)
}
}

#[cfg(test)]
Expand All @@ -107,6 +116,15 @@ mod tests {
assert_eq!(id.to_string(), "alpha-1");
}

#[test]
fn test_browser_agent_card() {
let card = AgentCard::browser_agent(42);
assert_eq!(card.id.as_str(), "browser-agent-42");
assert!(card.has_capability(&Capability::BrowserControl));
assert!(card.has_capability(&Capability::DomRead));
assert!(card.has_capability(&Capability::DomWrite));
}

#[test]
fn test_agent_card_builder() {
let card = AgentCard::new("alpha-1", "Alpha")
Expand All @@ -123,12 +141,4 @@ mod tests {
let json = serde_json::to_string(&status).unwrap();
assert_eq!(json, "\"busy\"");
}

#[test]
fn test_agent_is_available() {
let mut card = AgentCard::new("alpha-1", "Alpha");
assert!(card.is_available());
card.status = AgentStatus::Busy;
assert!(!card.is_available());
}
}
44 changes: 44 additions & 0 deletions crates/trios-a2a/rings/SR-03/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# AGENTS.md — SR-03 (trios-a2a)

> AAIF-compliant | MCP-compatible | BrowserOS server side

## Identity

- Ring: SR-03
- Package: trios-a2a-sr03
- Role: BrowserOS A2A agent — серверные типы и очередь команд

## Что делает этот ring

Определяет типы для протокола BrowserOS:
- Команды от AI агентов → браузеру
- Результаты от браузера → AI агентам
- Очередь с deduplication и TTL

## Rules (ABSOLUTE)

- Читай LAWS.md перед ЛЮБЫМ действием
- R1: только browser command domain
- Нет зависимостей кроме SR-00, SR-01, serde, uuid, chrono
- Нет async/tokio — sync типы
- Нет wasm-bindgen — это серверный код

## Ты МОЖЕШЬ

- ✅ Добавить новые `BrowserCommandType` варианты
- ✅ Добавить новые MCP tool definitions
- ✅ Улучшить `BrowserCommandQueue` логику
- ✅ Добавить тесты

## Ты НЕ МОЖЕШЬ

- ❌ Импортировать SR-02 (избегаем circular deps)
- ❌ Добавлять async/tokio
- ❌ Добавлять wasm-bindgen
- ❌ Делать HTTP запросы — это задача trios-server

## Build

```bash
cargo test -p trios-a2a-sr03
```
18 changes: 18 additions & 0 deletions crates/trios-a2a/rings/SR-03/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[package]
name = "trios-a2a-sr03"
version.workspace = true
edition.workspace = true
authors.workspace = true
license.workspace = true
description = "SR-03: BrowserOS A2A agent — browser command types and MCP tool definitions"

[lib]
path = "src/lib.rs"

[dependencies]
trios-a2a-sr00 = { path = "../SR-00" }
trios-a2a-sr01 = { path = "../SR-01" }
serde = { workspace = true }
serde_json = { workspace = true }
uuid = { workspace = true }
chrono = { workspace = true }
48 changes: 48 additions & 0 deletions crates/trios-a2a/rings/SR-03/RING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# RING — SR-03 (trios-a2a)

## Identity

| Field | Value |
|-------|-------|
| Metal | 🥈 Silver |
| Package | trios-a2a-sr03 |
| Sealed | No |

## Purpose

**BrowserOS A2A Agent** — серверная сторона управления браузером.

Этот ring определяет:
- `BrowserCommand` — MCP команда агенту в браузере
- `BrowserResult` — результат выполнения команды
- `BrowserCommandType` — все 12 поддерживаемых операций
- MCP tool definitions для регистрации в trios-server
- `BrowserCommandQueue` — очередь команд ожидающих выполнения

## Место в архитектуре

```
trios-server (SR-02 registry)
↓ a2a_browser_command({tool, params})
↓ → BrowserCommandQueue (SR-03)

Chrome Extension (EXT-02, WASM)
↓ GET /mcp/browser-commands (poll 2s)
↓ ← Vec<BrowserCommand>
↓ dispatch → DOM executor (EXT-02/EXT-03)
↓ POST /mcp/browser-result
↓ → BrowserResult → SR-03 queue update
```

## Почему отдельный ring, не расширение SR-02

SR-02 — общий A2A registry и MCP tools для агентов.
SR-03 — специализированный domain: браузерные команды, очередь,
deduplication, TTL. Разделение по Single Responsibility (R1).

## Laws

- R1: только browser domain типы и очередь
- Нет зависимостей кроме SR-00, SR-01
- Нет tokio/async — чистые sync типы
- Нет WASM — это серверный ring (native Rust)
35 changes: 35 additions & 0 deletions crates/trios-a2a/rings/SR-03/TASK.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# TASK — SR-03 (trios-a2a)

## Status: ACTIVE

## Completed ✅

- [x] `BrowserCommandType` enum — все 12 операций
- [x] `BrowserCommand` struct — команда с id, type, params, TTL
- [x] `BrowserResult` struct — результат с ok/data/error
- [x] `BrowserCommandQueue` — очередь с deduplication
- [x] `mcp_browser_tool_definitions()` — 12 MCP tool schemas
- [x] `AgentCard::browser_agent(tab_id)` в SR-00

## Open P0 (нужен trios-server)

- [ ] **HTTP endpoint** `GET /mcp/browser-commands`
trios-server держит `BrowserCommandQueue` из SR-03,
возвращает pending команды extension'у
- [ ] **HTTP endpoint** `POST /mcp/browser-result`
принимает `BrowserResult`, обновляет очередь
- [ ] **MCP handler** `a2a_browser_command` — AI агент вызывает tool,
команда попадает в очередь

## Open P1 (trios-ext WASM)

- [ ] EXT-02: `poll_commands()` → GET /mcp/browser-commands (каждые 2s)
- [ ] EXT-02: `report_result()` → POST /mcp/browser-result
- [ ] EXT-02: `register_agent()` → POST /a2a с AgentCard
- [ ] EXT-02/03: `dispatch_command(json)` — роутер к DOM операциям

## Open P2

- [ ] `browser_screenshot` — html2canvas или getDisplayMedia
- [ ] `browser_wait_for(selector, timeout_ms)` — MutationObserver
- [ ] WebRTC stream для live view (далёкое будущее)
Loading
Loading