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.
| Parameter | Type | Required | Description |
|---|---|---|---|
prompt | string | Yes | The natural language prompt |
options | RunOptions | No | Run-specific configuration |
RunOptions Properties
| Property | Type | Description |
|---|---|---|
outputSchema | JsonSchema | JSON Schema for structured output |
promptFile | string | Path to a file containing the prompt |
attachments | FileAttachment[] | File attachments to include |
model | string | Override the model for this run |
autonomyLevel | AutonomyLevel | Override 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.
| Parameter | Type | Required | Description |
|---|---|---|---|
prompt | string | Yes | The natural language prompt |
options | RunOptions | No | Run-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
| Type | Description | Properties |
|---|---|---|
system | System init | cwd, session_id, tools, model |
message | Message | role, text, id, timestamp |
tool_call | Tool call | toolName, parameters, id |
tool_result | Tool result | toolName, value, isError |
completion | Complete | finalText, durationMs, numTurns |
turn.failed | Failed | error.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);