> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dartantic.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# OpenAI Code Interpreter

> Let OpenAI execute Python code for you.

The OpenAI Responses provider exposes a code interpreter tool that allows you to
execute Python code in a sandboxed container environment hosted by OpenAI. If
you'd like to keep state between requests, you can reuse an existing container
from a previous request. Any artifacts that are generated by the code
interpreter tool can be downloaded by your app.

## Enable Code Interpreter

You can enable the code interpreter tool via the `chatModelOptions` parameter of
the `Agent` constructor:

```dart theme={null}
final agent = Agent(
  'openai-responses',
  chatModelOptions: const OpenAIResponsesChatModelOptions(
    serverSideTools: {OpenAIServerSideTool.codeInterpreter},
  ),
);
```

## Streaming Execution

Code deltas and lifecycle events stream through `metadata['code_interpreter']`:

```dart theme={null}
await for (final chunk in agent.sendStream(prompt)) {
  final events = chunk.metadata['code_interpreter'] as List?;
  if (events == null) continue;

  for (final event in events) {
    switch (event['type']) {
      case 'response.code_interpreter_call_code.delta':
        stdout.write(event['delta']);
      case 'response.output_item.done':
        stdout.writeln('container: ${event['item']['container_id']}');
    }
  }
}
```

Use these events to show live output, capture errors, or record container IDs.

## Container Reuse

Containers persist across turns when you supply a `containerId`. The example
below captures the ID from the first response and injects it into the second:

```dart theme={null}
String? containerId;
await for (final chunk in agent.sendStream(prompt)) {
  containerId ??= containerIdFromMetadata(chunk.metadata);
}

final agent2 = Agent(
  'openai-responses',
  chatModelOptions: OpenAIResponsesChatModelOptions(
    serverSideTools: const {OpenAIServerSideTool.codeInterpreter},
    codeInterpreterConfig: CodeInterpreterConfig(containerId: containerId),
  ),
);

agent2.sendStream(prompt2)...;

// Helper function to extract container ID from metadata
String? containerIdFromMetadata(Map<String, dynamic> metadata) {
  final ciEvents = metadata['code_interpreter'] as List?;
  if (ciEvents != null) {
    for (final event in ciEvents) {
      // Check for container_id at the top level (older synthetic events)
      if (event['container_id'] != null) {
        return event['container_id'] as String;
      }
      // Check for container_id nested in item (response.output_item.done
      // events)
      final item = event['item'];
      if (item is Map && item['container_id'] != null) {
        return item['container_id'] as String;
      }
    }
  }
  return null;
}
```

## Generated Files

When the interpreter saves files (e.g. images, CSVs) they are downloaded
automatically and attached as `DataPart` instances on the assistant message.
Each `DataPart` includes the actual filename from the interpreter (e.g.,
`fibonacci.csv`, `plot.png`) for easy identification and saving.

```dart theme={null}
final history = <ChatMessage>[];
await for (final chunk in agent.sendStream(prompt)) {
  history.addAll(chunk.messages);
}

// Access generated files
for (final msg in history) {
  for (final part in msg.parts) {
    if (part is DataPart) {
      print('File: ${part.name}'); // e.g., "fibonacci.csv"
      print('MIME: ${part.mimeType}'); // e.g., "text/csv"
      print('Size: ${part.bytes.length} bytes');

      // Save to disk with original filename
      File('output/${part.name}').writeAsBytesSync(part.bytes);
    }
  }
}
```

## Example

* [Server-side code interpreter
  demo](https://github.com/csells/dartantic_ai/blob/main/packages/dartantic_ai/example/bin/server_side_tools/server_side_code_interpreter.dart)

## Related Topics

* [Image Generation](/server-side-tools/image-generation)
* [Thinking Metadata](/thinking)
