@noodleseed/one 0.176.0 → 0.178.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 (73) hide show
  1. package/dist/commands/solutions-activity.d.ts.map +1 -1
  2. package/dist/commands/solutions-activity.js +9 -35
  3. package/dist/commands/solutions-activity.js.map +1 -1
  4. package/dist/commands/solutions-conversations.d.ts +6 -0
  5. package/dist/commands/solutions-conversations.d.ts.map +1 -0
  6. package/dist/commands/solutions-conversations.js +191 -0
  7. package/dist/commands/solutions-conversations.js.map +1 -0
  8. package/dist/commands/solutions-history.d.ts +9 -0
  9. package/dist/commands/solutions-history.d.ts.map +1 -0
  10. package/dist/commands/solutions-history.js +166 -0
  11. package/dist/commands/solutions-history.js.map +1 -0
  12. package/dist/commands/solutions-ops.d.ts.map +1 -1
  13. package/dist/commands/solutions-ops.js +6 -0
  14. package/dist/commands/solutions-ops.js.map +1 -1
  15. package/dist/commands/whatsapp-ops.d.ts.map +1 -1
  16. package/dist/commands/whatsapp-ops.js +0 -7
  17. package/dist/commands/whatsapp-ops.js.map +1 -1
  18. package/node_modules/@noodle-borg/agent-kit/dist/generated/example-files.js +1 -1
  19. package/node_modules/@noodle-borg/agent-kit/dist/skill-embedded-assistant-ref.js +14 -0
  20. package/node_modules/@noodle-borg/agent-kit/package.json +1 -1
  21. package/node_modules/@noodle-borg/assistant-gateway/dist/public-surface.d.ts +6 -0
  22. package/node_modules/@noodle-borg/assistant-gateway/dist/public-surface.js +5 -2
  23. package/node_modules/@noodle-borg/assistant-gateway/package.json +1 -1
  24. package/node_modules/@noodle-borg/authoring/dist/assistant.d.ts +18 -0
  25. package/node_modules/@noodle-borg/authoring/dist/assistant.js +14 -1
  26. package/node_modules/@noodle-borg/cli-catalog/dist/catalog-data-channels.js +0 -3
  27. package/node_modules/@noodle-borg/cli-catalog/dist/catalog-data-solution-conversations.js +142 -0
  28. package/node_modules/@noodle-borg/cli-catalog/dist/catalog-data-solution-history.js +82 -0
  29. package/node_modules/@noodle-borg/cli-catalog/dist/catalog-data-solutions.js +5 -42
  30. package/node_modules/@noodle-borg/compiler/dist/manifest/schema.d.ts +8 -0
  31. package/node_modules/@noodle-borg/compiler/dist/manifest/schema.js +7 -0
  32. package/node_modules/@noodle-borg/service/dist/application-activity.js +76 -21
  33. package/node_modules/@noodle-borg/service/dist/application-history-settings.js +108 -0
  34. package/node_modules/@noodle-borg/service/dist/assistant-composition.js +11 -2
  35. package/node_modules/@noodle-borg/service/dist/channels/composition.js +10 -1
  36. package/node_modules/@noodle-borg/service/dist/channels/provider.js +40 -4
  37. package/node_modules/@noodle-borg/service/dist/channels/runtime.js +31 -5
  38. package/node_modules/@noodle-borg/service/dist/conversation-history/capture.js +63 -7
  39. package/node_modules/@noodle-borg/service/dist/conversation-history/contracts.js +13 -0
  40. package/node_modules/@noodle-borg/service/dist/conversation-history/customer.js +118 -0
  41. package/node_modules/@noodle-borg/service/dist/conversation-history/operator.js +293 -0
  42. package/node_modules/@noodle-borg/service/dist/routes/assistant-conversations.js +52 -0
  43. package/node_modules/@noodle-borg/service/dist/routes/assistant-dispatch.js +6 -0
  44. package/node_modules/@noodle-borg/service/dist/routes/assistant-elevation.js +3 -0
  45. package/node_modules/@noodle-borg/service/dist/routes/assistant-interaction-stream.js +2 -1
  46. package/node_modules/@noodle-borg/service/dist/routes/assistant-interactions.js +6 -11
  47. package/node_modules/@noodle-borg/service/dist/routes/assistant-public-session.js +6 -0
  48. package/node_modules/@noodle-borg/service/dist/routes/assistant-route-http.js +16 -0
  49. package/node_modules/@noodle-borg/service/dist/routes/assistant.js +5 -17
  50. package/node_modules/@noodle-borg/service/dist/routes/business-information-activity.js +6 -5
  51. package/node_modules/@noodle-borg/service/dist/routes/business-information-conversations.js +90 -0
  52. package/node_modules/@noodle-borg/service/dist/routes/business-information-dispatch.js +7 -2
  53. package/node_modules/@noodle-borg/service/dist/routes/business-information-paths.js +20 -2
  54. package/node_modules/@noodle-borg/service/dist/routes/business-information.js +4 -0
  55. package/node_modules/@noodle-borg/service/dist/routes/whatsapp.js +0 -10
  56. package/node_modules/@noodle-borg/service/dist/service-history-projections.js +52 -0
  57. package/node_modules/@noodle-borg/service/dist/service-resource-cleanup.js +32 -0
  58. package/node_modules/@noodle-borg/service/dist/service.js +6 -9
  59. package/node_modules/@noodle-borg/service/package.json +1 -1
  60. package/node_modules/@noodle-borg/wire-contracts/dist/application-activity.d.ts +0 -28
  61. package/node_modules/@noodle-borg/wire-contracts/dist/application-activity.js +0 -18
  62. package/node_modules/@noodle-borg/wire-contracts/dist/application-history-settings.d.ts +190 -0
  63. package/node_modules/@noodle-borg/wire-contracts/dist/application-history-settings.js +92 -0
  64. package/node_modules/@noodle-borg/wire-contracts/dist/assistant.d.ts +3 -0
  65. package/node_modules/@noodle-borg/wire-contracts/dist/assistant.js +6 -0
  66. package/node_modules/@noodle-borg/wire-contracts/dist/conversation-history.d.ts +523 -0
  67. package/node_modules/@noodle-borg/wire-contracts/dist/conversation-history.js +192 -0
  68. package/node_modules/@noodle-borg/wire-contracts/dist/index.d.ts +2 -0
  69. package/node_modules/@noodle-borg/wire-contracts/dist/index.js +2 -0
  70. package/node_modules/@noodle-borg/wire-contracts/dist/whatsapp.d.ts +2 -2
  71. package/node_modules/@noodleseed/assistant/README.md +19 -0
  72. package/node_modules/@noodleseed/assistant/package.json +1 -1
  73. package/package.json +2 -2
