Shared TypeScript types for Multiplayer AI agent clients and services
npm install @multiplayer-app/ai-agent-typesShared TypeScript contracts for Multiplayer AI agent clients, transports, and services.
AgentAttachmentType.Context)This package supports attaching structured context to a user message as attachments. These attachments are:
- Small: meant to be _snippets_, not full-page dumps.
- Typed + versioned: metadata.schemaVersion is required (currently 1).
- Safe by default: web snippets are treated as _untrusted_ content by the server prompt renderer.
- Extensible: library consumers can introduce custom kinds without forking.
A context attachment is a normal AgentAttachment with:
- type: AgentAttachmentType.Context
- metadata: ContextAttachmentMetadataV1
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:
- 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.
- redactionsApplied: string[]: An audit trail of what sanitization you already applied before attaching it. Example values: ['email', 'phone', 'credit_card', 'access_token'].
If you set containsPII: true with redactionsApplied: [], you are explicitly saying: “this may contain sensitive data and we did not redact it.”
Built-ins have strict validation and well-known shapes:
- webSnippet: selected text from a webpage (plus optional title/source)
- formSnapshot: a set of form fields at a point in time
- formField: a single field value
If metadata.kind is not one of the built-ins, it is treated as a custom kind with a bounded generic shape:
- title?: string
- summary?: string
- data?: Record (budgeted; rejected if too large)
Custom kinds must not collide with built-in kind names.
This package exports shared schemas you can use in services/clients:
- ContextAttachmentMetadataSchemaV1
- AgentAttachmentSchema
- SendMessagePayloadSchema
Example:
``ts
import { AgentAttachmentSchema, SendMessagePayloadSchema, AgentAttachmentType } from '@multiplayer-app/ai-agent-types'
const payload = SendMessagePayloadSchema.parse({
content: 'Can you summarize this?',
contextKey: 'support',
attachments: [
{
id: 'att-1',
type: AgentAttachmentType.Context,
name: 'Selection: Billing policy',
url: 'https://example.com/policy',
metadata: {
schemaVersion: 1,
kind: 'webSnippet',
capturedAt: new Date().toISOString(),
title: 'Billing policy',
selectedText: 'Customers may request a refund within 30 days...',
source: { app: 'browser', url: 'https://example.com/policy' },
security: { containsPII: true, redactionsApplied: [] }
}
}
]
})
// You can also validate just one attachment:
AgentAttachmentSchema.parse(payload.attachments?.[0])
`
#### webSnippet
`ts`
{
id: 'att-1',
type: AgentAttachmentType.Context,
name: 'Selection: Checkout page',
url: 'https://app.example.com/checkout',
metadata: {
schemaVersion: 1,
kind: 'webSnippet',
capturedAt: '2026-01-09T08:00:00.000Z',
title: 'Checkout',
selectedText: 'Error: card declined (code 54)',
source: { app: 'browser', url: 'https://app.example.com/checkout' },
security: { containsPII: true, redactionsApplied: [] }
}
}
#### formSnapshot
`ts`
{
id: 'att-2',
type: AgentAttachmentType.Context,
name: 'Form snapshot: Lead',
metadata: {
schemaVersion: 1,
kind: 'formSnapshot',
capturedAt: '2026-01-09T08:00:00.000Z',
formId: 'leadForm',
formName: 'Lead',
fields: [
{ name: 'company', label: 'Company', value: 'Acme Inc.' },
{ name: 'plan', label: 'Plan', value: 'Enterprise' }
],
security: { containsPII: true, redactionsApplied: [] }
}
}
#### formField
`ts`
{
id: 'att-3',
type: AgentAttachmentType.Context,
name: 'Field: Budget',
metadata: {
schemaVersion: 1,
kind: 'formField',
capturedAt: '2026-01-09T08:00:00.000Z',
formId: 'leadForm',
fieldName: 'budget',
fieldLabel: 'Budget',
value: '$25k',
security: { containsPII: true, redactionsApplied: [] }
}
}
`ts`
{
id: 'att-5',
type: AgentAttachmentType.Context,
name: 'CRM context',
metadata: {
schemaVersion: 1,
kind: 'crmRecord', // custom kind
capturedAt: '2026-01-09T08:00:00.000Z',
title: 'Account: Acme Inc.',
summary: 'Renewal in 14 days. Open escalation on billing.',
data: {
accountId: 'acc_123',
renewalDate: '2026-01-23',
health: 'yellow'
},
security: { containsPII: true, redactionsApplied: ['email'] }
}
}
objection is intentionally not a built-in kind. Represent objections as a custom kind using summary/data:
`ts`
{
id: 'att-4',
type: AgentAttachmentType.Context,
name: 'Objection: Pricing',
metadata: {
schemaVersion: 1,
kind: 'objection', // custom kind
capturedAt: '2026-01-09T08:00:00.000Z',
summary: 'It’s too expensive compared to Vendor X.',
data: {
label: 'Price',
evidence: 'Vendor X quoted $18k/year for similar seats.'
},
security: { containsPII: false, redactionsApplied: [] }
}
}
`bash`
npm run build
Generates dist/index.js and dist/index.d.ts` for downstream packages.