Skip to content

release: 0.0.1-alpha.1 - #1

Closed
stainless-app[bot] wants to merge 4 commits into
mainfrom
release-please--branches--main--changes--next
Closed

stainless-app[bot] wants to merge 4 commits into
mainfrom
release-please--branches--main--changes--next

Conversation

@stainless-app

@stainless-app stainless-app Bot commented Jul 22, 2025

Copy link
Copy Markdown
Contributor

Automated Release PR

0.0.1-alpha.1 (2025-07-22)

Full Changelog: v0.0.1-alpha.0...v0.0.1-alpha.1

Chores


This pull request is managed by Stainless's GitHub App.

The semver version number is based on included commit messages. Alternatively, you can manually set the version number in the title of this pull request.

For a better experience, it is recommended to use either rebase-merge or squash-merge when merging this pull request.

🔗 Stainless website
📚 Read the docs
🙋 Reach out for help or questions

@stainless-app stainless-app Bot closed this Jul 22, 2025
@stainless-app
stainless-app Bot deleted the release-please--branches--main--changes--next branch July 22, 2025 01:15
stephen-wang24 added a commit that referenced this pull request Sep 15, 2026
Moves the pilot's per-agent sgp-obs wiring into the SDK, so an agent adopts
observability by installing sgp-obs and setting environment rather than carrying
the wiring code — including the parts that are easy to get wrong and fail
silently. AGX1-1113.

No `obs` extra, and that is deliberate. Declaring sgp-obs in
[project.optional-dependencies] makes THIS repo's uv workspace unresolvable,
because sgp-obs is not on public PyPI. Measured: `uv lock --check`,
`uv sync --all-extras`, plain `uv sync` with no extras, and
`uv sync --all-extras --no-extra obs` all fail — sync re-locks, locking must
resolve every declared optional dependency of every workspace member, and
`--no-extra` filters what is installed rather than what is resolved. `uv lock`
has no `--no-extra`, and `[tool.uv] override-dependencies` does not exempt it
either (tried with and without the extras in the override). Only `--frozen`
works, which would leave nobody able to re-lock this repo again. CI runs
`uv sync --all-packages --all-extras` in 5 places, so this would have gone red
on the first push. The dependency is therefore the agent's to declare, against
the curated mirror, and the SDK wires it when it is importable. adk/pyproject.toml
is now TOML-identical to the released one; only a comment was added, recording
why an extra must not be re-added here.

Verified against sgp-obs 0.16.0, not the 0.11.0 in the local scaleapi checkout —
that package was 23 files behind, and two of the changes matter here:

- `sgp_obs.shutdown()` is new in 0.16.0 and the draft never called anything like
  it. Whatever sits in a periodic exporter's buffer when the pod stops was being
  dropped, which for a short-lived or scaled-to-zero agent is most of what it
  recorded. Now flushed from the ACP lifespan's `finally`, in a thread because
  the flush blocks up to the export timeout. Feature-detected rather than
  version-pinned, since this package declares no dependency on sgp-obs and so
  cannot set a floor.
- The trace-context ingress no longer hides an active span. That was the
  span-reparenting hazard behind the old "keep traces off" advice.

All three signals, not metrics only. The double opt-in is the trap here, and it
is the opposite of what the 0.15.0-era notes say. Measured on 0.16.0 with a real
ACP server against a local OTLP receiver:

  SGP_OBS_ENABLED=true alone            -> []                         (nothing!)
  + METRICS=false TRACES=true LOGS=true -> ['metrics']
  + all three *_DISABLED=false          -> ['logs','metrics','traces']
  SGP_OBS_ENABLED=false                 -> []

Every signal needs its `*_DISABLED` set to an explicit `false`; unset leaves it
off. So the master switch on its own produces no telemetry and sgp-obs says
nothing about it. init_sgp_obs now warns, naming the three variables, and warns
separately when the switch is on but sgp-obs is not installed at all. Those two
warnings are the only new log output; absent-and-unasked-for stays silent,
because that is every agent that has not adopted.

What each signal actually delivers, decoded off the wire:

  metrics  4 http.server.* families over OTLP, resource service.name set and
           telemetry_sdk_name=opentelemetry. This is the app= handoff working.
  traces   spans over OTLP, but only business spans or a continued trace — the
           ingress middleware continues an inbound traceparent and never mints a
           server span. An agent with no span call sites exports zero, which is
           correct, not a defect. Confirmed by adding one correlated_span:
           1 record, name='agent.turn'.
  logs     structured JSON on STDOUT, not OTLP, carrying source=agentex and
           service.name. A collector scrapes stdout, so no endpoint is needed —
           but the pipeline REPLACES the root logger's handlers, so an adopting
           agent's log format changes.

Also passes `source="agentex"` (stamps agent_id and task_id onto every record;
the SDK knows the runtime, an agent author would have to know to pass it) and
offers AGENT_NAME as the service-name fallback, blank normalised to None so the
Helm rendered-empty idiom does not set an empty OTEL_SERVICE_NAME.

Two fixes to the draft while reviewing it:

1. [project.optional-dependencies] sat inside the [project] table, between
   requires-python and classifiers, so TOML reparented `classifiers` into it as
   an extra whose "requirements" were classifier strings. Fail-closed: hatchling
   refused to build with "Dependency #1 of option `classifiers` ... is invalid:
   Typing :: Typed". Moot now the extra is gone, but it would have broken the
   release build after the title edit and merge.
2. `_split_model`'s docstring claimed `"gpt-4o" -> ("openai", False)`. The code
   returns True and the code is right: a bare name is OpenAI, litellm reaches
   OpenAI through the openai client, so the client instrumentor already sees it
   and `call()` must stand down. Corrected the example, not the code.

Tests: 81 passing, `ruff check .` clean, `pyright -p .` 0 errors. They cover what
has to hold when sgp-obs is absent, which is every environment today —
`init_sgp_obs` returns not_installed AND the ACP server still constructs and
answers /healthz and /api (Nitesh's startup item) — plus the flush, the two
warnings, and the litellm recorder's null path, which is what every model call
goes through without sgp-obs, so a regression there breaks calls rather than
losing a metric. The fakes are stand-in modules, so the suite passes with sgp-obs
installed or absent.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants