Skip to main content

Fury Logo

Fury

Discord Tests

A flexible and powerful AI agent library for Python, designed to build agents with tool support, multimodal capabilities, and streaming responses.

Features

  • Interruption and early stopping: Agents now use the Runner pattern, allowing them to be interrupted or stopped mid-generation.
  • Tool Support: Define and register custom tools (functions) that the agent can execute and parallel tool execution support.
  • Image inputs: Support for multimodal image inputs.
  • History Management: Use HistoryManager for simple target-context trimming.
  • Optional session storage: Save append-only conversations, metadata, and custom events to JSONL or your own database callbacks.

Installation

Install with uv:

uv add fury-sdk

Quick Start

from fury import Agent

agent = Agent(
    model="unsloth/GLM-4.6V-Flash-GGUF:Q8_0",
    system_prompt="You are a helpful assistant.",
)

print(agent.ask("Hello!", history=[]))
print(agent.ask("Hello!", history=[], model="another-model"))

Other examples:

History Management

Fury's HistoryManager is intentionally small: it stores a list of OpenAI-compatible JSON message dictionaries and trims old messages to keep the newest context within a target size.

from fury import HistoryManager

history_manager = HistoryManager(target_context_length=4096)

await history_manager.add({"role": "user", "content": user_input})

transcript = []
runner = agent.runner()
async for event in runner.chat(history_manager.history):
    if event.history_delta:
        transcript.append(event.history_delta.message)
await history_manager.extend(transcript)

Image messages are supported via add_image(). By default Fury stores a lightweight placeholder plus path metadata; set save_images_to_history=True to keep the full image payload.

See docs/history_manager.md.

Configuration Options

agent = Agent(
    model="your-model-name",
    system_prompt="You are a helpful assistant.",
    parallel_tool_calls=False,
    generation_params={
        "temperature": 0.2,
        "max_tokens": 512,
    },
)

# Disable reasoning stream content (default is False)
runner = agent.runner()
async for event in runner.chat(history, reasoning=False):
    ...

Session Storage

from fury.sessions import JSONLStorage, SessionManager

session = await SessionManager.load_or_create(
    storage=JSONLStorage("./sessions"), id="my-chat",
)
async for event in session.stream(agent.runner(), "Hello!"):
    if event.content:
        print(event.content, end="", flush=True)

Storage is opt-in and independent of Agent and HistoryManager. Use custom async callbacks for database storage without adding database dependencies to Fury. See session storage for metadata, interruption handling, backend contracts, and a complete MongoDB example.

Persisting Transcripts

Fury separates UI stream events from model-visible transcript events. Persist event.history_delta.message to save the exact OpenAI-compatible messages Fury used for tool calls, tool results, multimodal follow-ups, and final assistant replies.

transcript = []

async for event in agent.runner().chat(history):
    if event.content:
        print(event.content, end="")
    if event.history_delta:
        transcript.append(event.history_delta.message)

save_messages(transcript)

For non-streaming collection:

result = await agent.runner().complete(history)
save_messages(result.transcript)
print(result.content)

Defining Tools

You can give your agent tools to interact with the world. Tools are Tool objects.

Input and output schemas help the model to correctly pass parameters through to the function. Fury will automatically prune any hallucinated parameters not defined in the input schema.

Learn more in the OpenAI guide

from fury import Agent, Tool


def add(a: int, b: int):
    return {"result": a + b}

# Create the tool
add_tool = Tool(
    name="add",
    description="Add two numbers together",
    execute=add,
    input_schema={
        "type": "object",
        "properties": {
            "a": {"type": "integer"},
            "b": {"type": "integer"},
        },
        "required": ["a", "b"],
    },
    output_schema={
        "type": "object",
        "properties": {"result": {"type": "integer"}},
        "required": ["result"],
    },
)

# Pass to agent
agent = Agent(..., tools=[add_tool])

If your tool accepts an emit parameter, Fury injects a runtime-only callback during execution so the tool can stream structured UI events during tool execution.

def search(query: str, emit):
    emit({"id": "search-1", "title": f"Searching for {query}", "type": "tool_call"})
    return {"query": query}

These arrive in the chat stream as event.tool_ui, separate from event.tool_call.

Coding Assistant Example

Check out examples/coding-assistant/coding_assistant.py for a full-featured example that includes:

  • Tools: File system operations (read, write, edit, bash).
  • Skills System: Loading specialized capabilities from SKILL.md files.
  • Markdown Memory Example: A simple editable markdown file injected into the system prompt.
  • History Manager: Uses HistoryManager to summarize long conversations and save context window.

Build something neat.

Release files for fury-sdk 0.3.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for fury-sdk 0.3.2
File Size Uploaded
fury_sdk-0.3.2.tar.gz 510.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for fury-sdk 0.3.2
File Interpreter ABI Platform
fury_sdk-0.3.2-py3-none-any.whl Python 3 none any Details

Total release size: 539.8 kB

Release files / fury_sdk-0.3.2.tar.gz

Download URL fury_sdk-0.3.2.tar.gz
Size 510.6 kB
Tags Source
SHA-256 checksum
How to use checksums
68ff2a33d9bd64f2971a958b76a65ea873afcb0afd1b729c2e74cadf0627ed7f
BLAKE2b-256 checksum
How to use checksums
49c4db14c3a3155140d10e684bab3da18772e3e424746c345416dc8da651adb5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.9.5

Release files / fury_sdk-0.3.2-py3-none-any.whl

Download URL fury_sdk-0.3.2-py3-none-any.whl
Size 29.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
75b2985ec38820d9bccdb1babfdd4b9a9c0e31bba8d608764188cd67d73239cc
BLAKE2b-256 checksum
How to use checksums
8f4c0190b16b36dac7d65e75e1a9db5f947062eade39094fab5c1ee3ff6b9645
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.9.5

Release history Release notifications | RSS feed

This release

0.3.2 This release

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.15

2 release files

0.1.13

2 release files

0.1.12

2 release files

0.1.11

2 release files

0.1.10

2 release files

0.1.9

2 release files

0.1.8

2 release files

0.1.7

2 release files

0.1.6

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

0.0.17

2 release files

0.0.16

2 release files

0.0.11

2 release files

0.0.10

2 release files

0.0.9

2 release files

0.0.8

2 release files

0.0.7

2 release files

0.0.6

2 release files

0.0.5

2 release files

0.0.4

2 release files

0.0.3

2 release files

0.0.2

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page