@jev-harness/pi
v0.5.0
Published
Pi extension packaging TypeSafe Jev (System One) judgments: tools, skill routing, and verbatim compaction.
Maintainers
Readme
@jev-harness/pi
Pi extension packaging TypeSafe Jev (System One) judgments: five fail-open
tools, an append-only skill-router advisory, and Jev-driven verbatim
compaction. Mirrors the OMP adapter; Pi and OMP share the same extension
factory shape (export default function (pi: ExtensionAPI)).
Pi manifest field
Pi discovers extensions through the pi.extensions
array in package.json — a list of paths (files or directories) resolved
relative to the package root by Pi's extension loader
(readPiManifest reads the pi object; resolveExtensionEntries
resolves each entry; verified against
@earendil-works/[email protected] sources). This package declares:
{ "pi": { "extensions": ["./src/extension.ts"] } }The reference repo points at a directory (["./extensions"]); this package
points at the entry file instead so the jiti module import Pi performs per
loadExtensionModule resolves unambiguously (no directory-index guessing).
Source: https://github.com/joelhooks/pi-fast-jev-compaction —
package.json
("pi": { "extensions": ["./extensions"] }) and
extensions/pi-fast-jev-compaction.ts
(default-export factory, session_before_compact returning
{ compaction: { summary, firstKeptEntryId, tokensBefore, details } }).
Install
From the Pi agent directory (global install):
# from a checkout of jev-harness
pi install ./packages/pi
# or by git URL once published
pi install git:github.com/Talya1412/jev-harnessFor one run without installing:
pi -e ./packages/piRequires Node >= 20 (Pi itself targets Node 24.18; see the reference repo).
Environment
| Variable | Meaning | Default |
| ------------------------ | ------------------------------------------------------------------------------------------------------- | ---------------------------------------- |
| TYPESAFE_API_KEY | TypeSafe API key. Read on every call, never logged. All tools/hooks fail open without it. | (none — required) |
| TYPESAFE_BASE_URL | Jev endpoint override. | core default (https://api.typesafe.ai) |
| TYPESAFE_DEFAULT_MODEL | Jev model override. | core default (jev-latest) |
| JEV_TIMEOUT_MS | Per-request timeout in ms. | 15000 |
| OMP_JEV_KEEP_THRESHOLD | Shared with the OMP adapter: noul keep-scores below this on both call and result mark a pair stale. | 0.2 |
export TYPESAFE_API_KEY='...'Tools
All five tools fail open: Jev errors resolve to advisory text, never throw.
jev_ask— raw judgments over an arbitrary JSONstateplus aquestionsmap (noul/choice/score).jev_models— list Jev models available to the configured key.jev_route_skills— route a message to one skill (or none). Send skill descriptions, not bare names.jev_pick_tool— pick one tool (or none), with a confirmation flag for side-effecting choices. Does not execute anything.jev_browse_action— pick the next browser operation from a page snapshot. Does not execute anything.
Hooks
session_before_compact— collects assistant tool-call / tool-result pairs (bytoolCallId, capped at 40), asks twonoulquestions per pair (keep the call, keep the result), and returns verbatim compaction when at least one pair is stale on both scores:{ compaction: { summary, firstKeptEntryId, tokensBefore, details } }. Returnsundefined(Pi falls back to built-in summary) when there is no key, no complete pairs, nothing stale, or Jev fails.input— fire-and-forget skill-router advisory. Notifies when a registered tool looks relevant; never blocks, transforms, or handles input.
Assumptions
- No destructive
tool_callgate: Pi'stool_callevent only supports fail-closed blocking ({ block: true }), and per instructions a risky gate was omitted rather than shipped.jev_pick_toolexposes the confirmation signal to the model instead. - Pi's
CompactionResulthas noshortSummaryfield (verified in@earendil-works/[email protected]:{ summary, firstKeptEntryId, tokensBefore, estimatedTokensAfter?, usage?, details? }), so the OMP-adaptershortSummaryis folded intodetails: { shortSummary, threshold, decisions }. inputusespi.getAllTools()(ExtensionAPI method) as the routing candidate set; the async judgment notifies viactx.ui.notify.
