Weft AI Language
Expert skill for building AI systems with Weft, a Rust-based programming language where LLMs, humans, APIs, and infrastructure are first-class primitives with typed connections and durable execution.
- Skill ID
- reason-machines/trending-skills/weft-ai-language
- Publisher
- reason-machines
- Repository
- trending-skills
- Installs
- 0
- Files
- 1
- Synced
- Sep 23, 2026
Open any RiverX project, open the Skills panel in the chat, and search for this identifier. The files are fetched from the source repository at install time.
reason-machines/trending-skills/weft-ai-languageInstalls these files- SKILL.md
What this skill tells the agent
Weft AI Language
Skill by ara.so — Daily 2026 Skills collection.
Weft is a programming language (implemented in Rust) for AI systems where LLMs, humans, APIs, databases, and agents are base language primitives. You wire nodes together, the compiler type-checks every connection, and the program runs with durable execution backed by Restate (survives crashes, supports multi-day human-in-the-loop pauses). A visual graph view is generated automatically from code.
Installation & Setup
Prerequisites
- Docker (for PostgreSQL)
- Node.js
- macOS:
brew install bash(Bash 4+ required) - Rust, Restate, and pnpm are auto-installed by
dev.sh
Clone and Configure
git clone https://github.com/WeaveMindAI/weft.git
cd weft
cp .env.example .env
# Edit .env — add your API keysEnvironment Variables (.env)
OPENROUTER_API_KEY= # Required for LLM nodes
TAVILY_API_KEY= # Required for Web Search nodes
ELEVENLABS_API_KEY= # Required for Speech-to-Text nodes
APOLLO_API_KEY= # Required for Apollo enrichment nodes
DISCORD_BOT_TOKEN= # Required for Discord nodesAll keys are optional at startup — missing keys surface as runtime errors only when the relevant node executes.
Start Development
# Terminal 1 — backend (PostgreSQL, Restate, all services)
./dev.sh server
# Terminal 2 — dashboard (SvelteKit at http://localhost:5173)
./dev.sh dashboard
# Or both at once
./dev.sh allVS Code
Use the Dev Local All task to start server + dashboard in split terminals.
Development Commands
./dev.sh server # Start backend services
./dev.sh dashboard # Start frontend
./dev.sh all # Start everything
./dev.sh extension # Build browser extension
./cleanup.sh # Stop everything, wipe Restate + DB
./cleanup.sh --no-db # Stop services, keep database
./cleanup.sh --services # Stop services only
./cleanup.sh --db-destroy # Remove PostgreSQL container entirely
cargo build # Build without running PostgreSQL (uses .sqlx snapshots)
cargo test # Test without running PostgreSQLInfrastructure Nodes (Kubernetes)
Only needed if using nodes like Postgres Database that provision K8s resources:
curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.31.0/kind-$(uname -s | tr '[:upper:]' '[:lower:]')-amd64
chmod +x ./kind && sudo mv ./kind /usr/local/bin/kind
INFRASTRUCTURE_TARGET=local ./dev.sh serverThe Weft Language
Core Concepts
- Nodes — typed computational units (LLM, HTTP, Human Query, Gate, etc.)
- Connections — typed edges between node ports; compiler validates all types
- Groups — collapse any set of nodes into a single reusable node
- Durable execution — programs checkpoint via Restate; long pauses are transparent
Node Syntax
node_name = NodeType -> (output_port: OutputType) {
label: "Human-readable name"
config_key: "value"
}
node_name.input_port = other_node.output_portSimple Example — Poem Generator
# Project: Poem Generator
# Description: Writes a short poem about any topic
topic = Text {
label: "Topic"
value: "the silence between stars"
}
llm_config = LlmConfig {
label: "Config"
model: "anthropic/claude-sonnet-4.6"
systemPrompt: "Write a short, beautiful poem (4-6 lines) about the given topic."
temperature: "0.8"
}
poet = LlmInference -> (response: String) {
label: "Poet"
}
poet.prompt = topic.value
poet.config = llm_config.config
output = Debug { label: "Poem" }
output.data = poet.responseBuilt-in Node Catalog
AI Nodes
| Node | Purpose |
|---|---|
LlmConfig | Configure model, system prompt, temperature |
LlmInference | Call an LLM, returns response: String |
Data Nodes
| Node | Purpose |
|---|---|
Text | Static or dynamic text value |
Number | Numeric value |
Dict | Key-value map |
List | Ordered list |
Pack / Unpack | Bundle/unbundle multiple values |
Flow Nodes
| Node | Purpose |
|---|---|
Gate | Conditional branching |
HumanQuery | Pause execution, send form to human, resume on response |
HumanTrigger | Start a program from a human action |
Communication Nodes
Discord, Slack, Telegram, WhatsApp, Email, X
Storage Nodes
Postgres, Memory
Enrichment Nodes
Apollo, WebSearch, SpeechToText
Trigger Nodes
Cron, webhooks, polling
Utility Nodes
Debug, Template, HTTP, Code (Python execution)
Common Patterns
Pattern 1 — LLM with Structured Config
# Project: Content Summarizer
# Description: Summarizes a webpage given a URL
url_input = Text {
label: "URL"
value: "https://example.com/article"
}
search = WebSearch -> (results: String) {
label: "Fetch Content"
}
search.query = url_input.value
summarizer_config = LlmConfig {
label: "Summarizer Config"
model: "anthropic/claude-sonnet-4.6"
systemPrompt: "Summarize the following content in 3 bullet points."
temperature: "0.3"
}
summarizer = LlmInference -> (response: String) {
label: "Summarizer"
}
summarizer.prompt = search.results
summarizer.config = summarizer_config.config
output = Debug { label: "Summary" }
output.data = summarizer.responsePattern 2 — Human-in-the-Loop Approval
# Project: Content Approval Pipeline
# Description: AI drafts content, human approves before publishing
draft_config = LlmConfig {
label: "Drafter Config"
model: "openai/gpt-4o"
systemPrompt: "Write a Twitter thread about the given topic. Be engaging."
temperature: "0.7"
}
topic = Text {
label: "Topic"
value: "distributed systems"
}
drafter = LlmInference -> (response: String) {
label: "Content Drafter"
}
drafter.prompt = topic.value
drafter.config = draft_config.config
# Pauses execution indefinitely until a human responds
approval = HumanQuery -> (approved: Boolean, feedback: String) {
label: "Human Approval"
question: "Do you approve this draft for publishing?"
}
approval.content = drafter.response
gate = Gate -> (passed: String) {
label: "Approval Gate"
}
gate.condition = approval.approved
gate.value = drafter.response
publisher = Discord {
label: "Publish to Discord"
channel: "announcements"
}
publisher.message = gate.passedPattern 3 — Conditional Branching with Gate
# Project: Sentiment Router
# Description: Routes messages based on sentiment analysis
message = Text {
label: "Input Message"
value: "This product is absolutely terrible!"
}
sentiment_config = LlmConfig {
label: "Sentiment Config"
model: "anthropic/claude-haiku-3.5"
systemPrompt: "Classify sentiment as 'positive' or 'negative'. Respond with one word only."
temperature: "0.0"
}
classifier = LlmInference -> (response: String) {
label: "Sentiment Classifier"
}
classifier.prompt = message.value
classifier.config = sentiment_config.config
is_negative = Gate -> (passed: String) {
label: "Is Negative?"
}
is_negative.condition = classifier.response
is_negative.value = message.value
alert = Slack {
label: "Alert Team"
channel: "customer-issues"
}
alert.message = is_negative.passedPattern 4 — Cron-Triggered Pipeline
# Project: Daily Digest
# Description: Sends a daily news digest every morning
schedule = Cron {
label: "Daily Trigger"
expression: "0 8 * * *"
}
news = WebSearch -> (results: String) {
label: "Fetch News"
}
news.query = "AI and technology news today"
digest_config = LlmConfig {
label: "Digest Config"
model: "openai/gpt-4o-mini"
systemPrompt: "Summarize these news items into a concise morning digest."
temperature: "0.4"
}
digest = LlmInference -> (response: String) {
label: "Digest Writer"
}
digest.prompt = news.results
digest.config = digest_config.config
send = Email {
label: "Send Digest"
to: "team@example.com"More from reason-machines
Use this skill in a project
Open any RiverX project, search the Skills panel for reason-machines/trending-skills/weft-ai-language, and install it in one click.
