@columenlabs/lumen-ai 0.1.228 → 0.1.230

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
@@ -72,6 +72,7 @@ const assistant = createAssistant({
72
72
  name: 'Helper',
73
73
  system: 'You help people with their notes. Use the notes tools for facts.',
74
74
  hideModel: true, // never names its model, provider or tier; asked, it is just "Helper"
75
+ // pickTier: false, // the app picks each turn's tier (agentTurn input.tier); no tier menu in the panel
75
76
  // Smallest first. The app names them; a person picks each tier's model and effort.
76
77
  tiers: [
77
78
  { id: 'fast', label: 'Fast', about: 'Quick lookups', model: 'claude-haiku-5-5' },
@@ -218,7 +218,12 @@ export declare abstract class LumenAgent<Env = unknown> extends Think<Env> {
218
218
  dismissCard(id: string): AgentCard;
219
219
  /** The person undid a write made at once. */
220
220
  undoCard(id: string): Promise<AgentCard>;
221
- /** Think compacts the chat past `COMPACT_AT` tokens, on the last turn's model and key. */
221
+ /**
222
+ * Past this many tokens Think summarizes the chat's older part, out of sight of the person
223
+ * (`COMPACT_AT` by default). An app overrides it to keep its chats shorter.
224
+ */
225
+ protected compactAt(): number;
226
+ /** Think compacts the chat past `compactAt()` tokens, on the last turn's model and key. */
222
227
  configureSession(session: Session): Session;
223
228
  /** Never read: `beforeTurn` gives every turn its own model. */
224
229
  getModel(): ThinkModel;
@@ -481,11 +481,18 @@ export class LumenAgent extends Think {
481
481
  this.sql `UPDATE lumen_cards SET told = 1 WHERE id = ${r.id}`;
482
482
  return cardNews(rows.map(cardOf));
483
483
  }
484
- /** Think compacts the chat past `COMPACT_AT` tokens, on the last turn's model and key. */
484
+ /**
485
+ * Past this many tokens Think summarizes the chat's older part, out of sight of the person
486
+ * (`COMPACT_AT` by default). An app overrides it to keep its chats shorter.
487
+ */
488
+ compactAt() {
489
+ return COMPACT_AT;
490
+ }
491
+ /** Think compacts the chat past `compactAt()` tokens, on the last turn's model and key. */
485
492
  configureSession(session) {
486
493
  return session
487
494
  .onCompaction(createCompactFunction({ summarize: (prompt) => this.#summarize(prompt) }))
488
- .compactAfter(COMPACT_AT);
495
+ .compactAfter(this.compactAt());
489
496
  }
490
497
  async #summarize(prompt) {
491
498
  const last = this.#last;
@@ -142,6 +142,12 @@ export interface AssistantOptions {
142
142
  * it, and answers "which model are you?" with its own `name`. Off by default (it names them).
143
143
  */
144
144
  hideModel?: boolean;
145
+ /**
146
+ * Who picks the tier a chat turn runs on. False: the app does, each turn, through
147
+ * `AgentTurnInput.tier` (any of its tiers; left out, the chat task's tier). The person's saved
148
+ * tier and task picks are ignored and the panel offers no tier menu. True by default.
149
+ */
150
+ pickTier?: boolean;
145
151
  /**
146
152
  * The app's slash commands, listed in the composer when the person types `/`. A message
147
153
  * `/name words` is sent to the model as `prompt` with `{args}` replaced by the words (or what the
@@ -216,7 +216,7 @@ export class Assistant {
216
216
  }
217
217
  /** The tier the person's chat runs on: their pick, else the chat task's start tier. */
218
218
  async mainTier(caller, task = 'chat') {
219
- const p = await this.state.person(caller.id);
219
+ const p = this.o.pickTier === false ? {} : await this.state.person(caller.id);
220
220
  const startId = p.tasks?.[task] ?? this.tasks.find((t) => t.id === task)?.tier;
221
221
  return (this.tierById(task === 'chat' ? (p.tier ?? startId) : startId) ?? this.tiers[0]);
222
222
  }
@@ -240,7 +240,9 @@ export class Assistant {
240
240
  async agentTurn(caller, input) {
241
241
  const message = input.message.trim();
242
242
  const picked = await this.mainTier(caller);
243
- const lower = input.tier && !this.above(picked).some((t) => t.id === input.tier)
243
+ // The app picks the tier (pickTier: false): any of its tiers, never a hand off.
244
+ const byApp = this.o.pickTier === false;
245
+ const lower = input.tier && (byApp || !this.above(picked).some((t) => t.id === input.tier))
244
246
  ? this.tierById(input.tier)
245
247
  : undefined;
246
248
  const main = await this.session(caller, lower ?? picked);
@@ -264,7 +266,7 @@ export class Assistant {
264
266
  const p = await this.state.person(caller.id);
265
267
  const policy = p.hand_off ?? 'next';
266
268
  const advisor = await this.advisorFor(caller, p.advice, main);
267
- const handTo = input.tier ? this.above(main.tier).find((t) => t.id === input.tier) : undefined;
269
+ const handTo = input.tier && !byApp ? this.above(main.tier).find((t) => t.id === input.tier) : undefined;
268
270
  const appSystem = typeof this.o.system === 'string' ? this.o.system : await this.o.system(caller);
269
271
  const asked = await this.expand(caller, message);
270
272
  const told = await bearings({
@@ -551,6 +553,7 @@ export class Assistant {
551
553
  admin: caller.admin,
552
554
  tier: main.id,
553
555
  tiers,
556
+ ...(this.o.pickTier === false ? { pick_tier: false } : {}),
554
557
  models: this.models.map((m) => ({
555
558
  id: m.id,
556
559
  label: m.label,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@columenlabs/lumen-ai",
3
- "version": "0.1.228",
3
+ "version": "0.1.230",
4
4
  "description": "Lumen's assistant and agent parts: a chat assistant's server (Claude tiers, tools over MCP, the web, hand off, spend caps), serving an MCP server from a Worker, read-only tool sets and metered tool calls.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -52,8 +52,8 @@
52
52
  "@ai-sdk/openai": "4.0.108",
53
53
  "@anthropic-ai/sdk": "0.133.0",
54
54
  "@cloudflare/think": "0.23.0",
55
- "@columenlabs/lumen-ops": "0.1.228",
56
- "@columenlabs/lumen-ui-types": "0.1.228",
55
+ "@columenlabs/lumen-ops": "0.1.230",
56
+ "@columenlabs/lumen-ui-types": "0.1.230",
57
57
  "agents": "0.32.0",
58
58
  "ai": "7.0.162",
59
59
  "just-bash": "3.6.0",