@things-factory/ai-assistant 10.1.25 → 10.1.26

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 (38) hide show
  1. package/client/components/assistant-chat.ts +3 -2
  2. package/client/components/assistant-mode.test.ts +18 -3
  3. package/client/components/assistant-mode.ts +12 -6
  4. package/dist-client/components/assistant-chat.js +3 -2
  5. package/dist-client/components/assistant-chat.js.map +1 -1
  6. package/dist-client/components/assistant-mode.d.ts +11 -5
  7. package/dist-client/components/assistant-mode.js +12 -6
  8. package/dist-client/components/assistant-mode.js.map +1 -1
  9. package/dist-client/components/assistant-mode.test.js +16 -3
  10. package/dist-client/components/assistant-mode.test.js.map +1 -1
  11. package/dist-client/tsconfig.tsbuildinfo +1 -0
  12. package/dist-server/index.d.ts +1 -0
  13. package/dist-server/index.js +1 -0
  14. package/dist-server/index.js.map +1 -1
  15. package/dist-server/service/assistant-chat-resolver.js +3 -1
  16. package/dist-server/service/assistant-chat-resolver.js.map +1 -1
  17. package/dist-server/service/index.d.ts +1 -0
  18. package/dist-server/service/index.js +1 -0
  19. package/dist-server/service/index.js.map +1 -1
  20. package/dist-server/service/tool-access.d.ts +4 -0
  21. package/dist-server/service/tool-access.js +23 -0
  22. package/dist-server/service/tool-access.js.map +1 -0
  23. package/dist-server/tool-registry-boot-report.d.ts +3 -0
  24. package/dist-server/tool-registry-boot-report.js +29 -0
  25. package/dist-server/tool-registry-boot-report.js.map +1 -0
  26. package/dist-server/tsconfig.tsbuildinfo +1 -0
  27. package/docs/session-controller.md +1 -1
  28. package/package.json +6 -5
  29. package/server/index.ts +1 -0
  30. package/server/service/assistant-chat-resolver.ts +3 -1
  31. package/server/service/index.ts +1 -0
  32. package/server/service/tool-access.test.ts +48 -0
  33. package/server/service/tool-access.ts +27 -0
  34. package/server/tool-registry-boot-report.test.ts +18 -0
  35. package/server/tool-registry-boot-report.ts +26 -0
  36. package/test/assistant-request-context.test.ts +2 -2
  37. package/test/assistant-session-controller.test.ts +0 -1
  38. package/test/assistant-session-toolbar.test.ts +2 -2
