docs: slim down README and split into topic-specific docs
Add local full-stack development section (pnpm dev:local) and move detailed content (credentials, CLI, skills/tools, time injection, development guide) into separate docs/ files. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
058af56d47
commit
18a6996c97
6 changed files with 250 additions and 198 deletions
242
README.md
242
README.md
|
|
@ -9,31 +9,27 @@ See [Memo](./docs/memo.md) for product vision, architecture, and roadmap.
|
||||||
## Project Structure
|
## Project Structure
|
||||||
|
|
||||||
```
|
```
|
||||||
src/
|
|
||||||
├── agent/ # Core agent module
|
|
||||||
│ ├── context-window/ # Token-aware context management
|
|
||||||
│ ├── profile/ # Agent profile management
|
|
||||||
│ ├── session/ # Session persistence with compaction
|
|
||||||
│ ├── skills/ # Modular skill system
|
|
||||||
│ └── tools/ # Agent tools
|
|
||||||
│ └── web/ # Web fetch and search tools
|
|
||||||
├── gateway/ # WebSocket gateway for remote access
|
|
||||||
├── hub/ # Agent coordination hub
|
|
||||||
└── shared/ # Shared types
|
|
||||||
|
|
||||||
apps/
|
apps/
|
||||||
├── desktop/ # Electron desktop app (recommended)
|
├── cli/ # Command-line interface
|
||||||
└── web/ # Next.js web application
|
├── desktop/ # Electron desktop app (recommended)
|
||||||
|
├── gateway/ # NestJS WebSocket gateway
|
||||||
|
├── server/ # NestJS REST API server
|
||||||
|
├── web/ # Next.js web app
|
||||||
|
└── mobile/ # React Native mobile app
|
||||||
|
|
||||||
packages/
|
packages/
|
||||||
├── sdk/ # Gateway client SDK
|
├── core/ # Agent engine, hub, channels
|
||||||
├── store/ # Zustand state management
|
├── sdk/ # Gateway client SDK
|
||||||
└── ui/ # Shared UI components
|
├── ui/ # Shared UI components (Shadcn/Tailwind v4)
|
||||||
|
├── store/ # Zustand state management
|
||||||
|
├── hooks/ # React hooks
|
||||||
|
├── types/ # Shared TypeScript types
|
||||||
|
└── utils/ # Utility functions
|
||||||
|
|
||||||
skills/ # Bundled skills (commit, code-review)
|
skills/ # Bundled agent skills
|
||||||
```
|
```
|
||||||
|
|
||||||
## Getting Started
|
## Quick Start
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pnpm install
|
pnpm install
|
||||||
|
|
@ -42,149 +38,38 @@ pnpm install
|
||||||
### Development
|
### Development
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Desktop app (recommended for local development)
|
pnpm dev # Desktop app (standalone, no Gateway needed)
|
||||||
pnpm dev
|
pnpm dev:gateway # Gateway only
|
||||||
|
pnpm dev:web # Web app only
|
||||||
# Web app (for browser-based access)
|
pnpm dev:all # Gateway + Web
|
||||||
pnpm dev:web # Start Web app on :3000
|
|
||||||
|
|
||||||
# Gateway (for remote/mobile clients)
|
|
||||||
pnpm dev:gateway # Start Gateway on :3000
|
|
||||||
pnpm dev:all # Start both Gateway and Web app
|
|
||||||
```
|
```
|
||||||
|
|
||||||
The Desktop app runs a standalone Hub with embedded Agent Engine - no Gateway required for local use.
|
### Local Full-Stack Development
|
||||||
|
|
||||||
### Environment Configuration
|
`pnpm dev:local` starts the entire stack locally (Gateway + Desktop + Web) with isolated data directories, useful for end-to-end development and testing.
|
||||||
|
|
||||||
**Desktop** (`apps/desktop/.env.*`):
|
**Setup:**
|
||||||
|
|
||||||
| Variable | Description |
|
1. Copy `.env.example` to `.env` at the repo root
|
||||||
|----------|-------------|
|
2. Fill in `TELEGRAM_BOT_TOKEN` (get from [@BotFather](https://t.me/BotFather))
|
||||||
| `MAIN_VITE_GATEWAY_URL` | WebSocket Gateway URL for remote device pairing |
|
3. Run `pnpm dev:local`
|
||||||
| `MAIN_VITE_WEB_URL` | Web app URL for OAuth login redirect |
|
|
||||||
|
|
||||||
**Web** (`apps/web/next.config.ts`):
|
**What it starts:**
|
||||||
|
|
||||||
| Variable | Description |
|
| Service | Address | Notes |
|
||||||
|----------|-------------|
|
|---------|---------|-------|
|
||||||
| `API_URL` | Backend API URL (default: `https://api-dev.copilothub.ai`) |
|
| Gateway | `http://localhost:4000` | Telegram long-polling mode |
|
||||||
|
| Web | `http://localhost:3000` | OAuth login flow |
|
||||||
|
| Desktop | — | Connects to local Gateway + Web |
|
||||||
|
|
||||||
**Build for different environments:**
|
**Data isolation:** All data goes to `~/.super-multica-dev` and `~/Documents/Multica-dev`, separate from production `~/.super-multica`.
|
||||||
|
|
||||||
|
**Related commands:**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Desktop
|
pnpm dev:local:archive # Archive dev data and start fresh
|
||||||
pnpm --filter @multica/desktop build # Production (.env.production)
|
|
||||||
pnpm --filter @multica/desktop build:staging # Staging (.env.staging)
|
|
||||||
|
|
||||||
# Web (Vercel)
|
|
||||||
# Set API_URL in Vercel Dashboard → Settings → Environment Variables
|
|
||||||
```
|
```
|
||||||
|
|
||||||
See `apps/desktop/.env.example` and `apps/web/.env.example` for details.
|
|
||||||
|
|
||||||
### Monorepo Development
|
|
||||||
|
|
||||||
| Command | Purpose |
|
|
||||||
|---------|---------|
|
|
||||||
| `pnpm dev` | Full dev mode — watches `core`, `types`, `utils` packages |
|
|
||||||
| `pnpm dev:desktop` | Desktop only — skip package watching |
|
|
||||||
|
|
||||||
**When modifying packages:**
|
|
||||||
|
|
||||||
1. Edit code in `packages/core`, `packages/types`, or `packages/utils`
|
|
||||||
2. Terminal shows `[core] ESM ⚡️ Build success` (~100ms)
|
|
||||||
3. Restart Desktop to apply changes (Ctrl+C, then `pnpm dev`)
|
|
||||||
|
|
||||||
> **Why restart?** Electron main process does not support hot reload — this is an Electron limitation, not ours.
|
|
||||||
|
|
||||||
### Credentials
|
|
||||||
|
|
||||||
```bash
|
|
||||||
multica credentials init
|
|
||||||
```
|
|
||||||
|
|
||||||
Creates:
|
|
||||||
- `~/.super-multica/credentials.json5` — LLM providers + tools
|
|
||||||
- `~/.super-multica/skills.env.json5` — skill/plugin API keys
|
|
||||||
|
|
||||||
Example `credentials.json5`:
|
|
||||||
|
|
||||||
```json5
|
|
||||||
{
|
|
||||||
version: 1,
|
|
||||||
llm: {
|
|
||||||
provider: "openai",
|
|
||||||
providers: {
|
|
||||||
openai: { apiKey: "sk-xxx", model: "gpt-4o" }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
tools: {
|
|
||||||
brave: { apiKey: "brv-..." }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### LLM Providers
|
|
||||||
|
|
||||||
**OAuth Providers** (external CLI login):
|
|
||||||
- `claude-code` — requires `claude login`
|
|
||||||
- `openai-codex` — requires `codex login`
|
|
||||||
|
|
||||||
**API Key Providers** (configure in `credentials.json5`):
|
|
||||||
- `anthropic`, `openai`, `kimi-coding`, `google`, `groq`, `mistral`, `xai`, `openrouter`
|
|
||||||
|
|
||||||
Check status: `/provider` in interactive mode
|
|
||||||
|
|
||||||
## CLI
|
|
||||||
|
|
||||||
```bash
|
|
||||||
multica # Interactive mode
|
|
||||||
multica run "prompt" # Single prompt
|
|
||||||
multica chat --profile my-agent # Use profile
|
|
||||||
multica --session abc123 # Continue session
|
|
||||||
multica session list # List sessions
|
|
||||||
multica profile list # List profiles
|
|
||||||
multica skills list # List skills
|
|
||||||
multica help # Show help
|
|
||||||
```
|
|
||||||
|
|
||||||
Short alias: `mu`
|
|
||||||
|
|
||||||
## Sessions
|
|
||||||
|
|
||||||
Sessions persist to `~/.super-multica/sessions/<id>/` with JSONL message history and JSON metadata. Context windows are automatically managed with token-aware compaction.
|
|
||||||
|
|
||||||
## Profiles
|
|
||||||
|
|
||||||
Profiles define agent identity, personality, and memory in `~/.super-multica/agent-profiles/<id>/`.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
multica profile new my-agent # Create profile
|
|
||||||
multica profile list # List all
|
|
||||||
multica profile edit my-agent # Open in file manager
|
|
||||||
```
|
|
||||||
|
|
||||||
Profile files: `soul.md`, `user.md`, `workspace.md`, `memory.md`, `memory/*.md`
|
|
||||||
|
|
||||||
## Skills
|
|
||||||
|
|
||||||
Skills extend agent functionality via `SKILL.md` files. See [Skills Documentation](./src/agent/skills/README.md).
|
|
||||||
|
|
||||||
```bash
|
|
||||||
multica skills list # List skills
|
|
||||||
multica skills add owner/repo # Install from GitHub
|
|
||||||
multica skills status # Check status
|
|
||||||
```
|
|
||||||
|
|
||||||
Built-in: `commit`, `code-review`, `skill-creator`
|
|
||||||
|
|
||||||
## Tools
|
|
||||||
|
|
||||||
Available tools: `read`, `write`, `edit`, `glob`, `exec`, `process`, `web_fetch`, `web_search`, `memory_search`, `sessions_spawn`
|
|
||||||
|
|
||||||
See [Tools Documentation](./src/agent/tools/README.md) for details.
|
|
||||||
|
|
||||||
## Architecture
|
## Architecture
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
@ -202,52 +87,13 @@ Web/Mobile Clients
|
||||||
- **Gateway**: WebSocket server for remote clients
|
- **Gateway**: WebSocket server for remote clients
|
||||||
- **Hub**: Agent lifecycle and event distribution
|
- **Hub**: Agent lifecycle and event distribution
|
||||||
|
|
||||||
## Time
|
## Documentation
|
||||||
|
|
||||||
Super Multica now uses **message-level timestamp injection** for time awareness.
|
| Topic | Link |
|
||||||
Instead of placing dynamic time text in the system prompt, user turns are stamped at runtime.
|
|-------|------|
|
||||||
|
| Development guide | [docs/development.md](./docs/development.md) |
|
||||||
```mermaid
|
| Credentials & LLM providers | [docs/credentials.md](./docs/credentials.md) |
|
||||||
flowchart TD
|
| CLI usage | [docs/cli.md](./docs/cli.md) |
|
||||||
A[Incoming turn] --> B{Entry point}
|
| Skills & tools | [docs/skills-and-tools.md](./docs/skills-and-tools.md) |
|
||||||
B -->|Desktop/Gateway/Cron/Subagent| C[AsyncAgent.write]
|
| Time injection design | [docs/time-injection.md](./docs/time-injection.md) |
|
||||||
B -->|Heartbeat poll| D[AsyncAgent.write injectTimestamp=false]
|
| Package management | [docs/package-management.md](./docs/package-management.md) |
|
||||||
C --> E{Already stamped or has 'Current time:'?}
|
|
||||||
E -->|Yes| F[Keep original message]
|
|
||||||
E -->|No| G[Prefix: [DOW YYYY-MM-DD HH:mm TZ]]
|
|
||||||
D --> H[Keep original heartbeat prompt]
|
|
||||||
F --> I[Agent.run]
|
|
||||||
G --> I
|
|
||||||
H --> I
|
|
||||||
I --> J[LLM receives final turn text]
|
|
||||||
```
|
|
||||||
|
|
||||||
### Injection Matrix
|
|
||||||
|
|
||||||
| Path | Runtime call | Timestamp injected? | Notes |
|
|
||||||
| --- | --- | --- | --- |
|
|
||||||
| Desktop direct chat | `agent.write(content)` | Yes | Default behavior |
|
|
||||||
| Gateway/remote chat | `agent.write(content)` | Yes | Same entry path as desktop |
|
|
||||||
| `sessions_spawn` child task | `childAgent.write(task)` | Yes | Child turn gets current time context |
|
|
||||||
| Cron `agent-turn` payload | `agent.write(cronMessage)` | Yes (guarded) | Skips if message already carries `Current time:` |
|
|
||||||
| Heartbeat runner | `agent.write(prompt, { injectTimestamp: false })` | No | Prevents heartbeat prompt matching from breaking |
|
|
||||||
| Internal orchestration | `writeInternal(...)` | No | Uses separate internal run path |
|
|
||||||
|
|
||||||
### Why this design
|
|
||||||
|
|
||||||
- Keeps system prompt cache-stable (no per-turn date churn in system prompt text)
|
|
||||||
- Gives the model an explicit "now" reference on each user turn
|
|
||||||
- Uses guardrails to avoid double-stamping and heartbeat regressions
|
|
||||||
|
|
||||||
## Scripts
|
|
||||||
|
|
||||||
```bash
|
|
||||||
pnpm dev # Desktop app (recommended)
|
|
||||||
pnpm dev:gateway # Gateway only
|
|
||||||
pnpm dev:web # Web app only
|
|
||||||
pnpm dev:all # Gateway + Web
|
|
||||||
|
|
||||||
pnpm build # Production build
|
|
||||||
pnpm typecheck # Type check
|
|
||||||
pnpm test # Run tests
|
|
||||||
```
|
|
||||||
|
|
|
||||||
30
docs/cli.md
Normal file
30
docs/cli.md
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
# CLI
|
||||||
|
|
||||||
|
```bash
|
||||||
|
multica # Interactive mode
|
||||||
|
multica run "prompt" # Single prompt
|
||||||
|
multica chat --profile my-agent # Use profile
|
||||||
|
multica --session abc123 # Continue session
|
||||||
|
multica session list # List sessions
|
||||||
|
multica profile list # List profiles
|
||||||
|
multica skills list # List skills
|
||||||
|
multica help # Show help
|
||||||
|
```
|
||||||
|
|
||||||
|
Short alias: `mu`
|
||||||
|
|
||||||
|
## Sessions
|
||||||
|
|
||||||
|
Sessions persist to `~/.super-multica/sessions/<id>/` with JSONL message history and JSON metadata. Context windows are automatically managed with token-aware compaction.
|
||||||
|
|
||||||
|
## Profiles
|
||||||
|
|
||||||
|
Profiles define agent identity, personality, and memory in `~/.super-multica/agent-profiles/<id>/`.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
multica profile new my-agent # Create profile
|
||||||
|
multica profile list # List all
|
||||||
|
multica profile edit my-agent # Open in file manager
|
||||||
|
```
|
||||||
|
|
||||||
|
Profile files: `soul.md`, `user.md`, `workspace.md`, `memory.md`, `memory/*.md`
|
||||||
39
docs/credentials.md
Normal file
39
docs/credentials.md
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
# Credentials & LLM Providers
|
||||||
|
|
||||||
|
## Setup
|
||||||
|
|
||||||
|
```bash
|
||||||
|
multica credentials init
|
||||||
|
```
|
||||||
|
|
||||||
|
Creates:
|
||||||
|
- `~/.super-multica/credentials.json5` — LLM providers + tools
|
||||||
|
- `~/.super-multica/skills.env.json5` — skill/plugin API keys
|
||||||
|
|
||||||
|
Example `credentials.json5`:
|
||||||
|
|
||||||
|
```json5
|
||||||
|
{
|
||||||
|
version: 1,
|
||||||
|
llm: {
|
||||||
|
provider: "openai",
|
||||||
|
providers: {
|
||||||
|
openai: { apiKey: "sk-xxx", model: "gpt-4o" }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
tools: {
|
||||||
|
brave: { apiKey: "brv-..." }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## LLM Providers
|
||||||
|
|
||||||
|
**OAuth Providers** (external CLI login):
|
||||||
|
- `claude-code` — requires `claude login`
|
||||||
|
- `openai-codex` — requires `codex login`
|
||||||
|
|
||||||
|
**API Key Providers** (configure in `credentials.json5`):
|
||||||
|
- `anthropic`, `openai`, `kimi-coding`, `google`, `groq`, `mistral`, `xai`, `openrouter`
|
||||||
|
|
||||||
|
Check status: `/provider` in interactive mode
|
||||||
82
docs/development.md
Normal file
82
docs/development.md
Normal file
|
|
@ -0,0 +1,82 @@
|
||||||
|
# Development Guide
|
||||||
|
|
||||||
|
## Dev Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pnpm dev # Desktop app (recommended)
|
||||||
|
pnpm dev:desktop # Same as above
|
||||||
|
pnpm dev:gateway # Gateway only
|
||||||
|
pnpm dev:web # Web app only
|
||||||
|
pnpm dev:all # Gateway + Web
|
||||||
|
|
||||||
|
pnpm build # Production build (turbo-orchestrated)
|
||||||
|
pnpm typecheck # Type check all packages
|
||||||
|
pnpm test # Run tests
|
||||||
|
pnpm test:watch # Watch mode
|
||||||
|
pnpm test:coverage # With v8 coverage
|
||||||
|
```
|
||||||
|
|
||||||
|
## Local Full-Stack Development
|
||||||
|
|
||||||
|
`pnpm dev:local` starts Gateway + Desktop + Web together with isolated data directories.
|
||||||
|
|
||||||
|
**Setup:**
|
||||||
|
|
||||||
|
1. Copy `.env.example` to `.env` at the repo root
|
||||||
|
2. Fill in `TELEGRAM_BOT_TOKEN` (get from [@BotFather](https://t.me/BotFather))
|
||||||
|
3. Run `pnpm dev:local`
|
||||||
|
|
||||||
|
| Service | Address | Notes |
|
||||||
|
|---------|---------|-------|
|
||||||
|
| Gateway | `http://localhost:4000` | Telegram long-polling mode |
|
||||||
|
| Web | `http://localhost:3000` | OAuth login flow |
|
||||||
|
| Desktop | — | Connects to local Gateway + Web |
|
||||||
|
|
||||||
|
Data is stored in `~/.super-multica-dev` and `~/Documents/Multica-dev`, isolated from production.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pnpm dev:local:archive # Archive dev data and start fresh
|
||||||
|
```
|
||||||
|
|
||||||
|
## Environment Configuration
|
||||||
|
|
||||||
|
**Desktop** (`apps/desktop/.env.*`):
|
||||||
|
|
||||||
|
| Variable | Description |
|
||||||
|
|----------|-------------|
|
||||||
|
| `MAIN_VITE_GATEWAY_URL` | WebSocket Gateway URL for remote device pairing |
|
||||||
|
| `MAIN_VITE_WEB_URL` | Web app URL for OAuth login redirect |
|
||||||
|
|
||||||
|
**Web** (`apps/web/next.config.ts`):
|
||||||
|
|
||||||
|
| Variable | Description |
|
||||||
|
|----------|-------------|
|
||||||
|
| `API_URL` | Backend API URL (default: `https://api-dev.copilothub.ai`) |
|
||||||
|
|
||||||
|
**Build for different environments:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Desktop
|
||||||
|
pnpm --filter @multica/desktop build # Production (.env.production)
|
||||||
|
pnpm --filter @multica/desktop build:staging # Staging (.env.staging)
|
||||||
|
|
||||||
|
# Web (Vercel)
|
||||||
|
# Set API_URL in Vercel Dashboard → Settings → Environment Variables
|
||||||
|
```
|
||||||
|
|
||||||
|
See `apps/desktop/.env.example` for the full variable reference.
|
||||||
|
|
||||||
|
## Monorepo Workflow
|
||||||
|
|
||||||
|
| Command | Purpose |
|
||||||
|
|---------|---------|
|
||||||
|
| `pnpm dev` | Full dev mode — watches `core`, `types`, `utils` packages |
|
||||||
|
| `pnpm dev:desktop` | Desktop only — skip package watching |
|
||||||
|
|
||||||
|
**When modifying packages:**
|
||||||
|
|
||||||
|
1. Edit code in `packages/core`, `packages/types`, or `packages/utils`
|
||||||
|
2. Terminal shows `[core] ESM ⚡️ Build success` (~100ms)
|
||||||
|
3. Restart Desktop to apply changes (Ctrl+C, then `pnpm dev`)
|
||||||
|
|
||||||
|
> **Why restart?** Electron main process does not support hot reload — this is an Electron limitation, not ours.
|
||||||
19
docs/skills-and-tools.md
Normal file
19
docs/skills-and-tools.md
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
# Skills & Tools
|
||||||
|
|
||||||
|
## Skills
|
||||||
|
|
||||||
|
Skills extend agent functionality via `SKILL.md` files. See [Skills Documentation](../packages/core/src/agent/skills/README.md).
|
||||||
|
|
||||||
|
```bash
|
||||||
|
multica skills list # List skills
|
||||||
|
multica skills add owner/repo # Install from GitHub
|
||||||
|
multica skills status # Check status
|
||||||
|
```
|
||||||
|
|
||||||
|
Built-in: `commit`, `code-review`, `skill-creator`
|
||||||
|
|
||||||
|
## Tools
|
||||||
|
|
||||||
|
Available tools: `read`, `write`, `edit`, `glob`, `exec`, `process`, `web_fetch`, `web_search`, `memory_search`, `sessions_spawn`
|
||||||
|
|
||||||
|
See [Tools Documentation](../packages/core/src/agent/tools/README.md) for details.
|
||||||
36
docs/time-injection.md
Normal file
36
docs/time-injection.md
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
# Time Injection Design
|
||||||
|
|
||||||
|
Super Multica uses **message-level timestamp injection** for time awareness.
|
||||||
|
Instead of placing dynamic time text in the system prompt, user turns are stamped at runtime.
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
flowchart TD
|
||||||
|
A[Incoming turn] --> B{Entry point}
|
||||||
|
B -->|Desktop/Gateway/Cron/Subagent| C[AsyncAgent.write]
|
||||||
|
B -->|Heartbeat poll| D[AsyncAgent.write injectTimestamp=false]
|
||||||
|
C --> E{Already stamped or has 'Current time:'?}
|
||||||
|
E -->|Yes| F[Keep original message]
|
||||||
|
E -->|No| G[Prefix: [DOW YYYY-MM-DD HH:mm TZ]]
|
||||||
|
D --> H[Keep original heartbeat prompt]
|
||||||
|
F --> I[Agent.run]
|
||||||
|
G --> I
|
||||||
|
H --> I
|
||||||
|
I --> J[LLM receives final turn text]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Injection Matrix
|
||||||
|
|
||||||
|
| Path | Runtime call | Timestamp injected? | Notes |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| Desktop direct chat | `agent.write(content)` | Yes | Default behavior |
|
||||||
|
| Gateway/remote chat | `agent.write(content)` | Yes | Same entry path as desktop |
|
||||||
|
| `sessions_spawn` child task | `childAgent.write(task)` | Yes | Child turn gets current time context |
|
||||||
|
| Cron `agent-turn` payload | `agent.write(cronMessage)` | Yes (guarded) | Skips if message already carries `Current time:` |
|
||||||
|
| Heartbeat runner | `agent.write(prompt, { injectTimestamp: false })` | No | Prevents heartbeat prompt matching from breaking |
|
||||||
|
| Internal orchestration | `writeInternal(...)` | No | Uses separate internal run path |
|
||||||
|
|
||||||
|
## Why This Design
|
||||||
|
|
||||||
|
- Keeps system prompt cache-stable (no per-turn date churn in system prompt text)
|
||||||
|
- Gives the model an explicit "now" reference on each user turn
|
||||||
|
- Uses guardrails to avoid double-stamping and heartbeat regressions
|
||||||
Loading…
Add table
Add a link
Reference in a new issue