ArctenArcten Docs

User & Conversations

Persist conversation history and enable personalized experiences

The user prop enables conversation persistence, personalization, and multi-device sync. Just pass in a user object with a unique id property.

User Object

Provide a user object to enable authenticated features.

<ArctenAgent
  user={{
    id: "user_123",           // Required
    email: "user@example.com",
    name: "John Doe",
    // Add any custom fields
  }}
/>

Required Fields

id (string, required): Unique identifier for the user. This is the only required field when providing a user object.

// Minimum required
<ArctenAgent
  user={{ id: "user_123" }}
/>

Optional Fields

You can include any additional fields that are relevant to your application:

<ArctenAgent
  user={{
    id: "user_123",
    email: "john@example.com",
    name: "John Doe",
    plan: "premium",
    role: "admin",
    company: "Acme Corp",
    metadata: {
      signupDate: "2024-01-15",
      lastLogin: "2024-03-20"
    }
  }}
/>

Benefits of User Authentication

1. Conversation Persistence

Conversations are automatically saved and associated with the user.

export default function App() {
  const user = {
    id: "user_123",
    email: "user@example.com"
  };

  return (
    <ArctenAgent
      user={user}
      systemPrompt="You are a helpful assistant."
    />
  );
}

Users can:

  • Resume conversations across sessions
  • View conversation history
  • Search through past conversations
  • Switch between different conversation threads

2. Personalized Responses

The agent can access user context for tailored responses.

const user = {
  id: "user_456",
  name: "Sarah",
  plan: "enterprise",
  industry: "healthcare"
};

<ArctenAgent
  user={user}
  systemPrompt={`You are assisting ${user.name}, an ${user.plan} customer in the ${user.industry} industry. Provide relevant examples and recommendations based on their context.`}
/>

3. Multi-Device Sync

Conversations sync automatically across all devices where the user is logged in.

4. User Context in Tools

Tools can access user information for personalized actions.

function getRecommendations(userId: string) {
  // Use userId to fetch personalized recommendations
  const userPrefs = database.getUserPreferences(userId);
  return recommendations.generate(userPrefs);
}

<ArctenAgent
  user={{ id: "user_789" }}
  safeTools={[getRecommendations]}
/>

Conversation Management

Recent Conversations

When a user object is provided, the agent automatically displays recent conversations in the sidebar.

<ArctenAgent
  user={{ id: "user_123" }}
  // Recent conversations appear automatically
/>

Users can:

  • View recent conversation titles
  • Click to load a previous conversation
  • Delete old conversations
  • Start new conversations

New Conversations

Users can start a new conversation at any time using the "+" button in the agent header.

Conversation Context

Each conversation maintains its own context and history, allowing users to:

  • Keep separate topics organized
  • Return to specific discussions
  • Maintain context within each conversation thread

Anonymous Users

If you don't provide a user object, the agent works in anonymous mode:

// Anonymous mode - no user object
<ArctenAgent
  systemPrompt="You are a helpful assistant."
/>

Anonymous mode behavior:

  • No persistent conversation history
  • No cross-device sync

Use anonymous mode when:

  • Users are not logged in
  • You don't need conversation persistence
  • Privacy is a primary concern
  • You're building a public-facing tool (unauthenticated page)

Integration Examples

With Next.js Auth

import { useSession } from "next-auth/react";
import { ArctenAgent } from "@arcteninc/core";
import "@arcteninc/core/styles";

export default function AuthenticatedApp() {
  const { data: session } = useSession();

  if (!session) {
    return <div>Please log in</div>;
  }

  const user = {
    id: session.user.id,
    email: session.user.email,
    name: session.user.name,
  };

  return (
    <div className="flex h-screen">
      <div className="flex-1 overflow-scroll">
        {/* Your app */}
      </div>
      <ArctenAgent
        user={user}
        systemPrompt="You are a helpful assistant."
      />
    </div>
  );
}

With Clerk

