@signalcore/ui 1.0.0-beta.2 → 1.0.0-beta.4

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 (99) hide show
  1. package/README.md +126 -21
  2. package/dist/AgentAbout.js +6 -2
  3. package/dist/AgentAbout.js.map +1 -1
  4. package/dist/AgentChat.d.ts +25 -3
  5. package/dist/AgentChat.js +302 -28
  6. package/dist/AgentChat.js.map +1 -1
  7. package/dist/AgentSpace.d.ts +25 -4
  8. package/dist/AgentSpace.js +55 -11
  9. package/dist/AgentSpace.js.map +1 -1
  10. package/dist/Threads.d.ts +73 -0
  11. package/dist/Threads.js +140 -0
  12. package/dist/Threads.js.map +1 -0
  13. package/dist/View.d.ts +48 -0
  14. package/dist/View.js +101 -0
  15. package/dist/View.js.map +1 -0
  16. package/dist/automation/marks.js +7 -3
  17. package/dist/automation/marks.js.map +1 -1
  18. package/dist/automation/messages.d.ts +4 -0
  19. package/dist/automation/messages.js +5 -1
  20. package/dist/automation/messages.js.map +1 -1
  21. package/dist/automation/when.js +8 -0
  22. package/dist/automation/when.js.map +1 -1
  23. package/dist/blocks.d.ts +83 -2
  24. package/dist/client.d.ts +23 -5
  25. package/dist/client.js +8 -2
  26. package/dist/client.js.map +1 -1
  27. package/dist/contract.d.ts +9 -4
  28. package/dist/es.d.ts +2 -0
  29. package/dist/es.js +34 -3
  30. package/dist/es.js.map +1 -1
  31. package/dist/frames.d.ts +7 -1
  32. package/dist/frames.js.map +1 -1
  33. package/dist/index.d.ts +14 -7
  34. package/dist/index.js +11 -4
  35. package/dist/kit/Agenda.d.ts +25 -0
  36. package/dist/kit/Agenda.js +119 -0
  37. package/dist/kit/Agenda.js.map +1 -0
  38. package/dist/kit/Combobox.js +1 -1
  39. package/dist/kit/DateField.js +1 -1
  40. package/dist/kit/Kanban.d.ts +17 -0
  41. package/dist/kit/Kanban.js +157 -0
  42. package/dist/kit/Kanban.js.map +1 -0
  43. package/dist/kit/TimeField.js +1 -1
  44. package/dist/kit/Timeline.d.ts +14 -0
  45. package/dist/kit/Timeline.js +71 -0
  46. package/dist/kit/Timeline.js.map +1 -0
  47. package/dist/kit/context.d.ts +1 -1
  48. package/dist/kit/context.js.map +1 -1
  49. package/dist/kit/messages.d.ts +22 -0
  50. package/dist/kit/messages.js +10 -0
  51. package/dist/kit/messages.js.map +1 -1
  52. package/dist/surface/Form.js +1 -1
  53. package/dist/surface/Placed.d.ts +20 -0
  54. package/dist/surface/Placed.js +70 -0
  55. package/dist/surface/Placed.js.map +1 -0
  56. package/dist/surface/Surface.d.ts +4 -2
  57. package/dist/surface/Surface.js +78 -2
  58. package/dist/surface/Surface.js.map +1 -1
  59. package/dist/surface/places.d.ts +16 -0
  60. package/dist/surface/places.js +15 -0
  61. package/dist/surface/places.js.map +1 -0
  62. package/dist/surface/scope.d.ts +17 -1
  63. package/dist/surface/scope.js +1 -0
  64. package/dist/surface/scope.js.map +1 -1
  65. package/dist/types.d.ts +23 -0
  66. package/dist/types.js.map +1 -1
  67. package/dist/useConversation.d.ts +2 -0
  68. package/dist/useConversation.js +16 -0
  69. package/dist/useConversation.js.map +1 -1
  70. package/dist/widget.js +17 -16
  71. package/package.json +1 -1
  72. package/src/AgentAbout.tsx +4 -0
  73. package/src/AgentChat.tsx +417 -34
  74. package/src/AgentSpace.tsx +106 -14
  75. package/src/Threads.tsx +218 -0
  76. package/src/View.tsx +117 -0
  77. package/src/automation/marks.tsx +7 -0
  78. package/src/automation/messages.ts +8 -0
  79. package/src/automation/when.ts +4 -0
  80. package/src/blocks.ts +100 -2
  81. package/src/client.ts +42 -10
  82. package/src/contract.ts +404 -29
  83. package/src/es.ts +30 -0
  84. package/src/frames.ts +3 -1
  85. package/src/index.ts +36 -3
  86. package/src/kit/Agenda.tsx +161 -0
  87. package/src/kit/Kanban.tsx +182 -0
  88. package/src/kit/Timeline.tsx +58 -0
  89. package/src/kit/context.tsx +45 -1
  90. package/src/kit/messages.ts +31 -0
  91. package/src/styles.css +825 -66
  92. package/src/surface/Placed.tsx +98 -0
  93. package/src/surface/Surface.tsx +92 -1
  94. package/src/surface/places.ts +19 -0
  95. package/src/surface/scope.ts +24 -1
  96. package/src/types.ts +24 -0
  97. package/src/useConversation.ts +10 -0
  98. package/src/widget/element.tsx +54 -7
  99. package/src/widget/widget.css +13 -0
