@yadsh/dsh-qa-surface 0.2.0 → 0.4.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 (325) hide show
  1. package/README.md +236 -20
  2. package/compatibility.json +11 -3
  3. package/lib/account-remotes.js +100 -0
  4. package/lib/account-remotes.js.map +1 -0
  5. package/lib/accounts/credentials.js +27 -0
  6. package/lib/accounts/credentials.js.map +1 -0
  7. package/lib/accounts/errors.js +9 -0
  8. package/lib/accounts/errors.js.map +1 -0
  9. package/lib/accounts/file.js +101 -0
  10. package/lib/accounts/file.js.map +1 -0
  11. package/lib/accounts/index.js +2 -0
  12. package/lib/accounts/index.js.map +1 -0
  13. package/lib/accounts/store.js +461 -0
  14. package/lib/accounts/store.js.map +1 -0
  15. package/lib/accounts/token.js +61 -0
  16. package/lib/accounts/token.js.map +1 -0
  17. package/lib/attachment-rules.js +111 -0
  18. package/lib/attachment-rules.js.map +1 -0
  19. package/lib/attestation.js.map +1 -1
  20. package/lib/cli.js +256 -0
  21. package/lib/cli.js.map +1 -0
  22. package/lib/client/QaAccountsController.js +359 -0
  23. package/lib/client/QaAccountsController.js.map +1 -0
  24. package/lib/client/QaSessionController.js +238 -180
  25. package/lib/client/QaSessionController.js.map +1 -1
  26. package/lib/client/QaSurface.js +281 -105
  27. package/lib/client/QaSurface.js.map +1 -1
  28. package/lib/client/QaTranscriptAdapter.js +95 -244
  29. package/lib/client/QaTranscriptAdapter.js.map +1 -1
  30. package/lib/client/attachments.js +150 -0
  31. package/lib/client/attachments.js.map +1 -0
  32. package/lib/client/attestation.js +7 -1
  33. package/lib/client/attestation.js.map +1 -1
  34. package/lib/client/base64.js +16 -0
  35. package/lib/client/base64.js.map +1 -0
  36. package/lib/client/chat-files.js +48 -0
  37. package/lib/client/chat-files.js.map +1 -0
  38. package/lib/client/components/Markdown.js +54 -13
  39. package/lib/client/components/Markdown.js.map +1 -1
  40. package/lib/client/components/QaAuthGate.js +40 -0
  41. package/lib/client/components/QaAuthGate.js.map +1 -0
  42. package/lib/client/components/QaChangelog.js +131 -0
  43. package/lib/client/components/QaChangelog.js.map +1 -0
  44. package/lib/client/components/QaComposer.js +56 -74
  45. package/lib/client/components/QaComposer.js.map +1 -1
  46. package/lib/client/components/QaFileAttachment.js +19 -0
  47. package/lib/client/components/QaFileAttachment.js.map +1 -0
  48. package/lib/client/components/QaFilesPanel.js +45 -0
  49. package/lib/client/components/QaFilesPanel.js.map +1 -0
  50. package/lib/client/components/QaHeader.js +34 -0
  51. package/lib/client/components/QaHeader.js.map +1 -0
  52. package/lib/client/components/QaMessage.js +61 -18
  53. package/lib/client/components/QaMessage.js.map +1 -1
  54. package/lib/client/components/QaModal.js +31 -0
  55. package/lib/client/components/QaModal.js.map +1 -0
  56. package/lib/client/components/QaProfile.js +64 -0
  57. package/lib/client/components/QaProfile.js.map +1 -0
  58. package/lib/client/components/QaRightRail.js +15 -0
  59. package/lib/client/components/QaRightRail.js.map +1 -0
  60. package/lib/client/components/QaSidebar.js +68 -20
  61. package/lib/client/components/QaSidebar.js.map +1 -1
  62. package/lib/client/components/QaSourcesPanel.js +127 -0
  63. package/lib/client/components/QaSourcesPanel.js.map +1 -0
  64. package/lib/client/components/QaTurnRail.js +296 -0
  65. package/lib/client/components/QaTurnRail.js.map +1 -0
  66. package/lib/client/components/QaWelcomeNotice.js +125 -0
  67. package/lib/client/components/QaWelcomeNotice.js.map +1 -0
  68. package/lib/client/components/QaWidthHandle.js +147 -0
  69. package/lib/client/components/QaWidthHandle.js.map +1 -0
  70. package/lib/client/components/QaWorkGroup.js +19 -20
  71. package/lib/client/components/QaWorkGroup.js.map +1 -1
  72. package/lib/client/components/source-refs.js +78 -0
  73. package/lib/client/components/source-refs.js.map +1 -0
  74. package/lib/client/components/surface-utils.js +28 -0
  75. package/lib/client/components/surface-utils.js.map +1 -0
  76. package/lib/client/components/thinking-phrases.js +24 -0
  77. package/lib/client/components/thinking-phrases.js.map +1 -0
  78. package/lib/client/create-session.js +26 -0
  79. package/lib/client/create-session.js.map +1 -0
  80. package/lib/client/failure-copy.js +63 -0
  81. package/lib/client/failure-copy.js.map +1 -0
  82. package/lib/client/index.js +135 -16
  83. package/lib/client/index.js.map +1 -1
  84. package/lib/client/project-session-state.js +78 -0
  85. package/lib/client/project-session-state.js.map +1 -0
  86. package/lib/client/prompt-content.js +54 -0
  87. package/lib/client/prompt-content.js.map +1 -0
  88. package/lib/client/session-admission.js +38 -0
  89. package/lib/client/session-admission.js.map +1 -0
  90. package/lib/client/session-assets.js +52 -0
  91. package/lib/client/session-assets.js.map +1 -0
  92. package/lib/client/session-sources.js +61 -0
  93. package/lib/client/session-sources.js.map +1 -0
  94. package/lib/client/settings/card.js +143 -0
  95. package/lib/client/settings/card.js.map +1 -0
  96. package/lib/client/settings/fields.js +145 -0
  97. package/lib/client/settings/fields.js.map +1 -0
  98. package/lib/client/settings/format.js +255 -0
  99. package/lib/client/settings/format.js.map +1 -0
  100. package/lib/client/settings/sections/access.js +25 -0
  101. package/lib/client/settings/sections/access.js.map +1 -0
  102. package/lib/client/settings/sections/accounts.js +47 -0
  103. package/lib/client/settings/sections/accounts.js.map +1 -0
  104. package/lib/client/settings/sections/attachments.js +46 -0
  105. package/lib/client/settings/sections/attachments.js.map +1 -0
  106. package/lib/client/settings/sections/branding.js +28 -0
  107. package/lib/client/settings/sections/branding.js.map +1 -0
  108. package/lib/client/settings/sections/common.js +20 -0
  109. package/lib/client/settings/sections/common.js.map +1 -0
  110. package/lib/client/settings/sections/embedding.js +19 -0
  111. package/lib/client/settings/sections/embedding.js.map +1 -0
  112. package/lib/client/settings/sections/interface.js +60 -0
  113. package/lib/client/settings/sections/interface.js.map +1 -0
  114. package/lib/client/settings/sections/lockdown.js +82 -0
  115. package/lib/client/settings/sections/lockdown.js.map +1 -0
  116. package/lib/client/settings/sections/session.js +53 -0
  117. package/lib/client/settings/sections/session.js.map +1 -0
  118. package/lib/client/settings/sections/sources.js +72 -0
  119. package/lib/client/settings/sections/sources.js.map +1 -0
  120. package/lib/client/settings/sections/status.js +37 -0
  121. package/lib/client/settings/sections/status.js.map +1 -0
  122. package/lib/client/settings/sections.js +23 -0
  123. package/lib/client/settings/sections.js.map +1 -0
  124. package/lib/client/settings/styles.js +57 -0
  125. package/lib/client/settings/styles.js.map +1 -0
  126. package/lib/client/settlement.js +24 -0
  127. package/lib/client/settlement.js.map +1 -0
  128. package/lib/client/stream-publisher.js +47 -0
  129. package/lib/client/stream-publisher.js.map +1 -0
  130. package/lib/client/styles.js +225 -17
  131. package/lib/client/styles.js.map +1 -1
  132. package/lib/client/tool-presentation.js +102 -0
  133. package/lib/client/tool-presentation.js.map +1 -0
  134. package/lib/client/turn-sources.js +98 -0
  135. package/lib/client/turn-sources.js.map +1 -0
  136. package/lib/client/types.js +2 -0
  137. package/lib/client/types.js.map +1 -1
  138. package/lib/client/use-right-rail.js +96 -0
  139. package/lib/client/use-right-rail.js.map +1 -0
  140. package/lib/client/use-session-ui-state.js +75 -0
  141. package/lib/client/use-session-ui-state.js.map +1 -0
  142. package/lib/client/use-transcript-view.js +44 -0
  143. package/lib/client/use-transcript-view.js.map +1 -0
  144. package/lib/client.js +9052 -1345
  145. package/lib/client.js.map +1 -1
  146. package/lib/config-resolvers/accounts.js +60 -0
  147. package/lib/config-resolvers/accounts.js.map +1 -0
  148. package/lib/config-resolvers/attachments.js +28 -0
  149. package/lib/config-resolvers/attachments.js.map +1 -0
  150. package/lib/config-resolvers/basics.js +59 -0
  151. package/lib/config-resolvers/basics.js.map +1 -0
  152. package/lib/config-resolvers/defaults.js +132 -0
  153. package/lib/config-resolvers/defaults.js.map +1 -0
  154. package/lib/config-resolvers/lockdown.js +79 -0
  155. package/lib/config-resolvers/lockdown.js.map +1 -0
  156. package/lib/config-resolvers/session.js +42 -0
  157. package/lib/config-resolvers/session.js.map +1 -0
  158. package/lib/config-resolvers/shared.js +42 -0
  159. package/lib/config-resolvers/shared.js.map +1 -0
  160. package/lib/config-resolvers/sources.js +81 -0
  161. package/lib/config-resolvers/sources.js.map +1 -0
  162. package/lib/config-resolvers/ui.js +20 -0
  163. package/lib/config-resolvers/ui.js.map +1 -0
  164. package/lib/config.js +279 -102
  165. package/lib/config.js.map +1 -1
  166. package/lib/entry-redirect.js +45 -0
  167. package/lib/entry-redirect.js.map +1 -0
  168. package/lib/host-route.js +25 -1
  169. package/lib/host-route.js.map +1 -1
  170. package/lib/index.js +258 -23
  171. package/lib/index.js.map +1 -1
  172. package/lib/launch-token.js +42 -0
  173. package/lib/launch-token.js.map +1 -0
  174. package/lib/profile.js +214 -0
  175. package/lib/profile.js.map +1 -0
  176. package/lib/prompt-notes.js +231 -0
  177. package/lib/prompt-notes.js.map +1 -0
  178. package/lib/provenance/collector.js +40 -0
  179. package/lib/provenance/collector.js.map +1 -0
  180. package/lib/provenance/connectors.js +147 -0
  181. package/lib/provenance/connectors.js.map +1 -0
  182. package/lib/provenance/dedupe.js +89 -0
  183. package/lib/provenance/dedupe.js.map +1 -0
  184. package/lib/provenance/extractors.js +340 -0
  185. package/lib/provenance/extractors.js.map +1 -0
  186. package/lib/provenance/file-preview.js +39 -0
  187. package/lib/provenance/file-preview.js.map +1 -0
  188. package/lib/provenance/host-store.js +387 -0
  189. package/lib/provenance/host-store.js.map +1 -0
  190. package/lib/provenance/index.js +9 -0
  191. package/lib/provenance/index.js.map +1 -0
  192. package/lib/provenance/normalize.js +128 -0
  193. package/lib/provenance/normalize.js.map +1 -0
  194. package/lib/provenance/reported.js +53 -0
  195. package/lib/provenance/reported.js.map +1 -0
  196. package/lib/provenance/types.js +2 -0
  197. package/lib/provenance/types.js.map +1 -0
  198. package/lib/resolve-config.js +35 -249
  199. package/lib/resolve-config.js.map +1 -1
  200. package/lib/secure-session.js +122 -14
  201. package/lib/secure-session.js.map +1 -1
  202. package/lib/shared/session-key.js +18 -0
  203. package/lib/shared/session-key.js.map +1 -0
  204. package/lib/shared/settings.js +10 -0
  205. package/lib/shared/settings.js.map +1 -0
  206. package/lib/thinking-phrases.js +68 -0
  207. package/lib/thinking-phrases.js.map +1 -0
  208. package/lib/typert.host.js +749 -11
  209. package/lib/typert.remote-client.d.ts +23 -3
  210. package/lib/typert.remote-client.js +593 -6
  211. package/lib/types/account-remotes.d.ts +42 -0
  212. package/lib/types/accounts/credentials.d.ts +14 -0
  213. package/lib/types/accounts/errors.d.ts +11 -0
  214. package/lib/types/accounts/file.d.ts +82 -0
  215. package/lib/types/accounts/index.d.ts +2 -0
  216. package/lib/types/accounts/store.d.ts +144 -0
  217. package/lib/types/accounts/token.d.ts +31 -0
  218. package/lib/types/attachment-rules.d.ts +44 -0
  219. package/lib/types/attestation.d.ts +1 -1
  220. package/lib/types/cli.d.ts +9 -0
  221. package/lib/types/client/QaAccountsController.d.ts +102 -0
  222. package/lib/types/client/QaConfigController.d.ts +1 -1
  223. package/lib/types/client/QaSessionController.d.ts +61 -22
  224. package/lib/types/client/QaSurface.d.ts +14 -3
  225. package/lib/types/client/QaTranscriptAdapter.d.ts +5 -10
  226. package/lib/types/client/attachments.d.ts +54 -0
  227. package/lib/types/client/base64.d.ts +10 -0
  228. package/lib/types/client/chat-files.d.ts +30 -0
  229. package/lib/types/client/components/Markdown.d.ts +11 -1
  230. package/lib/types/client/components/QaAgentsDrawer.d.ts +1 -1
  231. package/lib/types/client/components/QaAuthGate.d.ts +15 -0
  232. package/lib/types/client/components/QaChangelog.d.ts +21 -0
  233. package/lib/types/client/components/QaComposer.d.ts +8 -4
  234. package/lib/types/client/components/QaFileAttachment.d.ts +14 -0
  235. package/lib/types/client/components/QaFilesPanel.d.ts +15 -0
  236. package/lib/types/client/components/QaHeader.d.ts +41 -0
  237. package/lib/types/client/components/QaMessage.d.ts +12 -3
  238. package/lib/types/client/components/QaModal.d.ts +26 -0
  239. package/lib/types/client/components/QaProfile.d.ts +25 -0
  240. package/lib/types/client/components/QaRightRail.d.ts +23 -0
  241. package/lib/types/client/components/QaSidebar.d.ts +44 -2
  242. package/lib/types/client/components/QaSourcesPanel.d.ts +23 -0
  243. package/lib/types/client/components/QaTurnRail.d.ts +65 -0
  244. package/lib/types/client/components/QaWelcomeNotice.d.ts +27 -0
  245. package/lib/types/client/components/QaWidthHandle.d.ts +43 -0
  246. package/lib/types/client/components/QaWorkGroup.d.ts +5 -3
  247. package/lib/types/client/components/source-refs.d.ts +16 -0
  248. package/lib/types/client/components/surface-utils.d.ts +11 -0
  249. package/lib/types/client/components/thinking-phrases.d.ts +9 -0
  250. package/lib/types/client/create-session.d.ts +13 -0
  251. package/lib/types/client/failure-copy.d.ts +19 -0
  252. package/lib/types/client/index.d.ts +1 -0
  253. package/lib/types/client/project-session-state.d.ts +30 -0
  254. package/lib/types/client/prompt-content.d.ts +30 -0
  255. package/lib/types/client/session-admission.d.ts +23 -0
  256. package/lib/types/client/session-assets.d.ts +20 -0
  257. package/lib/types/client/session-sources.d.ts +28 -0
  258. package/lib/types/client/settings/card.d.ts +23 -0
  259. package/lib/types/client/settings/fields.d.ts +139 -0
  260. package/lib/types/client/settings/format.d.ts +108 -0
  261. package/lib/types/client/settings/sections/access.d.ts +9 -0
  262. package/lib/types/client/settings/sections/accounts.d.ts +9 -0
  263. package/lib/types/client/settings/sections/attachments.d.ts +15 -0
  264. package/lib/types/client/settings/sections/branding.d.ts +8 -0
  265. package/lib/types/client/settings/sections/common.d.ts +28 -0
  266. package/lib/types/client/settings/sections/embedding.d.ts +8 -0
  267. package/lib/types/client/settings/sections/interface.d.ts +9 -0
  268. package/lib/types/client/settings/sections/lockdown.d.ts +9 -0
  269. package/lib/types/client/settings/sections/session.d.ts +9 -0
  270. package/lib/types/client/settings/sections/sources.d.ts +9 -0
  271. package/lib/types/client/settings/sections/status.d.ts +22 -0
  272. package/lib/types/client/settings/sections.d.ts +25 -0
  273. package/lib/types/client/settings/styles.d.ts +8 -0
  274. package/lib/types/client/settlement.d.ts +6 -0
  275. package/lib/types/client/stream-publisher.d.ts +28 -0
  276. package/lib/types/client/tool-presentation.d.ts +6 -0
  277. package/lib/types/client/turn-sources.d.ts +14 -0
  278. package/lib/types/client/types.d.ts +101 -9
  279. package/lib/types/client/use-right-rail.d.ts +56 -0
  280. package/lib/types/client/use-session-ui-state.d.ts +41 -0
  281. package/lib/types/client/use-transcript-view.d.ts +20 -0
  282. package/lib/types/config-resolvers/accounts.d.ts +15 -0
  283. package/lib/types/config-resolvers/attachments.d.ts +6 -0
  284. package/lib/types/config-resolvers/basics.d.ts +8 -0
  285. package/lib/types/config-resolvers/defaults.d.ts +4 -0
  286. package/lib/types/config-resolvers/lockdown.d.ts +10 -0
  287. package/lib/types/config-resolvers/session.d.ts +6 -0
  288. package/lib/types/config-resolvers/shared.d.ts +16 -0
  289. package/lib/types/config-resolvers/sources.d.ts +6 -0
  290. package/lib/types/config-resolvers/ui.d.ts +6 -0
  291. package/lib/types/entry-redirect.d.ts +20 -0
  292. package/lib/types/host-route.d.ts +14 -1
  293. package/lib/types/index.d.ts +54 -3
  294. package/lib/types/launch-token.d.ts +21 -0
  295. package/lib/types/profile.d.ts +76 -0
  296. package/lib/types/prompt-notes.d.ts +110 -0
  297. package/lib/types/provenance/collector.d.ts +26 -0
  298. package/lib/types/provenance/connectors.d.ts +11 -0
  299. package/lib/types/provenance/dedupe.d.ts +6 -0
  300. package/lib/types/provenance/extractors.d.ts +14 -0
  301. package/lib/types/provenance/file-preview.d.ts +10 -0
  302. package/lib/types/provenance/host-store.d.ts +54 -0
  303. package/lib/types/provenance/index.d.ts +10 -0
  304. package/lib/types/provenance/normalize.d.ts +13 -0
  305. package/lib/types/provenance/reported.d.ts +5 -0
  306. package/lib/types/provenance/types.d.ts +78 -0
  307. package/lib/types/resolve-config.d.ts +8 -3
  308. package/lib/types/secure-session.d.ts +36 -2
  309. package/lib/types/shared/session-key.d.ts +23 -0
  310. package/lib/types/shared/settings.d.ts +10 -0
  311. package/lib/types/thinking-phrases.d.ts +17 -0
  312. package/lib/types/types.d.ts +290 -16
  313. package/lib/types/user-workspace.d.ts +38 -0
  314. package/lib/user-workspace.js +231 -0
  315. package/lib/user-workspace.js.map +1 -0
  316. package/package.json +71 -47
  317. package/CHANGELOG.md +0 -93
  318. package/SPEC-dsh-qa-surface.md +0 -2425
  319. package/docs/ARCHITECTURE.md +0 -66
  320. package/docs/COMPATIBILITY.md +0 -14
  321. package/docs/CONFIGURATION.md +0 -112
  322. package/docs/EMBEDDING.md +0 -13
  323. package/lib/client/components/QaSourcesDrawer.js +0 -46
  324. package/lib/client/components/QaSourcesDrawer.js.map +0 -1
  325. package/lib/types/client/components/QaSourcesDrawer.d.ts +0 -8
