agentenv-framework-protocol 0.1.369__tar.gz → 0.1.370__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. {agentenv_framework_protocol-0.1.369 → agentenv_framework_protocol-0.1.370}/PKG-INFO +46 -1
  2. {agentenv_framework_protocol-0.1.369 → agentenv_framework_protocol-0.1.370}/README.md +45 -0
  3. {agentenv_framework_protocol-0.1.369 → agentenv_framework_protocol-0.1.370}/pyproject.toml +1 -1
  4. {agentenv_framework_protocol-0.1.369 → agentenv_framework_protocol-0.1.370}/src/agentenv_protocol/a2a_agent/__init__.py +38 -0
  5. {agentenv_framework_protocol-0.1.369 → agentenv_framework_protocol-0.1.370}/src/agentenv_protocol/a2a_agent/extensions.py +147 -1
  6. agentenv_framework_protocol-0.1.370/src/agentenv_protocol/a2a_agent/proxy.py +516 -0
  7. agentenv_framework_protocol-0.1.370/tests/test_a2a_proxy.py +511 -0
  8. {agentenv_framework_protocol-0.1.369 → agentenv_framework_protocol-0.1.370}/.gitignore +0 -0
  9. {agentenv_framework_protocol-0.1.369 → agentenv_framework_protocol-0.1.370}/LICENSE +0 -0
  10. {agentenv_framework_protocol-0.1.369 → agentenv_framework_protocol-0.1.370}/NOTICE +0 -0
  11. {agentenv_framework_protocol-0.1.369 → agentenv_framework_protocol-0.1.370}/THIRD_PARTY_NOTICES.md +0 -0
  12. {agentenv_framework_protocol-0.1.369 → agentenv_framework_protocol-0.1.370}/examples/__init__.py +0 -0
  13. {agentenv_framework_protocol-0.1.369 → agentenv_framework_protocol-0.1.370}/examples/advanced_agent.py +0 -0
  14. {agentenv_framework_protocol-0.1.369 → agentenv_framework_protocol-0.1.370}/examples/basic_agent.py +0 -0
  15. {agentenv_framework_protocol-0.1.369 → agentenv_framework_protocol-0.1.370}/examples/custom_extensions_agent.py +0 -0
  16. {agentenv_framework_protocol-0.1.369 → agentenv_framework_protocol-0.1.370}/examples/multimodal_agent.py +0 -0
  17. {agentenv_framework_protocol-0.1.369 → agentenv_framework_protocol-0.1.370}/examples/reference_model.py +0 -0
  18. {agentenv_framework_protocol-0.1.369 → agentenv_framework_protocol-0.1.370}/examples/streaming_agent.py +0 -0
  19. {agentenv_framework_protocol-0.1.369 → agentenv_framework_protocol-0.1.370}/src/agentenv_protocol/__init__.py +0 -0
  20. {agentenv_framework_protocol-0.1.369 → agentenv_framework_protocol-0.1.370}/src/agentenv_protocol/a2a_agent/_trajectory_log.py +0 -0
  21. {agentenv_framework_protocol-0.1.369 → agentenv_framework_protocol-0.1.370}/src/agentenv_protocol/a2a_agent/_triggers.py +0 -0
  22. {agentenv_framework_protocol-0.1.369 → agentenv_framework_protocol-0.1.370}/src/agentenv_protocol/a2a_agent/framework.py +0 -0
  23. {agentenv_framework_protocol-0.1.369 → agentenv_framework_protocol-0.1.370}/src/agentenv_protocol/a2a_agent/peer_agents.py +0 -0
  24. {agentenv_framework_protocol-0.1.369 → agentenv_framework_protocol-0.1.370}/src/agentenv_protocol/a2a_agent/registry.py +0 -0
  25. {agentenv_framework_protocol-0.1.369 → agentenv_framework_protocol-0.1.370}/src/agentenv_protocol/a2a_agent/staging.py +0 -0
  26. {agentenv_framework_protocol-0.1.369 → agentenv_framework_protocol-0.1.370}/src/agentenv_protocol/a2a_agent/tasks/__init__.py +0 -0
  27. {agentenv_framework_protocol-0.1.369 → agentenv_framework_protocol-0.1.370}/src/agentenv_protocol/a2a_agent/tasks/v1.py +0 -0
  28. {agentenv_framework_protocol-0.1.369 → agentenv_framework_protocol-0.1.370}/src/agentenv_protocol/agent_env_environment.py +0 -0
  29. {agentenv_framework_protocol-0.1.369 → agentenv_framework_protocol-0.1.370}/src/agentenv_protocol/client.py +0 -0
  30. {agentenv_framework_protocol-0.1.369 → agentenv_framework_protocol-0.1.370}/src/agentenv_protocol/manifest.py +0 -0
  31. {agentenv_framework_protocol-0.1.369 → agentenv_framework_protocol-0.1.370}/src/agentenv_protocol/preflight.py +0 -0
  32. {agentenv_framework_protocol-0.1.369 → agentenv_framework_protocol-0.1.370}/src/agentenv_protocol/tool_client.py +0 -0
  33. {agentenv_framework_protocol-0.1.369 → agentenv_framework_protocol-0.1.370}/src/agentenv_protocol/tool_context.py +0 -0
  34. {agentenv_framework_protocol-0.1.369 → agentenv_framework_protocol-0.1.370}/src/agentenv_protocol/transfers.py +0 -0
  35. {agentenv_framework_protocol-0.1.369 → agentenv_framework_protocol-0.1.370}/src/agentenv_protocol/types.py +0 -0
  36. {agentenv_framework_protocol-0.1.369 → agentenv_framework_protocol-0.1.370}/tests/test_a2a_agent.py +0 -0
  37. {agentenv_framework_protocol-0.1.369 → agentenv_framework_protocol-0.1.370}/tests/test_a2a_agent_examples.py +0 -0
  38. {agentenv_framework_protocol-0.1.369 → agentenv_framework_protocol-0.1.370}/tests/test_a2a_object_transfers.py +0 -0
  39. {agentenv_framework_protocol-0.1.369 → agentenv_framework_protocol-0.1.370}/tests/test_a2a_peer_agents.py +0 -0
  40. {agentenv_framework_protocol-0.1.369 → agentenv_framework_protocol-0.1.370}/tests/test_a2a_staging.py +0 -0
  41. {agentenv_framework_protocol-0.1.369 → agentenv_framework_protocol-0.1.370}/tests/test_a2a_trajectory_log.py +0 -0
  42. {agentenv_framework_protocol-0.1.369 → agentenv_framework_protocol-0.1.370}/tests/test_agent_env_environment.py +0 -0
  43. {agentenv_framework_protocol-0.1.369 → agentenv_framework_protocol-0.1.370}/tests/test_client.py +0 -0
  44. {agentenv_framework_protocol-0.1.369 → agentenv_framework_protocol-0.1.370}/tests/test_data_objects.py +0 -0
  45. {agentenv_framework_protocol-0.1.369 → agentenv_framework_protocol-0.1.370}/tests/test_intake.py +0 -0
  46. {agentenv_framework_protocol-0.1.369 → agentenv_framework_protocol-0.1.370}/tests/test_manifest.py +0 -0
  47. {agentenv_framework_protocol-0.1.369 → agentenv_framework_protocol-0.1.370}/tests/test_preflight.py +0 -0
  48. {agentenv_framework_protocol-0.1.369 → agentenv_framework_protocol-0.1.370}/tests/test_tool_client.py +0 -0
  49. {agentenv_framework_protocol-0.1.369 → agentenv_framework_protocol-0.1.370}/tests/test_tool_context.py +0 -0
  50. {agentenv_framework_protocol-0.1.369 → agentenv_framework_protocol-0.1.370}/tests/test_tool_context_fastmcp.py +0 -0
  51. {agentenv_framework_protocol-0.1.369 → agentenv_framework_protocol-0.1.370}/tests/test_tool_context_injection.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: agentenv-framework-protocol