package/src/blocks.ts CHANGED
@@ -124,6 +124,88 @@ export interface ConnectBlock {
124
124
  connection: ConnectView | null;
125
125
  }
126
126
 
127
+ // --- Time and work ------------------------------------------------------------------------
128
+
129
+ /**
130
+ * One thing on a calendar: its title at its time ("YYYY-MM-DDTHH:MM" in the person's time; a day
131
+ * alone, "YYYY-MM-DD", is all of it), until `end`, with a line of detail and a page to open.
132
+ */
133
+ export interface CalendarEvent {
134
+ id: string;
135
+ title: string;
136
+ start: string;
137
+ end?: string;
138
+ detail?: string;
139
+ /** https only. */
140
+ url?: string;
141
+ }
142
+
143
+ /**
144
+ * A day's events, or a week's from `start` ("YYYY-MM-DD"), in their order. With `action`,
145
+ * pressing one sends it with `{event: id}`; one with `url` opens its page instead.
146
+ */
147
+ export interface CalendarBlock {
148
+ type: "calendar";
149
+ span: "day" | "week";
150
+ start: string;
151
+ events: CalendarEvent[];
152
+ action?: string;
153
+ }
154
+
155
+ /** One thing on a timeline: when, what, a line about it, where it stands in a word, its mark. */
156
+ export interface TimelineItem {
157
+ id?: string;
158
+ at: string;
159
+ title: string;
160
+ text?: string;
161
+ status?: string;
162
+ tone?: Tone;
163
+ }
164
+
165
+ /** Dated things, one under another, the newest first. */
166
+ export interface TimelineBlock {
167
+ type: "timeline";
168
+ items: TimelineItem[];
169
+ }
170
+
171
+ export interface BoardCard {
172
+ id: string;
173
+ title: string;
174
+ subtitle?: string;
175
+ /** At its foot: a price, a day, who. */
176
+ meta?: string;
177
+ }
178
+
179
+ export interface BoardColumn {
180
+ id: string;
181
+ title: string;
182
+ cards: BoardCard[];
183
+ }
184
+
185
+ /**
186
+ * Cards in columns, a column per stage. With `action`, the person moves a card to another column,
187
+ * which sends `action` with `{card, column}`.
188
+ */
189
+ export interface BoardBlock {
190
+ type: "board";
191
+ columns: BoardColumn[];
192
+ action?: string;
193
+ }
194
+
195
+ // --- The host's own -----------------------------------------------------------------------
196
+
197
+ /**
198
+ * One of the host's own blocks, by the name it declared (`PUT /v1/blocks/{name}`): its `props`,
199
+ * checked by the API against the schema the host declared, and `text`, the same in words, which a
200
+ * page that doesn't draw it shows instead.
201
+ */
202
+ export interface HostBlock {
203
+ type: "host";
204
+ name: string;
205
+ props: Record<string, unknown>;
206
+ text: string;
207
+ }
208
+
127
209
  // --- Action -------------------------------------------------------------------------------
128
210
 
129
211
  /** One thing the person can do: pressing it sends `action`, or, with `url`, opens that page. */
@@ -265,10 +347,26 @@ export type Block =
265
347
  | ConnectBlock
266
348
  | ButtonBlock
267
349
  | ChoiceBlock
268
- | FormBlock;
350
+ | FormBlock
351
+ | CalendarBlock
352
+ | TimelineBlock
353
+ | BoardBlock
354
+ | HostBlock;
269
355
 
270
- /** What the agent shows: blocks, and the words a channel without a screen gets instead. */
356
+ /**
357
+ * Where a surface shows in a page: in the conversation, in a panel beside it, or in a modal over
358
+ * it. A page that doesn't allow the place shows it in the conversation.
359
+ */
360
+ export type Place = "chat" | "panel" | "modal";
361
+
362
+ /**
363
+ * What the agent shows: blocks, and the words a channel without a screen gets instead; where it
364
+ * shows and, in a panel or a modal, its title, which the conversation's line to open it says.
365
+ */
271
366
  export interface Surface {
272
367
  blocks: Block[];
273
368
  text: string;
369
+ /** None: the conversation. */
370
+ where?: Place;
371
+ title?: string;
274
372
  }
package/src/client.ts CHANGED
@@ -13,6 +13,7 @@ import type {
13
13
  FileLink,
14
14
  FilePreview,
15
15
  StoredFile,
16
+ ViewRendered,
16
17
  } from "./types";
17
18
 
18
19
  /**
@@ -127,8 +128,10 @@ export interface Client {
127
128
  /** Takes one memory from it. */
128
129
  forget: (id: string, memoryId: string) => Promise<void>;
