Skip to content

Session & User Types

Complete TypeScript type reference for sessions, users, messages, and chat interactions.

import type {
ChatSession,
ChatUser,
ChatMessage,
SessionData,
ConverseRequest,
ConverseResponse,
SessionSearchRequest,
ChatMessageFile
} from 'pika-shared/types/chatbot/chatbot-types';

User profile with custom data support.

interface ChatUser<T extends RecordOrUndef = undefined> {
userId: string;
firstName?: string;
lastName?: string;
customData?: T;
viewingContentFor?: Record<string, ChatUserLite>;
overrideData?: Record<string, T>;
createDate?: string;
lastUpdate?: string;
userType?: UserType;
roles?: string[];
}

Fields:

  • userId - Unique user identifier
  • firstName / lastName - User's name
  • customData - Custom application data (e.g., accountId, accountType)
  • viewingContentFor - For content admins viewing other users' sessions
  • overrideData - Per-chat-app data overrides (stored in secure cookie)
  • userType - 'internal-user' or 'external-user'
  • roles - Array of role strings (e.g., ['pika:content-admin'])

Define your own user data structure:

interface MyCustomUserData {
accountId: string;
accountType: 'free' | 'premium' | 'enterprise';
region: string;
preferences: {
language: string;
theme: string;
};
}
const user: ChatUser<MyCustomUserData> = {
userId: 'user-123',
firstName: 'John',
lastName: 'Doe',
userType: 'external-user',
customData: {
accountId: 'acct-456',
accountType: 'premium',
region: 'us-east',
preferences: {
language: 'en',
theme: 'dark'
}
}
};
type UserType = 'internal-user' | 'external-user';

Minimal user information.

interface ChatUserLite {
userId: string;
firstName?: string;
lastName?: string;
userType?: UserType;
}

Complete chat session data.

interface ChatSession<T extends RecordOrUndef = undefined> {
userId: string;
sessionId: string;
chatAppId: string;
agentId: string;
title?: string;
customData?: T;
createDate: string;
lastUpdate: string;
inputTokens?: number;
outputTokens?: number;
totalCost?: number;
flaggedForHumanReview?: boolean;
insights?: SessionInsights;
}

Fields:

  • userId - User who owns this session
  • sessionId - Unique session identifier
  • chatAppId - Chat app this session belongs to
  • agentId - Agent used in this session
  • title - Session title (auto-generated or user-provided)
  • customData - Custom session data (inherits from user)
  • inputTokens / outputTokens - Token usage
  • totalCost - Estimated cost in USD
  • flaggedForHumanReview - Marked for manual review
  • insights - AI-generated session insights

Runtime session state (not persisted to database).

interface SessionData {
userId: string;
sessionId: string;
chatAppId: string;
agentId: string;
customData?: Record<string, any>;
}

Session data with user's custom data merged in.

type SessionDataWithChatUserCustomDataSpreadIn = SessionData & {
[key: string]: any; // Custom data fields spread in
};

Example:

// If user has customData: { accountId: 'acct-123', tier: 'premium' }
const sessionData: SessionDataWithChatUserCustomDataSpreadIn = {
userId: 'user-123',
sessionId: 'session-456',
chatAppId: 'support',
agentId: 'support-agent',
accountId: 'acct-123', // From customData
tier: 'premium' // From customData
};

Individual message in a session.

interface ChatMessage {
userId: string;
sessionId: string;
messageId: string;
role: 'user' | 'assistant' | 'system';
content: string;
createDate: string;
usage?: ChatMessageUsage;
files?: ChatMessageFile[];
metadata?: Record<string, any>;
}

Token usage and cost for a message.

interface ChatMessageUsage {
inputCost: number; // Cost in USD
inputTokens: number;
outputCost: number; // Cost in USD
outputTokens: number;
totalCost: number; // Cost in USD
}

File attachment metadata.

interface ChatMessageFile {
fileId: string;
fileName: string;
mimeType: string;
size: number;
s3Key: string;
uploadDate: string;
}

Request to send a message to an agent.

