@things-factory/ai-assistant 10.1.112 → 10.1.114

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 (49) hide show
  1. package/client/components/assistant-chat.ts +19 -0
  2. package/client/utils/open-page.ts +21 -0
  3. package/dist-client/components/assistant-chat.d.ts +2 -0
  4. package/dist-client/components/assistant-chat.js +19 -0
  5. package/dist-client/components/assistant-chat.js.map +1 -1
  6. package/dist-client/tsconfig.tsbuildinfo +1 -1
  7. package/dist-client/utils/open-page.d.ts +5 -0
  8. package/dist-client/utils/open-page.js +19 -0
  9. package/dist-client/utils/open-page.js.map +1 -0
  10. package/dist-server/service/assistant-mode/resolve.d.ts +1 -0
  11. package/dist-server/service/assistant-mode/resolve.js +2 -1
  12. package/dist-server/service/assistant-mode/resolve.js.map +1 -1
  13. package/dist-server/service/assistant-mode/types.d.ts +2 -0
  14. package/dist-server/service/assistant-mode/types.js.map +1 -1
  15. package/dist-server/service/chat-session/attachment-tool-result.d.ts +28 -0
  16. package/dist-server/service/chat-session/attachment-tool-result.js +9 -0
  17. package/dist-server/service/chat-session/attachment-tool-result.js.map +1 -0
  18. package/dist-server/service/chat-session/attachment-tools.js +4 -5
  19. package/dist-server/service/chat-session/attachment-tools.js.map +1 -1
  20. package/dist-server/service/data-read/list-read.d.ts +36 -0
  21. package/dist-server/service/data-read/list-read.js +64 -0
  22. package/dist-server/service/data-read/list-read.js.map +1 -0
  23. package/dist-server/service/data-read/read-target.d.ts +109 -0
  24. package/dist-server/service/data-read/read-target.js +189 -0
  25. package/dist-server/service/data-read/read-target.js.map +1 -0
  26. package/dist-server/service/data-read/read-tools.d.ts +228 -0
  27. package/dist-server/service/data-read/read-tools.js +197 -0
  28. package/dist-server/service/data-read/read-tools.js.map +1 -0
  29. package/dist-server/service/index.d.ts +3 -0
  30. package/dist-server/service/index.js +7 -1
  31. package/dist-server/service/index.js.map +1 -1
  32. package/dist-server/tsconfig.tsbuildinfo +1 -1
  33. package/package.json +5 -5
  34. package/server/service/assistant-mode/resolve.ts +3 -2
  35. package/server/service/assistant-mode/types.ts +2 -0
  36. package/server/service/chat-session/attachment-tool-result.test.ts +26 -0
  37. package/server/service/chat-session/attachment-tool-result.ts +18 -0
  38. package/server/service/chat-session/attachment-tools.ts +4 -5
  39. package/server/service/data-read/data-read.test.ts +229 -0
  40. package/server/service/data-read/list-read.ts +98 -0
  41. package/server/service/data-read/read-target.ts +230 -0
  42. package/server/service/data-read/read-tools.ts +212 -0
  43. package/server/service/index.ts +4 -0
  44. package/test/open-page.test.ts +31 -0
  45. package/translations/en.json +14 -0
  46. package/translations/ja.json +14 -0
  47. package/translations/ko.json +14 -0
  48. package/translations/ms.json +14 -0
  49. package/translations/zh.json +14 -0
@@ -70,6 +70,7 @@ import { availableTriggers, type TriggerChip } from './chat-triggers.js'
70
70
  import './entry-review.js'
71
71
  import { entryGroupOf, entryReadyCount, entryTitle, isChangeProposal, isEntryProposal, latestEntryKeys } from '../utils/entry-proposal.js'
72
72
  import { isWorkspaceProposal, versionOfCard, workspaceAddress } from '../utils/workspace.js'
73
+ import { isOpenPageProposal, openPageNote } from '../utils/open-page.js'
73
74
 