@@ -0,0 +1,192 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * Staff projection of durable conversation history (ADR 0241). Server output is strict; the tolerant
4
+ * `*ClientResponseSchema` variants let older clients ignore additive fields.
5
+ */
6
+ export const ConversationIdSchema = z.string().regex(/^cv_[A-Za-z0-9_-]{8,64}$/);
7
+ export const ConversationChannelSchema = z.enum(['website', 'whatsapp']);
8
+ /** Staff review state; a failed tool outcome sets `needs_attention` automatically. */
9
+ export const ConversationReviewStatusSchema = z.enum(['new', 'needs_attention', 'reviewed']);
10
+ const SubjectRefSchema = z.string().min(1).max(256);
11
+ /** Anonymous handles never leave the service; verified subjects carry the reference forget uses. */
12
+ const ConversationSubjectSchema = z.discriminatedUnion('kind', [
13
+ z.strictObject({ kind: z.literal('anonymous') }),
14
+ z.strictObject({ kind: z.literal('customer'), ref: SubjectRefSchema }),
15
+ z.strictObject({ kind: z.literal('participant'), ref: SubjectRefSchema }),
16
+ ]);
17
+ export const ConversationSummarySchema = z.strictObject({
18
+ id: ConversationIdSchema,
19
+ channel: ConversationChannelSchema,
20
+ subject: ConversationSubjectSchema,
21
+ startedAt: z.iso.datetime(),
22
+ lastMessageAt: z.iso.datetime(),
23
+ itemCount: z.number().int().min(1),
24
+ reviewStatus: ConversationReviewStatusSchema,
25
+ });
26
+ export const ConversationItemSchema = z.discriminatedUnion('kind', [
27
+ z.strictObject({
28
+ kind: z.literal('message'),
29
+ role: z.enum(['user', 'assistant']),
30
+ text: z.string().max(100_000),
31
+ at: z.iso.datetime(),
32
+ }),
33
+ z.strictObject({
34
+ kind: z.literal('outcome'),
35
+ interactionId: z.string().min(1).max(256),
36
+ tool: z.string().min(1).max(128),
37
+ status: z.enum(['succeeded', 'failed', 'declined', 'cancelled']),
38
+ at: z.iso.datetime(),
39
+ }),
40
+ ]);
41
+ export const ConversationDetailSchema = z.strictObject({
42
+ ...ConversationSummarySchema.shape,
43
+ /** When the last visible item is removed automatically under the live retention window. */
44
+ expiresAt: z.iso.datetime(),
45
+ items: z.array(ConversationItemSchema).max(10_000),
46
+ });
47
+ const NoteTextSchema = z.string().trim().min(1).max(2000);
48
+ /** A private staff note: never sent to the customer, never exported, removed with its conversation. */
49
+ export const ConversationNoteSchema = z.strictObject({
50
+ author: z.string().min(1).max(500),
51
+ text: NoteTextSchema,
52
+ at: z.iso.datetime(),
53
+ });
54
+ /** Show adds the private notes that export leaves out. */
55
+ export const ConversationShowSchema = z.strictObject({
56
+ ...ConversationDetailSchema.shape,
57
+ notes: z.array(ConversationNoteSchema).max(100),
58
+ });
59
+ const NextCursorSchema = z.string().min(1).max(2048);
60
+ export const ConversationListResponseSchema = z.strictObject({
61
+ ok: z.literal(true),
62
+ data: z.strictObject({
63
+ conversations: z.array(ConversationSummarySchema).max(100),
64
+ nextCursor: NextCursorSchema.optional(),
65
+ }),
66
+ });
67
+ /** Show and review both answer with the conversation as staff now see it. */
68
+ export const ConversationShowResponseSchema = z.strictObject({
69
+ ok: z.literal(true),
70
+ data: z.strictObject({ conversation: ConversationShowSchema }),
71
+ });
72
+ /** Review status needs `records:status`, a note `records:note`; at least one is required. */
73
+ export const ConversationReviewRequestSchema = z
74
+ .strictObject({
75
+ reviewStatus: ConversationReviewStatusSchema.optional(),
76
+ note: NoteTextSchema.optional(),
77
+ })
78
+ .refine((value) => value.reviewStatus !== undefined || value.note !== undefined, {
79
+ message: 'Set a review status or add a note.',
80
+ });
81
+ export const ConversationExportResponseSchema = z.strictObject({
82
+ ok: z.literal(true),
83
+ data: z.strictObject({
84
+ conversations: z.array(ConversationDetailSchema).max(25),
85
+ nextCursor: NextCursorSchema.optional(),
86
+ }),
87
+ });
88
+ export const ConversationForgetRequestSchema = z.union([
89
+ z.strictObject({ conversationId: ConversationIdSchema }),
90
+ z.strictObject({
91
+ subject: z.strictObject({
92
+ kind: z.enum(['customer', 'participant']),
93
+ ref: SubjectRefSchema,
94
+ }),
95
+ }),
96
+ ]);
97
+ export const ConversationForgetResponseSchema = z.strictObject({
98
+ ok: z.literal(true),
99
+ data: z.strictObject({
100
+ forgotten: z.strictObject({
101
+ conversations: z.number().int().nonnegative(),
102
+ items: z.number().int().nonnegative(),
103
+ }),
104
+ }),
105
+ });
106
+ const ClientSubjectSchema = z.discriminatedUnion('kind', [
107
+ z.object({ kind: z.literal('anonymous') }),
108
+ z.object({ kind: z.literal('customer'), ref: SubjectRefSchema }),
109
+ z.object({ kind: z.literal('participant'), ref: SubjectRefSchema }),
110
+ ]);
111
+ const ClientSummarySchema = z.object({
112
+ ...ConversationSummarySchema.shape,
113
+ subject: ClientSubjectSchema,
114
+ });
115
+ const ClientItemSchema = z.discriminatedUnion('kind', [
116
+ z.object(ConversationItemSchema.options[0].shape),
117
+ z.object(ConversationItemSchema.options[1].shape),
118
+ ]);
119
+ const ClientDetailSchema = z.object({
120
+ ...ClientSummarySchema.shape,
121
+ expiresAt: ConversationDetailSchema.shape.expiresAt,
122
+ items: z.array(ClientItemSchema).max(10_000),
123
+ });
124
+ export const ConversationListClientResponseSchema = z.object({
125
+ ok: z.literal(true),
126
+ data: z.object({
127
+ conversations: z.array(ClientSummarySchema).max(100),
128
+ nextCursor: NextCursorSchema.optional(),
129
+ }),
130
+ });
131
+ export const ConversationShowClientResponseSchema = z.object({
132
+ ok: z.literal(true),
133
+ data: z.object({
134
+ conversation: z.object({
135
+ ...ClientDetailSchema.shape,
136
+ notes: z.array(z.object(ConversationNoteSchema.shape)).max(100),
137
+ }),
138
+ }),
139
+ });
140
+ export const ConversationExportClientResponseSchema = z.object({
141
+ ok: z.literal(true),
142
+ data: z.object({
143
+ conversations: z.array(ClientDetailSchema).max(25),
144
+ nextCursor: NextCursorSchema.optional(),
145
+ }),
146
+ });
147
+ export const ConversationForgetClientResponseSchema = z.object({
148
+ ok: z.literal(true),
149
+ data: z.object({
150
+ forgotten: z.object(ConversationForgetResponseSchema.shape.data.shape.forgotten.shape),
151
+ }),
152
+ });
153
+ /**
154
+ * The customer-backend projection (ADR 0241 decision 12): an embed client lists or forgets one of its
155
+ * own verified users, by the same `user.id` its session exchange sent. The tenant comes from the client
156
+ * credential, never the body; rows carry no subject and at most a short preview of the first question.
157
+ */
158
+ const CustomerUserSchema = z.strictObject({ id: z.string().min(1).max(240) });
159
+ export const ASSISTANT_CONVERSATION_PAGE_MAXIMUM = 50;
160
+ export const ASSISTANT_CONVERSATION_PREVIEW_MAXIMUM = 120;
161
+ export const AssistantConversationListRequestSchema = z.strictObject({
162
+ user: CustomerUserSchema,
163
+ limit: z.number().int().min(1).max(ASSISTANT_CONVERSATION_PAGE_MAXIMUM).optional(),
164
+ cursor: NextCursorSchema.optional(),
165
+ });
166
+ export const AssistantConversationForgetUserRequestSchema = z.strictObject({
167
+ user: CustomerUserSchema,
168
+ });
169
+ const AssistantConversationRowSchema = z.strictObject({
170
+ id: ConversationIdSchema,
171
+ channel: ConversationChannelSchema,
172
+ startedAt: z.iso.datetime(),
173
+ lastMessageAt: z.iso.datetime(),
174
+ preview: z.string().min(1).max(ASSISTANT_CONVERSATION_PREVIEW_MAXIMUM).optional(),
175
+ });
176
+ export const AssistantConversationListResponseSchema = z.strictObject({
177
+ ok: z.literal(true),
178
+ data: z.strictObject({
179
+ conversations: z.array(AssistantConversationRowSchema).max(ASSISTANT_CONVERSATION_PAGE_MAXIMUM),
180
+ nextCursor: NextCursorSchema.optional(),
181
+ }),
182
+ });
183
+ export const AssistantConversationListClientResponseSchema = z.object({
184
+ ok: z.literal(true),
185
+ data: z.object({
186
+ conversations: z
187
+ .array(z.object(AssistantConversationRowSchema.shape))
188
+ .max(ASSISTANT_CONVERSATION_PAGE_MAXIMUM),
189
+ nextCursor: NextCursorSchema.optional(),
190
+ }),
191
+ });
192
+ //# sourceMappingURL=conversation-history.js.map
@@ -391,9 +391,11 @@ export * from './application-activity.js';
391
391
  export * from './application-connections.js';
