tdfs4ds.agentops.deploy¶
tdfs4ds.agentops.deploy
¶
One call from a named feature store to a verified running agent.
The packaging layer stops at a zip. Everything after it — register, poll, deploy, poll, read the log, prove it answers — was hand-run REST calls, and each mistake cost a full build cycle to discover. Driving one real deployment produced, in order: a payload field the API rejects outright, a missing base image, an empty runtime_config that shipped a pod with no configuration at all, and a version that cannot be installed inside the image. Every one of those is checkable before or during the deploy.
Two principles shape the pipeline:
A failing stage stops it. Registering a definition whose preflight failed only creates litter in the registry, and the later failure then hides the earlier cause.
The feature store is stated, never inherited. database is required.
Model and Vector Store settings still come from the running session — you proved
those work by asking the agent questions — but which store the pod serves is a
deployment decision that must be visible at the call site.
_STAGES
module-attribute
¶
_STAGES = ('validate_target', 'preflight', 'publication', 'package', 'register', 'deploy', 'verify')
_UNPUBLISHED
module-attribute
¶
_UNPUBLISHED = 'tdfs4ds {version} is not available on PyPI, so the deployment cannot succeed.\n\nThe image build runs `pip install -r requirements.txt` inside the container,\nwhich pins this exact version. A local or editable install satisfies your\nnotebook but is invisible to the build, so the pod fails minutes later with a\npip resolution error rather than anything about your agent.\n\nResolve it one of these ways:\n * publish {version} to PyPI, then deploy again;\n * if a private index or mirror already carries it, re-run with\n require_published=False - PyPI is consulted as a default, not an authority;\n * deploy a version that is published.\n'
_SERVER_UP_MARKERS
module-attribute
¶
_SERVER_UP_MARKERS = ('starting fastapi with uvicorn', 'uvicorn running on', 'application startup complete')
AgentOpsClient
¶
Minimal client for the endpoints a deployment needs.
Parameters¶
base_url : str, optional
Defaults to TD_AGENTOPS_BASE_URL, then the in-cluster service URL.
token : str, optional
JWT bearer token. Defaults to TDFS4DS_AGENTOPS_TOKEN. In an AI
Studio notebook this is the user_token produced by %gen_token.
register_definition
¶
Upload the zip and register an agent definition. Returns its id.
wait_definition_published
¶
Poll until the definition leaves creating. Returns its status.
create_deployment
¶
POST the deployment payload. Returns the full response body.
The payload is sent verbatim; see the module docstring on
extra_forbidden.
wait_deployment_active
¶
Poll the deployment until it settles. Returns the last body.
Emits current_step transitions rather than every poll, so a long
build reads as building -> pushing -> deploying instead of forty
identical lines.
delete_agent
¶
DELETE /agents/{id}: removes the deployment (pod, route, service).
delete_definition
¶
DELETE /agent_definitions/{id}: removes the registry entry.
get_logs
¶
Pod logs. Never raises — a missing log must not mask the real error.
_StageBar
¶
A progress bar over the deployment stages, shown when no callable is given.
The waits inside a stage (definition publication, pod start, log) take minutes; their status lines go on the bar so it never looks stalled.
_short
¶
First line of text, truncated — errors are often multi-page.
Exceptions are flattened first, so a task-group wrapper never hides the
cause from the caller or from :func:_match_hint.
analyze_pod_log
¶
Return findings for a pod log.
Parameters¶
text : str
Raw log text, as returned by GET /agents/{id}/logs.
max_excerpt : int
Per-finding excerpt cap. The excerpt is the first matching line, which
for a stack trace is the one naming the cause rather than the innermost
frame.
Returns¶
list of dict
{"name", "severity", "insight", "excerpt"}, errors first then
warnings then info, in table order within each severity. Empty when
nothing matched — which is itself a finding the caller should report as
"no known signature", never as "healthy".
format_insights
¶
Render findings as aligned plain text. ASCII only.
A deployment report is read on whatever console the notebook happens to have, and is often saved to a file: the same reason the rest of tdfs4ds keeps generated artifacts ASCII.
started_successfully
¶
True when the log confirms startup and shows no error-severity finding.
_emit
¶
Report message: to the caller's callable, and to the log at level.
A failure is logged at ERROR so the console shows it in red; every line used to be INFO, a failed stage included, and read like the others (0.3.6.3).
deploy_to_agentops
¶
deploy_to_agentops(dest=None, *, database=None, databases_readonly=None, database_view=None, data_domain=None, token=None, base_url=None, auth='service', mcp=False, name=None, description=None, dry_run=False, timeout=1800, require_published=True, agent_runtime='auto', verify=True, startup_timeout=300, progress=None, pod_host='auto')
Package, deploy and verify the consumer agent on AgentOps.
Parameters¶
dest : str, optional
The scaffolded agent directory holding the platform's agent_runtime/.
Defaults to tdfs4ds.AGENTOPS_PACKAGE_DIR.
database : str
Required. The feature store the deployed agent serves. Stated rather
than inherited, so the pod's store is visible at the call site.
databases_readonly : list of str, optional
Stores attached read-only. Each is validated before deploying.
database_view, data_domain : str, optional
View database and default data domain for the deployed agent.
token : str, optional
JWT for the AgentOps API. In AI Studio, the user_token from
%gen_token.
auth : {'service', 'jwt'}
Credential model baked into the generated agent.
**Prefer ``'jwt'`` where the environment allows it** — and note the
reasoning is the opposite of the notebook case, where a token that
expires in two hours makes a ``.env`` stop working:
* the token arrives **per request** from the caller, so expiry
self-heals instead of accumulating;
* the pod connects **as the caller**, so database permissions and
audit reflect the real user rather than one shared account;
* no durable database password sits in ``runtime_config``, which is
rendered **in clear** in the deployment UI — verified against a live
deployment. Its guarantee is "not committed to source control", not
secrecy.
``'service'`` is nevertheless the default, because ``'jwt'`` is
**conditional on something outside tdfs4ds**: the platform's
``auth_context.token`` has to be accepted by *Vantage* as a JWT logon
(``logmech='JWT'``, ``logdata='token=...'``). A token minted for a
platform API is not automatically a database credential — this package
has watched the MCP gateway accept a platform bearer and the database
then refuse the logon it attempted with it (Error 8017). A pod cannot
mint a token of its own, so where the platform's token is not a valid
Vantage JWT, ``'jwt'`` is simply not deployable and ``'service'`` with
a real account is the way in.
Test it before deploying, from the notebook, with the token the pod
will be handed::
tdml.create_context(host=..., logmech='JWT',
logdata='token=' + os.environ['OAUTH_ACCESS_TOKEN'])
A session there means ``auth='jwt'`` is viable; a refusal means it is
not, whatever else is configured.
mcp : bool, default False
Enable MCP tools (Enterprise edition only). Off is the recommended first
deployment: it removes Enterprise auth and the 132-tool context budget
from the run, so a failure is unambiguously about the agent.
dry_run : bool, default False
Validate, preflight and build the zip, then stop and return the payload
without touching the API.
require_published : bool, default True
Refuse when the running version is not on PyPI. Set False when a private
index carries it.
verify : bool, default True
Run the smoke test once the deployment is active. False returns as
soon as it is deployed, leaving verification to a later
:func:~tdfs4ds.agentops.smoke.check_deployed_agent call on
report["agent_url"] — useful when the pod is slow to warm, or when
the caller holding a token is not the one running the deploy.
startup_timeout : int, default 300
Seconds to wait for the pod's tdfs4ds startup block to appear in the log
before drawing conclusions from it. active is the platform's verdict
on the pod, which it reaches before tdfs4ds has finished importing, so
reading the log immediately finds nothing on a healthy deployment. The
wait ends early as soon as the block appears or an error signature
does. Set 0 to read once and move on.
progress : callable, optional
Called with a status line per step. None (default) shows a progress
bar over the stages instead; either way every stage is logged, a failed
one at ERROR with its cause and fix.
pod_host : str, 'auto' or None, default 'auto'
The database host the pod connects to. 'auto': on AI Studio, where
a pod cannot resolve the database name the notebook uses, the name is
resolved here (as is, then with cop1..cop3) and the pod gets the
address; elsewhere the session's TDFS4DS_TD_HOST is used unchanged.
A string is used as given; None keeps the session's value. The
session itself is never changed.
Returns¶
dict
{"ok", "verified", "stages", "store", "agent_definition_id",
"agent_id", "agent_url", "insights", "smoke", "payload"}. Stages use
the same {name, status, detail, hint} shape as every other tdfs4ds
report.
``ok`` is the **deployment's** verdict: the pod is active and has a URL.
``verified`` is the **smoke test's** — ``True``/``False``, or ``None``
when it did not run. They are separate because a check that depends on
pod warmth failing does not mean the deployment failed, and reporting it
as one flag sent a user to debug a deployment that was fine.
Raises¶
ValueError
database not given.
RuntimeError
The running version is not published and require_published is set.
_wait_for_startup
¶
Poll the pod log until it confirms startup, or timeout seconds pass.
A pod reports active as soon as the platform's health check passes, which
is before tdfs4ds has finished its module-scope work - connect(), the
configuration check, the graph build. Reading the log immediately therefore
finds no startup block and says so, on a deployment that is fine.
Returns the insights from the last log read. Bounded and fail-open: a log that never confirms startup still returns whatever it did contain, because an unreadable log must never be what stops the report.
timeout falsy (0/None/False) skips the wait entirely - used when the pod
never became active, where there is nothing to wait for.
lazy (auth='jwt'): the agent connects on its first request, so its startup
block cannot appear before the verification sends one. The wait then ends as
soon as the platform's server is up (it installs the dependencies first,
about two minutes seen live), instead of running out the whole timeout.
_validate_target
¶
The named store is readable and documented, and read-only stores attach.
An undocumented store is refused: the consumer agent answers only from the business dictionary, so it would deploy an agent that cannot answer anything — a failure that looks like a broken model rather than an empty catalog.
_documented_object_count
¶
Rows in the store's business-dictionary objects view. 0 on any error.
_pod_td_host
¶
The host to give the pod, and a line saying what was done.
Returns (None, note) when the session's TDFS4DS_TD_HOST is kept.
_store_data_domains
¶
The store's data domains, largest first. [] on any error.
Read for the registry description only, so a failure costs a sentence of it, never the deploy.
_validate_readonly
¶
Reuse the federation attach probe rather than inventing another one.
_ro_descriptor accepts the same string-or-dict spec extend_read_stores
takes, and _validate_store already probes the catalog views for
SELECT-ability and column compatibility, logging a prescriptive reason.
_publication_gate
¶
The running version must be installable inside the image.