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
32 changes: 32 additions & 0 deletions src/cli/agent.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
use clap::{Args, Subcommand};

#[derive(Args, Debug)]
pub struct AgentArgs {
#[command(subcommand)]
pub command: AgentCommand,
}

#[derive(Subcommand, Debug)]
pub enum AgentCommand {
/// Hand a task to a helper agent running in its own top-level session.
Spawn {
/// What the helper agent should do. Write it as a self-contained brief:
/// the helper starts with an empty transcript and cannot see this chat.
task: Option<String>,
/// Read the task from stdin instead, for long multi-paragraph briefs.
#[arg(long)]
stdin: bool,
/// Name the session in the sidebar. Defaults to an auto-generated title.
#[arg(long)]
title: Option<String>,
/// Harness for the helper (defaults to this session's).
#[arg(long)]
harness: Option<String>,
/// Model for the helper (defaults to this session's).
#[arg(long)]
model: Option<String>,
/// Do not resume this chat when the helper finishes.
#[arg(long)]
no_wake: bool,
},
}
8 changes: 8 additions & 0 deletions src/cli/auth.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
use clap::Args;

#[derive(Args, Debug)]
pub struct LoginArgs {
/// Override the API base URL (or set OPENRESEARCH_API_URL).
#[arg(long = "api-url")]
pub api_url: Option<String>,
}
98 changes: 98 additions & 0 deletions src/cli/compute.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
use clap::{Args, Subcommand};

#[derive(Args, Debug)]
pub struct ComputeArgs {
/// List CPU-only instance offers instead of the GPU catalog. CPU instances
/// suit GPU-less experiments (data prep, eval harnesses, CPU-bound papers).
#[arg(long)]
pub cpu: bool,
/// Filter to one GPU id (e.g. `H100_SXM`). Case-insensitive. GPU mode only.
#[arg(long)]
pub gpu: Option<String>,
/// Filter to a specific GPU count per instance. GPU mode only.
#[arg(long)]
pub count: Option<i64>,
/// Filter to one provider (e.g. `runpod`, `vast`, `lambda`). Case-insensitive. GPU mode only.
#[arg(long)]
pub provider: Option<String>,
}

#[derive(Args, Debug)]
pub struct SshKeyArgs {
#[command(subcommand)]
pub command: SshKeyCommand,
}

#[derive(Subcommand, Debug)]
pub enum SshKeyCommand {
/// Register a public key on your account. Every box in your orgs — including
/// ones already running — starts accepting it.
Add(SshKeyAddArgs),
/// List registered keys, marking the ones usable from this computer.
List,
}

#[derive(Args, Debug)]
pub struct SshKeyAddArgs {
/// Public key path. Without a path, reuse ~/.ssh/id_ed25519.pub or create a key pair.
pub path: Option<String>,
}

#[derive(Args, Debug)]
pub struct InstanceArgs {
#[command(subcommand)]
pub command: InstanceCommand,
}

#[derive(Subcommand, Debug)]
pub enum InstanceCommand {
/// Provision a standalone instance in an org (GPU with `--gpu`, or CPU with
/// `--cpu`). Not tied to an experiment — like the dashboard's "Spin up".
Create(InstanceCreateArgs),
/// List an org's instances (status, SSH endpoint, price) — including any
/// `--backend openresearch` box a failed teardown left behind.
List(InstanceListArgs),
/// Terminate an instance (destroys the provider machine). The manual
/// cleanup path when a run's automatic teardown failed.
Delete(InstanceDeleteArgs),
}

#[derive(Args, Debug)]
pub struct InstanceCreateArgs {
/// Organization id (from `orx orgs`).
pub org_id: String,
/// Provision a GPU instance with this GPU id, e.g. `H100_SXM` — the exact id
/// from `orx compute`, not a family name like `H100`.
#[arg(long)]
pub gpu: Option<String>,
/// GPUs per instance (with `--gpu`; default 1).
#[arg(long)]
pub count: Option<i64>,
/// Disk in GB (with `--gpu`; default 100).
#[arg(long)]
pub disk: Option<i64>,
/// Provider to provision from (with `--gpu`), e.g. runpod, vast, lambda.
/// Omit to pick the cheapest matching offer across providers (like the
/// dashboard). See `orx compute` for providers; validated server-side.
#[arg(long)]
pub provider: Option<String>,
/// Provision a CPU-only instance with this flavor: cpu5c (compute), cpu5g
/// (general), or cpu5m (memory-optimized). Mutually exclusive with `--gpu`.
#[arg(long)]
pub cpu: Option<String>,
/// vCPUs for a CPU instance (with `--cpu`): 2, 8, or 32 (default 8).
#[arg(long)]
pub vcpus: Option<i64>,
}

#[derive(Args, Debug)]
pub struct InstanceListArgs {
/// Organization id (from `orx orgs`).
pub org_id: String,
}

#[derive(Args, Debug)]
pub struct InstanceDeleteArgs {
/// The instance (sandbox) id to terminate.
pub sandbox_id: String,
}
61 changes: 61 additions & 0 deletions src/cli/daemon.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
use clap::{Args, Subcommand};

#[derive(Args, Debug)]
pub struct ServeArgs {
/// Port to bind on 127.0.0.1 (default 4790 — what the api proxies to).
#[arg(long)]
pub port: Option<u16>,
}

#[derive(Args, Debug)]
pub struct SuperviseArgs {
/// The run to supervise (must exist in the local store).
pub run_id: String,
}