392
392
  export * from './application-draft-validation.js';
393
393
  export * from './application-drafts.js';
394
+ export * from './application-history-settings.js';
394
395
  export * from './application-onboarding.js';
395
396
  export * from './billing-catalog.js';
396
397
  export * from './business-workspaces.js';
398
+ export * from './conversation-history.js';
397
399
  export * from './deployment-deletion.js';
398
400
  export * from './native-record-lifecycle.js';
399
401
  export * from './operation-coordination.js';
@@ -230,9 +230,11 @@ export * from './application-activity.js';
230
230
  export * from './application-connections.js';
231
231
  export * from './application-draft-validation.js';
232
232
  export * from './application-drafts.js';
233
+ export * from './application-history-settings.js';
233
234
  export * from './application-onboarding.js';
234
235
  export * from './billing-catalog.js';
235
236
  export * from './business-workspaces.js';
237
+ export * from './conversation-history.js';
236
238
  export * from './deployment-deletion.js';
237
239
  export * from './native-record-lifecycle.js';
238
240
  export * from './operation-coordination.js';
@@ -359,11 +359,11 @@ export declare const WhatsAppEventsResponseSchema: z.ZodObject<{
359
359
  queued: "queued";
360
360
  running: "running";
361
361
  failed: "failed";
362
+ cancelled: "cancelled";
362
363
  delivered: "delivered";
363
364
  reply: "reply";
364
365
  sending: "sending";
365
366
  refused: "refused";
366
- cancelled: "cancelled";
367
367
  }>;
