@columenlabs/lumen-ai 0.1.187 → 0.1.188

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
@@ -98,10 +98,10 @@ app.all('/api/assistant/*', (c) => routes(c.req.raw));
98
98
  - **Keys.** Each provider has its own keys (`?provider=anthropic|openai` on the key routes). An admin pastes the shared key everyone uses (`PUT /key`); it is tested with one free call before it is kept, then sealed, and no route returns it. A person may add their own (`PUT /my-key`), with one monthly cap on their own keys (`PUT /my-key/cap`).
99
99
  - **ChatGPT sign-in.** In place of their own OpenAI key a person may sign in with their ChatGPT plan (`POST /my-signin`, then `POST /my-signin/finish {url}`): the sign-in opens in a new tab and ends on `http://127.0.0.1:1455/auth/callback`, a page that does not load, whose address the person pastes back. The tokens are sealed as their own key and refreshed before they run out; answers on the plan count tokens and no dollars.
100
100
  - **Who pays.** The person's pick (the shared keys by default) while it has a key for the tier's provider and money left this month under its cap (an admin sets the shared keys' cap per person, `PUT /app`), else the other; with neither the panel says why.
101
- - **Tools.** Each group is Off, Read, Read + draft or Read + write per person. A tool is a read when its MCP `readOnlyHint` is set. On Read + draft a write only drafts a card, and runs as the person when they press Save, after access is checked again. A group with `readOnly: true` (read tools only) is offered Off or Read alone. Read + write is offered only for a group with `writes: true`: its writes run at once, and with `undo` set each one's line in the chat has Undo, which calls `undo(caller, { tool, args, result })` (`POST /chats/:id/writes/:step/undo`); the model is told what was undone. Cards drafted one after another show as one stack with Save all. Use `mcpServerTools` (an SDK `McpServer`), `mcpFetchTools` (a server served as a fetch handler, any SDK), `remoteMcpTools` or `plainTools`.
101
+ - **Tools.** Each group is Off, Read, Read + draft or Read + write per person. A tool is a read when its MCP `readOnlyHint` is set. On Read + draft a write only drafts a card, and runs as the person when they press Save, after access is checked again. A group with `readOnly: true` (read tools only) is offered Off or Read alone. Read + write is offered only for a group with `writes: true`: its writes run at once, and with `undo` set each one's line in the chat has Undo, which calls `undo(caller, { tool, args, result })`; the model is told what was undone. Cards drafted one after another show as one stack with Save all. Use `mcpServerTools` (an SDK `McpServer`), `mcpFetchTools` (a server served as a fetch handler, any SDK), `remoteMcpTools` or `plainTools`.
102
102
  - **Web.** `fetch` is a plain GET from the Worker (10 s, 2 MB, never the app's own hosts or private addresses). ScrapeQL's own tools join over its MCP API once an admin pastes a Cloudflare Access service token (`PUT /web/scrapeql`). A Worker on ScrapeQL's own Cloudflare account passes its service binding instead, `scrapeql: { url: 'https://scrapeql/mcp', fetch: env.SCRAPEQL.fetch.bind(env.SCRAPEQL) }`: no token is stored, the tools are always on and Settings shows the link with a Test.
103
103
  - **Hand off and advice.** The `escalate` tool hands one task to a higher tier (the person sets next, any or only when asked); Anthropic's advisor tool lets a higher tier send a plan, at most two an answer.
104
- - **Chats** stream as server-sent events (`POST /chat`); closing the request stops the answer and keeps what was said. Past 150k tokens, or on `/compact`, the history sent to the model becomes a summary. Run `assistant.purge()` once a day to drop chats 30 days after their last message.
104
+ - **Chats** run on the agent (`./agent`, `LumenAgent`, below): the app routes `POST /chat` and each chat's reads, cards and Undo to its own agent, and `assistantRoutes` answers `POST /chat` with 410 `moved`. Chats saved by the old turn loop stay readable (`GET /chats`, `GET|DELETE /chats/:id`) until `assistant.purge()` drops them 30 days after their last message.
105
105
  - **Background work** an app runs for a person (a score, a summary) is `assistant.complete(caller, { task, system, prompt, images?, maxTokens })`: one answer on the task's tier (`tasks`, so the person picks its model in Settings ▸ Models), no chat and no tools (`images`, base64 with their media type, are read with the prompt: a scanned page, a screenshot), billed to their payer and counted in their spend and allowance like a chat turn. It throws `AssistantError` `not_connected`, `app_cap` or `own_cap` when nobody can pay, so the caller waits and tries later.
106
106
 
107
107
  ### Commands, `@` and `#`
@@ -1,4 +1,4 @@
1
- import type { AllowanceRequest, AllowanceState, AllowanceUnit, AssistantAccess, AssistantChat, AssistantChatRow, AssistantMessage, AssistantOwnWay, AssistantProvider, AssistantStatus, DraftItem, StepItem } from '@columenlabs/lumen-ui-types/assistant';
1
+ import type { AllowanceRequest, AllowanceState, AllowanceUnit, AssistantAccess, AssistantChat, AssistantChatRow, AssistantMessage, AssistantOwnWay, AssistantProvider, AssistantStatus } from '@columenlabs/lumen-ui-types/assistant';
2
2
  import type { AgentTurnEnd, AgentTurnPlan } from '../agent/agent.js';
3
3
  import { type BearingsExtra, type BearingsNow } from './bearings.js';
4
4
  import { type ModelDef, type TaskDef, type TierDef } from './models.js';
@@ -173,7 +173,6 @@ export declare class AssistantError extends Error {
173
173
  readonly status: number;
174
174
  constructor(message: string, code: string, status?: number);
175
175
  }
176
- type Emit = (event: string, data: unknown) => void;
177
176
  /** What a Think turn calls this turn: what one turn asks besides the message itself. */
178
177
  export interface AgentTurnInput {
179
178
  message: string;
@@ -262,37 +261,17 @@ export declare class Assistant {
262
261
  removeChat(caller: Caller, id: string): Promise<void>;
263
262
  /** Deletes chats past `keepDays` since their last message; run it once a day. */
264
263
  purge(): Promise<number>;
265
- private writeChat;
266
264
  /** Opens the tools the person allows: each group's, then the web's. */
267
265
  /** The tool groups (and the web) at the person's access, not opened yet. */
268
266
  private sourcesOf;
269
- private openTools;
270
- private toolsFor;
271
- /** `batch`: any of the reads, up to BATCH_MAX at once, as one step. Null with no reads. */
272
- private batchTool;
273
- /** One answer as server-sent events. Abort `signal` to stop it. */
274
- turnStream(caller: Caller, req: AssistantMessage, signal?: AbortSignal): ReadableStream<Uint8Array>;
275
- turn(caller: Caller, req: AssistantMessage, emit: Emit, signal?: AbortSignal): Promise<void>;
276
267
  /** What the kit adds to the app's instructions: tools, drafts, hand off, advice, limits. */
277
268
  private rules;
278
269
  /** The advisor for this answer, or null when off. Never weaker than the model it advises. */
279
270
  private advisorFor;
280
- private escalateTool;
281
271
  /** What the model is asked: an app command's prompt, else the message as typed. */
282
272
  private expand;
283
273
  /** The tiers the person's message asks for by name ("go deeper" is the next one up). */
284
274
  private askedFor;
285
- private handOff;
286
- /** One tool call: a draft card for a write, else the call itself, timed. */
287
- private runTool;
288
- /** A batch of reads: each runs as its own call (the same read twice runs once), in parallel, shown as one step. */
289
- private runBatch;
290
- /** Model calls and tool rounds until the model answers; returns its words. */
291
- private loop;
292
- /** The loop on OpenAI's Responses API: the same tools, Stop, caps and rounds as Claude's. */
293
- private loopOpenAI;
294
- /** The loop on Anthropic's Messages API, with the advisor and prompt caching. */
295
- private loopClaude;
296
275
  /** Swaps the history for a short summary. False with nothing to compact. */
297
276
  /**
298
277
  * One plain answer from OpenAI, metered on `s`: no tools, no chat. Streamed and read from the raw
@@ -300,7 +279,6 @@ export declare class Assistant {
300
279
  * output cap and may send its words only as deltas.
301
280
  */
302
281
  private openaiOnce;
303
- private compact;
304
282
  /**
305
283
  * One prompt answered on a task's tier as the person: no chat, no tools. It is for background
306
284
  * work an app runs for someone (a job's fit score, a summary), billed to their payer and capped
@@ -320,8 +298,6 @@ export declare class Assistant {
320
298
  usd: number;
321
299
  model: string;
322
300
  }>;
323
- /** How the person's cards ended since the last answer, once each. */
324
- private cardNews;
325
301
  /** Starts a person's ChatGPT plan sign-in: the address to open in a new tab. */
326
302
  startSignin(caller: Caller, provider: AssistantProvider): Promise<{
327
303
  url: string;
@@ -353,10 +329,5 @@ export declare class Assistant {
353
329
  detail: string;
354
330
  at: number;
355
331
  }>;
356
- /** Saves (runs, as the person) or dismisses a drafted card. Access is checked again first. */
357
- settleDraft(caller: Caller, chatId: string, draftId: string, action: 'save' | 'dismiss'): Promise<DraftItem>;
358
- /** Takes back one change a write made at once, through its group's `undo`. */
359
- undoWrite(caller: Caller, chatId: string, stepId: string): Promise<StepItem>;
360
332
  }
361
333
  export declare function createAssistant(o: AssistantOptions): Assistant;
362
- export {};