interface ConverseRequest extends BaseRequestData {
message: string;
features: ChatAppOverridableFeaturesForConverseFn;
files?: ChatMessageFile[];
agentId: string;
entityAttributeNameInUserCustomData?: string;
invocationMode?: ConverseInvocationMode;
chatAppComponentConfig?: ChatAppComponentConfig;
source: ConverseSource;
}

Fields:

  • message - User's message text
  • features - Enabled features for this chat app
  • files - Attached files
  • agentId - Which agent to invoke
  • invocationMode - 'chat-app', 'direct-agent-invoke', or 'chat-app-component'
  • source - 'user', 'component-as-user', or 'component'
type ConverseInvocationMode =
| 'chat-app' // Normal chat app usage
| 'direct-agent-invoke' // Direct API call to agent
| 'chat-app-component'; // Widget invoking agent
type ConverseSource =
| 'user' // Human user message
| 'component-as-user' // Component on behalf of user (shows in history)
| 'component'; // Component message (hidden from user history)

Common request fields.

interface BaseRequestData {
userId: string;
sessionId?: string;
chatAppId?: string;
agentId?: string;
timezone?: string;
}

Search for sessions with filters.

interface SessionSearchRequest<T extends RecordOrUndef = undefined> {
userId?: string;
chatAppId?: string;
sessionId?: string;
customUserData?: T;
titlePartial?: string;
dateFilter?: SessionSearchDateFilter;
flagged?: boolean;
insights?: InsightsSearchParams;
scrollId?: string;
feedbackInStatus?: SessionFeedbackStatus[];
feedbackReportedByHuman?: boolean;
feedbackCreatedByCustomer?: boolean;
feedbackSeverity?: SessionFeedbackSeverity[];
feedbackType?: SessionFeedbackType[];
feedbackUserId?: string;
includeInsights?: boolean;
includeFeedback?: boolean;
sortBy?: Array<{
field: SessionSearchSortField;
order: 'asc' | 'desc';
}>;
size?: number;
}
type SessionSearchSortField =
| 'createDate'
| 'lastUpdate'
| 'sessionId'
| 'inputTokens'
| 'outputTokens'
| 'totalCost'
| 'insightGoalAchievementScore';
interface SessionSearchDateFilter {
dateType: 'created' | 'updated' | 'feedback';
startDate: string; // ISO 8601
endDate?: string; // ISO 8601
}
interface SessionSearchResponse<T extends RecordOrUndef = undefined> {
success: boolean;
sessions: ChatSession<T>[];
error?: string;
scrollId?: string;
total: number;
pageSize: number;
}

AI-generated insights about a session.

interface SessionInsights {
summary: string;
goalAchievement: {
score: number; // 0-100
status: SessionInsightGoalCompletionStatus;
explanation: string;
};
userSatisfaction: {
score: number; // 0-100
level: SessionInsightSatisfactionLevel;
sentiment: SessionInsightUserSentiment;
explanation: string;
};
aiPerformance: {
overallScore: number; // 0-100
accuracy: number; // 0-100
efficiency: number; // 0-100
explanation: string;
};
interactionQuality: {
score: number; // 0-100
explanation: string;
};
metrics: {
sessionDuration: SessionInsightMetricsSessionDurationEstimate;
complexity: SessionInsightMetricsComplexityLevel;
userEffort: SessionInsightMetricsUserEffortRequired;
aiConfidence: SessionInsightMetricsAiConfidenceLevel;
};
generateDate: string;
}
type SessionInsightGoalCompletionStatus =
| 'fully_achieved'
| 'partially_achieved'
| 'not_achieved'
| 'unclear';
type SessionInsightSatisfactionLevel =
| 'very_satisfied'
| 'satisfied'
| 'neutral'
| 'dissatisfied'
| 'very_dissatisfied';
type SessionInsightUserSentiment =
| 'positive'
| 'neutral'
| 'negative'
| 'mixed';
type SessionInsightMetricsSessionDurationEstimate =
| 'very_short'
| 'short'
| 'medium'
| 'long'
| 'very_long';
type SessionInsightMetricsComplexityLevel =
| 'simple'
| 'moderate'
| 'complex'
| 'very_complex';
type SessionInsightMetricsUserEffortRequired =
| 'minimal'
| 'low'
| 'moderate'
| 'high'
| 'very_high';
type SessionInsightMetricsAiConfidenceLevel =
| 'very_high'
| 'high'
| 'moderate'
| 'low'
| 'very_low';

