forge.rs threads Effort::Max on gen + cleanup. Audit + summarize stay default — they're structured-output / tool-shaped tasks where extended thinking doesn't help. Bumps subprocess timeout from 600s to 1800s so max-effort prose-craft has the wall clock it needs. continue_story::run takes a chapter_count param; loops gen+cleanup per chapter with each iteration's just-written prose appended to context. Audit fires once at end against the combined batch vs parent canon. Cap is 20 (~5h wall clock, ~$600 at max effort — beyond that is operationally absurd). CLI: 'skald continue --chapters N'. Web: numeric field on both new- story and continue forms, 1..=20, defaults to 1. Vendored clawdforge SDK refreshed for the Effort enum.
58 lines
1.8 KiB
Rust
58 lines
1.8 KiB
Rust
//! Async Rust client for the [clawdforge] HTTP service.
|
|
//!
|
|
//! clawdforge is a small LAN-only service that wraps `claude -p` subprocess
|
|
//! calls behind a bearer-token-gated REST API. This crate is a thin,
|
|
//! ergonomic Rust SDK for it.
|
|
//!
|
|
//! # Quickstart
|
|
//!
|
|
//! ```no_run
|
|
//! use clawdforge::{Client, RunRequest};
|
|
//!
|
|
//! # async fn run() -> Result<(), Box<dyn std::error::Error>> {
|
|
//! let client = Client::builder()
|
|
//! .base_url("http://localhost:8800")
|
|
//! .token("cf_xxxxxxxxxxxxxxxx")
|
|
//! .build()?;
|
|
//!
|
|
//! let h = client.healthz().await?;
|
|
//! println!("claude present: {}", h.claude_present);
|
|
//!
|
|
//! let r = client.run(RunRequest {
|
|
//! prompt: "Reply with JSON: {\"hello\":\"world\"}".into(),
|
|
//! model: Some("sonnet".into()),
|
|
//! ..Default::default()
|
|
//! }).await?;
|
|
//!
|
|
//! #[derive(serde::Deserialize)]
|
|
//! struct Hello { hello: String }
|
|
//! let typed: Hello = r.as_json()?;
|
|
//! println!("{}", typed.hello);
|
|
//! # Ok(()) }
|
|
//! ```
|
|
//!
|
|
//! [clawdforge]: https://git.sulkta.com/Sulkta-OSS/clawdforge
|
|
//!
|
|
//! # Field naming
|
|
//!
|
|
//! The clawdforge wire format is snake_case end-to-end (Python / Pydantic
|
|
//! conventions), so structs in [`crate::types`] do **not** carry
|
|
//! `#[serde(rename_all = "camelCase")]`. If a future endpoint exposes
|
|
//! camelCase, prefer per-field `#[serde(rename = "...")]` over a blanket
|
|
//! container attribute.
|
|
|
|
#![deny(rust_2018_idioms)]
|
|
#![deny(missing_docs)]
|
|
|
|
mod client;
|
|
mod error;
|
|
pub mod session;
|
|
pub mod types;
|
|
|
|
pub use client::{Client, ClientBuilder};
|
|
pub use error::Error;
|
|
pub use session::{Session, SessionList, SessionOptions, SessionState, TurnEvent, TurnResult};
|
|
pub use types::{
|
|
AppToken, AppTokenInfo, Effort, FileToken, Healthz, RunFailure, RunRequest, RunResult,
|
|
SystemMode, TokenCreateRequest, TokenList,
|
|
};
|