AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Threads

skill-andrmaz-spec-driven-architecture-threads · by andrmaz

Manages Tambo threads, messages, suggestions, voice input, and image attachments. Use when working with conversations, sending messages, implementing AI suggestions, adding voice input, managing multi-thread UIs, or handling image attachments with useTambo, useTamboThreadInput, useTamboSuggestions, or useTamboVoice.

No reviews yet
0 installs
10 views
0.0% view→install

Install

$ agentstack add skill-andrmaz-spec-driven-architecture-threads

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-andrmaz-spec-driven-architecture-threads)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
1mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Threads? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Threads and Input

Manages conversations, suggestions, voice input, and image attachments.

Quick Start

import { useTambo, useTamboThreadInput } from "@tambo-ai/react";

const { thread, messages, isIdle } = useTambo();
const { value, setValue, submit } = useTamboThreadInput();

await submit(); // sends current input value

Thread Management

Access and manage the current thread using useTambo() and useTamboThreadInput():

import {
  useTambo,
  useTamboThreadInput,
  ComponentRenderer,
} from "@tambo-ai/react";

function Chat() {
  const {
    thread, // Current thread state
    messages, // Messages with computed properties
    isIdle, // True when not generating
    isStreaming, // True when streaming response
    isWaiting, // True when waiting for server
    currentThreadId, // Active thread ID
    switchThread, // Switch to different thread
    startNewThread, // Create new thread, returns ID
    cancelRun, // Cancel active generation
  } = useTambo();

  const {
    value, // Current input value
    setValue, // Update input
    submit, // Send message
    isPending, // Submission in progress
    images, // Staged image files
    addImage, // Add single image
    removeImage, // Remove image by ID
  } = useTamboThreadInput();

  const handleSend = async () => {
    await submit();
  };

  return (
    
      {messages.map((msg) => (
        
          {msg.content.map((block) => {
            switch (block.type) {
              case "text":
                return {block.text};
              case "component":
                return (
                  
                );
              case "tool_use":
                return (
                  
                    {block.statusMessage ?? `Running ${block.name}...`}
                  
                );
              default:
                return null;
            }
          })}
        
      ))}
       setValue(e.target.value)} />
      
        Send
      
    
  );
}

Streaming State

| Property | Type | Description | | ------------- | --------- | --------------------------- | | isIdle | boolean | Not generating | | isWaiting | boolean | Waiting for server response | | isStreaming | boolean | Actively streaming response |

The streamingState object provides additional detail:

const { streamingState } = useTambo();
// streamingState.status: "idle" | "waiting" | "streaming"
// streamingState.runId: current run ID
// streamingState.error: { message, code } if error occurred

Content Block Types

Messages contain an array of content blocks. Handle each type:

| Type | Description | Key Fields | | ------------- | ---------------------- | ------------------------ | | text | Plain text | text | | component | AI-generated component | id, name, props | | tool_use | Tool invocation | id, name, input | | tool_result | Tool response | tool_use_id, content | | resource | MCP resource | uri, name, text |

Submit Options

const { submit } = useTamboThreadInput();

await submit({
  threadId: "specific-thread", // Override target thread
  toolChoice: "auto", // "auto" | "required" | "none" | { name: "toolName" }
  maxTokens: 4096, // Max response tokens
  systemPrompt: "Be helpful", // Override system prompt
});

Fetching a Thread by ID

To fetch a specific thread (e.g., for a detail view), use useTamboThread(threadId):

import { useTamboThread } from "@tambo-ai/react";

function ThreadView({ threadId }: { threadId: string }) {
  const { data: thread, isLoading, isError } = useTamboThread(threadId);

  if (isLoading) return ;
  if (isError) return Failed to load thread;

  return {thread.name};
}

This is a React Query hook - use it for read-only thread fetching, not for the active conversation.

Thread List

Manage multiple conversations:

import { useTambo, useTamboThreadList } from "@tambo-ai/react";

function ThreadSidebar() {
  const { data, isLoading } = useTamboThreadList();
  const { currentThreadId, switchThread, startNewThread } = useTambo();

  if (isLoading) return ;

  return (
    
       startNewThread()}>New Thread
      
        {data?.threads.map((t) => (
          
             switchThread(t.id)}
              className={currentThreadId === t.id ? "active" : ""}
            >
              {t.name || "Untitled"}
            
          
        ))}
      
    
  );
}

Thread List Options

const { data } = useTamboThreadList({
  userKey: "user_123", // Filter by user (defaults to provider's userKey)
  limit: 20, // Max results
  cursor: nextCursor, // Pagination cursor
});

// data.threads: TamboThread[]
// data.hasMore: boolean
// data.nextCursor: string

Suggestions

AI-generated follow-up suggestions after each assistant message:

import { useTamboSuggestions } from "@tambo-ai/react";

function Suggestions() {
  const { suggestions, isLoading, accept, isAccepting } = useTamboSuggestions({
    maxSuggestions: 3, // 1-10, default 3
    autoGenerate: true, // Auto-generate after assistant message
  });

  if (isLoading) return ;

  return (
    
      {suggestions.map((s) => (
         accept({ suggestion: s })}
          disabled={isAccepting}
        >
          {s.title}
        
      ))}
    
  );
}

Auto-Submit Suggestion

// Accept and immediately submit as a message
accept({ suggestion: s, shouldSubmit: true });

Manual Generation

const { generate, isGenerating } = useTamboSuggestions({
  autoGenerate: false, // Disable auto-generation
});

 generate()} disabled={isGenerating}>
  Get suggestions
;

Voice Input

Speech-to-text transcription:

import { useTamboVoice } from "@tambo-ai/react";

function VoiceButton() {
  const {
    startRecording,
    stopRecording,
    isRecording,
    isTranscribing,
    transcript,
    transcriptionError,
    mediaAccessError,
  } = useTamboVoice();

  return (
    
      
        {isRecording ? "Stop" : "Record"}
      
      {isTranscribing && Transcribing...}
      {transcript && {transcript}}
      {transcriptionError && {transcriptionError}}
    
  );
}

Voice Hook Returns

| Property | Type | Description | | -------------------- | ---------------- | --------------------------------- | | startRecording | () => void | Start recording, reset transcript | | stopRecording | () => void | Stop and start transcription | | isRecording | boolean | Currently recording | | isTranscribing | boolean | Processing audio | | transcript | string \| null | Transcribed text | | transcriptionError | string \| null | Transcription error | | mediaAccessError | string \| null | Mic access error |

Image Attachments

Images are managed via useTamboThreadInput():

import { useTamboThreadInput } from "@tambo-ai/react";

function ImageInput() {
  const { images, addImage, addImages, removeImage, clearImages } =
    useTamboThreadInput();

  const handleFiles = async (files: FileList) => {
    await addImages(Array.from(files));
  };

  return (
    
       handleFiles(e.target.files!)}
      />
      {images.map((img) => (
        
          
           removeImage(img.id)}>Remove
        
      ))}
    
  );
}

StagedImage Properties

| Property | Type | Description | | --------- | -------- | -------------------- | | id | string | Unique image ID | | name | string | File name | | dataUrl | string | Base64 data URL | | file | File | Original File object | | size | number | File size in bytes | | type | string | MIME type |

User Authentication

Enable per-user thread isolation:

import { TamboProvider } from "@tambo-ai/react";

function App() {
  return (
    
      
    
  );
}

For OAuth-based auth, use userToken instead:

function App() {
  const userToken = useUserToken(); // From your auth provider

  return (
    
      
    
  );
}

Use userKey for simple user identification or userToken for OAuth JWT tokens. Don't use both.

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.