@multiplayer-app/ai-agent-types 0.0.1-beta.2 → 0.0.1

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
@@ -2,6 +2,198 @@
2
2
 
3
3
  Shared TypeScript contracts for Multiplayer AI agent clients, transports, and services.
4
4
 
5
+ ## Context attachments (`AgentAttachmentType.Context`)
6
+
7
+ This package supports attaching **structured context** to a user message as attachments. These attachments are:
8
+
9
+ - **Small**: meant to be _snippets_, not full-page dumps.
10
+ - **Typed + versioned**: `metadata.schemaVersion` is required (currently `1`).
11
+ - **Safe by default**: web snippets are treated as _untrusted_ content by the server prompt renderer.
12
+ - **Extensible**: library consumers can introduce **custom `kind`s** without forking.
13
+
14
+ ### Where it lives
15
+
16
+ A context attachment is a normal `AgentAttachment` with:
17
+
18
+ - `type: AgentAttachmentType.Context`
19
+ - `metadata: ContextAttachmentMetadataV1`
20
+
21
+ ### `security.containsPII` and `security.redactionsApplied`
22
+
23
+ Context attachments may include sensitive information (emails, names, phone numbers, addresses, account IDs, access tokens, etc.). The optional `metadata.security` block is **declarative metadata** to help the host app/service apply correct privacy and retention policies:
24
+
25
+ - **`containsPII: true`**: “This attachment may contain PII / sensitive data.” This does **not** automatically protect anything; it is a signal for logging/storage/prompt policy decisions.
26
+ - **`redactionsApplied: string[]`**: An audit trail of what sanitization you already applied before attaching it. Example values: `['email', 'phone', 'credit_card', 'access_token']`.
27
+
28
+ If you set `containsPII: true` with `redactionsApplied: []`, you are explicitly saying: **“this may contain sensitive data and we did not redact it.”**
29
+
30
+ ### Built-in kinds (v1)
31
+
32
+ Built-ins have strict validation and well-known shapes:
33
+
34
+ - `webSnippet`: selected text from a webpage (plus optional title/source)
35
+ - `formSnapshot`: a set of form fields at a point in time
36
+ - `formField`: a single field value
37
+
38
+ ### Custom kinds (v1)
39
+
40
+ If `metadata.kind` is **not** one of the built-ins, it is treated as a **custom kind** with a bounded generic shape:
41
+
42
+ - `title?: string`
43
+ - `summary?: string`
44
+ - `data?: Record<string, unknown>` (budgeted; rejected if too large)
45
+
46
+ Custom kinds must **not** collide with built-in kind names.
47
+
48
+ ### Validating attachments (Zod)
49
+
50
+ This package exports shared schemas you can use in services/clients:
51
+
52
+ - `ContextAttachmentMetadataSchemaV1`
53
+ - `AgentAttachmentSchema`
54
+ - `SendMessagePayloadSchema`
55
+
56
+ Example:
57
+
58
+ ```ts
59
+ import { AgentAttachmentSchema, SendMessagePayloadSchema, AgentAttachmentType } from '@multiplayer-app/ai-agent-types'
60
+
61
+ const payload = SendMessagePayloadSchema.parse({
62
+ content: 'Can you summarize this?',
63
+ contextKey: 'support',
64
+ attachments: [
65
+ {
66
+ id: 'att-1',
67
+ type: AgentAttachmentType.Context,
68
+ name: 'Selection: Billing policy',
69
+ url: 'https://example.com/policy',
70
+ metadata: {
71
+ schemaVersion: 1,
72
+ kind: 'webSnippet',
73
+ capturedAt: new Date().toISOString(),
74
+ title: 'Billing policy',
75
+ selectedText: 'Customers may request a refund within 30 days...',
76
+ source: { app: 'browser', url: 'https://example.com/policy' },
77
+ security: { containsPII: true, redactionsApplied: [] }
78
+ }
79
+ }
80
+ ]
81
+ })
82
+
83
+ // You can also validate just one attachment:
84
+ AgentAttachmentSchema.parse(payload.attachments?.[0])
85
+ ```
86
+
87
+ ### Built-in examples
88
+
89
+ #### `webSnippet`
90
+
91
+ ```ts
92
+ {
93
+ id: 'att-1',
94
+ type: AgentAttachmentType.Context,
95
+ name: 'Selection: Checkout page',
96
+ url: 'https://app.example.com/checkout',
97
+ metadata: {
98
+ schemaVersion: 1,
99
+ kind: 'webSnippet',
100
+ capturedAt: '2026-01-09T08:00:00.000Z',
101
+ title: 'Checkout',
102
+ selectedText: 'Error: card declined (code 54)',
103
+ source: { app: 'browser', url: 'https://app.example.com/checkout' },
104
+ security: { containsPII: true, redactionsApplied: [] }
105
+ }
106
+ }
107
+ ```
108
+
109
+ #### `formSnapshot`
110
+
111
+ ```ts
112
+ {
113
+ id: 'att-2',
114
+ type: AgentAttachmentType.Context,
115
+ name: 'Form snapshot: Lead',
116
+ metadata: {
117
+ schemaVersion: 1,
118
+ kind: 'formSnapshot',
119
+ capturedAt: '2026-01-09T08:00:00.000Z',
120
+ formId: 'leadForm',
121
+ formName: 'Lead',
122
+ fields: [
123
+ { name: 'company', label: 'Company', value: 'Acme Inc.' },
124
+ { name: 'plan', label: 'Plan', value: 'Enterprise' }
125
+ ],
126
+ security: { containsPII: true, redactionsApplied: [] }
127
+ }
128
+ }
129
+ ```
130
+
131
+ #### `formField`
132
+
133
+ ```ts
134
+ {
135
+ id: 'att-3',
136
+ type: AgentAttachmentType.Context,
137
+ name: 'Field: Budget',
138
+ metadata: {
139
+ schemaVersion: 1,
140
+ kind: 'formField',
141
+ capturedAt: '2026-01-09T08:00:00.000Z',
142
+ formId: 'leadForm',
143
+ fieldName: 'budget',
144
+ fieldLabel: 'Budget',
145
+ value: '$25k',
146
+ security: { containsPII: true, redactionsApplied: [] }
147
+ }
148
+ }
149
+ ```
150
+
151
+ ### Custom kind example
152
+
153
+ ```ts
154
+ {
155
+ id: 'att-5',
156
+ type: AgentAttachmentType.Context,
157
+ name: 'CRM context',
158
+ metadata: {
159
+ schemaVersion: 1,
160
+ kind: 'crmRecord', // custom kind
161
+ capturedAt: '2026-01-09T08:00:00.000Z',
162
+ title: 'Account: Acme Inc.',
163
+ summary: 'Renewal in 14 days. Open escalation on billing.',
164
+ data: {
165
+ accountId: 'acc_123',
166
+ renewalDate: '2026-01-23',
167
+ health: 'yellow'
168
+ },
169
+ security: { containsPII: true, redactionsApplied: ['email'] }
170
+ }
171
+ }
172
+ ```
173
+
174
+ ### Custom objection example (recommended)
175
+
176
+ `objection` is intentionally **not** a built-in kind. Represent objections as a **custom kind** using `summary`/`data`:
177
+
178
+ ```ts
179
+ {
180
+ id: 'att-4',
181
+ type: AgentAttachmentType.Context,
182
+ name: 'Objection: Pricing',
183
+ metadata: {
184
+ schemaVersion: 1,
185
+ kind: 'objection', // custom kind
186
+ capturedAt: '2026-01-09T08:00:00.000Z',
187
+ summary: 'It’s too expensive compared to Vendor X.',
188
+ data: {
189
+ label: 'Price',
190
+ evidence: 'Vendor X quoted $18k/year for similar seats.'
191
+ },
192
+ security: { containsPII: false, redactionsApplied: [] }
193
+ }
194
+ }
195
+ ```
196
+
5
197
  ## Scripts
