Skip to main content

Thread

The Thread class manages multi-turn conversations with the Droid AI. It maintains context across prompts and supports both synchronous and streaming execution.

Import

import { Droid } from '@activade/droid-sdk';

// Threads are created via Droid methods
const droid = new Droid();
const thread = droid.startThread();

Properties

id

get id(): string | undefined

The unique session identifier for this thread. Returns undefined until the first prompt is executed.

const thread = droid.startThread();
console.log(thread.id); // undefined

await thread.run('Hello');
console.log(thread.id); // 'session_abc123...'

cwd

get cwd(): string

The working directory for this thread's CLI operations.

const thread = droid.startThread({ cwd: '/projects/my-app' });
console.log(thread.cwd); // '/projects/my-app'

Methods

run()

run(prompt: string, options?: RunOptions): Promise<TurnResult>

Executes a prompt and waits for the complete response.

ParameterTypeRequiredDescription
promptstringYesThe natural language prompt
optionsRunOptionsNoRun-specific configuration

RunOptions Properties

PropertyTypeDescription
outputSchemaJsonSchemaJSON Schema for structured output
promptFilestringPath to a file containing the prompt
attachmentsFileAttachment[]File attachments to include
modelstringOverride the model for this run
autonomyLevelAutonomyLevelOverride autonomy level

Returns: A promise resolving to the execution result.

const result = await thread.run('Create a function to sort an array');
console.log(result.finalResponse);

// Access tool calls
for (const call of result.toolCalls) {
console.log(`Used tool: ${call.toolName}`);
}

runStreamed()

runStreamed(prompt: string, options?: RunOptions): Promise<StreamedTurn>

Executes a prompt with real-time streaming of events.

ParameterTypeRequiredDescription
promptstringYesThe natural language prompt
optionsRunOptionsNoRun-specific configuration

Returns: A StreamedTurn containing an async event iterator and result promise.

const { events, result } = await thread.runStreamed('Build a REST API');

for await (const event of events) {
switch (event.type) {
case 'message':
console.log(`[${event.role}] ${event.text}`);
break;
case 'tool_call':
console.log(`Calling: ${event.toolName}`);
break;
case 'tool_result':
console.log(`Result: ${event.isError ? 'ERROR' : 'OK'}`);
break;
case 'completion':
console.log(`Completed in ${event.durationMs}ms`);
break;
}
}

const finalResult = await result;

StreamedTurn

The return type of runStreamed():

interface StreamedTurn {
events: AsyncIterable<StreamEvent>;
result: Promise<TurnResult>;
}

Event Types

TypeDescriptionProperties
systemSystem initcwd, session_id, tools, model
messageMessagerole, text, id, timestamp
tool_callTool calltoolName, parameters, id
tool_resultTool resulttoolName, value, isError
completionCompletefinalText, durationMs, numTurns
turn.failedFailederror.message, error.code

Type Guards

Use type guards for type-safe event handling:

import {
isToolCallEvent,
isToolResultEvent,
isMessageEvent
} from '@activade/droid-sdk';

for await (const event of events) {
if (isToolCallEvent(event)) {
// TypeScript knows event is ToolCallEvent
console.log(event.toolName, event.parameters);
}
}

File Attachments

Attach files to provide context:

const result = await thread.run('Describe this image', {
attachments: [
{ path: './screenshot.png', type: 'image' }
]
});

const result = await thread.run('Review these files', {
attachments: [
{ path: './src/main.ts', type: 'text', description: 'Main entry' },
{ path: './data.json', type: 'data' }
]
});

Full Example

import { Droid, MODELS, isToolCallEvent } from '@activade/droid-sdk';

const droid = new Droid({ model: MODELS.CLAUDE_SONNET });
const thread = droid.startThread();

// First turn
await thread.run('Create a TypeScript function to validate emails');

// Follow-up with context
await thread.run('Add support for custom domain restrictions');

// Streaming execution
const { events, result } = await thread.runStreamed('Write tests');

for await (const event of events) {
if (isToolCallEvent(event)) {
console.log(`Tool: ${event.toolName}`);
}
}

const finalResult = await result;
console.log('Tests created:', finalResult.finalResponse);

// Save session for later
console.log('Session ID:', thread.id);