Skip to content

4. Session-Aware Support Bot

Problem: Your support bot forgets the user’s prior tickets. Users retype everything. Agents can’t learn from past resolutions. You’re re-inventing the wheel every conversation.

Outcome: Use EdgeCrab’s built-in SQLite + FTS5 session store to find semantically relevant prior conversations in <10ms, inject them as context, and let the bot resolve faster using organizational memory.

User: "My Kubernetes pods keep OOMKilling."
┌─────────────────────────────────┐
│ FTS5 search on prior sessions │
│ query = "kubernetes OOM pods" │
│ ~8ms across 10,000+ sessions │
└─────────────┬───────────────────┘
top 3 matching sessions
┌───────────────────────────────────────────┐
│ Summarize + inject as "prior context": │
│ │
│ [FROM SESSION ses_abc12] │
│ "User had OOM due to JVM heap │
│ settings. Resolved by adding │
│ -XX:MaxRAMPercentage=75" │
│ │
│ [FROM SESSION ses_def78] │
│ "User increased limits from 512Mi │
│ to 2Gi; resolved." │
└───────────────┬───────────────────────────┘
┌───────────────────────────┐
│ Agent responds with full │
│ org knowledge on hand │
└───────────────────────────┘

Why FTS5? SQLite’s FTS5 extension gives full-text search with BM25 scoring at zero operational cost. No Elasticsearch, no pgvector, no infra. The database file lives at ~/.edgecrab/sessions.db.

examples/session_aware_support.py
import asyncio
from edgecrab import Agent, Session
async def resolve_ticket(user_message: str):
# ── 1. Search prior sessions for similar issues ─────────────────
db = Session() # opens ~/.edgecrab/sessions.db
hits = db.search(user_message, limit=3)
prior_context = ""
if hits:
prior_context = "\n\n--- RELEVANT PRIOR TICKETS ---\n"
for h in hits:
prior_context += (
f"[session={h.session_id[:8]}, score={h.score:.2f}]\n"
f"{h.snippet}\n\n"
)
# ── 2. Spin up an agent with the prior context pre-loaded ───────
agent = Agent(
"copilot/gpt-5-mini",
max_iterations=6,
quiet_mode=True,
instructions=(
"You are a senior support engineer. If prior tickets contain "
"the answer, reference them by session ID. Always state the "
"ROOT CAUSE before the FIX."
),
)
result = agent.run_sync(
f"User ticket: {user_message}{prior_context}"
)
print(f"Resolution:\n{result.response}")
print(f"\nSession: {result.session_id}")
print(f"Cost: ${result.total_cost:.6f}")
return result
if __name__ == "__main__":
asyncio.run(resolve_ticket("My K8s pods keep OOMKilling under load."))
//! examples/session_aware_support.rs
use edgecrab_sdk::prelude::*;
#[tokio::main]
async fn main() -> Result<(), SdkError> {
let user_message = "My K8s pods keep OOMKilling under load.";
// ── 1. Open the shared session DB and search ────────────────────
let db = SdkSession::open_default()?;
let hits = db.search_sessions(user_message, 3)?;
let prior_context = if hits.is_empty() {
String::new()
} else {
let mut s = String::from("\n\n--- RELEVANT PRIOR TICKETS ---\n");
for h in &hits {
s.push_str(&format!(
"[session={}, score={:.2}]\n{}\n\n",
&h.session.id[..8.min(h.session.id.len())],
h.score,
h.snippet,
));
}
s
};
// ── 2. Agent with prior context pre-loaded ──────────────────────
let agent = SdkAgent::builder("copilot/gpt-5-mini")?
.max_iterations(6)
.quiet_mode(true)
.instructions(
"You are a senior support engineer. If prior tickets contain \
the answer, reference them by session ID. Always state the \
ROOT CAUSE before the FIX.",
)
.build()?;
let result = agent
.run(&format!("User ticket: {user_message}{prior_context}"))
.await?;
println!("Resolution:\n{}", result.final_response);
println!("\nSession: {}", result.session_id);
println!("Cost: ${:.6}", result.cost.total_cost);
Ok(())
}
examples/session_aware_support.mjs
import { Agent, Session } from 'edgecrab';
const userMessage = 'My K8s pods keep OOMKilling under load.';
// 1. Search prior sessions
const db = new Session();
const hits = db.searchSessions(userMessage, 3);
let priorContext = '';
if (hits.length) {
priorContext = '\n\n--- RELEVANT PRIOR TICKETS ---\n';
for (const h of hits) {
priorContext +=
`[session=${h.sessionId.slice(0, 8)}, score=${h.score.toFixed(2)}]\n` +
`${h.snippet}\n\n`;
}
}
// 2. Agent with prior context pre-loaded
const agent = new Agent({
model: 'copilot/gpt-5-mini',
maxIterations: 6,
quietMode: true,
instructions:
'You are a senior support engineer. If prior tickets contain the ' +
'answer, reference them by session ID. Always state the ROOT CAUSE before the FIX.',
});
const result = await agent.run(`User ticket: ${userMessage}${priorContext}`);
console.log(`Resolution:\n${result.response}`);
console.log(`\nSession: ${result.sessionId}`);
console.log(`Cost: $${result.totalCost.toFixed(6)}`);

Your session DB grows indefinitely. Track + trim it:

db = Session()
stats = db.stats()
print(f"Sessions: {stats.total_sessions}")
print(f"Messages: {stats.total_messages}")
print(f"DB size: {stats.db_size_bytes / 1024 / 1024:.1f} MB")
# Prune sessions older than 90 days
pruned = db.prune_sessions(older_than_days=90)
print(f"Pruned {pruned} old sessions")
let db = SdkSession::open_default()?;
let stats = db.stats()?;
println!("Sessions: {}, Messages: {}, Size: {} MB",
stats.total_sessions, stats.total_messages,
stats.db_size_bytes / 1024 / 1024);
let pruned = db.prune_sessions(90, None)?;
println!("Pruned {pruned} sessions");

On a seeded DB with 5,000 historical support tickets (synthetic):

StrategyResolution accuracy*First-response timeCost / ticket
Agent alone, no prior context58%7.2s$0.0031
Agent + top-3 FTS5 hits (this)83%7.4s$0.0034

* Matches the known canonical resolution in the seed data. 3-rater agreement.

+25% accuracy for +$0.0003 per ticket. The FTS5 search adds ~8ms; negligible.

  • Cold-start. If you have <100 sessions, there’s nothing to retrieve — just run the agent directly.
  • Privacy-sensitive multi-tenant. Sessions from user A shouldn’t bleed into user B’s search results. Filter by source= / per-user DB files, OR use EdgeCrab profiles.
  • Structured knowledge bases. If your answers live in a CRM, use a custom tool (Tutorial 5). FTS5 is for conversation history.
Terminal window
# First, seed the DB by running a few conversations:
edgecrab chat "How do I fix K8s OOM errors?"
edgecrab chat "How do I tune JVM heap in K8s?"
# Then run the tutorial:
python examples/session_aware_support.py

Expected output includes:

[session=abc123de, score=2.34]
User was hitting OOMKilled on pods running Java workloads...