@almadar/std 16.243.0 → 16.244.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (140) hide show
  1. package/behaviors/behaviors-registry.json +72537 -31220
  2. package/behaviors/lolo/agent/atoms/std-agent-context.lolo +24 -4
  3. package/behaviors/lolo/agent/atoms/std-agent-memory.lolo +20 -5
  4. package/behaviors/lolo/agent/atoms/std-agent-proposal.lolo +550 -0
  5. package/behaviors/lolo/agent/atoms/std-agent-session.lolo +284 -25
  6. package/behaviors/lolo/agent/atoms/std-agent-suggestions.lolo +841 -0
  7. package/behaviors/lolo/agent/atoms/std-agent-tool-loop.lolo +58 -8
  8. package/behaviors/lolo/agent/organisms/std-agent-assistant.lolo +1 -0
  9. package/behaviors/lolo/infra/atoms/std-page-treat.lolo +28 -1
  10. package/behaviors/lolo/ui/avl/atoms/ui-avl-state-machine.lolo +22 -0
  11. package/behaviors/lolo/ui/avl/atoms/ui-avl-transition-explainer.lolo +175 -0
  12. package/behaviors/lolo/ui/avl/atoms/ui-module-card.lolo +22 -0
  13. package/behaviors/lolo/ui/core/atoms/std-app-layout.lolo +23 -4
  14. package/behaviors/lolo/ui/core/atoms/std-hero.lolo +72 -33
  15. package/behaviors/lolo/ui/core/molecules/ui-agent-chat-feed.lolo +1 -1
  16. package/behaviors/lolo/ui/core/molecules/ui-markdown-content.lolo +54 -0
  17. package/behaviors/lolo/ui/core/molecules/ui-upload-drop-zone.lolo +5 -0
  18. package/behaviors/lolo/ui/core/organisms/ui-segment-renderer.lolo +127 -3
  19. package/behaviors/lolo/ui/core/organisms/ui-state-machine-view.lolo +22 -0
  20. package/behaviors/lolo/ui/core/templates/ui-dashboard-layout.lolo +2 -2
  21. package/behaviors/lolo/ui/learning/atoms/std-learn-arrangement.lolo +87 -17
  22. package/behaviors/lolo/ui/learning/atoms/std-learn-classify.lolo +172 -37
  23. package/behaviors/lolo/ui/learning/atoms/std-learn-coupled-sim.lolo +183 -70
  24. package/behaviors/lolo/ui/learning/atoms/std-learn-derivation.lolo +78 -13
  25. package/behaviors/lolo/ui/learning/atoms/std-learn-diagram.lolo +58 -2
  26. package/behaviors/lolo/ui/learning/atoms/std-learn-doser.lolo +107 -12
  27. package/behaviors/lolo/ui/learning/atoms/std-learn-estimate.lolo +83 -10
  28. package/behaviors/lolo/ui/learning/atoms/std-learn-goal-seek.lolo +130 -9
  29. package/behaviors/lolo/ui/learning/atoms/std-learn-grid-sim.lolo +143 -59
  30. package/behaviors/lolo/ui/learning/atoms/std-learn-hotspot.lolo +96 -22
  31. package/behaviors/lolo/ui/learning/atoms/std-learn-live-sim.lolo +66 -5
  32. package/behaviors/lolo/ui/learning/atoms/std-learn-predict.lolo +84 -6
  33. package/behaviors/lolo/ui/learning/atoms/std-learn-sandbox.lolo +80 -14
  34. package/behaviors/lolo/ui/learning/atoms/std-learn-scatter-fit.lolo +99 -5
  35. package/behaviors/lolo/ui/learning/atoms/std-learn-scenario.lolo +81 -7
  36. package/behaviors/lolo/ui/learning/atoms/std-learn-speed-drill.lolo +83 -7
  37. package/behaviors/lolo/ui/learning/atoms/std-learn-stepper.lolo +224 -99
  38. package/behaviors/lolo/ui/learning/atoms/std-learn-tour-3d.lolo +63 -2
  39. package/behaviors/lolo/ui/learning/atoms/std-learn-trace-player.lolo +99 -38
  40. package/behaviors/lolo/ui/learning/atoms/std-learn-transport.lolo +7 -7
  41. package/behaviors/lolo/ui/learning/atoms/std-learn-tree.lolo +69 -4
  42. package/behaviors/lolo-behavior-contracts.json +1 -1
  43. package/behaviors/registry/agent/atoms/std-agent-context.orb +205 -6
  44. package/behaviors/registry/agent/atoms/std-agent-memory.orb +146 -4
  45. package/behaviors/registry/agent/atoms/std-agent-proposal.orb +1972 -0
  46. package/behaviors/registry/agent/atoms/std-agent-session.orb +2021 -597
  47. package/behaviors/registry/agent/atoms/std-agent-suggestions.orb +5079 -0
  48. package/behaviors/registry/agent/atoms/std-agent-tool-loop.orb +287 -5
  49. package/behaviors/registry/agent/organisms/std-agent-assistant.orb +7 -0
  50. package/behaviors/registry/factory-signatures.json +1 -1
  51. package/behaviors/registry/infra/atoms/std-page-treat.orb +327 -2
  52. package/behaviors/registry/ui/avl/atoms/ui-avl-state-machine.orb +134 -0
  53. package/behaviors/registry/ui/avl/atoms/ui-avl-transition-explainer.orb +678 -0
  54. package/behaviors/registry/ui/avl/atoms/ui-module-card.orb +122 -0
  55. package/behaviors/registry/ui/core/atoms/std-app-layout.orb +73 -4
  56. package/behaviors/registry/ui/core/atoms/std-hero.orb +174 -97
  57. package/behaviors/registry/ui/core/molecules/ui-markdown-content.orb +204 -1
  58. package/behaviors/registry/ui/core/molecules/ui-upload-drop-zone.orb +12 -0
  59. package/behaviors/registry/ui/core/organisms/ui-segment-renderer.orb +683 -30
  60. package/behaviors/registry/ui/learning/atoms/std-learn-arrangement.orb +748 -21
  61. package/behaviors/registry/ui/learning/atoms/std-learn-classify.orb +1429 -41
  62. package/behaviors/registry/ui/learning/atoms/std-learn-coupled-sim.orb +1031 -185
  63. package/behaviors/registry/ui/learning/atoms/std-learn-derivation.orb +807 -132
  64. package/behaviors/registry/ui/learning/atoms/std-learn-diagram.orb +553 -6
  65. package/behaviors/registry/ui/learning/atoms/std-learn-doser.orb +987 -21
  66. package/behaviors/registry/ui/learning/atoms/std-learn-estimate.orb +582 -16
  67. package/behaviors/registry/ui/learning/atoms/std-learn-goal-seek.orb +954 -13
  68. package/behaviors/registry/ui/learning/atoms/std-learn-grid-sim.orb +828 -88
  69. package/behaviors/registry/ui/learning/atoms/std-learn-hotspot.orb +730 -28
  70. package/behaviors/registry/ui/learning/atoms/std-learn-live-sim.orb +479 -9
  71. package/behaviors/registry/ui/learning/atoms/std-learn-predict.orb +797 -46
  72. package/behaviors/registry/ui/learning/atoms/std-learn-sandbox.orb +757 -58
  73. package/behaviors/registry/ui/learning/atoms/std-learn-scatter-fit.orb +1176 -164
  74. package/behaviors/registry/ui/learning/atoms/std-learn-scenario.orb +599 -12
  75. package/behaviors/registry/ui/learning/atoms/std-learn-speed-drill.orb +832 -150
  76. package/behaviors/registry/ui/learning/atoms/std-learn-stepper.orb +1561 -127
  77. package/behaviors/registry/ui/learning/atoms/std-learn-tour-3d.orb +655 -6
  78. package/behaviors/registry/ui/learning/atoms/std-learn-trace-player.orb +634 -43
  79. package/behaviors/registry/ui/learning/atoms/std-learn-transport.orb +85 -31
  80. package/behaviors/registry/ui/learning/atoms/std-learn-tree.orb +425 -9
  81. package/canonical-operators.json +45 -2
  82. package/dist/behaviors/exports-reader.js +16667 -7868
  83. package/dist/behaviors/functions/index.d.ts +711 -32
  84. package/dist/behaviors/functions/index.js +16651 -7869
  85. package/dist/behaviors/index.d.ts +1 -1
  86. package/dist/behaviors/index.js +16668 -7869
  87. package/dist/behaviors/query.js +16667 -7868
  88. package/dist/behaviors-embeddings.hash.json +3 -3
  89. package/dist/behaviors-embeddings.json +77 -53
  90. package/dist/behaviors-registry.json +72537 -31220
  91. package/dist/index.d.ts +3 -3
  92. package/dist/index.js +16101 -7275
  93. package/dist/knob-embeddings.hash.json +3 -3
  94. package/dist/knob-embeddings.json +11617 -1225
  95. package/dist/modules/anim.d.ts +1 -1
  96. package/dist/modules/array.d.ts +1 -1
  97. package/dist/modules/async.d.ts +1 -1
  98. package/dist/modules/behavior.d.ts +1 -1
  99. package/dist/modules/browser.d.ts +1 -1
  100. package/dist/modules/composition.d.ts +1 -1
  101. package/dist/modules/contract.d.ts +1 -1
  102. package/dist/modules/core.d.ts +1 -1
  103. package/dist/modules/core.js +29 -2
  104. package/dist/modules/data.d.ts +1 -1
  105. package/dist/modules/ease.d.ts +1 -1
  106. package/dist/modules/format.d.ts +1 -1
  107. package/dist/modules/geo.d.ts +1 -1
  108. package/dist/modules/graph.d.ts +1 -1
  109. package/dist/modules/grid.d.ts +1 -1
  110. package/dist/modules/i18n.d.ts +1 -1
  111. package/dist/modules/index.d.ts +1 -1
  112. package/dist/modules/index.js +29 -2
  113. package/dist/modules/integration.d.ts +1 -1
  114. package/dist/modules/json.d.ts +1 -1
  115. package/dist/modules/llm.d.ts +1 -1
  116. package/dist/modules/math.d.ts +1 -1
  117. package/dist/modules/memory.d.ts +1 -1
  118. package/dist/modules/nn.d.ts +1 -1
  119. package/dist/modules/noise.d.ts +1 -1
  120. package/dist/modules/object.d.ts +1 -1
  121. package/dist/modules/os.d.ts +1 -1
  122. package/dist/modules/path.d.ts +1 -1
  123. package/dist/modules/prob.d.ts +1 -1
  124. package/dist/modules/session.d.ts +1 -1
  125. package/dist/modules/str.d.ts +1 -1
  126. package/dist/modules/tensor.d.ts +1 -1
  127. package/dist/modules/time.d.ts +1 -1
  128. package/dist/modules/trace.d.ts +1 -1
  129. package/dist/modules/train.d.ts +1 -1
  130. package/dist/modules/validate.d.ts +1 -1
  131. package/dist/modules/vector.d.ts +1 -1
  132. package/dist/modules/workspace.d.ts +1 -1
  133. package/dist/registry/factory-signatures.json +1 -1
  134. package/dist/registry.d.ts +2 -2
  135. package/dist/registry.js +29 -2
  136. package/dist/{types-Cdb321uM.d.ts → types-Y-yYWEOX.d.ts} +1 -1
  137. package/i18n/ar.json +3 -1
  138. package/i18n/en.json +2 -0
  139. package/i18n/sl.json +3 -1
  140. package/package.json +3 -3
