Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,21 @@ export EPISODIC_MEMORY_API_TOKEN=your-token

# Increase timeout for slow endpoints (milliseconds)
export EPISODIC_MEMORY_API_TIMEOUT_MS=3000000

# Load Claude Code settings (comma-separated: user, project, local)
export EPISODIC_MEMORY_CLAUDE_CODE_SETTING_SOURCES=user
```

The `EPISODIC_MEMORY_CLAUDE_CODE_SETTING_SOURCES` variable controls which [Claude Code settings](https://docs.anthropic.com/en/docs/claude-code/settings) are loaded during summarization. By default, no settings are loaded (SDK isolation mode). Accepts a comma-separated list of:

| Value | Settings file | Description |
|-------|---------------|-------------|
| `user` | `~/.claude/settings.json` | Global user settings (e.g. `awsCredentialExport` for Bedrock) |
| `project` | `.claude/settings.json` | Shared project settings (version-controlled) |
| `local` | `.claude/settings.local.json` | Local project overrides (typically gitignored) |

**Recommended:** Leave empty or use `user` only. The `project` and `local` sources also load CLAUDE.md files and MCP servers into the summarization context, which can interfere with summary quality.

These settings only affect episodic-memory's summarization calls, not your interactive Claude sessions.

### What's Affected
Expand Down
19 changes: 19 additions & 0 deletions dist/summarizer.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { SUMMARIZER_CONTEXT_MARKER } from './constants.js';
* - EPISODIC_MEMORY_API_BASE_URL: Custom API endpoint
* - EPISODIC_MEMORY_API_TOKEN: Auth token for custom endpoint
* - EPISODIC_MEMORY_API_TIMEOUT_MS: Timeout for API calls (default: SDK default)
* - EPISODIC_MEMORY_CLAUDE_CODE_SETTING_SOURCES: Comma-separated list of Claude Code setting sources to load (default: none)
*/
function getApiEnv() {
const baseUrl = process.env.EPISODIC_MEMORY_API_BASE_URL;
Expand All @@ -26,6 +27,18 @@ function getApiEnv() {
...(timeoutMs && { API_TIMEOUT_MS: timeoutMs }),
};
}
/**
* Get setting sources for SDK configuration.
* Parses EPISODIC_MEMORY_CLAUDE_CODE_SETTING_SOURCES as comma-separated list.
* Default: empty (no settings loaded). Set to 'user' to load user settings (e.g., awsCredentialExport for Bedrock)
*/
function getSettingSources() {
const sources = process.env.EPISODIC_MEMORY_CLAUDE_CODE_SETTING_SOURCES;
if (!sources) {
return undefined;
}
return sources.split(',').map(s => s.trim()).filter(Boolean);
}
export function formatConversationText(exchanges) {
return exchanges.map(ex => {
return `User: ${ex.userMessage}\n\nAgent: ${ex.assistantMessage}`;
Expand All @@ -39,6 +52,10 @@ function extractSummary(text) {
// Fallback if no tags found
return text.trim();
}
/**
* Call Claude API to generate a summary.
* Uses the configured model and settings, with automatic fallback on errors.
*/
async function callClaude(prompt, sessionId, useFallback = false) {
const primaryModel = process.env.EPISODIC_MEMORY_API_MODEL || 'haiku';
const fallbackModel = process.env.EPISODIC_MEMORY_API_MODEL_FALLBACK || 'sonnet';
Expand All @@ -50,6 +67,8 @@ async function callClaude(prompt, sessionId, useFallback = false) {
max_tokens: 4096,
env: getApiEnv(),
resume: sessionId,
// Load settings to pick up API config (e.g., awsCredentialExport for Bedrock)
settingSources: getSettingSources(),
// Don't override systemPrompt when resuming - it uses the original session's prompt
// Instead, the prompt itself should provide clear instructions
...(sessionId ? {} : {
Expand Down
20 changes: 20 additions & 0 deletions src/summarizer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { SUMMARIZER_CONTEXT_MARKER } from './constants.js';
* - EPISODIC_MEMORY_API_BASE_URL: Custom API endpoint
* - EPISODIC_MEMORY_API_TOKEN: Auth token for custom endpoint
* - EPISODIC_MEMORY_API_TIMEOUT_MS: Timeout for API calls (default: SDK default)
* - EPISODIC_MEMORY_CLAUDE_CODE_SETTING_SOURCES: Comma-separated list of Claude Code setting sources to load (default: none)
*/
function getApiEnv(): Record<string, string | undefined> | undefined {
const baseUrl = process.env.EPISODIC_MEMORY_API_BASE_URL;
Expand All @@ -31,6 +32,19 @@ function getApiEnv(): Record<string, string | undefined> | undefined {
};
}

/**
* Get setting sources for SDK configuration.
* Parses EPISODIC_MEMORY_CLAUDE_CODE_SETTING_SOURCES as comma-separated list.
* Default: empty (no settings loaded). Set to 'user' to load user settings (e.g., awsCredentialExport for Bedrock)
*/
function getSettingSources(): string[] | undefined {
const sources = process.env.EPISODIC_MEMORY_CLAUDE_CODE_SETTING_SOURCES;
if (!sources) {
return undefined;
}
return sources.split(',').map(s => s.trim()).filter(Boolean);
}

export function formatConversationText(exchanges: ConversationExchange[]): string {
return exchanges.map(ex => {
return `User: ${ex.userMessage}\n\nAgent: ${ex.assistantMessage}`;
Expand All @@ -46,6 +60,10 @@ function extractSummary(text: string): string {
return text.trim();
}

/**
* Call Claude API to generate a summary.
* Uses the configured model and settings, with automatic fallback on errors.
*/
async function callClaude(prompt: string, sessionId?: string, useFallback = false): Promise<string> {
const primaryModel = process.env.EPISODIC_MEMORY_API_MODEL || 'haiku';
const fallbackModel = process.env.EPISODIC_MEMORY_API_MODEL_FALLBACK || 'sonnet';
Expand All @@ -58,6 +76,8 @@ async function callClaude(prompt: string, sessionId?: string, useFallback = fals
max_tokens: 4096,
env: getApiEnv(),
resume: sessionId,
// Load settings to pick up API config (e.g., awsCredentialExport for Bedrock)
settingSources: getSettingSources(),
// Don't override systemPrompt when resuming - it uses the original session's prompt
// Instead, the prompt itself should provide clear instructions
...(sessionId ? {} : {
Expand Down