368
368
  eventAt: z.ZodNumber;
369
369
  receivedAt: z.ZodNumber;
@@ -386,11 +386,11 @@ export declare const WhatsAppEventsClientResponseSchema: z.ZodObject<{
386
386
  queued: "queued";
387
387
  running: "running";
388
388
  failed: "failed";
389
+ cancelled: "cancelled";
389
390
  delivered: "delivered";
390
391
  reply: "reply";
391
392
  sending: "sending";
392
393
  refused: "refused";
393
- cancelled: "cancelled";
394
394
  }>;
395
395
  eventAt: z.ZodNumber;
396
396
  receivedAt: z.ZodNumber;
@@ -626,6 +626,25 @@ replay across sessions. React applications may observe recovery and structured f
626
626
  `createAssistantSession` returns the opaque token, expiry, resolved non-secret configuration, and explicit
627
627
  turn/interaction endpoint URLs. Forward that response unchanged to the component or headless client.
628
628
 
629
+ #### Your users' conversation history
630
+
631
+ When the business records conversations, the same backend credential lists or erases one signed-in user's
632
+ chats. Pass the exact `user.id` your session exchange sends; the client's application environment is the
633
+ only scope, so one customer's backend never reaches another's history.
634
+
635
+ ```ts
636
+ import { forgetUser, listConversations } from "@noodleseed/assistant/server";
637
+
638
+ const credentials = { serviceUrl, clientId, clientSecret };
639
+ // A "your chats" view: newest first, each with a short preview of the first question.
640
+ const page = await listConversations({ ...credentials, user: { id: account.id }, limit: 20 });
641
+ // In your own account deletion. Idempotent, so a retry after a 5xx is safe.
642
+ await forgetUser({ ...credentials, user: { id: account.id } });
643
+ ```
644
+
645
+ `forgetUser` erases stored conversation history only; a live session's short-lived working memory is not
646
+ touched and expires within two hours. Failures throw `AssistantConversationsError` with a typed `detail` (`status`, `retryable`, `serviceCode`).
647
+
629
648
  The MCP server's top-level `branding` block is the portable deployment source for identity and colors shared
