@almadar/std 16.239.0 → 16.242.0

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 (167) hide show
  1. package/behaviors/behaviors-registry.json +4814 -553
  2. package/behaviors/lolo/agent/atoms/std-agent-memory.lolo +38 -1
  3. package/behaviors/lolo/agent/atoms/std-agent-session.lolo +1074 -47
  4. package/behaviors/lolo/agent/atoms/std-agent-tool-loop.lolo +8 -7
  5. package/behaviors/lolo/agent/organisms/std-agent-assistant.lolo +56 -37
  6. package/behaviors/lolo/infra/atoms/std-page-open.lolo +59 -0
  7. package/behaviors/lolo/infra/atoms/std-page-search.lolo +134 -0
  8. package/behaviors/lolo/infra/atoms/std-page-treat.lolo +59 -0
  9. package/behaviors/lolo/infra/atoms/std-page-watch.lolo +86 -0
  10. package/behaviors/lolo/ui/core/atoms/std-board.lolo +53 -6
  11. package/behaviors/lolo/ui/core/atoms/std-book-reader.lolo +25 -1
  12. package/behaviors/lolo/ui/core/atoms/std-card-grid.lolo +9 -0
  13. package/behaviors/lolo/ui/core/atoms/std-doc-page.lolo +153 -0
  14. package/behaviors/lolo/ui/core/atoms/std-site-header.lolo +15 -3
  15. package/behaviors/lolo/ui/core/atoms/std-tag-strip.lolo +2 -2
  16. package/behaviors/lolo/ui/core/atoms/std-tag-taxonomy.lolo +7 -7
  17. package/behaviors/lolo/ui/core/atoms/std-version-history.lolo +1 -1
  18. package/behaviors/lolo/ui/core/molecules/ui-header.lolo +5 -0
  19. package/behaviors/lolo/ui/learning/atoms/std-learn-arrangement.lolo +124 -92
  20. package/behaviors/lolo/ui/learning/atoms/std-learn-classify.lolo +114 -55
  21. package/behaviors/lolo/ui/learning/atoms/std-learn-compare.lolo +40 -14
  22. package/behaviors/lolo/ui/learning/atoms/std-learn-coupled-sim.lolo +363 -123
  23. package/behaviors/lolo/ui/learning/atoms/std-learn-derivation.lolo +93 -48
  24. package/behaviors/lolo/ui/learning/atoms/std-learn-diagram.lolo +60 -28
  25. package/behaviors/lolo/ui/learning/atoms/std-learn-doser.lolo +193 -96
  26. package/behaviors/lolo/ui/learning/atoms/std-learn-estimate.lolo +75 -32
  27. package/behaviors/lolo/ui/learning/atoms/std-learn-goal-seek.lolo +142 -86
  28. package/behaviors/lolo/ui/learning/atoms/std-learn-grid-sim.lolo +266 -98
  29. package/behaviors/lolo/ui/learning/atoms/std-learn-hotspot.lolo +103 -65
  30. package/behaviors/lolo/ui/learning/atoms/std-learn-live-sim.lolo +223 -109
  31. package/behaviors/lolo/ui/learning/atoms/std-learn-measure.lolo +232 -64
  32. package/behaviors/lolo/ui/learning/atoms/std-learn-param-explorer.lolo +69 -29
  33. package/behaviors/lolo/ui/learning/atoms/std-learn-perturb.lolo +363 -123
  34. package/behaviors/lolo/ui/learning/atoms/std-learn-predict.lolo +73 -41
  35. package/behaviors/lolo/ui/learning/atoms/std-learn-sample-accumulator.lolo +96 -38
  36. package/behaviors/lolo/ui/learning/atoms/std-learn-sandbox.lolo +65 -45
  37. package/behaviors/lolo/ui/learning/atoms/std-learn-scatter-fit.lolo +243 -117
  38. package/behaviors/lolo/ui/learning/atoms/std-learn-scenario.lolo +76 -28
  39. package/behaviors/lolo/ui/learning/atoms/std-learn-sim-3d.lolo +228 -109
  40. package/behaviors/lolo/ui/learning/atoms/std-learn-speed-drill.lolo +95 -44
  41. package/behaviors/lolo/ui/learning/atoms/std-learn-stepper.lolo +199 -125
  42. package/behaviors/lolo/ui/learning/atoms/std-learn-tour-3d.lolo +92 -48
  43. package/behaviors/lolo/ui/learning/atoms/std-learn-trace-player.lolo +239 -78
  44. package/behaviors/lolo/ui/learning/atoms/std-learn-transport.lolo +147 -38
  45. package/behaviors/lolo/ui/learning/atoms/std-learn-tree.lolo +123 -58
  46. package/behaviors/lolo/ui/learning/atoms/ui-algo-graph-canvas.lolo +22 -0
  47. package/behaviors/lolo/ui/learning/atoms/ui-algorithm-canvas.lolo +26 -0
  48. package/behaviors/lolo/ui/learning/atoms/ui-biology-canvas.lolo +26 -0
  49. package/behaviors/lolo/ui/learning/atoms/ui-chemistry-canvas.lolo +27 -1
  50. package/behaviors/lolo/ui/learning/atoms/ui-learning-canvas.lolo +27 -1
  51. package/behaviors/lolo/ui/learning/atoms/ui-math-canvas.lolo +29 -9
  52. package/behaviors/lolo/ui/learning/atoms/ui-physics-canvas.lolo +26 -0
  53. package/behaviors/lolo-behavior-contracts.json +1 -1
  54. package/behaviors/registry/agent/atoms/std-agent-memory.orb +372 -2
  55. package/behaviors/registry/agent/atoms/std-agent-session.orb +4752 -348
  56. package/behaviors/registry/agent/atoms/std-agent-tool-loop.orb +54 -42
  57. package/behaviors/registry/agent/organisms/std-agent-assistant.orb +356 -122
  58. package/behaviors/registry/factory-signatures.json +1 -1
  59. package/behaviors/registry/infra/atoms/std-page-open.orb +435 -0
  60. package/behaviors/registry/infra/atoms/std-page-search.orb +867 -0
  61. package/behaviors/registry/infra/atoms/std-page-treat.orb +494 -0
  62. package/behaviors/registry/infra/atoms/std-page-watch.orb +554 -0
  63. package/behaviors/registry/ui/core/atoms/std-board.orb +110 -14
  64. package/behaviors/registry/ui/core/atoms/std-book-reader.orb +119 -0
  65. package/behaviors/registry/ui/core/atoms/std-card-grid.orb +61 -0
  66. package/behaviors/registry/ui/core/atoms/std-doc-page.orb +594 -0
  67. package/behaviors/registry/ui/core/atoms/std-site-header.orb +40 -2
  68. package/behaviors/registry/ui/core/atoms/std-tag-strip.orb +2 -0
  69. package/behaviors/registry/ui/core/atoms/std-tag-taxonomy.orb +24 -0
  70. package/behaviors/registry/ui/core/atoms/std-version-history.orb +8 -1
  71. package/behaviors/registry/ui/core/molecules/ui-header.orb +7 -0
  72. package/behaviors/registry/ui/learning/atoms/std-learn-arrangement.orb +903 -369
  73. package/behaviors/registry/ui/learning/atoms/std-learn-classify.orb +1002 -232
  74. package/behaviors/registry/ui/learning/atoms/std-learn-compare.orb +253 -74
  75. package/behaviors/registry/ui/learning/atoms/std-learn-coupled-sim.orb +3624 -921
  76. package/behaviors/registry/ui/learning/atoms/std-learn-derivation.orb +685 -144
  77. package/behaviors/registry/ui/learning/atoms/std-learn-diagram.orb +404 -52
  78. package/behaviors/registry/ui/learning/atoms/std-learn-doser.orb +1787 -210
  79. package/behaviors/registry/ui/learning/atoms/std-learn-estimate.orb +699 -71
  80. package/behaviors/registry/ui/learning/atoms/std-learn-goal-seek.orb +1102 -578
  81. package/behaviors/registry/ui/learning/atoms/std-learn-grid-sim.orb +2760 -872
  82. package/behaviors/registry/ui/learning/atoms/std-learn-hotspot.orb +689 -152
  83. package/behaviors/registry/ui/learning/atoms/std-learn-live-sim.orb +1431 -633
  84. package/behaviors/registry/ui/learning/atoms/std-learn-measure.orb +2485 -512
  85. package/behaviors/registry/ui/learning/atoms/std-learn-param-explorer.orb +501 -197
  86. package/behaviors/registry/ui/learning/atoms/std-learn-perturb.orb +3642 -928
  87. package/behaviors/registry/ui/learning/atoms/std-learn-predict.orb +705 -125
  88. package/behaviors/registry/ui/learning/atoms/std-learn-sample-accumulator.orb +624 -114
  89. package/behaviors/registry/ui/learning/atoms/std-learn-sandbox.orb +405 -153
  90. package/behaviors/registry/ui/learning/atoms/std-learn-scatter-fit.orb +1911 -611
  91. package/behaviors/registry/ui/learning/atoms/std-learn-scenario.orb +436 -128
  92. package/behaviors/registry/ui/learning/atoms/std-learn-sim-3d.orb +2482 -485
  93. package/behaviors/registry/ui/learning/atoms/std-learn-speed-drill.orb +896 -192
  94. package/behaviors/registry/ui/learning/atoms/std-learn-stepper.orb +2001 -759
  95. package/behaviors/registry/ui/learning/atoms/std-learn-tour-3d.orb +734 -228
  96. package/behaviors/registry/ui/learning/atoms/std-learn-trace-player.orb +2501 -764
  97. package/behaviors/registry/ui/learning/atoms/std-learn-transport.orb +1591 -173
  98. package/behaviors/registry/ui/learning/atoms/std-learn-tree.orb +883 -122
  99. package/behaviors/registry/ui/learning/atoms/ui-algo-graph-canvas.orb +176 -0
  100. package/behaviors/registry/ui/learning/atoms/ui-algorithm-canvas.orb +211 -0
  101. package/behaviors/registry/ui/learning/atoms/ui-biology-canvas.orb +211 -0
  102. package/behaviors/registry/ui/learning/atoms/ui-chemistry-canvas.orb +212 -1
  103. package/behaviors/registry/ui/learning/atoms/ui-learning-canvas.orb +212 -1
  104. package/behaviors/registry/ui/learning/atoms/ui-math-canvas.orb +203 -9
  105. package/behaviors/registry/ui/learning/atoms/ui-physics-canvas.orb +211 -0
  106. package/behaviors/signatures.lolo +325 -655
  107. package/canonical-operators.json +35 -1
  108. package/dist/behaviors/exports-reader.js +41980 -35508
  109. package/dist/behaviors/functions/index.d.ts +1063 -140
  110. package/dist/behaviors/functions/index.js +41951 -35506
  111. package/dist/behaviors/index.d.ts +1 -1
  112. package/dist/behaviors/index.js +41981 -35509
  113. package/dist/behaviors/query.js +41980 -35508
  114. package/dist/behaviors-embeddings.hash.json +3 -3
  115. package/dist/behaviors-embeddings.json +47 -27
  116. package/dist/behaviors-registry.json +4814 -553
  117. package/dist/index.d.ts +4 -4
  118. package/dist/index.js +42019 -35509
  119. package/dist/knob-embeddings.hash.json +3 -3
  120. package/dist/knob-embeddings.json +623 -263
  121. package/dist/modules/anim.d.ts +1 -1
  122. package/dist/modules/array.d.ts +1 -1
  123. package/dist/modules/async.d.ts +1 -1
  124. package/dist/modules/behavior.d.ts +1 -1
  125. package/dist/modules/browser.d.ts +1 -1
  126. package/dist/modules/composition.d.ts +1 -1
  127. package/dist/modules/contract.d.ts +1 -1
  128. package/dist/modules/core.d.ts +1 -1
  129. package/dist/modules/core.js +2 -0
  130. package/dist/modules/data.d.ts +1 -1
  131. package/dist/modules/ease.d.ts +1 -1
  132. package/dist/modules/format.d.ts +1 -1
  133. package/dist/modules/geo.d.ts +1 -1
  134. package/dist/modules/graph.d.ts +1 -1
  135. package/dist/modules/grid.d.ts +1 -1
  136. package/dist/modules/i18n.d.ts +17 -0
  137. package/dist/modules/i18n.js +22 -0
  138. package/dist/modules/index.d.ts +2 -1
  139. package/dist/modules/index.js +24 -1
  140. package/dist/modules/integration.d.ts +1 -1
  141. package/dist/modules/json.d.ts +1 -1
  142. package/dist/modules/llm.d.ts +1 -1
  143. package/dist/modules/math.d.ts +1 -1
  144. package/dist/modules/memory.d.ts +1 -1
  145. package/dist/modules/nn.d.ts +1 -1
  146. package/dist/modules/noise.d.ts +1 -1
  147. package/dist/modules/object.d.ts +1 -1
  148. package/dist/modules/os.d.ts +1 -1
  149. package/dist/modules/path.d.ts +1 -1
  150. package/dist/modules/prob.d.ts +1 -1
  151. package/dist/modules/session.d.ts +1 -1
  152. package/dist/modules/str.d.ts +1 -1
  153. package/dist/modules/tensor.d.ts +1 -1
  154. package/dist/modules/time.d.ts +1 -1
  155. package/dist/modules/trace.d.ts +1 -1
  156. package/dist/modules/train.d.ts +1 -1
  157. package/dist/modules/validate.d.ts +1 -1
  158. package/dist/modules/vector.d.ts +1 -1
  159. package/dist/modules/workspace.d.ts +1 -1
  160. package/dist/registry/factory-signatures.json +1 -1
  161. package/dist/registry.d.ts +10 -3
  162. package/dist/registry.js +31 -1
  163. package/dist/{types-DLx38UFZ.d.ts → types-Cdb321uM.d.ts} +9 -3
  164. package/i18n/ar.json +1 -0
  165. package/i18n/en.json +1 -0
  166. package/i18n/sl.json +1 -0
  167. package/package.json +3 -3