@@ -5,6 +5,11 @@ type AgentChatMessage = {
5
5
  role : "user" | "assistant"
6
6
  content : string!
7
7
  }
8
+ type AgentTool = {
9
+ event : event
10
+ read : string
11
+ scope : "declared"
12
+ }
8
13
 
9
14
  orbital AgentContextOrbital {
10
15
  type ContextSummarized = Event { summary : string, keyPoints : [string] } "Fired when the older turns have been summarized"
@@ -14,6 +19,9 @@ orbital AgentContextOrbital {
14
19
  id : string!
15
20
  pendingMessages : [AgentChatMessage] @description "The conversation being compacted." = []
16
21
  lastSize : number @description "Turns in the last conversation compacted." @synonyms "size, length" = 0
22
+ pendingInstructions : string @description "The ephemeral conversation's own instructions, carried through a summarizing." = ""
23
+ pendingTools : [AgentTool] @description "The ephemeral conversation's own tools, carried through a summarizing." = []
24
+ pendingEphemeral : boolean @description "The conversation being compacted is ephemeral." = false
17
25
  }
18
26
 
19
27
  trait AgentContextCompactor -> AgentContextWindow [interaction] {
@@ -31,10 +39,13 @@ orbital AgentContextOrbital {
31
39
  (set @entity.lastSize 0)
32
40
  COMPACT -> ready when (<= (array/len ?messages) @config.keepMessages)
33
41
  (set @entity.lastSize (array/len ?messages))
34
- (emit COMPACTED { messages: ?messages })
42
+ (emit COMPACTED { messages: ?messages, instructions: (str/default ?instructions ""), tools: (object/get ? tools []), ephemeral: (if ?ephemeral true false) })
35
43
  COMPACT -> summarizing when (> (array/len ?messages) @config.keepMessages)
36
44
  (set @entity.lastSize (array/len ?messages))
37
45
  (set @entity.pendingMessages ?messages)
46
+ (set @entity.pendingInstructions (str/default ?instructions ""))
47
+ (set @entity.pendingTools (object/get ? tools []))
48
+ (set @entity.pendingEphemeral (if ?ephemeral true false))
38
49
  (call-service llm summarize {
39
50
  text: (str/join (array/map (array/dropLast ?messages @config.keepMessages) (fn item (str/concat @item.role ": " @item.content))) "\n")
40
51
  } {
@@ -46,9 +57,12 @@ orbital AgentContextOrbital {
46
57
  ContextSummarized -> ready
47
58
  (emit COMPACTED {
48
59
  messages: (array/prepend (array/takeLast @entity.pendingMessages @config.keepMessages) { role: assistant, content: (str/concat "Earlier in this conversation: " ?summary) })
60
+ instructions: @entity.pendingInstructions
61
+ tools: @entity.pendingTools
62
+ ephemeral: @entity.pendingEphemeral
49
63
  })
50
64
  ContextSummarizeFailed -> ready
51
- (emit COMPACTED { messages: (array/takeLast @entity.pendingMessages @config.keepMessages) })
65
+ (emit COMPACTED { messages: (array/takeLast @entity.pendingMessages @config.keepMessages), instructions: @entity.pendingInstructions, tools: @entity.pendingTools, ephemeral: @entity.pendingEphemeral })
52
66
  (render-ui toast {
53
67
  message: ?error
54
68
  type: alert
@@ -59,8 +73,11 @@ orbital AgentContextOrbital {
59
73
  emits {
60
74
  COMPACTED -> external {
61
75
  messages : [AgentChatMessage]!
76
+ instructions : string
77
+ tools : [AgentTool]
78
+ ephemeral : boolean
62
79
  }
63
- @description "The conversation, bounded: recent turns verbatim, older turns as one summary note."
80
+ @description "The conversation, bounded: recent turns verbatim, older turns as one summary note. An ephemeral conversation's own `instructions`, `tools` and `ephemeral` flag pass through untouched."
64
81
  @synonyms "compacted, trimmed, bounded"
65
82
  @tier "domain"
66
83
  ContextSummarized -> internal {
@@ -77,8 +94,11 @@ orbital AgentContextOrbital {
77
94
  listens {
78
95
  COMPACT {
79
96
  messages : [AgentChatMessage]!
97
+ instructions : string
98
+ tools : [AgentTool]
99
+ ephemeral : boolean
80
100
  }
81
- @description "Bound this conversation for the model."
101
+ @description "Bound this conversation for the model. An ephemeral conversation's own `instructions`, `tools` and `ephemeral` flag ride along."
82
102
  }
83
103
  }
84
104
 
@@ -5,6 +5,11 @@ type AgentChatMessage = {
5
5
  role : "user" | "assistant"
6
6
  content : string!
7
7
  }
8
+ type AgentTool = {
9
+ event : event
10
+ read : string
11
+ scope : "declared"
12
+ }
8
13
  type AgentMemoryRow = {
9
14
  id : string!
10
15
  content : string!
@@ -56,7 +61,9 @@ orbital AgentMemoryOrbital {
56
61
  type: alert
57
62
  variant: error
58
63
  })
59
- RECALL -> recalling
64
+ RECALL -> ready when ?ephemeral
65
+ (emit RECALLED { messages: ?messages, context: "", instructions: (str/default ?instructions ""), tools: (object/get ? tools []), ephemeral: true })
66
+ RECALL -> recalling when (not ?ephemeral)
60
67
  (set @entity.pendingMessages ?messages)
61
68
  (set @entity.pendingQuery (object/get (array/last ?messages) content))
62
69
  (call-service llm embed {
@@ -64,7 +71,8 @@ orbital AgentMemoryOrbital {
64
71
  } {
65
72
  emit: { failure: MemoryEmbedFailed, success: MemoryEmbedded }
66
73
  })
67
- REMEMBER -> remembering
74
+ REMEMBER -> ready when ?ephemeral
75
+ REMEMBER -> remembering when (not ?ephemeral)
68
76
  (set @entity.pendingContent (str/concat "Asked: " @entity.pendingQuery " | Answered: " ?reply))
69
77
  (call-service llm embed {
70
78
  texts: [(str/concat "Asked: " @entity.pendingQuery " | Answered: " ?reply)]
@@ -122,8 +130,11 @@ orbital AgentMemoryOrbital {
122
130
  RECALLED -> external {
123
131
  messages : [AgentChatMessage]!
124
132
  context : string
133
+ instructions : string
134
+ tools : [AgentTool]
135
+ ephemeral : boolean
125
136
  }
126
- @description "The conversation, with what the assistant remembers that is closest to its last turn."
137
+ @description "The conversation, with what the assistant remembers that is closest to its last turn. An ephemeral conversation is never recalled for: empty `context`, its own `instructions`, `tools` and `ephemeral` flag pass through."
127
138
  @synonyms "recalled, remembered, context ready"
128
139
  @tier "domain"
129
140
  ASSISTANT_MEMORIES_LOADED -> external {
@@ -171,12 +182,16 @@ orbital AgentMemoryOrbital {
171
182
  @description "List what the assistant remembers for this person."
172
183
  RECALL {
173
184
  messages : [AgentChatMessage]!
185
+ instructions : string
186
+ tools : [AgentTool]
187
+ ephemeral : boolean
174
188
  }
175
- @description "Recall what is relevant to this conversation's last turn."
189
+ @description "Recall what is relevant to this conversation's last turn. An ephemeral conversation skips the recall."
176
190
  REMEMBER {
177
191
  reply : string!
192
+ ephemeral : boolean
178
193
  }
179
- @description "Remember the exchange just answered."
194
+ @description "Remember the exchange just answered. An ephemeral conversation is never remembered."
180
195
  }
181
196
  }
182
197
 
@@ -0,0 +1,550 @@
1
+ app std-agent-proposal "1.0.0"
2
+ "std-agent-proposal — an agent that reads what the person hands over, works out a structured proposal, and commits nothing until they approve it. The app starts it with PROPOSAL_REQUESTED { input, context } (any trait emitting it, or the person typing into the start form when `showInputForm` is on). A second std-agent-tool-loop answers with `instructions`, `prompt` and `tools` as the signed-in person — `quiet`, its reply and failure renamed PROPOSAL_LOOP_REPLIED / PROPOSAL_LOOP_FAILED so they never reach the assistant's chat — and submits its proposal through one declared input, PROPOSE (its @description is the tool text): a summary and a list of items, each a flat map of scalar values the app names. The person reviews it (the summary, the items drawn with `itemPattern` and `itemFields`) and chooses: Approve emits PROPOSAL_APPROVED { proposal } for the app to commit (the app owns the commit; this atom writes nothing); Revise sends their written feedback back to the agent, which proposes again; Discard emits PROPOSAL_DISCARDED. Cancel while the agent works aborts its model call and emits PROPOSAL_CANCELLED. A run that fails, or ends without proposing, shows its error with Retry and Discard. The panel renders into `panelSlot`. Import the orbital once per app: `orbital Proposal = Proposal.orbitals.AgentProposalOrbital { config { instructions: \"…\", prompt: \"…\", itemFields: […] } }`, restating `tools` with PROPOSE addressed by its local orbital name (`{ event: Proposal.AgentProposalWorkflow.PROPOSE }`). Instructions, prompts, item fields and labels are the app's vocabulary, declared in config."
3
+ ;; @capabilities "agent proposal, review before commit, human approval of agent output, approve or revise agent suggestions, structured proposal review, ai drafts for approval, extract then confirm"
4
+
5
+ type AgentTool = {
6
+ event : event
7
+ read : string
8
+ scope : "declared"
9
+ }
10
+ type AgentChatMessage = {
11
+ role : "user" | "assistant"
12
+ content : string!
13
+ }
14
+ type ProposalField = {
15
+ name : string!
16
+ label : string
17
+ variant : string
18
+ }
19
+ type ProposalPayload = {
20
+ summary : string
21
+ items : [Map string scalar]
22
+ }
23
+
24
+ orbital AgentProposalOrbital {
25
+ uses Loop from "std/behaviors/std-agent-tool-loop"
26
+
27
+ config {
28
+ instructions : string = "You turn what the person hands over into one structured proposal. Look things up with the tools if you need to, then call the proposal tool exactly once with a short summary and the list of items. Do not call it again unless asked to revise."
29
+ @label "How should the agent behave?"
30
+ @description "Standing instructions sent with every run."
31
+ @synonyms "system prompt, persona, guidance"
32
+ @tier "domain"
33
+ prompt : string = "Work out a proposal from the following."
34
+ @label "What is the agent asked to do?"
35
+ @description "The request that precedes the person's input in every run."
36
+ @synonyms "task, goal, brief, question"
37
+ @tier "domain"
38
+ tools : [AgentTool] = [{ event: AgentProposalWorkflow.PROPOSE }]
39
+ @label "What may the agent do?"
40
+ @description "The declared inputs it may fire and the entities it may read, as the signed-in person. An importing app restates the list with PROPOSE addressed by its local orbital name, which the agent can never propose without."
41
+ @synonyms "allowlist, abilities, permissions"
42
+ @tier "domain"
43
+ maxSteps : number = 8
44
+ @label "Model round-trips per run"
45
+ @tier "policy"
46
+ itemPattern : pattern = data-list
47
+ @label "How are the proposed items drawn?"
48
+ @description "The pattern the review renders the items with; it receives `entity` (the items) and `fields`."
49
+ @synonyms "item layout, list pattern, table"
50
+ @tier "presentation"
51
+ itemFields : [ProposalField] = []
52
+ @label "Which item values are shown?"
53
+ @description "The item keys to show, each `{ name, label, variant }`."
54
+ @synonyms "columns, fields, attributes"
55
+ @tier "domain"
56
+ showInputForm : boolean = true
57
+ @label "Show a start form?"
58
+ @description "On, the idle panel lets the person type what the agent works from. Off, the panel renders nothing until the app starts it with PROPOSAL_REQUESTED."
59
+ @synonyms "start form, input box, manual start"
60
+ @tier "presentation"
61
+ title : string = "Proposal"
62
+ @label "Panel heading"
63
+ @tier "presentation"
64
+ icon : string = sparkles
65
+ @label "Panel icon"
66
+ @tier "presentation"
67
+ inputLabel : string = "What should the agent work from?"
68
+ @label "Start form label"
69
+ @tier "presentation"
70
+ startLabel : string = "Propose"
71
+ @label "Start button"
72
+ @tier "presentation"
73
+ workingLabel : string = "Working out a proposal…"
74
+ @label "While the agent works"
75
+ @tier "presentation"
76
+ summaryHeading : string = Summary
77
+ @label "Summary heading"
78
+ @tier "presentation"
79
+ itemsHeading : string = Items
80
+ @label "Items heading"
81
+ @tier "presentation"
82
+ feedbackLabel : string = "What should change?"
83
+ @label "Revision feedback label"
84
+ @tier "presentation"
85
+ approveLabel : string = Approve
86
+ @label "Approve button"
87
+ @tier "presentation"
88
+ reviseLabel : string = Revise
89
+ @label "Revise button"
90
+ @tier "presentation"
91
+ discardLabel : string = Discard
92
+ @label "Discard button"
93
+ @tier "presentation"
94
+ cancelLabel : string = Cancel
95
+ @label "Cancel button"
96
+ @tier "presentation"
97
+ retryLabel : string = Retry
98
+ @label "Retry button"
99
+ @tier "presentation"
100
+ panelSlot : slot = main
101
+ @label "Where the panel renders"
102
+ @description "`main` for the content of a page or launcher; `modal` or `drawer` for an overlay."
103
+ @tier "presentation"
104
+ }
105
+
106
+ entity AgentProposalRun [runtime] {
107
+ id : string!
108
+ input : string @description "What the person handed over." = ""
109
+ context : string @description "Extra background the app handed over." = ""
110
+ request : string @description "The request the agent is answering, with any revision feedback." = ""
111
+ feedback : string @description "What the person asked to change." = ""
112
+ summary : string @description "The proposal in a few lines." = ""
113
+ items : [Map string scalar] @description "The proposed items." = []
114
+ error : string @description "Why the last run failed." = ""
115
+ }
116
+
117
+ trait AgentProposalWorkflow -> AgentProposalRun [interaction] {
118
+ config {
119
+ heading : string = @config.title
120
+ @label "Panel heading"
121
+ @tier "presentation"
122
+ headingIcon : string = @config.icon
123
+ @label "Panel icon"
124
+ @tier "presentation"
125
+ framing : string = @config.prompt
126
+ @label "What is the agent asked to do?"
127
+ @description "The request that precedes the person's input."
128
+ @synonyms "task, goal, brief"
129
+ @tier "domain"
130
+ slot : slot = @config.panelSlot
131
+ @label "Where the panel renders"
132
+ @tier "internal"
133
+ withInputForm : boolean = @config.showInputForm
134
+ @label "Show a start form?"
135
+ @tier "presentation"
136
+ patternForItems : pattern = @config.itemPattern
137
+ @label "How are the proposed items drawn?"
138
+ @tier "presentation"
139
+ fieldsForItems : [ProposalField] = @config.itemFields
140
+ @label "Which item values are shown?"
141
+ @tier "domain"
142
+ inputText : string = @config.inputLabel
143
+ @label "Start form label"
144
+ @tier "presentation"
145
+ startButton : string = @config.startLabel
146
+ @label "Start button"
147
+ @tier "presentation"
148
+ workingText : string = @config.workingLabel
149
+ @label "While the agent works"
150
+ @tier "presentation"
151
+ summaryTitle : string = @config.summaryHeading
152
+ @label "Summary heading"
153
+ @tier "presentation"
154
+ itemsTitle : string = @config.itemsHeading
155
+ @label "Items heading"
156
+ @tier "presentation"
157
+ feedbackText : string = @config.feedbackLabel
158
+ @label "Revision feedback label"
159
+ @tier "presentation"
160
+ approveButton : string = @config.approveLabel
161
+ @label "Approve button"
162
+ @tier "presentation"
163
+ reviseButton : string = @config.reviseLabel
164
+ @label "Revise button"
165
+ @tier "presentation"
166
+ discardButton : string = @config.discardLabel
167
+ @label "Discard button"
168
+ @tier "presentation"
169
+ cancelButton : string = @config.cancelLabel
170
+ @label "Cancel button"
171
+ @tier "presentation"
172
+ retryButton : string = @config.retryLabel
173
+ @label "Retry button"
174
+ @tier "presentation"
175
+ }
176
+ initial: idle
177
+
178
+ state idle {
179
+ PROPOSE -> idle
180
+ INIT -> idle when @config.withInputForm
181
+ (render-ui @config.slot {
182
+ children: [{
183
+ align: center
184
+ children: [{ name: @config.headingIcon, size: lg, type: icon }, {
185
+ content: @config.heading
186
+ type: typography
187
+ variant: h3
188
+ }]
189
+ direction: horizontal
190
+ gap: sm
191
+ type: stack
192
+ }, { type: divider }, {
193
+ label: @config.inputText
194
+ onChange: INPUT_CHANGED
195
+ rows: 6
196
+ type: textarea
197
+ }, {
198
+ action: START_TYPED
199
+ icon: sparkles
200
+ label: @config.startButton
201
+ type: button
202
+ variant: primary
203
+ }]
204
+ direction: vertical
205
+ gap: md
206
+ type: stack
207
+ })
208
+ INIT -> idle when (not @config.withInputForm)
209
+ INPUT_CHANGED -> idle
210
+ (set @entity.input ?value)
211
+ CLOSE -> idle
212
+ (render-ui @config.slot null)
213
+ START_TYPED -> working when (!= (str/default @entity.input "") "")
214
+ (set @entity.context "")
215
+ (set @entity.request (str/concat @config.framing "\n\n" @entity.input))
216
+ (set @entity.feedback "")
217
+ (emit PROPOSAL_RUN_REQUESTED { messages: [{ role: user, content: @entity.request }] })
218
+ (render-ui @config.slot {
219
+ children: [{
220
+ align: center
221
+ children: [{ size: sm, type: spinner }, {
222
+ color: muted
223
+ content: @config.workingText
224
+ type: typography
225
+ variant: caption
226
+ }]
227
+ direction: horizontal
228
+ gap: sm
229
+ role: status
230
+ type: stack
231
+ }, {
232
+ action: CANCEL
233
+ icon: x
234
+ label: @config.cancelButton
235
+ type: button
236
+ variant: ghost
237
+ }]
238
+ direction: vertical
239
+ gap: md
240
+ type: stack
241
+ })
242
+ PROPOSAL_REQUESTED -> working
243
+ (set @entity.input ?input)
244
+ (set @entity.context (str/default ?context ""))
245
+ (set @entity.request (if ["=", (str/default ?context ""), ""] (str/concat @config.framing "\n\n" ?input) (str/concat @config.framing "\n\n" ?input "\n\nBackground:\n" ?context)))
246
+ (set @entity.feedback "")
247
+ (emit PROPOSAL_RUN_REQUESTED { messages: [{ role: user, content: @entity.request }] })
248
+ (render-ui @config.slot {
249
+ children: [{
250
+ align: center
251
+ children: [{ size: sm, type: spinner }, {
252
+ color: muted
253
+ content: @config.workingText
254
+ type: typography
255
+ variant: caption
256
+ }]
257
+ direction: horizontal
258
+ gap: sm
259
+ role: status
260
+ type: stack
261
+ }, {
262
+ action: CANCEL
263
+ icon: x
264
+ label: @config.cancelButton
265
+ type: button
266
+ variant: ghost
267
+ }]
268
+ direction: vertical
269
+ gap: md
270
+ type: stack
271
+ })
272
+ }
273
+
274
+ state working {
275
+ PROPOSE -> review
276
+ (set @entity.summary (str/default ?summary ""))
277
+ (set @entity.items ?items)
278
+ (render-ui @config.slot {
279
+ children: [{
280
+ align: center
281
+ children: [{ name: @config.headingIcon, size: lg, type: icon }, {
282
+ content: @config.heading
283
+ type: typography
284
+ variant: h3
285
+ }]
286
+ direction: horizontal
287
+ gap: sm
288
+ type: stack
289
+ }, { type: divider }, {
290
+ content: @config.summaryTitle
291
+ type: typography
292
+ variant: h4
293
+ }, {
294
+ content: @entity.summary
295
+ type: typography
296
+ variant: body
297
+ }, {
298
+ content: @config.itemsTitle
299
+ type: typography
300
+ variant: h4
301
+ }, {
302
+ entity: @entity.items
303
+ fields: @config.fieldsForItems
304
+ gap: sm
305
+ type: @config.patternForItems
306
+ }, { type: divider }, {
307
+ label: @config.feedbackText
308
+ onChange: FEEDBACK_CHANGED
309
+ rows: 3
310
+ type: textarea
311
+ }, {
312
+ align: center
313
+ children: [{
314
+ action: APPROVE
315
+ icon: check
316
+ label: @config.approveButton
317
+ type: button
318
+ variant: primary
319
+ }, {
320
+ action: REVISE
321
+ icon: refresh-cw
322
+ label: @config.reviseButton
323
+ type: button
324
+ variant: secondary
325
+ }, {
326
+ action: DISCARD
327
+ icon: x
328
+ label: @config.discardButton
329
+ type: button
330
+ variant: ghost
331
+ }]
332
+ direction: horizontal
333
+ gap: sm
334
+ type: stack
335
+ wrap: true
336
+ }]
337
+ direction: vertical
338
+ gap: md
339
+ type: stack
340
+ })
341
+ PROPOSAL_LOOP_REPLIED -> failed
342
+ (set @entity.error "The agent finished without making a proposal.")
343
+ (render-ui @config.slot {
344
+ children: [{
345
+ message: @entity.error
346
+ type: alert
347
+ variant: error
348
+ }, {
349
+ align: center
350
+ children: [{
351
+ action: RETRY
352
+ icon: refresh-cw
353
+ label: @config.retryButton
354
+ type: button
355
+ variant: primary
356
+ }, {
357
+ action: DISCARD
358
+ icon: x
359
+ label: @config.discardButton
360
+ type: button
361
+ variant: ghost
362
+ }]
363
+ direction: horizontal
364
+ gap: sm
365
+ type: stack
366
+ }]
367
+ direction: vertical
368
+ gap: md
369
+ type: stack
370
+ })
371
+ PROPOSAL_LOOP_FAILED -> failed
372
+ (set @entity.error ?error)
373
+ (render-ui @config.slot {
374
+ children: [{
375
+ message: @entity.error
376
+ type: alert
377
+ variant: error
378
+ }, {
379
+ align: center
380
+ children: [{
381
+ action: RETRY
382
+ icon: refresh-cw
383
+ label: @config.retryButton
384
+ type: button
385
+ variant: primary
386
+ }, {
387
+ action: DISCARD
388
+ icon: x
389
+ label: @config.discardButton
390
+ type: button
391
+ variant: ghost
392
+ }]
393
+ direction: horizontal
394
+ gap: sm
395
+ type: stack
396
+ }]
397
+ direction: vertical
398
+ gap: md
399
+ type: stack
400
+ })
401
+ CANCEL -> idle when (== @config.slot main)
402
+ (emit PROPOSAL_CANCELLED {})
403
+ CANCEL -> idle when (!= @config.slot main)
404
+ (emit PROPOSAL_CANCELLED {})
405
+ (render-ui @config.slot null)
406
+ CLOSE -> idle
407
+ (emit PROPOSAL_CANCELLED {})
408
+ (render-ui @config.slot null)
409
+ }
410
+
411
+ state review {
412
+ FEEDBACK_CHANGED -> review
413
+ (set @entity.feedback ?value)
414
+ PROPOSE -> review
415
+ (set @entity.summary (str/default ?summary ""))
416
+ (set @entity.items ?items)
417
+ APPROVE -> idle when (== @config.slot main)
418
+ (emit PROPOSAL_APPROVED { proposal: { summary: @entity.summary, items: @entity.items } })
419
+ APPROVE -> idle when (!= @config.slot main)
420
+ (emit PROPOSAL_APPROVED { proposal: { summary: @entity.summary, items: @entity.items } })
421
+ (render-ui @config.slot null)
422
+ REVISE -> working when (!= (str/default @entity.feedback "") "")
423
+ (set @entity.request (str/concat @entity.request "\n\nYour earlier proposal:\n" (json/stringify { summary: @entity.summary, items: @entity.items }) "\n\nRevise it: " @entity.feedback))
424
+ (emit PROPOSAL_RUN_REQUESTED { messages: [{ role: user, content: @entity.request }] })
425
+ (set @entity.feedback "")
426
+ REVISE -> review when (= (str/default @entity.feedback "") "")
427
+ (notify warning "Say what should change before asking for a revision.")
428
+ DISCARD -> idle when (== @config.slot main)
429
+ (emit PROPOSAL_DISCARDED {})
430
+ DISCARD -> idle when (!= @config.slot main)
431
+ (emit PROPOSAL_DISCARDED {})
432
+ (render-ui @config.slot null)
433
+ CLOSE -> idle
434
+ (emit PROPOSAL_DISCARDED {})
435
+ (render-ui @config.slot null)
436
+ }
437
+
438
+ state failed {
439
+ RETRY -> working
440
+ (emit PROPOSAL_RUN_REQUESTED { messages: [{ role: user, content: @entity.request }] })
441
+ DISCARD -> idle when (== @config.slot main)
442
+ (emit PROPOSAL_DISCARDED {})
443
+ DISCARD -> idle when (!= @config.slot main)
444
+ (emit PROPOSAL_DISCARDED {})
445
+ (render-ui @config.slot null)
446
+ CLOSE -> idle
447
+ (emit PROPOSAL_DISCARDED {})
448
+ (render-ui @config.slot null)
449
+ }
450
+
451
+ emits {
452
+ PROPOSAL_APPROVED -> external {
453
+ proposal : ProposalPayload!
454
+ }
455
+ @description "The person approved the proposal as it stands. The app commits it; nothing has been written."
456
+ @synonyms "approved, accepted, confirmed, go ahead, commit"
457
+ @tier "domain"
458
+ PROPOSAL_DISCARDED -> external {
459
+ }
460
+ @description "The person discarded the proposal (or a failed run); nothing was committed."
461
+ @synonyms "rejected, dismissed, thrown away"
462
+ @tier "domain"
463
+ PROPOSAL_CANCELLED -> external {
464
+ }
465
+ @description "The person cancelled while the agent was still working; its model call was aborted."
466
+ @synonyms "stopped, aborted"
467
+ @tier "domain"
468
+ PROPOSAL_RUN_REQUESTED -> external {
469
+ messages : [AgentChatMessage]!
470
+ }
471
+ @description "The agent was asked to work out (or revise) a proposal."
472
+ @synonyms "run started, working"
473
+ @tier "domain"
474
+ }
475
+
476
+ listens {
477
+ PROPOSAL_REQUESTED {
478
+ input : string!
479
+ context : string
480
+ }
481
+ @description "Work out a proposal from this: the documents or text the person handed over, and optional background."
482
+ @synonyms "start, propose, analyze, extract, begin"
483
+ PROPOSE -> external {
484
+ summary : string
485
+ items : [Map string scalar]!
486
+ }
487
+ @description "Submit the proposal for the person to review: a short summary and the list of proposed items, each a flat map of values. Call it once with everything; the person approves, asks for a revision, or discards it."
488
+ @synonyms "propose, submit proposal, draft"
489
+ INPUT_CHANGED {
490
+ value : string
491
+ }
492
+ @description "The start form's text changed."
493
+ FEEDBACK_CHANGED {
494
+ value : string
495
+ }
496
+ @description "The revision feedback changed."
497
+ AgentProposalLoop.PROPOSAL_LOOP_REPLIED -> PROPOSAL_LOOP_REPLIED
498
+ AgentProposalLoop.PROPOSAL_LOOP_FAILED -> PROPOSAL_LOOP_FAILED
499
+ PROPOSAL_LOOP_REPLIED {
500
+ reply : string
501
+ }
502
+ @description "The agent's run ended."
503
+ PROPOSAL_LOOP_FAILED {
504
+ error : string
505
+ }
506
+ @description "The agent's run failed."
507
+ CANCEL {
508
+ }
509
+ @description "Cancel the agent's work."
510
+ CLOSE {
511
+ }
512
+ @description "The overlay's own close control was used: cancels the agent's work while it runs, discards the proposal otherwise."
513
+ APPROVE {
514
+ }
515
+ @description "Approve the proposal."
516
+ REVISE {
517
+ }
518
+ @description "Ask for a revision with the written feedback."
519
+ DISCARD {
520
+ }
521
+ @description "Discard the proposal."
522
+ RETRY {
523
+ }
524
+ @description "Run the agent again."
525
+ START_TYPED {
526
+ }
527
+ @description "Start from the text typed into the start form."
528
+ }
529
+ }
530
+
531
+ trait AgentProposalLoop = Loop.traits.AgentToolLoop {
532
+ config {
533
+ tools: @config.tools
534
+ instructions: @config.instructions
535
+ maxSteps: @config.maxSteps
536
+ quiet: true
537
+ cancelKey: "agent-proposal"
538
+ }
539
+ events {
540
+ ASSISTANT_REPLIED: PROPOSAL_LOOP_REPLIED
541
+ ASSISTANT_REPLY_FAILED: PROPOSAL_LOOP_FAILED
542
+ }
543
+ listens {
544
+ AgentProposalWorkflow.PROPOSAL_RUN_REQUESTED -> CONVERSE
545
+ AgentProposalWorkflow.PROPOSAL_CANCELLED -> CANCEL
546
+ }
547
+ }
548
+
549
+ page "/agent-proposal" as AgentProposalPage -> AgentProposalWorkflow, AgentProposalLoop
550
+ }