|
15 | 15 | - [Skills](#skills) |
16 | 16 | - [Apps](#apps) |
17 | 17 | - [Auth endpoints](#auth-endpoints) |
18 | | -- [Adding an experimental field](#adding-an-experimental-field) |
| 18 | +- [Experimental API Opt-in](#experimental-api-opt-in) |
19 | 19 |
|
20 | 20 | ## Protocol |
21 | 21 |
|
@@ -827,7 +827,67 @@ Field notes: |
827 | 827 | - `windowDurationMins` is the quota window length. |
828 | 828 | - `resetsAt` is a Unix timestamp (seconds) for the next reset. |
829 | 829 |
|
830 | | -## Adding an experimental field |
| 830 | +## Experimental API Opt-in |
| 831 | + |
| 832 | +Some app-server methods and fields are intentionally gated behind an experimental capability with no backwards-compatible guarantees. This lets clients choose between: |
| 833 | + |
| 834 | +- Stable surface only (default): no opt-in, no experimental methods/fields exposed. |
| 835 | +- Experimental surface: opt in during `initialize`. |
| 836 | + |
| 837 | +### Generating stable vs experimental client schemas |
| 838 | + |
| 839 | +`codex app-server` schema generation defaults to the stable API surface (experimental fields and methods filtered out). Pass `--experimental` to include experimental methods/fields in generated TypeScript or JSON schema: |
| 840 | + |
| 841 | +```bash |
| 842 | +# Stable-only output (default) |
| 843 | +codex app-server generate-ts --out DIR |
| 844 | +codex app-server generate-json-schema --out DIR |
| 845 | + |
| 846 | +# Include experimental API surface |
| 847 | +codex app-server generate-ts --out DIR --experimental |
| 848 | +codex app-server generate-json-schema --out DIR --experimental |
| 849 | +``` |
| 850 | + |
| 851 | +### How clients opt in at runtime |
| 852 | + |
| 853 | +Set `capabilities.experimentalApi` to `true` in your single `initialize` request: |
| 854 | + |
| 855 | +```json |
| 856 | +{ |
| 857 | + "method": "initialize", |
| 858 | + "id": 1, |
| 859 | + "params": { |
| 860 | + "clientInfo": { |
| 861 | + "name": "my_client", |
| 862 | + "title": "My Client", |
| 863 | + "version": "0.1.0" |
| 864 | + }, |
| 865 | + "capabilities": { |
| 866 | + "experimentalApi": true |
| 867 | + } |
| 868 | + } |
| 869 | +} |
| 870 | +``` |
| 871 | + |
| 872 | +Then send the standard `initialized` notification and proceed normally. |
| 873 | + |
| 874 | +Notes: |
| 875 | + |
| 876 | +- If `capabilities` is omitted, `experimentalApi` is treated as `false`. |
| 877 | +- This setting is negotiated once at initialization time for the process lifetime (re-initializing is rejected with `"Already initialized"`). |
| 878 | + |
| 879 | +### What happens without opt-in |
| 880 | + |
| 881 | +If a request uses an experimental method or sets an experimental field without opting in, app-server rejects it with a JSON-RPC error. The message is: |
| 882 | + |
| 883 | +`<descriptor> requires experimentalApi capability` |
| 884 | + |
| 885 | +Examples of descriptor strings: |
| 886 | + |
| 887 | +- `mock/experimentalMethod` (method-level gate) |
| 888 | +- `thread/start.mockExperimentalField` (field-level gate) |
| 889 | + |
| 890 | +### For maintainers: Adding experimental fields and methods |
831 | 891 | Use this checklist when introducing a field/method that should only be available when the client opts into experimental APIs. |
832 | 892 |
|
833 | 893 | At runtime, clients must send `initialize` with `capabilities.experimentalApi = true` to use experimental methods or fields. |
|
0 commit comments