@agentshouse/app-bridge 0.1.0-c6f0ca4067690 → 0.1.0-c6f4d423ead48

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.
package/README.md CHANGED
@@ -3,16 +3,16 @@
3
3
  The types of the agents.house App bridge, an accessor and an in-page test host.
4
4
  House builds the bridge object in every App it serves and hands it to the page
5
5
  before the App's own scripts run; `houseBridge()` returns that object, so an App
6
- carries no bridge code of its own. It carries eleven families: navigation,
6
+ carries no bridge code of its own. It carries twelve families: navigation,
7
7
  ceremonies, installation, notifications, status, Site image reads, App release
8
- code, external calls, App messages and App and Site screenshot reads.
8
+ code, external calls, App messages, App and Site screenshot reads and the Chat.
9
9
  [docs/families.md](docs/families.md) describes each and the test host.
10
10
 
11
11
  The bridge carries no credential handling and no Runtime family. House builds
12
- the MD Runtime client into the page beside the bridge, and `bridge.runtime`
13
- resolves to that client, so the App imports and constructs none.
12
+ the MD Runtime client into the page beside the bridge and serves it the Chat, so
13
+ the App imports, constructs and bundles neither: `bridge.runtime` resolves to the client.
14
14
 
15
- House's `find_command` "App" is the guide to building an App or a Site.
15
+ House's guide to building an App is its Guide's `apps/` pages, which `open_guide` opens.
16
16
 
17
17
  ## Use
18
18
 
package/dist/calls.d.ts CHANGED
@@ -64,19 +64,6 @@ export interface HouseMethods {
64
64
  readonly url: string;
65
65
  };
66
66
  };
