main
md 150 lines 4.53 KB
Rendered Raw
1 # Extensions
2
3 ## Source Anchors
4
5 - Extension base and discovery: `/a0/helpers/extension.py`
6 - Backend extension DOX: `/a0/extensions/AGENTS.md`, `/a0/extensions/python/AGENTS.md`
7 - WebUI extension DOX: `/a0/extensions/webui/AGENTS.md`
8 - Plugin extension contract: `/a0/plugins/AGENTS.md`
9 - Example profile note: `/a0/agents/_example/AGENTS.md`
10
11 ## Python Extension Contract
12
13 Backend extensions derive from `helpers.extension.Extension`:
14
15 ```python
16 from helpers.extension import Extension
17
18 class MyExtension(Extension):
19 async def execute(self, **kwargs):
20 ...
21 ```
22
23 `self.agent` may be `None` for startup or non-agent hooks. Match the arguments supplied by the hook point. Keep imports light because many extensions run in hot paths.
24
25 ## Python Discovery Layout
26
27 `helpers.extension._get_extension_classes(...)` discovers backend extension classes through:
28
29 ```text
30 extensions/python/<extension_point>/
31 ```
32
33 using `helpers.subagents.get_paths(agent, "extensions/python", extension_point)`.
34
35 Common locations:
36
37 | Location | Use |
38 |---|---|
39 | `extensions/python/<point>/` | Built-in framework extension. |
40 | `plugins/<plugin>/extensions/python/<point>/` | Bundled plugin extension. |
41 | `usr/plugins/<plugin>/extensions/python/<point>/` | User plugin extension. |
42 | `usr/extensions/python/<point>/` | Standalone user extension. Prefer plugin packaging for durable features. |
43 | Project/profile roots resolved by `helpers.subagents.get_paths(...)` | Scope-specific extension overrides when discovery supports the path. Verify before copying examples. |
44
45 The checked-in `_example` profile contains an older-looking `agents/_example/extensions/agent_init/...` sample. Current discovery code expects `extensions/python/<point>`. Treat source code and DOX as authority before copying profile extension layout.
46
47 ## Ordering And Overrides
48
49 - Files are sorted by filename. Numeric prefixes like `_10_`, `_20_`, `_50_` control order.
50 - Use gaps between prefixes so future extensions can fit between them.
51 - Discovery de-duplicates by module filename, preserving the first occurrence by search priority.
52 - Do not bypass secret masking, auth, persistence, or cleanup extensions for convenience.
53
54 ## Implicit `@extensible` Hooks
55
56 Functions decorated with `@extensible` emit two implicit hook points:
57
58 ```text
59 _functions/<module>/<qualname>/start
60 _functions/<module>/<qualname>/end
61 ```
62
63 The path preserves every module segment and nested qualname segment. Example:
64
65 ```text
66 helpers.something.Outer.Inner.__init__
67 ```
68
69 becomes:
70
71 ```text
72 _functions/helpers/something/Outer/Inner/__init__/start
73 _functions/helpers/something/Outer/Inner/__init__/end
74 ```
75
76 Extensions receive a mutable `data` dict with `args`, `kwargs`, `result`, and `exception`. They may mutate inputs, short-circuit by setting `result`, or force/clear an exception.
77
78 Do not use retired flattened `_functions` folder names.
79
80 ## Current Built-In Python Hook Directories
81
82 Directory-backed built-in hook points currently include:
83
84 ```text
85 agent_init
86 banners
87 before_main_llm_call
88 error_format
89 hist_add_before
90 hist_add_tool_result
91 job_loop
92 message_loop_end
93 message_loop_prompts_after
94 message_loop_prompts_before
95 message_loop_start
96 monologue_end
97 monologue_start
98 process_chain_end
99 reasoning_stream
100 reasoning_stream_chunk
101 reasoning_stream_end
102 response_stream
103 response_stream_chunk
104 response_stream_end
105 startup_migration
106 system_prompt
107 tool_execute_after
108 tool_execute_before
109 user_message_ui
110 util_model_call_before
111 webui_ws_connect
112 webui_ws_disconnect
113 webui_ws_event
114 ```
115
116 This list comes from the current `extensions/python/` tree. Re-check the tree before claiming the complete current set.
117
118 ## WebUI Extension Points
119
120 Frontend extension files live under:
121
122 ```text
123 extensions/webui/<point>/
124 plugins/<plugin>/extensions/webui/<point>/
125 usr/plugins/<plugin>/extensions/webui/<point>/
126 ```
127
128 Current built-in WebUI extension directories include:
129
130 ```text
131 fetch_api_call_after
132 fetch_api_call_before
133 get_message_handler
134 initFw_end
135 json_api_call_after
136 json_api_call_before
137 right-canvas-panels
138 right_canvas_register_surfaces
139 set_messages_after_loop
140 set_messages_before_loop
141 webui_ws_push
142 ```
143
144 Plugin frontend HTML extensions should include a root Alpine scope and use `x-move-*` directives when targeting static breakpoints. JS extensions export a default function.
145
146 ## Verification
147
148 - Run targeted lifecycle, prompt, stream, WebSocket, or WebUI extension tests for changed hook points.
149 - Smoke-test startup for `agent_init`, `startup_migration`, and `system_prompt` changes when practical.
150 - Check the exact directory path used by `helpers.extension` before adding profile or plugin extension files.