Repository navigation
Commit ce02534
committed
feat(diagrams): render_diagram — the agent draws in the chat
Ask the agent how something is put together and it answered with boxes and
arrows made of characters, which break with the font, the theme and the width
of the panel. Now it has a tool. It describes the structure; the editor
validates it, lays it out and paints it in the chat, in the editor's theme,
with nodes that open the code they stand for.
Graph JSON only: phase 1 of the spec. Mermaid, Vega-Lite and raw SVG are not
built, and the rules tell the model to use a table for numbers and a numbered
list for sequences rather than a format the chat would show as source.
The model's side (diagram/tool.js)
render_diagram its input schema is the validator's own schema object
the rules when a diagram earns its place; never draw with characters;
asked for a diagram, draw it here rather than writing a file
of diagram source; the title states the takeaway; one
accent; split above twelve nodes; link nodes to workspace
files. One worked example, itself a valid spec.
the answer {"ok":true,"id":"d-1"}, or every error at once
About 520 tokens of tool and 450 of rules on every request from a client
that can render — constant for a session, so they sit in the cached prefix.
One conversation's diagrams (diagram/service.js)
A call that fails validation is sent back ONCE, with every error. A second
failure is drawn degraded, with a banner naming each loss and a Retry button
that the user presses, not the editor. Three bounces in one run and every
later call is final. A diagram still owed its repair when the run ends — the
model gave up, ran out of steps, was stopped — is settled from its last
attempt before agentDone, so no placeholder is left waiting. Arguments cut
off at the token limit are asked for again, never repaired.
In the chat (media/chat.html)
A placeholder from the moment the call starts, titled as soon as the title
has streamed; then the picture. The shared modules are inlined into the page
by diagram/bundle.js under the page's existing nonce: the content security
policy is unchanged, and the page still loads nothing. Text is measured in
the real font. A column too narrow for a left-to-right flow turns it
downward, and it turns back when the column widens. A full-size view with
zoom and pan. The "auto-fixed" badge and its details; the degraded banner;
the errors and the source when nothing can be drawn. Copy source, SVG, PNG,
open as Mermaid, insert into a Markdown file. The title is the accessible
name, and a text outline is there for screen readers. If painting fails, or
the modules never loaded, the same diagram is shown as text — drawn by the
page in the first case and by the host in the second.
What the page may ask of the editor
openLink, export, retry and ascii. Each names a diagram by id and is looked
up in the host's own records. A click sends the NODE id; the path comes from
the record and is resolved again at that moment (diagram/links.js): inside a
workspace folder once ".." and symlinks are followed, and a file. SVG and PNG
come back from the page, so they are checked before they are written
(diagram/exportCheck.js). The spec lists two actions; its own Retry button
and text fallback need the other two.
Sessions and context
The final record — spec, status, fixes, what was lost — is stored with the
turn and replayed when a chat is reopened; nothing is repaired again. A
session file is input too: a stored spec passes the validator on its way
back in, in the host and in the page. At compaction a diagram becomes one
line ("diagram: <title>, 4 nodes, id d-17"), and get_diagram is offered from
then on. A session export writes each diagram as a fenced Mermaid block.
Who gets it
A run carries client.render: rich or ascii. Rich is the chat webview, unless
levelcode.ai.diagrams.enabled is off or the model's catalog row says
diagrams: false — the switch for a model that fails the eval. An ascii client
is offered neither the tool nor the rules. Chat mode has no tools and is
unchanged.
Counters (diagram/stats.js, "AI: Diagram Statistics")
First-pass valid rate, fixes by rung, error classes per model, render time,
tokens per diagram, and answers that drew with characters anyway. Kept in
the editor's own storage and sent nowhere; enums and numbers only, never a
label, a title or a path.
Providers: onToolStart now carries the call's id, a new onToolInput streams its
arguments, and a turn returns the raw text of arguments that did not parse.
All additive.
Four existing suites change. agentNoWorkspace and sessionsUi pinned the shape
of the tool list in source, and now pin the new shape. authRetryCallers and
sessionExpiredHost slice compactAgentMemory and resumeSession out of
extension.js, and needed the names those now use.
Tests: diagramAgent (22 — the real runAgent with a scripted provider),
diagramSession (12), diagramLinks (9), diagramHost (27 — extension.js's own
functions against a stand-in for vscode), diagramStats (8), diagramUi (11).1 parent f35fbc1 commit ce02534
27 files changed
Lines changed: 3400 additions & 60 deletions
File tree
- extensions/levelcode-ai
- diagram
- media
- providers
- test
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
21 | 21 | | |
22 | 22 | | |
23 | 23 | | |
| 24 | + | |
| 25 | + | |
24 | 26 | | |
25 | 27 | | |
26 | 28 | | |
| |||
307 | 309 | | |
308 | 310 | | |
309 | 311 | | |
| 312 | + | |
| 313 | + | |
| 314 | + | |
| 315 | + | |
| 316 | + | |
| 317 | + | |
| 318 | + | |
310 | 319 | | |
311 | 320 | | |
312 | 321 | | |
| |||
517 | 526 | | |
518 | 527 | | |
519 | 528 | | |
| 529 | + | |
| 530 | + | |
| 531 | + | |
| 532 | + | |
| 533 | + | |
| 534 | + | |
| 535 | + | |
| 536 | + | |
| 537 | + | |
| 538 | + | |
| 539 | + | |
| 540 | + | |
| 541 | + | |
| 542 | + | |
| 543 | + | |
| 544 | + | |
520 | 545 | | |
521 | 546 | | |
522 | 547 | | |
| |||
753 | 778 | | |
754 | 779 | | |
755 | 780 | | |
756 | | - | |
| 781 | + | |
| 782 | + | |
| 783 | + | |
| 784 | + | |
| 785 | + | |
| 786 | + | |
| 787 | + | |
757 | 788 | | |
758 | 789 | | |
759 | 790 | | |
| |||
792 | 823 | | |
793 | 824 | | |
794 | 825 | | |
795 | | - | |
796 | | - | |
797 | | - | |
| 826 | + | |
| 827 | + | |
| 828 | + | |
| 829 | + | |
| 830 | + | |
| 831 | + | |
| 832 | + | |
| 833 | + | |
| 834 | + | |
798 | 835 | | |
799 | 836 | | |
800 | 837 | | |
801 | 838 | | |
802 | | - | |
| 839 | + | |
803 | 840 | | |
804 | 841 | | |
805 | 842 | | |
| |||
812 | 849 | | |
813 | 850 | | |
814 | 851 | | |
| 852 | + | |
| 853 | + | |
| 854 | + | |
815 | 855 | | |
816 | 856 | | |
817 | 857 | | |
| |||
898 | 938 | | |
899 | 939 | | |
900 | 940 | | |
901 | | - | |
| 941 | + | |
902 | 942 | | |
903 | 943 | | |
904 | 944 | | |
905 | | - | |
| 945 | + | |
| 946 | + | |
906 | 947 | | |
| 948 | + | |
| 949 | + | |
| 950 | + | |
| 951 | + | |
| 952 | + | |
| 953 | + | |
| 954 | + | |
| 955 | + | |
| 956 | + | |
| 957 | + | |
| 958 | + | |
| 959 | + | |
| 960 | + | |
907 | 961 | | |
908 | 962 | | |
909 | 963 | | |
| |||
975 | 1029 | | |
976 | 1030 | | |
977 | 1031 | | |
978 | | - | |
| 1032 | + | |
| 1033 | + | |
| 1034 | + | |
| 1035 | + | |
| 1036 | + | |
| 1037 | + | |
| 1038 | + | |
| 1039 | + | |
| 1040 | + | |
| 1041 | + | |
| 1042 | + | |
| 1043 | + | |
| 1044 | + | |
| 1045 | + | |
| 1046 | + | |
| 1047 | + | |
979 | 1048 | | |
980 | 1049 | | |
981 | 1050 | | |
| |||
995 | 1064 | | |
996 | 1065 | | |
997 | 1066 | | |
| 1067 | + | |
998 | 1068 | | |
999 | 1069 | | |
1000 | 1070 | | |
| |||
1059 | 1129 | | |
1060 | 1130 | | |
1061 | 1131 | | |
| 1132 | + | |
| 1133 | + | |
| 1134 | + | |
| 1135 | + | |
| 1136 | + | |
1062 | 1137 | | |
1063 | 1138 | | |
1064 | 1139 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
0 commit comments