Agent Configurations
Overview
A profile is the definition of an agent: which capability packages it has, which tools it can call, which prompt files compose its system prompt, how much CPU and memory it runs on, which sub-agents it may delegate to, and its timeouts.
You author a Profile and pass it to a deployment. The deployed job's name is what you then pass to run_tasks_until_done and send_chat_message — identical in use to the built-in JobNames entries.
from edison_client import EdisonClient, JobDeploymentConfig
from edison_client.models.profile import BaseImageTier, Profile, Timeouts
client = EdisonClient()The Edison platform supports three different means of modifying agents:
1. Profile
Profile on JobDeploymentConfig
Deploy
Editing the profile and redeploying
2. Per-call overrides
RuntimeConfig, chat ttl_seconds / timeout
Every call
The call itself
3. Directives
ResolvedDirective
Next session start
A directive binding — no redeploy
You should modify the lowest layer that does the job. Directives are fastest and don't need a new deploy, profile changes with custom code often need a new build.
Deploying an agent
Deployment is the existing create_job path with one new field. profile takes the profile object, so nothing about the agent needs to pre-exist inside the image:
acme_profile = Profile(
base_image_tier=BaseImageTier.CHEM,
packages=["e14c-core", "e14c-client", "e14c-data-storage", "e14c-chemistry"],
auto_skills=["glyph-structure-recognition"],
memory="32Gi",
timeouts=Timeouts(job=2 * 60 * 60, code_cell=20 * 60),
)
config = JobDeploymentConfig(
name="acme-assay-analysis",
profile=acme_profile, # the object, not a name
environment_variables=ENV_VARS,
force=True,
)
client.create_job(config)Then drive it exactly like a built-in job:
container_config still wins over Profile.cpu / Profile.memory where the two overlap — it is infrastructure configuration rather than agent definition.
Everything else about deployment is unchanged: name is the job identity, force overwrites an existing deployment of the same name without prompting, and create_job returns the build metadata.
The Profile schema
base_image_tier
BaseImageTier
5-r
build
Container tier (see below)
packages
list[str]
Core packages
build
Capability packages installed into the code-execution environment. Will be parsed and built.
cpu
float | None
5
deploy
CPU request
memory
str | None
"16Gi"
deploy
Memory request
timeouts
Timeouts
see below
deploy
Job / cell / LLM budgets
subagent_jobs
SubagentJobs | None
None
deploy
Which sub-agents this agent may delegate to
subordinate_job
str | None
None
deploy
Job this agent may spawn subordinate chat sessions as
model_override
str | None
None
deploy
LLM for this profile; None uses the platform default. Expands to a fallback chain at runtime
tools
list[str]
run_cell, reset_kernel, submit_answer, read, explore, view_docs, load_skill
session
Tools registered for the agent. Must include run_cell and reset_kernel
prompt_files
list[str]
BASE_GENERIC.md, SUBAGENT_PRINCIPLES.md, + common
session
Markdown files composed into the system prompt, in order
workspace_prompt_files
list[str]
["MEMORY.md", "USER.md"]
session
Prompt files sourced from the workspace rather than the image
chat_prompt_files
list[str]
[]
session
Extra prompt files applied only in chat mode
auto_skills
list[str]
[]
session
Skills loaded without the agent asking for them
system_reminder
str | None
None
session
Markdown file re-injected periodically
system_reminder_interval
int
20
session
Steps between reminder injections
bootstrap_data_entry
str | None
None
session
Data storage entry seeded into the workspace at start
workspace_callbacks
list[str]
[]
session
Named workspace callbacks to run
orchestrator
bool
False
both
Delegates rather than executing directly
chat
bool
False
both
Multi-turn chat agent rather than one-shot
chat_reasoning_effort
str | None
None
session
Required when chat is True
unsafe_explore
bool
False
session
Allows reads and shell outside the workspace. Leave False unless the deployment is isolated
Changing base_image_tier or packages means the redeploy rebuilds an image, which can take up to an hour. Changing anything else reuses the cached image, so a prompt or timeout edit redeploys quickly. Either way it is a redeploy — see directives for changing a live agent's guidance without one.
BaseImageTier
Tiers are cumulative — each includes everything below it. Pick the lowest tier that covers your dependencies, since tier drives image size and cold-start time.
0-kernel-base
Python, system packages, base pip packages
1-data
Core scientific Python stack
2-bio
Bioinformatics tools
3-chem
Chemistry tooling (RDKit et al.)
4-mamba
Conda/Mamba environment packages
5-r
R language and bioconda tools
A package needing native libraries from a higher tier will not import. This is the most common cause of a profile that deploys cleanly and then fails on its first cell, so check your packages against the tier before deploying.
Timeouts
job
float
3600 (1h)
Whole-job budget in seconds
code_cell
float
900 (15m)
Per-cell execution budget
llm_call
float | None
None
Per-request LLM timeout; None leaves provider defaults
Chat agents want a larger job — 4 hours is the platform default for chat profiles — because the budget covers a whole turn including tool work. The agent receives a "wrap up" warning at a fraction of job, so raising the job budget widens that window automatically.
SubagentJobs
Which specialists the agent may delegate to. None for an entry means no access — the standard way to prevent an agent from recursing into itself.
analysis
analysis
Data analysis
analysis_gpu
analysis-gpu
GPU data analysis
molecules
molecules
Chemistry / small-molecule design
data_retrieval
data-retrieval
Dataset retrieval
literature
literature
Literature review
artifact_generation
artifact-generation
Long-form document authoring
Both spellings are accepted on input; the kebab-case aliases are the serialized format. Every value must be a job that is actually deployed and that you can reach — your own deployments are eligible, so an orchestrator can delegate to a worker you built.
Authoring profiles
Validation
Two things are checked when you construct a Profile, so you find out at author time rather than at first run:
toolscontainsrun_cellandreset_kernel.Unknown fields are rejected — no silently-ignored typos.
Variants
A profile is a plain pydantic model, so a variant is model_copy. This is how you get an A/B pair: same profile, one field changed, two job names.
model_copy(update=...) replaces list fields rather than merging them. To add one package, pass the full list:
Profiles also round-trip as JSON (Profile.model_validate(blob)), which is the form to use if you want to keep them under version control on your side or review them as config rather than code.
A worker profile, serialized
Layer 2 — per-call overrides
Redeploying is not the only way to change behavior. For a one-off, override at call time instead.
RuntimeConfig (tasks)
Passed as runtime_config on a TaskRequest. extra="forbid"; must be JSON serializable.
timeout
int | None
Maximum execution time in seconds
environment_config
dict[str, Any] | None
Kwargs for the environment constructor — see below
continued_job_id
UUID | None
Continue from a previous task
world_model_id
UUID | str | None
World model to attach
agent
AgentConfig | None
Agent config override
max_steps
int | None
Deprecated — use timeout
environment_config keys
Validated with extra="forbid", so a typo raises rather than being ignored.
data_storage_uris
list[str]
Data entries to download into the workspace (data_entry:<uuid>)
tool_names
list[str] | None
Replaces the profile's tools. Must still contain run_cell and reset_kernel
prompting_config
object
system_prompt here bypasses prompt_files entirely; also additional_system_prompt_guidelines, output_format_prompt
llm_config
object
Overrides the model and fallback chain from model_override
compaction_config
object
Context-compaction behavior
agent_name
str | None
Display-name override
text_only
bool
Strip images from tool responses, for text-only LLM backends
guidance_dag_overrides
dict
Register or replace guidance corpora
evaluate_config
dict | None
Evaluation harness settings
Chat session overrides
Chat has no runtime_config. Its two per-session knobs are arguments on send_chat_message, and they override the profile's timeouts for that session only:
ttl_seconds
60–86400
How long the sandbox survives idle
timeout
30–172800
How long one turn may run — the Timeouts.job equivalent
Layer 3 — directives
Directives change a deployed agent's behavior without any redeploy at all. A directive is guidance — a system-prompt fragment or a skill — bound to a profile and resolved on every session start.
Publishing will not activate the directive. A version exists and is reviewable before it can affect a single session, which is what makes it safe to draft policy in a shared account. Nothing takes effect until step 3.
1. Register the directive
create_directive establishes identity and never carries content.
key
str
Stable identifier for the directive
injection
"system_prompt" | "skill"
How the content reaches the agent — fixed at creation
organization_id
int | None
Owning organization. None is tenant-wide
injection is fixed here because it determines what a version may carry:
injection
Version carries
Reaches the agent as
system_prompt
body: str
Text appended to the system prompt
skill
dss_entry_id: UUID
A skill loaded from data storage
2. Publish a version
directive_id
UUID
Directive to publish under
name
str | None
Human label
description
str | None
Longer human label
body
str | None
The prompt fragment — system_prompt directives only
dss_entry_id
UUID | None
The skill entry — skill directives only
change_note
str | None
Why this version exists; shown in version history
directive_metadata
JsonValue | None
Free-form metadata
Versions are immutable and monotonic. Editing guidance means publishing a new version, so change_note is the audit trail for why an agent's behavior changed:
A skill directive publishes an entry id rather than text:
3. Bind it
bind_directive is what activates a version, and it pins that version explicitly.
directive_id
UUID
Directive to activate
version
int
The version to pin
profile_key
str | None
Profile to apply to. None is a wildcard — every profile
organization_id
int | None
Organization to apply to. None is a wildcard
user_id
str | None
Single user. None is a wildcard
order
int | None
Application order among directives on the same session
Bindings resolve across (profile_key, organization_id, user_id), where a null column is a wildcard and the most specific binding wins. That is how a tenant default and a per-org exception coexist:
Because a binding pins a version, publishing never changes a live agent. Rolling forward is a second bind_directive against the new version — the same explicitness as redeploying a profile, without the redeploy. Rolling back is a bind against the old version. unbind_directive(directive_id, ...) with the same scope arguments deactivates it and leaves the versions intact.
Verifying what an agent will see
resolve_directives answers with exactly what the resolver hands a session for a given profile — the check to run after binding, and the fastest way to debug a directive that appears to be doing nothing.
Each entry is a ResolvedDirective (edison_client.models.directive):
directive_id
UUID
Stable directive identity
key
str
Directive key
order
int
Application order
version_id / version
UUID / int
The pinned version that resolved
name / description
str | None
Human labels
directive_metadata
JsonValue | None
Free-form metadata
version_created_at
datetime
When this version was created
injection is the discriminator: body is set on system_prompt directives and dss_entry_id on skill directives, never both.
Two behaviors to expect. A directive missing from this list is almost always a binding-scope problem rather than a content problem — check profile_key against the profile you actually deployed. And resolution is deliberately soft-failing on the agent side: if the resolver is unreachable the session proceeds without directives rather than aborting, so a directive is guidance an agent normally has, not a guarantee it always has. Anything that must hold every run belongs in the profile's prompt_files. Errors surface as DirectiveResolveError when you call the resolver yourself.
Choosing between a directive and a profile edit
Add a skill or prompt fragment for one org
Directive — no redeploy, effective next session
Draft guidance now, activate it later
Directive — publish the version, bind when approved
Roll a guidance change back
Directive — bind the previous version
Guarantee guidance on every run
Profile prompt_files — directives soft-fail, prompt files do not
Change guidance for every user of the agent
Profile prompt_files / auto_skills — a redeploy, but no image rebuild
Add a capability package or change the image tier
Profile — a redeploy with an image rebuild
Try something once
environment_config on the call
Last updated
