# Agent Skill Compiler

`agent-skill-compiler` is a Python SDK for sending agent traces from your application backend to a remote Agent Skill Compiler backend.

This package is for `pip install` only. It does not run the ASC server, database, or UI.

## Install

```bash
pip install agent-skill-compiler
```

With Agno support:

```bash
pip install "agent-skill-compiler[agno]"
```

For Microsoft Agent Framework:

```bash
pip install agent-skill-compiler
pip install agent-framework --pre
```

## What You Need

Your app backend needs these environment variables:

```bash
ASC_BASE_URL=http://your-asc-backend
ASC_PUBLIC_KEY=asc_pk_...
ASC_SECRET_KEY=asc_sk_...
```

Legacy aliases are also supported:

```bash
SKILL_COMPILER_HOST=http://your-asc-backend
SKILL_COMPILER_PUBLIC_KEY=asc_pk_...
SKILL_COMPILER_SECRET_KEY=asc_sk_...
```

## Quick Start

```python
from agent_skill_compiler import SkillCompilerTracer

tracer = SkillCompilerTracer.from_env(
    optional=True,
    default_agent_name="planner",
    metadata={
        "service": "app-backend",
        "framework": "custom",
    },
)

with tracer.trace(
    task_name="ai_planner_chat",
    input_text=user_prompt,
    metadata={
        "workflow": "ai_planner",
        "session_id": session_id,
        "user_id": user_id,
    },
) as run:
    tool_call = run.tool_call(
        action_name="get_calendar_tasks",
        semantic_name="list_user_tasks",
        arguments={"user_id": user_id, "date": "today"},
    )

    tasks = load_tasks(user_id)

    run.tool_result(
        action_name="get_calendar_tasks",
        semantic_name="list_user_tasks",
        result={"task_count": len(tasks), "tasks": tasks},
        parent_event_id=tool_call.event_id,
    )

    run.decision(
        action_name="prioritize_tasks",
        decision={"strategy": "due_date_then_importance"},
        reason="Tasks exist and need ordering.",
    )

    run.final_output(output=assistant_response)
```

If the environment variables are missing and `optional=True`, the SDK becomes a safe no-op and will not break your app.

## Low-Level Client

```python
from agent_skill_compiler import SkillCompilerClient

client = SkillCompilerClient.from_env(optional=False)

run = client.start_run(
    task_name="customer_followup",
    input_text="Review this customer issue and prepare next steps.",
    metadata={"service": "support-api", "workflow": "support_triage"},
)

event = client.record_event(
    run_id=run.run_id,
    agent_name="ResearchAgent",
    action_name="search_docs",
    action_kind="tool_call",
    input_payload={"query": "latest billing escalation policy"},
)

client.record_event(
    run_id=run.run_id,
    agent_name="ResearchAgent",
    action_name="search_docs",
    action_kind="tool_result",
    output_payload={"documents": ["billing-policy-v2"]},
    parent_event_id=event.event_id,
)

client.finish_run(run_id=run.run_id, status="success")
client.close()
```

## What The Tracer Captures

The generic tracer supports:

- `run.tool_call(...)`
- `run.tool_result(...)`
- `run.decision(...)`
- `run.route(...)`
- `run.message(...)`
- `run.error(...)`
- `run.final_output(...)`
- `run.update_metadata(...)`

Use `semantic_name=...` on tool events when you want stable grouping across framework-specific tool names.

## Helpers Exported By The SDK

- `SkillCompilerClient`
- `AsyncSkillCompilerClient`
- `SkillCompilerTracer`
- `AsyncSkillCompilerTracer`
- `trace_run(...)`
- `trace_run_async(...)`
- `serialize_for_trace(...)`
- `normalize_tool_arguments(...)`
- `get_first_attr(...)`

## Framework Integrations

### Generic

```python
from agent_skill_compiler import SkillCompilerClient, trace_run

client = SkillCompilerClient.from_env(optional=False)

with trace_run(
    client,
    task_name="support_triage",
    input_text="Investigate this issue.",
    metadata={"framework": "custom"},
) as run:
    tool_call = run.tool_call(
        action_name="search_docs",
        arguments={"query": "refund policy"},
    )
    run.tool_result(
        action_name="search_docs",
        result={"documents": ["refund-policy-v2"]},
        parent_event_id=tool_call.event_id,
    )
    run.final_output(output="Escalate to billing.")
```

### Agno

```python
from agent_skill_compiler import SkillCompilerClient, run_agno_agent

client = SkillCompilerClient.from_env(optional=False)

response = run_agno_agent(
    agent,
    client,
    input="Summarize the latest billing guidance.",
    task_name="billing_guidance",
    metadata={"framework": "agno"},
)
```

### Microsoft Agent Framework

```python
from agent_skill_compiler import AsyncSkillCompilerClient, create_agent_framework_middleware

client = AsyncSkillCompilerClient.from_env(optional=False)

middleware = create_agent_framework_middleware(
    client,
    task_name="weather_assistant",
    metadata={"framework": "microsoft-agent-framework"},
)
```

## Important

- This package does not create ASC projects or keys.
- This package does not run the ASC backend.
- This package does not include the frontend.
- Keep `ASC_SECRET_KEY` on the backend only.

## License

MIT