#[derive(Args, Debug)]
pub struct UpArgs {
/// Port to bind on 127.0.0.1. With `--remote`, the local presentation port.
#[arg(long, default_value_t = 4791)]
pub port: u16,
/// Run `orx up` on a remote box over SSH and forward it here. The value is
/// an `~/.ssh/config` host alias, or `user@host` (append `:PORT` for a
/// non-standard SSH port, e.g. `root@1.2.3.4:38455`). Only user@host + port
/// are reconstructed; a custom key or jump host must come from `~/.ssh/config`.
/// Starts an authenticated server there, tunnels it through a hidden local
/// port, and opens a dedicated local presentation gateway in your browser.
#[arg(long, value_name = "HOST")]
pub remote: Option<String>,
/// Don't open the dashboard in the browser on startup.
#[arg(long)]
pub no_browser: bool,
/// Don't spawn the opencode agent on startup (for tests).
#[arg(long)]
pub no_agent: bool,
/// opencode model override, e.g. `anthropic/claude-sonnet-4-5`.
#[arg(long)]
pub model: Option<String>,
/// Internal persistent dashboard/agent-host mode.
#[arg(long, hide = true)]
pub remote_host: bool,
}

#[derive(Args, Clone, Debug)]
pub struct RemoteHostArgs {
#[command(subcommand)]
pub command: RemoteHostCommand,
}

#[derive(Clone, Subcommand, Debug)]
pub enum RemoteHostCommand {
Ensure {
#[arg(long)]
expected_instance: Option<String>,
},
Status,
Attach {
#[arg(long)]
expected_instance: String,
},
Stop,
}
106 changes: 106 additions & 0 deletions src/cli/discover.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
use clap::{Args, Subcommand, ValueEnum};

/// Which corpus a literature command searches or reads from.
#[derive(ValueEnum, Clone, Copy, Debug, PartialEq, Eq)]
#[value(rename_all = "lower")]
pub enum LitSource {
/// alphaXiv (arXiv corpus: CS, math, physics, stats — the default).
Alphaxiv,
/// OpenAlex (general scholarly graph across all disciplines).
Openalex,
/// bioRxiv biology preprints (searched via OpenAlex, fetched via bioRxiv).
Biorxiv,
}

impl LitSource {
/// Lowercase wire name used to enforce against the Settings disable-set.
/// Matches the `--source` flag values (clap `rename_all = "lower"`) and the
/// `LitHit.source` JSON labels.
pub fn as_str(&self) -> &'static str {
match self {
LitSource::Alphaxiv => "alphaxiv",
LitSource::Openalex => "openalex",
LitSource::Biorxiv => "biorxiv",
}
}

/// Human-facing name for error/UI text.
pub fn display_name(&self) -> &'static str {
match self {
LitSource::Alphaxiv => "alphaXiv",
LitSource::Openalex => "OpenAlex",
LitSource::Biorxiv => "bioRxiv",
}
}
}

#[derive(Args, Debug)]
pub struct DiscoverArgs {
#[command(subcommand)]
pub command: DiscoverCommand,
}

#[derive(Subcommand, Debug)]
pub enum DiscoverCommand {
/// alphaXiv full-text BM25 retrieval with match snippets.
Keyword(DiscoverySearchArgs),
/// alphaXiv semantic title/abstract retrieval with similarity/popularity reranking.
Embedding(DiscoverySearchArgs),
/// OpenAlex scholarly-graph search across disciplines.
Openalex(DiscoverySearchArgs),
/// bioRxiv preprint search through OpenAlex's bioRxiv source index.
Biorxiv(DiscoverySearchArgs),
}

#[derive(Args, Debug)]
pub struct DiscoverySearchArgs {
/// Exact keyword query or semantic description, depending on the strategy.
pub query: String,
/// Include papers first published on or after this date (YYYY-MM-DD).
#[arg(long = "published-after")]
pub published_after: Option<String>,
/// Include papers first published on or before this date (YYYY-MM-DD). Older
/// or narrow embedding windows can return a thin candidate set.
#[arg(long = "published-before")]
pub published_before: Option<String>,
/// Ranking policy after topical relevance is accounted for.
#[arg(long, value_enum, default_value = "default")]
pub prioritize: DiscoveryPriority,
/// Maximum results to emit (default 15). alphaXiv uses its fixed server-side candidate pool.
#[arg(long, default_value_t = 15, value_parser = clap::value_parser!(u32).range(1..=200))]
pub limit: u32,
}

#[derive(ValueEnum, Clone, Copy, Debug, PartialEq, Eq)]
#[value(rename_all = "lower")]
pub enum DiscoveryPriority {
Historical,
Default,
Recency,
Popular,
}

impl DiscoveryPriority {
pub fn as_str(self) -> &'static str {
match self {
Self::Historical => "historical",
Self::Default => "default",
Self::Recency => "recency",
Self::Popular => "popular",
}
}
}

#[derive(Args, Debug)]
pub struct PaperArgs {
/// Paper id: an arXiv id / URL (alphaXiv), a DOI (bioRxiv `10.1101/…` or any
/// other), or an OpenAlex `W…` id. The source is auto-detected.
pub id: String,
/// Force the source instead of auto-detecting it from the id.
#[arg(long, value_enum)]
pub source: Option<LitSource>,
/// Fetch the full extracted paper text instead of the report (alphaXiv only;
/// OpenAlex/bioRxiv have no extracted full text and point you at the PDF).
#[arg(long)]
pub full: bool,
}
Loading