Skip to content

feat(sdk): add shutdown() and ashutdown() lifecycle API#70

Merged
namrataghadi-galileo merged 3 commits into
mainfrom
abhi/sdk-lifecycle-shutdown
Mar 9, 2026
Merged

feat(sdk): add shutdown() and ashutdown() lifecycle API#70
namrataghadi-galileo merged 3 commits into
mainfrom
abhi/sdk-lifecycle-shutdown

Conversation

@abhinav-galileo
Copy link
Copy Markdown
Collaborator

@abhinav-galileo abhinav-galileo commented Mar 6, 2026

Summary

Adds agent_control.shutdown() (sync) and agent_control.ashutdown() (async) for deterministic SDK teardown.

  • Flushes all pending observability events
  • Stops the policy refresh background thread and prevents in-flight refreshes from publishing after shutdown
  • Resets global state
  • Idempotent and safe to call without prior init()

This gives users a single, documented shutdown path instead of relying on best-effort atexit behavior - which is fragile for short-lived scripts, CLI tools, and demos.

Implementation details

  • Extracted _fetch_controls_async() (fetch-only, no publish) so the refresh worker can check the stop event between fetch and publish, preventing zombie state writes after shutdown.
  • Added sync_shutdown_observability() as a public API in the observability module; shutdown() uses it instead of reaching into _batcher internals.
  • Extracted _reset_state() helper to deduplicate state clearing across both shutdown paths.

Shortcut: sc-57753

Test plan

  • make sdk-lint
  • make sdk-typecheck
  • make sdk-test (all passed, pre-existing integration failures only)
  • 10 new tests in test_shutdown.py covering sync/async paths, idempotency, no-init safety, and zombie refresh race regression
  • Updated test_policy_refresh_loop.py to match new _fetch_controls_async call path (14 tests pass)

@codecov
Copy link
Copy Markdown

codecov Bot commented Mar 6, 2026

Codecov Report

❌ Patch coverage is 93.42105% with 5 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
sdks/python/src/agent_control/__init__.py 92.95% 5 Missing ⚠️

📢 Thoughts on this report? Let us know!

…internals

- Split _fetch_controls_async() from refresh_controls_async() so the
  background worker can check stop_event after fetch, before publishing.
  This prevents an in-flight refresh from writing controls back into
  global state after shutdown() has logically completed.
- Add sync_shutdown_observability() as a public API in the observability
  module; shutdown() now uses it instead of reaching into _batcher.
- Extract _reset_state() helper to deduplicate state clearing in both
  shutdown() and ashutdown().
- Fix unused import (F401) and import ordering (I001) in test_shutdown.py.
- Update test_policy_refresh_loop.py to patch _fetch_controls_async.
- Add race regression tests for both sync and async shutdown paths.
Comment thread sdks/python/src/agent_control/__init__.py Outdated
Copy link
Copy Markdown
Contributor

@lan17 lan17 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The shutdown API is close, but there are still two lifecycle regressions in the refresh path that should be fixed before merge.

Comment thread sdks/python/src/agent_control/__init__.py
Comment thread sdks/python/src/agent_control/__init__.py Outdated
Copy link
Copy Markdown
Contributor

@lan17 lan17 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-reviewed the updated lifecycle changes. The prior refresh/shutdown concerns appear addressed, and the current SDK tests pass locally.

@namrataghadi-galileo namrataghadi-galileo merged commit 9e29d86 into main Mar 9, 2026
7 checks passed
@namrataghadi-galileo namrataghadi-galileo deleted the abhi/sdk-lifecycle-shutdown branch March 9, 2026 23:55
galileo-automation pushed a commit that referenced this pull request Mar 11, 2026
## [1.1.0](ts-sdk-v1.0.1...ts-sdk-v1.1.0) (2026-03-11)

### Features

