{"_id":"@anarkhli/provider-sdk","name":"@anarkhli/provider-sdk","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@anarkhli/provider-sdk","version":"0.1.0","description":"Provider-side SDK and CLI for Token Relay.","type":"module","main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"bin":{"token-relay-provider":"dist/cli.js"},"scripts":{"build":"tsc -p tsconfig.json","typecheck":"npm run build -w @anarkhli/protocol && tsc -p tsconfig.json --noEmit","test":"npm run build -w @anarkhli/protocol && npm run build && node --test ./test/*.test.mjs","prepack":"npm run build -w @anarkhli/protocol && npm run build"},"keywords":["llm","relay","provider","codex","claude","cli"],"dependencies":{"@anarkhli/protocol":"0.1.0","ws":"^8.18.3"},"engines":{"node":">=22.13.0"},"license":"MIT","publishConfig":{"access":"public"},"_id":"@anarkhli/provider-sdk@0.1.0","_integrity":"sha512-zvkfrOg0A3zi+G9C07l05em93Z/lqHlG64fm+KqpHV+SP+T0HoAeXQs7KdXAXvjySc3aFwM38IDi8D4EpaaXyQ==","_resolved":"/tmp/anarkhli-token-relay-pack-final.6Fw0AWHd/anarkhli-provider-sdk-0.1.0.tgz","_from":"file:/tmp/anarkhli-token-relay-pack-final.6Fw0AWHd/anarkhli-provider-sdk-0.1.0.tgz","_nodeVersion":"26.0.0","_npmVersion":"11.12.1","dist":{"integrity":"sha512-zvkfrOg0A3zi+G9C07l05em93Z/lqHlG64fm+KqpHV+SP+T0HoAeXQs7KdXAXvjySc3aFwM38IDi8D4EpaaXyQ==","shasum":"cb385a49b49fb2850d9b2867c36fa20b6697350e","tarball":"https://registry.npmjs.org/@anarkhli/provider-sdk/-/provider-sdk-0.1.0.tgz","fileCount":48,"unpackedSize":125591,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCIDItCksAJxOuIgM3IwcU4S4VgRfxIoZHK6FEmaNTFygIhAIq7/58wEOOozwNSJU/24p0+ooa/2onWSXFmOtpvBp+H"}]},"_npmUser":{"name":"anarkhli","email":"710809606@qq.com"},"directories":{},"maintainers":[{"name":"anarkhli","email":"710809606@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/provider-sdk_0.1.0_1785918428044_0.33783424087001235"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-05T08:27:07.909Z","0.1.0":"2026-08-05T08:27:08.186Z","modified":"2026-08-05T08:27:08.370Z"},"maintainers":[{"name":"anarkhli","email":"710809606@qq.com"}],"description":"Provider-side SDK and CLI for Token Relay.","keywords":["llm","relay","provider","codex","claude","cli"],"license":"MIT","readme":"# Token Relay Provider SDK\n\nProvider-side SDK and CLI for connecting subscription-backed local model CLIs\nto Token Relay. The provider makes an outbound authenticated WebSocket\nconnection; the relay never receives the provider's model credentials.\n\nRequires Node.js 22.13 or newer. The SDK is ESM-only; CommonJS applications\nshould load it with dynamic `import()`.\n\n## Install and configure\n\n```bash\nnpm install -g @anarkhli/provider-sdk\ntoken-relay-provider version\n```\n\nCreate `provider.config.json` in the directory where the Provider process will\nrun. Keep the one-time Provider token in an environment variable instead of\nwriting it into the file:\n\n```json\n{\n  \"relayUrl\": \"wss://relay.example.com/provider/v1/connect\",\n  \"providerToken\": \"${TOKEN_RELAY_PROVIDER_TOKEN}\",\n  \"concurrency\": 1,\n  \"models\": {\n    \"gpt-5.6-sol\": {\n      \"adapter\": \"codex\",\n      \"command\": \"codex\",\n      \"cliModel\": \"gpt-5.6-sol\"\n    }\n  }\n}\n```\n\n```bash\nexport TOKEN_RELAY_PROVIDER_TOKEN='replace-with-provider-token'\ntoken-relay-provider doctor --config provider.config.json\ntoken-relay-provider start --config provider.config.json\n```\n\nThe default endpoint is `ws://127.0.0.1:8787/provider/v1/connect`. Use `wss://`\noutside a trusted local network.\n\nEach model name advertised to the relay maps to a local `codex`, `claude`,\n`aiden`, or custom executable. Set `cliModel` when the public relay model name\nis an alias for a specific local CLI model; when omitted, built-in adapters use\nthat CLI's default model. Custom arguments are passed directly without a shell\nand support `{model}`, `{workspace}`, `{promptFile}`, and `{outputFile}`\nplaceholders.\n\n## SDK\n\n```ts\nimport {\n  ProviderClient,\n  type ModelExecutor\n} from \"@anarkhli/provider-sdk\";\n\nconst executor: ModelExecutor = {\n  async execute(job, target, signal) {\n    // A custom executor is useful for containers, remote workers, and tests.\n    return {\n      content: `Handled ${job.model} with ${target.adapter}`,\n      finishReason: \"stop\",\n      usage: {\n        promptTokens: 1,\n        completionTokens: 1,\n        totalTokens: 2,\n        estimated: true\n      }\n    };\n  }\n};\n\nconst client = new ProviderClient({\n  relayUrl: \"wss://relay.example.com/provider/v1/connect\",\n  providerToken: process.env.TOKEN_RELAY_PROVIDER_TOKEN,\n  concurrency: 2,\n  models: {\n    \"test-model\": {\n      adapter: \"custom\",\n      command: \"/usr/local/bin/my-agent\"\n    }\n  }\n}, { executor });\n\nawait client.start(); // resolves after the relay sends ready\n// ...\nawait client.stop(); // aborts active jobs and closes the connection\n```\n\n## Execution safety\n\nThe built-in executor creates a new empty temporary workspace per job, writes\nthe prompt to a mode-0600 file, and attaches that file as non-TTY stdin. It\nuses a small environment allowlist, direct process spawning without a shell,\ntimeouts, an output byte limit, process-group cancellation, and recursive\ntemporary-directory cleanup.\n\nCodex uses a read-only sandbox, Claude uses plan permission mode, and Aiden\nuses read-only mode. A custom executable is responsible for enforcing an\nequivalent sandbox. For untrusted users, run the provider under a dedicated OS\naccount or container: local CLI authentication may still require access to the\nprovider account's home directory.\n","readmeFilename":"README.md","_rev":"1-6b52c370d6dc1833f0cb203891ff8bfb"}