config: update channel_directory.json,config.yaml,tasks.py

This commit is contained in:
Alexander Whitestone
2026-03-27 16:00:29 -04:00
parent f9be0eb481
commit 3b34faeb17
3 changed files with 108 additions and 20 deletions

View File

@@ -1,5 +1,5 @@
{
"updated_at": "2026-03-27T14:55:51.294449",
"updated_at": "2026-03-27T15:20:52.948451",
"platforms": {
"discord": [
{

View File

@@ -1,7 +1,8 @@
model:
default: claude-opus-4-6
provider: anthropic
default: auto
provider: custom
context_length: 65536
base_url: http://localhost:8081/v1
toolsets:
- all
agent:
@@ -95,11 +96,13 @@ display:
compact: false
personality: ''
resume_display: full
busy_input_mode: interrupt
bell_on_complete: false
show_reasoning: false
streaming: false
show_cost: false
skin: timmy
tool_progress_command: false
tool_progress: all
privacy:
redact_pii: false
@@ -182,21 +185,17 @@ session_reset:
mode: none
idle_minutes: 0
custom_providers:
- name: Local Ollama
base_url: http://localhost:11434/v1
api_key: ollama
model: hermes4:14b
- name: Local llama.cpp
base_url: http://localhost:8081/v1
api_key: none
model: auto
- name: Google Gemini
base_url: https://generativelanguage.googleapis.com/v1beta/openai
api_key_env: GEMINI_API_KEY
model: gemini-2.5-pro
- name: Local (localhost:8081)
base_url: http://localhost:8081/v1
api_key: ollama
model: hermes4
system_prompt_suffix: "You are Timmy. Your soul is defined in SOUL.md \u2014 read\
\ it, live it.\nYou run locally on your owner's machine via Ollama. You never phone\
\ home.\nYou speak plainly. You prefer short sentences. Brevity is a kindness.\n\
\ it, live it.\nYou run locally on your owner's machine via llama.cpp. You never\
\ phone home.\nYou speak plainly. You prefer short sentences. Brevity is a kindness.\n\
When you don't know something, say so. Refusal over fabrication.\nSovereignty and\
\ service always.\n"
skills:

103
tasks.py
View File

@@ -28,11 +28,11 @@ HEARTBEAT_MODEL = "hermes4:14b"
FALLBACK_MODEL = "hermes3:8b"
def hermes_local(prompt, model=None, caller_tag=None):
"""Call a local Ollama model through the Hermes harness.
def hermes_local(prompt, model=None, caller_tag=None, toolsets=None):
"""Call a local model through the Hermes harness.
Uses provider="local-ollama" which routes through the custom_providers
entry in config.yaml → Ollama at localhost:11434.
Uses provider="local-llama.cpp" which routes through the custom_providers
entry in config.yaml → llama-server at localhost:8081.
Returns response text or None on failure.
Every call creates a Hermes session with telemetry.
"""
@@ -53,13 +53,16 @@ def hermes_local(prompt, model=None, caller_tag=None):
buf = io.StringIO()
err = io.StringIO()
with redirect_stdout(buf), redirect_stderr(err):
hermes_main(
kwargs = dict(
query=tagged,
model=_model,
provider="local-ollama",
provider="local-llama.cpp",
quiet=True,
)
if toolsets:
kwargs["toolsets"] = toolsets
with redirect_stdout(buf), redirect_stderr(err):
hermes_main(**kwargs)
output = buf.getvalue().strip()
# Strip session_id line from quiet output
lines = [l for l in output.split("\n") if not l.startswith("session_id:")]
@@ -98,6 +101,92 @@ def hermes_local(prompt, model=None, caller_tag=None):
os.chdir(old_cwd)
# ── Know Thy Father: Twitter Archive Ingestion ───────────────────────
ARCHIVE_DIR = TIMMY_HOME / "twitter-archive"
ARCHIVE_CHECKPOINT = ARCHIVE_DIR / "checkpoint.json"
ARCHIVE_LOCK = ARCHIVE_DIR / ".lock"
ARCHIVE_PROMPT = (
"You are Timmy. Resume your work on the Twitter archive. "
"Your workspace is ~/.timmy/twitter-archive/. "
"Read checkpoint.json and UNDERSTANDING.md first. "
"Then process the next batch. "
"You know the drill — read your own prior work, assess where you are, "
"process new data, update your understanding, reflect, and plan for "
"the next iteration."
)
ARCHIVE_SRC = (
"~/Downloads/twitter-2026-03-27-d4471cc6eb6703034d592f870933561ebee374d9d9b90c9b8923abff064afc1e/data"
)
ARCHIVE_FIRST_RUN_PROMPT = (
"You are Timmy. Your father Alexander's full Twitter archive is at: "
f"{ARCHIVE_SRC}/\n\n"
"Your workspace is ~/.timmy/twitter-archive/\n\n"
"STEP 1 — EXTRACTION (use terminal with python3, NOT read_file):\n"
"The .js files are too large for read_file but trivial for Python.\n"
"Write a python3 script via terminal that:\n"
" - Opens tweets.js, strips everything before the first '[', json.loads the rest\n"
" - Separates originals (full_text does NOT start with 'RT @') from retweets\n"
" - Sorts both chronologically by created_at\n"
" - Writes extracted/tweets.jsonl and extracted/retweets.jsonl (one JSON per line)\n"
" - Writes extracted/manifest.json with counts, date range, source file\n"
"The whole file is 12MB. Python handles it in under a second.\n\n"
"STEP 2 — FIRST READ:\n"
"Read the first 50 lines of extracted/tweets.jsonl (your originals, chronological).\n"
"Read them carefully — this is your father talking.\n"
"Note his voice, humor, what he cares about, who he talks to, emotional tone, "
"recurring themes. Quote him directly when something stands out.\n\n"
"STEP 3 — WRITE:\n"
"Write notes/batch_001.md — your real observations, not a book report.\n"
"Create UNDERSTANDING.md — your living model of who Alexander is. "
"It starts now and you'll update it every batch.\n\n"
"STEP 4 — CHECKPOINT:\n"
"Write checkpoint.json: "
'{"data_source": "tweets", "next_offset": 50, "batches_completed": 1, '
'"phase": "discovery", "confidence": "<your honest assessment>", '
'"next_focus": "<what you want to look for next>", "understanding_version": 1}'
)
@huey.task()
@huey.lock_task("know-thy-father")
def know_thy_father():
"""Process one batch of Alexander's Twitter archive.
Single batch, no internal loop. Huey schedules the cadence.
Lock prevents overlapping runs. Timmy reads his own prior notes,
processes the next chunk, updates his understanding, and checkpoints.
"""
is_first_run = not ARCHIVE_CHECKPOINT.exists()
prompt = ARCHIVE_FIRST_RUN_PROMPT if is_first_run else ARCHIVE_PROMPT
response = hermes_local(
prompt=prompt,
caller_tag="know-thy-father",
toolsets="file,terminal",
)
if not response:
return {"status": "error", "reason": "hermes_local returned None"}
# Read checkpoint to report progress
try:
cp = json.loads(ARCHIVE_CHECKPOINT.read_text())
except Exception:
cp = {}
return {
"status": "ok",
"batch": cp.get("batches_completed", 0),
"phase": cp.get("phase", "unknown"),
"confidence": cp.get("confidence", "unknown"),
}
# ── Existing: Orchestration ──────────────────────────────────────────
@huey.periodic_task(crontab(minute="*/15"))