* **examples:** add Google ADK Agent Control examples ([#69](#69)) ([4b83542](4b83542))
* **infra:** publish UI image and add compose UI service ([#57](#57)) ([207c1af](207c1af))
* **sdk:** 57143 strands extra ([#59](#59)) ([97f2518](97f2518))
* **sdk:** add shutdown() and ashutdown() lifecycle API ([#70](#70)) ([9e29d86](9e29d86))
* **sdk:** migrate strands integration to be a plugin ([#74](#74)) ([897ece3](897ece3))
* **server:** enforce admin-only control-plane mutations ([#62](#62)) ([579407f](579407f)), closes [#61](#61)
* **ui:** serve exported Agent Control UI from the FastAPI server ([#71](#71)) ([c140198](c140198))

### Bug Fixes

* **docs:** add centered logo, header, and badges to README ([#92](#92)) ([39c3cbf](39c3cbf))
* **docs:** Test all examples ([#16](#16)) ([39e95c2](39e95c2))
* **evaluators:** migrate sqlglot rs extra to sqlglot c ([#86](#86)) ([5e3e48c](5e3e48c))
* **infra:** fix docker compose to make ui work ([#82](#82)) ([5edbb6b](5edbb6b))
* **infra:** Remove UI service from docker-compose.yml ([#91](#91)) ([330ef55](330ef55))
* **sdk): Revert "fix(sdk:** bundle evaluators in sdk wheel" ([#90](#90)) ([b516ea6](b516ea6)), closes [#89](#89)
* **sdk:** bundle evaluators in sdk wheel ([#89](#89)) ([ea5889a](ea5889a))
* **sdk:** fix observability events not reaching the server ([#63](#63)) ([70016db](70016db))
* **ui:** name update being saved now ([#87](#87)) ([919672d](919672d))
* **ui:** Step name not getting saved ([#68](#68)) ([13abef9](13abef9))
@galileo-automation
Copy link
Copy Markdown
Collaborator

🎉 This PR is included in version 1.1.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

shyamsunderrai pushed a commit to shyamsunderrai/agent-control that referenced this pull request Apr 20, 2026
## 1.0.0 (2026-03-04)

### ⚠ BREAKING CHANGES

* **server:** Feature/56688 fix image bug (#48)
* **sdk:** a bug in docker file (#46)
* **server:** Feature/56688 fix docker and create bash (#45)
* **evaluators:** Evaluator reorganization with new package structure

Package Structure:
- agent-control-evaluators (v3.0.0): core + regex, list, json, sql
- agent-control-evaluator-galileo (v3.0.0): Luna2 evaluator

Key Changes:
- Entry points for evaluator discovery (agent_control.evaluators)
- Dot notation for external evaluators (galileo.luna2 not galileo/luna2)
- Dynamic __version__ via importlib.metadata
- Server uses evaluators as runtime dep (no longer vendored)
- Release workflow publishes both packages to PyPI

Bug Fixes:
- JSON evaluator: field_constraints/field_patterns in extra-fields allow-list
- SQL evaluator: LIMIT/OFFSET bypass fix

Migration:
- Import: agent_control_evaluator_galileo.luna2 (not agent_control_evaluators.galileo_luna2)
- DB: UPDATE controls SET evaluator.name replace('/', '.')
* **server:** add time-series stats and split API endpoints (#6)
* **evaluators:** rename plugin to evaluator throughout  (#81)
* **models:** simplify step model and schema (#70)

### Features

* Add plugin auto-discovery via Python entry points ([#49](agentcontrol/agent-control#49)) ([1521182](agentcontrol/agent-control@1521182))
* **docs:** add GitHub badges and CI coverage reporting ([#90](agentcontrol/agent-control#90)) ([be1fa14](agentcontrol/agent-control@be1fa14))
* **evaluators:** add required_column_values for multi-tenant SQL validation ([#30](agentcontrol/agent-control#30)) ([532386c](agentcontrol/agent-control@532386c))
* **sdk-ts:** automate semantic-release for npm publishing ([#52](agentcontrol/agent-control#52)) ([2b43958](agentcontrol/agent-control@2b43958))
* **sdk:** Add PyPI packaging with semantic release ([#52](agentcontrol/agent-control#52)) ([7c24f7f](agentcontrol/agent-control@7c24f7f))
* **sdk:** Auto-populate init() steps from [@control](https://github.com/control)() decorators ([#23](agentcontrol/agent-control#23)) ([dc0f2a4](agentcontrol/agent-control@dc0f2a4))
* **sdk:** export ControlScope, ControlMatch, and EvaluatorResult models ([#18](agentcontrol/agent-control#18)) ([0d49cad](agentcontrol/agent-control@0d49cad))
* **sdk:** Get Agent Controls from SDK Init ([#15](agentcontrol/agent-control#15)) ([a485f93](agentcontrol/agent-control@a485f93))
* **sdk:** Refresh controls in a background loop ([#43](agentcontrol/agent-control#43)) ([03f826d](agentcontrol/agent-control@03f826d))
* **sdk:** ship TypeScript SDK with deterministic method naming ([#32](agentcontrol/agent-control#32)) ([a76e9b0](agentcontrol/agent-control@a76e9b0))
* **server:** add evaluator config store ([#78](agentcontrol/agent-control#78)) ([cc14aa6](agentcontrol/agent-control@cc14aa6))
* **server:** add initAgent conflict_mode overwrite mode with SDK defaults ([#40](agentcontrol/agent-control#40)) ([f3ed2b8](agentcontrol/agent-control@f3ed2b8))
* **server:** Add observability system for control execution tracking ([#44](agentcontrol/agent-control#44)) ([fd0bddc](agentcontrol/agent-control@fd0bddc))
* **server:** add prometheus metrics for endpoints ([#68](agentcontrol/agent-control#68)) ([775612c](agentcontrol/agent-control@775612c))
* **server:** add time-series stats and split API endpoints ([#6](agentcontrol/agent-control#6)) ([a0fa597](agentcontrol/agent-control@a0fa597))
* **server:** hard-cut migrate to remove agent UUID ([#44](agentcontrol/agent-control#44)) ([ee322c9](agentcontrol/agent-control@ee322c9))
* **server:** Optional Policy and many to many relationships ([#41](agentcontrol/agent-control#41)) ([1a62746](agentcontrol/agent-control@1a62746))
* **ui:** add sql, luna2, json control forms and restructure the code ([#54](agentcontrol/agent-control#54)) ([c4c1d4a](agentcontrol/agent-control@c4c1d4a))
* **ui:** allow to delete control ([#39](agentcontrol/agent-control#39)) ([7dc4ca3](agentcontrol/agent-control@7dc4ca3))
* **ui:** Control Store Flow Updated ([#4](agentcontrol/agent-control#4)) ([dda9f70](agentcontrol/agent-control@dda9f70))
* **ui:** stats dashboard ([#80](agentcontrol/agent-control#80)) ([4cbb7fe](agentcontrol/agent-control@4cbb7fe))
* **ui:** Steps dropdown rendered based on api return values ([#36](agentcontrol/agent-control#36)) ([a2aca43](agentcontrol/agent-control@a2aca43))
* **ui:** tests added and some minor ui changes, added error boundaries ([#61](agentcontrol/agent-control#61)) ([009852b](agentcontrol/agent-control@009852b))
* **ui:** update agent control icon and favicon ([#42](agentcontrol/agent-control#42)) ([19af8fa](agentcontrol/agent-control@19af8fa))

### Bug Fixes

* **ci:** Add ui scope to PR title validation ([#59](agentcontrol/agent-control#59)) ([e0fdb52](agentcontrol/agent-control@e0fdb52))
* **ci:** correct galileo contrib path in release build script ([#51](agentcontrol/agent-control#51)) ([2de6013](agentcontrol/agent-control@2de6013))
* **ci:** Enable pr title on prs ([#56](agentcontrol/agent-control#56)) ([3d8b5fe](agentcontrol/agent-control@3d8b5fe))
* **ci:** Fix release ([#11](agentcontrol/agent-control#11)) ([9dd3dd7](agentcontrol/agent-control@9dd3dd7))
* **ci:** Use galileo-automation bot for releases ([#57](agentcontrol/agent-control#57)) ([bc8eea0](agentcontrol/agent-control@bc8eea0))
* **docs:** Add Example for Evaluator Extension ([#3](agentcontrol/agent-control#3)) ([c2a70b3](agentcontrol/agent-control@c2a70b3))
* **docs:** add setup script ([#49](agentcontrol/agent-control#49)) ([7a212c3](agentcontrol/agent-control@7a212c3))
* **docs:** Clean up Protect  ([#76](agentcontrol/agent-control#76)) ([99c16fd](agentcontrol/agent-control@99c16fd))
* **docs:** Fix Examples for LangGraph ([#64](agentcontrol/agent-control#64)) ([23b30ae](agentcontrol/agent-control@23b30ae))
* **docs:** Improve documentation for open source release ([#47](agentcontrol/agent-control#47)) ([9018fb3](agentcontrol/agent-control@9018fb3))
* **docs:** Remove old/unused examples ([#66](agentcontrol/agent-control#66)) ([f417781](agentcontrol/agent-control@f417781))
* **docs:** Update Contributing Guide ([#8](agentcontrol/agent-control#8)) ([10b34c8](agentcontrol/agent-control@10b34c8))
* **docs:** Update readme  ([#37](agentcontrol/agent-control#37)) ([7531d83](agentcontrol/agent-control@7531d83))
* **docs:** Update README ([#2](agentcontrol/agent-control#2)) ([379bb15](agentcontrol/agent-control@379bb15))
* **examples:** Control sets cleanup with signed ([#65](agentcontrol/agent-control#65)) ([af7b5fb](agentcontrol/agent-control@af7b5fb))
* **examples:** Update crew ai example to use evaluator ([#93](agentcontrol/agent-control#93)) ([1c65084](agentcontrol/agent-control@1c65084))
* **infra:** Add plugins directory to Dockerfile ([#58](agentcontrol/agent-control#58)) ([171d459](agentcontrol/agent-control@171d459))
* **infra:** install engine/evaluators in server image ([#14](agentcontrol/agent-control#14)) ([d5ae157](agentcontrol/agent-control@d5ae157))
* **models:** use StrEnum for error enums ([#12](agentcontrol/agent-control#12)) ([3f41c9f](agentcontrol/agent-control@3f41c9f))
* **sdk-ts:** add conventional commits preset dependency ([#55](agentcontrol/agent-control#55)) ([540fe9d](agentcontrol/agent-control@540fe9d))
* **sdk-ts:** export npm token for semantic-release npm auth ([#54](agentcontrol/agent-control#54)) ([1b6b993](agentcontrol/agent-control@1b6b993))
* **sdk:** 54253 add steer action and example ([#38](agentcontrol/agent-control#38)) ([bf2380a](agentcontrol/agent-control@bf2380a))
* **sdk:** a bug in docker file ([#46](agentcontrol/agent-control#46)) ([12d1794](agentcontrol/agent-control@12d1794))
* **sdk:** Add step_name as parameter to control ([#25](agentcontrol/agent-control#25)) ([19ade9d](agentcontrol/agent-control@19ade9d))
* **sdk:** emit observability events for SDK-evaluated controls and fix non_matches propagation ([#24](agentcontrol/agent-control#24)) ([6a9da69](agentcontrol/agent-control@6a9da69))
* **sdk:** enforce UUID agent IDs ([#9](agentcontrol/agent-control#9)) ([5ccdbd0](agentcontrol/agent-control@5ccdbd0))
* **sdk:** Fix logging  ([#77](agentcontrol/agent-control#77)) ([b1f078c](agentcontrol/agent-control@b1f078c))
* **sdk:** plugin to evaluator.. agent_protect to agent_control ([#88](agentcontrol/agent-control#88)) ([fc9b088](agentcontrol/agent-control@fc9b088))
* **server:** enforce public-safe API error responses ([#20](agentcontrol/agent-control#20)) ([e50d817](agentcontrol/agent-control@e50d817))
* **server:** Feature/56688 fix docker and create bash ([#45](agentcontrol/agent-control#45)) ([7277e27](agentcontrol/agent-control@7277e27))
* **server:** Feature/56688 fix image bug ([#48](agentcontrol/agent-control#48)) ([71e6b44](agentcontrol/agent-control@71e6b44))
* **server:** fix alembic migrations ([#47](agentcontrol/agent-control#47)) ([c19c17c](agentcontrol/agent-control@c19c17c))
* **server:** reject initAgent UUID/name mismatch ([#13](agentcontrol/agent-control#13)) ([19d61ff](agentcontrol/agent-control@19d61ff))
* tighten evaluation error handling and preserve control data ([52a1ef8](agentcontrol/agent-control@52a1ef8))
* **ui:** Fix UI and clients for simplified step schema ([#75](agentcontrol/agent-control#75)) ([be2aaf0](agentcontrol/agent-control@be2aaf0))
* **ui:** json validation ([#10](agentcontrol/agent-control#10)) ([a0cd5af](agentcontrol/agent-control@a0cd5af))
* **ui:** selector subpaths issue ([#34](agentcontrol/agent-control#34)) ([79cb776](agentcontrol/agent-control@79cb776))
* **ui:** UI feedback fixes ([#27](agentcontrol/agent-control#27)) ([6004761](agentcontrol/agent-control@6004761))

### Code Refactoring

* **evaluators:** rename plugin to evaluator throughout  ([#81](agentcontrol/agent-control#81)) ([0134682](agentcontrol/agent-control@0134682))
* **evaluators:** split into builtin + extra packages for PyPI ([#5](agentcontrol/agent-control#5)) ([0e0a78a](agentcontrol/agent-control@0e0a78a))
* **models:** simplify step model and schema ([#70](agentcontrol/agent-control#70)) ([4c1d637](agentcontrol/agent-control@4c1d637))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants