Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 68 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,65 @@
<a href="https://github.com/evalstate/fast-agent-mcp/blob/main/LICENSE"><img src="https://img.shields.io/pypi/l/fast-agent-mcp" /></a>
</p>

## Overview
## Start Here

> [!TIP]
> Please see : https://fast-agent.ai for latest documentation. There is also an LLMs.txt [here](https://fast-agent.ai/llms.txt)
> Please see https://fast-agent.ai for latest documentation.

**`fast-agent`** is a flexible way to interact with LLMs, excellent for use as a Coding Agent, Development Toolkit, Evaluation or Workflow platform.

To start an interactive session with shell support, install [uv](https://astral.sh/uv) and run

```bash
uvx fast-agent-mcp@latest -x
```

To start coding with Hugging Face inference providers or use your OpenAI Codex plan:

```bash
# Code with Hugging Face Inference Providers
uvx fast-agent-mcp@latest --pack hf-dev

# Code with Codex (agents optimized for OpenAI)
uvx fast-agent-mcp@latest --pack codex
```

Enter a shell with `!`, or run shell commands e.g. `! cd web && npm run build`.

Manage skills with the `/skills` command, and connect to MCP Servers with `/connect`. The default **`fast-agent`** registry contains skills to let you set up LSP, Agent and Tool Hooks, Compaction strategies, Automation and more.

```bash
# /connect supports stdio or streamable http (with OAuth)

# Start a STDIO server
/connect @modelcontextprotocol/server-everything

# Connect to a Streamable HTTP Server
/connect https://huggingface.co/mcp
```

It's recommended to install **`fast-agent`** to set up the shell aliases and other tooling.

```bash
# Install fast-agent
uv tool install -U fast-agent-mcp

# Run fast-agent with opus, shell support and subagent/smart mode
fast-agent --model opus -x --smart
```

Use local models with the generic provider, or automatically create the correct configuration for `llama.cpp`:

```bash
fast-agent model llamacpp
```

Any **`fast-agent`** setup or program can be used with any ACP client - the simplest way is to use `fast-agent-acp`:

```bash
# Run fast-agent inside Toad
toad acp "fast-agent-acp -x --model sonnet"
```

**`fast-agent`** enables you to create and interact with sophisticated multimodal Agents and Workflows in minutes. It is the first framework with complete, end-to-end tested MCP Feature support including Sampling and Elicitations.

Expand All @@ -23,32 +78,32 @@ The simple declarative syntax lets you concentrate on composing your Prompts and
Model support is comprehensive with native support for Anthropic, OpenAI and Google providers as well as Azure, Ollama, Deepseek and dozens of others via TensorZero. Structured Outputs, PDF and Vision support is simple to use and well tested. Passthrough and Playback LLMs enable rapid development and test of Python glue-code for your applications.

Recent features include:
- Agent Skills (SKILL.md)
- MCP-UI Support |
- OpenAI Apps SDK (Skybridge)
- Shell Mode
- Advanced MCP Transport Diagnsotics
- MCP Elicitations

<img width="800" alt="MCP Transport Diagnostics" src="https://github.com/user-attachments/assets/e26472de-58d9-4726-8bdd-01eb407414cf" />
- Agent Skills (SKILL.md)
- MCP-UI Support |
- OpenAI Apps SDK (Skybridge)
- Shell Mode
- Advanced MCP Transport Diagnsotics
- MCP Elicitations

<img width="800" alt="MCP Transport Diagnostics" src="https://github.com/user-attachments/assets/e26472de-58d9-4726-8bdd-01eb407414cf" />

`fast-agent` is the only tool that allows you to inspect Streamable HTTP Transport usage - a critical feature for ensuring reliable, compliant deployments. OAuth is supported with KeyRing storage for secrets. Use the `fast-agent auth` command to manage.





> [!IMPORTANT]
>
> Documentation is included as a submodule. When cloning, use `--recurse-submodules` to get everything:
>
> ```bash
> git clone --recurse-submodules https://github.com/evalstate/fast-agent.git
> ```
>
> Or if you've already cloned:
>
> ```bash
> git submodule update --init --recursive
> ```
>
> The documentation source is also available at: https://github.com/evalstate/fast-agent-docs

### Agent Application Development
Expand Down
4 changes: 2 additions & 2 deletions examples/hf-toad-cards/hooks/save_history.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from collections.abc import Iterable
from datetime import datetime
from typing import TYPE_CHECKING
from typing import TYPE_CHECKING, cast

from fast_agent.hooks import HookContext
from fast_agent.mcp.prompt_serialization import save_messages
Expand Down Expand Up @@ -30,7 +30,7 @@ async def save_history_to_file(ctx: HookContext) -> None:
# Fall back to runner's turn messages + final response
runner_messages = getattr(ctx.runner, "delta_messages", None)
if isinstance(runner_messages, Iterable):
messages = list(runner_messages)
messages = [cast("PromptMessageExtended", message) for message in runner_messages]
else:
messages = []
if ctx.message and ctx.message not in messages:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
import subprocess
import sys
from dataclasses import asdict, dataclass, field
from typing import Optional
from typing import Optional, cast
from urllib.parse import quote, urlparse

JsonValue = str | int | float | bool | None | list["JsonValue"] | dict[str, "JsonValue"]
Expand Down Expand Up @@ -120,12 +120,25 @@ def run_gh_jsonlines(args: list[str], check: bool = True) -> list[dict]:
return out


def _ensure_json_value(value: object, label: str) -> JsonValue:
if value is None or isinstance(value, str | int | float | bool):
return value
if isinstance(value, list):
return [_ensure_json_value(item, f"{label}[]") for item in value]
if isinstance(value, dict):
return _ensure_json_dict(value, label)
raise ValueError(f"Expected JSON-compatible value for {label}")


def _ensure_json_dict(value: object, label: str) -> JsonDict:
if not isinstance(value, dict):
raise ValueError(f"Expected object for {label}")
if not all(isinstance(key, str) for key in value.keys()):
raise ValueError(f"Expected string keys for {label}")
return {str(key): val for key, val in value.items()}
return cast(
"JsonDict",
{str(key): _ensure_json_value(val, f"{label}.{key}") for key, val in value.items()},
)


def _get_required_str(data: JsonDict, key: str) -> str:
Expand Down
4 changes: 2 additions & 2 deletions publish/fast-agent-acp/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "hatchling.build"

[project]
name = "fast-agent-acp"
version = "0.4.7"
version = "0.6.9"
description = "Convenience launcher that pulls in fast-agent-mcp and exposes the ACP CLI entrypoint."
readme = "README.md"
license = { text = "Apache-2.0" }
Expand All @@ -18,7 +18,7 @@ classifiers = [
]
requires-python = ">=3.13.5,<3.15"
dependencies = [
"fast-agent-mcp==0.4.7",
"fast-agent-mcp==0.6.9",
]

[project.urls]
Expand Down
4 changes: 2 additions & 2 deletions publish/hf-inference-acp/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "hatchling.build"

[project]
name = "hf-inference-acp"
version = "0.4.31"
version = "0.6.9"
description = "Hugging Face inference agent with ACP support, powered by fast-agent-mcp"
readme = "README.md"
license = { text = "Apache-2.0" }
Expand All @@ -18,7 +18,7 @@ classifiers = [
]
requires-python = ">=3.13.5,<3.15"
dependencies = [
"fast-agent-mcp==0.5.7",
"fast-agent-mcp==0.6.9",
"huggingface_hub>=1.3.4",
]

Expand Down
23 changes: 21 additions & 2 deletions publish/hf-inference-acp/src/hf_inference_acp/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
from fast_agent.cli.commands.server_helpers import add_servers_to_config, generate_server_name
from fast_agent.cli.commands.url_parser import generate_server_configs, parse_server_urls
from fast_agent.core.agent_card_validation import collect_agent_card_names, find_loaded_agent_issues
from fast_agent.llm.model_database import ModelDatabase
from fast_agent.llm.model_factory import ModelFactory
from fast_agent.llm.provider_key_manager import ProviderKeyManager
from fast_agent.llm.provider_types import Provider
Expand All @@ -43,8 +44,26 @@
)
from hf_inference_acp.wizard import WizardSetupLLM

# Register wizard-setup model locally
ModelFactory.register_runtime_model("wizard-setup", provider=Provider.FAST_AGENT, llm_class=WizardSetupLLM)

def _register_wizard_setup_model() -> None:
"""Register the local wizard model across fast-agent versions."""
register_runtime_model = getattr(ModelFactory, "register_runtime_model", None)
if callable(register_runtime_model):
register_runtime_model(
"wizard-setup",
provider=Provider.FAST_AGENT,
llm_class=WizardSetupLLM,
)
return

ModelFactory.MODEL_SPECIFIC_CLASSES["wizard-setup"] = WizardSetupLLM
ModelDatabase.register_runtime_model_params(
"wizard-setup",
ModelDatabase.FAST_AGENT_STANDARD.model_copy(),
)


_register_wizard_setup_model()

app = typer.Typer(
help="Run the Hugging Face Inference ACP agent over stdio.",
Expand Down
7 changes: 4 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ dependencies = [
"pyyaml>=6.0.2",
"rich>=14.3.3",
"typer>=0.24.1",
"anthropic>=0.84.0",
"openai[aiohttp]>=2.28.0",
"anthropic[vertex]>=0.86.0",
"openai[aiohttp]>=2.29.0",
"prompt-toolkit>=3.0.52",
"aiohttp>=3.13.2",
"opentelemetry-distro==0.60b1",
Expand All @@ -40,11 +40,12 @@ dependencies = [
"keyring>=24.3.1",
"python-frontmatter>=1.1.0",
"watchfiles>=1.1.0",
"agent-client-protocol>=0.8.1",
"agent-client-protocol==0.9.0",
"tiktoken>=0.12.0",
"uvloop>=0.22.1; platform_system != 'Windows'",
"multilspy>=0.0.15",
"ruamel.yaml>=0.18.16",
"mslex>=1.3.0",
]

[project.optional-dependencies]
Expand Down
15 changes: 14 additions & 1 deletion src/fast_agent/acp/__init__.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
"""Agent Client Protocol (ACP) support for fast-agent."""

from typing import TYPE_CHECKING, Any

from fast_agent.acp.acp_aware_mixin import ACPAwareMixin, ACPCommand, ACPModeInfo
from fast_agent.acp.acp_context import ACPContext, ClientCapabilities, ClientInfo
from fast_agent.acp.filesystem_runtime import ACPFilesystemRuntime
from fast_agent.acp.server.agent_acp_server import AgentACPServer
from fast_agent.acp.terminal_runtime import ACPTerminalRuntime

if TYPE_CHECKING: # pragma: no cover - type checking only
from fast_agent.acp.server.agent_acp_server import AgentACPServer as AgentACPServer

__all__ = [
"ACPCommand",
"ACPModeInfo",
Expand All @@ -17,3 +21,12 @@
"ACPFilesystemRuntime",
"ACPTerminalRuntime",
]


def __getattr__(name: str) -> Any:
if name == "AgentACPServer":
from fast_agent.acp.server.agent_acp_server import AgentACPServer

return AgentACPServer

raise AttributeError(f"module '{__name__}' has no attribute '{name}'")
Loading
Loading