Skip to content

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.

FAILED module-attribute

FAILED = 'failed'

OK module-attribute

OK = 'ok'

SKIPPED module-attribute

SKIPPED = 'skipped'

logger module-attribute

logger = getLogger('tdfs4ds.agentops')

_STARTUP_POLL module-attribute

_STARTUP_POLL = 5

_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'

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.

base_url instance-attribute

base_url = rstrip('/')

timeout instance-attribute

timeout = timeout

__init__

__init__(base_url=None, token=None, timeout=60)

register_definition

register_definition(zip_path, name, description='', framework='LangGraph', tags=None)

Upload the zip and register an agent definition. Returns its id.

get_definition

get_definition(definition_id)

wait_definition_published

wait_definition_published(definition_id, timeout=600, interval=10, progress=None)

Poll until the definition leaves creating. Returns its status.

create_deployment

create_deployment(payload)

POST the deployment payload. Returns the full response body.

The payload is sent verbatim; see the module docstring on extra_forbidden.

get_agent

get_agent(agent_id)

wait_deployment_active

wait_deployment_active(agent_id, timeout=1800, interval=15, progress=None)

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.

get_logs

get_logs(agent_id, tail_lines=200)

Pod logs. Never raises — a missing log must not mask the real error.

_result

_result(name, label, status, detail='', hint=None, error=None, elapsed_s=None)

_short

_short(text, limit=_MAX_ECHO)

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

analyze_pod_log(text, *, max_excerpt=200)

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

format_insights(findings)

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

started_successfully(findings)

True when the log confirms startup and shows no error-severity finding.

_emit

_emit(progress, message)

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=120, 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 120 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. 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

_wait_for_startup(client, agent_id, timeout, progress=None)

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.

_validate_target

_validate_target(database=None, database_view=None, databases_readonly=None, data_domain=None)

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

_documented_object_count(view_db)

Rows in the store's business-dictionary objects view. 0 on any error.

_pod_td_host

_pod_td_host(pod_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

_store_data_domains(view_db)

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

_validate_readonly(store)

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

_publication_gate(require_published)

The running version must be installable inside the image.