Skip to content

Commit ddbb61b

Browse files
author
Symbiont OSS Sync
committed
Sync OSS release
1 parent d7f5156 commit ddbb61b

File tree

9 files changed

+1256
-2
lines changed

9 files changed

+1256
-2
lines changed

AGENTS.md

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,3 +79,73 @@ bash scripts/sync_oss_to_github.sh --force
7979
```
8080

8181
The script exits with code 1 during cleanup even on success — this is a known quirk.
82+
83+
## DSL Quick Reference
84+
85+
Agent definitions live in `agents/*.dsl`. Key block types:
86+
87+
```
88+
metadata { version "1.0", author "team", description "What this agent does" }
89+
90+
with { sandbox docker, timeout 30.seconds }
91+
92+
schedule daily_report { cron: "0 9 * * *", timezone: "UTC", agent: "reporter" }
93+
94+
channel slack_support { platform: "slack", default_agent: "helper", channels: ["#support"] }
95+
96+
webhook github_events { path: "/hooks/github", provider: github, agent: "deployer" }
97+
98+
memory context_store { store markdown, path "data/agents", retention "90d" }
99+
```
100+
101+
Parse DSL files with `symbi dsl -f agents/<name>.dsl`.
102+
103+
## MCP Server
104+
105+
Start with `symbi mcp` (stdio transport). Available tools:
106+
107+
- `invoke_agent` — Run a named agent with a prompt via LLM
108+
- `list_agents` — List all agents in the `agents/` directory
109+
- `parse_dsl` — Parse and validate DSL content (file or inline)
110+
- `get_agent_dsl` — Get raw `.dsl` source for a specific agent
111+
- `get_agents_md` — Read the project's AGENTS.md file
112+
- `verify_schema` — Verify MCP tool schema via SchemaPin (ECDSA P-256)
113+
114+
## HTTP API
115+
116+
The runtime API runs on port 8080 (configurable via `--port`):
117+
118+
- `GET /api/v1/health` — Health check (no auth)
119+
- `GET /api/v1/agents` — List agents
120+
- `POST /api/v1/agents` — Create agent
121+
- `POST /api/v1/agents/:id/execute` — Execute agent
122+
- `GET /api/v1/schedules` — List cron schedules
123+
- `POST /api/v1/schedules` — Create schedule
124+
- `GET /api/v1/channels` — List channel adapters
125+
- `POST /api/v1/workflows/execute` — Execute workflow
126+
- `GET /api/v1/metrics` — Runtime metrics
127+
- `GET /swagger-ui` — Interactive API docs
128+
129+
All endpoints except health require `Authorization: Bearer <token>`.
130+
131+
## Agent Capabilities
132+
133+
Agents defined in the Symbi DSL can:
134+
135+
- Invoke LLMs (OpenRouter, OpenAI, Anthropic) with policy-governed prompts
136+
- Use skills (verified via SchemaPin cryptographic signatures)
137+
- Run in sandboxed environments (Docker, gVisor, Firecracker, E2B)
138+
- Operate on cron schedules with timezone support
139+
- Connect to chat platforms (Slack, Teams, Mattermost) as channel adapters
140+
- Receive webhooks (GitHub, Stripe, Slack, custom) with signature verification
141+
- Maintain persistent memory stores with hybrid search (vector + keyword)
142+
- Enforce runtime policies (allow, deny, require, audit)
143+
- Produce cryptographic audit trails for all actions
144+
145+
## Trust Stack
146+
147+
Symbiont is part of the ThirdKey cryptographic trust chain:
148+
149+
1. **SchemaPin** — Tool schema verification. Ensures MCP tool schemas haven't been tampered with by verifying ECDSA P-256 signatures against publisher-hosted public keys.
150+
2. **AgentPin** — Domain-anchored agent identity. Binds agent identities to DNS domains via `.well-known/agentpin.json`, enabling cross-runtime trust.
151+
3. **Symbiont** — The agent runtime. Executes policy-aware agents with sandbox isolation, integrating SchemaPin for tool trust and AgentPin for agent identity.

CLAUDE.md

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,3 +79,73 @@ bash scripts/sync_oss_to_github.sh --force
7979
```
8080

8181
The script exits with code 1 during cleanup even on success — this is a known quirk.
82+
83+
## DSL Quick Reference
84+
85+
Agent definitions live in `agents/*.dsl`. Key block types:
86+
87+
```
88+
metadata { version "1.0", author "team", description "What this agent does" }
89+
90+
with { sandbox docker, timeout 30.seconds }
91+
92+
schedule daily_report { cron: "0 9 * * *", timezone: "UTC", agent: "reporter" }
93+
94+
channel slack_support { platform: "slack", default_agent: "helper", channels: ["#support"] }
95+
96+
webhook github_events { path: "/hooks/github", provider: github, agent: "deployer" }
97+
98+
memory context_store { store markdown, path "data/agents", retention "90d" }
99+
```
100+
101+
Parse DSL files with `symbi dsl -f agents/<name>.dsl`.
102+
103+
## MCP Server
104+
105+
Start with `symbi mcp` (stdio transport). Available tools:
106+
107+
- `invoke_agent` — Run a named agent with a prompt via LLM
108+
- `list_agents` — List all agents in the `agents/` directory
109+
- `parse_dsl` — Parse and validate DSL content (file or inline)
110+
- `get_agent_dsl` — Get raw `.dsl` source for a specific agent
111+
- `get_agents_md` — Read the project's AGENTS.md file
112+
- `verify_schema` — Verify MCP tool schema via SchemaPin (ECDSA P-256)
113+
114+
## HTTP API
115+
116+
The runtime API runs on port 8080 (configurable via `--port`):
117+
118+
- `GET /api/v1/health` — Health check (no auth)
119+
- `GET /api/v1/agents` — List agents
120+
- `POST /api/v1/agents` — Create agent
121+
- `POST /api/v1/agents/:id/execute` — Execute agent
122+
- `GET /api/v1/schedules` — List cron schedules
123+
- `POST /api/v1/schedules` — Create schedule
124+
- `GET /api/v1/channels` — List channel adapters
125+
- `POST /api/v1/workflows/execute` — Execute workflow
126+
- `GET /api/v1/metrics` — Runtime metrics
127+
- `GET /swagger-ui` — Interactive API docs
128+
129+
All endpoints except health require `Authorization: Bearer <token>`.
130+
131+
## Agent Capabilities
132+
133+
Agents defined in the Symbi DSL can:
134+
135+
- Invoke LLMs (OpenRouter, OpenAI, Anthropic) with policy-governed prompts
136+
- Use skills (verified via SchemaPin cryptographic signatures)
137+
- Run in sandboxed environments (Docker, gVisor, Firecracker, E2B)
138+
- Operate on cron schedules with timezone support
139+
- Connect to chat platforms (Slack, Teams, Mattermost) as channel adapters
140+
- Receive webhooks (GitHub, Stripe, Slack, custom) with signature verification
141+
- Maintain persistent memory stores with hybrid search (vector + keyword)
142+
- Enforce runtime policies (allow, deny, require, audit)
143+
- Produce cryptographic audit trails for all actions
144+
145+
## Trust Stack
146+
147+
Symbiont is part of the ThirdKey cryptographic trust chain:
148+
149+
1. **SchemaPin** — Tool schema verification. Ensures MCP tool schemas haven't been tampered with by verifying ECDSA P-256 signatures against publisher-hosted public keys.
150+
2. **AgentPin** — Domain-anchored agent identity. Binds agent identities to DNS domains via `.well-known/agentpin.json`, enabling cross-runtime trust.
151+
3. **Symbiont** — The agent runtime. Executes policy-aware agents with sandbox isolation, integrating SchemaPin for tool trust and AgentPin for agent identity.

crates/runtime/src/api/routes.rs

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,67 @@ use super::types::{
3333
#[cfg(feature = "http-api")]
3434
use crate::types::AgentId;
3535

36+
// ── AGENTS.md endpoint ─────────────────────────────────────────────────
37+
38+
/// Serve AGENTS.md with sensitive sections stripped.
39+
///
40+
/// Reads `AGENTS.md` from the working directory, removes content between
41+
/// `<!-- agents-md:sensitive-start -->` and `<!-- agents-md:sensitive-end -->`
42+
/// markers, and returns the filtered markdown.
43+
#[cfg(feature = "http-api")]
44+
pub async fn serve_agents_md() -> Result<
45+
(
46+
StatusCode,
47+
[(axum::http::header::HeaderName, &'static str); 1],
48+
String,
49+
),
50+
StatusCode,
51+
> {
52+
let content = std::fs::read_to_string("AGENTS.md").map_err(|_| StatusCode::NOT_FOUND)?;
53+
let filtered = strip_sensitive_sections(&content);
54+
Ok((
55+
StatusCode::OK,
56+
[(
57+
axum::http::header::CONTENT_TYPE,
58+
"text/markdown; charset=utf-8",
59+
)],
60+
filtered,
61+
))
62+
}
63+
64+
/// Strip sensitive sections from AGENTS.md content (inline helper).
65+
///
66+
/// Removes all content between `<!-- agents-md:sensitive-start -->` and
67+
/// `<!-- agents-md:sensitive-end -->` markers, including the markers themselves.
68+
#[cfg(feature = "http-api")]
69+
fn strip_sensitive_sections(content: &str) -> String {
70+
const SENSITIVE_START: &str = "<!-- agents-md:sensitive-start -->";
71+
const SENSITIVE_END: &str = "<!-- agents-md:sensitive-end -->";
72+
73+
let mut result = content.to_string();
74+
while let (Some(start), Some(end)) = (result.find(SENSITIVE_START), result.find(SENSITIVE_END))
75+
{
76+
if end <= start {
77+
break;
78+
}
79+
let end_pos = end + SENSITIVE_END.len();
80+
let end_pos = if result[end_pos..].starts_with('\n') {
81+
end_pos + 1
82+
} else {
83+
end_pos
84+
};
85+
let start_pos = if start > 0 && result.as_bytes()[start - 1] == b'\n' {
86+
start - 1
87+
} else {
88+
start
89+
};
90+
result = format!("{}{}", &result[..start_pos], &result[end_pos..]);
91+
}
92+
result
93+
}
94+
95+
// ── Workflow / Agent / Schedule / Channel endpoints ────────────────────
96+
3697
/// Workflow execution endpoint handler
3798
#[cfg(feature = "http-api")]
3899
#[utoipa::path(

crates/runtime/src/api/server.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,8 @@ pub struct HttpApiConfig {
161161
pub enable_rate_limiting: bool,
162162
/// Optional path to API keys JSON file for per-agent authentication
163163
pub api_keys_file: Option<std::path::PathBuf>,
164+
/// Serve AGENTS.md at /agents.md and /.well-known/agents.md (auth-gated)
165+
pub serve_agents_md: bool,
164166
}
165167

166168
#[cfg(feature = "http-api")]
@@ -173,6 +175,7 @@ impl Default for HttpApiConfig {
173175
enable_tracing: true,
174176
enable_rate_limiting: true,
175177
api_keys_file: None,
178+
serve_agents_md: false,
176179
}
177180
}
178181
}
@@ -370,6 +373,21 @@ impl HttpApiServer {
370373
.merge(health_router);
371374
}
372375

376+
// Conditionally serve AGENTS.md at well-known paths (auth-gated, no provider state needed)
377+
if self.config.serve_agents_md {
378+
use super::middleware::auth_middleware;
379+
use axum::middleware;
380+
381+
let agents_md_router = Router::new()
382+
.route("/agents.md", get(super::routes::serve_agents_md))
383+
.route(
384+
"/.well-known/agents.md",
385+
get(super::routes::serve_agents_md),
386+
)
387+
.layer(middleware::from_fn(auth_middleware));
388+
router = router.merge(agents_md_router);
389+
}
390+
373391
// Add API key store as extension if available
374392
if let Some(ref store) = self.api_key_store {
375393
router = router.layer(axum::Extension(store.clone()));

0 commit comments

Comments
 (0)