@multiplayer-app/ai-agent-types
v0.1.0-beta.50
Published
Shared TypeScript types for Multiplayer AI agent clients and services
Keywords
Readme
@multiplayer-app/ai-agent-types
Shared TypeScript contracts for Multiplayer AI agent clients, transports, and services.
Context attachments (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.schemaVersionis required (currently1). - Safe by default: web snippets are treated as untrusted content by the server prompt renderer.
- Extensible: library consumers can introduce custom
kinds without forking.
Where it lives
A context attachment is a normal AgentAttachment with:
type: AgentAttachmentType.Contextmetadata: ContextAttachmentMetadataV1
security.containsPII and security.redactionsApplied
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-in kinds (v1)
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 timeformField: a single field value
Custom kinds (v1)
If metadata.kind is not one of the built-ins, it is treated as a custom kind with a bounded generic shape:
title?: stringsummary?: stringdata?: Record<string, unknown>(budgeted; rejected if too large)
Custom kinds must not collide with built-in kind names.
Validating attachments (Zod)
This package exports shared schemas you can use in services/clients:
ContextAttachmentMetadataSchemaV1AgentAttachmentSchemaSendMessagePayloadSchema
Example:
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])Built-in examples
webSnippet
{
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
{
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
{
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: [] }
}
}Custom kind example
{
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'] }
}
}Custom objection example (recommended)
objection is intentionally not a built-in kind. Represent objections as a custom kind using summary/data:
{
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: [] }
}
}Scripts
npm run buildGenerates dist/index.js and dist/index.d.ts for downstream packages.