@@ -1,9 +1,10 @@
1
1
  app std-agent-tool-loop "2.0.0"
2
- "std-agent-tool-loop — answers a conversation by operating the running app as the caller, through `call-service llm call-tools`. The `tools` allowlist names declared external inputs (addressed like a listens source: `Trait.EVENT`, `Orbital.Trait.EVENT`) and entities to read; each input fires as the signed-in user through the ordinary dispatch (guards and entity policies apply) and each read returns only the rows the caller may read. Headless: the conversation UI (std-agent-session) shows the reply; a failure shows as a toast. CONVERSE carries the conversation (and optionally what std-agent-memory recalled); STEP carries each step live while it works (a model call, a tool it used, what the app answered) to the asking tab; REPLIED carries the reply, every step and the token usage; REPLY_FAILED carries the error. Compose with std-agent-session (the conversation) and std-agent-trace (the step record)."
2
+ "std-agent-tool-loop — answers a conversation by operating the running app as the caller, through `call-service llm call-tools`. Its `tools` are `{ scope: declared }` (every declared external input plus a read over every persisted entity), or named declared inputs (addressed like a listens source: `Trait.EVENT`, `Orbital.Trait.EVENT`) and entities to read; each input fires as the signed-in user through the ordinary dispatch (guards and entity policies apply) and each read returns only the rows the caller may read. Headless: the conversation UI (std-agent-session) shows the reply; a failure shows as a toast. CONVERSE carries the conversation (and optionally what std-agent-memory recalled); ASSISTANT_STEP carries each step live while it works (a model call, a tool it used, what the app answered) to the asking tab; ASSISTANT_REPLIED carries the reply, every step and the token usage; ASSISTANT_REPLY_FAILED carries the error. These names are the assistant contract std-agent-session's conversation hears from any orbital. Compose with std-agent-session (the conversation) and std-agent-trace (the step record)."
3
3
 