129
130
  /**
130
- * The owner's call with the agent, from the browser (v3/VOICE.md): the call and its
131
- * conversation (a test) made now, and where to join it (`VoiceCall`'s `connect`).
131
+ * The owner's call with the agent, from our own app (v3/VOICE.md): the call and its
132
+ * conversation (a test) made now, and where to join it (`VoiceCall`'s `connect`). App only:
133
+ * it is `/api`'s, signed in by the owner's cookie, and 404s on `/v1`; a host's page calls with
134
+ * `conversations.call(agentId)`.
132
135
  */
133
136
  call: (id: string) => Promise<CallToken>;
134
137
  };
@@ -151,6 +154,14 @@ export interface Client {
151
154
  /** One run of an automation with its record: every call it made, step by step. */
152
155
  get: (id: string) => Promise<RunRecord>;
153
156
  };
157
+ /** What an agent keeps on show for each person it serves (`compose_view`, `/agents/{id}/views`). */
158
+ views: {
159
+ /**
160
+ * A view rendered from the rows now: for a person, their own; for the business, for the
161
+ * contact it names (`contact`, their id).
162
+ */
163
+ render: (name: string, contact?: string) => Promise<ViewRendered>;
164
+ };
154
165
  /**
155
166
  * The tasks an agent runs for contacts, each with its newest runs: a person's own only (what
156
167
  * they asked the agent for in their conversations); the business's, every one.
@@ -169,8 +180,14 @@ export interface Client {
169
180
  conversations: {
170
181
  /** One conversation with its messages. */
171
182
  get: (id: string) => Promise<ConversationDetail>;
172
- /** A new conversation with an agent. */
173
- start: (agentId: string) => Promise<Conversation>;
183
+ /** The agent's conversations, newest first: a person's own only, each with what is unread. */
184
+ list: (agentId: string) => Promise<Conversation[]>;
185
+ /** A new conversation with an agent, titled when given. */
186
+ start: (agentId: string, options?: { title?: string | undefined }) => Promise<Conversation>;
187
+ /** How far the person has read it: all of it, now. */
188
+ read: (id: string) => Promise<Conversation>;
189
+ /** Its title, as the person gives it. */
190
+ rename: (id: string, title: string) => Promise<Conversation>;
174
191
  /** The files that arrived in a conversation: attached, sent through a form. */
175
192
  files: (id: string) => Promise<ConversationFile[]>;
176
193
  /**
@@ -201,6 +218,10 @@ export interface Client {
201
218
 
202
219
  const seg = encodeURIComponent;
203
220
 
221
+ /** A request's JSON body. */
222
+ const body = (value: unknown): Blob =>
223
+ new Blob([JSON.stringify(value)], { type: "application/json" });
224
+
204
225
  /** A file's path in a URL: each name of it encoded, the slashes between them kept. */
205
226
  const filePath = (path: string): string => path.split("/").map(seg).join("/");
206
227
 
@@ -354,14 +375,17 @@ export function createClient(options: ClientOptions): Client {
354
375
  runs: {
355
376
  get: (id) => json("GET", `/runs/${seg(id)}`),
356
377
  },
378
+ views: {
379
+ render: (name, contact) =>
380
+ json(
381
+ "GET",
382
+ `/views/${seg(name)}/render${contact === undefined ? "" : `?contact=${seg(contact)}`}`,
383
+ ),
384
+ },
357
385
  tasks: {
358
386
  list: (agentId) => json("GET", `/agents/${seg(agentId)}/tasks`),
359
387
  switch: (agentId, taskId, on) =>
360
- json(
361
- "PATCH",
362
- `/agents/${seg(agentId)}/tasks/${seg(taskId)}`,
363
- new Blob([JSON.stringify({ on })], { type: "application/json" }),
364
- ),
388
+ json("PATCH", `/agents/${seg(agentId)}/tasks/${seg(taskId)}`, body({ on })),
365
389
  remove: (agentId, taskId) => run("DELETE", `/agents/${seg(agentId)}/tasks/${seg(taskId)}`),
366
390
  },
367
391
  channels: {
@@ -370,7 +394,15 @@ export function createClient(options: ClientOptions): Client {
370
394
  },
371
395
  conversations: {
372
396
  get: (id) => json("GET", `/conversations/${seg(id)}`),
373
- start: (agentId) => json("POST", `/agents/${seg(agentId)}/conversations`),
397
+ list: (agentId) => json("GET", `/agents/${seg(agentId)}/conversations`),
398
+ start: (agentId, { title } = {}) =>
399
+ json(
400
+ "POST",
401
+ `/agents/${seg(agentId)}/conversations`,
402
+ title === undefined ? undefined : body({ title }),
403
+ ),
404
+ read: (id) => json("POST", `/conversations/${seg(id)}/read`, body({})),
405
+ rename: (id, title) => json("PATCH", `/conversations/${seg(id)}`, body({ title })),
374
406
  files: (id) => json("GET", `/conversations/${seg(id)}/files`),
375
407
  upload: (id, file, options) => sendFile(`/conversations/${seg(id)}/files`, file, options),
376
408
  play: async (id, fileId) => {