@nocobase/app-plugin-agents 1.0.0-beta.26 → 1.0.0-beta.28

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 (189) hide show
  1. package/CHANGELOG.md +58 -0
  2. package/README.md +40 -22
  3. package/dist/client/chat/api.d.ts +18 -1
  4. package/dist/client/chat/api.d.ts.map +1 -1
  5. package/dist/client/chat/api.js +37 -0
  6. package/dist/client/chat/api.js.map +1 -1
  7. package/dist/client/chat/coalesced-invalidation.d.ts +15 -0
  8. package/dist/client/chat/coalesced-invalidation.d.ts.map +1 -0
  9. package/dist/client/chat/coalesced-invalidation.js +29 -0
  10. package/dist/client/chat/coalesced-invalidation.js.map +1 -0
  11. package/dist/client/chat/controller.d.ts +8 -1
  12. package/dist/client/chat/controller.d.ts.map +1 -1
  13. package/dist/client/chat/controller.js +21 -0
  14. package/dist/client/chat/controller.js.map +1 -1
  15. package/dist/client/chat/message-model.d.ts.map +1 -1
  16. package/dist/client/chat/message-model.js +4 -0
  17. package/dist/client/chat/message-model.js.map +1 -1
  18. package/dist/client/chat/submissions.d.ts +3 -0
  19. package/dist/client/chat/submissions.d.ts.map +1 -1
  20. package/dist/client/chat/submissions.js +1 -0
  21. package/dist/client/chat/submissions.js.map +1 -1
  22. package/dist/client/chat/use-chat-scroll.d.ts +8 -1
  23. package/dist/client/chat/use-chat-scroll.d.ts.map +1 -1
  24. package/dist/client/chat/use-chat-scroll.js +29 -5
  25. package/dist/client/chat/use-chat-scroll.js.map +1 -1
  26. package/dist/client/chat/use-chat.d.ts +2 -0
  27. package/dist/client/chat/use-chat.d.ts.map +1 -1
  28. package/dist/client/chat/use-chat.js +17 -7
  29. package/dist/client/chat/use-chat.js.map +1 -1
  30. package/dist/client/components/agent-prompt-callout.d.ts +19 -0
  31. package/dist/client/components/agent-prompt-callout.d.ts.map +1 -0
  32. package/dist/client/components/agent-prompt-callout.js +28 -0
  33. package/dist/client/components/agent-prompt-callout.js.map +1 -0
  34. package/dist/client/locales/chat.en-US.d.ts +1 -0
  35. package/dist/client/locales/chat.en-US.d.ts.map +1 -1
  36. package/dist/client/locales/chat.en-US.js +1 -0
  37. package/dist/client/locales/chat.en-US.js.map +1 -1
  38. package/dist/client/locales/chat.zh-CN.d.ts.map +1 -1
  39. package/dist/client/locales/chat.zh-CN.js +1 -0
  40. package/dist/client/locales/chat.zh-CN.js.map +1 -1
  41. package/dist/client/locales/de-DE.d.ts.map +1 -1
  42. package/dist/client/locales/de-DE.js +1 -0
  43. package/dist/client/locales/de-DE.js.map +1 -1
  44. package/dist/client/locales/es-ES.d.ts.map +1 -1
  45. package/dist/client/locales/es-ES.js +1 -0
  46. package/dist/client/locales/es-ES.js.map +1 -1
  47. package/dist/client/locales/fr-FR.d.ts.map +1 -1
  48. package/dist/client/locales/fr-FR.js +1 -0
  49. package/dist/client/locales/fr-FR.js.map +1 -1
  50. package/dist/client/locales/id-ID.d.ts.map +1 -1
  51. package/dist/client/locales/id-ID.js +1 -0
  52. package/dist/client/locales/id-ID.js.map +1 -1
  53. package/dist/client/locales/ja-JP.d.ts.map +1 -1
  54. package/dist/client/locales/ja-JP.js +1 -0
  55. package/dist/client/locales/ja-JP.js.map +1 -1
  56. package/dist/client/locales/pt-BR.d.ts.map +1 -1
  57. package/dist/client/locales/pt-BR.js +1 -0
  58. package/dist/client/locales/pt-BR.js.map +1 -1
  59. package/dist/client/locales/runtimes.en-US.d.ts +4 -1
  60. package/dist/client/locales/runtimes.en-US.d.ts.map +1 -1
  61. package/dist/client/locales/runtimes.en-US.js +6 -3
  62. package/dist/client/locales/runtimes.en-US.js.map +1 -1
  63. package/dist/client/locales/runtimes.zh-CN.d.ts.map +1 -1
  64. package/dist/client/locales/runtimes.zh-CN.js +6 -3
  65. package/dist/client/locales/runtimes.zh-CN.js.map +1 -1
  66. package/dist/client/locales/vi-VN.d.ts.map +1 -1
  67. package/dist/client/locales/vi-VN.js +1 -0
  68. package/dist/client/locales/vi-VN.js.map +1 -1
  69. package/dist/client/locales/zh-TW.d.ts.map +1 -1
  70. package/dist/client/locales/zh-TW.js +1 -0
  71. package/dist/client/locales/zh-TW.js.map +1 -1
  72. package/dist/client/pages/runtimes/connect.d.ts.map +1 -1
  73. package/dist/client/pages/runtimes/connect.js +16 -10
  74. package/dist/client/pages/runtimes/connect.js.map +1 -1
  75. package/dist/client/pages/skills/index.js +2 -2
  76. package/dist/client/pages/skills/index.js.map +1 -1
  77. package/dist/database/migrations/.manifest.json +8 -0
  78. package/dist/database/migrations/202611010001_ag_conversation_runner_attention.d.ts +4 -0
  79. package/dist/database/migrations/202611010001_ag_conversation_runner_attention.d.ts.map +1 -0
  80. package/dist/database/migrations/202611010001_ag_conversation_runner_attention.js +30 -0
  81. package/dist/database/migrations/202611010001_ag_conversation_runner_attention.js.map +1 -0
  82. package/dist/database/migrations/202611010002_ag_create_conversation_links.d.ts +4 -0
  83. package/dist/database/migrations/202611010002_ag_create_conversation_links.d.ts.map +1 -0
  84. package/dist/database/migrations/202611010002_ag_create_conversation_links.js +30 -0
  85. package/dist/database/migrations/202611010002_ag_create_conversation_links.js.map +1 -0
  86. package/dist/package.json +1 -1
  87. package/dist/server/composition.d.ts.map +1 -1
  88. package/dist/server/composition.js +1 -0
  89. package/dist/server/composition.js.map +1 -1
  90. package/dist/server/core/conversations/attachments.d.ts +5 -0
  91. package/dist/server/core/conversations/attachments.d.ts.map +1 -1
  92. package/dist/server/core/conversations/attachments.js +10 -0
  93. package/dist/server/core/conversations/attachments.js.map +1 -1
  94. package/dist/server/core/conversations/conversation.service.d.ts +3 -1
  95. package/dist/server/core/conversations/conversation.service.d.ts.map +1 -1
  96. package/dist/server/core/conversations/conversation.service.js +693 -32
  97. package/dist/server/core/conversations/conversation.service.js.map +1 -1
  98. package/dist/server/core/conversations/conversation.store.d.ts +24 -0
  99. package/dist/server/core/conversations/conversation.store.d.ts.map +1 -1
  100. package/dist/server/core/conversations/conversation.store.js +10 -0
  101. package/dist/server/core/conversations/conversation.store.js.map +1 -1
  102. package/dist/server/core/conversations/index.d.ts +1 -1
  103. package/dist/server/core/conversations/index.d.ts.map +1 -1
  104. package/dist/server/core/conversations/index.js.map +1 -1
  105. package/dist/server/core/conversations/links.d.ts +27 -0
  106. package/dist/server/core/conversations/links.d.ts.map +1 -0
  107. package/dist/server/core/conversations/links.js +188 -0
  108. package/dist/server/core/conversations/links.js.map +1 -0
  109. package/dist/server/core/conversations/ports.d.ts +107 -3
  110. package/dist/server/core/conversations/ports.d.ts.map +1 -1
  111. package/dist/server/core/runs/claim.d.ts.map +1 -1
  112. package/dist/server/core/runs/claim.js +47 -3
  113. package/dist/server/core/runs/claim.js.map +1 -1
  114. package/dist/server/core/runs/lifecycle.d.ts.map +1 -1
  115. package/dist/server/core/runs/lifecycle.js +28 -3
  116. package/dist/server/core/runs/lifecycle.js.map +1 -1
  117. package/dist/server/core/runs/ports.d.ts +15 -0
  118. package/dist/server/core/runs/ports.d.ts.map +1 -1
  119. package/dist/server/core/runs/ports.js.map +1 -1
  120. package/dist/server/core/runs/run-data-purge.d.ts +7 -0
  121. package/dist/server/core/runs/run-data-purge.d.ts.map +1 -1
  122. package/dist/server/core/runs/run-data-purge.js +13 -0
  123. package/dist/server/core/runs/run-data-purge.js.map +1 -1
  124. package/dist/server/core/runs/run.store.d.ts +6 -2
  125. package/dist/server/core/runs/run.store.d.ts.map +1 -1
  126. package/dist/server/core/runs/run.store.js +28 -10
  127. package/dist/server/core/runs/run.store.js.map +1 -1
  128. package/dist/server/kernel/errors.d.ts +1 -1
  129. package/dist/server/kernel/errors.d.ts.map +1 -1
  130. package/dist/server/kernel/errors.js +2 -0
  131. package/dist/server/kernel/errors.js.map +1 -1
  132. package/dist/server/kernel/events.d.ts +19 -0
  133. package/dist/server/kernel/events.d.ts.map +1 -1
  134. package/dist/server/kernel/events.js.map +1 -1
  135. package/dist/server/online/agent/contracts.d.ts +5 -0
  136. package/dist/server/online/agent/contracts.d.ts.map +1 -1
  137. package/dist/server/online/agent/native/session.d.ts +1 -0
  138. package/dist/server/online/agent/native/session.d.ts.map +1 -1
  139. package/dist/server/online/agent/native/session.js +4 -1
  140. package/dist/server/online/agent/native/session.js.map +1 -1
  141. package/dist/server/online/agent/persistence/store.d.ts.map +1 -1
  142. package/dist/server/online/agent/persistence/store.js +8 -1
  143. package/dist/server/online/agent/persistence/store.js.map +1 -1
  144. package/dist/server/online/agent/runner/backend.d.ts +15 -0
  145. package/dist/server/online/agent/runner/backend.d.ts.map +1 -1
  146. package/dist/server/online/agent/runner/backend.js +310 -70
  147. package/dist/server/online/agent/runner/backend.js.map +1 -1
  148. package/dist/server/online/agent/runner/projection.d.ts +24 -2
  149. package/dist/server/online/agent/runner/projection.d.ts.map +1 -1
  150. package/dist/server/online/agent/runner/projection.js +330 -26
  151. package/dist/server/online/agent/runner/projection.js.map +1 -1
  152. package/dist/server/online/agent/runner/types.d.ts +8 -1
  153. package/dist/server/online/agent/runner/types.d.ts.map +1 -1
  154. package/dist/server/online/agent/types.d.ts +2 -0
  155. package/dist/server/online/agent/types.d.ts.map +1 -1
  156. package/dist/server/providers/agents.d.ts +7 -0
  157. package/dist/server/providers/agents.d.ts.map +1 -1
  158. package/dist/server/providers/agents.js +3 -1
  159. package/dist/server/providers/agents.js.map +1 -1
  160. package/dist/server/providers/runners.d.ts.map +1 -1
  161. package/dist/server/providers/runners.js +12 -1
  162. package/dist/server/providers/runners.js.map +1 -1
  163. package/dist/server/routes/chat.d.ts.map +1 -1
  164. package/dist/server/routes/chat.js +270 -2
  165. package/dist/server/routes/chat.js.map +1 -1
  166. package/dist/server/routes/run.d.ts.map +1 -1
  167. package/dist/server/routes/run.js +44 -0
  168. package/dist/server/routes/run.js.map +1 -1
  169. package/dist/server/routes/schemas.d.ts +15 -1
  170. package/dist/server/routes/schemas.d.ts.map +1 -1
  171. package/dist/server/routes/schemas.js +116 -1
  172. package/dist/server/routes/schemas.js.map +1 -1
  173. package/dist/server/runners/workspaces.d.ts.map +1 -1
  174. package/dist/server/runners/workspaces.js +46 -2
  175. package/dist/server/runners/workspaces.js.map +1 -1
  176. package/dist/server/tokens.d.ts +1 -1
  177. package/dist/server/tokens.d.ts.map +1 -1
  178. package/dist/server/tokens.js.map +1 -1
  179. package/dist/shared/conversations.d.ts +107 -1
  180. package/dist/shared/conversations.d.ts.map +1 -1
  181. package/dist/shared/conversations.js +19 -0
  182. package/dist/shared/conversations.js.map +1 -1
  183. package/dist/shared/ui-message.d.ts +30 -0
  184. package/dist/shared/ui-message.d.ts.map +1 -1
  185. package/dist/shared/ui-message.js +17 -0
  186. package/dist/shared/ui-message.js.map +1 -1
  187. package/package.json +10 -10
  188. package/skills/nocobase-app-plugin-agents/references/extension-points.md +19 -19
  189. package/skills/nocobase-app-plugin-agents/references/online-agent.md +16 -2
