{"_id":"@astronova-ai/pi-provider","name":"@astronova-ai/pi-provider","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@astronova-ai/pi-provider","version":"0.1.0","description":"pi (pi.dev) extension that registers the Salesforce LLM Gateway as a model provider.","type":"module","license":"MIT","main":"./dist/index.js","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"pi":{"extensions":["./dist/index.js"]},"sideEffects":false,"scripts":{"build":"tsup","typecheck":"tsc --noEmit","test":"vitest run","prepack":"npm run build","clean":"rm -rf dist"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"dependencies":{"@astronova-ai/sf-llm-core":"^0.1.0"},"peerDependencies":{"@earendil-works/pi-ai":"*","@earendil-works/pi-coding-agent":"*"},"devDependencies":{"@earendil-works/pi-ai":"^0.80.2","@earendil-works/pi-coding-agent":"^0.80.2","typescript":"^5.7.2","tsup":"^8.3.5","vitest":"^2.1.8"},"keywords":["pi","pi.dev","salesforce","llm","provider","extension","claude","gpt"],"_id":"@astronova-ai/pi-provider@0.1.0","gitHead":"aad46f58b12f80ebba70012c1e2253e9f19a1103","_nodeVersion":"22.23.1","_npmVersion":"10.9.8","dist":{"integrity":"sha512-RQLxyI1xmUJbk8L5CkbLs1Aeibm7hetYd1bFt7S2hSrndDhIe1O6A8cWGlMfoImR1lUwlRrI13qGhzUOUdu0Mw==","shasum":"9d6e31cbe14bce6243c4f2533af86508ee331aa7","tarball":"https://registry.npmjs.org/@astronova-ai/pi-provider/-/pi-provider-0.1.0.tgz","fileCount":11,"unpackedSize":50232,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIAxMzlOV943rB4fkf7rH7owzkJO/KdFhrhmIjQ2h/dqAAiBez43kECHhFxyNv1SaocPRhR4WLkVka2PUtJI8VTYT2Q=="}]},"_npmUser":{"name":"dfleminks","email":"damien@fleminks.com"},"directories":{},"maintainers":[{"name":"dfleminks","email":"damien@fleminks.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/pi-provider_0.1.0_1784200866813_0.5830562171505909"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-16T11:21:06.607Z","0.1.0":"2026-07-16T11:21:06.969Z","modified":"2026-07-16T11:21:07.172Z"},"maintainers":[{"name":"dfleminks","email":"damien@fleminks.com"}],"description":"pi (pi.dev) extension that registers the Salesforce LLM Gateway as a model provider.","keywords":["pi","pi.dev","salesforce","llm","provider","extension","claude","gpt"],"license":"MIT","readme":"# @astronova-ai/pi-provider\n\n> [!IMPORTANT]\n> This is an independent, unofficial package. It is not endorsed by, affiliated with, or supported\n> by Salesforce. Salesforce is a trademark of Salesforce, Inc. Use requires an entitled Salesforce\n> org and remains subject to your agreements with Salesforce.\n\nA [pi](https://pi.dev) extension that registers the **Salesforce LLM Gateway** as a model\nprovider. Use the Claude / GPT models your Salesforce org is entitled to, from inside pi — no\nseparate model API key.\n\n## Install & use\n\n```bash\npi -e @astronova-ai/pi-provider\n```\n\nThen, inside pi:\n\n```\n/login salesforce-gateway      # OAuth device flow (opens a URL + shows a code)\n/model salesforce-gateway/llmgateway__BedrockAnthropicClaude46Sonnet\n```\n\nOr skip OAuth entirely with environment variables (handy in CI / dev):\n\n```bash\nSF_ACCESS_TOKEN=00D...  SF_INSTANCE_URL=https://your-org.my.salesforce.com  pi -e @astronova-ai/pi-provider\n```\n\n## What it registers\n\n- **Provider id:** `salesforce-gateway`\n- **Models:** all 8 gateway models (Claude Sonnet/Opus 4.5–4.7, GPT-5/5.4/5.5), keyed by gateway\n  id. Cost is reported as `0` because inference bills against your org, not a per-token account.\n- **`streamSimple`:** a custom implementation that runs `@astronova-ai/sf-llm-core`'s **unified\n  client** and maps its chunks to pi's event protocol (`start → text_* → toolcall_* →\n  done`/`error`). Tool calls, token usage, and reasoning effort are surfaced.\n- **Surface routing (automatic):** GPT models stream through the newer **Responses API**; Claude\n  models through **chat/generations** (the Responses API is GPT-only on the gateway today). You\n  pick a model in pi; the provider picks the surface. When Salesforce enables Claude on the\n  Responses API, it upgrades with no change. pi's thinking level maps to Responses reasoning effort\n  (`xhigh → high`).\n- **OAuth:** Salesforce Device Flow — no loopback server. Uses the public `PlatformCLI` connected\n  app by default; override with `SF_OAUTH_CLIENT_ID` / `SF_LOGIN_URL` for a custom connected app\n  or a sandbox.\n\n## How the org URL is carried (the interesting bit)\n\npi persists OAuth credentials as `{ refresh, access, expires }` — but minting a Salesforce gateway\nJWT also needs the org's **`instanceUrl`**. pi's `OAuthCredentials` has a `[key: string]: unknown`\nindex signature and round-trips the whole object through `~/.pi/agent/auth.json`, so we store\n`instanceUrl` (and the chosen `featureId`) as extra keys. They come back in `refreshToken(cred)`.\n\n`streamSimple` only receives `options.apiKey` (the string `getApiKey(cred)` returns) — not the\ncredential object — so `getApiKey` **packs** `{ accessToken, instanceUrl, featureId }` into that\nstring (`sfgw1:<base64url>`), and `streamSimple` unpacks it. A bare token from the env path is\nalso accepted. This path is verified end-to-end against a live org (text + tool calls).\n\n## Configuration\n\n| Env var | Purpose |\n|---|---|\n| `SF_ACCESS_TOKEN` + `SF_INSTANCE_URL` | Use a token directly, skipping `/login`. |\n| `SF_FEATURE_ID` | JWT-mint feature id (default `AgentforceVibes`). |\n| `SF_OAUTH_CLIENT_ID` | Custom connected-app client id for OAuth. |\n| `SF_LOGIN_URL` | `https://login.salesforce.com` (prod) or `https://test.salesforce.com` (sandbox). |\n\n## Verified in the real pi CLI\n\nRun against the installed pi CLI (v0.79.9) and a live org, via the env-var path:\n\n```bash\n$ SF_ACCESS_TOKEN=… SF_INSTANCE_URL=https://your-org.my.salesforce.com SF_FEATURE_ID=AgentforceVibes \\\n  pi -e @astronova-ai/pi-provider \\\n     --provider salesforce-gateway \\\n     --model salesforce-gateway/llmgateway__BedrockAnthropicClaude46Sonnet \\\n     --print \"Reply with exactly: PI VIA SALESFORCE GATEWAY\"\n\nPI VIA SALESFORCE GATEWAY\n```\n\nClaude Opus 4.7 works too (the client auto-strips the deprecated `temperature` param):\n\n```bash\n$ pi -e @astronova-ai/pi-provider --provider salesforce-gateway \\\n     --model salesforce-gateway/llmgateway__BedrockAnthropicClaude47Opus \\\n     --print \"List two Salesforce products as a bulleted list. Be brief.\"\n\n- Sales Cloud\n- Service Cloud\n```\n\nTwo things to know:\n- **Loading:** `pi -e <path-to-this-package>` works against both the built `dist/index.js` and the\n  source `src/index.ts` (pi's jiti loader aliases the bundled `pi-ai` for `.ts` extensions; the\n  built form uses our self-contained fallback runtime). For day-to-day use, `pi install` it.\n- **Auth gate:** pi checks for a provider key *before* calling `streamSimple`, so the provider\n  declares `apiKey: \"$SF_ACCESS_TOKEN\"`. The env path needs `SF_INSTANCE_URL` too; `/login\n  salesforce-gateway` (OAuth device flow) carries the instance URL automatically.\n\n## Peer dependencies\n\n`@earendil-works/pi-coding-agent` and `@earendil-works/pi-ai` are **peer dependencies** provided\nby the pi host. The package falls back to a small bundled event-stream implementation when pi-ai\nisn't importable (e.g. unit tests / standalone embedding).\n\n## License\n\nMIT\n","readmeFilename":"README.md","_rev":"1-80e0fd705fcca5811de941f990e2f9dd"}