Skip to main content
Archived

This project has been archived by its maintainers, and is no longer receiving any updates.

fountain-agent-sdk

Give an agent a computer, your repositories, and your credentials in one call.

from fountain import Fountain

fountain = Fountain()
result = fountain.run(
    "Upgrade us to Phoenix 1.8 and open a PR",
    agent="reposage",
    vault="github-bot",
).result()

print(result.text)
print(result.url)

The agent runs on a real sandbox with the selected environment and vault. The sandbox remains after the turn, so a follow-up continues on the same computer and in the same agent session.

Install

pip install fountain-agent-sdk

Python 3.9 or newer. The SDK has no runtime dependencies.

Credentials

Fountain() resolves credentials the same way as the Fountain CLI:

api_key:  argument -> FOUNTAIN_API_KEY -> FOUNTAIN_TOKEN -> ~/.fountain/credentials
base_url: argument -> FOUNTAIN_BASE_URL -> ~/.fountain/credentials -> hosted Fountain

Use profile="work" to select another credentials-file profile. A client in a Fountain sandbox automatically uses its conversation-scoped token and marks the work it creates as child conversations.

Wait, stream, or fan out

run() starts work immediately in a background thread. Calling result() waits for the finished turn. Iterating the same handle streams its events.

run = fountain.run("Review this repository", agent="reviewer")

for event in run:
    if event["type"] == "tool":
        print("->", event["name"])
    elif event["type"] == "text":
        print(event["text"], end="", flush=True)

result = run.result()  # this is the same run; no second request is made

For only the answer text:

run = fountain.run("Review this repository", agent="reviewer")
for chunk in run.text_stream:
    print(chunk, end="", flush=True)

The same handle also works in asyncio code. HTTP still runs in the SDK's background thread, so it does not block the event loop.

result = await fountain.run("Review this repository", agent="reviewer")

run = fountain.run("Review another repository", agent="reviewer")
async for event in run:
    print(event)

Start several handles before collecting them to provision their sandboxes in parallel:

runs = [fountain.run(prompt, agent=agent) for agent in agents]
results = [run.result() for run in runs]

A failed agent turn is a RunResult with state == "failed". Rejected HTTP requests, transport failures, and SDK wait timeouts raise typed exceptions.

Follow-ups and permissions

first = fountain.run("Find every N+1 query", agent="reposage").result()
second = fountain.resume(first.conversation_id).send("Fix the worst three.").result()

An agent with an ask permission policy emits permission events. Answer with one of the option ids it offered:

run = fountain.run("Clean the build tree", agent="reposage")
for event in run:
    if event["type"] != "permission":
        continue
    request = event["request"]
    allow = next(option for option in request["options"] if option.get("kind") == "allow_once")
    run.answer(request["request_id"], allow["option_id"])

Resources and teammates

Resource definitions use the API's snake_case keys, so the same dictionary can also appear in a fountain.yml manifest or raw REST request.

environment = fountain.environments.create({
    "name": "fountain-ci",
    "packages": {"apt": ["ripgrep"]},
    "repositories": [{
        "url": "https://github.com/managoat/fountain",
        "mount_path": "/work/fountain",
    }],
})

vault = fountain.vaults.create({"name": "github-bot"})
fountain.vaults.secrets.set("github-bot", "GITHUB_TOKEN", token)

agent = fountain.agents.create({
    "name": "reposage",
    "runtime": "claude",
    "model": "anthropic/claude-sonnet-5",
    "environment_id": environment["id"],
    "allowed_vault_ids": [vault["id"]],
})

Agents, environments, and vaults each have list, get, create, update, and delete. Environments and vaults also have write-only secrets helpers.

fountain.team.add("watchtower", name="Watchtower")
reply = fountain.team.message("watchtower", "Any disks over 80%?").result()
fountain.team.schedules.create("watchtower", {
    "cron": "0 9 * * *",
    "prompt": "Check disk usage and say only what changed.",
})

Cancel a wait

run.cancel() stops the local wait and skips the final status request. The agent continues its work. A silent stream can delay cancellation by up to five seconds. Idle reads reconnect from the last complete event.

A custom HTTP transport must honor the supplied socket timeout.

Raw API and errors

Every endpoint remains available through the authenticated HTTP layer:

rows = fountain.request("GET", "/api/audit", query={"limit": 50})

Catch subclasses such as ConversationBusyError, NotReadyError, QuotaExceededError, ValidationError, and AuthError. Every FountainError carries status, code, body, retry_after, and a retryable property.

Develop

python3 -m unittest discover -s tests -v
python3 -m pip wheel . --no-deps

Metadata

Release files for fountain-agent-sdk 0.2.0

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

Source distribution (sdist)

Source distribution for fountain-agent-sdk 0.2.0
File Size Uploaded
fountain_agent_sdk-0.2.0.tar.gz 39.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for fountain-agent-sdk 0.2.0
File Interpreter ABI Platform
fountain_agent_sdk-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 72.1 kB

Release files / fountain_agent_sdk-0.2.0.tar.gz

Download URL fountain_agent_sdk-0.2.0.tar.gz
Size 39.8 kB
Tags Source
SHA-256 checksum
How to use checksums
3734b444ebea34da6ed4412caa583b1e153cf63f6a32573d3621fae484343586
BLAKE2b-256 checksum
How to use checksums
da1c86a3319a96ef9a5ac1c99ba3f48fca9a022a729bb3e34bd3070935121d6e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 12, 2026.

Transparency log

Release files / fountain_agent_sdk-0.2.0-py3-none-any.whl

Download URL fountain_agent_sdk-0.2.0-py3-none-any.whl
Size 32.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6773049f1e150c12c86e0022a4b9e8fa50cbafe1657d2122dbafebf2a52f326d
BLAKE2b-256 checksum
How to use checksums
0dc230f44c4c27cd186f67a0947a81a0e8e652cc588a86acb9d9c3d4ced899fc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 12, 2026.

Transparency log
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