@@ -708,8 +708,9 @@ export class OxAssistantChat extends LitElement {
708
708
  /*
709
709
  * ── What this conversation is, resolved ──────────────────────────────────────────────
710
710
  *
711
- * A mode answers first. A host that has not declared one keeps the separate properties and
712
- * the global defaults it had before, which is what every consumer written before modes does.
711
+ * A host that declares a mode gets the mode and nothing else a field it leaves out is empty,
712
+ * never filled from these properties or the registered defaults. A host that has not declared
713
+ * one keeps the separate properties and the global defaults it had before.
713
714
  */
714
715
  private get conversation() {
715
716
  return resolveConversation(
@@ -45,10 +45,25 @@ describe('resolveConversation', () => {
45
45
  expect(JSON.stringify(c.slashTemplates)).not.toContain('add-monitor')
46
46
  })
47
47
 
48
- test('what a mode leaves out still comes from the defaults', () => {
48
+ test('what a mode leaves out stays out the defaults another package registered do not fill it', () => {
49
49
  const c = resolveConversation(MODE, HOST_PROPERTIES, GLOBAL_DEFAULTS)
50
- expect(c.catalogEntries).toEqual(GLOBAL_DEFAULTS.catalogEntries)
51
- expect(c.footerNoticeKey).toBe(GLOBAL_DEFAULTS.footerNoticeKey)
50
+ /* The board's `@` catalog and its "previewed on the board" line belong to board authoring. */
51
+ expect(c.catalogEntries).toEqual([])
52
+ expect(c.footerNoticeKey).toBeUndefined()
53
+ })
54
+
55
+ test('★ a mode that declares no slash list offers none, even when a board package registered its own', () => {
56
+ /* plant's factory mode declares no `slashTemplates`; board-ai registers `/add-monitor` globally. */
57
+ const { slashTemplates, ...withoutSlash } = MODE
58
+ const c = resolveConversation({ ...withoutSlash, id: 'plant:factory:D-1' }, HOST_PROPERTIES, GLOBAL_DEFAULTS)
59
+ expect(c.slashTemplates).toEqual([])
60
+ })
61
+
62
+ test('★ a mode that leaves out a field the host also set as a property does not take the property either', () => {
63
+ const c = resolveConversation({ id: 'twin:none' }, HOST_PROPERTIES, GLOBAL_DEFAULTS)
64
+ expect(c.systemPrompt).toBeUndefined()
65
+ expect(c.toolCategories).toBeUndefined()
66
+ expect(c.hostContext).toBeUndefined()
52
67
  })
53
68
 
54
69
  test('a host with no mode gets exactly what it had before modes existed', () => {
@@ -92,15 +92,21 @@ export interface ConversationSettings {
92
92
  }
93
93
 
94
94
  /**
95
- * Reconcile the three places a setting can come from.
95
+ * Reconcile the places a setting can come from.
96
96
  *
97
- * **The mode answers first, as a whole.** Then the host's own properties, then whatever was
98
- * registered globally. The order matters in one direction only: a host that declares a mode
99
- * must not have half of its conversation decided somewhere else, which is the failure this
100
- * type exists to remove.
97
+ * **A host that declares a mode gets the mode and nothing else.** A field the mode leaves out is
98
+ * empty: it is not filled from the element's own properties, and it is not filled from the
99
+ * defaults another package registered. Filling it back in is how the defect this type removes
100
+ * returned board-ai registers board authoring's `/add-monitor`, its component `@` catalog and
101
+ * its "previewed on the board" line globally, and plant's factory mode, which declares no slash
102
+ * list, offered them on a factory screen once the board modeller had been loaded. A mode that
103
+ * wants those declares them.
101
104
  *
102
105
  * A host that declares no mode gets exactly what it got before modes existed — its own
103
106
  * properties, falling back to the registered defaults.
107
+ *
108
+ * `chatEndpoint` still falls back to `boardAIChat` when nothing names one; that default is a
109
+ * separate question (standard A2).
104
110
  */
105
111
  export function resolveConversation(
106
112
  mode: AssistantMode | undefined,
@@ -108,7 +114,7 @@ export function resolveConversation(
108
114
  defaults: Partial<ConversationSettings>
109
115
  ): ConversationSettings {
110
116
  const pick = <K extends keyof ConversationSettings>(key: K): ConversationSettings[K] =>
111
- (mode as any)?.[key] ?? (own as any)[key] ?? (defaults as any)[key]
117
+ mode ? (mode as any)[key] : ((own as any)[key] ?? (defaults as any)[key])
112
118
 
113
119
  return {
114
120
  systemPrompt: pick('systemPrompt'),
@@ -440,8 +440,9 @@ let OxAssistantChat = class OxAssistantChat extends LitElement {
440
440
  /*
441
441
  * ── What this conversation is, resolved ──────────────────────────────────────────────
442
442
  *
443
- * A mode answers first. A host that has not declared one keeps the separate properties and
444
- * the global defaults it had before, which is what every consumer written before modes does.
443
+ * A host that declares a mode gets the mode and nothing else a field it leaves out is empty,
444
+ * never filled from these properties or the registered defaults. A host that has not declared
445
+ * one keeps the separate properties and the global defaults it had before.
445
446
  */
446
447
  get conversation() {
447
448
  return resolveConversation(this.mode, {