Limitations
What Jonaki does not do yet — stated plainly, because you will hit these.
Jonaki is 0.1.0. Here is what it does not do, so you can decide honestly
whether it fits.
Context management is windowing only
There is no summarization. When history exceeds context.maxTokens, the
oldest turns are dropped outright, not condensed. The earliest turns — often
where the user stated the actual task — go first.
Windowing is opt-in: with no maxTokens, the full history is sent and you get
a provider error rather than silent forgetting. Anything that must survive
belongs in instructions, which is never dropped.
Workaround: keep durable facts in the system prompt, or summarize yourself and start a fresh session.
Token counts are estimated
Roughly four characters per token. It is not a real tokenizer and will not match any provider's count exactly. Budget with headroom.
Cost is computed from a static per-model price table. Unknown models price at
zero, so usage.costUSD is a floor, not a guarantee. Check
usage.inputTokens if you need certainty that a call happened.
PII redaction is regex-based
redactPII catches common formats of email, phone, and card numbers. It will
miss variants and will occasionally match something that is not PII. It is a
safety net, not a compliance control. Do not rely on it for GDPR, PCI, or
HIPAA obligations.
Streaming is partial
text_delta streams from the provider's streaming API, but tool arguments
are not streamed incrementally — a tool call arrives whole, once complete.
If you want to show arguments filling in live, Jonaki cannot do that yet.
Replay matches by turn index
ReplayProvider serves recorded responses in the order they were captured. It
does not fuzzy-match the request against the recording. If your agent's
behaviour changes such that it makes model calls in a different order — while
still calling the same tools — the replay may pass while testing the wrong
thing.
Divergence is detected for two cases only: a tool the agent no longer exposes, and running out of recorded turns.
Stores are built for local development
FileStore.listRuns reads every run file, and neither it nor SQLiteStore is
tuned for a large corpus. There is no pagination cursor, no retention policy,
and no compaction. For production volume you will want your own Store
implementation against a real database — the interface is five methods.
No built-in retries or rate-limit handling
A model call that fails moves to the next rung of the fallback ladder; if there
is no next rung, the run fails with PROVIDER_ERROR. There is no exponential
backoff, no 429-aware waiting, and no request queue. Wrap run() yourself —
see the retry pattern.
No parallel tool execution
When a model requests several tools in one turn, Jonaki executes them one at a time, in order. This keeps the step machine deterministic and replayable, but it is slower than it could be for independent calls.
No multimodal input
Messages are text only. Images, audio, and files are not supported, even though
all three providers offer them. Message.content is a string.
No MCP support
There is no Model Context Protocol client. Tools are defined in code with Zod.
Approval resume is single-decision
resume(runId, store, { agent, approved }) applies one decision to the pending
call. If a turn requests several tools that each need approval, you approve
them one at a time across successive resumes.
Not yet published, not yet in CI
At 0.1.0 the package has not been published to npm, and the repository has no
CI workflow running the test suite on push. Both are next.
What it does do well
To be even-handed: replay testing, resumable state, the trace-as-data model, typed tools, and cross-provider fallback are all implemented, tested, and verified end to end against live APIs. The gaps above are real, but they are gaps at the edges rather than holes in the middle.