Skip to main content

Run the example agent

Try examples/jev-triage: Jev classifies a ticket, an LLM drafts a reply, and Harnest returns it. The routing decision supplies private context to the LLM. From the repository root, with a Harnest build that includes typed decisions:
Set JEV_LLM_MODEL to your LiteLLM provider/model identifier before a live run; the source default is the compile-only placeholder openai/your-model. The command above uses ollama_chat/qwen3.5:cloud, which requires a local Ollama service with that model and cloud access configured. You can also set JEV_LLM_API_BASE and JEV_LLM_API_KEY. For models that support it, JEV_LLM_REASONING_EFFORT="none" disables reasoning for this short drafting step; omit the variable to use the provider default. TYPESAFE_API_KEY also works and takes precedence when both are set. Ask “I was charged twice for the same order.” The public result contains the customer-facing reply; department, confidence, queue, and live/offline provenance remain internal. Billing and support require confidence of at least 0.8; other categories and evaluation failures recommend manual review. For a credential-free run or tests:
Offline mode uses a fixed billing decision and an “Offline fixture” reply without credentials. Sessions are in-memory. The agent drafts recommendations without changing accounts or sending tickets; live LLM failures return request errors.
Use the checkout’s Python runtime when your installed CLI predates typed decisions:
Export your key before serving, or prefix the last command with JEV_TRIAGE_OFFLINE=true.

Show or hide Jev results

The example hides decision events with this factory:
lifecycle/output.py
Jev still evaluates each ticket and the LLM still receives its recommendation. Callers receive the reply without a Jev result panel. Internal state remains available in Playground’s State inspector. Set OutputPolicy(decision_results=True) and recompile/restart to publish decision events alongside the unchanged reply schema. This works with any provider; see Output policy.

Add Jev to your own agent

Replace the quickstart’s offline fixture with Jev. Reuse its lib/triage.py and tools/triage_ticket.py; the adapter below supports Choice questions, including batches, probabilities, and confidence. This is an application-local integration using the TypeSafe Python SDK. It does not require a packaged Jev extension.
1

Add the SDK and credentials

Add typesafe-sdk==0.7.1 to your agent’s existing project.dependencies in pyproject.toml, then run:
Get a key from the TypeSafe console. The example pins jev-1.13.0; check the model catalog before changing it.
2

Add the provider adapter

lib/jev.py
Harnest checks that every requested question is answered and each choice belongs to its declared options.
3

Replace the fixture registration

Replace lifecycle/decisions.py with this resource. The async context manager closes the SDK client at application shutdown.
lifecycle/decisions.py
SDK retries are disabled explicitly. See the asynchronous client reference for timeout and retry options.
4

Try a ticket

Run harnest serve . and ask your agent:
Use triage_ticket to classify: “I was charged twice for the same order.”
The tool calls Jev through context.decisions.evaluate(...) and returns a route or review recommendation.
Tune the confidence threshold with your own tickets. Routing remains your application’s responsibility; returning billing_agent does not invoke it.
The adapter has been checked with SDK 0.7.1 and mocked HTTP responses. Live predictions require your TypeSafe credentials. Harnest’s private decision traces do not control SDK logging; avoid SDK debug logging of customer payloads.
To support other primitives, extend the adapter using TypeSafe’s question contracts: map Jev Score to ScoreResult and Jev Noul to PredicateResult, then declare those capabilities. The adapter above intentionally advertises only what it implements.