@@ -1,12 +1,24 @@
1
1
  import qaSurfaceRemote from "@yadsh/dsh-qa-surface/remote";
2
+ import { registerSettingsCard } from "@yadsh/dsh-plugin-kit/client";
2
3
  import { QaConfigController } from "./QaConfigController.js";
3
- import { QaRouteController } from "./QaRouteController.js";
4
+ import { matchesQaRoute, QaRouteController } from "./QaRouteController.js";
5
+ import { QaAccountsController } from "./QaAccountsController.js";
6
+ import { QaChatIndex } from "./chat-index.js";
4
7
  import { QaSurface } from "./QaSurface.js";
8
+ import { QaWelcomeNoticeStep } from "./components/QaWelcomeNotice.js";
5
9
  import { QA_SURFACE_STYLES } from "./styles.js";
6
- const SETTINGS_NAMESPACE = "qa-surface";
10
+ import { QA_SURFACE_SETTINGS_NAMESPACE } from "../shared/settings.js";
11
+ import { qaStorageNamespace } from "../shared/session-key.js";
12
+ import { QaSettingsCard } from "./settings/card.js";
13
+ import { QA_SETTINGS_STYLES } from "./settings/styles.js";
14
+ const QA_WELCOME_SLOT_ID = "welcome-notice";
15
+ function qaWelcomeStorageKey(config) {
16
+ return `${qaStorageNamespace(config)}:welcome-notice`;
17
+ }
7
18
  export const inject = [
8
19
  "slots",
9
20
  "sessions",
21
+ "uiConversation",
10
22
  "connection",
11
23
  "settingsScope",
12
24
  "remote",
@@ -15,26 +27,74 @@ export const inject = [
15
27
  export async function apply(ctx) {
16
28
  const remote = ctx.remote;
17
29
  const disposeRemote = await remote.$mount(qaSurfaceRemote);
18
- await ctx.inject(["remote.qaSurface"], (remoteContext) => {
19
- const policyRemote = remoteContext.remote
20
- .qaSurface;
21
- const secureSession = (sessionId) => policyRemote.secureSession(sessionId);
30
+ await ctx.inject(["remote.qaSurface", "remote.session", "remote.agentPresets"], (remoteContext) => {
31
+ const injectedRemote = remoteContext.remote;
32
+ const policyRemote = injectedRemote.qaSurface;
33
+ const secureSession = (token, sessionId) => policyRemote.secureSession(token, sessionId);
22
34
  const qaApi = {
23
- selectModel: ctx.connection.api.sessions.selectModel,
24
- selectAgentPreset: ctx.connection.api.agentPresets.select,
35
+ selectModel: (request) => injectedRemote.session.selectModel(request),
36
+ selectAgentPreset: (agentId, agentPreset) => injectedRemote.agentPresets.select(agentId, agentPreset),
37
+ };
38
+ const sourceApi = {
39
+ sources: (token, sessionId) => policyRemote.sources(token, sessionId),
40
+ readSourceFile: (token, sessionId, sourcePath) => policyRemote.readSourceFile(token, sessionId, sourcePath),
25
41
  };
42
+ // The account gate rides its own remote; a stale token simply answers
43
+ // "not authenticated" and the browser shows the login card.
44
+ const accounts = new QaAccountsController({
45
+ remote: policyRemote,
46
+ storage: window.localStorage,
47
+ config: () => config.getSnapshot().config,
48
+ legacyChatIds: () => {
49
+ // A standalone index view over the same prefix: reads the chat ids
50
+ // this browser accumulated before accounts existed.
51
+ const snapshot = config.getSnapshot().config;
52
+ const index = new QaChatIndex(window.localStorage, qaStorageNamespace(snapshot));
53
+ const ids = [...index.chatIds()];
54
+ const active = index.activeId();
55
+ if (active !== null && !ids.includes(active))
56
+ ids.push(active);
57
+ return ids;
58
+ },
59
+ forgetChat: (sessionId) => {
60
+ const snapshot = config.getSnapshot().config;
61
+ new QaChatIndex(window.localStorage, qaStorageNamespace(snapshot)).forgetChat(sessionId);
62
+ },
63
+ });
26
64
  const route = new QaRouteController();
27
- const config = new QaConfigController(ctx.settingsScope.bind({
28
- namespace: SETTINGS_NAMESPACE,
29
- }), async () => {
65
+ // One binding for both readers: the surface projects it into the page's
66
+ // configuration, the settings card edits the same namespace through it.
67
+ const settingsScope = ctx.settingsScope.bind({
68
+ namespace: QA_SURFACE_SETTINGS_NAMESPACE,
69
+ });
70
+ const config = new QaConfigController(settingsScope, async () => {
30
71
  // Settings RPCs are loopback-pinned by the gateway, so a browser the
31
72
  // Host serves over the LAN reads the effective configuration here.
32
73
  const described = await policyRemote.describe();
33
74
  if (!described.ok) {
34
75
  throw new Error(`qaSurface/describe failed: ${described.error.code}`);
35
76
  }
77
+ // The generated self-remote resolves through the previous build's
78
+ // declarations during an incremental source typecheck.
36
79
  return described.value;
37
80
  });
81
+ // The operator edits this deployment through the shared plugin-cards
82
+ // tab: the same namespace the page reads, plus the Host's own answer
83
+ // about what it resolved. Its stylesheet is the card shell, not the QA
84
+ // page's palette.
85
+ ctx.effect(() => {
86
+ const cardFace = {
87
+ scope: settingsScope,
88
+ describe: () => policyRemote.describe(),
89
+ };
90
+ return registerSettingsCard(remoteContext, {
91
+ key: QA_SURFACE_SETTINGS_NAMESPACE,
92
+ pluginName: "@yadsh/dsh-qa-surface",
93
+ styles: QA_SETTINGS_STYLES,
94
+ component: QaSettingsCard,
95
+ inject: () => cardFace,
96
+ });
97
+ }, "dsh-qa-surface: settings-card");
38
98
  const syncRoute = () => {
39
99
  const snapshot = config.getSnapshot();
40
100
  route.configure(snapshot.config, snapshot.status === "ready" || snapshot.status === "unavailable");
@@ -46,13 +106,59 @@ export async function apply(ctx) {
46
106
  // refuses. Loopback pages follow the settings mirror; this covers the
47
107
  // describe fallback (LAN browsers). Fires on every lost→restored
48
108
  // connection transition; while connected, ticks are ignored.
49
- let connectionUp = ctx.connection.hostDescription.getSnapshot() !== undefined;
50
- const unsubscribeConnection = ctx.connection.hostDescription.subscribe(() => {
51
- const connected = ctx.connection.hostDescription.getSnapshot() !== undefined;
52
- if (connected && !connectionUp)
109
+ let connectionUp = ctx.connection.generation.getSnapshot() !== undefined;
110
+ const unsubscribeConnection = ctx.connection.generation.subscribe(() => {
111
+ const connected = ctx.connection.generation.getSnapshot() !== undefined;
112
+ if (connected && !connectionUp) {
53
113
  config.refreshFallback();
114
+ // A boot-time whoami may have raced the lost connection; the
115
+ // controller no-ops unless it is still in the checking stage.
116
+ void accounts.start();
117
+ }
54
118
  connectionUp = connected;
55
119
  });
120
+ void accounts.start();
121
+ // The stock DSH welcome notice cannot persist its acknowledgement for
122
+ // non-loopback browsers. Shadow only its list-slot cell while the QA
123
+ // route is selected; leaving /qa immediately restores the host entry.
124
+ ctx.slots.inject("settings.onboarding", () => {
125
+ let removeEntry;
126
+ let mountedKey;
127
+ const reconcile = () => {
128
+ const configSnapshot = config.getSnapshot().config;
129
+ const routeSnapshot = route.getSnapshot();
130
+ const active = configSnapshot.enabled &&
131
+ matchesQaRoute(routeSnapshot.pathname, configSnapshot.route);
132
+ const nextKey = active
133
+ ? qaWelcomeStorageKey(configSnapshot)
134
+ : undefined;
135
+ if (nextKey === mountedKey)
136
+ return;
137
+ removeEntry?.();
138
+ removeEntry = undefined;
139
+ mountedKey = nextKey;
140
+ if (nextKey === undefined)
141
+ return;
142
+ removeEntry = ctx.slots.register({
143
+ name: "settings.onboarding",
144
+ id: QA_WELCOME_SLOT_ID,
145
+ order: -100,
146
+ priority: -1_000,
147
+ inject: () => ({
148
+ storage: window.localStorage,
149
+ storageKey: nextKey,
150
+ }),
151
+ }, QaWelcomeNoticeStep);
152
+ };
153
+ reconcile();
154
+ const unsubscribeRoute = route.subscribe(reconcile);
155
+ const unsubscribeConfig = config.subscribe(reconcile);
156
+ return () => {
157
+ unsubscribeRoute();
158
+ unsubscribeConfig();
159
+ removeEntry?.();
160
+ };
161
+ });
56
162
  ctx.effect(() => {
57
163
  const style = document.createElement("style");
58
164
  style.dataset.dshQaSurface = "styles";
@@ -73,16 +179,29 @@ export async function apply(ctx) {
73
179
  inject: () => ({
74
180
  route,
75
181
  config,
182
+ // The host dsh-session merge types ctx.sessions as SessionStore in
183
+ // this program; the client assembly provides the ISessions face.
76
184
  sessions: ctx.sessions,
185
+ conversation: ctx.uiConversation,
77
186
  api: qaApi,
78
- connection: ctx.connection.hostDescription,
187
+ connection: ctx.connection.generation,
79
188
  secureSession,
189
+ createSession: (token) => policyRemote.createSession(token),
190
+ sourceApi,
191
+ accounts,
192
+ // The upload service is optional on the page: a deployment that
193
+ // does not serve it keeps images, and a staged file refuses the
194
+ // send with a message instead of losing the draft. Read through
195
+ // the untyped service lookup on purpose — the QA bundle does not
196
+ // link the upload package.
197
+ fileUpload: () => ctx.get("fileUpload"),
80
198
  }),
81
199
  }, QaSurface));
82
200
  });
83
201
  return disposeRemote;
84
202
  }
85
203
  export { QaConfigController } from "./QaConfigController.js";
204
+ export { QaAccountsController } from "./QaAccountsController.js";
86
205
  export { QaRouteController, matchesQaRoute } from "./QaRouteController.js";
87
206
  export { QaSessionController } from "./QaSessionController.js";
88
207
  export { projectTranscript } from "./QaTranscriptAdapter.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/client/index.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/client/index.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,78 @@
1
+ import { projectTranscript } from "./QaTranscriptAdapter.js";
2
+ /**
3
+ * Project one bound chat into the observable surface state: phase, transcript
4
+ * with per-turn sources, footer sources, and the composer's capabilities.
5
+ * Side effects (host-bundle refresh, notifications) live in the controller.
6
+ */
7
+ export function projectBoundSessionState(input) {
8
+ const { config, sessionSnapshot: snapshot } = input;
9
+ // A pending approval interaction is invisible to this snapshot in 0.1.5;
10
+ // the QA lockdown pins approval=never and strips escalation-requiring
11
+ // tools, so no interaction the surface cannot answer should ever arise.
12
+ const error = input.operationError ??
13
+ (snapshot.removed || snapshot.openState === "error"
14
+ ? "Этот чат больше недоступен."
15
+ : null);
16
+ const phase = !input.connected
17
+ ? "reconnecting"
18
+ : snapshot.removed || snapshot.openState === "error"
19
+ ? "error"
20
+ : snapshot.openState !== "open"
21
+ ? "creating"
22
+ : snapshot.running || input.admissionPending
23
+ ? "running"
24
+ : "ready";
25
+ const sourcesByTurn = new Map(input.sourceBundles.map((bundle) => [bundle.turn, bundle]));
26
+ const messages = projectTranscript(input.conversationSnapshot, {
27
+ running: snapshot.running,
28
+ showToolActivity: config.ui.showToolActivity,
29
+ showReasoning: config.ui.showReasoning,
30
+ }).map((message) => {
31
+ if (message.role === "user" && input.author !== undefined) {
32
+ return { ...message, author: input.author };
33
+ }
34
+ if (message.role !== "assistant" || message.turn === undefined)
35
+ return message;
36
+ const bundle = sourcesByTurn.get(message.turn);
37
+ const sources = bundle === undefined
38
+ ? undefined
39
+ : [
40
+ ...bundle.sources,
41
+ ...(config.sources.display.showDiscovered
42
+ ? (bundle.discovered ?? [])
43
+ : []),
44
+ ];
45
+ return sources === undefined || sources.length === 0
46
+ ? message
47
+ : {
48
+ ...message,
49
+ sources,
50
+ sourcesComplete: bundle?.complete ?? true,
51
+ ...(bundle?.incompleteOrigins === undefined
52
+ ? {}
53
+ : { incompleteSourceOrigins: bundle.incompleteOrigins }),
54
+ };
55
+ });
56
+ const latest = input.sourceBundles.at(-1);
57
+ return {
58
+ phase,
59
+ sessionId: input.sessionId,
60
+ messages,
61
+ error,
62
+ canSend: input.connected && phase === "ready" && input.policyReady,
63
+ canStop: input.connected && snapshot.running && config.ui.showStop,
64
+ chatsRevision: input.chatsRevision,
65
+ sources: latest === undefined
66
+ ? []
67
+ : [
68
+ ...latest.sources,
69
+ ...(config.sources.display.showDiscovered
70
+ ? (latest.discovered ?? [])
71
+ : []),
72
+ ],
73
+ sourcesComplete: latest?.complete ?? true,
74
+ incompleteSourceOrigins: latest?.incompleteOrigins,
75
+ viewingSubagent: input.viewingSubagent,
76
+ };
77
+ }
78
+ //# sourceMappingURL=project-session-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-session-state.js","sourceRoot":"","sources":["../../src/client/project-session-state.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Stage every pending file on the Host and collect the receipts the prompt
3
+ * cites. Sequential on purpose: a partial batch must be attributable to the
4
+ * exact file that failed, and the visitor's file counts are small.
5
+ * `service` is undefined on a page the deployment serves without the upload
6
+ * plugin, which leaves attachments unavailable rather than broken. The
7
+ * receipt is opaque and host-minted — the upload service answers with a
8
+ * plain string, and only the session wire brand knows it as an id.
9
+ */
10
+ export async function stageQaFiles(service, session, files) {
11
+ if (service === undefined)
12
+ return { kind: "unavailable" };
13
+ const receipts = new Map();
14
+ for (const file of files) {
15
+ try {
16
+ const result = await service.upload(session.sessionId, file.blob, file.name);
17
+ if (!result.ok) {
18
+ console.error("dsh-qa-surface: file upload refused", result.error);
19
+ return { kind: "failed" };
20
+ }
21
+ receipts.set(file.id, result.value.receiptId);
22
+ }
23
+ catch (error) {
24
+ console.error("dsh-qa-surface: file upload failed", error);
25
+ return { kind: "failed" };
26
+ }
27
+ }
28
+ return { kind: "ok", receipts };
29
+ }
30
+ /**
31
+ * Assemble the wire content of one prompt: the text part, images riding the
32
+ * prompt inline, and files cited by their staged receipts. The visitor's own
33
+ * order decides the prompt order, so images and files are assembled from one
34
+ * walk over the drafts; an unpaired file receipt (a draft kept while its
35
+ * staging failed elsewhere) degrades to an empty receipt rather than
36
+ * dropping the attachment.
37
+ */
38
+ export function buildQaPromptContent(prompt, attachments, receipts) {
39
+ return [
40
+ ...(prompt === "" ? [] : [{ type: "text", text: prompt }]),
41
+ ...attachments.map((attachment) => attachment.kind === "image"
42
+ ? {
43
+ type: "image",
44
+ mediaType: attachment.mediaType,
45
+ data: attachment.data,
46
+ name: attachment.name,
47
+ }
48
+ : {
49
+ type: "file",
50
+ receiptId: receipts.get(attachment.id) ?? "",
51
+ }),
52
+ ];
53
+ }
54
+ //# sourceMappingURL=prompt-content.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt-content.js","sourceRoot":"","sources":["../../src/client/prompt-content.ts"],"names":[],"mappings":"AAIA;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,OAAiC,EACjC,OAAoB,EACpB,KAA6B;IAM7B,IAAI,OAAO,KAAK,SAAS;QAAE,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC;IAC1D,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC3C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,MAAM,CACjC,OAAO,CAAC,SAAS,EACjB,IAAI,CAAC,IAAI,EACT,IAAI,CAAC,IAAI,CACV,CAAC;YACF,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;gBACf,OAAO,CAAC,KAAK,CAAC,qCAAqC,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;gBACnE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;YAC5B,CAAC;YACD,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QAChD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,oCAAoC,EAAE,KAAK,CAAC,CAAC;YAC3D,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;QAC5B,CAAC;IACH,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;AAClC,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,oBAAoB,CAClC,MAAc,EACd,WAAyC,EACzC,QAAqC;IAErC,OAAO;QACL,GAAG,CAAC,MAAM,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;QACnE,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAChC,UAAU,CAAC,IAAI,KAAK,OAAO;YACzB,CAAC,CAAC;gBACE,IAAI,EAAE,OAAgB;gBACtB,SAAS,EAAE,UAAU,CAAC,SAAS;gBAC/B,IAAI,EAAE,UAAU,CAAC,IAAI;gBACrB,IAAI,EAAE,UAAU,CAAC,IAAI;aACtB;YACH,CAAC,CAAC;gBACE,IAAI,EAAE,MAAe;gBACrB,SAAS,EAAE,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE;aAC7C,CACN;KACiB,CAAC;AACvB,CAAC"}
@@ -0,0 +1,38 @@
1
+ import { attestationHint, attestationReasonOf, proofMatchesConfig, } from "./attestation.js";
2
+ /**
3
+ * One send-time policy attestation against the Host admission gate. The
4
+ * QA-facing message stays generic by design; the coarse reason plus an
5
+ * operator hint go to the console once per refusal.
6
+ */
7
+ export async function attestQaPolicy(args) {
8
+ try {
9
+ const result = await args.secureSession(args.token, args.sessionId);
10
+ if (!result.ok) {
11
+ const reason = attestationReasonOf(result.error);
12
+ if (reason === "auth-required") {
13
+ if (args.report) {
14
+ console.error("dsh-qa-surface: policy attestation failed (reason: auth-required). The account token is absent or expired.");
15
+ }
16
+ return { ok: false, authRequired: true, reason };
17
+ }
18
+ return reject(args, reason);
19
+ }
20
+ if (!proofMatchesConfig(result.value, args.lockdown, args.sessionId)) {
21
+ return reject(args, "proof-mismatch");
22
+ }
23
+ return { ok: true };
24
+ }
25
+ catch (error) {
26
+ if (args.report) {
27
+ console.error("dsh-qa-surface: policy attestation request failed", error);
28
+ }
29
+ return { ok: false, authRequired: false, reason: null };
30
+ }
31
+ }
32
+ function reject(args, reason) {
33
+ if (args.report) {
34
+ console.error(`dsh-qa-surface: policy attestation failed (reason: ${reason ?? "unknown"}). ${attestationHint(reason)}`);
35
+ }
36
+ return { ok: false, authRequired: false, reason };
37
+ }
38
+ //# sourceMappingURL=session-admission.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-admission.js","sourceRoot":"","sources":["../../src/client/session-admission.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,kBAAkB,CAAC;AAa1B;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAMpC;IACC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QACpE,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;YACf,MAAM,MAAM,GAAG,mBAAmB,CAChC,MAAM,CAAC,KAAsC,CAC9C,CAAC;YACF,IAAI,MAAM,KAAK,eAAe,EAAE,CAAC;gBAC/B,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;oBAChB,OAAO,CAAC,KAAK,CACX,4GAA4G,CAC7G,CAAC;gBACJ,CAAC;gBACD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;YACnD,CAAC;YACD,OAAO,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAC9B,CAAC;QACD,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;YACrE,OAAO,MAAM,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;QACxC,CAAC;QACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IACtB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,OAAO,CAAC,KAAK,CAAC,mDAAmD,EAAE,KAAK,CAAC,CAAC;QAC5E,CAAC;QACD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IAC1D,CAAC;AACH,CAAC;AAED,SAAS,MAAM,CACb,IAAkC,EAClC,MAAqB;IAErB,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;QAChB,OAAO,CAAC,KAAK,CACX,sDAAsD,MAAM,IAAI,SAAS,MAAM,eAAe,CAAC,MAAM,CAAC,EAAE,CACzG,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AACpD,CAAC"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Per-chat cache of resolved attachment URLs. Attachment reads are
3
+ * session-scoped (the loader reads the bound session's durable store), and
4
+ * attachment ids are only unique within a chat, so both the cache and the
5
+ * blob lifetime are keyed by chat, not by the page.
6
+ */
7
+ export class SessionAssetRepository {
8
+ bySession = new Map();
9
+ /** Resolve one attachment of one chat, deduplicating concurrent reads. */
10
+ resolve(sessionId, attachmentId, load) {
11
+ const byAttachment = this.bySession.get(sessionId) ?? new Map();
12
+ this.bySession.set(sessionId, byAttachment);
13
+ let pending = byAttachment.get(attachmentId);
14
+ if (pending === undefined) {
15
+ pending = load(attachmentId);
16
+ byAttachment.set(attachmentId, pending);
17
+ // A failed read must not poison the slot: the broken view retries by
18
+ // re-resolving on demand.
19
+ pending.catch(() => {
20
+ if (byAttachment.get(attachmentId) === pending)
21
+ byAttachment.delete(attachmentId);
22
+ });
23
+ }
24
+ return pending;
25
+ }
26
+ /**
27
+ * Revoke the chat's blob URLs and drop its cache. Data URLs need no
28
+ * revocation; a failed resolution never produced a URL at all.
29
+ */
30
+ release(sessionId) {
31
+ const byAttachment = this.bySession.get(sessionId);
32
+ if (byAttachment === undefined)
33
+ return;
34
+ this.bySession.delete(sessionId);
35
+ for (const pending of byAttachment.values())
36
+ void pending.then(revokeIfBlob, () => undefined);
37
+ }
38
+ dispose() {
39
+ for (const sessionId of [...this.bySession.keys()])
40
+ this.release(sessionId);
41
+ }
42
+ }
43
+ function revokeIfBlob(url) {
44
+ revokeObjectUrlIfBlob(url);
45
+ }
46
+ /** Revoke one blob URL; data URLs (and other runtimes) need nothing. */
47
+ export function revokeObjectUrlIfBlob(url) {
48
+ if (url.startsWith("blob:") && typeof URL.revokeObjectURL === "function") {
49
+ URL.revokeObjectURL(url);
50
+ }
51
+ }
52
+ //# sourceMappingURL=session-assets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-assets.js","sourceRoot":"","sources":["../../src/client/session-assets.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,OAAO,sBAAsB;IAChB,SAAS,GAAG,IAAI,GAAG,EAAwC,CAAC;IAE7E,0EAA0E;IAC1E,OAAO,CACL,SAAiB,EACjB,YAAoB,EACpB,IAA+C;QAE/C,MAAM,YAAY,GAChB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,IAAI,GAAG,EAA2B,CAAC;QACtE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;QAC5C,IAAI,OAAO,GAAG,YAAY,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QAC7C,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1B,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC;YAC7B,YAAY,CAAC,GAAG,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;YACxC,qEAAqE;YACrE,0BAA0B;YAC1B,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE;gBACjB,IAAI,YAAY,CAAC,GAAG,CAAC,YAAY,CAAC,KAAK,OAAO;oBAC5C,YAAY,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;YACtC,CAAC,CAAC,CAAC;QACL,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;;OAGG;IACH,OAAO,CAAC,SAAiB;QACvB,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACnD,IAAI,YAAY,KAAK,SAAS;YAAE,OAAO;QACvC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QACjC,KAAK,MAAM,OAAO,IAAI,YAAY,CAAC,MAAM,EAAE;YACzC,KAAK,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IACrD,CAAC;IAED,OAAO;QACL,KAAK,MAAM,SAAS,IAAI,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;YAAE,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAC9E,CAAC;CACF;AAED,SAAS,YAAY,CAAC,GAAW;IAC/B,qBAAqB,CAAC,GAAG,CAAC,CAAC;AAC7B,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,qBAAqB,CAAC,GAAW;IAC/C,IAAI,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,OAAO,GAAG,CAAC,eAAe,KAAK,UAAU,EAAE,CAAC;QACzE,GAAG,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;AACH,CAAC"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Host-side provenance of the bound chat. The client projects turn sources
3
+ * from durable conversation events; the Host bundle (which also carries
4
+ * subagent-inherited evidence) is fetched on the side and merged by turn,
5
+ * Host data winning over the projection.
6
+ */
7
+ export class QaHostSourceBridge {
8
+ sourceApi;
9
+ token;
10
+ bundles = [];
11
+ signature = "";
12
+ refreshing = false;
13
+ /** Bumped on reset so a stale in-flight fetch never lands. */
14
+ generation = 0;
15
+ constructor(sourceApi, token) {
16
+ this.sourceApi = sourceApi;
17
+ this.token = token;
18
+ }
19
+ /** Leave the chat: drop its bundles; merging degrades to the projection. */
20
+ reset() {
21
+ this.generation += 1;
22
+ this.bundles = [];
23
+ this.signature = "";
24
+ this.refreshing = false;
25
+ }
26
+ merge(projected) {
27
+ const merged = new Map();
28
+ for (const bundle of projected)
29
+ merged.set(bundle.turn, bundle);
30
+ for (const bundle of this.bundles)
31
+ merged.set(bundle.turn, bundle);
32
+ return [...merged.values()].sort((left, right) => left.turn - right.turn);
33
+ }
34
+ /**
35
+ * Fetch the Host bundles of one chat; a changed payload republishes through
36
+ * the callback. Repeated calls coalesce while one is in flight, and a
37
+ * response that outlives the chat is dropped.
38
+ */
39
+ async refresh(sessionId, onChanged) {
40
+ if (this.refreshing)
41
+ return;
42
+ const generation = this.generation;
43
+ this.refreshing = true;
44
+ try {
45
+ const result = await this.sourceApi.sources(this.token(), sessionId);
46
+ if (!result.ok || generation !== this.generation)
47
+ return;
48
+ const signature = JSON.stringify(result.value);
49
+ if (signature === this.signature)
50
+ return;
51
+ this.signature = signature;
52
+ this.bundles = result.value;
53
+ onChanged();
54
+ }
55
+ finally {
56
+ if (generation === this.generation)
57
+ this.refreshing = false;
58
+ }
59
+ }
60
+ }
61
+ //# sourceMappingURL=session-sources.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-sources.js","sourceRoot":"","sources":["../../src/client/session-sources.ts"],"names":[],"mappings":"AAGA;;;;;GAKG;AACH,MAAM,OAAO,kBAAkB;IAQV,SAAS;IACT,KAAK;IARhB,OAAO,GAA6B,EAAE,CAAC;IACvC,SAAS,GAAG,EAAE,CAAC;IACf,UAAU,GAAG,KAAK,CAAC;IAC3B,8DAA8D;IACtD,UAAU,GAAG,CAAC,CAAC;IAEvB,YACmB,SAAsB,EACtB,KAAmB;yBADnB,SAAS;qBACT,KAAK;IACrB,CAAC;IAEJ,4EAA4E;IAC5E,KAAK;QACH,IAAI,CAAC,UAAU,IAAI,CAAC,CAAC;QACrB,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC;QAClB,IAAI,CAAC,SAAS,GAAG,EAAE,CAAC;QACpB,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;IAC1B,CAAC;IAED,KAAK,CAAC,SAAmC;QACvC,MAAM,MAAM,GAAG,IAAI,GAAG,EAAyB,CAAC;QAChD,KAAK,MAAM,MAAM,IAAI,SAAS;YAAE,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAChE,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO;YAAE,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACnE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;IAC5E,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,OAAO,CAAC,SAAiB,EAAE,SAAqB;QACpD,IAAI,IAAI,CAAC,UAAU;YAAE,OAAO;QAC5B,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;QACnC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,SAAS,CAAC,CAAC;YACrE,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,UAAU,KAAK,IAAI,CAAC,UAAU;gBAAE,OAAO;YACzD,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC/C,IAAI,SAAS,KAAK,IAAI,CAAC,SAAS;gBAAE,OAAO;YACzC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;YAC3B,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC;YAC5B,SAAS,EAAE,CAAC;QACd,CAAC;gBAAS,CAAC;YACT,IAAI,UAAU,KAAK,IAAI,CAAC,UAAU;gBAAE,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;QAC9D,CAAC;IACH,CAAC;CACF"}