630
649
  by widgets and the assistant. The embedding application may use the typed `appearance` object when it needs
631
650
  exact control over assistant-specific roles:
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@noodleseed/assistant",
3
- "version": "1.36.1",
3
+ "version": "1.37.0",
4
4
  "description": "Embed the Noodle Seed customer-branded assistant in your web app with managed or framework-owned UI, a framework-neutral MCP App host, a DOM-free client, and a backend session helper. Authoring and deploying the server is @noodleseed/one.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@noodleseed/one",
3
- "version": "0.176.0",
3
+ "version": "0.178.0",
4
4
  "private": false,
5
5
  "description": "Noodle CLI by Noodle Seed — author, run, and deploy declarative MCP servers. Embedding the assistant in your own web app is @noodleseed/assistant.",
6
6
  "license": "Apache-2.0",
@@ -236,7 +236,7 @@
236
236
  "@modelcontextprotocol/client": "2.0.0",
237
237
  "@modelcontextprotocol/server": "2.0.0",
238
238
  "@noodle-borg/admission-limits": "0.0.0",
239
- "@noodle-borg/agent-kit": "0.107.0",
239
+ "@noodle-borg/agent-kit": "0.108.0",
240
240
  "@noodle-borg/app-audit": "0.0.0",
241
241
  "@noodle-borg/app-package": "0.0.0",
242
242
  "@noodle-borg/assistant-gateway": "0.0.0",