3
- Version: 0.1.369
3
+ Version: 0.1.370
4
4
  Summary: Open data-plane protocol and server SDK for agent environments.
5
5
  Project-URL: Homepage, https://www.agentenvframework.com
6
6
  Project-URL: Documentation, https://www.agentenvframework.com/docs
@@ -743,6 +743,51 @@ The answer is agent-wide rather than per caller, and like every extension route
743
743
  probe carries no access check of its own, so expose an agent only to the control plane
744
744
  that drives it.
745
745
 
746
+ `PROXY_V1` hands an agent's turns to a driver outside its sandbox, and `ProxyAgent`
747
+ (`agentenv_protocol.a2a_agent.proxy`) serves it. The proxy has no model: each message it
748
+ gets stays an open turn, its task working, until the driver replies, and every action the
749
+ driver's model takes runs in the proxy, where the agent would work. The driver's first
750
+ `POST /ext/proxy/claim` (`{"token"}`, at least 22 characters) sets the token every later
751
+ call carries in its body. A claim with another token gets 409, and any other call with a
752
+ wrong one 401. The token is held in memory only, never in the environment a command
753
+ inherits. Content travels as parts, `{"kind": "text", "text": ...}`; a message with any
754
+ other part fails as `proxy.unsupported_part` before the driver sees it. The other
755
+ operations:
756
+
757
+ - `next` (`{"token", "after"}`) waits up to 25 s for the turns' version to pass `after`,
758
+ then returns `{"version", "turns": [{"task_id", "context_id", "parts", "system_prompt",
759
+ "skills"}]}`. A turn its sender cancels drops out of the list.
760
+ - `tools` (`{"token", "task_id"}`) lists what the turn can call, with input schemas: the
761
+ tools of each env server registered through mcp-config, and `bash`. Two servers offering
762
+ one name are refused with 409.
763
+ - `act` (`{"token", "task_id", "action_id", "action"}`) runs one action: `{"kind": "tool",
764
+ "server", "name", "arguments"}` calls an env server through `ToolSession`, with the URL
765
+ and headers registered for it, and `{"kind": "bash", "command"}` runs `bash -c` in the
766
+ proxy's folder, as its user, in a process group of its own; either takes
767
+ `"timeout_seconds"` (3600 for `bash`, 600 for a tool by default). The driver picks
768
+ `action_id`, so a retried `act` returns the action it already started. It answers
769
+ `{"done", "result"}` at once when the action ends within the long-poll; `result`
770
+ (`{"token", "action_id"}`) long-polls one that doesn't. A `bash` result is
771
+ `{"exit_code", "stdout", "stderr", "timed_out"}`, a tool's `{"content", "is_error"}`.
772
+ - `record` (`{"token", "task_id", "message", "model", "usage"}`) records one model call: an
773
+ OpenAI chat message, an Anthropic message or a string; anything else gets 400. Once a turn
774
+ records a call, each action must be one the last recorded call made, by name and
775
+ arguments, and all of them must run before the next `record` or the `reply`, else 409.
776
+ Calls to tools the turn doesn't offer aren't checked.
777
+ - `reply` (`{"token", "task_id", "parts"}`, or `"error"` in place of `"parts"`) ends the
778
+ turn: parts complete the task, and an error fails it as `proxy.driver_error`.
779
+
780
+ A turn's actions belong to it: when it closes, by reply or withdrawal, those still running
781
+ are stopped, their whole process groups killed, and its results forgotten; the app's
782
+ lifespan stops what runs when it shuts down. The proxy writes the turn's trajectory as it
783
+ goes, readable live, as OTel GenAI spans in format `agentenv-proxy/v1`: `chat` for each
784
+ recorded call, `execute_tool` for each action, and `chain` for the turn. Skills it is given
785
+ are written to `~/skills/<name>/`, once each, and a turn names each one's folder.
786
+ `ProxyAgent(shell=False)` is a proxy for an agent that works in no sandbox: it offers no
787
+ `bash` and keeps no skills. It holds the env servers' headers as any agent does, so run it
788
+ with no credentials in its environment and expose it only to the control plane that drives
789
+ it.
790
+
746
791
  Runnable, self-contained reference agents live in [`examples/`](https://github.com/scaleapi/agentenv-framework/tree/main/packages/agentenv-protocol/examples):
747
792
  the normal, streaming, and multimodal `run(request)` paths, single- and
748
793
  multi-operation custom extensions, and advanced ASGI-lifespan plus
@@ -697,6 +697,51 @@ The answer is agent-wide rather than per caller, and like every extension route
697
697
  probe carries no access check of its own, so expose an agent only to the control plane
698
698
  that drives it.
699
699
 
700
+ `PROXY_V1` hands an agent's turns to a driver outside its sandbox, and `ProxyAgent`
701
+ (`agentenv_protocol.a2a_agent.proxy`) serves it. The proxy has no model: each message it
702
+ gets stays an open turn, its task working, until the driver replies, and every action the
703
+ driver's model takes runs in the proxy, where the agent would work. The driver's first
704
+ `POST /ext/proxy/claim` (`{"token"}`, at least 22 characters) sets the token every later
705
+ call carries in its body. A claim with another token gets 409, and any other call with a
706
+ wrong one 401. The token is held in memory only, never in the environment a command
707
+ inherits. Content travels as parts, `{"kind": "text", "text": ...}`; a message with any
708
+ other part fails as `proxy.unsupported_part` before the driver sees it. The other
709
+ operations:
710
+
711
+ - `next` (`{"token", "after"}`) waits up to 25 s for the turns' version to pass `after`,
712
+ then returns `{"version", "turns": [{"task_id", "context_id", "parts", "system_prompt",
713
+ "skills"}]}`. A turn its sender cancels drops out of the list.
714
+ - `tools` (`{"token", "task_id"}`) lists what the turn can call, with input schemas: the
715
+ tools of each env server registered through mcp-config, and `bash`. Two servers offering
716
+ one name are refused with 409.
717
+ - `act` (`{"token", "task_id", "action_id", "action"}`) runs one action: `{"kind": "tool",
718
+ "server", "name", "arguments"}` calls an env server through `ToolSession`, with the URL
719
+ and headers registered for it, and `{"kind": "bash", "command"}` runs `bash -c` in the
720
+ proxy's folder, as its user, in a process group of its own; either takes
721
+ `"timeout_seconds"` (3600 for `bash`, 600 for a tool by default). The driver picks
722
+ `action_id`, so a retried `act` returns the action it already started. It answers
723
+ `{"done", "result"}` at once when the action ends within the long-poll; `result`
724
+ (`{"token", "action_id"}`) long-polls one that doesn't. A `bash` result is
725
+ `{"exit_code", "stdout", "stderr", "timed_out"}`, a tool's `{"content", "is_error"}`.
726
+ - `record` (`{"token", "task_id", "message", "model", "usage"}`) records one model call: an
727
+ OpenAI chat message, an Anthropic message or a string; anything else gets 400. Once a turn
728
+ records a call, each action must be one the last recorded call made, by name and
729
+ arguments, and all of them must run before the next `record` or the `reply`, else 409.
730
+ Calls to tools the turn doesn't offer aren't checked.
731
+ - `reply` (`{"token", "task_id", "parts"}`, or `"error"` in place of `"parts"`) ends the
732
+ turn: parts complete the task, and an error fails it as `proxy.driver_error`.
733
+
734
+ A turn's actions belong to it: when it closes, by reply or withdrawal, those still running
735
+ are stopped, their whole process groups killed, and its results forgotten; the app's
736
+ lifespan stops what runs when it shuts down. The proxy writes the turn's trajectory as it
737
+ goes, readable live, as OTel GenAI spans in format `agentenv-proxy/v1`: `chat` for each
738
+ recorded call, `execute_tool` for each action, and `chain` for the turn. Skills it is given
739
+ are written to `~/skills/<name>/`, once each, and a turn names each one's folder.
740
+ `ProxyAgent(shell=False)` is a proxy for an agent that works in no sandbox: it offers no
741
+ `bash` and keeps no skills. It holds the env servers' headers as any agent does, so run it
742
+ with no credentials in its environment and expose it only to the control plane that drives
743
+ it.
744
+
700
745
  Runnable, self-contained reference agents live in [`examples/`](https://github.com/scaleapi/agentenv-framework/tree/main/packages/agentenv-protocol/examples):
701
746
  the normal, streaming, and multimodal `run(request)` paths, single- and
702
747
  multi-operation custom extensions, and advanced ASGI-lifespan plus
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "agentenv-framework-protocol"
3
- version = "0.1.369"
3
+ version = "0.1.370"
4
4
  description = "Open data-plane protocol and server SDK for agent environments."
5
5
  readme = "README.md"
6
6
  license = "Apache-2.0"
@@ -5,6 +5,7 @@ from a2a.types import AgentCapabilities
5
5
  from .extensions import (
6
6
  AGENT_CONFIG_V1,
7
7
  ATTRIBUTION_PROBE_V1,
8
+ PROXY_V1,
8
9
  INSTALL_V1,
9
10
  MCP_CONFIG_V1,
10
11
  PEER_AGENTS_V1,
@@ -19,6 +20,24 @@ from .extensions import (
19
20
  ContextEventsTrajectoryRequest,
20
21
  ContextObjectTrajectoryRequest,
21
22
  ContextTrajectoryRequest,
23
+ ProxyActRequest,
24
+ ProxyActionState,
25
+ ProxyBashAction,
26
+ ProxyBashResult,
27
+ ProxyClaimRequest,
28
+ ProxyNextRequest,
29
+ ProxyNextResponse,
30
+ ProxyRecordRequest,
31
+ ProxyReplyRequest,
32
+ ProxyResultRequest,
33
+ ProxySkill,
34
+ ProxyTextPart,
35
+ ProxyTool,
36
+ ProxyToolAction,
37
+ ProxyToolResult,
38
+ ProxyToolsRequest,
39
+ ProxyToolsResponse,
40
+ ProxyTurn,
22
41
  ExtensionActivation,
23
42
  ExtensionConfiguration,
24
43
  ExtensionDefinition,
@@ -117,6 +136,7 @@ from ..transfers import (
117
136
  __all__ = [
118
137
  "AGENT_CONFIG_V1",
119
138
  "ATTRIBUTION_PROBE_V1",
139
+ "PROXY_V1",
120
140
  "INSTALL_V1",
121
141
  "MCP_CONFIG_V1",
122
142
  "PEER_AGENTS_V1",
@@ -139,6 +159,24 @@ __all__ = [
139
159
  "ContextEventsTrajectoryRequest",
140
160
  "ContextObjectTrajectoryRequest",
141
161
  "ContextTrajectoryRequest",
162
+ "ProxyActRequest",
163
+ "ProxyActionState",
164
+ "ProxyBashAction",
165
+ "ProxyBashResult",
166
+ "ProxyClaimRequest",
167
+ "ProxyNextRequest",
168
+ "ProxyNextResponse",
169
+ "ProxyRecordRequest",
170
+ "ProxyReplyRequest",
171
+ "ProxyResultRequest",
172
+ "ProxySkill",
173
+ "ProxyTextPart",
174
+ "ProxyTool",
175
+ "ProxyToolAction",
176
+ "ProxyToolResult",
177
+ "ProxyToolsRequest",
178
+ "ProxyToolsResponse",
179
+ "ProxyTurn",
142
180
  "DataPart",
143
181
  "DefaultExtensionHandlers",
144
182
  "ExtensionActivation",
@@ -10,7 +10,7 @@ from collections.abc import Callable, Iterable, Mapping
10
10
  from dataclasses import dataclass, field
11
11
  from enum import Enum
12
12
  from types import MappingProxyType
13
- from typing import Annotated, Any
13
+ from typing import Annotated, Any, Literal
14
14
 
15
15
  from pydantic import (
16
16
  BaseModel,
@@ -287,6 +287,124 @@ class TriggerDecideRequest(ExtensionRequest):
287
287
  env_triggers: dict[str, dict[str, Any]] | None = None
288
288
 
289
289
 
290
+ PROXY_TOKEN_MIN_LENGTH = 22
291
+
292
+
293
+ class ProxyClaimRequest(ExtensionRequest):
294
+ token: str = Field(min_length=PROXY_TOKEN_MIN_LENGTH)
295
+
296
+
297
+ class ProxyNextRequest(ExtensionRequest):
298
+ token: str
299
+ after: int = Field(default=0, ge=0)
300
+
301
+
302
+ class ProxyTextPart(ExtensionRequest):
303
+ kind: Literal["text"] = "text"
304
+ text: str
305
+
306
+
307
+ class ProxySkill(ExtensionResponse):
308
+ name: str
309
+ description: str
310
+ path: str
311
+
312
+
313
+ class ProxyTurn(ExtensionResponse):
314
+ task_id: str
315
+ context_id: str
316
+ parts: list[ProxyTextPart]
317
+ system_prompt: str | None = None
318
+ skills: list[ProxySkill] = Field(default_factory=list)
319
+
320
+
321
+ class ProxyNextResponse(ExtensionResponse):
322
+ version: int
323
+ turns: list[ProxyTurn]
324
+
325
+
326
+ class ProxyToolsRequest(ExtensionRequest):
327
+ token: str
328
+ task_id: str
329
+
330
+
331
+ class ProxyTool(ExtensionResponse):
332
+ name: str
333
+ description: str | None = None
334
+ input_schema: dict[str, Any] | None = None
335
+ server: str | None = None # the env server that offers it; none for bash
336
+
337
+
338
+ class ProxyToolsResponse(ExtensionResponse):
339
+ tools: list[ProxyTool]
340
+
341
+
342
+ class ProxyToolAction(ExtensionRequest):
343
+ kind: Literal["tool"]
344
+ server: str
345
+ name: str
346
+ arguments: dict[str, Any] = Field(default_factory=dict)
347
+ timeout_seconds: float | None = Field(default=None, gt=0)
348
+
349
+
350
+ class ProxyBashAction(ExtensionRequest):
351
+ kind: Literal["bash"]
352
+ command: str
353
+ timeout_seconds: float | None = Field(default=None, gt=0)
354
+
355
+
356
+ class ProxyActRequest(ExtensionRequest):
357
+ token: str
358
+ task_id: str
359
+ action_id: str = Field(min_length=1, max_length=128)
360
+ action: Annotated[ProxyToolAction | ProxyBashAction, Field(discriminator="kind")]
361
+
362
+
363
+ class ProxyResultRequest(ExtensionRequest):
364
+ token: str
365
+ action_id: str
366
+
367
+
368
+ class ProxyBashResult(ExtensionResponse):
369
+ kind: Literal["bash"] = "bash"
370
+ exit_code: int | None # none when the command was stopped
371
+ stdout: str
372
+ stderr: str
373
+ timed_out: bool
374
+
375
+
376
+ class ProxyToolResult(ExtensionResponse):
377
+ kind: Literal["tool"] = "tool"
378
+ content: list[dict[str, Any]]
379
+ is_error: bool
380
+
381
+
382
+ class ProxyActionState(ExtensionResponse):
383
+ done: bool
384
+ result: Annotated[ProxyBashResult | ProxyToolResult, Field(discriminator="kind")] | None = None
385
+
386
+
387
+ class ProxyRecordRequest(ExtensionRequest):
388
+ token: str
389
+ task_id: str
390
+ message: str | dict[str, Any]
391
+ model: str | None = None
392
+ usage: dict[str, Any] | None = None
393
+
394
+
395
+ class ProxyReplyRequest(ExtensionRequest):
396
+ token: str
397
+ task_id: str
398
+ parts: list[ProxyTextPart] | None = Field(default=None, min_length=1)
399
+ error: str | None = None
400
+
401
+ @model_validator(mode="after")
402
+ def _parts_or_error(self) -> ProxyReplyRequest:
403
+ if (self.parts is None) == (self.error is None):
404
+ raise ValueError("a reply carries exactly one of parts and error")
405
+ return self
406
+
407
+
290
408
  def _tuple(values: Iterable[str]) -> tuple[str, ...]:
291
409
  return tuple(dict.fromkeys(values))
292
410
 
@@ -1167,6 +1285,33 @@ INSTALL_V1 = ExtensionDefinition(
1167
1285
  configuration_validator=_configure_install,
1168
1286
  )
1169
1287
 
1288
+ PROXY_V1 = ExtensionDefinition(
1289
+ uri="urn:agentenv:proxy/v1",
1290
+ description="Hand the agent's turns to a driver outside its sandbox, and run the driver's actions where the agent works.",
1291
+ endpoint="/ext/proxy",
1292
+ core_operations={
1293
+ "claim": _op("claim", "POST", "/ext/proxy/claim", RUNTIME, request_model=ProxyClaimRequest),
1294
+ "next": _op(
1295
+ "next", "POST", "/ext/proxy/next", RUNTIME,
1296
+ request_model=ProxyNextRequest, response_model=ProxyNextResponse,
1297
+ ),
1298
+ "tools": _op(
1299
+ "tools", "POST", "/ext/proxy/tools", RUNTIME,
1300
+ request_model=ProxyToolsRequest, response_model=ProxyToolsResponse,
1301
+ ),
1302
+ "act": _op(
1303
+ "act", "POST", "/ext/proxy/act", RUNTIME,
1304
+ request_model=ProxyActRequest, response_model=ProxyActionState,
1305
+ ),
1306
+ "result": _op(
1307
+ "result", "POST", "/ext/proxy/result", RUNTIME,
1308
+ request_model=ProxyResultRequest, response_model=ProxyActionState,
1309
+ ),
1310
+ "record": _op("record", "POST", "/ext/proxy/record", RUNTIME, request_model=ProxyRecordRequest),
1311
+ "reply": _op("reply", "POST", "/ext/proxy/reply", RUNTIME, request_model=ProxyReplyRequest),
1312
+ },
1313
+ )
1314
+
1170
1315
  STANDARD_EXTENSIONS: Mapping[str, ExtensionDefinition] = MappingProxyType(
1171
1316
  {
1172
1317
  extension.uri: extension
@@ -1180,6 +1325,7 @@ STANDARD_EXTENSIONS: Mapping[str, ExtensionDefinition] = MappingProxyType(
1180
1325
  ATTRIBUTION_PROBE_V1,
1181
1326
  TRIGGERS_V1,
1182
1327
  INSTALL_V1,
1328
+ PROXY_V1,
1183
1329
  )
1184
1330
  }
1185
1331
  )