import { useUser } from "@clerk/nextjs";
import { ArctenAgent } from "@arcteninc/core";
import "@arcteninc/core/styles";

export default function App() {
  const { user: clerkUser } = useUser();

  if (!clerkUser) {
    return <div>Loading...</div>;
  }

  const user = {
    id: clerkUser.id,
    email: clerkUser.primaryEmailAddress?.emailAddress,
    name: clerkUser.fullName,
  };

  return (
    <ArctenAgent
      user={user}
      systemPrompt="You are a helpful assistant."
    />
  );
}

With Supabase Auth

import { useSupabaseClient, useUser } from "@supabase/auth-helpers-react";
import { ArctenAgent } from "@arcteninc/core";
import "@arcteninc/core/styles";

export default function App() {
  const supabaseUser = useUser();

  if (!supabaseUser) {
    return <div>Not authenticated</div>;
  }

  const user = {
    id: supabaseUser.id,
    email: supabaseUser.email,
  };

  return (
    <ArctenAgent
      user={user}
      systemPrompt="You are a helpful assistant."
    />
  );
}

With Firebase Auth

import { useAuth } from "@/hooks/useAuth";
import { ArctenAgent } from "@arcteninc/core";
import "@arcteninc/core/styles";

export default function App() {
  const { user: firebaseUser } = useAuth();

  if (!firebaseUser) {
    return <div>Please sign in</div>;
  }

  const user = {
    id: firebaseUser.uid,
    email: firebaseUser.email,
    name: firebaseUser.displayName,
  };

  return (
    <ArctenAgent
      user={user}
      systemPrompt="You are a helpful assistant."
    />
  );
}

Security Best Practices

Validate User Identity

In your token endpoint, verify that the requesting user matches the authenticated session:

import { verifyToken } from "@arcteninc/core/server";
import { getServerSession } from "next-auth";

export async function POST(req: NextRequest) {
  const body = await req.json();
  const { user } = body;

  // Get authenticated session
  const session = await getServerSession();

  // Verify the user matches the session
  if (!session || session.user.id !== user.id) {
    return NextResponse.json(
      { error: "Unauthorized" },
      { status: 401 }
    );
  }

  // Generate token
  const tokenResponse = await verifyToken({
    apiKey: process.env.ARCTEN_API_KEY!,
    user,
  });

  return NextResponse.json(tokenResponse);
}

Don't Trust Client Data

Never trust user data from the client without verification:

// ❌ Bad - trusting client data
const { user } = req.body;
const tokenResponse = await verifyToken({
  apiKey: process.env.ARCTEN_API_KEY!,
  user, // Unverified!
});

// ✅ Good - verify against session
const session = await getServerSession();
if (!session) {
  return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
}

const user = {
  id: session.user.id, // Verified from session
  email: session.user.email,
};

const tokenResponse = await verifyToken({
  apiKey: process.env.ARCTEN_API_KEY!,
  user,
});

Protect User Privacy

Only include necessary user information:

// ❌ Oversharing
const user = {
  id: "user_123",
  email: "user@example.com",
  password: "...",           // Never include sensitive data!
  creditCard: "...",         // Never include sensitive data!
  ssn: "...",                // Never include sensitive data!
};

// ✅ Appropriate
const user = {
  id: "user_123",
  email: "user@example.com",
  name: "John Doe",
  plan: "premium",
};

Conversation Data Access

Conversation data is:

  • Encrypted at rest
  • Accessible only by the authenticated user
  • Stored securely on Arcten servers
  • Subject to your data retention policies

GDPR & Data Deletion

To delete a user's conversation data, contact Arcten support or use the API (coming soon).

Tips

  1. Always provide user.id: This is the only required field for authenticated mode
  2. Include relevant context: Add custom fields that help personalize the experience
  3. Validate authentication: Always verify user identity in your token endpoint
  4. Don't overshare: Only include non-sensitive user information
  5. Consider privacy: Use anonymous mode for public-facing tools
  6. Test multi-device sync: Verify conversations sync correctly across devices