@sourcegraph/the-orb-is-awake
Version:
TypeScript SDK for Amp CLI - Build custom AI agents with Amp's capabilities
423 lines (319 loc) • 10.3 kB
Markdown
# Amp TypeScript SDK
A TypeScript SDK for running Amp CLI programmatically in Node.js applications. This SDK wraps the Amp CLI with structured JSON output to provide a clean, type-safe interface.
## Installation
```bash
npm install @sourcegraph/amp-sdk
```
The SDK automatically manages the Amp CLI dependency and will use a pinned, compatible version. No additional dependencies or separate CLI installation is required.
## Quick Start
```typescript
import { execute } from '@sourcegraph/amp-sdk'
// Simple execution - get the final result
for await (const message of execute({ prompt: 'What is the current directory?' })) {
if (message.type === 'result' && !message.is_error) {
console.log('Result:', message.result)
break
}
}
// Stream all messages for full control
for await (const message of execute({
prompt: 'Analyze this codebase',
})) {
if (message.type === 'result') {
console.log('Final result:', message.result)
} else if (message.type === 'assistant') {
console.log('Assistant response:', message.message.content)
}
}
```
## API Reference
### Core Functions
#### `execute(options: ExecuteOptions): AsyncIterable<StreamMessage>`
The main function for executing Amp CLI commands. Returns an async iterator of streaming messages.
```typescript
import { execute } from '@sourcegraph/amp-sdk'
// Returns AsyncIterable<StreamMessage>
```
#### `createUserMessage(text: string): UserInputMessage`
Helper function to create properly formatted user input messages for streaming conversations.
```typescript
import { createUserMessage } from '@sourcegraph/amp-sdk'
// Returns UserInputMessage
```
### TypeScript Types
The SDK exports comprehensive TypeScript types for full type safety:
```typescript
import type {
// Main types
ExecuteOptions,
AmpOptions,
StreamMessage,
UserInputMessage,
// Message types
SystemMessage,
AssistantMessage,
UserMessage,
ResultMessage,
ErrorResultMessage,
// Content types
TextContent,
ToolUseContent,
ToolResultContent,
Usage,
} from '@sourcegraph/amp-sdk'
```
```typescript
import { execute } from '@sourcegraph/amp-sdk'
for await (const message of execute({
prompt: 'Run the tests',
options: {
dangerouslyAllowAll: true,
cwd: './my-project',
},
})) {
if (message.type === 'result' && !message.is_error) {
console.log('Tests completed:', message.result)
}
}
```
### Simple Result Pattern
For cases where you just want the final result without handling all messages:
```typescript
import { execute } from '@sourcegraph/amp-sdk'
async function getResult(prompt: string, options?: AmpOptions): Promise<string> {
for await (const message of execute({ prompt, options })) {
if (message.type === 'result') {
if (message.is_error) {
throw new Error(message.error)
}
return message.result
}
}
throw new Error('No result received')
}
// Usage
const result = await getResult('List all TypeScript files', {
dangerouslyAllowAll: true,
})
console.log(result)
```
### Helper Functions
#### `createUserMessage(text: string): UserInputMessage`
Creates a properly formatted user input message for streaming conversations:
```typescript
import { createUserMessage } from '@sourcegraph/amp-sdk'
const message = createUserMessage('Analyze this code')
console.log(message)
// Output: { type: 'user', message: { role: 'user', content: [{ type: 'text', text: 'Analyze this code' }] } }
```
This helper is useful when building streaming conversations or when you need to construct messages programmatically.
### Configuration Options
The `AmpOptions` type supports the following configuration:
```typescript
import type { AmpOptions } from '@sourcegraph/amp-sdk'
// AmpOptions includes:
/** Current working directory */
cwd?: string
/** Allow all tool usage without asking for permission */
dangerouslyAllowAll?: boolean
/** Visibility level for new threads */
visibility?: 'public' | 'private' | 'team'
/** Settings file path */
settingsFile?: string
/** Log level */
logLevel?: 'debug' | 'info' | 'warn' | 'error' | 'audit'
/** Log file path */
logFile?: string
/** MCP server configuration as JSON string or path to JSON file */
mcpConfig?: string
/** Additional environment variables */
env?: Record<string, string>
/** Continue the most recent thread (true) or a specific thread by ID (string) */
continue?: boolean | string
```
### Continuing Existing Threads
You can continue previous conversations using the `continue` option:
```typescript
import { execute } from '@sourcegraph/amp-sdk'
// Continue the most recent thread
for await (const message of execute({
prompt: 'What was my previous question about?',
options: {
continue: true,
},
})) {
if (message.type === 'result') {
console.log(message.result)
}
}
// Continue a specific thread by ID
for await (const message of execute({
prompt: 'Can you update that code we discussed?',
options: {
continue: 'T-abc123-def456', // or full URL: 'https://ampcode.com/threads/T-abc123-def456'
},
})) {
if (message.type === 'result') {
console.log(message.result)
}
}
```
### Multi-turn Conversations
For multi-turn conversations, you can use streaming input mode with the `createUserMessage` helper:
```typescript
import { execute, createUserMessage } from '@sourcegraph/amp-sdk'
async function* generateMessages() {
yield createUserMessage('Start analyzing the codebase')
// Wait for some condition or user input
await new Promise((resolve) => setTimeout(resolve, 1000))
yield createUserMessage('Now focus on the authentication module')
}
for await (const message of execute({
prompt: generateMessages(),
})) {
if (message.type === 'result') {
console.log(message.result)
}
}
```
### Message Types
All messages follow the Amp CLI's stream JSON format:
- `SystemMessage` - Emitted first with session info and available tools
- `AssistantMessage` - AI agent responses with text and tool usage
- `UserMessage` - User input and tool results
- `ResultMessage` - Final result on success
- `ErrorResultMessage` - Final result on error
### Message Type Checking
Check message types directly using the `type` and `subtype` properties:
```typescript
import { execute } from '@sourcegraph/amp-sdk'
for await (const message of execute({ prompt: 'Hello' })) {
if (message.type === 'system' && message.subtype === 'init') {
console.log('Available tools:', message.tools)
} else if (message.type === 'assistant') {
console.log('Assistant:', message.message.content)
} else if (message.type === 'result') {
if (message.is_error) {
console.error('Error:', message.error)
} else {
console.log('Success:', message.result)
}
}
}
```
### Error Handling
The SDK handles errors at multiple levels:
#### Result-level Errors
Check for errors in result messages:
```typescript
import { execute } from '@sourcegraph/amp-sdk'
for await (const message of execute({ prompt: 'Run command' })) {
if (message.type === 'result') {
if (message.is_error) {
console.error('Command failed:', message.error)
// Handle specific error
} else {
console.log('Success:', message.result)
}
}
}
```
#### Process-level Errors
Handle SDK execution failures:
```typescript
try {
for await (const message of execute({ prompt: 'Run dangerous command' })) {
// Process messages
}
} catch (error) {
console.error('SDK execution failed:', error.message)
// This could be CLI not found, network issues, etc.
}
```
### Abort Support
Use `AbortController` to cancel long-running executions:
```typescript
import { execute } from '@sourcegraph/amp-sdk'
const abortController = new AbortController()
// Cancel after 30 seconds
setTimeout(() => abortController.abort(), 30000)
try {
for await (const message of execute({
prompt: 'Long running analysis',
signal: abortController.signal,
})) {
console.log(message)
}
} catch (error) {
if (error.message.includes('aborted')) {
console.log('Execute was cancelled')
}
}
```
## Complete Example
Here's a comprehensive example showing multiple SDK features:
```typescript
import { execute, createUserMessage, type AmpOptions } from '@sourcegraph/amp-sdk'
async function comprehensiveExample() {
const options: AmpOptions = {
cwd: process.cwd(),
dangerouslyAllowAll: true,
visibility: 'private',
logLevel: 'info',
env: { NODE_ENV: 'development' },
}
try {
for await (const message of execute({
prompt: 'Analyze this project structure',
options,
})) {
if (message.type === 'system') {
console.log(`Session: ${message.session_id}`)
console.log(`Tools: ${message.tools.join(', ')}`)
} else if (message.type === 'result') {
if (message.is_error) {
console.error('Error:', message.error)
} else {
console.log('Success:', message.result)
}
break
}
}
} catch (error) {
console.error('Execution failed:', error.message)
}
}
```
## Examples and Development
Comprehensive examples are available in the source repository:
```bash
# Install the SDK
npm install @sourcegraph/amp-sdk
# Clone the repository to access examples
git clone https://github.com/sourcegraph/amp.git
cd amp/sdk
# Run the comprehensive example (requires TypeScript)
npm run examples:basic
```
The [`examples/basic-usage.ts`](https://github.com/sourcegraph/amp/blob/main/sdk/examples/basic-usage.ts) file demonstrates:
- Simple execution patterns
- Streaming message handling
- Multi-turn conversations
- Thread continuation
- Abort controller usage
- All configuration options
- Working directory settings
- Environment variables
- Custom visibility levels
- Log file configuration
## Requirements
- Node.js 18+
## Dependencies
The SDK has minimal dependencies for a lightweight installation:
- **`@sourcegraph/amp`** - The Amp CLI (automatically managed)
All other dependencies (including validation libraries) are bundled within the package, so you don't need to install additional packages. The complete SDK package is only **14.4 kB compressed** with full TypeScript definitions and examples included.
## CLI Resolution
The SDK will automatically locate and use the Amp CLI locally installed CLI in your project's `node_modules`
## Compatibility
This SDK provides access to Amp CLI's capabilities through a streaming JSON output format for easy integration.
## License