67
- readonly 'conversation.attach': {
68
- readonly params: {
69
- readonly blob: Blob;
70
- readonly byteLength: number;
71
- readonly contentHash: string;
72
- readonly mediaType: string;
73
- readonly name: string;
74
- readonly room: string;
75
- };
76
- readonly result: {
77
- readonly path: string;
78
- };
79
- };
80
67
  readonly 'conversation.create': {
81
68
  readonly params: {
82
69
  readonly agent_id: string;
@@ -240,7 +227,7 @@ export interface HouseMethods {
240
227
  readonly params: Readonly<Record<string, never>>;
241
228
  readonly result: {
242
229
  readonly features: readonly {
243
- readonly feature: 'microphone' | 'camera' | 'geolocation' | 'clipboard-read' | 'notifications';
230
+ readonly feature: string;
244
231
  readonly allowed: boolean;
245
232
  }[];
246
233
  };
@@ -623,293 +610,6 @@ export interface HouseMethods {
623
610
  readonly submitted: true;
624
611
  };
625
612
  };
626
- readonly 'trigger.list': {
627
- readonly params: {
628
- readonly room_refs: readonly string[];
629
- };
630
- readonly result: {
631
- readonly rooms: readonly {
632
- readonly room_ref: string;
633
- readonly triggers: readonly {
634
- readonly trigger: string;
635
- readonly creator: {
636
- readonly user: string;
637
- readonly name: string;
638
- };
639
- readonly description: string;
640
- readonly condition: {
641
- readonly on: 'documents';
642
- readonly scope: {
643
- readonly type: string;
644
- } | {
645
- readonly folder: string;
646
- } | {
647
- readonly document: string;
648
- };
649
- readonly mode: 'starts_matching';
650
- readonly new_documents: boolean;
651
- readonly match: {
652
- readonly all: readonly unknown[];
653
- } | {
654
- readonly any: readonly unknown[];
655
- } | {
656
- readonly not: unknown;
657
- } | {
658
- readonly path: string;
659
- readonly eq: string | number | boolean;
660
- } | {
661
- readonly path: string;
662
- readonly in: readonly (string | number | boolean)[];
663
- } | {
664
- readonly path: string;
665
- readonly exists: boolean;
666
- } | {
667
- readonly path: string;
668
- readonly contains: string | number | boolean;
669
- } | {
670
- readonly path: string;
671
- readonly gt: number | string;
672
- } | {
673
- readonly path: string;
674
- readonly gte: number | string;
675
- } | {
676
- readonly path: string;
677
- readonly lt: number | string;
678
- } | {
679
- readonly path: string;
680
- readonly lte: number | string;
681
- } | {
682
- readonly path: string;
683
- readonly prefix: string;
684
- };
685
- readonly by?: {
686
- readonly all: readonly unknown[];
687
- } | {
688
- readonly any: readonly unknown[];
689
- } | {
690
- readonly not: unknown;
691
- } | {
692
- readonly path: string;
693
- readonly eq: string | number | boolean;
694
- } | {
695
- readonly path: string;
696
- readonly in: readonly (string | number | boolean)[];
697
- } | {
698
- readonly path: string;
699
- readonly exists: boolean;
700
- } | {
701
- readonly path: string;
702
- readonly contains: string | number | boolean;
703
- } | {
704
- readonly path: string;
705
- readonly gt: number | string;
706
- } | {
707
- readonly path: string;
708
- readonly gte: number | string;
709
- } | {
710
- readonly path: string;
711
- readonly lt: number | string;
712
- } | {
713
- readonly path: string;
714
- readonly lte: number | string;
715
- } | {
716
- readonly path: string;
717
- readonly prefix: string;
718
- };
719
- readonly moved_between_rooms?: boolean;
720
- } | {
721
- readonly on: 'documents';
722
- readonly scope: {
723
- readonly type: string;
724
- } | {
725
- readonly folder: string;
726
- } | {
727
- readonly document: string;
728
- };
729
- readonly mode: 'field_changes';
730
- readonly field: string;
731
- readonly from?: readonly (string | number | boolean)[] | 'new';
732
- readonly to?: readonly (string | number | boolean)[] | 'deleted';
733
- readonly match?: {
734
- readonly all: readonly unknown[];
735
- } | {
736
- readonly any: readonly unknown[];
737
- } | {
738
- readonly not: unknown;
739
- } | {
740
- readonly path: string;
741
- readonly eq: string | number | boolean;
742
- } | {
743
- readonly path: string;
744
- readonly in: readonly (string | number | boolean)[];
745
- } | {
746
- readonly path: string;
747
- readonly exists: boolean;
748
- } | {
749
- readonly path: string;
750
- readonly contains: string | number | boolean;
751
- } | {
752
- readonly path: string;
753
- readonly gt: number | string;
754
- } | {
755
- readonly path: string;
756
- readonly gte: number | string;
757
- } | {
758
- readonly path: string;
759
- readonly lt: number | string;
760
- } | {
761
- readonly path: string;
762
- readonly lte: number | string;
763
- } | {
764
- readonly path: string;
765
- readonly prefix: string;
766
- };
767
- readonly by?: {
768
- readonly all: readonly unknown[];
769
- } | {
770
- readonly any: readonly unknown[];
771
- } | {
772
- readonly not: unknown;
773
- } | {
774
- readonly path: string;
775
- readonly eq: string | number | boolean;
776
- } | {
777
- readonly path: string;
778
- readonly in: readonly (string | number | boolean)[];
779
- } | {
780
- readonly path: string;
781
- readonly exists: boolean;
782
- } | {
783
- readonly path: string;
784
- readonly contains: string | number | boolean;
785
- } | {
786
- readonly path: string;
787
- readonly gt: number | string;
788
- } | {
789
- readonly path: string;
790
- readonly gte: number | string;
791
- } | {
792
- readonly path: string;
793
- readonly lt: number | string;
794
- } | {
795
- readonly path: string;
796
- readonly lte: number | string;
797
- } | {
798
- readonly path: string;
799
- readonly prefix: string;
800
- };
801
- readonly moved_between_rooms?: boolean;
802
- } | {
803
- readonly on: 'items';
804
- readonly source?: string;
805
- readonly address?: string;
806
- readonly match?: {
807
- readonly all: readonly unknown[];
808
- } | {
809
- readonly any: readonly unknown[];
810
- } | {
811
- readonly not: unknown;
812
- } | {
813
- readonly path: string;
814
- readonly eq: string | number | boolean;
815
- } | {
816
- readonly path: string;
817
- readonly in: readonly (string | number | boolean)[];
818
- } | {
819
- readonly path: string;
820
- readonly exists: boolean;
821
- } | {
822
- readonly path: string;
823
- readonly contains: string | number | boolean;
824
- } | {
825
- readonly path: string;
826
- readonly gt: number | string;
827
- } | {
828
- readonly path: string;
829
- readonly gte: number | string;
830
- } | {
831
- readonly path: string;
832
- readonly lt: number | string;
833
- } | {
834
- readonly path: string;
835
- readonly lte: number | string;
836
- } | {
837
- readonly path: string;
838
- readonly prefix: string;
839
- };
840
- } | {
841
- readonly on: 'clock';
842
- readonly cron: string;
843
- readonly time_zone: string;
844
- } | {
845
- readonly on: 'clock';
846
- readonly scope: {
847
- readonly type: string;
848
- };
849
- readonly date: string;
850
- readonly days: number;
851
- readonly at: string;
852
- readonly time_zone: string;
853
- readonly match?: {
854
- readonly all: readonly unknown[];
855
- } | {
856
- readonly any: readonly unknown[];
857
- } | {
858
- readonly not: unknown;
859
- } | {
860
- readonly path: string;
861
- readonly eq: string | number | boolean;
862
- } | {
863
- readonly path: string;
864
- readonly in: readonly (string | number | boolean)[];
865
- } | {
866
- readonly path: string;
867
- readonly exists: boolean;
868
- } | {
869
- readonly path: string;
870
- readonly contains: string | number | boolean;
871
- } | {
872
- readonly path: string;
873
- readonly gt: number | string;
874
- } | {
875
- readonly path: string;
876
- readonly gte: number | string;
877
- } | {
878
- readonly path: string;
879
- readonly lt: number | string;
880
- } | {
881
- readonly path: string;
882
- readonly lte: number | string;
883
- } | {
884
- readonly path: string;
885
- readonly prefix: string;
886
- };
887
- };
888
- readonly enabled: boolean;
889
- readonly paused_by?: 'types';
890
- readonly actions: readonly ({
891
- readonly kind: 'notify';
892
- readonly enabled: boolean;
893
- readonly title: string;
894
- readonly text: string;
895
- readonly to: {
896
- readonly users: readonly string[];
897
- readonly fields: readonly string[];
898
- readonly roles: readonly string[];
899
- };
900
- readonly holds: boolean;
901
- } | {
902
- readonly kind: 'routine';
903
- readonly enabled: boolean;
904
- readonly access?: string;
905
- readonly payload: string;
906
- readonly holds: boolean;
907
- })[];
908
- }[];
909
- readonly url: string;
910
- }[];
911
- };
912
- };
913
613
  readonly 'triggerOccurrence.list': {
914
614
  readonly params: {
915
615
  readonly room_ref: string;
@@ -928,6 +628,7 @@ export interface HouseMethods {
928
628
  } | {
929
629
  readonly position: number;
930
630
  readonly outcome: 'no_target';
631
+ readonly code: 'no_recipient' | 'routine_access_not_found' | 'routine_retired' | 'target_agent_unavailable';
931
632
  } | {
932
633
  readonly position: number;
933
634
  readonly outcome: 'requested';
@@ -987,9 +688,11 @@ export interface HouseMethods {
987
688
  } | {
988
689
  readonly position: number;
989
690
  readonly outcome: 'withdrawn';
691
+ readonly code: 'agent_unavailable';
990
692
  } | {
991
693
  readonly position: number;
992
694
  readonly outcome: 'failed';
695
+ readonly code: 'internal_error' | 'routine_request_not_started';
993
696
  } | {
994
697
  readonly position: number;
995
698
  readonly outcome: 'waiting';
package/dist/index.d.ts CHANGED
@@ -21,7 +21,7 @@ export interface HouseCredentialState {
21
21
  readonly state: Open<'none' | 'held' | 'rejected'>;
22
22
  readonly expiresAt: number | null;
23
23
  }
24
- export type HouseDatabaseFailure = 'unsupported' | 'damaged' | 'update-required';
24
+ export type HouseDatabaseFailure = 'unsupported' | 'damaged';
25
25
  export type HouseAnalyticsChoice = 'accept' | 'decline';
26
26
  export interface HouseAnalytics {
27
27
  readonly measures: boolean;
@@ -134,8 +134,29 @@ export interface HouseCooperation {
134
134
  ready(): Promise<boolean> | boolean;
135
135
  settle(activation: HouseActivation): void;
136
136
  }
137
+ export type HouseChatWidth = 'full' | '3/4' | '1/2' | '1/3';
138
+ export interface HouseChatOpened {
139
+ readonly conversation: string | null;
140
+ readonly agent: string | null;
141
+ }
142
+ export interface HouseChatOptions {
143
+ readonly conversation?: string | null;
144
+ readonly agent?: string | null;
145
+ readonly showChats?: boolean;
146
+ readonly width?: HouseChatWidth;
147
+ readonly onOpen?: (opened: HouseChatOpened) => void;
148
+ readonly onLink?: (href: string) => void;
149
+ }
150
+ export interface HouseMountedChat {
151
+ update(options: HouseChatOptions): void;
152
+ unmount(): void;
153
+ }
154
+ export interface HouseChat {
155
+ mount(element: object, options?: HouseChatOptions): Promise<HouseMountedChat>;
156
+ }
137
157
  export interface HouseBridge {
138
158
  readonly runtime: Promise<HouseRuntime>;
159
+ readonly chat: HouseChat;
139
160
  address(): string | null;
140
161
  onAddress(listener: (address: string) => void): () => void;
141
162
  push(address: string): Promise<string>;
@@ -2,6 +2,7 @@ import type { Definition } from './definition.js';
2
2
  export type Library = Readonly<Record<string, string>>;
3
3
  export type VerifiedModel = {
4
4
  readonly types: Readonly<Record<string, Definition>>;
5
+ readonly nameable?: readonly string[];
5
6
  };
6
7
  export type ModelVerification = {
7
8
  readonly verdict: 'accept';
@@ -50,7 +50,7 @@ export type ListedConversation = {
50
50
  outcome: string | null;
51
51
  waiting: boolean;
52
52
  };
53
- export type ConversationAction = 'conversation.create' | 'conversation.send' | 'conversation.attach' | 'conversation.answer' | 'conversation.interrupt' | 'conversation.kill' | 'conversation.cancel' | 'conversation.delete' | 'conversation.history';
53
+ export type ConversationAction = 'conversation.create' | 'conversation.send' | 'conversation.answer' | 'conversation.interrupt' | 'conversation.kill' | 'conversation.cancel' | 'conversation.delete' | 'conversation.history';
54
54
  export type ConversationMessage = {
55
55
  identity: string;
56
56
  turn: string;
@@ -298,7 +298,6 @@ export type BootstrapInventory = {
298
298
  };
299
299
  export type RoomModels = {
300
300
  collection?: ModelResult;
301
- selection?: ModelResult;
302
301
  };
303
302
  export type BootstrapPage = {
304
303
  kind: 'bootstrap';
@@ -432,6 +431,22 @@ export type BinaryLinkResult = {
432
431
  kind: 'link';
433
432
  url: string;
434
433
  name: string;
434
+ mediaType?: string;
435
+ } | (ProviderRefusal & {
436
+ kind: 'rejected';
437
+ }) | AdapterFailure;
438
+ export type AttachRequest = {
439
+ locator: string;
440
+ name: string;
441
+ mediaType: string;
442
+ byteLength: number;
443
+ sha256: string;
444
+ blob: Blob;
445
+ };
446
+ export type AttachResult = {
447
+ kind: 'attached';
448
+ path: string;
449
+ revision: string;
435
450
  } | (ProviderRefusal & {
436
451
  kind: 'rejected';
437
452
  }) | AdapterFailure;
@@ -495,6 +510,7 @@ export type Adapter = {
495
510
  readonly localSaves?: true;
496
511
  readonly exhaustiveDiscovery?: true;
497
512
  readonly roomTypes?: string;
513
+ readonly nameableRoomTypes?: readonly string[];
498
514
  authorize(): Promise<Authorization>;
499
515
  discover(authorization: Authorization, scope?: DiscoveryScope): Promise<DiscoverResult>;
500
516
  bootstrap(authorization: Authorization, request: BootstrapRequest): Promise<BootstrapResult>;
@@ -503,6 +519,7 @@ export type Adapter = {
503
519
  history(authorization: Authorization, request: HistoryRequest): Promise<HistoryResult>;
504
520
  binary(authorization: Authorization, request: BinaryRequest): Promise<BinaryResult>;
505
521
  link(authorization: Authorization, request: BinaryRequest): Promise<BinaryLinkResult>;
522
+ attach(authorization: Authorization, request: AttachRequest): Promise<AttachResult>;
506
523
  action(authorization: Authorization, request: ActionRequest): Promise<ActionResult>;
507
524
  reached(locator: string, roomVersion: string, target: string): boolean;
508
525
  follows(locator: string, roomVersion: string, next: string): boolean;
@@ -2,8 +2,7 @@ import type { AppRoom, ConnectionRefusal, HistoryQuery, RoomSchemas, SavedParts,
2
2
  import type { Member, ServiceMode } from './adapter.js';
3
3
  import type { ChatDraft, ConversationAgent, ConversationEntry, ConversationOptions, ConversationView } from './conversation.js';
4
4
  import { type Observation } from './observation.js';
5
- import type { ChosenFile } from './file.js';
6
- import type { BinaryAnswer, BinaryLinkAnswer, CallResult, HistoryAnswer, Offline, QueueEntry, Resolution } from './outcome.js';
5
+ import type { AttachAnswer, BinaryAnswer, CallResult, DownloadAnswer, HistoryAnswer, Offline, QueueEntry, Resolution } from './outcome.js';
7
6
  import type { DocumentQuery, DocumentResult, GroupQuery, GroupResult, PendingResult } from './query.js';
8
7
  import type { RoomDraft, RoomDraftParts, RoomDraftWrite } from './room-draft.js';
9
8
  import type { SearchRequest, SearchResult } from './search.js';
@@ -21,7 +20,7 @@ export type MdRuntimeClient = {
21
20
  roomDraft: {
22
21
  list(): Promise<readonly RoomDraft[]>;
23
22
  read(room: string, path: string): Promise<RoomDraft | null>;
24
- write(room: string, path: string, revision: string | null, parts: RoomDraftParts): Promise<RoomDraftWrite>;
23
+ write(room: string, path: string, revision: string | null, parts: RoomDraftParts, next?: string): Promise<RoomDraftWrite>;
25
24
  discard(room: string, path: string, revision: string): Promise<RoomDraftWrite>;
26
25
  };
27
26
  save(room: string, roomDrafts: readonly SavedRoomDraft[]): Promise<SaveResult>;
@@ -36,7 +35,6 @@ export type MdRuntimeClient = {
36
35
  read(conversation: string, options?: ConversationOptions): Promise<ConversationView>;
37
36
  create(input: unknown): Promise<CallResult>;
38
37
  send(conversation: string, operation?: string, draft?: ChatDraft): Promise<CallResult | Offline>;
39
- attach(room: string, file: ChosenFile): Promise<CallResult | Offline>;
40
38
  answer(conversation: string, answer: unknown): Promise<CallResult>;
41
39
  interrupt(conversation: string): Promise<CallResult>;
42
40
  kill(conversation: string): Promise<CallResult>;
@@ -52,7 +50,8 @@ export type MdRuntimeClient = {
52
50
  resolve(room: string, path: string, destination: string): Promise<Resolution>;
53
51
  binaryFile: {
54
52
  read(room: string, path: string, revision?: string): Promise<BinaryAnswer>;
55
- link(room: string, path: string, revision?: string): Promise<BinaryLinkAnswer>;
53
+ attach(room: string, file: File): Promise<AttachAnswer>;
54
+ download(room: string, path: string, revision?: string): Promise<DownloadAnswer>;
56
55
  };
57
56
  call(name: string, input: unknown): Promise<CallResult>;
58
57
  reached(locator: string, roomVersion: string, path?: string): Promise<boolean>;
@@ -84,6 +83,8 @@ export type MdRuntimeClient = {
84
83
  export declare function connectMdRuntime(port: RuntimePort): MdRuntimeClient;
85
84
  export declare function inTurn(client: MdRuntimeClient, work: () => Promise<void>): Promise<void>;
86
85
  export { chainedWindows, type WindowAnswer, type WindowChain } from './chain.js';
86
+ export { roomDraftRevision } from './identity.js';
87
+ export { defineRoomMedia, ROOM_MEDIA } from './media.js';
87
88
  export type { Observation } from './observation.js';
88
89
  export type { Open } from './open.js';
89
90
  export { unanswered, type RuntimePort, type WireMember } from './wire.js';
@@ -7,7 +7,7 @@ import { type Adapter, type Authorization, type Member, type ProviderRefusal, ty
7
7
  import { type ChatDraftSurface, type ConversationAgent, type ConversationEntry, type ConversationOptions, type ConversationSurface, type ConversationView } from './conversation.js';
8
8
  import { type WrittenBy } from './change.js';
9
9
  import type { Open } from './open.js';
10
- import { type BinaryLinkAnswer, type CallResult, type HeldBinaryAnswer, type HistoryAnswer, type QueueEntry, type Resolution } from './outcome.js';
10
+ import { type AttachAnswer, type BinaryLinkAnswer, type CallResult, type HeldBinaryAnswer, type HeldShownAnswer, type HistoryAnswer, type QueueEntry, type Resolution } from './outcome.js';
11
11
  import { type Recovery } from './recovery.js';
12
12
  import { type SaveRefusal } from './save.js';
13
13
  import { type RoomDraft, type RoomDraftParts, type RoomDraftWrite } from './room-draft.js';
@@ -72,7 +72,7 @@ export type SavedParts = {
72
72
  export type RoomDraftSurface = {
73
73
  list(): Promise<readonly RoomDraft[]>;
74
74
  read(room: string, path: string): Promise<RoomDraft | null>;
75
- write(room: string, path: string, revision: string | null, parts: unknown): Promise<RoomDraftWrite>;
75
+ write(room: string, path: string, revision: string | null, parts: unknown, next?: string): Promise<RoomDraftWrite>;
76
76
  discard(room: string, path: string, revision: string): Promise<RoomDraftWrite>;
77
77
  };
78
78
  export type PresentationSurface = {
@@ -83,6 +83,8 @@ export type PresentationSurface = {
83
83
  export type BinaryFileSurface = {
84
84
  read(room: string, path: string, revision?: string): Promise<HeldBinaryAnswer>;
85
85
  link(room: string, path: string, revision?: string): Promise<BinaryLinkAnswer>;
86
+ show(room: string, path: string, revision?: string): Promise<HeldShownAnswer>;
87
+ attach(room: string, file: File): Promise<AttachAnswer>;
86
88
  part(file: string, part: number): Promise<Uint8Array | null>;
87
89
  };
88
90
  export type HistoryQuery = {
@@ -1,6 +1,5 @@
1
1
  import type { ConversationAction, ConversationAgents, ConversationEvent, ConversationMessage, ConversationStream, ProcessCommand, SessionOption, TurnContext } from './adapter.js';
2
2
  import { type ChangeSet } from './change-set.js';
3
- import { type ChosenFile } from './file.js';
4
3
  import type { Open } from './open.js';
5
4
  import { type CallResult, type Offline } from './outcome.js';
6
5
  import type { DocumentResult, PendingResult } from './query.js';
@@ -65,7 +64,6 @@ export type ConversationSurface = {
65
64
  read(conversation: string, options?: ConversationOptions): Promise<ConversationView>;
66
65
  create(input: unknown): Promise<CallResult>;
67
66
  send(conversation: string, operation?: string, draft?: ChatDraft): Promise<CallResult | Offline>;
68
- attach(room: string, file: ChosenFile): Promise<CallResult | Offline>;
69
67
  answer(conversation: string, answer: unknown): Promise<CallResult>;
70
68
  interrupt(conversation: string): Promise<CallResult>;
71
69
  kill(conversation: string): Promise<CallResult>;
@@ -0,0 +1,6 @@
1
+ export declare function changeBatchIdentity(at?: number): string;
2
+ export declare function identityTime(identity: string): number;
3
+ export declare function roomDraftRevision(): string;
4
+ export declare function chatDraftRevision(): string;
5
+ export declare function transferIdentity(): string;
6
+ export declare function binaryLocalId(): string;
@@ -0,0 +1,7 @@
1
+ import type { MdRuntimeClient } from './client.js';
2
+ import type { ShownAnswer } from './outcome.js';
3
+ export declare const ROOM_MEDIA = "room-media";
4
+ type Show = (room: string, path: string, revision?: string) => Promise<ShownAnswer>;
5
+ export declare function shownBy(show: Show, client: MdRuntimeClient): MdRuntimeClient;
6
+ export declare function defineRoomMedia(client: Promise<MdRuntimeClient> | MdRuntimeClient, registry?: CustomElementRegistry): void;
7
+ export {};
@@ -1,4 +1,4 @@
1
- import type { ActionResult, AdapterFailure, BinaryLinkResult, HistoryResult, HistoryRevision, ProviderRefusal, RoomVersionAt, ScopedRefusal } from './adapter.js';
1
+ import type { ActionResult, AdapterFailure, AttachResult, BinaryLinkResult, HistoryResult, HistoryRevision, ProviderRefusal, RoomVersionAt, ScopedRefusal } from './adapter.js';
2
2
  import type { ChangeBatch } from './change.js';
3
3
  import type { KeptBinary, KeptResult } from './opened.js';
4
4
  type Refused<Kind extends string> = ProviderRefusal & {
@@ -29,7 +29,17 @@ export type BinaryLinkAnswer = {
29
29
  kind: 'link';
30
30
  url: string;
31
31
  name: string;
32
+ mediaType: string;
32
33
  } | Refused<'rejected'> | Refused<'absent'> | Failure;
34
+ export type HeldShownAnswer = KeptBinary | BinaryLinkAnswer;
35
+ export type ShownAnswer = BinaryAnswer | BinaryLinkAnswer;
36
+ export type AttachAnswer = {
37
+ kind: 'attached';
38
+ path: string;
39
+ } | Offline | Refused<'rejected'> | Failure;
40
+ export type DownloadAnswer = {
41
+ kind: 'started';
42
+ } | Refused<'rejected'> | Refused<'absent'> | Refused<'blocked'> | Failure;
33
43
  export type Resolution = {
34
44
  readonly kind: 'document';
35
45
  readonly room: string;
@@ -45,7 +55,8 @@ export declare const LOCKED_UNREADABLE: Refused<'unreadable'>;
45
55
  export declare const ABSENT_TARGET: Refused<'absent'>;
46
56
  export declare function absentBinary(path: string): Refused<'absent'>;
47
57
  export declare function binaryAnswer(result: KeptResult): HeldBinaryAnswer;
48
- export declare function binaryLinkAnswer(result: BinaryLinkResult): BinaryLinkAnswer;
58
+ export declare function binaryLinkAnswer(result: BinaryLinkResult, held?: string): BinaryLinkAnswer;
59
+ export declare function attachAnswer(result: AttachResult): AttachAnswer;
49
60
  export declare const ROOM_LOCKED = "room-locked";
50
61
  export declare function lockedRoom(locator: string): Refused<'room-locked'> & {
51
62
  locator: string;
@@ -232,9 +232,15 @@ export type GroupShape = {
232
232
  direction: Direction;
233
233
  }[];
234
234
  };
235
+ export type PlanArea = {
236
+ room: string;
237
+ path: string;
238
+ types: readonly string[];
239
+ };
235
240
  export type PlanReach = {
236
241
  rooms: readonly string[];
237
242
  documents: readonly string[];
243
+ areas: readonly PlanArea[];
238
244
  };
239
245
  export type Continuation = {
240
246
  text: string;
@@ -6,9 +6,15 @@ export type ReachedDocument = {
6
6
  readonly room: string;
7
7
  readonly path: string;
8
8
  };
9
+ export type ReachedArea = {
10
+ readonly room: string;
11
+ readonly path: string;
12
+ readonly types: readonly string[];
13
+ };
9
14
  export type PortReach = {
10
15
  readonly rooms: readonly string[];
11
16
  readonly documents: readonly ReachedDocument[];
17
+ readonly areas?: readonly ReachedArea[];
12
18
  readonly conversations: boolean;
13
19
  };
14
20
  export type Deliver = (message: unknown) => void;
@@ -12,7 +12,6 @@ export type ReplicaRecord = {
12
12
  readonly replica: ReplicaAdmission;
13
13
  readonly model: ModelState;
14
14
  readonly typedSelection: TypedSelection | null;
15
- readonly selectionModel: ModelState;
16
15
  readonly providerOwnedPaths: readonly string[];
17
16
  readonly roomVersion: string;
18
17
  readonly transfer: string;
@@ -34,7 +33,7 @@ export type Slice = Layer & {
34
33
  readonly written: Readonly<Record<string, string>>;
35
34
  readonly held: ReadonlySet<string>;
36
35
  };
37
- export declare function compositionOf(record: Pick<ReplicaRecord, 'model' | 'typedSelection' | 'selectionModel'>): Composition;
36
+ export declare function compositionOf(record: Pick<ReplicaRecord, 'model' | 'typedSelection'>, builtIn: ModelState): Composition;
38
37
  export declare function sameMembership(record: Pick<ReplicaRecord, 'typedSelection'>, other: Pick<ReplicaRecord, 'typedSelection'>): boolean;
39
38
  export declare function storedRecord(record: ReplicaRecord): string;
40
39
  export declare function slicing(entries: readonly HeldEntry[], paths: Iterable<string>): Generator<number, Slice, void>;
@@ -127,6 +127,7 @@ export type SavedDraft = {
127
127
  readonly parts: HeldParts;
128
128
  };
129
129
  export declare function readParts(value: unknown): RoomDraftParts;
130
+ export declare function gatheredParts(earlier: unknown, later: unknown): unknown;
130
131
  export declare function held(current: HeldParts | undefined, parts: RoomDraftParts, file?: HeldFile): HeldParts;
131
132
  export declare function underneath(parts: HeldParts, path: string, visible: VisibleLayer | undefined): ChangedUnderneath;
132
133
  export declare function heldFile(blob: Blob, base: string | null): Promise<HeldFile>;
@@ -7,12 +7,8 @@ import type { Submission } from './outcome.js';
7
7
  import type { RoomDraftRecord, SavedDraft } from './room-draft.js';
8
8
  import type { ModelState } from './model.js';
9
9
  import type { SearchWindow } from './search.js';
10
- import type { CommittedWrite, ConversationWrite, CountedRoom, HeldConversation, HeldEntry, MessageWindow, QueryAnswer, QueryRoom, Referrer, RoomCommit, RuntimeDatabase, SearchAsk, StoredEntry, StoredFile, TypedEntry, View, Walked } from './tables.js';
10
+ import type { CommittedWrite, ConversationWrite, CountedRoom, HeldConversation, HeldEntry, KeptPart, MessageWindow, QueryAnswer, QueryRoom, Referrer, RoomCommit, RuntimeDatabase, SearchAsk, StoredEntry, StoredFile, TypedEntry, View, Walked } from './tables.js';
11
11
  export type { ConversationWrite, HeldConversation, MessageWindow } from './tables.js';
12
- export type TransferWriting = {
13
- readonly token: string | null;
14
- readonly written: number;
15
- };
16
12
  export type TransferRecord = {
17
13
  readonly locator: string;
18
14
  readonly transfer: string;
@@ -20,12 +16,10 @@ export type TransferRecord = {
20
16
  readonly from: string;
21
17
  readonly last: string;
22
18
  readonly pageToken: string | null;
23
- readonly writing: TransferWriting | null;
24
19
  readonly inventory: BootstrapInventory | null;
25
20
  readonly done: BootstrapInventory;
26
21
  readonly models: {
27
22
  readonly collection: ModelState;
28
- readonly selection: ModelState;
29
23
  };
30
24
  readonly key: number | null;
31
25
  };
@@ -90,6 +84,7 @@ export type RefreshedPage = StagedPage & {
90
84
  export type Opened = {
91
85
  readonly rooms: ReadonlyMap<string, ReplicaRecord>;
92
86
  readonly transfers: ReadonlyMap<string, TransferRecord>;
87
+ readonly kept: ReadonlyMap<string, ReadonlyMap<string, number>>;
93
88
  readonly unindexed: ReadonlySet<number>;
94
89
  readonly overlaid: ReadonlyMap<number, ReadonlySet<string>>;
95
90
  readonly erasing: boolean;
@@ -125,7 +120,7 @@ export type RuntimeStore = {
125
120
  search(ask: SearchAsk): Promise<SearchWindow>;
126
121
  stage(record: TransferRecord, composition: Composition, page: StagedPage, written?: string): Promise<number | null>;
127
122
  transferPart(locator: string, token: string): Promise<Uint8Array | null>;
128
- keepPart(locator: string, token: string, part: Uint8Array): Promise<void>;
123
+ keepParts(parts: readonly KeptPart[]): Promise<void>;
129
124
  refresh(key: number, page: RefreshedPage): Promise<void>;
130
125
  unrefresh(key: number): Promise<void>;
131
126
  commit(commit: Commit): Promise<CommittedWrite>;
@@ -133,7 +128,7 @@ export type RuntimeStore = {
133
128
  erase(locator: string | null, limit: number): Promise<boolean>;
134
129
  abandon(locator: string, kept?: boolean): Promise<number | null>;
135
130
  release(key: number): Promise<void>;
136
- rederive(key: number, limit: number): Promise<boolean>;
131
+ rederive(key: number, bytes: number): Promise<boolean>;
137
132
  fact(name: string, value: unknown): Promise<void>;
138
133
  queues(): Promise<readonly QueueRecord[]>;
139
134
  submit(locator: string, id: string, submission: Submission, lost: boolean): Promise<void>;
@@ -34,6 +34,7 @@ export type HeldKey = {
34
34
  readonly locator: string;
35
35
  readonly transfer: string;
36
36
  readonly rederiving: number | null;
37
+ readonly searching: number | null;
37
38
  };
38
39
  export type ReplicaOpened = {
39
40
  readonly rooms: readonly {
@@ -46,6 +47,11 @@ export type ReplicaOpened = {
46
47
  readonly key: number;
47
48
  readonly record: string;
48
49
  }[];
50
+ readonly kept: readonly {
51
+ readonly locator: string;
52
+ readonly token: string;
53
+ readonly bytes: number;
54
+ }[];
49
55
  readonly keys: readonly HeldKey[];
50
56
  readonly facts: Readonly<Record<string, string>>;
51
57
  readonly presentation: readonly {
@@ -122,7 +128,7 @@ export declare function release(connection: Connection, key: number): null;
122
128
  export declare function erase(connection: Connection, locator: string | null, limit: number): {
123
129
  readonly remaining: boolean;
124
130
  };
125
- export declare function rederive(connection: Connection, key: number, limit: number): {
131
+ export declare function rederive(connection: Connection, key: number, bytes: number): {
126
132
  readonly done: boolean;
127
133
  };
128
134
  export declare function entries(connection: Connection, key: number, view: View, list: readonly string[]): HeldEntry[];
@@ -135,10 +141,11 @@ export declare function files(connection: Connection, key: number, view: View, a
135
141
  }[];
136
142
  export declare function typedWithin(connection: Connection, key: number, view: View, roots: readonly string[], within: boolean): boolean;
137
143
  export declare function transferPart(connection: Connection, locator: string, token: string): Uint8Array | null;
138
- export declare function keepPart(connection: Connection, request: {
144
+ export type KeptPart = {
139
145
  readonly locator: string;
140
146
  readonly token: string;
141
147
  readonly part: Uint8Array;
142
- }): null;
148
+ };
149
+ export declare function keepParts(connection: Connection, parts: readonly KeptPart[]): null;
143
150
  export declare function opened(connection: Connection): ReplicaOpened;
144
151
  export declare function ended(connection: Connection): void;
@@ -5,8 +5,8 @@ import { type SearchAsk } from './fulltext.js';
5
5
  import { type ConversationWrite, type HeldConversation, type MessageWindow } from './messages.js';
6
6
  import type { Plan } from './query.js';
7
7
  import type { SearchWindow } from './search.js';
8
- import { type Committed, type CountedRoom, type HeldEntry, type ReplicaOpened, type Referrer, type RoomCommit, type StoredEntry, type TypedEntry, type View, type Walked } from './stored.js';
9
- export type { Committed, CountedRoom, HeldEntry, OverlayEntry, ReplicaOpened, Referrer, RoomCommit, StoredEntry, TypedEntry, View, Walked, } from './stored.js';
8
+ import { type Committed, type CountedRoom, type HeldEntry, type KeptPart, type ReplicaOpened, type Referrer, type RoomCommit, type StoredEntry, type TypedEntry, type View, type Walked } from './stored.js';
9
+ export type { Committed, CountedRoom, HeldEntry, KeptPart, OverlayEntry, ReplicaOpened, Referrer, RoomCommit, StoredEntry, TypedEntry, View, Walked, } from './stored.js';
10
10
  export type { QueryAnswer, QueryRoom } from './compile.js';
11
11
  export type { SearchAsk } from './fulltext.js';
12
12
  export type { ConversationWrite, HeldConversation, MessageWindow } from './messages.js';
@@ -226,10 +226,8 @@ export interface RuntimeRequests {
226
226
  readonly locator: string;
227
227
  readonly token: string;
228
228
  }, Uint8Array | null>;
229
- readonly 'replica.keepPart': Asked<{
230
- readonly locator: string;
231
- readonly token: string;
232
- readonly part: Uint8Array;
229
+ readonly 'replica.keepParts': Asked<{
230
+ readonly parts: readonly KeptPart[];
233
231
  }, null>;
234
232
  readonly 'replica.refresh': Asked<{
235
233
  readonly key: number;
@@ -263,7 +261,7 @@ export interface RuntimeRequests {
263
261
  }, null>;
264
262
  readonly 'replica.rederive': Asked<{
265
263
  readonly key: number;
266
- readonly limit: number;
264
+ readonly bytes: number;
267
265
  }, {
268
266
  readonly done: boolean;
269
267
  }>;
@@ -54,6 +54,14 @@ declare const MEMBERS: {
54
54
  readonly reach: 'within';
55
55
  readonly effect: 'read';
56
56
  };
57
+ readonly 'binaryFile.show': {
58
+ readonly reach: 'within';
59
+ readonly effect: 'read';
60
+ };
61
+ readonly 'binaryFile.attach': {
62
+ readonly reach: 'within';
63
+ readonly effect: 'action';
64
+ };
57
65
  readonly 'binaryFile.part': {
58
66
  readonly reach: 'within';
59
67
  readonly effect: 'read';
@@ -130,10 +138,6 @@ declare const MEMBERS: {
130
138
  readonly reach: 'within';
131
139
  readonly effect: 'action';
132
140
  };
133
- readonly 'conversation.attach': {
134
- readonly reach: 'within';
135
- readonly effect: 'action';
136
- };
137
141
  readonly 'conversation.answer': {
138
142
  readonly reach: 'within';
139
143
  readonly effect: 'action';
@@ -1,11 +1,17 @@
1
1
  import type { MdRuntimeClient } from './mdruntime/client.js';
2
- import type { HouseActivation, HouseAnalyticsChoice, HouseAppMessage, HouseExternalAnswer, HouseExternalRequest, HouseNavigationMode, HouseRefusal, HouseSourceDownload, HouseSourceTop, HouseStatus, HouseTab, HouseTask } from './index.js';
2
+ import type { HouseActivation, HouseAnalyticsChoice, HouseAppMessage, HouseChatOptions, HouseExternalAnswer, HouseExternalRequest, HouseNavigationMode, HouseRefusal, HouseSourceDownload, HouseSourceTop, HouseStatus, HouseTab, HouseTask } from './index.js';
3
3
  export interface HouseBridgeNavigation {
4
4
  readonly mode: HouseNavigationMode;
5
5
  readonly address: string;
6
6
  }
7
+ export interface HouseBridgeChat {
8
+ readonly element: object;
9
+ readonly options: HouseChatOptions;
10
+ readonly mounted: boolean;
11
+ }
7
12
  export interface HouseBridgeTestHost {
8
13
  readonly navigations: readonly HouseBridgeNavigation[];
14
+ readonly chats: readonly HouseBridgeChat[];
9
15
  readonly ceremonies: readonly string[];
10
16
  readonly consents: readonly HouseAnalyticsChoice[];
11
17
  readonly tabs: readonly HouseTab[];
package/dist/test-host.js CHANGED
@@ -50,6 +50,7 @@ export function createHouseBridgeTestHost(options = {}) {
50
50
  const consents = [];
51
51
  const tabs = [];
52
52
  const externalCalls = [];
53
+ const chats = [];
53
54
  const addressListeners = new Set();
54
55
  const statusListeners = new Set();
55
56
  const messageListeners = new Set();
@@ -100,6 +101,20 @@ export function createHouseBridgeTestHost(options = {}) {
100
101
  }
101
102
  const bridge = {
102
103
  runtime: runtime,
104
+ chat: {
105
+ mount(element, options = {}) {
106
+ const chat = { element, options, mounted: true };
107
+ chats.push(chat);
108
+ return Promise.resolve({
109
+ update(next) {
110
+ chat.options = next;
111
+ },
112
+ unmount() {
113
+ chat.mounted = false;
114
+ },
115
+ });
116
+ },
117
+ },
103
118
  address: () => shown,
104
119
  onAddress(listener) {
105
120
  return followHeld(addressListeners, listener, () => shown);
@@ -164,6 +179,7 @@ export function createHouseBridgeTestHost(options = {}) {
164
179
  arrive(current);
165
180
  return {
166
181
  navigations,
182
+ chats,
167
183
  ceremonies,
168
184
  consents,
169
185
  tabs,
package/docs/families.md CHANGED
@@ -96,8 +96,23 @@
96
96
  after its latest release, as a JPEG `Blob`, or `null` when House holds none
97
97
  or does not answer. A Site's own renderer reads none.
98
98
 
99
+ - **Chat** - `chat.mount(element, options)` places House's Chat, the one chat
100
+ in which the User's Agent conversations show, in `element` over the page's
101
+ `runtime` client, and resolves to a handle: `update(options)` replaces its
102
+ options and `unmount()` removes it. House serves the Chat with the page and
103
+ keeps it current, so the App installs and bundles nothing for it. The
104
+ options: `conversation` opens one, `null` for a new chat, `agent` is the
105
+ Agent a new chat goes to, `showChats` adds its conversation list, `width` is
106
+ `full`, the element, or `3/4`, `1/2` or `1/3` of the window docked at its
107
+ right edge, `onOpen` hears each conversation it opens as
108
+ `{ conversation, agent }`, and `onLink` takes a link without a scheme in
109
+ place of the browser. CSS custom properties named `--chat-*` on the element
110
+ or an ancestor set its look. It shows conversations only to a release that
111
+ declares them. A Site and the House panel have none: their call rejects with
112
+ an error named and coded `NotSupportedError`, with `retryable` false.
113
+
99
114
  - **Cooperation** - `cooperate({ checkpoint, persist, capture, restore,
100
- ready, settle })` lets House activate a newer release of the App while it
115
+ ready, settle })` lets House activate a newer release of the App while it
101
116
  runs, keeping the User's task; the function it returns withdraws it.
102
117
  Register it in the entry script, before the first draw, or House treats the
103
118
  page as not cooperating and the newer release waits for the App's next
@@ -141,7 +156,9 @@ records in `tabs` each `setTab`, answers a release code read from the
141
156
  by App reference and `readSiteScreenshot` from the `siteScreenshots` it was
142
157
  given by Site identifier, answers every `install()` `'manual'`, as a browser
143
158
  with no install prompt does, answers every `notifications()` `'unavailable'`,
144
- as a browser without push does, settles every `setBadge`, delivers each App
159
+ as a browser without push does, settles every `setBadge`, records in `chats`
160
+ each Chat `chat.mount` places, with its `element`, the `options` it was last
161
+ given and whether it is still `mounted`, drawing nothing, delivers each App
145
162
  message `message({ from, body })` plays, and hands `bridge.runtime` the MD
146
163
  Runtime client `attachRuntime(client)` gives it. `checkpoint()` runs the
147
164
  registered cooperation's checkpoint, persist and capture and answers the task,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@agentshouse/app-bridge",
3
- "version": "0.1.0-c6f0ca4067690",
4
- "description": "Types of the agents.house App bridge House hands every App: navigation, the tab title and icon, ceremonies, installation, notifications and the icon badge, status, Site image reads, App release code, App and Site screenshot reads, and App messages, with an accessor and an in-page test host.",
3
+ "version": "0.1.0-c6f4d423ead48",
4
+ "description": "Types of the agents.house App bridge House hands every App: navigation, the tab title and icon, ceremonies, installation, notifications and the icon badge, status, Site image reads, App release code, App and Site screenshot reads, App messages and the Chat, with an accessor and an in-page test host.",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
7
  "sideEffects": false,
@@ -23,5 +23,10 @@
23
23
  "docs",
24
24
  "README.md",
25
25
  "LICENSE"
26
- ]
26
+ ],
27
+ "repository": {
28
+ "type": "git",
29
+ "url": "git+https://github.com/agentshouse/core.git",
30
+ "directory": "client"
31
+ }
27
32
  }
@@ -1,11 +0,0 @@
1
- export type ChosenFile = {
2
- name: string;
3
- blob: Blob;
4
- };
5
- export type FileDeclaration = {
6
- name: string;
7
- mediaType: string;
8
- byteLength: number;
9
- contentHash: string;
10
- };
11
- export declare function declaredFile(file: ChosenFile): Promise<FileDeclaration>;