final gaps: .gitattributes, .dockerignore, structured logger, clean stray files
This commit is contained in:
parent
be7354ee38
commit
e92eaeaefc
|
|
@ -0,0 +1,13 @@
|
||||||
|
node_modules/
|
||||||
|
.git/
|
||||||
|
.gitignore
|
||||||
|
.gitattributes
|
||||||
|
*.md
|
||||||
|
src/
|
||||||
|
tsconfig.json
|
||||||
|
vitest.config.ts
|
||||||
|
.env
|
||||||
|
.env.local
|
||||||
|
LOGS/
|
||||||
|
TEMP/
|
||||||
|
.familiar-test
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
# Auto-detect text files and normalize to LF
|
||||||
|
* text=auto
|
||||||
42
CLAUDE.md
42
CLAUDE.md
|
|
@ -1,42 +0,0 @@
|
||||||
# fable-agent — Project Instructions
|
|
||||||
|
|
||||||
## Project
|
|
||||||
TypeScript self-improving agent system implementing the Fable 5 compound stack. All model calls route through the local proxy at `localhost:18901`.
|
|
||||||
|
|
||||||
## Build / Test
|
|
||||||
- `npm run build`
|
|
||||||
- `node dist/index.js demo`
|
|
||||||
- `npx tsc --noEmit`
|
|
||||||
|
|
||||||
## Model Routing
|
|
||||||
|
|
||||||
All model calls route through `http://localhost:18901/v1`.
|
|
||||||
|
|
||||||
### Working verified routes
|
|
||||||
| Alias | Provider | Notes |
|
|
||||||
|-------|----------|-------|
|
|
||||||
| `go-dsv4-flash` | Go API | Primary cheap/fast route |
|
|
||||||
| `claude-sonnet-4-6` | Zen API | Code review, bounded subtasks |
|
|
||||||
| `fi-gemini` | Free provider | Gemini free tier |
|
|
||||||
| `fi-mistral` | Free provider | Mistral free tier |
|
|
||||||
| `nemotron-3-ultra-free` | Free provider | Nvidia free tier |
|
|
||||||
|
|
||||||
### Provider groups
|
|
||||||
- **Go API**: `go-*` models (12 models, $10/mo flat)
|
|
||||||
- **Zen API**: `claude-*`, `gpt-*`, `gemini-*`, etc.
|
|
||||||
- **CrofAI**: fallback provider on 429
|
|
||||||
- **Free providers (`fi-*`)**: free-tier models
|
|
||||||
|
|
||||||
The proxy currently exposes 58 model aliases across these providers. The model router tracks 35 models with real pricing.
|
|
||||||
|
|
||||||
## Proxy Configuration
|
|
||||||
- Proxy config: `~/.config/grok-proxy.cjs`
|
|
||||||
- Provider keys: `~/.config/infer/keys.env`, `~/.config/fi/keys.env`
|
|
||||||
- Restart proxy after config changes.
|
|
||||||
|
|
||||||
## Project Structure
|
|
||||||
- CLI: `dist/index.js`
|
|
||||||
- Source: `src/`
|
|
||||||
- State: `~/.fable-agent/`
|
|
||||||
- Skills: `SKILLS/`
|
|
||||||
- Phases: `PHASES/`
|
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
/**
|
||||||
|
* Structured logger — replaces console.log across the system.
|
||||||
|
* Writes JSONL logs for machine parsing + human-readable terminal output.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import * as fs from "node:fs";
|
||||||
|
import * as path from "node:path";
|
||||||
|
|
||||||
|
export type LogLevel = "debug" | "info" | "warn" | "error";
|
||||||
|
|
||||||
|
const LOG_DIR = path.join(
|
||||||
|
process.env.FABLE_DATA_DIR || process.env.HOME || process.env.USERPROFILE || ".", ".fable-agent", "logs"
|
||||||
|
);
|
||||||
|
|
||||||
|
const COLORS: Record<LogLevel, string> = {
|
||||||
|
debug: "\x1b[90m", // gray
|
||||||
|
info: "\x1b[36m", // cyan
|
||||||
|
warn: "\x1b[33m", // yellow
|
||||||
|
error: "\x1b[31m", // red
|
||||||
|
};
|
||||||
|
const RESET = "\x1b[0m";
|
||||||
|
|
||||||
|
class Logger {
|
||||||
|
private logFile: string;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
try {
|
||||||
|
if (!fs.existsSync(LOG_DIR)) fs.mkdirSync(LOG_DIR, { recursive: true });
|
||||||
|
} catch {}
|
||||||
|
this.logFile = path.join(LOG_DIR, `${new Date().toISOString().slice(0, 10)}.jsonl`);
|
||||||
|
}
|
||||||
|
|
||||||
|
private write(level: LogLevel, message: string, data?: Record<string, unknown>): void {
|
||||||
|
const entry = {
|
||||||
|
timestamp: new Date().toISOString(),
|
||||||
|
level,
|
||||||
|
message,
|
||||||
|
...data,
|
||||||
|
};
|
||||||
|
|
||||||
|
// JSONL for machine parsing
|
||||||
|
try {
|
||||||
|
fs.appendFileSync(this.logFile, JSON.stringify(entry) + "\n", "utf-8");
|
||||||
|
} catch {}
|
||||||
|
|
||||||
|
// Colored terminal output
|
||||||
|
const prefix = level === "error" ? "✗" : level === "warn" ? "⚠" : level === "debug" ? "·" : "✓";
|
||||||
|
if (level !== "debug" || process.env.FABLE_DEBUG) {
|
||||||
|
process.stdout.write(`${COLORS[level]}${prefix}${RESET} ${message}\n`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
info(message: string, data?: Record<string, unknown>): void { this.write("info", message, data); }
|
||||||
|
warn(message: string, data?: Record<string, unknown>): void { this.write("warn", message, data); }
|
||||||
|
error(message: string, data?: Record<string, unknown>): void { this.write("error", message, data); }
|
||||||
|
debug(message: string, data?: Record<string, unknown>): void { this.write("debug", message, data); }
|
||||||
|
}
|
||||||
|
|
||||||
|
export const logger = new Logger();
|
||||||
Loading…
Reference in New Issue