Skip to content

Latest commit

 

History

History
217 lines (161 loc) · 7.23 KB

File metadata and controls

217 lines (161 loc) · 7.23 KB

OpenClaw

What Is This?

This guide shows how to use Agentic Programming within OpenClaw — as a skill, a utility library, or an MCP tool provider.

Agentic Programming and OpenClaw solve different problems:

  • OpenClaw orchestrates agents, manages sessions, routes messages
  • Agentic Programming gives individual functions the ability to think (LLM-in-the-loop)

They compose naturally: OpenClaw's skills can use agentic functions internally.

Setup

# In your OpenClaw workspace
cd ~/.openclaw/workspace

# Clone OpenProgram
git clone https://github.com/Fzkuji/OpenProgram.git

# Prepare the source checkout
cd OpenProgram
uv sync --locked

Usage Pattern 1: Agentic Functions Inside a Skill

The simplest integration — use agentic functions as building blocks within an OpenClaw skill.

Skill structure:

~/.openclaw/workspace/skills/my-agentic-skill/
├── SKILL.md
└── scripts/
    └── analyze.py

scripts/analyze.py:

#!/usr/bin/env python3
"""
OpenClaw skill script that uses Agentic Programming internally.
Called by the agent via the exec tool.
"""
import sys
import os

# Add the source checkout to the script path
sys.path.insert(0, os.path.expanduser("~/.openclaw/workspace/OpenProgram"))

from openprogram import agentic_function
from openprogram.agentic_programming import llm
from openprogram.providers.registry import create_runtime

runtime = create_runtime(provider="claude-code", model="haiku")


@agentic_function
def decompose(task, runtime=None):
    """Break a complex task into actionable steps."""
    return llm([
        {"type": "text", "text": f"Break this task into 3-5 concrete, actionable steps:\n{task}\n\nNumber each step. Be specific."},
    ])


@agentic_function
def assess(step, runtime=None):
    """Assess difficulty and time estimate for a step."""
    return llm([
        {"type": "text", "text": f"For this step, give: difficulty (easy/medium/hard) and time estimate.\nFormat: [difficulty] ~Xh\n\nStep: {step}"},
    ])


@agentic_function
def plan(task, runtime=None):
    """Create a detailed plan for a task."""
    steps_text = decompose(task=task, runtime=runtime)

    lines = [l.strip() for l in steps_text.split("\n") if l.strip() and l.strip()[0].isdigit()]
    assessments = []
    for line in lines[:5]:
        a = assess(step=line, runtime=runtime)
        assessments.append(f"{line}\n{a}")

    return "\n\n".join(assessments)


if __name__ == "__main__":
    task = " ".join(sys.argv[1:]) if len(sys.argv) > 1 else "Build a REST API with authentication"
    result = plan(task=task, runtime=runtime)
    print(result)

SKILL.md (OpenClaw requires the YAML front matter — name and description are what the agent matches on):

---
name: my-agentic-skill
description: Plan and decompose tasks using Agentic Programming with automatic context tracking.
---

# my-agentic-skill

When the user asks to plan, decompose, or break down a task, run:

\`\`\`bash
uv run --project ~/.openclaw/workspace/OpenProgram python \
  ~/.openclaw/workspace/skills/my-agentic-skill/scripts/analyze.py \
  "the task description"
\`\`\`

This runs the script with the source checkout's locked environment. Do not run it with the system Python, which does not contain OpenProgram's dependencies.

OpenClaw and OpenProgram use the same AgentSkills-compatible SKILL.md format, so user, project, or plugin skills can be shared between them. OpenProgram does not ship default skills; product workflows are Programs.

Usage Pattern 2: As a Python Library in Agent Scripts

If your OpenClaw agent runs Python scripts, you can import agentic functions directly:

"""
Code review script called by an OpenClaw agent.
"""
from openprogram import agentic_function
from openprogram.agentic_programming import llm
from openprogram.providers.registry import create_runtime

runtime = create_runtime(provider="claude-code", model="haiku")


@agentic_function
def review_code(code, language="python", runtime=None):
    """Review code for bugs, style issues, and improvements."""
    return llm([
        {"type": "text", "text": f"Review this {language} code. List:\n1. Bugs (if any)\n2. Style issues\n3. Suggested improvements\n\n```{language}\n{code}\n```"},
    ])


@agentic_function
def suggest_tests(code, runtime=None):
    """Suggest test cases for the given code."""
    return llm([
        {"type": "text", "text": f"Suggest 3 test cases for this code. For each, give: test name, input, expected output.\n\n```python\n{code}\n```"},
    ])


@agentic_function
def code_analysis(code, runtime=None):
    """Full code analysis: review + test suggestions."""
    review = review_code(code=code, runtime=runtime)
    tests = suggest_tests(code=code, runtime=runtime)
    return f"## Code Review\n{review}\n\n## Suggested Tests\n{tests}"

Usage Pattern 3: MCP Tool Wrapper

Wrap agentic functions as MCP tools that OpenClaw can call:

#!/usr/bin/env python3
"""
MCP-compatible tool server that exposes agentic functions.
"""
import json
import sys

from openprogram import agentic_function
from openprogram.agentic_programming import llm
from openprogram.providers.registry import create_runtime

runtime = create_runtime(provider="claude-code", model="haiku")


@agentic_function
def summarize_text(text, style="bullet_points", runtime=None):
    """Summarize text in the specified style."""
    style_instructions = {
        "bullet_points": "Summarize as 3-5 bullet points.",
        "one_paragraph": "Summarize in one paragraph.",
        "eli5": "Explain like I'm 5.",
    }
    instruction = style_instructions.get(style, style_instructions["bullet_points"])

    return llm([
        {"type": "text", "text": f"{instruction}\n\nText:\n{text}"},
    ])


if __name__ == "__main__":
    request = json.loads(sys.stdin.read())
    tool = request.get("tool")
    args = request.get("args", {})

    if tool == "summarize":
        result = summarize_text(**args, runtime=runtime)
        print(json.dumps({"result": result}))
    else:
        print(json.dumps({"error": f"Unknown tool: {tool}"}))

Why Use Agentic Programming in OpenClaw?

Without Agentic Programming With Agentic Programming
Agent does all reasoning in one LLM call Reasoning is split into focused function calls
Context grows unboundedly Context is a structured DAG, scoped per function
Hard to debug what the agent "thought" Every call is recorded as a session DAG node, reviewable in the Web UI or the session files
Retry = retry the entire agent turn Retry = retry just the failed function

Tips

  1. Start with the claude-code provider — no extra API key needed; a Claude Code login is enough, and it runs on your subscription. See Claude Code integration.
  2. Pick the provider by billingcreate_runtime(provider="claude-code") runs on your Claude subscription, create_runtime(provider="anthropic") bills against an Anthropic API key.
  3. Review execution traces — every function call is recorded in the session DAG; find the session with the Web UI or openprogram sessions list and review it there.
  4. Keep functions small and focused — each @agentic_function should do one thing; let Python compose them.