Skip to content

Commit a84f3ea

Browse files
os-litantclaude
andauthored
fix(spec): render a nested item shape as a table so its describe text reaches the reference page (#12309)
* fix(spec): render a nested item shape as a table so its describe text reaches the reference page `build-docs.ts` collapsed an inline object property into a one-line signature cell that has no description column, so every `.describe()` on a key of that shape was unreachable from the page. Measured: 1208 property rows across 566 published schemas carry 7502 described nested keys (~473 KB of prose) that reached no page, and adding such a describe produced a zero-line `gen:docs` diff. `nestedShapeOf` (beside `renderType`, so the two agree about what one shape level is) names the single shape a cell opens and the TypeScript indexed accessor that selects it. `renderSchemaSection` renders it as a `### Nested Shape:` table directly under the Properties table, in the position and grammar `### Allowed Values:` has used since #6225. Bounded: one level; only where a key carries describe text; never for a union of two or more object shapes; and a nested table elides vocabularies instead of relocating them. Regenerated output is purely additive. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NDGG54XF5gbTLdQzCtnaVV * chore(spec): regenerate content/docs/references from the merged tree Discharges the os-regen deferral recorded by the merge commit. `main` gained `SearchAllResponseSchema` / `SearchAllHitSchema` / `CloneDataResponseSchema` (#12203) while this branch was open, so the pages this branch regenerated at its fork point described a source the merged tree no longer has — which is what `check:docs` reported on the merge ref. Regenerated with `gen:schema && gen:docs` from the merged tree, never by hand. `api/protocol.mdx` gains the three new schema sections plus one nested-shape table this branch's renderer produces for the new array-of-object property, `SearchAllResponse.hits[number]`. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NDGG54XF5gbTLdQzCtnaVV --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 1f6b8bb commit a84f3ea

147 files changed

Lines changed: 14858 additions & 122 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
---
2+
"@objectstack/spec": patch
3+
---
4+
5+
fix(spec): reference pages carry a nested item shape's `.describe()` text instead of collapsing it into a signature cell (#11601)
6+
7+
`build-docs.ts` renders a property whose type is an inline object as a
8+
one-line signature — `{ label: string; icon?: string; visibleWhen?: string |
9+
object; value?: string; … }[]` — into a table cell that has **no description
10+
column**. Every `.describe()` an author wrote on a key of that shape was
11+
therefore unreachable from the reference page: not truncated, not marked,
12+
absent. `page:tabs`'s item-level `visibleWhen` carries a ~600-character
13+
contract note whose whole point is that its evaluation environment is **not**
14+
the page-component `visibleWhen` of the same name, and
15+
`content/docs/references/ui/component.mdx` rendered that row with an empty
16+
Description cell.
17+
18+
The loss was invisible from both sides. `check:docs` compares generated output
19+
with committed output, so it is green forever on prose neither side contains —
20+
measured on the tree before this change, adding a `.describe()` to a nested
21+
item key produced a **zero-line** `gen:docs` diff.
22+
23+
**The population, measured on the emitted tree.** 1293 property rows across
24+
566 published schemas and 13 of 14 categories open a nested shape; 1208 of them
25+
have at least one key carrying describe text, 7502 described keys in total,
26+
~473 KB of authored prose that reached no page.
27+
28+
**What is rendered now.** A property that opens exactly one shape, and whose
29+
shape has at least one described key, gets a `### Nested Shape:` table directly
30+
under the Properties table — the same position, addressing and heading level
31+
the `### Allowed Values:` relocation has used since #6225, so the page gains no
32+
second grammar. The heading names the shape with a TypeScript indexed accessor
33+
(`PageTabsProps.items[number]`, `Object.fields[string]`), which is a real
34+
spelling rather than a sigil invented for the docs.
35+
36+
Four bounds, each measured rather than chosen:
37+
38+
- **One level**, matching the `SHAPE_DEPTH_LIMIT` budget a cell already spends.
39+
A nested table opens no table of its own.
40+
- **Only where there is text to publish.** A shape whose keys carry no
41+
describe text keeps its cell; a table there would restate the cell in more
42+
space.
43+
- **A union of two or more object shapes keeps its cell.** There is no single
44+
"the shape of this property" to name — the same reason `formatPropertyType`
45+
refuses to relocate a vocabulary out of `Enum<…>[]`.
46+
- **A nested table does not relocate vocabularies.** It is a second position
47+
for those keys, so it elides them the way a `{ … }` summary does. Without
48+
this rule the 288-member `ApiError.code` vocabulary was re-listed under every
49+
nested `error` shape — 20,260 bullet lines across the tree, `api/metadata.mdx`
50+
alone +6097.
51+
52+
Tombstoned keys are rendered in a nested table, unlike in the cell above it:
53+
`retiredKey()` puts the whole `[REMOVED]` migration prescription in
54+
`description`, and a signature has no column to carry it.
55+
56+
The regenerated tree is **purely additive** — 143 files, +14195 / -118 lines,
57+
and every one of the 38177 pre-existing lines is still present byte for byte
58+
(the 118 are re-ordering around the inserted sections, not removal).

content/docs/references/ai/agent.mdx

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,68 @@ const result = AIModelConfigSchema.parse(data);
7171
| **_packageVersion** | `string` | optional | Owning package version. |
7272
| **_lockDocsUrl** | `string` | optional | Optional documentation link surfaced next to _lockReason. |
7373

74+
### Nested Shape: `Agent.model`
75+
76+
| Property | Type | Required | Description |
77+
| :--- | :--- | :--- | :--- |
78+
| **provider** | `Enum<'openai' \| 'azure_openai' \| 'anthropic' \| 'local'>` | optional (default: `"openai"`) | |
79+
| **model** | `string` || Model name (e.g. gpt-4, claude-3-opus) |
80+
| **temperature** | `number` | optional (default: `0.7`) | |
81+
| **maxTokens** | `number` | optional | |
82+
| **topP** | `number` | optional | |
83+
84+
### Nested Shape: `Agent.lifecycle`
85+
86+
| Property | Type | Required | Description |
87+
| :--- | :--- | :--- | :--- |
88+
| **id** | `string` || Unique Machine ID |
89+
| **description** | `string` | optional | |
90+
| **contextSchema** | `Record<string, any>` | optional | Zod Schema for the machine context/memory |
91+
| **initial** | `string` || Initial State ID |
92+
| **states** | `Record<string, { type: Enum<'atomic' \| 'compound' \| 'parallel' \| 'final' \| 'history'>; entry?: (string \| object)[]; exit?: (string \| object)[]; on?: Record<string, string \| object \| object[]>; … }>` || State Nodes |
93+
| **on** | `Record<string, string \| { target?: string; cond?: string \| object; actions?: (string \| object)[]; description?: string } \| { target?: string; cond?: string \| object; actions?: (string \| object)[]; description?: string }[]>` | optional | |
94+
95+
### Nested Shape: `Agent.planning`
96+
97+
| Property | Type | Required | Description |
98+
| :--- | :--- | :--- | :--- |
99+
| **maxIterations** | `integer` | optional (default: `10`) | Maximum planning loop iterations |
100+
101+
### Nested Shape: `Agent.memory`
102+
103+
| Property | Type | Required | Description |
104+
| :--- | :--- | :--- | :--- |
105+
| **longTerm** | `{ enabled: boolean; store: Enum<'vector' \| 'database' \| 'redis'>; maxEntries?: integer }` | optional | Long-term / persistent memory |
106+
| **reflectionInterval** | `integer` | optional | Reflect every N interactions to improve behavior |
107+
108+
### Nested Shape: `Agent.guardrails`
109+
110+
| Property | Type | Required | Description |
111+
| :--- | :--- | :--- | :--- |
112+
| **maxTokensPerInvocation** | `integer` | optional | Token budget per single invocation |
113+
| **maxExecutionTimeSec** | `integer` | optional | Max execution time in seconds |
114+
| **blockedTopics** | `string[]` | optional | Forbidden topics or action names |
115+
116+
### Nested Shape: `Agent.structuredOutput`
117+
118+
| Property | Type | Required | Description |
119+
| :--- | :--- | :--- | :--- |
120+
| **format** | `Enum<'json_object' \| 'json_schema' \| 'regex' \| 'grammar' \| 'xml'>` || Expected output format |
121+
| **schema** | `Record<string, any>` | optional | JSON Schema definition for output |
122+
| **strict** | `boolean` | optional (default: `false`) | Enforce exact schema compliance |
123+
| **retryOnValidationFailure** | `boolean` | optional (default: `true`) | Retry generation when output fails validation |
124+
| **maxRetries** | `integer` | optional (default: `3`) | Maximum retries on validation failure |
125+
| **fallbackFormat** | `Enum<'json_object' \| 'json_schema' \| 'regex' \| 'grammar' \| 'xml'>` | optional | Fallback format if primary format fails |
126+
| **transformPipeline** | `Enum<'trim' \| 'parse_json' \| 'validate' \| 'coerce_types'>[]` | optional | Post-processing steps applied to output |
127+
128+
### Nested Shape: `Agent.protection`
129+
130+
| Property | Type | Required | Description |
131+
| :--- | :--- | :--- | :--- |
132+
| **lock** | `Enum<'none' \| 'no-overlay' \| 'no-delete' \| 'full'>` || Lock policy — none \| no-overlay \| no-delete \| full. |
133+
| **reason** | `string` || User-visible reason shown when the lock blocks an action. |
134+
| **docsUrl** | `string` | optional | Optional URL the Studio banner links to for more context. |
135+
74136

75137
---
76138

content/docs/references/ai/conversation.mdx

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,30 @@ const result = CodeContentSchema.parse(data);
104104
| **embedding** | `number[]` | optional | Vector embedding for semantic search |
105105
| **metadata** | `Record<string, any>` | optional | |
106106

107+
### Nested Shape: `ConversationMessage.functionCall`
108+
109+
| Property | Type | Required | Description |
110+
| :--- | :--- | :--- | :--- |
111+
| **name** | `string` || Function name |
112+
| **arguments** | `string` || JSON string of function arguments |
113+
| **result** | `string` | optional | Function execution result |
114+
115+
### Nested Shape: `ConversationMessage.toolCalls[number]`
116+
117+
| Property | Type | Required | Description |
118+
| :--- | :--- | :--- | :--- |
119+
| **id** | `string` || Tool call ID |
120+
| **type** | `Enum<'function'>` | optional (default: `"function"`) | |
121+
| **function** | `{ name: string; arguments: string; result?: string }` || |
122+
123+
### Nested Shape: `ConversationMessage.tokens`
124+
125+
| Property | Type | Required | Description |
126+
| :--- | :--- | :--- | :--- |
127+
| **promptTokens** | `integer` || Tokens consumed by the prompt |
128+
| **completionTokens** | `integer` || Tokens generated in the completion |
129+
| **totalTokens** | `integer` || Total tokens (prompt + completion) |
130+
107131

108132
---
109133

@@ -128,6 +152,79 @@ const result = CodeContentSchema.parse(data);
128152
| **expiresAt** | `string` | optional | ISO 8601 timestamp |
129153
| **metadata** | `Record<string, any>` | optional | |
130154

155+
### Nested Shape: `ConversationSession.context`
156+
157+
| Property | Type | Required | Description |
158+
| :--- | :--- | :--- | :--- |
159+
| **sessionId** | `string` || Conversation session ID |
160+
| **userId** | `string` | optional | User identifier |
161+
| **agentId** | `string` | optional | AI agent identifier |
162+
| **object** | `string` | optional | Related object (e.g., "case", "project") |
163+
| **recordId** | `string` | optional | Related record ID |
164+
| **scope** | `Record<string, any>` | optional | Additional context scope |
165+
| **systemMessage** | `string` | optional | System prompt/instructions |
166+
| **metadata** | `Record<string, any>` | optional | |
167+
168+
### Nested Shape: `ConversationSession.tokenBudget`
169+
170+
| Property | Type | Required | Description |
171+
| :--- | :--- | :--- | :--- |
172+
| **maxTokens** | `integer` || Maximum total tokens |
173+
| **maxPromptTokens** | `integer` | optional | Max tokens for prompt |
174+
| **maxCompletionTokens** | `integer` | optional | Max tokens for completion |
175+
| **reserveTokens** | `integer` | optional (default: `500`) | Reserve tokens for system messages |
176+
| **bufferPercentage** | `number` | optional (default: `0.1`) | Buffer percentage (0.1 = 10%) |
177+
| **strategy** | `Enum<'fifo' \| 'importance' \| 'semantic' \| 'sliding_window' \| 'summary'>` | optional (default: `"sliding_window"`) | |
178+
| **slidingWindowSize** | `integer` | optional | Number of recent messages to keep |
179+
| **minImportanceScore** | `number` | optional | Minimum importance to keep |
180+
| **semanticThreshold** | `number` | optional | Semantic similarity threshold |
181+
| **enableSummarization** | `boolean` | optional (default: `false`) | Enable context summarization |
182+
| **summarizationThreshold** | `integer` | optional | Trigger summarization at N tokens |
183+
| **summaryModel** | `string` | optional | Model ID for summarization |
184+
| **warnThreshold** | `number` | optional (default: `0.8`) | Warn at % of budget (0.8 = 80%) |
185+
186+
### Nested Shape: `ConversationSession.messages[number]`
187+
188+
| Property | Type | Required | Description |
189+
| :--- | :--- | :--- | :--- |
190+
| **id** | `string` || Unique message ID |
191+
| **timestamp** | `string` || ISO 8601 timestamp |
192+
| **role** | `Enum<'system' \| 'user' \| 'assistant' \| 'function' \| 'tool'>` || |
193+
| **content** | `({ type: 'text'; text: string; metadata?: Record<string, any> } \| { type: 'image'; imageUrl: string; detail: Enum<'low' \| 'high' \| 'auto'>; metadata?: Record<string, any> } \| { type: 'file'; fileUrl: string; mimeType: string; fileName?: string; … } \| { type: 'code'; text: string; language: string; metadata?: Record<string, any> })[]` || Message content (multimodal array) |
194+
| **functionCall** | `{ name: string; arguments: string; result?: string }` | optional | Legacy function call |
195+
| **toolCalls** | `{ id: string; type: Enum<'function'>; function: object }[]` | optional | Tool calls |
196+
| **toolCallId** | `string` | optional | Tool call ID this message responds to |
197+
| **name** | `string` | optional | Name of the function/user |
198+
| **tokens** | `{ promptTokens: integer; completionTokens: integer; totalTokens: integer }` | optional | Token usage for this message |
199+
| **cost** | `number` | optional | Cost for this message in USD |
200+
| **pinned** | `boolean` | optional (default: `false`) | Prevent removal during pruning |
201+
| **importance** | `number` | optional | Importance score for pruning |
202+
| **embedding** | `number[]` | optional | Vector embedding for semantic search |
203+
| **metadata** | `Record<string, any>` | optional | |
204+
205+
### Nested Shape: `ConversationSession.tokens`
206+
207+
| Property | Type | Required | Description |
208+
| :--- | :--- | :--- | :--- |
209+
| **promptTokens** | `integer` | optional (default: `0`) | |
210+
| **completionTokens** | `integer` | optional (default: `0`) | |
211+
| **totalTokens** | `integer` | optional (default: `0`) | |
212+
| **budgetLimit** | `integer` || |
213+
| **budgetUsed** | `integer` | optional (default: `0`) | |
214+
| **budgetRemaining** | `integer` || |
215+
| **budgetPercentage** | `number` || Usage as percentage of budget |
216+
| **messageCount** | `integer` | optional (default: `0`) | |
217+
| **prunedMessageCount** | `integer` | optional (default: `0`) | |
218+
| **summarizedMessageCount** | `integer` | optional (default: `0`) | |
219+
220+
### Nested Shape: `ConversationSession.totalTokens`
221+
222+
| Property | Type | Required | Description |
223+
| :--- | :--- | :--- | :--- |
224+
| **promptTokens** | `integer` || Tokens consumed by the prompt |
225+
| **completionTokens** | `integer` || Tokens generated in the completion |
226+
| **totalTokens** | `integer` || Total tokens (prompt + completion) |
227+
131228

132229
---
133230

@@ -381,6 +478,14 @@ This schema accepts one of the following structures:
381478
| **type** | `Enum<'function'>` | optional (default: `"function"`) | |
382479
| **function** | `{ name: string; arguments: string; result?: string }` || |
383480

481+
### Nested Shape: `ToolCall.function`
482+
483+
| Property | Type | Required | Description |
484+
| :--- | :--- | :--- | :--- |
485+
| **name** | `string` || Function name |
486+
| **arguments** | `string` || JSON string of function arguments |
487+
| **result** | `string` | optional | Function execution result |
488+
384489

385490
---
386491

content/docs/references/ai/knowledge-source.mdx

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,26 @@ const result = FileKnowledgeSourceSchema.parse(data);
8787
| **refresh** | `{ onRecordChange?: boolean; cron?: string }` | optional (default: `{}`) | |
8888
| **aiExposed** | `boolean` | optional (default: `true`) | |
8989

90+
### Nested Shape: `KnowledgeSource.embedding`
91+
92+
| Property | Type | Required | Description |
93+
| :--- | :--- | :--- | :--- |
94+
| **provider** | `Enum<'openai' \| 'cohere' \| 'azure_openai' \| 'huggingface' \| 'local' \| 'custom'>` || |
95+
| **model** | `string` || Provider-specific model identifier |
96+
| **dimensions** | `integer` || Embedding vector dimensions |
97+
| **endpoint** | `string` | optional | Custom endpoint URL |
98+
| **secretRef** | `string` | optional | Reference to stored API key secret |
99+
100+
### Nested Shape: `KnowledgeSource.vectorStore`
101+
102+
| Property | Type | Required | Description |
103+
| :--- | :--- | :--- | :--- |
104+
| **provider** | `Enum<'pgvector' \| 'chroma' \| 'qdrant' \| 'pinecone' \| 'weaviate' \| 'milvus' \| 'redis' \| …>` || |
105+
| **collection** | `string` || Collection / index / namespace name |
106+
| **endpoint** | `string` | optional | Connection string or endpoint URL |
107+
| **secretRef** | `string` | optional | Reference to stored credential secret |
108+
| **dimensions** | `integer` | optional | |
109+
90110

91111
---
92112

0 commit comments

Comments
 (0)