@@ -4,25 +4,25 @@ A subject's optional `sink.onCancelRequested(tx, run)` runs once in the accepted
4
4
 
5
5
  Everything the App contributes goes through `agentsToken` (`@nocobase/app-plugin-agents/server/tokens`), resolved in one of the App's service providers when it boots. Text people read is an `I18nText` (`{ key, ns }`) in the App's own namespace. The README's "Extension points" section describes each field; this is the map. Where the two disagree, the types exported from `server/tokens` (the `Agents` interface) are authoritative.
6
6
 
7
- | Extension point | Contributes | Typical use |
8
- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
9
- | `subjects.register(binding)` | A kind of subject runs work on: `kind`, `title`, `triggers`, `preview`, `context.assemble`, `sink.onRunFinished`, `queuedExpiryMs`, `reports.describe` | An issue, a ticket, a document an agent works on |
10
- | `runs.enqueue(...)`, `runs.withdrawQueued(...)`, `runs.workload(...)` | Wake an agent on a subject, withdraw queued work, read the board of open runs | Assigning work to an agent from a business action |
11
- | `scopes.register(kind)` | A scope of variables and default skills (`key`, `title`, `description`, `access(scopeId, userId)`); `agent` and the skill-only `global` are reserved, `workdir` is registered by the App | Per-project or per-team variables |
12
- | `actions.provide(source)` | The business actions an agent may be given (`key`, `group`, `title`, `description`, `defaultOn`), and those never granted (`grantable: false` with a `reason`) | What the agent editor's Capabilities tab offers |
13
- | `agents.setDefaults(provider)`, `agents.applyDefaults()` | The instructions and business actions every agent discovered from runners gets; `applyDefaults` writes them to the agents that differ |
14
- | `agents.ensureSystem(input)` | An agent of the App's own (fixed id, name, description, instructions, actions, tools and models), kept as given and enabled |
15
- | `gate.set(gate)` (`ActionGate`: `allowed(identity)`, optional `consultable(action)`) | Which business actions a caller holds now: a person their own (narrowed by an API key's scope), a run those its agent is configured with within the waking person's | Bounding the command manifest and every request a run makes; without a gate a caller holds only `agents.agents/view` (and `agents.runs/self` for a run) |
16
- | `conversations.sources.register`, `conversations.contextKinds.register`, `conversations.rules.provide`, `conversations.deliver`, `consultations.rules.provide` | Where conversations start from, what a page context may reference, extra system rules, news delivered into a conversation | "Ask agent" buttons on business pages |
17
- | `people.provide(source)` | The App's directory: names, whom to pick, who can no longer act (`inactive`) | Disabling a person stops their runners |
18
- | `events.on('agent.removed' \| 'notice', listener)` | An agent disabled; people to be told, such as `runner_upgrade_required` | Releasing work given to an agent; forwarding notices to the App's inbox |
19
- | `jobs.register(kind, registration)` | A build job kind, only for an off-by-default runner build method | Builds on runners |
20
- | `reporting.usage`, `reporting.runFigures`, `reporting.range`, `reporting.modelUsage` | What runs used and cost, grouped as the App needs | The App's report pages |
21
- | `briefs.sections.register(provider)` | Sections added to every brief's context layer | Project conventions every run should read |
22
- | `mounts.register(provider)` | Directories of files placed beside the agent | Reference material for a run |
23
- | `repoAccess.register(provider)` | Commit identity and short-lived push credentials per run, at the claim or, with `issue`, whenever the runner's git needs one (`gitCredentials` runners); code host CLI wrappers (`RunGit.tools`, `gitTools` runners) | Git hosting integration |
24
- | `models.gateway` | The model gateway for the App's own model calls | See [Online agents](online-agents.md) |
25
- | `vectors.collection(spec)`, `vectors.stores.register` | Vector collections searched by meaning; another vector store type | Semantic search for a knowledge base |
7
+ | Extension point | Contributes | Typical use |
8
+ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
9
+ | `subjects.register(binding)` | A kind of subject runs work on: `kind`, `title`, `triggers`, `preview`, `context.assemble`, `sink.onRunFinished`, `queuedExpiryMs`, `reports.describe` | An issue, a ticket, a document an agent works on |
10
+ | `runs.enqueue(...)`, `runs.withdrawQueued(...)`, `runs.workload(...)` | Wake an agent on a subject, withdraw queued work, read the board of open runs | Assigning work to an agent from a business action |
11
+ | `scopes.register(kind)` | A scope of variables and default skills (`key`, `title`, `description`, `access(scopeId, userId)`); `agent` and the skill-only `global` are reserved, `workdir` is registered by the App | Per-project or per-team variables |
12
+ | `actions.provide(source)` | The business actions an agent may be given (`key`, `group`, `title`, `description`, `defaultOn`), and those never granted (`grantable: false` with a `reason`) | What the agent editor's Capabilities tab offers |
13
+ | `agents.setDefaults(provider)`, `agents.applyDefaults()` | The instructions and business actions every agent discovered from runners gets; `applyDefaults` writes them to the agents that differ |
14
+ | `agents.ensureSystem(input)` | An agent of the App's own (fixed id, name, description, instructions, actions, tools and models), kept as given and enabled |
15
+ | `gate.set(gate)` (`ActionGate`: `allowed(identity)`, optional `consultable(action)`) | Which business actions a caller holds now: a person their own (narrowed by an API key's scope), a run those its agent is configured with within the waking person's | Bounding the command manifest and every request a run makes; without a gate a caller holds only `agents.agents/view` (and `agents.runs/self` for a run) |
16
+ | `conversations.sources.register`, `conversations.contextKinds.register`, `conversations.rules.provide`, `conversations.deliver`, `conversations.links`, `consultations.rules.provide` | Where conversations start from, what a page context may reference, extra system rules, news delivered into a conversation | "Ask agent" buttons on business pages |
17
+ | `people.provide(source)` | The App's directory: names, whom to pick, who can no longer act (`inactive`) | Disabling a person stops their runners |
18
+ | `events.on('agent.removed' \| 'notice', listener)` | An agent disabled; people to be told, such as `runner_upgrade_required` | Releasing work given to an agent; forwarding notices to the App's inbox |
19
+ | `jobs.register(kind, registration)` | A build job kind, only for an off-by-default runner build method | Builds on runners |
20
+ | `reporting.usage`, `reporting.runFigures`, `reporting.range`, `reporting.modelUsage` | What runs used and cost, grouped as the App needs | The App's report pages |
21
+ | `briefs.sections.register(provider)` | Sections added to every brief's context layer | Project conventions every run should read |
22
+ | `mounts.register(provider)` | Directories of files placed beside the agent | Reference material for a run |
23
+ | `repoAccess.register(provider)` | Commit identity and short-lived push credentials per run, at the claim or, with `issue`, whenever the runner's git needs one (`gitCredentials` runners); code host CLI wrappers (`RunGit.tools`, `gitTools` runners) | Git hosting integration |
24
+ | `models.gateway` | The model gateway for the App's own model calls | See [Online agents](online-agents.md) |
25
+ | `vectors.collection(spec)`, `vectors.stores.register` | Vector collections searched by meaning; another vector store type | Semantic search for a knowledge base |
26
26
 
27
27
  Rules that are easy to miss:
28
28
 
@@ -213,7 +213,7 @@ Native and Runner realtime history is `AppUIMessage[]`, and HTTP input for both
213
213
 
214
214
  For multiple instances configure `agents.uiRecovery: { namespace, redis: { host, port, ... } }` with an application-specific namespace and a shared Redis deployment. The plugin owns the connections. `DefaultChatTransport.prepareReconnectToStreamRequest` points to `/api/agents/conversations/:id/events`. Without configuration there is one live response and history only, reported as `x-online-agent-recovery: live`; configured failures never fall back. Replay requires the live producer: process death does not restart inference, tools or Runner work. Stop remains a separate authenticated action and can signal a live native producer on another instance; read execution and saved history until termination is confirmed. Approval waiting and a missing stream are not business success. See [UI messages and recovery](../../../docs/ui-messages.md) for identity, lifecycle, limits, costs and validation boundaries.
215
215
 
216
- Existing system notices are delivered through `ConversationService.deliver()` in the caller's business transaction. OnlineAgent bindings persist them without starting another execution, and rollback removes them with the business changes. Native notices use standard public data parts and remain readable after a response closes. Independent application timeline content should use the authorized business subscription and rendering extensions; OnlineAgent has no separate notification-injection API.
216
+ Existing system notices are delivered through `ConversationService.deliver()` in the caller's business transaction. OnlineAgent bindings persist them without starting another execution, unless a Runner binding's news passes `wake: true`, and rollback removes them with the business changes. Native notices use standard public data parts and remain readable after a response closes. Independent application timeline content should use the authorized business subscription and rendering extensions; OnlineAgent has no separate notification-injection API.
217
217
 
218
218
  ## Public UI messages
219
219
 
@@ -223,10 +223,24 @@ Browser consumers use the SDK-owned `AppUIMessage` and `ChatProvider` from `clie
223
223
 
224
224
  Deploy one execution process per logical application/database, fully stopping the old process before starting its replacement. A real serving host repairs pre-process native occupancy at startup: complete saved results are finalized; missing terminal snapshots become failed UI messages on their stable IDs. Current-process rows, valid approval waits and Runner bindings are preserved. Command hosts do not perform crash recovery. Repeated reads and initialization do not rerun models or tools. Shared stream markers express transport reachability, never execution-process death; overlapping deployment and execution takeover are outside this contract.
225
225
 
226
- Normal native and Runner creation accepts showInChatList (default true); background creation always hides the record. List filtering happens in the database before pagination. A known hidden ID retains its ownership checks and remains readable. Notifications delivered through conversations.deliver join the caller's transaction, do not wake new native/Runner execution, and roll back with business changes; native realtime notices are saved as standard data parts.
226
+ Normal native and Runner creation accepts showInChatList (default true); background creation always hides the record. List filtering happens in the database before pagination. A known hidden ID retains its ownership checks and remains readable. Notifications delivered through conversations.deliver join the caller's transaction, do not wake new native/Runner execution (Runner only with `wake: true`), and roll back with business changes; native realtime notices are saved as standard data parts.
227
227
 
228
228
  HTTP creation/configuration cannot override tool lists, model lists or system prompts. Business variables must be declared and validated by selected scopes; selectedModel still selects an authorized catalog entry. Trusted server SDK configuration retains its policy capability. Legacy unbound conversations are read-only but their owner can still Stop their existing Run without a current model or online Agent.
229
229
 
230
+ ## Runner binding, links and attention
231
+
232
+ A conversation is bound to the first runner that takes one of its runs, in the claim's transaction; later runs go only to that runner (`SubjectBinding.runnerPin`), so its working directory `chat-<id>.task` and the coding tool's session carry on. Task runs are unaffected. While the bound runner is offline, revoked or deleted, queued runs and new turns wait instead of failing; `ConversationSummary.runner` (`id`, `name`, `status` `online|offline|revoked|missing`) lets the client say so, and `POST /api/agents/conversations/{conversationId}/switchRunner` (owner only) unbinds it, so the next eligible runner binds it and starts a fresh session with the history and the last summary. A session whose directory a runner's workspace report no longer lists is forgotten, so a cleaned directory also starts fresh with the history.
233
+
234
+ An application registers what conversations may be tied to with `conversations.links.registerKind({ key, title?, resolve? })`; `resolve(conn, userId, targetIds)` answers the views (`key`, `title`, `status`, `url`) the owner may see, reading only through `conn`. Owners tie and untie records with `GET|POST /api/agents/conversations/{conversationId}/links` and `DELETE …/links/{linkId}`; the application ties what a run created with `conversations.links.attach(conversationId, target, { origin: 'agent', outer? })`, finding the conversation with `conversations.ofRunId(runId)`. `GET /api/agents/conversations?linkKind=&linkTargetId=` lists the viewer's conversations tied to a record, and `conversations.links.linkedTo(conn, target)` every owner's, for delivering news to each. Each turn of a conversation lists its links as "Linked work" after the turn's first line; `conversations.rules.provide` may return `turn` sections as well, which never stop a session from resuming.
235
+
236
+ A turn that ends completed or failed while the owner has not seen everything sets `needsYou` (`reply`, `failed`), and a run's `conversation ask-owner "<question>"` (`POST /api/agents/runs/current/conversation/askOwner`) sets `confirm`, which waits until the owner writes. Each is announced once per turn as the `conversation.attention` event (`conversationId`, `userId`, `reason`, `seq`, `title`, `text`) for reminders and push; the client moves the read position with `POST …/markSeen { seq }` (`seenSeq`), which settles a reply or failure, and reads badge counts from `GET /api/agents/conversationAttention` (`unread`, `needsYou`). `conversations.markNoticed(id, seq)` records what the application already told the owner (`noticedSeq`).
237
+
238
+ ## Queued messages, usage and deletion
239
+
240
+ While a Runner conversation's agent works, `RealtimeOnlineAgent.queue(messages, input?)` (HTTP `POST /api/agents/conversations/{conversationId}/queue`, the same body as sending) joins one more user message to that work instead of refusing it as busy: the runner steers it into the running turn when its tool can, and takes it as the next turn otherwise. It answers the saved message, whose `metadata.queue` is `queued` until the agent takes it; one taken as the next turn gets an answer of its own, split from the run's response. `POST …/messages/{messageId}/withdraw` takes it back while no runner has it (`queue: 'withdrawn'`); once a runner has it the answer is `400 CONVERSATION_CONFLICT` with `metadata.reason` `messageTaken`. `queue` is refused (`409`) when the agent is not working: send the message instead. Native sessions do not implement it.
241
+
242
+ `GET /api/agents/conversations/{conversationId}/usage` sums the tokens of the conversation's runs and returns the latest context window and the cost, each `null` where the runs' coding tools do not report it. Each ended run closes its response with a `data-turn` part (duration, tokens, outcome), and the agent's todo list shows as a `data-plan` part. `DELETE /api/agents/conversations/{conversationId}` deletes the owner's conversation for good; archived conversations are deleted after `agents.conversations.archivedRetentionDays`.
243
+
230
244
  ## Runner conversation previews
231
245
 
232
246
  Upgrade the server agents plugin before runners. Conversation claims automatically include `outputBlocks: true` when the runner advertises the capability; tasks never receive it, and there is no application configuration switch. All task adapters, storage, summaries and run-history components keep their previous behavior.