@nevescloud/pip 3.0.0 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -26,7 +26,7 @@ Provider-named bundles re-export the three primitives most hosts compose, from a
26
26
 
27
27
  ```js
28
28
  // Anthropic — Claude on /v1/messages
29
- import { createPip, createRuntime, anthropic } from 'https://cdn.jsdelivr.net/npm/@nevescloud/pip@latest/bundle/anthropic';
29
+ import { createPip, createRuntime, anthropic } from 'https://cdn.jsdelivr.net/npm/@nevescloud/pip@latest/bundle/anthropic.esm.js';
30
30
 
31
31
  const rt = createRuntime({ provider: anthropic({ model: 'claude-opus-4-7', apiKey: '…' }) });
32
32
  const pip = createPip({ onSubmit: rt.onSubmit, onSlash: rt.onSlash, slashSource: rt.slashSource });
@@ -34,10 +34,15 @@ const pip = createPip({ onSubmit: rt.onSubmit, onSlash: rt.onSlash, slashSource:
34
34
 
35
35
  ```js
36
36
  // OpenAI-compatible — OpenAI, GitHub Models, Together, Groq, OpenRouter, LM Studio, llama.cpp
37
- import { createPip, createRuntime, openai } from 'https://cdn.jsdelivr.net/npm/@nevescloud/pip@latest/bundle/openai';
37
+ import { createPip, createRuntime, openai } from 'https://cdn.jsdelivr.net/npm/@nevescloud/pip@latest/bundle/openai.esm.js';
38
38
  ```
39
39
 
40
- `pip/bundle` (no provider segment) is an alias for `pip/bundle/anthropic` — the default when you haven't picked a brain. Bundles are sugar over the layered files; hosts with a different brain shape (UI only, custom provider, in-browser model) import the granular files directly. See [CONSUMERS.md](../../CONSUMERS.md) for the full entry-point list.
40
+ ```js
41
+ // Local — in-browser inference via transformers.js + WebGPU (different shape: no runtime, renderer is host-driven)
42
+ import { createPip, createTransformersRenderer } from 'https://cdn.jsdelivr.net/npm/@nevescloud/pip@latest/bundle/local.esm.js';
43
+ ```
44
+
45
+ On jsdelivr the `.esm.js` suffix is required — jsdelivr serves files by raw path, not via `package.json` exports. npm-installed consumers can use the shorter `@nevescloud/pip/bundle/anthropic` (Node ESM resolver honors the exports map). `pip/bundle.esm.js` (or `pip/bundle` via npm) is an alias for `bundle/anthropic` — the default when you haven't picked a brain. Bundles are sugar over the layered files; hosts with a different brain shape (UI only, custom provider, in-browser model) import the granular files directly. See [CONSUMERS.md](../../CONSUMERS.md) for the full entry-point list.
41
46
 
42
47
  ## Options
43
48
 
@@ -81,7 +86,12 @@ pip.registerSlash({
81
86
  pip.unregisterSlash("model");
82
87
  ```
83
88
 