User or system feedback on a session.

interface ChatSessionFeedback {
feedbackId: string;
sessionId: string;
userId: string;
type: SessionFeedbackType;
severity: SessionFeedbackSeverity;
status: SessionFeedbackStatus;
title: string;
description: string;
reportedByHuman: boolean;
createdByCustomer: boolean;
createDate: string;
lastUpdate: string;
internalComments?: FeedbackInternalComment[];
}
type SessionFeedbackType =
| 'incorrect_response'
| 'incomplete_response'
| 'inappropriate_content'
| 'technical_error'
| 'other';
type SessionFeedbackSeverity =
| 'critical'
| 'high'
| 'medium'
| 'low';
type SessionFeedbackStatus =
| 'new'
| 'in_progress'
| 'resolved'
| 'dismissed';
interface MySessionData {
accountId: string;
transactionId?: string;
context: string;
}
const session: ChatSession<MySessionData> = {
userId: 'user-123',
sessionId: 'session-456',
chatAppId: 'support',
agentId: 'support-agent',
title: 'Order Status Inquiry',
customData: {
accountId: 'acct-789',
transactionId: 'txn-abc',
context: 'order-inquiry'
},
createDate: '2024-01-15T10:00:00Z',
lastUpdate: '2024-01-15T10:15:00Z',
inputTokens: 150,
outputTokens: 300,
totalCost: 0.0045
};
const searchRequest: SessionSearchRequest<MySessionData> = {
chatAppId: 'support',
customUserData: {
accountId: 'acct-789',
context: 'order-inquiry'
},
dateFilter: {
dateType: 'created',
startDate: '2024-01-01T00:00:00Z',
endDate: '2024-01-31T23:59:59Z'
},
includeInsights: true,
sortBy: [
{ field: 'createDate', order: 'desc' }
],
size: 20
};
const request: ConverseRequest = {
userId: 'user-123',
sessionId: 'session-456',
chatAppId: 'support',
agentId: 'support-agent',
message: 'What is the status of my order?',
features: {
userMemory: {
featureId: 'userMemory',
enabled: true,
strategies: ['short-term', 'long-term']
},
verifyResponse: {
featureId: 'verifyResponse',
enabled: true
}
// ... other features
},
invocationMode: 'chat-app',
source: 'user',
timezone: 'America/New_York'
};
import type { BedrockActionGroupLambdaEvent } from 'pika-shared/types/chatbot/bedrock';
import { normalizeSessionAttributes } from 'pika-shared/util/bedrock';
export const handler = async (event: BedrockActionGroupLambdaEvent) => {
// Get session data with custom fields
const sessionData = normalizeSessionAttributes(event.sessionAttributes);
// Access custom data
const accountId = sessionData.accountId;
const accountType = sessionData.accountType;
// Use in your tool logic
if (accountType === 'premium') {
// Provide premium features
}
// Return result
return result;
};

Store arbitrary data scoped to user + widget.

type UserWidgetData = Record<string, unknown>;
interface GetUserWidgetDataRequest {
scope: string; // e.g., 'custom'
tag: string; // e.g., 'calculator'
}
interface SetUserWidgetDataRequest {
scope: string;
tag: string;
data: UserWidgetData;
partial?: boolean; // If true, merge with existing
}

Example:

// Store widget state
const saveRequest: SetUserWidgetDataRequest = {
scope: 'custom',
tag: 'order-form',
data: {
draftOrder: {
items: ['item1', 'item2'],
total: 99.99
},
lastSaved: '2024-01-15T10:00:00Z'
},
partial: false
};
// Load widget state
const loadRequest: GetUserWidgetDataRequest = {
scope: 'custom',
tag: 'order-form'
};