4
4
  type AgentTool = {
5
5
  event : event
6
6
  read : string
7
+ scope : "declared"
7
8
  }
8
9
  type AgentChatMessage = {
9
10
  role : "user" | "assistant"
@@ -94,7 +95,7 @@ orbital AgentToolLoopOrbital {
94
95
  instructions: (if ["=", (str/default ?context ""), ""] @config.instructions (str/concat @config.instructions "\n\nWhat you remember that may be relevant:\n" ?context))
95
96
  maxSteps: @config.maxSteps
96
97
  } {
97
- emit: { failure: ASK_FAILED, success: ANSWERED, onMessage: STEP }
98
+ emit: { failure: ASK_FAILED, success: ANSWERED, onMessage: ASSISTANT_STEP }
98
99
  })
99
100
  }
100
101
 
@@ -102,11 +103,11 @@ orbital AgentToolLoopOrbital {
102
103
  ANSWERED -> idle
103
104
  (set @entity.status answered)
104
105
  (set @entity.reply ?reply)
105
- (emit REPLIED { reply: ?reply, steps: ?steps, usage: ?usage })
106
+ (emit ASSISTANT_REPLIED { reply: ?reply, steps: ?steps, usage: ?usage })
106
107
  ASK_FAILED -> idle
107
108
  (set @entity.status failed)
108
109
  (set @entity.error ?error)
109
- (emit REPLY_FAILED { error: ?error })
110
+ (emit ASSISTANT_REPLY_FAILED { error: ?error })
110
111
  (render-ui toast {
111
112
  message: ?error
112
113
  type: alert
@@ -115,13 +116,13 @@ orbital AgentToolLoopOrbital {
115
116
  }
116
117
 
117
118
  emits {
118
- STEP -> external {
119
+ ASSISTANT_STEP -> external {
119
120
  activity : AgentActivity!
120
121
  }
121
122
  @description "One thing the assistant just did, live while it works: a model call, a tool it used, or what the app answered. Delivered to the asking tab only."
122
123
  @synonyms "progress, activity, trace step, working"
123
124
  @tier "domain"
124
- REPLIED -> external {
125
+ ASSISTANT_REPLIED -> external {
125
126
  reply : string!
126
127
  steps : [AgentActivity]!
127
128
  usage : AgentUsage!
@@ -129,7 +130,7 @@ orbital AgentToolLoopOrbital {
129
130
  @description "The assistant answered; carries every tool step it took and the tokens it used."
130
131
  @synonyms "answered, responded, done"
131
132
  @tier "domain"
132
- REPLY_FAILED -> external {
133
+ ASSISTANT_REPLY_FAILED -> external {
133
134
  error : string!
134
135
  }
135
136
  @description "The assistant could not answer (model unavailable, or out of steps)."
@@ -1,14 +1,16 @@
1
1
  app std-agent-assistant "2.0.0"
2
- "std-agent-assistant — an in-app assistant that operates the running app for the signed-in user. A floating button opens it in a side panel docked beside the page (std-panel-launcher; a side sheet on small screens), where the conversation shows every step the assistant takes live as it works. List AssistantDock with the assistant's traits on each page that should carry the button. One request flows down a chain of std agent atoms on the bus: the conversation (std-agent-session) SENDs → CONVERSE → std-agent-context bounds it → std-agent-memory adds what it recalls → std-agent-tool-loop answers it through `call-service llm call-tools`, firing only the inputs and reading only the entities the `tools` allowlist names, as the signed-in user → REPLIED goes back to the conversation, to memory (remembered) and to std-agent-trace (the run record). Import the orbital and supply the allowlist: `orbital Assistant = Agent.orbitals.AgentAssistantOrbital { config { tools: [{ event: TaskOrbital.TaskPersistor.DO_CREATE }, { read: Task }], instructions: \"…\" } }`. The conversation, memory and run records live in AgentRecordsOrbital; retarget them onto your own owner-scoped entities (`ownerId` a relation to your [identity] roster, with @read/@create) with `entities { AgentMessage: …, AgentMemory: …, AgentRun: … }`."
2
+ "std-agent-assistant — an in-app assistant that operates the running app for the signed-in user. Each section's floating button opens it in a side panel docked beside the page (std-panel-launcher; a side sheet on small screens), where the conversation shows every step the assistant takes live as it works; /assistant is the same conversation as a full page, in the app's own shell (pass `appName` and `navItems`); past conversations and what the assistant remembers open in place from its toolbar (Back returns to the chat), on either surface. One request flows down a chain of std agent atoms on the bus: the conversation (std-agent-session) SENDs → CONVERSE → std-agent-context bounds it → std-agent-memory adds what it recalls → std-agent-tool-loop answers it through `call-service llm call-tools`, firing only the inputs and reading only the entities its `tools` allow, as the signed-in user → ASSISTANT_REPLIED goes back to the conversation, to memory (remembered) and to std-agent-trace (the run record). By default the tools are the program's own declarations: every `-> external` input (its @description is the tool text) and a read over every persisted entity, so composing building blocks composes the assistant's abilities. Any section's page gets the assistant with two traits, `XAssistant = AgentSession.traits.AgentConversation` and a std-panel-launcher dock: the conversation speaks the ASSISTANT_* contract from any orbital, so the assistant needs no per-section wiring. Import the orbital once per app: `orbital Assistant = Agent.orbitals.AgentAssistantOrbital { config { instructions: \"…\" } }`. The conversation, memory and run records live in AgentRecordsOrbital; retarget them onto your own owner-scoped entities (`ownerId` a relation to your [identity] roster, with @read/@create) with `entities { AgentMessage: …, AgentMemory: …, AgentRun: …, AgentChat: … }`. The conversation is kept across pages and reloads (each person's most recently used conversation is the current one);"
3
3
 
4
4
  type AgentTool = {
5
5
  event : event
6
6
  read : string
7
+ scope : "declared"
7
8
  }
8
9
  type AgentLink = {
9
10
  label : string!
10
11
  href : string!
11
12
  }
13
+ type NavItem = { label : string!, href : string!, icon : string, badge : string, children : [NavItem], roles : [string] }
12
14
 
13
15
  orbital AgentAssistantOrbital {
14
16
  uses Session from "std/behaviors/std-agent-session"
@@ -16,12 +18,12 @@ orbital AgentAssistantOrbital {
16
18
  uses Memory from "std/behaviors/std-agent-memory"
17
19
  uses Loop from "std/behaviors/std-agent-tool-loop"
18
20
  uses Trace from "std/behaviors/std-agent-trace"
19
- uses Launcher from "std/behaviors/std-panel-launcher"
21
+ uses Shell from "std/behaviors/std-app-layout"
20
22
 
21
23
  config {
22
- tools : [AgentTool] = []
24
+ tools : [AgentTool] = [{ scope: declared }]
23
25
  @label "What may the assistant do?"
24
- @description "The declared inputs it may fire (`{ event: Trait.EVENT }` / `{ event: Orbital.Trait.EVENT }`) and the entities it may read (`{ read: Entity }`), as the signed-in user."
26
+ @description "As the signed-in user: `{ scope: declared }` (the default) gives it every external input the program declares and a read over every persisted entity, so each building block's declared inputs become its abilities; or list them — `{ event: Orbital.Trait.EVENT }` for one input, `{ read: Entity }` for one entity."
25
27
  @synonyms "allowlist, abilities, actions, permissions"
26
28
  @tier "domain"
27
29
  instructions : string = "You operate this app for the signed-in user. Use the tools to act and to look things up; when a tool reports that something was refused or denied, say so plainly."
@@ -38,17 +40,22 @@ orbital AgentAssistantOrbital {
38
40
  recallLimit : number = 3
39
41
  @label "Memories recalled per request"
40
42
  @tier "policy"
41
- links : [AgentLink] = [{ label: "Run history", href: "/assistant/runs" }, { label: "What I remember", href: "/assistant/memory" }]
43
+ links : [AgentLink] = [{ label: "Run history", href: "/assistant/runs" }]
42
44
  @label "Links above the conversation"
43
- @description "The pages showing the assistant's run history and memory."
45
+ @description "Related pages, e.g. the assistant's run history."
44
46
  @tier "presentation"
45
- title : string = "Assistant"
46
- @label "Panel title"
47
+ appName : string = "Assistant"
48
+ @label "App name in the assistant page's header"
49
+ @description "Pass the app's own name so the assistant page matches the rest of the app."
47
50
  @tier "presentation"
48
- buttonLabel : string = "Open the assistant"
49
- @label "Button label"
50
- @description "What the floating button does, read to screen readers and shown as its tooltip."
51
+ navItems : [NavItem] = []
52
+ @label "Sidebar navigation on the assistant page"
53
+ @description "Pass the app's own navItems so the assistant page keeps the app's sidebar."
51
54
  @tier "presentation"
55
+ viewerRole : string = ""
56
+ @label "Viewer role on the assistant page"
57
+ @description "The role the assistant page's sidebar items and their `roles` are checked against. Bind `@user.role` in an app whose identity carries a role; left empty, only items with no `roles` show."
58
+ @tier "policy"
52
59
  }
53
60
 
54
61
  entity AgentAssistant [runtime] {
@@ -60,8 +67,20 @@ orbital AgentAssistantOrbital {
60
67
  CONVERSE: REQUEST_CONTEXT
61
68
  }
62
69
  listens {
63
- AssistantConversation.SEND -> SEND
64
- AssistantLoop.REPLIED -> REPLIED
70
+ AssistantChatKeeper.ASSISTANT_CHAT_OPENED -> OPEN_CHAT
71
+ AssistantChatKeeper.ASSISTANT_SEND_IN_CHAT -> SEND_IN_CHAT
72
+ AssistantChatKeeper.ASSISTANT_REPLY_IN_CHAT -> REPLY_IN_CHAT
73
+ }
74
+ }
75
+
76
+ trait AssistantChatKeeper = Session.traits.AgentChatKeeper -> AgentChat {
77
+ listens {
78
+ *.ASSISTANT_SEND -> SEND
79
+ *.ASSISTANT_HISTORY_REQUESTED -> LOAD_HISTORY
80
+ *.ASSISTANT_NEW_CHAT -> NEW_CHAT
81
+ *.ASSISTANT_CHAT_SELECTED -> SELECT_CHAT
82
+ *.ASSISTANT_CHATS_REQUESTED -> LIST_CHATS
83
+ AssistantLoop.ASSISTANT_REPLIED -> REPLIED
65
84
  }
66
85
  }
67
86
 
@@ -69,21 +88,19 @@ orbital AgentAssistantOrbital {
69
88
  config {
70
89
  links: @config.links
71
90
  }
72
- listens {
73
- AssistantThread.AgentMessagesLoaded -> THREAD_LOADED
74
- AssistantThread.THREAD_FAILED -> REPLY_FAILED
75
- AssistantLoop.STEP -> STEP
76
- AssistantLoop.REPLIED -> REPLIED
77
- AssistantLoop.REPLY_FAILED -> REPLY_FAILED
78
- }
79
91
  }
80
92
 
81
- trait AssistantDock = Launcher.traits.PanelLauncher {
93
+ ;; The full assistant page: the same conversation as the side panel, in the
94
+ ;; app's own shell.
95
+ trait AssistantLayout = Shell.traits.AppLayout {
82
96
  config {
83
- contentTrait: @trait.AssistantConversation
84
- title: @config.title
85
- label: @config.buttonLabel
86
- icon: message-circle
97
+ viewerRole: @config.viewerRole
98
+ viewerName: @user.name
99
+ viewerEmail: @user.email
100
+ appName: @config.appName
101
+ navItems: @config.navItems
102
+ contentTrait: <trait.AssistantConversation />
103
+ contentClassName: "mx-auto flex w-full max-w-3xl flex-col h-[calc(100vh-9rem)] min-h-0"
87
104
  }
88
105
  }
89
106
 
@@ -102,7 +119,8 @@ orbital AgentAssistantOrbital {
102
119
  }
103
120
  listens {
104
121
  AssistantContext.COMPACTED -> RECALL
105
- AssistantLoop.REPLIED -> REMEMBER
122
+ AssistantLoop.ASSISTANT_REPLIED -> REMEMBER
123
+ *.ASSISTANT_MEMORIES_REQUESTED -> LIST
106
124
  }
107
125
  }
108
126
 
@@ -119,19 +137,18 @@ orbital AgentAssistantOrbital {
119
137
 
120
138
  trait AssistantTrace = Trace.traits.AgentTraceRecorder -> AgentRun {
121
139
  listens {
122
- AssistantLoop.REPLIED -> REPLIED
123
- AssistantLoop.REPLY_FAILED -> REPLY_FAILED
140
+ AssistantLoop.ASSISTANT_REPLIED -> REPLIED
141
+ AssistantLoop.ASSISTANT_REPLY_FAILED -> REPLY_FAILED
124
142
  }
125
143
  }
126
144
 
127
- page "/assistant" as AssistantPage -> AssistantDock, AssistantThread, AssistantContext, AssistantMemory, AssistantLoop, AssistantTrace
145
+ page "/assistant" as AssistantPage -> AssistantLayout, AssistantThread, AssistantChatKeeper, AssistantContext, AssistantMemory, AssistantLoop, AssistantTrace
128
146
  }
129
147
 
130
148
  ;; The assistant's records live outside AgentAssistantOrbital, so a consumer
131
149
  ;; importing that orbital retargets them onto its own owner-scoped entities:
132
150
  ;; `entities { AgentMessage: MyMessage, AgentMemory: MyMemory, AgentRun: MyRun }`.
133
151
  orbital AgentRecordsOrbital {
134
- uses Memory from "std/behaviors/std-agent-memory"
135
152
  uses Trace from "std/behaviors/std-agent-trace"
136
153
 
137
154
  entity AgentRun [persistent: agentRuns] {
@@ -143,6 +160,15 @@ orbital AgentRecordsOrbital {
143
160
  entity AgentMemory [persistent: agentMemories] {
144
161
  id : string!
145
162
  }
163
+ entity AgentChat [persistent: agentChats] {
164
+ id : string!
165
+ ownerId : string!
166
+ title : string = ""
167
+ startedAt : number = 0
168
+ lastActiveAt : number = 0
169
+ pendingMessage : string @intrinsic = ""
170
+ pendingReply : string @intrinsic = ""
171
+ }
146
172
 
147
173
  trait AgentRunHistory = Trace.traits.AgentRunBrowse -> AgentRun {
148
174
  listens {
@@ -150,12 +176,5 @@ orbital AgentRecordsOrbital {
150
176
  }
151
177
  }
152
178
 
153
- trait AgentMemoryList = Memory.traits.AgentMemoryBrowse -> AgentMemory {
154
- listens {
155
- AgentAssistantOrbital.AssistantMemory.MEMORY_STORED -> MEMORY_STORED
156
- }
157
- }
158
-
159
179
  page "/assistant/runs" as AssistantRunsPage -> AgentRunHistory
160
- page "/assistant/memory" as AssistantMemoryPage -> AgentMemoryList
161
180
  }
@@ -0,0 +1,59 @@
1
+ app std-page-open "1.0.0"
2
+ "std-page-open — opens a URL in a new, focused browser tab and reports the tab. Wire OPEN to something the person does (a button or a row action), so a page only ever opens because they asked for it. Needs a host with the `page` service (a browser extension)."
3
+
4
+ orbital PageOpenOrbital {
5
+ entity PageOpenRecord [runtime] {
6
+ opened : number @description "How many pages were opened" @synonyms "count" = 0
7
+ errorMessage : string @description "Why the last page could not be opened; blank = none" @synonyms "error, failure reason" = ""
8
+ }
9
+
10
+ trait PageOpen -> PageOpenRecord [interaction, instance] {
11
+ initial: ready
12
+
13
+ config {
14
+ statusSlot : slot = main
15
+ @label "Status slot"
16
+ @description "Where the atom shows its one-line status; an organism running it in the background sends it to `system`"
17
+ @synonyms "status area, slot"
18
+ @tier "presentation"
19
+ }
20
+
21
+ state ready {
22
+ INIT -> ready
23
+ (render-ui @config.statusSlot { type: typography, variant: body, role: status, content: "Ready to open pages" })
24
+ OPEN -> ready
25
+ (call-service "page" "openTab" { url: ?url, active: true }
26
+ { emit: { success: TAB_OPENED, failure: OPEN_CALL_FAILED } })
27
+ TAB_OPENED -> ready
28
+ (set @entity.opened (+ @entity.opened 1))
29
+ (emit OPENED { tab: ?tab })
30
+ OPEN_CALL_FAILED -> ready
31
+ (set @entity.errorMessage ?error)
32
+ (emit OPEN_FAILED { error: ?error })
33
+ (notify error (str/concat "Couldn't open the page — " ?error))
34
+ }
35
+
36
+ emits {
37
+ TAB_OPENED { tab : number! }
38
+ @description "The page service opened the tab"
39
+ @tier "secondary"
40
+ OPEN_CALL_FAILED { error : string! }
41
+ @description "The page service could not open the tab"
42
+ @tier "secondary"
43
+ OPENED -> external { tab : number! }
44
+ @description "The page is open in a new, focused tab"
45
+ @synonyms "opened, launched, visited"
46
+ @tier "primary"
47
+ OPEN_FAILED -> external { error : string! }
48
+ @description "The page could not be opened"
49
+ @tier "primary"
50
+ }
51
+
52
+ listens {
53
+ OPEN -> external { url : string! }
54
+ @description "Open `url` in a new, focused tab — wire it to something the person does"
55
+ }
56
+ }
57
+
58
+ page "/page-open" as PageOpenPage -> PageOpen
59
+ }
@@ -0,0 +1,134 @@
1
+ app std-page-search "1.0.0"
2
+ "std-page-search — runs one search on a site in a background tab: opens `searchUrl` with the query as the `queryParam` parameter, reads up to `maxResults` elements matching `resultSelector` (waiting up to `waitMs` for the results to appear), closes the tab, and reports RESULTS with the fields read from each. One search at a time: SEARCH is accepted again once RESULTS or SEARCH_FAILED is reported. It never clicks anything. Needs a host with the `page` service (a browser extension with access to the search pages)."
3
+
4
+ orbital PageSearchOrbital {
5
+ type PageField = {
6
+ selector : string
7
+ attr : string
8
+ resolve : boolean
9
+ }
10
+
11
+ type PageResult = {
12
+ elementId : string!
13
+ fields : Map string string
14
+ }
15
+
16
+ entity PageSearchRecord [runtime] {
17
+ query : string @description "The search being run" @synonyms "search term, terms, topic" = ""
18
+ tab : number @description "The background tab running the search; 0 = none" @synonyms "tab id" = 0
19
+ errorMessage : string @description "Why the last search failed; blank = none" @synonyms "error, failure reason" = ""
20
+ status : "idle" | "searching" @description "Whether a search is running" @synonyms "state, busy" = idle
21
+ }
22
+
23
+ trait PageSearch -> PageSearchRecord [interaction, instance] {
24
+ initial: idle
25
+
26
+ config {
27
+ statusSlot : slot = main
28
+ @label "Status slot"
29
+ @description "Where the atom shows its one-line status; an organism running it in the background sends it to `system`"
30
+ @synonyms "status area, slot"
31
+ @tier "presentation"
32
+ searchUrl : string = "https://example.com/search"
33
+ @label "Search page"
34
+ @description "URL of the site's search results page, without the query"
35
+ @synonyms "search url, results page, endpoint"
36
+ @tier "domain"
37
+ resultsMatch : string = "https://example.com/search*"
38
+ @label "Results pages"
39
+ @description "URL match pattern the results page lies in (Chrome match-pattern syntax); the search page must match it, and the extension asks for access to exactly these pages"
40
+ @synonyms "site, url pattern, results url"
41
+ @tier "domain"
42
+ queryParam : string = "q"
43
+ @label "Query parameter"
44
+ @description "Name of the URL parameter that carries the search terms"
45
+ @synonyms "query key, search parameter"
46
+ @tier "domain"
47
+ resultSelector : string = ".result"
48
+ @label "Result selector"
49
+ @description "CSS selector of one result on the results page"
50
+ @synonyms "result, item, card, tile"
51
+ @tier "domain"
52
+ fields : Map string PageField = {}
53
+ @label "Fields"
54
+ @description "Field name to how to read it from each result: `selector` (a descendant; absent reads the result itself), `attr` (an attribute; absent reads the text) and `resolve` (the attribute is a URL: return it absolute)"
55
+ @synonyms "columns, properties, extract"
56
+ @tier "domain"
57
+ maxResults : number = 10
58
+ @label "Results per search"
59
+ @description "Most results read from one search"
60
+ @synonyms "limit, count, how many"
61
+ @tier "policy"
62
+ waitMs : number = 8000
63
+ @label "Wait for results (ms)"
64
+ @description "How long to wait for the results page to load and its first result to appear"
65
+ @synonyms "timeout, wait, patience"
66
+ @tier "infra"
67
+ }
68
+
69
+ state idle {
70
+ INIT -> idle
71
+ (render-ui @config.statusSlot { type: typography, variant: body, role: status, content: "Ready to search" })
72
+ SEARCH -> searching
73
+ (set @entity.query ?query)
74
+ (set @entity.tab 0)
75
+ (set @entity.status searching)
76
+ (call-service "page" "openTab" { url: @config.searchUrl, params: (object/set {} @config.queryParam ?query), match: @config.resultsMatch, active: false }
77
+ { emit: { success: TAB_OPENED, failure: SEARCH_CALL_FAILED } })
78
+ (render-ui @config.statusSlot { type: typography, variant: body, role: status, content: (str/concat "Searching for " ?query) })
79
+ }
80
+
81
+ state searching {
82
+ INIT -> searching
83
+ (render-ui @config.statusSlot { type: typography, variant: body, role: status, content: (str/concat "Searching for " @entity.query) })
84
+ TAB_OPENED -> searching
85
+ (set @entity.tab ?tab)
86
+ (call-service "page" "query" { tab: ?tab, selector: @config.resultSelector, fields: @config.fields, limit: @config.maxResults, waitMs: @config.waitMs }
87
+ { emit: { success: RESULTS_READ, failure: SEARCH_CALL_FAILED } })
88
+ RESULTS_READ -> idle
89
+ (call-service "page" "closeTab" { tab: ?tab })
90
+ (set @entity.tab 0)
91
+ (set @entity.status idle)
92
+ (emit RESULTS { query: @entity.query, results: ?elements })
93
+ (render-ui @config.statusSlot { type: typography, variant: body, role: status, content: (str/concat "Searched for " @entity.query) })
94
+ SEARCH_CALL_FAILED -> idle when (> @entity.tab 0)
95
+ (call-service "page" "closeTab" { tab: @entity.tab })
96
+ (set @entity.tab 0)
97
+ (set @entity.errorMessage ?error)
98
+ (set @entity.status idle)
99
+ (emit SEARCH_FAILED { query: @entity.query, error: ?error })
100
+ (render-ui @config.statusSlot { type: typography, variant: body, role: status, content: (str/concat "Couldn't search: " ?error) })
101
+ SEARCH_CALL_FAILED -> idle when (== @entity.tab 0)
102
+ (set @entity.errorMessage ?error)
103
+ (set @entity.status idle)
104
+ (emit SEARCH_FAILED { query: @entity.query, error: ?error })
105
+ (render-ui @config.statusSlot { type: typography, variant: body, role: status, content: (str/concat "Couldn't search: " ?error) })
106
+ }
107
+
108
+ emits {
109
+ TAB_OPENED { tab : number! }
110
+ @description "The background tab for the search is open"
111
+ @tier "secondary"
112
+ RESULTS_READ { tab : number!, elements : [PageResult]! }
113
+ @description "The results were read from the search page"
114
+ @tier "secondary"
115
+ SEARCH_CALL_FAILED { error : string! }
116
+ @description "Opening the search page or reading it failed"
117
+ @tier "secondary"
118
+ RESULTS -> external { query : string!, results : [PageResult]! }
119
+ @description "What one search found: each result's element id and the fields read from it"
120
+ @synonyms "search results, found, hits"
121
+ @tier "primary"
122
+ SEARCH_FAILED -> external { query : string!, error : string! }
123
+ @description "The search could not be run or read"
124
+ @tier "primary"
125
+ }
126
+
127
+ listens {
128
+ SEARCH -> external { query : string! }
129
+ @description "Search the site for `query`"
130
+ }
131
+ }
132
+
133
+ page "/page-search" as PageSearchPage -> PageSearch
134
+ }
@@ -0,0 +1,59 @@
1
+ app std-page-treat "1.0.0"
2
+ "std-page-treat — applies a declared visual treatment to one element of a browser tab (hide, blur, highlight, or label it with text) or restores it, and reports which element it treated. TREAT takes the tab and element id std-page-watch reports. The treatments are a fixed, declared set: no arbitrary styles or scripts. Needs a host with the `page` service (a browser extension)."
3
+
4
+ orbital PageTreatOrbital {
5
+ entity PageTreatRecord [runtime] {
6
+ treated : number @description "How many treatments were applied" @synonyms "count, applied" = 0
7
+ errorMessage : string @description "Why the last treatment failed; blank = none" @synonyms "error, failure reason" = ""
8
+ }
9
+
10
+ trait PageTreat -> PageTreatRecord [interaction, instance] {
11
+ initial: ready
12
+
13
+ config {
14
+ statusSlot : slot = main
15
+ @label "Status slot"
16
+ @description "Where the atom shows its one-line status; an organism running it in the background sends it to `system`"
17
+ @synonyms "status area, slot"
18
+ @tier "presentation"
19
+ }
20
+
21
+ state ready {
22
+ INIT -> ready
23
+ (render-ui @config.statusSlot { type: typography, variant: body, role: status, content: "Ready to treat page elements" })
24
+ TREAT -> ready
25
+ (call-service "page" "apply" { tab: ?tab, elementId: ?elementId, treatment: ?treatment, label: ?label }
26
+ { emit: { success: APPLIED, failure: APPLY_FAILED } })
27
+ APPLIED -> ready
28
+ (set @entity.treated (+ @entity.treated 1))
29
+ (emit TREATED { tab: ?tab, elementId: ?elementId, treatment: ?treatment })
30
+ APPLY_FAILED -> ready
31
+ (set @entity.errorMessage ?error)
32
+ (emit TREAT_FAILED { error: ?error })
33
+ (render-ui @config.statusSlot { type: typography, variant: body, role: status, content: (str/concat "Couldn't treat a page element: " ?error) })
34
+ }
35
+
36
+ emits {
37
+ APPLIED { applied : boolean!, tab : number!, elementId : string!, treatment : "hide" | "blur" | "highlight" | "label" | "restore" }
38
+ @description "The page service applied the treatment"
39
+ @tier "secondary"
40
+ APPLY_FAILED { error : string! }
41
+ @description "The page service could not apply the treatment"
42
+ @tier "secondary"
43
+ TREATED -> external { tab : number!, elementId : string!, treatment : "hide" | "blur" | "highlight" | "label" | "restore" }
44
+ @description "The element now shows the treatment (or, for restore, is back as it was)"
45
+ @synonyms "hidden, blurred, highlighted, labelled, restored"
46
+ @tier "primary"
47
+ TREAT_FAILED -> external { error : string! }
48
+ @description "The treatment could not be applied (the element is gone, or the tab closed)"
49
+ @tier "primary"
50
+ }
51
+
52
+ listens {
53
+ TREAT -> external { tab : number!, elementId : string!, treatment : "hide" | "blur" | "highlight" | "label" | "restore", label : string }
54
+ @description "Treat one page element; `label` is the text shown with it (for example why it was hidden)"
55
+ }
56
+ }
57
+
58
+ page "/page-treat" as PageTreatPage -> PageTreat
59
+ }
@@ -0,0 +1,86 @@
1
+ app std-page-watch "1.0.0"
2
+ "std-page-watch — watches every browser tab whose URL matches `match` for elements matching `itemSelector`, and reports each element once as ITEM with the `fields` read from it, now and as the page changes. Needs a host with the `page` service (a browser extension, which asks for access to exactly the `match` pages). Each item carries its tab and element id; compose std-page-treat to hide, blur, highlight or label it."
3
+
4
+ orbital PageWatchOrbital {
5
+ type PageField = {
6
+ selector : string
7
+ attr : string
8
+ resolve : boolean
9
+ }
10
+
11
+ entity PageWatchRecord [runtime] {
12
+ watchId : string @description "Id of the attached watch" @synonyms "watch id, subscription" = ""
13
+ found : number @description "How many elements have been reported" @synonyms "count, items seen, reported" = 0
14
+ errorMessage : string @description "Why the watch could not be attached; blank = none" @synonyms "error, failure reason" = ""
15
+ status : "starting" | "watching" | "failed" @description "Whether the watch is attached" @synonyms "state, watching, connected" = starting
16
+ }
17
+
18
+ trait PageWatch -> PageWatchRecord [lifecycle, instance] {
19
+ initial: active
20
+
21
+ config {
22
+ statusSlot : slot = main
23
+ @label "Status slot"
24
+ @description "Where the atom shows its one-line status; an organism running it in the background sends it to `system`"
25
+ @synonyms "status area, slot"
26
+ @tier "presentation"
27
+ match : string = "https://example.com/*"
28
+ @label "Pages"
29
+ @description "URL match pattern of the tabs to watch, in Chrome match-pattern syntax (`<scheme>://<host>/<path>` with `*` wildcards)"
30
+ @synonyms "site, url pattern, pages, domain"
31
+ @tier "domain"
32
+ itemSelector : string = ".item"
33
+ @label "Item selector"
34
+ @description "CSS selector of the elements to report"
35
+ @synonyms "selector, element, card, tile, row"
36
+ @tier "domain"
37
+ fields : Map string PageField = {}
38
+ @label "Fields"
39
+ @description "Field name to how to read it from each element: `selector` (a descendant; absent reads the element itself), `attr` (an attribute; absent reads the text) and `resolve` (the attribute is a URL: return it absolute)"
40
+ @synonyms "columns, properties, extract, read"
41
+ @tier "domain"
42
+ itemEvent : event = "PageWatch.ITEM_FOUND"
43
+ @label "Item input"
44
+ @description "The declared input each element arrives as; it follows the trait when a composer renames it"
45
+ @tier "internal"
46
+ }
47
+
48
+ state active {
49
+ INIT -> active
50
+ (call-service "page" "watch" { match: @config.match, selector: @config.itemSelector, fields: @config.fields, event: @config.itemEvent }
51
+ { emit: { success: WATCHING, failure: WATCH_FAILED } })
52
+ (render-ui @config.statusSlot { type: typography, variant: body, role: status, content: "Connecting to the pages…" })
53
+ WATCHING -> active
54
+ (set @entity.watchId ?watchId)
55
+ (set @entity.status watching)
56
+ (render-ui @config.statusSlot { type: typography, variant: body, role: status, content: (str/concat "Watching " @config.match) })
57
+ WATCH_FAILED -> active
58
+ (set @entity.errorMessage ?error)
59
+ (set @entity.status failed)
60
+ (render-ui @config.statusSlot { type: typography, variant: body, role: status, content: (str/concat "Can't watch these pages: " ?error) })
61
+ ITEM_FOUND -> active
62
+ (set @entity.found (+ @entity.found 1))
63
+ (emit ITEM { tab: ?tab, elementId: ?elementId, url: ?url, fields: ?fields })
64
+ }
65
+
66
+ emits {
67
+ WATCHING { watchId : string! }
68
+ @description "The watch is attached"
69
+ @tier "secondary"
70
+ WATCH_FAILED -> external { error : string! }
71
+ @description "The watch could not be attached (no page service, or no access to the pages)"
72
+ @tier "primary"
73
+ ITEM -> external { tab : number!, elementId : string!, url : string!, fields : Map string string }
74
+ @description "One matching element, reported once, with the fields read from it"
75
+ @synonyms "element found, item seen, new item"
76
+ @tier "primary"
77
+ }
78
+
79
+ listens {
80
+ ITEM_FOUND -> external { tab : number!, elementId : string!, url : string!, fields : Map string string }
81
+ @description "One matching element, delivered by the page service"
82
+ }
83
+ }
84
+
85
+ page "/page-watch" as PageWatchPage -> PageWatch
86
+ }