Skip to main content

systemprompt_cli/commands/core/contexts/
use_context.rs

1//! `core contexts use` command switching the active context.
2//!
3//! Copyright (c) systemprompt.io — Business Source License 1.1.
4//! See <https://systemprompt.io> for licensing details.
5
6use anyhow::{Context, Result};
7use clap::Args;
8use systemprompt_agent::repository::context::ContextRepository;
9use systemprompt_cloud::{SessionKey, SessionStore};
10use systemprompt_logging::CliService;
11
12use super::resolve::resolve_context;
13use super::types::ContextSwitchedOutput;
14use crate::CliConfig;
15use crate::context::CommandContext;
16use crate::paths::ResolvedPaths;
17use crate::session::{CliSessionContext, get_or_create_session};
18use crate::shared::CommandOutput;
19use std::path::Path;
20use systemprompt_database::DbPool;
21
22#[derive(Debug, Args)]
23pub struct UseArgs {
24    #[arg(help = "Context ID (full, partial prefix, or name)")]
25    pub context: String,
26}
27
28pub(super) async fn execute(args: UseArgs, ctx: &CommandContext) -> Result<CommandOutput> {
29    let session_ctx = get_or_create_session(ctx).await?;
30    let pool = ctx.db_pool().await?;
31    let sessions_dir = ResolvedPaths::discover().sessions_dir();
32    execute_resolved(args, &ctx.cli, &session_ctx, &pool, &sessions_dir).await
33}
34
35pub async fn execute_resolved(
36    args: UseArgs,
37    cli: &CliConfig,
38    session_ctx: &CliSessionContext,
39    pool: &DbPool,
40    sessions_dir: &Path,
41) -> Result<CommandOutput> {
42    let repo = ContextRepository::new(pool)?;
43
44    let context_id = resolve_context(&args.context, &session_ctx.session.user_id, &repo).await?;
45
46    let context = repo
47        .get_context(&context_id, &session_ctx.session.user_id)
48        .await
49        .context("Failed to fetch context details")?;
50
51    let mut store = SessionStore::load_or_create(sessions_dir)?;
52
53    let session_key = SessionKey::from_tenant_id(
54        session_ctx
55            .profile
56            .cloud
57            .as_ref()
58            .and_then(|c| c.tenant_id.as_ref()),
59    );
60
61    let mut session = session_ctx.session.clone();
62    session.set_context_id(context_id.clone());
63    store.upsert_session(&session_key, session);
64    store.save(sessions_dir)?;
65
66    let output = ContextSwitchedOutput {
67        id: context_id.clone(),
68        name: context.name.clone(),
69        message: format!("Switched to context '{}'", context.name),
70    };
71
72    if !cli.is_json_output() {
73        CliService::success(&output.message);
74        CliService::key_value("ID", context_id.as_str());
75        CliService::key_value("Name", &context.name);
76    }
77
78    Ok(CommandOutput::card_value("Context Switched", &output))
79}