84
- Handler returns `{ reply?, clearedUI?, passThrough? } | null`. `null` falls through to `onSlash` (if provided) and then to the LLM. Built-ins ship `/help` (auto-lists registered + built-ins) and `/clear` (wipes pip's local history + DOM).
89
+ Handler returns `{ reply?, clearedUI?, openCompletions?, passThrough? } | null`. `null` falls through to `onSlash` (if provided) and then to the LLM. Built-ins ship `/help` (auto-lists registered + built-ins) and `/clear` (wipes pip's local history + DOM).
90
+
91
+ - `reply` — render as an assistant turn in chat history.
92
+ - `clearedUI` — the handler already painted its own UI (via `startTurn`, `askInChat`, etc.); pip-core skips creating a turn.
93
+ - `openCompletions` — re-open the autocomplete dropdown in arg-mode for this command. Use when the bare command (no arg) is meant to surface a sub-menu like a model picker — keeps the navigation inside the dropdown the user came from instead of logging a listing to history. Pip-core puts `"/<cmd> "` in the input, focuses it, and runs the registered `complete('')` to populate the dropdown.
94
+ - `passThrough` — treat as if the handler didn't match; falls through to `onSlash` then the LLM.
85
95
 
86
96
  ## Tool-using turns
87
97
 
@@ -0,0 +1,9 @@
1
+ // Quickstart entry — pip wired to an in-browser model in one import.
2
+ // Re-exports the two primitives most local-renderer hosts compose.
3
+ // Different shape from bundle/anthropic and bundle/openai: there's no
4
+ // runtime here — the renderer is host-driven (one-shot generate),
5
+ // not part of the turn loop. Consumers shouldn't need to know which
6
+ // underlying library powers the renderer; that's why this entry exists.
7
+
8
+ export { createPip } from '../pip-core.esm.js';
9
+ export { createTransformersRenderer, splitThinking } from '../providers/local.esm.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nevescloud/pip",
3
- "version": "3.0.0",
3
+ "version": "3.2.0",
4
4
  "description": "Floating assistant bubble + panel + chat runtime. ESM, no build.",
5
5
  "type": "module",
6
6
  "main": "pip-core.esm.js",
@@ -13,6 +13,8 @@
13
13
  "./bundle/anthropic.esm.js": "./bundle/anthropic.esm.js",
14
14
  "./bundle/openai": "./bundle/openai.esm.js",
15
15
  "./bundle/openai.esm.js": "./bundle/openai.esm.js",
16
+ "./bundle/local": "./bundle/local.esm.js",
17
+ "./bundle/local.esm.js": "./bundle/local.esm.js",
16
18
  "./providers/anthropic.esm.js": "./providers/anthropic.esm.js",
17
19
  "./providers/openai.esm.js": "./providers/openai.esm.js",
18
20
  "./providers/local.esm.js": "./providers/local.esm.js"
package/pip-core.esm.js CHANGED
@@ -1072,7 +1072,7 @@ export function createPip(opts = {}) {
1072
1072
  // null/0 disables. Manual opens are never auto-closed.
1073
1073
  panelAutoCloseMs = null,
1074
1074
  onSubmit = null, // optional host handler; receives (text, turnApi) — if present, bypasses `ask`
1075
- onSlash = null, // optional (text) -> { reply?, clearedUI? } | null — fallback after registered commands miss
1075
+ onSlash = null, // optional (text) -> { reply?, clearedUI?, openCompletions?, passThrough? } | null — fallback after registered commands miss
1076
1076
  slashSource = null, // optional () -> [{ name, description?, complete? }] — overrides built-in source from registerSlash()
1077
1077
  placeholder = "Ask Pip…",
1078
1078
  maxLength = 4000,
@@ -1960,6 +1960,21 @@ export function createPip(opts = {}) {
1960
1960
  if (!r && onSlash) r = onSlash(text);
1961
1961
  if (r && !r.passThrough) {
1962
1962
  if (r.clearedUI) { scrollToBottom(); return; }
1963
+ if (r.openCompletions) {
1964
+ // Sub-menu navigation: re-open arg-mode autocomplete for this
1965
+ // command without committing a turn. Lets hosts surface
1966
+ // sub-options (model list, scope picker, etc.) inside the same
1967
+ // dropdown the user used to reach the command, instead of
1968
+ // logging the listing to chat history.
1969
+ const slashName = text.match(/^\/(\S+)/)?.[1];
1970
+ if (slashName) {
1971
+ input.value = `/${slashName} `;
1972
+ input.setSelectionRange(input.value.length, input.value.length);
1973
+ input.focus();
1974
+ updateSlashSuggest();
1975
+ }
1976
+ return;
1977
+ }
1963
1978
  const t = startTurn({ echo: text });
1964
1979
  if (r.reply) setReplyText(t, r.reply, true);
1965
1980
  return;