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/BinaryBourbon/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
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file fountain_agent_sdk-0.1.1.tar.gz.
File metadata
- Download URL: fountain_agent_sdk-0.1.1.tar.gz
- Upload date:
- Size: 39.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
797ce66b8f75c8661f8f0562a5ed642522a7903767924f5f9d9cb4e08b5df446
|
|
| MD5 |
14c15c8f613e55245fc4ff88005bc4c4
|
|
| BLAKE2b-256 |
722c6e48088838b083d099a967a24adcf4b77c6c458c42a46748e179bc8a64fa
|
Provenance
The following attestation bundles were made for fountain_agent_sdk-0.1.1.tar.gz:
Publisher:
python-sdk-publish.yml on BinaryBourbon/fountain
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
fountain_agent_sdk-0.1.1.tar.gz -
Subject digest:
797ce66b8f75c8661f8f0562a5ed642522a7903767924f5f9d9cb4e08b5df446 - Sigstore transparency entry: 2733010909
- Sigstore integration time:
-
Permalink:
BinaryBourbon/fountain@073a589bbbd934e3729509719bda999ca3c98ebf -
Branch / Tag:
refs/heads/main - Owner: https://github.com/BinaryBourbon
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-sdk-publish.yml@073a589bbbd934e3729509719bda999ca3c98ebf -
Trigger Event:
push
-
Statement type:
File details
Details for the file fountain_agent_sdk-0.1.1-py3-none-any.whl.
File metadata
- Download URL: fountain_agent_sdk-0.1.1-py3-none-any.whl
- Upload date:
- Size: 32.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
691ebdb7f36e7f882a92f0343b24678179ee6d69e2b2d8f35e8de455e0fb9414
|
|
| MD5 |
7e9e903138278c9b7f296fb9da88535e
|
|
| BLAKE2b-256 |
d63a4502c02d92f623520fa8c043372857a1aed19532bf65cdff00ab3b83ae9b
|
Provenance
The following attestation bundles were made for fountain_agent_sdk-0.1.1-py3-none-any.whl:
Publisher:
python-sdk-publish.yml on BinaryBourbon/fountain
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
fountain_agent_sdk-0.1.1-py3-none-any.whl -
Subject digest:
691ebdb7f36e7f882a92f0343b24678179ee6d69e2b2d8f35e8de455e0fb9414 - Sigstore transparency entry: 2733010946
- Sigstore integration time:
-
Permalink:
BinaryBourbon/fountain@073a589bbbd934e3729509719bda999ca3c98ebf -
Branch / Tag:
refs/heads/main - Owner: https://github.com/BinaryBourbon
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-sdk-publish.yml@073a589bbbd934e3729509719bda999ca3c98ebf -
Trigger Event:
push
-
Statement type: