{"id":51425162,"url":"https://github.com/smooai/smooth-operator-core","last_synced_at":"2026-07-05T02:01:03.635Z","repository":{"id":360110768,"uuid":"1248745981","full_name":"SmooAI/smooth-operator-core","owner":"SmooAI","description":"Polyglot AI agent orchestration core (Rust reference + TS/Go/.NET/Python bindings) — agents, workflows, tools, checkpointing, memory, HITL, cost. A security-first LangGraph; the engine behind smooth-operator and lom.smoo.ai.","archived":false,"fork":false,"pushed_at":"2026-07-01T00:05:44.000Z","size":1901,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-07-01T02:08:02.814Z","etag":null,"topics":["agent-orchestration","ai-agent","checkpointing","langgraph-alternative","llm","multi-language","polyglot","rust","workflows"],"latest_commit_sha":null,"homepage":"https://lom.smoo.ai","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/SmooAI.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-25T02:32:40.000Z","updated_at":"2026-07-01T00:05:47.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/SmooAI/smooth-operator-core","commit_stats":null,"previous_names":["smooai/agent","smooai/smooth-operator","smooai/smooth-operator-core"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/SmooAI/smooth-operator-core","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SmooAI%2Fsmooth-operator-core","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SmooAI%2Fsmooth-operator-core/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SmooAI%2Fsmooth-operator-core/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SmooAI%2Fsmooth-operator-core/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/SmooAI","download_url":"https://codeload.github.com/SmooAI/smooth-operator-core/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SmooAI%2Fsmooth-operator-core/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35141083,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-05T02:00:06.290Z","response_time":100,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agent-orchestration","ai-agent","checkpointing","langgraph-alternative","llm","multi-language","polyglot","rust","workflows"],"created_at":"2026-07-05T02:00:47.137Z","updated_at":"2026-07-05T02:01:03.594Z","avatar_url":"https://github.com/SmooAI.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://smoo.ai\"\u003e\u003cimg src=\".github/banner.png\" alt=\"smooth-operator-core — The Rust engine for orchestrated AI agents\" width=\"100%\" /\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://smoo.ai/th\"\u003e\u003cimg src=\"https://img.shields.io/badge/Smoo_AI-platform-00A6A6?style=for-the-badge\u0026labelColor=020618\" alt=\"Smoo AI\"\u003e\u003c/a\u003e\n  \u003ca href=\"./LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/badge/license-MIT-F49F0A?style=for-the-badge\u0026labelColor=020618\" alt=\"license\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://lom.smoo.ai\"\u003e\u003cimg src=\"https://img.shields.io/badge/hosted-lom.smoo.ai-FF6B6C?style=for-the-badge\u0026labelColor=020618\" alt=\"lom.smoo.ai\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/Rust-reference%20impl-FF6B6C?style=flat-square\" alt=\"Rust reference implementation\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/tests-337%20passing-00A6A6?style=flat-square\" alt=\"337 tests passing\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"#why-this\"\u003e\u003cb\u003eFeatures\u003c/b\u003e\u003c/a\u003e \u0026nbsp;·\u0026nbsp; \u003ca href=\"#quickstart\"\u003e\u003cb\u003eInstall\u003c/b\u003e\u003c/a\u003e \u0026nbsp;·\u0026nbsp; \u003ca href=\"#quickstart\"\u003e\u003cb\u003eUsage\u003c/b\u003e\u003c/a\u003e \u0026nbsp;·\u0026nbsp; \u003ca href=\"#architecture\"\u003e\u003cb\u003eArchitecture\u003c/b\u003e\u003c/a\u003e \u0026nbsp;·\u0026nbsp; \u003ca href=\"#part-of-smoo-ai\"\u003e\u003cb\u003ePlatform\u003c/b\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n---\n\n\u003e The agent runtime behind the [smooth-operator](https://github.com/SmooAI/smooth-operator) service and [lom.smoo.ai](https://lom.smoo.ai). Agents, workflows, tools, checkpointing, memory, human-in-the-loop, and per-model cost budgets — as a single embeddable Rust crate. It's the engine, not a notebook demo.\n\n`smooai-smooth-operator-core` is the agent runtime that powers the [**smooth-operator**](https://github.com/SmooAI/smooth-operator) service and [**lom.smoo.ai**](https://lom.smoo.ai). It gives you the moving parts of a serious agent framework — an observe→think→act loop, a typed tool system, a graph workflow engine, pluggable checkpoint stores, memory, RAG, human-in-the-loop gates, and per-model cost budgets — as a single, embeddable Rust crate.\n\nInspired by LangGraph, CrewAI, and Agno, with one hard difference: **it's the engine, not a notebook demo.** Every surface is covered by **337 fast, offline unit tests** built on a deterministic `MockLlmClient`, so the loop is verified — not vibe-coded.\n\n\u003e The Rust implementation is the source of truth. TypeScript, Go, C#/.NET, and Python bindings mirror its surface (protocol-first; see [Repository layout](#repository-layout)).\n\n---\n\n## Quickstart\n\n```toml\n# Cargo.toml\n[dependencies]\nsmooai-smooth-operator-core = { git = \"https://github.com/SmooAI/smooth-operator-core.git\", branch = \"main\" }\nasync-trait = \"0.1\"\ntokio = { version = \"1\", features = [\"full\"] }\nanyhow = \"1\"\nserde_json = \"1\"\n```\n\nOr, once published to crates.io _(publish pending — use the git dep above today)_:\n\n```bash\ncargo add smooai-smooth-operator-core\n```\n\nA complete agent — one tool, one LLM, one `run()` — in about 40 lines:\n\n```rust\nuse smooth_operator_core::{Agent, AgentConfig, LlmConfig, Role, Tool, ToolRegistry, ToolSchema};\nuse async_trait::async_trait;\n\nstruct GetWeather;\n\n#[async_trait]\nimpl Tool for GetWeather {\n    fn schema(\u0026self) -\u003e ToolSchema {\n        ToolSchema {\n            name: \"get_weather\".into(),\n            description: \"Get current weather for a city\".into(),\n            parameters: serde_json::json!({\n                \"type\": \"object\",\n                \"properties\": { \"city\": { \"type\": \"string\" } },\n                \"required\": [\"city\"]\n            }),\n        }\n    }\n\n    async fn execute(\u0026self, args: serde_json::Value) -\u003e anyhow::Result\u003cString\u003e {\n        let city = args[\"city\"].as_str().unwrap_or(\"unknown\");\n        Ok(format!(\"Weather in {city}: 72F, sunny\"))\n    }\n}\n\n#[tokio::main]\nasync fn main() -\u003e anyhow::Result\u003c()\u003e {\n    // OpenAI-compatible by default — `openrouter()` is a convenience preset.\n    // Point `api_url` at OpenAI, an Anthropic-compatible endpoint, or your\n    // own gateway (e.g. `https://llm.smoo.ai/v1`).\n    let llm = LlmConfig::openrouter(std::env::var(\"OPENROUTER_API_KEY\")?)\n        .with_model(\"openai/gpt-4o\");\n\n    let config = AgentConfig::new(\"assistant\", \"You are a helpful assistant.\", llm)\n        .with_max_iterations(10)\n        .with_parallel_tools(true);\n\n    let mut registry = ToolRegistry::new();\n    registry.register(GetWeather);\n\n    let agent = Agent::new(config, registry);\n    let conversation = agent.run(\"What's the weather in Tokyo?\").await?;\n\n    // The final answer is the last assistant message in the returned conversation.\n    if let Some(answer) = conversation.messages.iter().rev().find(|m| m.role == Role::Assistant) {\n        println!(\"{}\", answer.content);\n    }\n    Ok(())\n}\n```\n\n\u003e Note: the LLM client is **OpenAI-compatible**. Point `api_url` at OpenAI, an Anthropic-compatible endpoint, or your own gateway (e.g. `https://llm.smoo.ai/v1`). `run()` returns the full `Conversation`; for live token deltas / tool-call / tool-result events, use `run_with_channel(msg, tx)` and consume the `AgentEvent` stream off the receiver.\n\n---\n\n## Showcase: a checkpointed workflow with HITL and a cost budget\n\nThe agent loop is the front door. Underneath, you can compose **stateful workflows**, gate dangerous tool calls behind a **human confirmation hook**, **checkpoint** every step for resume, and cap spend with a **cost budget** — all from the same crate.\n\n```rust\nuse std::sync::Arc;\nuse std::time::Duration;\nuse smooth_operator_core::{\n    Agent, AgentConfig, LlmConfig, ToolRegistry,\n    MemoryCheckpointStore,\n    ConfirmationHook, human_channel, HumanResponse,\n    CostBudget,\n};\n\nlet llm = LlmConfig::openrouter(std::env::var(\"OPENROUTER_API_KEY\")?);\nlet mut registry = ToolRegistry::new();\n\n// 1. Persist progress so a crashed turn resumes instead of restarting.\n//    (Swap in the `sqlite` or `postgres` store for durable, multi-process resume.)\nlet checkpoints = Arc::new(MemoryCheckpointStore::default());\n\n// 2. Cap spend per session — `CostTracker::check_budget` refuses to exceed it.\nlet budget = CostBudget { max_cost_usd: Some(0.50), max_tokens: None };\n\n// 3. Gate write/irreversible tools behind a human \"yes\". The hook fires for\n//    any tool whose name contains one of these substrings.\nlet channels = human_channel();\nlet confirm = ConfirmationHook::new(\n    vec![\"delete_\".into(), \"send_\".into()],\n    channels.request_tx,\n    channels.response_rx,\n    Duration::from_secs(300),\n);\nregistry.add_hook(confirm);\n\n// The UI side drives the human loop: read each request, answer it.\nlet mut requests = channels.request_rx;\nlet responses = channels.response_tx;\ntokio::spawn(async move {\n    while let Some(req) = requests.recv().await {\n        // Surface `req` to a human (Slack, dashboard, CLI) and answer.\n        let _ = responses.send(HumanResponse::Approved);\n        // or: HumanResponse::Denied { reason: \"not allowed\".into() }\n    }\n});\n\nlet config = AgentConfig::new(\"assistant\", \"You are a careful assistant.\", llm)\n    .with_budget(budget);\nlet agent = Agent::new(config, registry).with_checkpoint_store(checkpoints);\n```\n\n`CheckpointStore`, `CostTracker`, and `ConfirmationHook` are **traits + ready-made impls**: start with the in-memory versions, then swap to SQLite/Postgres and a real approval surface without touching your agent code.\n\n---\n\n## Why this\n\n| You want… | smooth-operator-core gives you |\n| --- | --- |\n| An agent loop you can **trust** | observe→think→act with iteration caps, parallel tool calls, and a typed `AgentEvent` stream |\n| **Typed tools** with guardrails | `Tool` trait + `ToolRegistry`, with pre/post hooks for surveillance, secret detection, prompt-injection guards |\n| **Stateful graphs** (a LangGraph analog) | `Workflow\u003cS\u003e` / `WorkflowBuilder\u003cS\u003e` with conditional edges and typed state |\n| **Resume after a crash** | `CheckpointStore`: in-memory, file, SQLite, or Postgres |\n| **RAG + memory** | `KnowledgeBase` / `Memory` traits (with in-memory impls) as clean seams |\n| **Humans in the loop** | `ConfirmationHook` + human channels for gated tool calls |\n| **Spend control** | per-model `ModelPricing`, `CostBudget`, `CostTracker` with hard enforcement |\n| **Offline, deterministic tests** | `LlmProvider` trait + `MockLlmClient` — script responses, assert on requests, no network |\n| To **embed it anywhere** | one crate, `provided.al2023`-friendly, runs in a Lambda, a container, or any host process |\n\nIt's the runtime the smooth-operator service actually ships on — not a reference design.\n\n---\n\n## Architecture\n\n### The agent loop\n\n```mermaid\n%%{init: {'theme':'base','themeVariables':{\n  'background':'#020618','primaryColor':'#0b1426','primaryTextColor':'#e6edf6','primaryBorderColor':'#2b3a52',\n  'lineColor':'#7c8aa0','secondaryColor':'#0b1426','tertiaryColor':'#0b1426','fontFamily':'ui-sans-serif, system-ui, sans-serif',\n  'clusterBkg':'#0b1426','clusterBorder':'#22304a'}}}%%\nflowchart TD\n    U[User input] --\u003e OBS[Observe: context window]\n    OBS --\u003e THINK[Think: LlmProvider.chat]\n    THINK --\u003e|text answer| DONE[Final AgentEvent]\n    THINK --\u003e|tool calls| GATE{HITL gate?}\n    GATE --\u003e|approved| ACT[Act: execute tools]\n    GATE --\u003e|rejected| THINK\n    ACT --\u003e COST[Charge + enforce budget]\n    COST --\u003e CP[Checkpoint step]\n    CP --\u003e MEM[Update memory + knowledge]\n    MEM --\u003e|under max| OBS\n    MEM --\u003e|max reached| DONE\n    classDef warm fill:#f49f0a,stroke:#ff6b6c,color:#1a0f00;\n    classDef teal fill:#00a6a6,stroke:#00c2c2,color:#011;\n    class THINK warm\n    class DONE teal\n```\n\nEvery edge above is a swappable trait: `LlmProvider`, `Tool`/`ToolRegistry`, `ConfirmationHook`, `CostTracker`, `CheckpointStore`, `Memory`, `KnowledgeBase`.\n\n### How the service consumes the engine\n\n```mermaid\n%%{init: {'theme':'base','themeVariables':{\n  'background':'#020618','primaryColor':'#0b1426','primaryTextColor':'#e6edf6','primaryBorderColor':'#2b3a52',\n  'lineColor':'#7c8aa0','secondaryColor':'#0b1426','tertiaryColor':'#0b1426','fontFamily':'ui-sans-serif, system-ui, sans-serif',\n  'clusterBkg':'#0b1426','clusterBorder':'#22304a'}}}%%\nflowchart LR\n    WID[chat-widget / clients] --\u003e|WS protocol| WS\n    subgraph svc[\"smooth-operator service (thin)\"]\n        WS[WebSocket API] --\u003e RT[ChatRuntime]\n    end\n    RT --\u003e|drives| AG\n    subgraph core[\"this crate\"]\n        AG[Agent loop]\n    end\n    AG -.-\u003e|OpenAI-compatible| GW[(LLM gateway)]\n    AG --\u003e|streamed answer| WID\n    classDef warm fill:#f49f0a,stroke:#ff6b6c,color:#1a0f00;\n    classDef teal fill:#00a6a6,stroke:#00c2c2,color:#011;\n    class AG warm\n    class GW teal\n```\n\nThe service is thin: it terminates the WebSocket protocol and hands turns to the engine. All the agent intelligence lives here.\n\n---\n\n## Test-driven by default — verified, not vibe-coded\n\nThis is the part we care about most. The engine ships **408 unit tests** that run in **seconds, fully offline**, because every LLM call goes through an `LlmProvider` seam that tests satisfy with `MockLlmClient`:\n\n```rust\nuse smooth_operator_core::llm_provider::{LlmProvider, MockLlmClient};\nuse smooth_operator_core::conversation::Message;\n\n#[tokio::test]\nasync fn agent_uses_the_tool_then_answers() {\n    let mock = MockLlmClient::new();\n    // Script the model: first a tool call, then a final answer.\n    mock.push_tool_call(\"call_1\", \"get_weather\", serde_json::json!({ \"city\": \"Tokyo\" }));\n    mock.push_text(\"It's 72F and sunny in Tokyo.\");\n\n    // ... drive the agent with `mock` injected as its LlmProvider ...\n\n    // Assert on what the agent actually sent the model — not just the output.\n    assert_eq!(mock.call_count(), 2);\n    let first = \u0026mock.calls()[0];\n    assert!(first.tools.iter().any(|t| t.name == \"get_weather\"));\n}\n```\n\n`MockLlmClient` replays scripted text, tool-calls, errors, and streaming events **in FIFO order**, and records every request — so a test can assert on the exact messages and tool schemas the agent sent, not just the final string. Clones share state (`Arc\u003cMutex\u003c_\u003e\u003e`), so the copy handed to the `Agent` and the handle held by the test see the same script and recordings.\n\n### The test pyramid\n\n```mermaid\n%%{init: {'theme':'base','themeVariables':{\n  'background':'#020618','primaryColor':'#0b1426','primaryTextColor':'#e6edf6','primaryBorderColor':'#2b3a52',\n  'lineColor':'#7c8aa0','secondaryColor':'#0b1426','tertiaryColor':'#0b1426','fontFamily':'ui-sans-serif, system-ui, sans-serif',\n  'clusterBkg':'#0b1426','clusterBorder':'#22304a'}}}%%\nflowchart TD\n    J[\"LLM-as-judge evals — multi-turn quality, 0–5\"]\n    E[\"Live E2E — real gateway + WS, streamed answer\"]\n    C[\"Conformance — SQLite + Postgres stores, testcontainers\"]\n    U[\"337 unit tests — MockLlmClient, offline, fast\"]\n\n    J --\u003e E --\u003e C --\u003e U\n\n    classDef warm fill:#f49f0a,stroke:#ff6b6c,color:#1a0f00;\n    classDef teal fill:#00a6a6,stroke:#00c2c2,color:#011;\n    class J warm\n    class U teal\n```\n\n- **Unit (408):** the bulk. Loop control, tool dispatch, workflow edges, compaction, cost enforcement, HITL gating, checkpoint round-trips — all against `MockLlmClient`.\n- **Conformance:** the `sqlite` and `postgres` checkpoint stores run the same suite against real engines (testcontainers), so \"resume\" means the same thing everywhere.\n- **Live E2E:** the smooth-operator service + [chat-widget](https://github.com/SmooAI/chat-widget) drive a real streamed, knowledge-grounded answer through a live gateway.\n- **LLM-as-judge:** multi-turn conversation quality is scored 0–5 by a judge model. This caught a real multi-turn context defect: a regression scored **1/5**, the fix landed, and it went back to **5/5** — a class of bug no assertion-based test would have flagged.\n\nRun them:\n\n```bash\ncd rust/smooth-operator-core\ncargo test                                   # 337 unit tests, offline\ncargo test --features sqlite,postgres        # + checkpoint-store conformance\ncargo clippy --all-targets -- -D warnings\n```\n\n---\n\n## Cargo features\n\n| Feature | Effect |\n| --- | --- |\n| `sqlite` | SQLite checkpoint store (`rusqlite`, bundled) |\n| `postgres` | Postgres checkpoint store (r2d2 pool) |\n\n---\n\n## Repository layout\n\nThis is a multi-language SmooAI package. The Rust crate is the reference; other languages mirror its surface. For install commands and a hello-agent example in every language, see [**docs/Polyglot-Engines.md**](./docs/Polyglot-Engines.md).\n\n| Directory | Language | Status |\n| --- | --- | --- |\n| [`rust/`](./rust) | Rust (reference) | Active — crate `smooai-smooth-operator-core` (lib `smooth_operator_core`) |\n| [`typescript/`](./typescript) | TypeScript | Planned |\n| [`go/`](./go) | Go | Active — module `github.com/SmooAI/smooth-operator-core/go` |\n| [`dotnet/`](./dotnet) | C# / .NET | Planned (first-class target) |\n| [`python/`](./python) | Python | Planned |\n\nBindings follow a **protocol-first** strategy (a stable wire spec each language implements natively), with in-process FFI (napi-rs, PyO3/uniffi) layered on where embedding the engine pays off.\n\n---\n\n## Smoo-powered or bring-your-own\n\n**Bring-your-own:** point `LlmConfig.api_url` at any OpenAI-compatible endpoint (OpenAI, an Anthropic-compatible proxy, vLLM, Ollama's OpenAI shim). Provide your own `CheckpointStore`, `Memory`, and `KnowledgeBase` impls. The engine has zero hosted dependencies — it's a library.\n\n**Smoo-powered:** point it at the SmooAI LLM gateway (`https://llm.smoo.ai/v1`) for unified billing, model routing, and cost tracking, and let [**lom.smoo.ai**](https://lom.smoo.ai) run the smooth-operator service for you — no infra to operate.\n\n---\n\n## Links\n\n- [**lom.smoo.ai**](https://lom.smoo.ai) — run it hosted\n- [smooth-operator](https://github.com/SmooAI/smooth-operator) — the agent service built on this engine\n- [chat-widget](https://github.com/SmooAI/chat-widget) — the embeddable widget that talks to it\n- [smoo.ai](https://smoo.ai) — the product · [github.com/SmooAI](https://github.com/SmooAI) — more open source\n\n## Part of Smoo AI\n\n`smooth-operator-core` is built and open-sourced by **[Smoo AI](https://smoo.ai)** — the AI-powered business platform with AI built into every product: CRM, customer support, campaigns, field service, observability, and developer tools.\n\n- 🚀 **Smooth on the platform** — [smoo.ai/th](https://smoo.ai/th)\n- 🧰 **More open source from Smoo AI** — [smoo.ai/open-source](https://smoo.ai/open-source)\n- 🧩 **Sibling repos** — [smooth-operator](https://github.com/SmooAI/smooth-operator) (the agent service), [@smooai/chat-widget](https://github.com/SmooAI/chat-widget) (the embeddable UI), [@smooai/config](https://github.com/SmooAI/config), [@smooai/logger](https://github.com/SmooAI/logger)\n\n## Contributing\n\nIssues and PRs welcome. Keep the engine test-first: every change ships with the offline `MockLlmClient` coverage that proves the loop still holds.\n\n## License\n\nMIT — see [LICENSE](./LICENSE).\n\n---\n\n\u003cp align=\"center\"\u003e\n  Built by \u003ca href=\"https://smoo.ai\"\u003e\u003cstrong\u003eSmoo AI\u003c/strong\u003e\u003c/a\u003e — AI built into every product.\n\u003c/p\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsmooai%2Fsmooth-operator-core","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsmooai%2Fsmooth-operator-core","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsmooai%2Fsmooth-operator-core/lists"}