[PR #356] feat: add webhook API #375

Open
opened 2026-10-29 14:22:45 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/kvcache-ai/AgentENV/pull/356
Author: @zlzGithub-0801
Created: 10/10/2026
Status: 🔄 Open

Base: main ← Head: feat/webhook-limit


📝 Commits (1)

📊 Changes

30 files changed (+2706 additions, -29 deletions)

View changed files

📝 Cargo.lock (+2 -0)
📝 docs/src/concepts/custom-extension/connect-and-use.md (+93 -0)
📝 docs/src/concepts/custom-extension/index.md (+1 -1)
📝 docs/src/concepts/custom-extension/lifecycle-hooks.md (+22 -3)
📝 src/api/generated/src/apis/mod.rs (+1 -0)
➕ src/api/generated/src/apis/webhooks.rs (+95 -0)
📝 src/api/generated/src/models.rs (+461 -0)
📝 src/api/generated/src/server/mod.rs (+487 -0)
📝 src/api/impls/mod.rs (+9 -0)
➕ src/api/impls/webhooks.rs (+231 -0)
📝 src/api/openapi.yml (+152 -0)
📝 src/api/server.rs (+1 -0)
📝 src/bin/server.rs (+8 -0)
📝 src/custom_extension_api/generated/Cargo.toml (+2 -0)
📝 src/custom_extension_api/generated/README.md (+3 -0)
📝 src/custom_extension_api/generated/docs/DefaultApi.md (+35 -0)
➕ src/custom_extension_api/generated/docs/SandboxEventData.md (+12 -0)
➕ src/custom_extension_api/generated/docs/SandboxEventHookRequest.md (+22 -0)
📝 src/custom_extension_api/generated/src/apis/default_api.rs (+63 -0)
📝 src/custom_extension_api/generated/src/models/mod.rs (+4 -0)

...and 10 more files

📄 Description

What

Adds an E2B-compatible lifecycle event webhook, backed by the custom extension:

  • GET /events/webhooks, GET/PATCH /events/webhooks/{webhookID}
  • A new extension hook, POST {url}/sandbox-hook/event, that receives sandbox
    lifecycle events (created, killed, paused, resumed, forked) as signed
    E2B v2 SandboxEvents while the webhook is enabled

Why

Webhooks are not implemented in AgentENV, so clients built on E2B's webhook API
cannot use it. This version reuses the custom extension: AgentENV forwards events
to the extension, and the extension decides how to fan them out.

#5

Scope and non-goals

  • Included: the 3 endpoints and the sandbox-hook/event extension hook.
  • Not included: creating and deleting webhooks, deliveries and stats,
    delivery retries, E2B's updated and checkpointed events (setting them
    returns 400), event_data.execution and kill_reason, the
    /events/sandboxes* query API, and multi-tenancy.
  • The existing custom extension hooks are unchanged.

Design and behavior changes

  1. Configuration is stored in the shared backend. There is exactly one
    webhook. Its settings (name, events, enabled, signatureSecret) are
    stored as webhooks/extension.json in the snapshot repository (POSIX or OSS).
    Its URL is not stored: it is always {url}/sandbox-hook/event from
    [custom_extension].url, and setting it returns 400. Nodes read the file on
    every event, so a change made on any node applies to the next event on every
    node.
  2. Webhooks listen to sandbox lifecycle events. They subscribe to the existing
    orchestrator lifecycle broadcast and support created, killed, paused,
    resumed, and forked. forked is an AgentENV extension and carries
    source_sandbox_id. Each node delivers only events for its own sandboxes.
  3. Events are forwarded to the extension once each. Delivery is asynchronous
    and best-effort: one attempt per event, failures are only logged, and the
    sandbox operation is never blocked or failed. Requests are signed only when a
    signatureSecret is set. No delivery history is kept.

Compatibility and operations

  • Public API or generated protocol: Additive. 3 endpoints under a new
    webhooks tag, with E2B schemas. The extension API gains the optional
    sandbox-hook/event hook. The scheduler proto is unchanged.
  • Configuration or defaults: No new config. The webhook exists only while
    [custom_extension].url is set, and it is disabled until enabled through PATCH.
  • Snapshot manifest, artifact layout, or storage format: Repositories gain
    webhooks/extension.json.
  • Upgrade and rollback: N/A
  • Host requirements, permissions, ports, or dependencies: N/A

Validation

  • make fmt
  • make clippy
  • make test-unit
  • Relevant Rust integration tests
  • Generated clients/server regenerated with the documented make target
    (make agentenv-server, make custom-extension-client)
  • Documentation updated (docs/src/concepts/custom-extension/)
  • Benchmarks or performance comparison completed

Risks and reviewer notes

  • signatureSecret is stored in plaintext in the repository.
  • Delivery is best-effort. Events are lost on restart, broadcast lag, or an
    unavailable extension.

