Commit Graph
5 Commits
Author SHA1 Message Date
mrcharles fc518c475e quota: z.ai credit-bucket back-pressure + resource gate + usage accounting (Redmine 490+491)
The loop now consults quota and host state before every dispatch and
DEFERS gated work with a logged reason instead of letting turns die at
the provider (the 2026-08-28 19:00 quota-wall failure mode, replayed as
a test). Adds internal/quota: 5h/weekly credit buckets (provider poll
when z.ai ships an endpoint - fake-server tested - else locally
estimated from the documented credit formula), TZ-aware peak window
(default 01:00-05:00 America/Chicago weekdays, matching the documented
z.ai peak Mon-Fri 14:00-18:00 Singapore), block/defer thresholds, a
read-only load/mem/disk/IO-PSI monitor, an optional redis shared-state
hop (stdlib RESP2 mini-client) so all instances of an account
coordinate, per-class token+credit accounting in loop.jsonl, and
`harness quota status|probe|gate`. Config: [quota] + [resources]
sections; README runbook covers the redis container and deploy-time
cgroup enforcement.

💘 Generated with Crush

Assisted-by: Crush:glm-5.2
2026-08-29 05:37:15 -05:00
mrcharles c54a5a4f82 config: [serve] section for the OpenAI-compatible front door
listen (default :8090, own port so it coexists with [events]), vkey_ref
(the bearer key OpenWebUI connections present; refs only, resolved at
startup), and an optional enabled_models subset of the catalog. Entries
must name a real servable model (mopac-<class> from [models.classes]) so
a typo fails at config load, not mid-request. Example file extended;
once/loop configs without [serve] stay valid.

💘 Generated with Crush

Assisted-by: Crush:glm-5.2
2026-08-29 01:10:35 -05:00
mrcharles c869ac1b06 config: keyproxy mpk refs, loop daemon knobs, redmine status map, gitea section
mpk: key refs resolve through the ukrrs/mopac-keyproxy hop ([keyproxy]
url + token_ref, POST /v1/resolve, short in-memory cache); env:/file:/
literal: refs keep working untouched, so the harness runs with or
without keyproxy up. [loop] gains poll_interval_secs + state_dir for the
self-host daemon; [redmine.status_map] (quoted TOML keys) drives status
transitions; [gitea] carries the optional REPORT-commit step, off by
default. All hosts live in harness.toml, none in code.

💘 Generated with Crush

Assisted-by: Crush:glm-5.2
2026-08-28 22:05:41 -05:00
mrcharles 164b14592b events: config surface for the webhook receiver
[events] listen/state_dir plus per-source secret refs (env:/file:/literal:)
for redmine, discourse and gitea webhooks. Defaults: :4100, state/events,
X-Redmine/X-Discourse-Webhook-Secret headers. Refs validate fail-fast; set
refs must be well-formed or config load names the [events.*] section.
2026-08-28 21:38:06 -05:00
mrcharles 62d3781d71 harness: single-shot conductor + CLI with MVP demo path
`harness once` runs one bounded iteration (intake -> routing -> bounded turn
-> REPORT) then exits, so callers chain it without a daemon. The bounded
turn loops request -> tool calls -> results up to max_rounds; gate denials
feed back to the model and are counted instead of failing the turn.
--dry-run prints the plan (task, resolved model, tool bounds) and makes zero
LLM calls; --demo runs the [demo] issue ("tell me about yourself" through
LiteLLM -> GLM self-description as the REPORT), the MVP acceptance bar.
Distinct exit codes for config/usage, intake, and llm failures. Ships
harness.toml.example (scope query, tier map, allow-lists); real configs are
gitignored. Loop tests run end-to-end against a scripted fake OpenAI server:
demo turn, dry-run zero-call, tool round-trip, denial counting, round limit,
and error-class mapping.

💘 Generated with Crush

Assisted-by: Crush:glm-5.2
2026-08-28 19:21:04 -05:00