{"_id":"@bradsjm/logprob-visualizer","_rev":"2-6c05141d0a1b5f04cdb3961c3a26c87f","name":"@bradsjm/logprob-visualizer","dist-tags":{"latest":"2.0.0"},"versions":{"1.0.0":{"name":"@bradsjm/logprob-visualizer","version":"1.0.0","keywords":["logprobs","openai","llm","visualizer","tokens"],"author":{"name":"Jonathan Bradshaw","email":"jb@nrgup.net"},"license":"MIT","_id":"@bradsjm/logprob-visualizer@1.0.0","maintainers":[{"name":"bradsjm","email":"jb@nrgup.net"}],"homepage":"https://github.com/bradsjm/logprob-visualizer#readme","bugs":{"url":"https://github.com/bradsjm/logprob-visualizer/issues"},"bin":{"logprob-visualizer":"bin/logprob-visualizer.js"},"dist":{"shasum":"440344f8304bc22703f0a1c94d1fc9545361c7b0","tarball":"https://registry.npmjs.org/@bradsjm/logprob-visualizer/-/logprob-visualizer-1.0.0.tgz","fileCount":15,"integrity":"sha512-NgD7uRpxwiugeej+oPRhLujwLI7Mk5iFv7J/haMA94Ipf084P3YJk7leuVMXmKnp1c25oiO4ZubWEEnSDEr4OQ==","signatures":[{"sig":"MEUCIQDKqZ55WArkQOjenPU3MjMoUfGSGxiBD7BWinlhgdHd5AIgG2R5us+8wPd/+4k48KG2yLKMh+SlWBpReesmNsBwF6A=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":511244},"type":"module","engines":{"node":">=20.0.0"},"gitHead":"7d6f6ab8a3e6b585b58cc77eca8f2bc1d8ee6b06","scripts":{"dev":"vite","lint":"eslint .","test":"vitest run","build":"vite build","start":"node ./bin/logprob-visualizer.js","pretty":"prettier --write \"./**/*.{js,jsx,mjs,cjs,ts,tsx,json}\"","prepack":"pnpm run build","preview":"vite preview","lint:fix":"eslint . --fix","build:dev":"vite build --mode development","typecheck":"tsc -p tsconfig.app.json --noEmit"},"_npmUser":{"name":"bradsjm","email":"jb@nrgup.net"},"repository":{"url":"git+https://github.com/bradsjm/logprob-visualizer.git","type":"git"},"_npmVersion":"11.12.1","description":"Local web UI for exploring token-level log probabilities from OpenAI-compatible chat models.","directories":{},"_nodeVersion":"24.14.1","dependencies":{"clsx":"^2.1.1","react":"^18.3.1","sonner":"^1.7.4","react-dom":"^18.3.1","lucide-react":"^0.462.0","tailwind-merge":"^2.6.1","react-router-dom":"^6.30.3","tailwindcss-animate":"^1.0.7","use-stick-to-bottom":"^1.1.3","@radix-ui/react-slot":"^1.2.4","@radix-ui/react-label":"^2.1.8","@tanstack/react-query":"^5.96.2","@radix-ui/react-dialog":"^1.1.15","@radix-ui/react-select":"^2.2.6","@radix-ui/react-slider":"^1.3.6","@radix-ui/react-switch":"^1.2.6","@radix-ui/react-tooltip":"^1.2.8","class-variance-authority":"^0.7.1","@radix-ui/react-collapsible":"^1.1.12"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"packageManager":"pnpm@10.33.0+sha512.10568bb4a6afb58c9eb3630da90cc9516417abebd3fabbe6739f0ae795728da1491e9db5a544c76ad8eb7570f5c4bb3d6c637b2cb41bfdcdb47fa823c8649319","devDependencies":{"vite":"^5.4.21","jsdom":"^26.1.0","eslint":"^9.39.4","vitest":"^2.1.9","globals":"^17.4.0","postcss":"^8.5.8","@eslint/js":"^9.39.4","typescript":"^5.9.3","@types/node":"^22.19.17","tailwindcss":"^3.4.19","@types/react":"^18.3.28","autoprefixer":"^10.4.27","@types/react-dom":"^18.3.7","typescript-eslint":"^8.58.0","eslint-plugin-react":"^7.37.5","eslint-plugin-import":"^2.32.0","@tailwindcss/typography":"^0.5.19","@vitejs/plugin-react-swc":"^3.11.0","eslint-plugin-react-hooks":"^5.2.0","eslint-plugin-react-refresh":"^0.4.26"},"_npmOperationalInternal":{"tmp":"tmp/logprob-visualizer_1.0.0_1775405171346_0.7498757728700729","host":"s3://npm-registry-packages-npm-production"}},"2.0.0":{"name":"@bradsjm/logprob-visualizer","version":"2.0.0","description":"Local web UI for exploring token-level log probabilities from OpenAI-compatible chat models.","keywords":["logprobs","openai","llm","visualizer","tokens"],"homepage":"https://github.com/bradsjm/logprob-visualizer#readme","bugs":{"url":"https://github.com/bradsjm/logprob-visualizer/issues"},"license":"MIT","author":{"name":"Jonathan Bradshaw","email":"jb@nrgup.net"},"repository":{"type":"git","url":"git+https://github.com/bradsjm/logprob-visualizer.git"},"publishConfig":{"access":"public"},"packageManager":"pnpm@10.33.0+sha512.10568bb4a6afb58c9eb3630da90cc9516417abebd3fabbe6739f0ae795728da1491e9db5a544c76ad8eb7570f5c4bb3d6c637b2cb41bfdcdb47fa823c8649319","type":"module","bin":{"logprob-visualizer":"bin/logprob-visualizer.js"},"engines":{"node":">=20.0.0"},"scripts":{"build:dev":"vite build --mode development","build":"vite build","dev":"vite","lint:fix":"eslint . --fix","lint":"eslint .","prepack":"pnpm run build","pretty":"prettier --write \"./**/*.{js,jsx,mjs,cjs,ts,tsx,json}\"","preview":"vite preview","start":"node ./bin/logprob-visualizer.js","test":"vitest run","typecheck":"tsc -p tsconfig.app.json --noEmit"},"dependencies":{"@radix-ui/react-collapsible":"^1.1.12","@radix-ui/react-dialog":"^1.1.15","@radix-ui/react-label":"^2.1.8","@radix-ui/react-select":"^2.2.6","@radix-ui/react-slider":"^1.3.6","@radix-ui/react-slot":"^1.2.4","@radix-ui/react-switch":"^1.2.6","@radix-ui/react-tooltip":"^1.2.8","@tanstack/react-query":"^5.96.2","class-variance-authority":"^0.7.1","clsx":"^2.1.1","lucide-react":"^0.462.0","react":"^18.3.1","react-dom":"^18.3.1","react-router-dom":"^6.30.3","sonner":"^1.7.4","tailwind-merge":"^2.6.1","tailwindcss-animate":"^1.0.7","use-stick-to-bottom":"^1.1.3"},"devDependencies":{"@eslint/js":"^9.39.4","@tailwindcss/typography":"^0.5.19","@types/node":"^22.19.17","@types/react":"^18.3.28","@types/react-dom":"^18.3.7","@vitejs/plugin-react-swc":"^3.11.0","autoprefixer":"^10.4.27","eslint":"^9.39.4","eslint-plugin-import":"^2.32.0","eslint-plugin-react":"^7.37.5","eslint-plugin-react-hooks":"^5.2.0","eslint-plugin-react-refresh":"^0.4.26","globals":"^17.4.0","jsdom":"^26.1.0","postcss":"^8.5.8","tailwindcss":"^3.4.19","typescript":"^5.9.3","typescript-eslint":"^8.58.0","vite":"^5.4.21","vitest":"^2.1.9"},"gitHead":"7d6f6ab8a3e6b585b58cc77eca8f2bc1d8ee6b06","_id":"@bradsjm/logprob-visualizer@2.0.0","_nodeVersion":"24.14.1","_npmVersion":"11.12.1","dist":{"integrity":"sha512-1p6F/EZ01XFWqw2JOt2aLj8ucjzREk6m2JSfAOFjBWM1qDoUOfUqsHA9YkzsIrvL/JdXkdXvk/5vQh3kWyS7Cg==","shasum":"b2b37e00f0f97489d89583385e588b1ce939cf49","tarball":"https://registry.npmjs.org/@bradsjm/logprob-visualizer/-/logprob-visualizer-2.0.0.tgz","fileCount":15,"unpackedSize":511244,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIGMtAs2IYoP0y6bpk8kK5REqdorsU24E9xnZJMN6AFe0AiB3j24UPs8eS6sM8h2LaIWkTEChikSEQ8WL6/XVx5C5Mw=="}]},"_npmUser":{"name":"bradsjm","email":"jb@nrgup.net"},"directories":{},"maintainers":[{"name":"bradsjm","email":"jb@nrgup.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/logprob-visualizer_2.0.0_1775405422563_0.19651526515014828"},"_hasShrinkwrap":false}},"time":{"created":"2026-04-05T16:06:11.205Z","modified":"2026-04-05T16:10:22.858Z","1.0.0":"2026-04-05T16:06:11.557Z","2.0.0":"2026-04-05T16:10:22.744Z"},"bugs":{"url":"https://github.com/bradsjm/logprob-visualizer/issues"},"author":{"name":"Jonathan Bradshaw","email":"jb@nrgup.net"},"license":"MIT","homepage":"https://github.com/bradsjm/logprob-visualizer#readme","keywords":["logprobs","openai","llm","visualizer","tokens"],"repository":{"type":"git","url":"git+https://github.com/bradsjm/logprob-visualizer.git"},"description":"Local web UI for exploring token-level log probabilities from OpenAI-compatible chat models.","maintainers":[{"name":"bradsjm","email":"jb@nrgup.net"}],"readme":"# Logprob Visualizer\n\nLogprob Visualizer is a local React app and packaged CLI for inspecting token-level log probabilities from OpenAI-compatible chat completion providers. The published package serves the built single-page app locally, opens it in your browser by default, and the browser then talks directly to the configured provider API.\n\n## Features\n- Provider-backed model discovery via `GET /models`\n- Per-model capability probing before use to check whether `logprobs` are supported\n- Streaming chat completions from `POST /chat/completions` with token-by-token logprob analysis\n- Interactive transcript tokens with probability coloring, alternative-token tooltips, and regenerate support\n- Analysis panel with probability chart, usage stats, raw JSON view, and JSON/CSV export\n- URL-backed model and generation parameters for shareable local state\n\n## Security Model\n- API keys are stored in `localStorage` in the current browser profile.\n- Provider requests go directly from the browser to the configured base URL.\n- The packaged Node runtime serves static files only. It does not proxy provider requests or hide credentials.\n\n## Prerequisites\n- Node.js 20 or newer\n- An OpenAI-compatible provider that exposes `GET /models` and `POST /chat/completions`\n- A model that returns `logprobs` data for chat completions\n\n## Getting Started\nRun the published package:\n\n```bash\nnpx @bradsjm/logprob-visualizer\n```\n\nThe CLI starts a local static server on `http://127.0.0.1:8080` by default and attempts to open your default browser. In the app, open `Connection Settings`, enter an API key, and optionally set a base URL.\n\nA blank base URL resolves to `https://api.openai.com/v1`.\n\n## CLI Options\n- `--host <address>`: bind address for the local static server. Default: `127.0.0.1`\n- `--port <number>`: bind port for the local static server. Default: `8080`\n- `--no-open`: do not open a browser automatically\n- `--help`: print CLI help\n\nExamples:\n\n```bash\nnpx @bradsjm/logprob-visualizer --port 9000\nnpx @bradsjm/logprob-visualizer --host 0.0.0.0 --no-open\n```\n\n## Repository Development\n\n```bash\npnpm install\npnpm dev\n```\n\nUseful commands:\n\n| Command | Purpose |\n| --- | --- |\n| `pnpm dev` | Start the Vite dev server on `0.0.0.0:8080` |\n| `pnpm build` | Build the production SPA into `dist/` |\n| `pnpm build:dev` | Build with development-mode sourcemaps |\n| `pnpm preview` | Preview the production build locally |\n| `pnpm start` | Run the packaged CLI/static server against `dist/` |\n| `pnpm typecheck` | Run TypeScript type-checking |\n| `pnpm lint` | Run ESLint |\n| `pnpm lint:fix` | Run ESLint with automatic fixes |\n| `pnpm test` | Run Vitest |\n| `pnpm pretty` | Run Prettier on JS/TS/JSON files |\n| `pnpm pack --dry-run` | Inspect the publishable package contents |\n\n## Project Structure\n- `bin/logprob-visualizer.js`: published CLI entrypoint\n- `runtime/server.js`: static file server and CLI argument handling\n- `src/pages/Playground.tsx`: main application screen\n- `src/features/provider/`: provider HTTP client and streaming/logprob parsing\n- `src/features/playground/`: session state and generation parameter management\n- `src/components/`: transcript, analysis, composer, settings dialog, and UI primitives\n- `src/lib/transport/stream.ts`: browser transport for streaming completions\n\n## How It Works\n- Connection settings are read from and written to browser `localStorage`.\n- Model discovery fetches `${baseUrl}/models` after a key is saved.\n- Selecting a model triggers a small non-streaming probe request to verify `logprobs` support.\n- Sending a prompt starts a streaming `chat/completions` request with `logprobs: true` and `stream_options.include_usage: true`.\n- The client parses server-sent events in the browser, accumulates token probabilities, and renders the transcript and analysis views progressively.\n\n## Quality Gates\n- `pnpm typecheck`\n- `pnpm lint`\n- `pnpm test`\n- `pnpm build`\n\n## Contributing\nConsult `AGENTS.md` before opening a pull request.\n","readmeFilename":"README.md"}