Checklist

  • The PR contains one coherent change and no unrelated formatting or refactoring.
  • New behavior is covered by tests, or I explained why testing is impractical.
  • Logs and examples contain no credentials, tokens, or private registry information.
  • I did not manually edit generated code without updating its source and regenerating it.

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/kvcache-ai/AgentENV/pull/356 **Author:** [@zlzGithub-0801](https://github.com/zlzGithub-0801) **Created:** 10/10/2026 **Status:** 🔄 Open **Base:** `main` ← **Head:** `feat/webhook-limit` --- ### 📝 Commits (1) - [`042d0e3`](https://github.com/kvcache-ai/AgentENV/commit/042d0e32eaf77a6f00c8fb74b094ef8f1051be3d) feat: add webhook API ### 📊 Changes **30 files changed** (+2706 additions, -29 deletions) <details> <summary>View changed files</summary> 📝 `Cargo.lock` (+2 -0) 📝 `docs/src/concepts/custom-extension/connect-and-use.md` (+93 -0) 📝 `docs/src/concepts/custom-extension/index.md` (+1 -1) 📝 `docs/src/concepts/custom-extension/lifecycle-hooks.md` (+22 -3) 📝 `src/api/generated/src/apis/mod.rs` (+1 -0) ➕ `src/api/generated/src/apis/webhooks.rs` (+95 -0) 📝 `src/api/generated/src/models.rs` (+461 -0) 📝 `src/api/generated/src/server/mod.rs` (+487 -0) 📝 `src/api/impls/mod.rs` (+9 -0) ➕ `src/api/impls/webhooks.rs` (+231 -0) 📝 `src/api/openapi.yml` (+152 -0) 📝 `src/api/server.rs` (+1 -0) 📝 `src/bin/server.rs` (+8 -0) 📝 `src/custom_extension_api/generated/Cargo.toml` (+2 -0) 📝 `src/custom_extension_api/generated/README.md` (+3 -0) 📝 `src/custom_extension_api/generated/docs/DefaultApi.md` (+35 -0) ➕ `src/custom_extension_api/generated/docs/SandboxEventData.md` (+12 -0) ➕ `src/custom_extension_api/generated/docs/SandboxEventHookRequest.md` (+22 -0) 📝 `src/custom_extension_api/generated/src/apis/default_api.rs` (+63 -0) 📝 `src/custom_extension_api/generated/src/models/mod.rs` (+4 -0) _...and 10 more files_ </details> ### 📄 Description ## What Adds an E2B-compatible lifecycle event webhook, backed by the custom extension: - `GET /events/webhooks`, `GET/PATCH /events/webhooks/{webhookID}` - A new extension hook, `POST {url}/sandbox-hook/event`, that receives sandbox lifecycle events (`created`, `killed`, `paused`, `resumed`, `forked`) as signed E2B v2 `SandboxEvent`s while the webhook is enabled ## Why Webhooks are not implemented in AgentENV, so clients built on E2B's webhook API cannot use it. This version reuses the custom extension: AgentENV forwards events to the extension, and the extension decides how to fan them out. ## Related issue #5 ## Scope and non-goals - Included: the 3 endpoints and the `sandbox-hook/event` extension hook. - Not included: creating and deleting webhooks, `deliveries` and `stats`, delivery retries, E2B's `updated` and `checkpointed` events (setting them returns `400`), `event_data.execution` and `kill_reason`, the `/events/sandboxes*` query API, and multi-tenancy. - The existing custom extension hooks are unchanged. ## Design and behavior changes 1. **Configuration is stored in the shared backend.** There is exactly one webhook. Its settings (`name`, `events`, `enabled`, `signatureSecret`) are stored as `webhooks/extension.json` in the snapshot repository (POSIX or OSS). Its URL is not stored: it is always `{url}/sandbox-hook/event` from `[custom_extension].url`, and setting it returns `400`. Nodes read the file on every event, so a change made on any node applies to the next event on every node. 2. **Webhooks listen to sandbox lifecycle events.** They subscribe to the existing orchestrator lifecycle broadcast and support `created`, `killed`, `paused`, `resumed`, and `forked`. `forked` is an AgentENV extension and carries `source_sandbox_id`. Each node delivers only events for its own sandboxes. 3. **Events are forwarded to the extension once each.** Delivery is asynchronous and best-effort: one attempt per event, failures are only logged, and the sandbox operation is never blocked or failed. Requests are signed only when a `signatureSecret` is set. No delivery history is kept. ## Compatibility and operations - **Public API or generated protocol:** Additive. 3 endpoints under a new `webhooks` tag, with E2B schemas. The extension API gains the optional `sandbox-hook/event` hook. The scheduler proto is unchanged. - **Configuration or defaults:** No new config. The webhook exists only while `[custom_extension].url` is set, and it is disabled until enabled through PATCH. - **Snapshot manifest, artifact layout, or storage format:** Repositories gain `webhooks/extension.json`. - **Upgrade and rollback:** N/A - **Host requirements, permissions, ports, or dependencies:** N/A ## Validation - [x] `make fmt` - [x] `make clippy` - [x] `make test-unit` - [x] Relevant Rust integration tests - [x] Generated clients/server regenerated with the documented `make` target (`make agentenv-server`, `make custom-extension-client`) - [x] Documentation updated (`docs/src/concepts/custom-extension/`) - [ ] Benchmarks or performance comparison completed ## Risks and reviewer notes - `signatureSecret` is stored in plaintext in the repository. - Delivery is best-effort. Events are lost on restart, broadcast lag, or an unavailable extension. ## Checklist - [x] The PR contains one coherent change and no unrelated formatting or refactoring. - [x] New behavior is covered by tests, or I explained why testing is impractical. - [x] Logs and examples contain no credentials, tokens, or private registry information. - [x] I did not manually edit generated code without updating its source and regenerating it. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
kvcache-ai/AgentENV#375
No description provided.