74
75
  interface ChatLine {
75
76
  role: 'user' | 'assistant' | 'system'
@@ -4321,6 +4322,8 @@ export class OxAssistantChat extends LitElement {
4321
4322
  const key = this.proposalKey(p)
4322
4323
  /* A workspace card opens the page; it runs nothing (design/ai/workspace.md §4). */
4323
4324
  if (isWorkspaceProposal(p)) return this.renderWorkspaceCard(p, key)
4325
+ /* A screen card opens the application's list with the question's conditions; it runs nothing (design/ai/read-targets.md §5). */
4326
+ if (isOpenPageProposal(p)) return this.renderOpenPageCard(p)
4324
4327
  const card = proposalCardState(key, { outcomes, requested, sentHere: this.sentProposals.has(key) })
4325
4328
  const entry = isEntryProposal(p)
4326
4329
  const replaced = entry && latestEntry?.get(entryGroupOf(p)) !== key && card.state === 'ready'
@@ -4415,6 +4418,22 @@ export class OxAssistantChat extends LitElement {
4415
4418
  `
4416
4419
  }
4417
4420
 
4421
+ /** The screen card - which list, the conditions the screen does not take, and the way to open it. */
4422
+ private renderOpenPageCard(p: any) {
4423
+ const note = openPageNote(p, (key, options) => String(i18next.t(key, options)))
4424
+ const open = () => this.dispatchEvent(new CustomEvent('assistant-open-page', { detail: { href: p.href }, bubbles: true, composed: true }))
4425
+ return html`
4426
+ <div class="proposal workspace">
4427
+ <md-icon>${p.icon || 'open_in_new'}</md-icon>
4428
+ <span class="pbody">
4429
+ <span class="plabel">${p.label}</span>
4430
+ ${note ? html`<span class="preason">${note}</span>` : nothing}
4431
+ </span>
4432
+ <button class="run" @click=${open}>${i18next.t('ai-assistant.screen.open', { defaultValue: 'open the screen' })}</button>
4433
+ </div>
4434
+ `
4435
+ }
4436
+
4418
4437
  /** The AI 작업판 card - what it holds, which version, and the way to open it. The person opens it; the model does not. */
4419
4438
  private renderWorkspaceCard(p: any, key: string) {
4420
4439
  const { version, of } = versionOfCard(this.lines.map(one => one.proposals ?? []), p.workspace.name, key)
@@ -0,0 +1,21 @@
1
+ /*
2
+ * The card that opens an application's list screen with the conditions of a question (design/ai/read-targets.md §5).
3
+ * It reads nothing and runs nothing - the person presses it and the page opens beside the dock.
4
+ */
5
+
6
+ /** An address inside the application - never another origin, never a script. */
7
+ export function isAppAddress(href: unknown): href is string {
8
+ return typeof href === 'string' && !!href.trim() && !/^[a-z][a-z0-9+.-]*:/i.test(href.trim()) && !href.trim().startsWith('//')
9
+ }
10
+
11
+ export function isOpenPageProposal(proposal: any): boolean {
12
+ return proposal?.kind === 'open-page' && isAppAddress(proposal?.href)
13
+ }
14
+
15
+ /** The line under the card's title - the conditions the screen does not take, said, never dropped quietly. */
16
+ export function openPageNote(proposal: any, t: (key: string, options?: any) => string): string {
17
+ const missing: string[] = Array.isArray(proposal?.notAppliedLabels) ? proposal.notAppliedLabels : []
18
+ return missing.length
19
+ ? t('ai-assistant.screen.not-applied', { defaultValue: 'the screen does not take: {conditions}', conditions: missing.join(', ') })
20
+ : ''
21
+ }
@@ -560,6 +560,8 @@ export declare class OxAssistantChat extends LitElement {
560
560
  * 실행 결과는 호스트가 **대화에 기록**한다 — 누가 무엇을 실행했는지가 협의 이력에 남아야 한다.
561
561
  */
562
562
  private renderProposals;
563
+ /** The screen card - which list, the conditions the screen does not take, and the way to open it. */
564
+ private renderOpenPageCard;
563
565
  /** The AI 작업판 card - what it holds, which version, and the way to open it. The person opens it; the model does not. */
564
566
  private renderWorkspaceCard;
565
567
  /**
@@ -54,6 +54,7 @@ import { availableTriggers } from './chat-triggers.js';
54
54
  import './entry-review.js';
55
55
  import { entryGroupOf, entryReadyCount, entryTitle, isChangeProposal, isEntryProposal, latestEntryKeys } from '../utils/entry-proposal.js';
56
56
  import { isWorkspaceProposal, versionOfCard, workspaceAddress } from '../utils/workspace.js';
57
+ import { isOpenPageProposal, openPageNote } from '../utils/open-page.js';
57
58
  function formatFileSize(bytes) {
58
59
  if (!bytes || bytes < 1024)
59
60
  return `${bytes || 0} B`;
@@ -3868,6 +3869,9 @@ let OxAssistantChat = class OxAssistantChat extends LitElement {
3868
3869
  /* A workspace card opens the page; it runs nothing (design/ai/workspace.md §4). */
3869
3870
  if (isWorkspaceProposal(p))
3870
3871
  return this.renderWorkspaceCard(p, key);
3872
+ /* A screen card opens the application's list with the question's conditions; it runs nothing (design/ai/read-targets.md §5). */
3873
+ if (isOpenPageProposal(p))
3874
+ return this.renderOpenPageCard(p);
3871
3875
  const card = proposalCardState(key, { outcomes, requested, sentHere: this.sentProposals.has(key) });
3872
3876
  const entry = isEntryProposal(p);
3873
3877
  const replaced = entry && latestEntry?.get(entryGroupOf(p)) !== key && card.state === 'ready';
@@ -3959,6 +3963,21 @@ let OxAssistantChat = class OxAssistantChat extends LitElement {
3959
3963
  </div>
3960
3964
  `;
3961
3965
  }
3966
+ /** The screen card - which list, the conditions the screen does not take, and the way to open it. */
3967
+ renderOpenPageCard(p) {
3968
+ const note = openPageNote(p, (key, options) => String(i18next.t(key, options)));
3969
+ const open = () => this.dispatchEvent(new CustomEvent('assistant-open-page', { detail: { href: p.href }, bubbles: true, composed: true }));
3970
+ return html `
3971
+ <div class="proposal workspace">
3972
+ <md-icon>${p.icon || 'open_in_new'}</md-icon>
3973
+ <span class="pbody">
3974
+ <span class="plabel">${p.label}</span>
3975
+ ${note ? html `<span class="preason">${note}</span>` : nothing}
3976
+ </span>
3977
+ <button class="run" @click=${open}>${i18next.t('ai-assistant.screen.open', { defaultValue: 'open the screen' })}</button>
3978
+ </div>
3979
+ `;
3980
+ }
3962
3981
  /** The AI 작업판 card - what it holds, which version, and the way to open it. The person opens it; the model does not. */
3963
3982
  renderWorkspaceCard(p, key) {
3964
3983
  const { version, of } = versionOfCard(this.lines.map(one => one.proposals ?? []), p.workspace.name, key);