6
198
 
7
199
  ```bash
@@ -0,0 +1,112 @@
1
+ import type { AgentAttachment } from '../models.js';
2
+ import { AgentAttachmentType } from '../enums.js';
3
+ export declare const BuiltinContextAttachmentKinds: readonly ["webSnippet", "formSnapshot", "formField"];
4
+ export type BuiltinContextAttachmentKind = (typeof BuiltinContextAttachmentKinds)[number];
5
+ /**
6
+ * Allow library consumers to introduce custom kinds without forking.
7
+ *
8
+ * Built-in kinds get strict typing + validation; unknown kinds fall back to a bounded generic schema.
9
+ */
10
+ export type ContextAttachmentKind = BuiltinContextAttachmentKind | (string & {});
11
+ export type FormInputType = 'text' | 'textarea' | 'number' | 'select' | 'radio' | 'checkbox' | 'date' | 'email' | 'tel';
12
+ export interface FormSelectOption {
13
+ value: string;
14
+ label: string;
15
+ }
16
+ export interface ContextAttachmentSourceV1 {
17
+ app?: string;
18
+ url?: string;
19
+ route?: string;
20
+ domPath?: string;
21
+ }
22
+ export interface ContextAttachmentSecurityV1 {
23
+ /**
24
+ * Treat as PII-bearing unless explicitly false.
25
+ */
26
+ containsPII?: boolean;
27
+ redactionsApplied?: string[];
28
+ }
29
+ export interface ContextTextSelectionTargetV1 {
30
+ /**
31
+ * Text quote selector (robust across minor DOM changes).
32
+ */
33
+ type: 'text';
34
+ exact: string;
35
+ prefix?: string;
36
+ suffix?: string;
37
+ /**
38
+ * Optional container selector where selection was taken.
39
+ */
40
+ domPath?: string;
41
+ /**
42
+ * Optional offsets relative to container text. Helpful but not reliable across rerenders.
43
+ */
44
+ startOffset?: number;
45
+ endOffset?: number;
46
+ }
47
+ export interface ContextDomTargetV1 {
48
+ type: 'dom';
49
+ domPath: string;
50
+ }
51
+ export interface ContextFormTargetV1 {
52
+ type: 'form';
53
+ formId?: string;
54
+ fieldName?: string;
55
+ domPath?: string;
56
+ }
57
+ export type ContextAttachmentTargetV1 = ContextTextSelectionTargetV1 | ContextDomTargetV1 | ContextFormTargetV1;
58
+ export interface ContextAttachmentMetadataBaseV1 {
59
+ schemaVersion: 1;
60
+ kind: ContextAttachmentKind;
61
+ capturedAt: string;
62
+ source?: ContextAttachmentSourceV1;
63
+ security?: ContextAttachmentSecurityV1;
64
+ /**
65
+ * Optional locator/selector to re-find or highlight the originating UI element later.
66
+ */
67
+ target?: ContextAttachmentTargetV1;
68
+ }
69
+ export interface WebSnippetContextV1 extends ContextAttachmentMetadataBaseV1 {
70
+ kind: 'webSnippet';
71
+ title?: string;
72
+ selectedText: string;
73
+ }
74
+ export interface FormSnapshotContextV1 extends ContextAttachmentMetadataBaseV1 {
75
+ kind: 'formSnapshot';
76
+ formId?: string;
77
+ formName?: string;
78
+ fields: Array<{
79
+ name: string;
80
+ label?: string;
81
+ value: string;
82
+ inputType?: FormInputType;
83
+ options?: FormSelectOption[];
84
+ domPath?: string;
85
+ }>;
86
+ }
87
+ export interface FormFieldContextV1 extends ContextAttachmentMetadataBaseV1 {
88
+ kind: 'formField';
89
+ formId?: string;
90
+ fieldName: string;
91
+ fieldLabel?: string;
92
+ value: string;
93
+ inputType?: FormInputType;
94
+ options?: FormSelectOption[];
95
+ domPath?: string;
96
+ }
97
+ /**
98
+ * Generic, bounded context metadata for custom kinds. Consumers should define their
99
+ * own schemas on top of `data` if they need stronger validation.
100
+ */
101
+ export interface CustomContextMetadataV1 extends ContextAttachmentMetadataBaseV1 {
102
+ kind: Exclude<string, BuiltinContextAttachmentKind>;
103
+ title?: string;
104
+ summary?: string;
105
+ data?: Record<string, unknown>;
106
+ }
107
+ export type ContextAttachmentMetadataV1 = WebSnippetContextV1 | FormSnapshotContextV1 | FormFieldContextV1 | CustomContextMetadataV1;
108
+ export type ContextAgentAttachment = Omit<AgentAttachment, 'type' | 'metadata'> & {
109
+ type: AgentAttachmentType.Context;
110
+ metadata: ContextAttachmentMetadataV1;
111
+ };
112
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/attachments/context.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export const BuiltinContextAttachmentKinds = [
2
+ 'webSnippet',
3
+ 'formSnapshot',
4
+ 'formField',
5
+ ];
6
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/attachments/context.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,MAAM,6BAA6B,GAAG;IAC3C,YAAY;IACZ,cAAc;IACd,WAAW;CACH,CAAC"}