pi-actualyze3.0.0
Native Actualyze model provider for pi with automatic model discovery
Untested on omp
This is a pi package. No one has reported whether it works on omp yet. If you try it, add your result below.
Reports 0
No reports yet.
Readme
pi-actualyze
A native pi provider package for
Actualyze, the AI platform built by Actualyze AI.
Log in with an Actualyze API key, and the provider discovers every model
advertised by Actualyze automatically. No models.json, copied model
IDs, or per-model configuration required.
Quick Start
Install from npm:
pi install npm:pi-actualyze
Start pi and authenticate:
/login actualyze
Enter your Actualyze API key when asked. Login connects to the production
endpoint, https://app.actualyze.ai, and does not ask about environments.
Login validates the credentials, downloads the complete model catalog, and makes the discovered models available immediately. Open pi's model selector:
/model
Select any model under the actualyze provider.
Upgrading from 2.x? A key set only through ACTUALYZE_API_KEY now needs an
endpoint as well (a target or base URL) or a saved login; see
Upgrading to 3.0.
The Problem
An Actualyze deployment can expose a changing catalog of direct models, routed
aliases, and workload-oriented model groups. Hard-coding that catalog in pi would
be incomplete as soon as Actualyze adds, removes, or updates an entry. Requiring
users to copy each model into models.json would also duplicate metadata that the
Actualyze API already publishes, including context limits, output limits,
modalities, reasoning support, and caching information.
pi-actualyze makes Actualyze a native dynamic pi provider. The API key is the only user configuration. The package queries Actualyze directly, validates the complete catalog as one atomic generation, converts every valid entry into a pi model, and routes inference through pi's native OpenAI Chat Completions implementation.
How It Works
The provider owns the complete lifecycle:
Configuration:
/login actualyzeasks only for an API key and logs in to production (app) unless another endpoint is selected. A target label always maps to the fixed endpointhttps://<target>.actualyze.ai/openai/v1, and a launcher can name any other Actualyze environment withACTUALYZE_OPENAI_BASE_URL. A key from the environment is sent only to an endpoint the environment names.Credential validation: Before pi saves anything, the provider sends an authenticated
GET /modelsrequest through a guarded transport. Invalid credentials, malformed responses, and unsafe catalog entries fail the login.Automatic discovery: The OpenAI-style model list is authoritative for membership. Every unique, safely representable ID becomes a pi model. The provider does not filter entries by owner, price, or advisory capability flags.
Atomic publication: A generation is published only when the complete list validates. One malformed or duplicate entry rejects the new generation instead of silently presenting a partial catalog. An existing valid generation remains intact when refresh fails.
Endpoint-scoped persistence: Pi can restore a cached catalog on startup only when every cached model belongs to
actualyzeand points at the active endpoint's exact base URL. Switching endpoints discards mismatched cached and in-memory catalogs.Native inference: Requests use pi's OpenAI Chat Completions adapter with a conservative, explicit compatibility profile. Text, images, reasoning, streamed usage, function tools, and tool-result continuation use pi's normal model pipeline.
Routed aliases: Pi retains the requested Actualyze catalog ID as the model identity. If Actualyze reports the selected upstream model in stream chunks, pi records it separately as
responseModel.
Installation
npm (recommended)
pi install npm:pi-actualyze
To pin a version:
pi install npm:pi-actualyze@3.0.0
Uninstall with:
pi remove npm:pi-actualyze
GitHub
To track the repository directly instead of npm releases:
pi install git:github.com/actualyze-ai/pi-actualyze
To pin a tag or commit:
pi install git:github.com/actualyze-ai/pi-actualyze@<tag-or-commit>
Git installations are managed by pi. Use pi update --extensions to reconcile
unpinned package installations and pi remove to uninstall:
pi remove git:github.com/actualyze-ai/pi-actualyze
Local checkout
For development, install the checkout by absolute path:
git clone git@github.com:actualyze-ai/pi-actualyze.git
cd pi-actualyze
npm install
npm run check
pi install "$PWD"
A local-path installation references the directory in place. Source edits are picked up the next time pi starts; no copy is made into pi's package directory.
To try the extension for one process without changing pi settings:
pi --no-extensions -e .
Requirements
- pi
1.0.0or newer - Node.js
22.19.0or newer for development - Network access to
app.actualyze.ai(or the selected target or base URL) - An Actualyze API key valid for that endpoint
Configuration
Interactive Login
Run:
/login actualyze
The flow asks for one value, your API key. The prompt names the host it will authenticate against:
Actualyze API key for app.actualyze.ai
Login fetches and validates the catalog before returning the credential to pi. A failed validation stores nothing.
Selecting Another Environment
Most users never need this section. To use a target other than production,
select it before logging in with either the --actualyze-target flag or the
ACTUALYZE_TARGET environment variable:
pi --actualyze-target staging
/login actualyze
The endpoint is resolved in this order:
| Priority | Source | Example |
|---|---|---|
| 1 | Saved credential's endpoint | set by the last /login |
| 2 | The target with ACTUALYZE_OPENAI_BASE_URL (they must agree) |
pi --actualyze-target staging |
| 3 | Production (app), for /login only |
/login actualyze |
The target is the --actualyze-target flag when it is set, else
ACTUALYZE_TARGET. A target or ACTUALYZE_OPENAI_BASE_URL alone names the
endpoint (see below for the base URL).
They can both be set only when they name the same endpoint; when they disagree,
the provider stays unavailable and sends nothing.
The target - selects no *.actualyze.ai target, which leaves the choice to
ACTUALYZE_OPENAI_BASE_URL. Set it as ACTUALYZE_TARGET=- or
--actualyze-target=-: pi reads a - after a space as an option of its own and
exits with Unknown option: -. A label works either way, as in
--actualyze-target staging.
Production is a default only for /login, whose prompt names the host you are
entering a key for. A key from ACTUALYZE_API_KEY is never sent to production
unless a target or base URL names it: with only the key set, the provider is
unavailable.
At login there is no saved credential yet, so the flag, the environment
variables, or the production default decide. A saved credential keeps the
endpoint it was created with; to move a saved login to another environment,
start pi with the flag and run /login actualyze again.
The target staging resolves only to:
https://staging.actualyze.ai/openai/v1
Target labels may contain ASCII letters, digits, and internal hyphens. The provider rejects dots, schemes, paths, ports, whitespace, Unicode lookalikes, control characters, and labels longer than 63 characters. Uppercase ASCII letters are normalized to lowercase. Login rejects an invalid label before asking for the API key.
Another Actualyze Environment by URL
A tool that launches pi for one run against an Actualyze environment outside
*.actualyze.ai sets ACTUALYZE_OPENAI_BASE_URL to that environment's OpenAI
base URL, for example https://actualyze.example.com/openai/v1, together with
the run's key in ACTUALYZE_API_KEY. The provider then discovers models and
sends inference there, and nowhere else.
The value must be an absolute https URL without a user name, password, query,
or fragment. Plain http is accepted only for localhost, 127.0.0.1, and
[::1], such as a local Actualyze stack. A value that breaks these rules makes
the provider unavailable instead of being ignored, because the key set beside it
belongs to that endpoint. /login actualyze uses the variable too when it is
set, and the saved credential keeps the base URL.
Plain http requests connect directly and never through a proxy, whatever
HTTP_PROXY or pi's httpProxy setting says. A request to localhost fails
when the name resolves to any address that is not loopback, for example through
a hosts-file entry.
Environment Configuration
For non-interactive authentication, set the API key and the endpoint before starting pi:
export ACTUALYZE_API_KEY='your-api-key'
export ACTUALYZE_TARGET=app
pi
| Variable | Required | Description |
|---|---|---|
ACTUALYZE_API_KEY |
Yes | API key for the endpoint |
ACTUALYZE_TARGET |
Unless ACTUALYZE_OPENAI_BASE_URL is set |
DNS label, such as app for production; - selects none; --actualyze-target wins |
ACTUALYZE_OPENAI_BASE_URL |
Unless a target is set | Full OpenAI base URL of an Actualyze environment |
Stored credential fields take precedence over the corresponding environment variables. Invalid ambient configuration is treated as unavailable authentication. Invalid stored configuration also makes the provider unavailable at availability check time (so one corrupt credential cannot blank the model picker for every provider); the underlying validation error surfaces when a request or refresh resolves the credential.
Credential Storage and Logout
Pi stores the API key in its provider credential store and stores only the
non-secret endpoint in credential metadata: the target, or
ACTUALYZE_OPENAI_BASE_URL for a login made with that variable set. A
production login looks like this:
{
"type": "api_key",
"key": "<secret>",
"env": {
"ACTUALYZE_TARGET": "app"
}
}
Remove the saved credential with:
/logout actualyze
After logout, Actualyze models are unavailable even if an in-memory catalog still exists. Environment variables can still provide authentication if they remain set.
Automatic Model Discovery
The provider requests:
GET <base-url>/models
Authorization: Bearer <api-key>
The base URL is https://<target>.actualyze.ai/openai/v1 for a target, or the
value of ACTUALYZE_OPENAI_BASE_URL.
The list response, not a bundled static file, is authoritative for model membership. The provider registers exactly one model for every unique valid list ID.
Catalog Validation
A new generation is rejected atomically when:
- the response is not JSON;
- the envelope is not an object with a
dataarray; - a claimed model lacks a non-empty string ID;
- model IDs are duplicated;
- an ID is a dot segment, oversized, not URL-encodable, or contains unsafe terminal or bidirectional control characters; or
- required catalog structure cannot be represented safely.
The provider does not request individual model details. The list endpoint already advertises the metadata pi needs, and a single request keeps refresh within pi's interactive deadline.
Refresh and Cache Behavior
- Login installs the validated catalog in memory immediately.
- Normal refresh fetches a complete new
/modelsgeneration. - The aggregate catalog request budget is 10 seconds.
- Only rate limits and transient 5xx responses are retried.
- Valid
Retry-Aftervalues are honored only when they fit the remaining budget. - Cancellation stops active fetches, response reads, and retry delays.
- Failed refresh never replaces a previously accepted generation.
- A cached generation is restored only for the exact active base URL.
- pi resolves
--provider actualyze --model <id>(or--model actualyze/<id>) before its own network refresh. When the environment names the key and the endpoint, and pi's cache has no catalog for that endpoint listing<id>, a run started that way fetches the catalog while pi loads the extension. The first run then works with nothing cached, and the catalog is stored for later runs. Until the fetch ends, pi waits before it starts, for at most the 10-second catalog budget when the endpoint does not answer. A model pattern that is not an exact ID, such as one with a:highthinking suffix, always fetches.--offlineskips the fetch. - Same-target key rotation persists the newly validated login catalog instead of restoring the previous key's catalog.
Model Metadata
Actualyze model advertisements are mapped into pi as follows:
| Actualyze field | pi field | Behavior |
|---|---|---|
id |
id, name |
Preserved exactly after safety validation |
context_window |
contextWindow |
Preferred positive limit |
max_model_len |
contextWindow |
Fallback when context_window is absent |
max_output_tokens |
maxTokens |
Positive output limit |
modalities.input includes image |
input |
Enables image input |
capabilities.thinking |
reasoning |
Enables reasoning when true |
capabilities.thinking_adaptive |
reasoning |
Also enables reasoning when true |
cost |
cost |
Mapped as an estimate; see below |
Missing Limits
Pi requires numeric context and output limits. When Actualyze advertises no positive value, the provider uses compatibility sentinels:
- context window:
128,000tokens - maximum output:
16,384tokens
These values satisfy pi's model schema; they are not claims about an undisclosed upstream limit.
When a model's real limits are smaller, pi compacts the conversation only after
a request fails with a context-overflow error, and it keeps asking for 16,384
output tokens. A model with a small context window or output limit can keep
failing. Set the real limits with pi's modelOverrides in models.json, which
lives in pi's agent directory (~/.pi/agent/models.json by default):
{
"providers": {
"actualyze": {
"modelOverrides": {
"<model id>": { "contextWindow": 32000, "maxTokens": 4096 }
}
}
}
}
Use the model id exactly as /model shows it. Overrides apply on top of the
discovered catalog and survive catalog refreshes. Only modelOverrides is
supported for Actualyze models; models entries are not (see
Security).
While pi has no Actualyze model list loaded, for example after switching to a
target that lists no models, a providers.actualyze entry in models.json makes
pi send a request for a model it already holds through its own OpenAI client
instead of this provider. Such a request still goes to the active endpoint with
the active key, but without the guarded transport, the endpoint checks, or the
attribution header. Load the list with /login actualyze or interactive pi
before relying on an override.
Pricing
Actualyze lists each model's cost in US dollars per million tokens, the unit pi uses, and the provider maps it into pi's cost fields:
cost.inputandcost.outputbecome pi's input and output rates.cost.cache_readandcost.cache_writebecome pi's cache rates. When the listing omits one, the provider estimates it from the input rate: the input rate itself for cache reads, and 1.25 times the input rate for cache writes.- A malformed
inputoroutputfigure becomes0for that field only. A malformed cache rate is estimated the same way as a missing one.
When Actualyze lists no cost for a model, all of its cost fields are 0, an
unknown-price sentinel. Zero does not mean inference is free.
The cost pi shows is an estimate. Each listed rate is the highest among the routes your key can reach, so a Virtual Model or Model Group whose members are priced differently can read high. Actualyze's own usage metering is the record of what a request cost.
Modalities
Pi represents text and image input metadata. Actualyze advertisements for PDF/document, audio, or video input are not converted to another modality and are not presented as supported by this provider.
Advisory Capability Flags
Actualyze's streaming and tool_use flags are treated as advisory. A false
value never removes a model from the discovered catalog, and pi has no per-model
tool-support field. The provider keeps every valid model visible and uses the same
native pi request shape for all of them.
OpenAI Compatibility
The provider uses pi's native OpenAI Chat Completions implementation and pins a conservative compatibility profile:
| Behavior | Setting |
|---|---|
| Output token field | max_completion_tokens |
| Streamed usage | Enabled |
reasoning_effort |
Enabled |
| Finish reasons | Enabled |
store |
Disabled |
| Developer role | Disabled; system role is used |
| Strict tool schemas | Disabled |
Contract tests cover exact outbound roles and fields, text and reasoning streams,
reasoning replay via reasoning_content, images, Unicode, incremental function
arguments, tool-result continuation, usage, cancellation, routed aliases, error
redaction, and pi's standard context-overflow classification. Context-overflow
messages matching pi's standard patterns retain pi's normal compaction behavior.
Request Attribution
Every inference request carries an X-Actualyze-Request-Metadata header:
{ "agent": "pi", "run_id": "<pi session id>" }
Actualyze's Observability Activity tab shows the agent value with the run_id
beneath it and can filter on both, so one pi session's requests can be found
together. Actualyze records the header on the
request and does not forward it to the model provider.
The session id is left out when pi supplies none or when it does not fit
Actualyze's limits for these values (up to 256 characters drawn from letters,
digits, spaces, and - : _ @ $ # = / + , .), so the header never makes a request
fail. If your pi configuration already sets this header for the model or the
request, under any letter case, the provider sends your value unchanged.
Security
Authenticated traffic is deliberately constrained:
- a key from the environment goes only to an endpoint the environment names, and
production is a default only for
/login, whose prompt names the host; - targets are one validated ASCII DNS label;
- a base URL is an absolute URL without credentials, query, or fragment;
- all requests must use HTTPS, except plain HTTP to a
localhost,127.0.0.1, or[::1]base URL, which goes directly to this machine and never through a proxy, and is refused whenlocalhostresolves to any address that is not loopback; - the origin must exactly match the configured endpoint;
- paths must remain beneath the base URL's path (
/openai/v1for a target); - redirects are rejected with
redirect: "error"; - cached models from another endpoint are discarded, so the catalog never mixes endpoints;
- inference refuses a request before sending credentials when the current catalog attributes the model id to another endpoint's base URL, when the model object's base URL does not match the active endpoint (direct provider use), or when the id is absent from the current non-empty discovered catalog (covering stale sessions after upstream catalog changes and models.json-defined entries, which this provider does not support);
- the guarded fetch confines credentials to the resolved origin regardless of model metadata;
- retries never switch origins;
- catalog and error bodies are size-bounded;
- provider error bodies and headers are sanitized before pi receives them; and
- API keys and authorization headers are redacted from transport errors.
These guarantees cover requests this provider sends. One models.json
configuration makes pi bypass it; see Missing Limits.
Do not commit credentials, .env files, live API response captures, or generated pi
credential stores. Live tests are excluded from the default test suite and require
explicit opt-in flags.
Timeouts and Resilience
The provider is designed to fail without corrupting a valid catalog:
- Aggregate request budget: 10 seconds for list discovery, including retries, body reads, and backoff.
- Retry scope: HTTP 429 and transient 5xx responses only.
- Retry delay:
Retry-Afterwhen valid and affordable within the deadline; otherwise bounded exponential backoff. - Cancellation: Parent abort signals stop fetch, body consumption, and sleep.
- Response limits: Catalog and provider-error bodies are read with explicit byte limits.
- Atomic refresh: A malformed generation never partially replaces the current model list.
- Offline startup: A matching persisted catalog can remain available without a successful network refresh.
- Endpoint isolation: A cache from another endpoint is removed rather than exposed under the current credential.
pi Commands and CLI Behavior
| Command | Purpose |
|---|---|
/login actualyze |
Enter an API key, validate it, and discover models |
/model |
Browse and select discovered Actualyze models |
/logout actualyze |
Remove the stored Actualyze credential |
--actualyze-target |
CLI flag selecting a target (--actualyze-target=- for none) |
pi list |
Show installed pi packages |
pi remove … |
Uninstall the package |
Print Mode and Model Listing
pi -p and pi --list-models use the saved model list and never fetch it from
Actualyze. pi fetches the list on /login actualyze, after interactive pi starts,
and when /model opens. The one exception is a run that names an Actualyze model
with --model, which fetches the list while pi loads the extension (see
Refresh and Cache Behavior). Without --model, a
new environment that sets the key and endpoint through environment variables and
has no saved list therefore shows no Actualyze models in these modes. Start
interactive pi once, or run /login actualyze, to save the list.
When the key and endpoint come only from environment variables, pi -p without
--model sometimes starts with no model selected and reports "No API key found
for the selected model."
This is a startup race in pi, and it happens more often when models.json
exists. Pass --model actualyze/<model id>, or log in with /login actualyze so
that pi stores the credential.
Troubleshooting
pi fails while loading the extension
Start once without extensions:
pi --no-extensions
Then verify:
pi list
pi --version
The package requires pi 1.0.0 or newer. Upgrade pi if pi --version reports
an older release.
actualyze does not appear in /login
Confirm the package is installed:
pi list
For a local checkout, ensure the listed path still exists. Reinstall if necessary:
pi remove /absolute/path/to/pi-actualyze
pi install /absolute/path/to/pi-actualyze
Login rejects the target or base URL
Login never asks for an endpoint, so this only happens when --actualyze-target,
ACTUALYZE_TARGET, or ACTUALYZE_OPENAI_BASE_URL holds an invalid value, when a
target and the base URL name different endpoints, or when the target is - and
no base URL is set. Pass only the DNS label:
pi --actualyze-target staging
Do not pass staging.actualyze.ai, https://staging.actualyze.ai, a port, path,
or surrounding whitespace. For an environment outside *.actualyze.ai, set
ACTUALYZE_OPENAI_BASE_URL instead. Unset all three to log in to production.
pi exits with Unknown provider "actualyze"
pi looks up --provider actualyze --model <id> before it refreshes catalogs from
the network, so the provider needs a cached catalog or a successful fetch while
the extension loads. Check that:
- the environment names an endpoint (
ACTUALYZE_TARGET=appfor production, orACTUALYZE_OPENAI_BASE_URL) as well asACTUALYZE_API_KEY, or you have run/login actualyze; a key alone names no endpoint; - a first run is not started with
--offline; and - the endpoint accepts the key:
/login actualyzereports the error.
A saved login stores its catalog when you log in. If that cache is gone, start
pi once without --model and open /model, which refreshes it.
Login returns an authentication or catalog error
Check that:
- the API key belongs to the selected endpoint (production unless you chose another one);
- the endpoint's
/models(for a target,https://<target>.actualyze.ai/openai/v1/models) is reachable; - a proxy is not returning HTML or a redirect; and
- the endpoint returns a complete OpenAI-style JSON model list.
The provider intentionally rejects redirects and non-JSON responses.
Models do not appear in --list-models or pi -p
These modes show only the saved model list. Start interactive pi once, or run
/login actualyze, to fetch and save it. See
Print Mode and Model Listing.
Costs display as zero
Zero means Actualyze lists no cost for the model, so its price is unknown, not free. See Pricing. After an upgrade from pi-actualyze 2.0.0 or earlier, a saved model list shows zero costs until pi next refreshes it from Actualyze.
Upgrading to 3.0
A saved login from /login actualyze keeps working as before. What changes:
- A key from the environment needs an endpoint. With
ACTUALYZE_API_KEYset and no--actualyze-target,ACTUALYZE_TARGET, orACTUALYZE_OPENAI_BASE_URL, 2.x sent the key to production. 3.0 sends it nowhere, and the provider is unavailable. The same holds for a key passed with pi's--api-key. To keep using production, addACTUALYZE_TARGET=appor run/login actualyzeonce. ACTUALYZE_OPENAI_BASE_URLnames the endpoint for a run, so a launcher can point pi at an Actualyze environment outside*.actualyze.ai(see Another Actualyze Environment by URL). When a target is set as well, both must name the same endpoint.ACTUALYZE_TARGET=-(or--actualyze-target=-, with the=) selects no*.actualyze.aitarget.- A first run with
--provider actualyze --model <id>fetches the catalog while pi loads the extension, so it works with nothing cached instead of exiting withUnknown provider "actualyze". - Downgrading. pi-actualyze 2.x does not read a saved login's
ACTUALYZE_OPENAI_BASE_URLand would send that login's key to production. Run/logout actualyzebefore you install 2.x again. - SDK hosts. The controller from
createActualyzeProviderhas a newprimeCatalog()method. A provider env passed tostream()may nameACTUALYZE_OPENAI_BASE_URLinstead ofACTUALYZE_TARGET; an env whose two values name different endpoints is refused before the request is sent.
Development
Install dependencies and run the complete offline validation suite:
npm install
npm run check
npm audit --audit-level=low
Useful commands:
| Command | Purpose |
|---|---|
npm run typecheck |
Strict TypeScript validation |
npm run lint |
Biome lint checks |
npm run format:check |
Verify formatting |
npm test |
Offline unit, lifecycle, and contract tests |
npm run build |
Build JavaScript and declarations into dist/ |
npm run pack:check |
Inspect the npm package allowlist |
npm run test:live |
Explicit credential-gated live tests |
npm run test:contract |
Catalog contract test against a live endpoint |
The offline suite covers endpoint validation, transport boundaries, redirects, redaction, hostile catalogs, exact fixture parity, login and cache lifecycle, native request shape, reasoning replay, images, Unicode, tools, cancellation, context overflow, and isolated pi package loading.
Live Tests
Live tests never run through npm test or npm run check.
Catalog-only parity check:
ACTUALYZE_TARGET=app \
ACTUALYZE_API_KEY='...' \
npm run test:live
Paid streamed tool-loop check:
ACTUALYZE_TARGET=app \
ACTUALYZE_API_KEY='...' \
ACTUALYZE_LIVE_INFERENCE=1 \
ACTUALYZE_LIVE_MODEL='<model-id>' \
npm run test:live
Optional advisory-capability model:
ACTUALYZE_TARGET=app \
ACTUALYZE_API_KEY='...' \
ACTUALYZE_LIVE_INFERENCE=1 \
ACTUALYZE_LIVE_ADVISORY_MODEL='<model-id>' \
npm run test:live
Choose the main live model from catalog entries advertising streaming and tool use; the advisory model is expected to advertise both as false. The default live command fetches only the catalog and verifies raw-to-parsed ID parity; the paid streamed tool loop runs only with the explicit inference flag and model.
To run the same suite against an environment outside *.actualyze.ai, such as a
local Actualyze stack or a mock on this machine, name its base URL instead of a
target:
ACTUALYZE_OPENAI_BASE_URL='http://127.0.0.1:8080/openai/v1' \
ACTUALYZE_API_KEY='...' \
npm run test:live
Never enable live tests for untrusted pull requests. Supply credentials only through protected local or CI secret environments.
Contract Test
npm run test:contract fetches the model list from the endpoint in
ACTUALYZE_BASE_URL and checks that the provider parses every entry, in order,
and carries the advertised limits, image input, and reasoning flags into each
model. It also fails if no entry advertises a context or output limit, which
would mean the API renamed those fields. The endpoint must be https, or plain
http on this machine. Without both variables the test is skipped:
ACTUALYZE_BASE_URL='https://<target>.actualyze.ai/openai/v1' \
ACTUALYZE_API_KEY='...' \
npm run test:contract
The contract-tests.yml workflow runs it daily with the endpoint and key held
in the repository's contract-tests environment.
Package Contents
The npm file allowlist contains only:
src/README.mdLICENSEand npm-generated package metadata
Tests, .env.example, credentials, build output, and coverage are excluded.
Support
pi-actualyze is maintained by @jsquyres and @dpippenger at Actualyze AI.
| Topic | Support |
|---|---|
| Bugs and questions | GitHub issues |
| Security reports | Private vulnerability reporting, as described in SECURITY.md |
| Security fix targets | Critical 3 days, High 30 days, Medium 60 days, Low 90 days |
| Supported package version | The latest minor release |
| Supported hosts | The versions package.json declares: @earendil-works/pi-ai and @earendil-works/pi-coding-agent >=1.0.0, Node.js >=22.19.0 |
CI tests every change against the pi version pinned in package-lock.json. A
daily workflow also tests pi's latest and next releases and opens an issue
labeled compat when one fails.
Verifying Releases
Releases are built and published from this repository by GitHub Actions with npm trusted publishing, so each version carries a registry signature and a signed provenance attestation that names the workflow and commit that built it.
To verify an installed version, install it into an empty project and run
npm audit signatures:
mkdir verify-pi-actualyze && cd verify-pi-actualyze
npm init -y >/dev/null
npm install --ignore-scripts pi-actualyze@<version>
npm audit signatures
The output must report verified registry signatures and verified attestations
for pi-actualyze. To look at one version's provenance record directly:
npm view pi-actualyze@<version> dist.attestations
Contributing
See CONTRIBUTING.md for the architecture overview, development workflow, invariants that must not regress, and known caveats.
License
MIT © Actualyze AI, Inc.