B1-1: distill 9 inline surface types into editor_chat.allium spec
This commit is contained in:
@@ -60,7 +60,7 @@ Gap categories: **SC** = spec correct, fix code | **CS** = code correct, update
|
|||||||
|
|
||||||
| ID | Behavior | Code Location | Path |
|
| ID | Behavior | Code Location | Path |
|
||||||
|---|---|---|---|
|
|---|---|---|---|
|
||||||
| B1-1 | Chat inline surfaces (9 types: card, chart, form, list, metric, mindmap, table, tabs, text/json) | `lib/bds/ui/chat/tool_surfaces.ex:6-15` | Distill into spec |
|
| ~~B1-1~~ | ~~Chat inline surfaces (9 types: card, chart, form, list, metric, mindmap, table, tabs, text/json)~~ | `tool_surfaces.ex` | **Resolved:** added InlineSurface value type with all 9 discriminators, supporting value types (SurfaceAction, ChartSeries, MindmapNode, FormField, FieldOption, TabPanel), inline_surfaces on ChatMessage, InlineSurfaceRendering guarantee, and surface_form_debounce_ms config to editor_chat.allium; updated StructuredRenderTools invariant in ai.allium to list all 9 types |
|
||||||
| B1-2 | Auto-translation system (AutoTranslation.maybe_schedule, media cascade, batch fill) | `lib/bds/posts/auto_translation.ex` | Distill into spec |
|
| B1-2 | Auto-translation system (AutoTranslation.maybe_schedule, media cascade, batch fill) | `lib/bds/posts/auto_translation.ex` | Distill into spec |
|
||||||
| B1-3 | 3 extra settings sections (Technology, MCP, Data Maintenance) | `lib/bds/ui/settings_editor/` | Distill into spec |
|
| B1-3 | 3 extra settings sections (Technology, MCP, Data Maintenance) | `lib/bds/ui/settings_editor/` | Distill into spec |
|
||||||
| B1-4 | Style/Theme as separate tab (`:style`), not settings section | `lib/bds/ui/style_editor.ex` | Distill into spec |
|
| B1-4 | Style/Theme as separate tab (`:style`), not settings section | `lib/bds/ui/style_editor.ex` | Distill into spec |
|
||||||
|
|||||||
@@ -396,8 +396,14 @@ invariant ChatCancellation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
invariant StructuredRenderTools {
|
invariant StructuredRenderTools {
|
||||||
-- Chat may emit structured render payloads for charts, tables, and forms.
|
-- Chat may emit structured render payloads via tool calls prefixed "render_".
|
||||||
|
-- 9 inline surface types: card, chart, form, list, metric, mindmap, table, tabs, text, json.
|
||||||
|
-- Render tool names: render_card, render_chart, render_form, render_list,
|
||||||
|
-- render_metric, render_mindmap, render_table, render_tabs.
|
||||||
|
-- Unrecognized render tool names render as JSON (raw dump).
|
||||||
|
-- Tab content may nest any surface type including plain text.
|
||||||
-- These payloads are data contracts, not arbitrary HTML strings.
|
-- These payloads are data contracts, not arbitrary HTML strings.
|
||||||
|
-- Surface data contracts are defined in editor_chat.allium InlineSurface value.
|
||||||
}
|
}
|
||||||
|
|
||||||
invariant BlogStatsPromptAugmentation {
|
invariant BlogStatsPromptAugmentation {
|
||||||
|
|||||||
@@ -23,9 +23,72 @@ value ChatMessage {
|
|||||||
role: String -- user | assistant | system
|
role: String -- user | assistant | system
|
||||||
content: String -- user: plain text; assistant: GFM markdown
|
content: String -- user: plain text; assistant: GFM markdown
|
||||||
tool_markers: List<ToolMarker>
|
tool_markers: List<ToolMarker>
|
||||||
|
inline_surfaces: List<InlineSurface>
|
||||||
is_streaming: Boolean -- true while accumulating
|
is_streaming: Boolean -- true while accumulating
|
||||||
}
|
}
|
||||||
|
|
||||||
|
value InlineSurface {
|
||||||
|
id: String
|
||||||
|
type: "card" | "chart" | "form" | "list" | "metric" | "mindmap" | "table" | "tabs" | "text" | "json"
|
||||||
|
title: String?
|
||||||
|
subtitle: String? -- card only
|
||||||
|
body: String? -- card, text
|
||||||
|
actions: List<SurfaceAction> -- card only
|
||||||
|
columns: List<String> -- table
|
||||||
|
rows: List<List<String>> -- table
|
||||||
|
chart_type: String? -- chart: bar/pie/line
|
||||||
|
series: List<ChartSeries> -- chart
|
||||||
|
max_value: Integer? -- chart
|
||||||
|
label: String? -- metric
|
||||||
|
value: String? -- metric
|
||||||
|
items: List<String> -- list
|
||||||
|
nodes: List<MindmapNode> -- mindmap
|
||||||
|
fields: List<FormField> -- form
|
||||||
|
submit_label: String? -- form
|
||||||
|
submit_action: String? -- form
|
||||||
|
tabs: List<TabPanel> -- tabs
|
||||||
|
selected_index: Integer? -- tabs
|
||||||
|
raw: Map? -- json catch-all
|
||||||
|
}
|
||||||
|
|
||||||
|
value SurfaceAction {
|
||||||
|
label: String
|
||||||
|
action: String
|
||||||
|
payload: Map
|
||||||
|
}
|
||||||
|
|
||||||
|
value ChartSeries {
|
||||||
|
label: String
|
||||||
|
value: Integer
|
||||||
|
segments: List
|
||||||
|
}
|
||||||
|
|
||||||
|
value MindmapNode {
|
||||||
|
id: String?
|
||||||
|
label: String
|
||||||
|
children: List<String>
|
||||||
|
}
|
||||||
|
|
||||||
|
value FormField {
|
||||||
|
key: String
|
||||||
|
label: String
|
||||||
|
input_type: String
|
||||||
|
placeholder: String?
|
||||||
|
value: String?
|
||||||
|
options: List<FieldOption>
|
||||||
|
required: Boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
value FieldOption {
|
||||||
|
label: String
|
||||||
|
value: String
|
||||||
|
}
|
||||||
|
|
||||||
|
value TabPanel {
|
||||||
|
label: String
|
||||||
|
content: List<InlineSurface> -- nested surfaces or text
|
||||||
|
}
|
||||||
|
|
||||||
value ToolMarker {
|
value ToolMarker {
|
||||||
tool_name: String
|
tool_name: String
|
||||||
args_preview: String -- string args truncated to config.chat_tool_args_max_length
|
args_preview: String -- string args truncated to config.chat_tool_args_max_length
|
||||||
@@ -66,6 +129,7 @@ value ModelEntry {
|
|||||||
config {
|
config {
|
||||||
chat_tool_args_max_length: Integer = 30
|
chat_tool_args_max_length: Integer = 30
|
||||||
chat_input_max_height: Integer = 200
|
chat_input_max_height: Integer = 200
|
||||||
|
surface_form_debounce_ms: Integer = 500
|
||||||
}
|
}
|
||||||
|
|
||||||
surface ChatPanelSurface {
|
surface ChatPanelSurface {
|
||||||
@@ -85,6 +149,9 @@ surface ChatPanelSurface {
|
|||||||
tm.tool_name
|
tm.tool_name
|
||||||
tm.args_preview
|
tm.args_preview
|
||||||
tm.is_complete
|
tm.is_complete
|
||||||
|
for sfc in msg.inline_surfaces:
|
||||||
|
sfc.type
|
||||||
|
sfc.id
|
||||||
|
|
||||||
provides:
|
provides:
|
||||||
ChatSendMessage(panel.conversation_id, panel.input_text)
|
ChatSendMessage(panel.conversation_id, panel.input_text)
|
||||||
@@ -138,6 +205,19 @@ surface ChatPanelSurface {
|
|||||||
-- Actions dispatched through store, same as user clicks.
|
-- Actions dispatched through store, same as user clicks.
|
||||||
-- Navigation actions open tabs with pin intent.
|
-- Navigation actions open tabs with pin intent.
|
||||||
|
|
||||||
|
@guarantee InlineSurfaceRendering
|
||||||
|
-- Assistant render-tool calls produce structured inline surfaces
|
||||||
|
-- rendered between message content and tool markers.
|
||||||
|
-- 9 surface types: card, chart, form, list, metric, mindmap, table, tabs, text, json.
|
||||||
|
-- Render tool names: render_card, render_chart, render_form, render_list,
|
||||||
|
-- render_metric, render_mindmap, render_table, render_tabs.
|
||||||
|
-- Unrecognized render names render as json (raw dump).
|
||||||
|
-- Tab content nests any surface type including plain text.
|
||||||
|
-- Form surfaces persist field values in conversation surface_state.
|
||||||
|
-- Tab surfaces track selected_index in conversation surface_state.
|
||||||
|
-- Surfaces can be dismissed, persisted in conversation surface_state.
|
||||||
|
-- Form debounce: config.surface_form_debounce_ms.
|
||||||
|
|
||||||
@guarantee TokenTracking
|
@guarantee TokenTracking
|
||||||
-- Token usage tracked per conversation.
|
-- Token usage tracked per conversation.
|
||||||
-- Displayed in status bar, not in the chat panel itself.
|
-- Displayed in status bar, not in the chat panel itself.
|
||||||
|
|||||||
Reference in New Issue
Block a user