feat: add config.example.json template and update AGENTS.md with new config path

This commit is contained in:
xiaoxixi 2026-05-10 18:45:53 +08:00
parent a479b92cdf
commit 5aec8cefb9
5 changed files with 15 additions and 13 deletions

View File

@ -10,8 +10,7 @@
- Config load order: `~/.picobot/config.json` then fallback to `./config.json` (`src/config/mod.rs:237-267`) - Config load order: `~/.picobot/config.json` then fallback to `./config.json` (`src/config/mod.rs:237-267`)
- `.env` (cwd) is loaded with a custom parser, not via dotenv crate; env var placeholders `<VAR_NAME>` in config JSON are substituted - `.env` (cwd) is loaded with a custom parser, not via dotenv crate; env var placeholders `<VAR_NAME>` in config JSON are substituted
- Config example: `config.example.json` - Config example: `resources/templates/config.example.json` (released to `~/.picobot/` on first run)
- `session_ttl_hours` defaults to 4 in code when absent (`src/gateway/mod.rs:44`); config.example.json shows 168 as a suggestion
## Tests ## Tests

View File

@ -220,7 +220,7 @@ graph LR
Providers --> PT["type (openai / anthropic)<br/>base_url<br/>api_key<br/>extra_headers"] Providers --> PT["type (openai / anthropic)<br/>base_url<br/>api_key<br/>extra_headers"]
Models --> MT["model_id<br/>temperature<br/>max_tokens"] Models --> MT["model_id<br/>temperature<br/>max_tokens"]
Agents --> AT["provider (ref)<br/>model (ref)<br/>max_tool_iterations<br/>token_limit"] Agents --> AT["provider (ref)<br/>model (ref)<br/>max_tool_iterations<br/>token_limit"]
Gateway --> GT["host / port<br/>session_ttl_hours<br/>cleanup_interval_minutes<br/>session_db_path<br/>scheduler"] Gateway --> GT["host / port<br/>session_db_path<br/>scheduler"]
Channels --> CT["feishu: app_id, app_secret<br/>allow_from, agent, media_dir"] Channels --> CT["feishu: app_id, app_secret<br/>allow_from, agent, media_dir"]
``` ```
@ -234,8 +234,6 @@ The `.env` file in the working directory is loaded manually (not via dotenv crat
|-----|------|---------|-------------| |-----|------|---------|-------------|
| `host` | string | `127.0.0.1` | Bind address | | `host` | string | `127.0.0.1` | Bind address |
| `port` | u16 | `19876` | Listen port | | `port` | u16 | `19876` | Listen port |
| `session_ttl_hours` | number | `4` | Inactive session expiration (hours) |
| `cleanup_interval_minutes` | number | `60` | Session cleanup interval |
| `session_db_path` | string | workspace `picobot.db` | SQLite database path | | `session_db_path` | string | workspace `picobot.db` | SQLite database path |
| `scheduler.enabled` | bool | `false` | Enable cron scheduler | | `scheduler.enabled` | bool | `false` | Enable cron scheduler |
@ -402,6 +400,8 @@ Integration tests are `#[ignore]` by default because they make real API calls.
│ ├── test.env.example # Test environment template │ ├── test.env.example # Test environment template
│ └── test.env # Actual test keys (gitignored) │ └── test.env # Actual test keys (gitignored)
├── reference/ # Third-party reference code (do not modify) ├── reference/ # Third-party reference code (do not modify)
├── resources/ # Assets embedded in binary
│ └── templates/ # Templates released to ~/.picobot/ on first run
├── config.example.json # Full config example ├── config.example.json # Full config example
└── Cargo.toml └── Cargo.toml
``` ```

View File

@ -46,8 +46,7 @@
}, },
"gateway": { "gateway": {
"host": "127.0.0.1", "host": "127.0.0.1",
"port": 19876, "port": 19876
"session_ttl_hours": 168
}, },
"client": { "client": {
"gateway_url": "ws://127.0.0.1:19876/ws" "gateway_url": "ws://127.0.0.1:19876/ws"
@ -67,7 +66,6 @@
"consolidation_provider": null, "consolidation_provider": null,
"consolidation_model": null, "consolidation_model": null,
"recall_limit": 5, "recall_limit": 5,
"consolidation_turn_threshold": 10,
"idle_consolidation_minutes": 10, "idle_consolidation_minutes": 10,
"timeline_retention_days": 90, "timeline_retention_days": 90,
"max_failures_before_degrade": 3 "max_failures_before_degrade": 3

View File

@ -233,9 +233,6 @@ pub struct MemoryConfig {
/// Max knowledge entries injected into system prompt per turn. /// Max knowledge entries injected into system prompt per turn.
#[serde(default = "default_recall_limit")] #[serde(default = "default_recall_limit")]
pub recall_limit: usize, pub recall_limit: usize,
/// Number of turns without consolidation before forcing one.
#[serde(default = "default_consolidation_turn_threshold")]
pub consolidation_turn_threshold: usize,
/// Idle minutes before triggering consolidation (for async channels). /// Idle minutes before triggering consolidation (for async channels).
#[serde(default = "default_idle_consolidation_minutes")] #[serde(default = "default_idle_consolidation_minutes")]
pub idle_consolidation_minutes: u64, pub idle_consolidation_minutes: u64,
@ -253,7 +250,6 @@ impl Default for MemoryConfig {
consolidation_provider: None, consolidation_provider: None,
consolidation_model: None, consolidation_model: None,
recall_limit: 5, recall_limit: 5,
consolidation_turn_threshold: 10,
idle_consolidation_minutes: 10, idle_consolidation_minutes: 10,
timeline_retention_days: 90, timeline_retention_days: 90,
max_failures_before_degrade: 3, max_failures_before_degrade: 3,
@ -274,7 +270,6 @@ impl MemoryConfig {
} }
fn default_recall_limit() -> usize { 5 } fn default_recall_limit() -> usize { 5 }
fn default_consolidation_turn_threshold() -> usize { 10 }
fn default_idle_consolidation_minutes() -> u64 { 10 } fn default_idle_consolidation_minutes() -> u64 { 10 }
fn default_timeline_retention_days() -> u64 { 90 } fn default_timeline_retention_days() -> u64 { 90 }
fn default_max_failures_before_degrade() -> usize { 3 } fn default_max_failures_before_degrade() -> usize { 3 }

View File

@ -378,4 +378,14 @@ fn ensure_default_config_files() {
tracing::info!(path = %user_path.display(), "Released default USER.md template"); tracing::info!(path = %user_path.display(), "Released default USER.md template");
} }
} }
let config_example_path = picobot_dir.join("config.example.json");
if !config_example_path.exists() {
let content = include_str!("../../resources/templates/config.example.json");
if let Err(e) = std::fs::write(&config_example_path, content) {
tracing::warn!(path = %config_example_path.display(), error = %e, "Failed to write config.example.json template");
} else {
tracing::info!(path = %config_example_path.display(), "Released config.example.json template");
}
}
} }