@betterlu/agentlu 1.10.0 → 1.12.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
@@ -236,7 +236,7 @@ Plain text (throws unless `status === "completed"` with non-empty `output_text`)
236
236
  const { text } = await ai.tag.runText({ input: "summarize this" });
237
237
  ```
238
238
 
239
- `timeoutMs` aborts the HTTP attempt and, when `timeout_ms` is omitted, is also sent as the server-side run budget. Constructor `new AgentLu({ timeoutMs: 30_000 })` is the default for calls that omit it.
239
+ `timeoutMs` aborts the HTTP attempt and, when `timeout_ms` is omitted, is also sent as the server-side run budget. Constructor `new AgentLu({ timeoutMs: 30_000 })` is the default for calls that omit it. The server rejects `timeout_ms` below 15 000 ms and `max_output_tokens` below 256 with a 400 naming the minimum; `/v1/chat/completions` applies the same minimum to `max_tokens` / `max_completion_tokens`. Registered defaults below either minimum are clamped up with a once-per-client warning.
240
240
 
241
241
  Upload-and-run:
242
242
 
@@ -359,3 +359,21 @@ const signal = await alu.household.signal({
359
359
  `deduped`). Facts are data, never instructions; urgency `now` requests a batched
360
360
  review, not guaranteed delivery. See [Household signals](../../docs/household-signals.md)
361
361
  for limits, expiry, dedupe and editorial semantics.
362
+
363
+ ## Publishing
364
+
365
+ Every change to this package is published; consumer apps must only use
366
+ published versions (never copy SDK code or hand-roll `/v1` fetch helpers for a
367
+ feature the SDK lacks: add it here and publish).
368
+
369
+ 1. Make the change (after `/v1` contract edits, regenerate `src/generated.ts`
370
+ and confirm `npm run check:contract` from the repo root).
371
+ 2. Bump the version: `npm version <x.y.z> --no-git-tag-version` (minor for new
372
+ methods/fields, patch for fixes, major for breaking changes).
373
+ 3. Add a `CHANGELOG.md` entry for that version.
374
+ 4. Verify: `npm run build` here and `npx vitest run tests/sdk` from the repo root.
375
+ 5. Publish: `npm publish` (runs `prepublishOnly` → build; npm user `betterlu`).
376
+ Check with `npm view @betterlu/agentlu version`.
377
+ 6. Commit the bump with the change, then update consumers to the new range
378
+ (`npm install @betterlu/agentlu@^<x.y.z>`) and switch them to the new API.
379
+
@@ -8,6 +8,77 @@
8
8
  * contract. They describe the bytes on the wire (snake_case); the SDK's own
9
9
  * types are the ergonomic view over them.
10
10
  */
11
+ export interface WireBriefPublishInput {
12
+ "source": string;
13
+ "key": string;
14
+ "kind": "edition" | "report" | "note" | "story";
15
+ "audience": "larry" | "misa" | "both";
16
+ "title": string;
17
+ "dek"?: string;
18
+ "body"?: string;
19
+ "bodyFormat"?: "markdown" | "html";
20
+ "entries"?: Array<{
21
+ "title": string;
22
+ "url"?: string;
23
+ "image"?: string;
24
+ "chips"?: string[];
25
+ "body"?: string;
26
+ }>;
27
+ "images"?: string[];
28
+ "url"?: string;
29
+ "keep"?: boolean;
30
+ "ttlDays"?: number;
31
+ "collection"?: string;
32
+ "sourceLabel"?: string;
33
+ "sourceEmoji"?: string;
34
+ "coverArt"?: boolean;
35
+ "jobRunId"?: string;
36
+ "artifactId"?: string;
37
+ "publishedAt"?: string;
38
+ }
39
+ export interface WireBriefDetail {
40
+ "id": string;
41
+ "source": string;
42
+ "sourceLabel": string;
43
+ "sourceEmoji": string | null;
44
+ "kind": "edition" | "report" | "note" | "story";
45
+ "audience": "larry" | "misa" | "both";
46
+ "title": string;
47
+ "dek": string | null;
48
+ "coverUrl": string | null;
49
+ "coverArtStatus": "none" | "pending" | "ready" | "failed";
50
+ "edition": {
51
+ "hero": string;
52
+ "highlights": string[];
53
+ } | null;
54
+ "keep": boolean;
55
+ "collection": string | null;
56
+ "readingMinutes": number | null;
57
+ "publishedAt": string;
58
+ "bodyFormat": "markdown" | "html";
59
+ "bodyHtml": string | null;
60
+ "frameUrl": string | null;
61
+ "entries": Array<{
62
+ "title": string;
63
+ "url"?: string;
64
+ "image"?: string;
65
+ "chips"?: string[];
66
+ "body"?: string;
67
+ "bodyHtml"?: string;
68
+ }> | null;
69
+ "images": string[];
70
+ "url": string | null;
71
+ "jobRunId": string | null;
72
+ "artifactId": string | null;
73
+ "expiresAt": string | null;
74
+ }
75
+ export interface WireBriefPublishResult {
76
+ "id": string;
77
+ "url": string;
78
+ "coverUrl": string | null;
79
+ "coverArtStatus": "none" | "pending" | "ready" | "failed";
80
+ "updated": boolean;
81
+ }
11
82
  export interface WireHouseholdSignalInput {
12
83
  "source": string;
13
84
  "kind": string;
@@ -59,7 +130,7 @@ export interface WireCreateResponse {
59
130
  "conversation"?: string | {
60
131
  "id": string;
61
132
  };
62
- /** Optional and discouraged. Omit it to use the model's own output limit; values here are applied verbatim. If the limit is reached, the HTTP 200 Response has status `incomplete`, reason `max_output_tokens`, and may retain partial output. */
133
+ /** Optional and discouraged. Minimum 256 tokens; omit it to use the model's own output limit; values here are applied verbatim. A registered client default below the minimum is clamped up. If the limit is reached, the HTTP 200 Response has status `incomplete`, reason `max_output_tokens`, and may retain partial output. */
63
134
  "max_output_tokens"?: number;
64
135
  "temperature"?: number;
65
136
  "text"?: {
@@ -85,13 +156,13 @@ export interface WireCreateResponse {
85
156
  "tool_choice"?: "auto" | "none" | "required";
86
157
  "metadata"?: Record<string, string>;
87
158
  "include"?: Array<"reasoning" | "rounds" | "subagents" | "artifacts">;
88
- /** Which agent runs the request. The recommended general machine agent is `api`, which has no persona: `instructions` replace its system prompt. Pin `fast` for the chat-tuned version. `direct` selects the direct tier: the profile-free `api` agent with no tools and no session (see the Tiers section). `household/<slug>` runs a household agent built in the Agents studio (list them at GET /v1/agents). An `<app>/<name>` id runs an agent the caller's app declared at registration. `research` is an alias for `thorough` with Report output (a sourced report artifact). Retired ids (`mealu`, `nestlu`, `kitchen`, `waterlu`, `money`, `swarm`, `storylu`, `google-research`, `google-image`, `android`) return HTTP 400 `unknown_agent` with a pointer to their successor; the Android phone is now the `android` tool family on `assistant`. */
89
- "agent"?: "auto" | "fast" | "thorough" | "assistant" | "code" | "google" | "image" | "api" | "digest" | "herald" | "cradle" | "custom" | "direct" | string | "mealu" | "nestlu" | "kitchen" | "waterlu" | "money" | "swarm" | "stage" | "roleplay" | "storylu" | "google-research" | "google-image" | "android" | "research";
159
+ /** Which agent runs the request. The recommended general machine agent is `api`, which has no persona: `instructions` replace its system prompt. Pin `fast` for the chat-tuned version. `direct` selects the direct tier: the profile-free `api` agent with no tools and no session (see the Tiers section). `household/<slug>` runs a household agent built in the Agents studio (list them at GET /v1/agents). An `<app>/<name>` id runs an agent the caller's app declared at registration. `research` is an alias for `thorough` with Report output (a sourced report artifact). Retired ids (`mealu`, `nestlu`, `kitchen`, `waterlu`, `money`, `code`, `image`, `swarm`, `storylu`, `google-research`, `google-image`, `android`) return HTTP 400 `unknown_agent` with a pointer to their successor; Code and Image merged into `assistant` (AgentLu). The Android phone is now the `android` tool family on `assistant`. */
160
+ "agent"?: "auto" | "fast" | "thorough" | "assistant" | "google" | "api" | "digest" | "herald" | "cradle" | "custom" | "direct" | string | "mealu" | "nestlu" | "kitchen" | "waterlu" | "money" | "code" | "image" | "swarm" | "stage" | "roleplay" | "storylu" | "google-research" | "google-image" | "android" | "research";
90
161
  /** Thinking level. Explicit `effort: "off"` is honored; other requests are clamped to the selected model's supported capabilities. The SDK does not promise provider benchmark parity. */
91
162
  "reasoning"?: {
92
163
  "effort"?: "off" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max";
93
164
  };
94
- /** Wall clock for this run. Default: the use-case tier's (45s instant / 180s standard / 600s deep). */
165
+ /** Wall clock for this run. Minimum 15000 ms (15 s); a registered client default below it is clamped up. Default: the use-case tier's (45s instant / 180s standard / 600s deep). */
95
166
  "timeout_ms"?: number;
96
167
  /** Provider attempts for this run (1 = none). Bounds model-chain fallbacks. Default: the use-case tier's (instant 1, standard 2, deep 3) when the client declares a profile; without one the run keeps the pre-tier budget (the direct tier walks its whole chain, the agent tier does not fall back). */
97
168
  "attempts"?: number;
@@ -164,9 +235,9 @@ export interface WireRegisterClientRequest {
164
235
  /** Run defaults applied when a request omits the field: request > registered client default > use-case tier > agent/profile default. The built-in `store` default is true. Register one client per use-case (e.g. mealu-enrich) with its system prompt and tools baked in. */
165
236
  "defaults"?: {
166
237
  "backend"?: "pi";
167
- "agent"?: "auto" | "fast" | "thorough" | "assistant" | "code" | "google" | "image" | "api" | "digest" | "herald" | "cradle" | "custom" | "direct" | string | "mealu" | "nestlu" | "kitchen" | "waterlu" | "money" | "swarm" | "stage" | "roleplay" | "storylu" | "google-research" | "google-image" | "android" | "research";
238
+ "agent"?: "auto" | "fast" | "thorough" | "assistant" | "google" | "api" | "digest" | "herald" | "cradle" | "custom" | "direct" | string | "mealu" | "nestlu" | "kitchen" | "waterlu" | "money" | "code" | "image" | "swarm" | "stage" | "roleplay" | "storylu" | "google-research" | "google-image" | "android" | "research";
168
239
  "model"?: string;
169
- "modelRoute"?: "chat.quick" | "chat.household" | "chat.deep" | "chat.code" | "device" | "background.digest" | "utility" | "memory.extract" | "memory.judge" | "memory.consolidate";
240
+ "modelRoute"?: "chat.quick" | "chat.household" | "chat.deep" | "device" | "background.digest" | "utility" | "memory.extract" | "memory.judge" | "memory.consolidate";
170
241
  "instructions"?: string;
171
242
  "temperature"?: number;
172
243
  "store"?: boolean;
@@ -215,12 +286,12 @@ export interface WireRegisterClientRequest {
215
286
  /** Run defaults applied when a request omits the field: request > registered client default > use-case tier > agent/profile default. The built-in `store` default is true. Register one client per use-case (e.g. mealu-enrich) with its system prompt and tools baked in. */
216
287
  export interface WireClientDefaults {
217
288
  "backend"?: "pi";
218
- /** Which agent runs the request. The recommended general machine agent is `api`, which has no persona: `instructions` replace its system prompt. Pin `fast` for the chat-tuned version. `direct` selects the direct tier: the profile-free `api` agent with no tools and no session (see the Tiers section). `household/<slug>` runs a household agent built in the Agents studio (list them at GET /v1/agents). An `<app>/<name>` id runs an agent the caller's app declared at registration. `research` is an alias for `thorough` with Report output (a sourced report artifact). Retired ids (`mealu`, `nestlu`, `kitchen`, `waterlu`, `money`, `swarm`, `storylu`, `google-research`, `google-image`, `android`) return HTTP 400 `unknown_agent` with a pointer to their successor; the Android phone is now the `android` tool family on `assistant`. */
219
- "agent"?: "auto" | "fast" | "thorough" | "assistant" | "code" | "google" | "image" | "api" | "digest" | "herald" | "cradle" | "custom" | "direct" | string | "mealu" | "nestlu" | "kitchen" | "waterlu" | "money" | "swarm" | "stage" | "roleplay" | "storylu" | "google-research" | "google-image" | "android" | "research";
289
+ /** Which agent runs the request. The recommended general machine agent is `api`, which has no persona: `instructions` replace its system prompt. Pin `fast` for the chat-tuned version. `direct` selects the direct tier: the profile-free `api` agent with no tools and no session (see the Tiers section). `household/<slug>` runs a household agent built in the Agents studio (list them at GET /v1/agents). An `<app>/<name>` id runs an agent the caller's app declared at registration. `research` is an alias for `thorough` with Report output (a sourced report artifact). Retired ids (`mealu`, `nestlu`, `kitchen`, `waterlu`, `money`, `code`, `image`, `swarm`, `storylu`, `google-research`, `google-image`, `android`) return HTTP 400 `unknown_agent` with a pointer to their successor; Code and Image merged into `assistant` (AgentLu). The Android phone is now the `android` tool family on `assistant`. */
290
+ "agent"?: "auto" | "fast" | "thorough" | "assistant" | "google" | "api" | "digest" | "herald" | "cradle" | "custom" | "direct" | string | "mealu" | "nestlu" | "kitchen" | "waterlu" | "money" | "code" | "image" | "swarm" | "stage" | "roleplay" | "storylu" | "google-research" | "google-image" | "android" | "research";
220
291
  /** ModelConfig id (GET /v1/models). Stock clients may also use an agent name here; prefer explicit `agent` for machine calls. */
221
292
  "model"?: string;
222
293
  /** Task route whose pool order and effort apply to automatic model selection. Mutually exclusive with model. Explicit request models, builtin chat agents, and agent model pins win; app-owned and api agents inherit the client route. */
223
- "modelRoute"?: "chat.quick" | "chat.household" | "chat.deep" | "chat.code" | "device" | "background.digest" | "utility" | "memory.extract" | "memory.judge" | "memory.consolidate";
294
+ "modelRoute"?: "chat.quick" | "chat.household" | "chat.deep" | "device" | "background.digest" | "utility" | "memory.extract" | "memory.judge" | "memory.consolidate";
224
295
  /** System prompt for every run of this client. */
225
296
  "instructions"?: string;
226
297
  "temperature"?: number;
@@ -251,8 +322,9 @@ export interface WireClientDefaults {
251
322
  "url": string;
252
323
  "allowed_tools"?: string[];
253
324
  }>;
325
+ /** Default wall clock when the request omits `timeout_ms`. Values below 15000 ms are clamped up at run time (with a once-per-client warning). */
254
326
  "timeoutMs"?: number;
255
- /** Default output cap when the request omits `max_output_tokens`. The use-case tier supplies one when this is unset (instant 2048, deep 8192, standard none); requests always win. Honored for defaults written after this release: a value stored earlier stays inert until the app re-declares its defaults (or the console edits them), so a re-enable can never silently cap runs that used to complete. */
327
+ /** Default output cap when the request omits `max_output_tokens`. Values below 256 tokens are clamped up at run time (with a once-per-client warning). The use-case tier supplies one when this is unset (instant 2048, deep 8192, standard none); requests always win. Honored for defaults written after this release: a value stored earlier stays inert until the app re-declares its defaults (or the console edits them), so a re-enable can never silently cap runs that used to complete. */
256
328
  "maxOutputTokens"?: number;
257
329
  /** Provider attempts per run (1 = none). Bounds model-chain fallbacks, and is the background queue's retry budget. Defaults to the tier's (instant 1, standard 2, deep 3) when `use_case_profile.priority` is declared; without one the run keeps the pre-tier budget. */
258
330
  "attempts"?: number;
@@ -281,7 +353,7 @@ export interface WireAppAgentDeclaration {
281
353
  }
282
354
  export interface WireCreateThreadRequest {
283
355
  "title"?: string;
284
- "agent"?: "auto" | "fast" | "thorough" | "assistant" | "code" | "google" | "image" | "api" | "digest" | "herald" | "cradle" | "custom" | "research" | string;
356
+ "agent"?: "auto" | "fast" | "thorough" | "assistant" | "google" | "api" | "digest" | "herald" | "cradle" | "custom" | "research" | string;
285
357
  "model"?: string;
286
358
  "person"?: string | null;
287
359
  "owner"?: "client" | "person";
@@ -317,7 +389,7 @@ export interface WireResponse {
317
389
  "created_at": number;
318
390
  "status": "queued" | "in_progress" | "completed" | "failed" | "incomplete" | "cancelled";
319
391
  "backend": "pi";
320
- "agent": "auto" | "fast" | "thorough" | "assistant" | "code" | "google" | "image" | "api" | "digest" | "herald" | "cradle" | "custom";
392
+ "agent": "auto" | "fast" | "thorough" | "assistant" | "google" | "api" | "digest" | "herald" | "cradle" | "custom";
321
393
  "model": string;
322
394
  "conversation"?: {
323
395
  "id": string;
@@ -387,7 +459,7 @@ export interface WireResponse {
387
459
  "thread_id"?: string | null;
388
460
  "retries"?: number;
389
461
  "effective_model"?: string | null;
390
- "model_route"?: "chat.quick" | "chat.household" | "chat.deep" | "chat.code" | "device" | "background.digest" | "utility" | "memory.extract" | "memory.judge" | "memory.consolidate";
462
+ "model_route"?: "chat.quick" | "chat.household" | "chat.deep" | "device" | "background.digest" | "utility" | "memory.extract" | "memory.judge" | "memory.consolidate";
391
463
  "service_tier"?: "standard" | "priority";
392
464
  "execution_path"?: string | null;
393
465
  "queue_wait_ms"?: number | null;
@@ -507,7 +579,7 @@ export interface WireThread {
507
579
  "created_at": number;
508
580
  "updated_at": number;
509
581
  "title": string;
510
- "agent": "auto" | "fast" | "thorough" | "assistant" | "code" | "google" | "image" | "api" | "digest" | "herald" | "cradle" | "custom";
582
+ "agent": "auto" | "fast" | "thorough" | "assistant" | "google" | "api" | "digest" | "herald" | "cradle" | "custom";
511
583
  "model": string | null;
512
584
  /** "api" for threads created through /v1; "chat" when a human started it. */
513
585
  "origin": string;
@@ -546,9 +618,9 @@ export interface WireClient {
546
618
  "allow_person_threads"?: boolean;
547
619
  "defaults"?: {
548
620
  "backend"?: "pi";
549
- "agent"?: "auto" | "fast" | "thorough" | "assistant" | "code" | "google" | "image" | "api" | "digest" | "herald" | "cradle" | "custom" | "direct" | string | "mealu" | "nestlu" | "kitchen" | "waterlu" | "money" | "swarm" | "stage" | "roleplay" | "storylu" | "google-research" | "google-image" | "android" | "research";
621
+ "agent"?: "auto" | "fast" | "thorough" | "assistant" | "google" | "api" | "digest" | "herald" | "cradle" | "custom" | "direct" | string | "mealu" | "nestlu" | "kitchen" | "waterlu" | "money" | "code" | "image" | "swarm" | "stage" | "roleplay" | "storylu" | "google-research" | "google-image" | "android" | "research";
550
622
  "model"?: string;
551
- "modelRoute"?: "chat.quick" | "chat.household" | "chat.deep" | "chat.code" | "device" | "background.digest" | "utility" | "memory.extract" | "memory.judge" | "memory.consolidate";
623
+ "modelRoute"?: "chat.quick" | "chat.household" | "chat.deep" | "device" | "background.digest" | "utility" | "memory.extract" | "memory.judge" | "memory.consolidate";
552
624
  "instructions"?: string;
553
625
  "temperature"?: number;
554
626
  "store"?: boolean;
@@ -672,7 +744,7 @@ export interface WireResponseList {
672
744
  "created_at": number;
673
745
  "status": "queued" | "in_progress" | "completed" | "failed" | "incomplete" | "cancelled";
674
746
  "backend": "pi";
675
- "agent": "auto" | "fast" | "thorough" | "assistant" | "code" | "google" | "image" | "api" | "digest" | "herald" | "cradle" | "custom";
747
+ "agent": "auto" | "fast" | "thorough" | "assistant" | "google" | "api" | "digest" | "herald" | "cradle" | "custom";
676
748
  "model": string;
677
749
  "conversation"?: {
678
750
  "id": string;
@@ -737,7 +809,7 @@ export interface WireResponseList {
737
809
  "thread_id"?: string | null;
738
810
  "retries"?: number;
739
811
  "effective_model"?: string | null;
740
- "model_route"?: "chat.quick" | "chat.household" | "chat.deep" | "chat.code" | "device" | "background.digest" | "utility" | "memory.extract" | "memory.judge" | "memory.consolidate";
812
+ "model_route"?: "chat.quick" | "chat.household" | "chat.deep" | "device" | "background.digest" | "utility" | "memory.extract" | "memory.judge" | "memory.consolidate";
741
813
  "service_tier"?: "standard" | "priority";
742
814
  "execution_path"?: string | null;
743
815
  "queue_wait_ms"?: number | null;
@@ -807,7 +879,7 @@ export interface WireThreadList {
807
879
  "created_at": number;
808
880
  "updated_at": number;
809
881
  "title": string;
810
- "agent": "auto" | "fast" | "thorough" | "assistant" | "code" | "google" | "image" | "api" | "digest" | "herald" | "cradle" | "custom";
882
+ "agent": "auto" | "fast" | "thorough" | "assistant" | "google" | "api" | "digest" | "herald" | "cradle" | "custom";
811
883
  "model": string | null;
812
884
  "origin": string;
813
885
  "end_user"?: string | null;
package/dist/index.d.ts CHANGED
@@ -1,3 +1,6 @@
1
+ import type { WireBriefPublishInput, WireBriefPublishResult, WireBriefDetail } from "./generated.js";
2
+ export type { WireBriefPublishInput, WireBriefPublishResult, WireBriefDetail } from "./generated.js";
3
+ export type { WireBriefPublishInput as BriefPublishInput, WireBriefPublishResult as BriefPublishResult, WireBriefDetail as BriefDetail } from "./generated.js";
1
4
  /**
2
5
  * @betterlu/agentlu - client for the agentlu service API.
3
6
  *
@@ -668,6 +671,10 @@ export declare class AgentLu {
668
671
  delete: (id: string) => Promise<unknown>;
669
672
  messages: (id: string) => Promise<unknown>;
670
673
  };
674
+ readonly briefs: {
675
+ publish: (input: WireBriefPublishInput, opts?: RequestOptions) => Promise<WireBriefPublishResult>;
676
+ get: (id: string, opts?: RequestOptions) => Promise<WireBriefDetail>;
677
+ };
671
678
  readonly household: {
672
679
  signal: (input: WireHouseholdSignalInput, opts?: RequestOptions) => Promise<WireHouseholdSignalResult>;
673
680
  };
package/dist/index.js CHANGED
@@ -728,6 +728,10 @@ export class AgentLu {
728
728
  delete: (id) => this.request("DELETE", `/threads/${encodeURIComponent(id)}`),
729
729
  messages: (id) => this.request("GET", `/threads/${encodeURIComponent(id)}/messages`),
730
730
  };
731
+ briefs = {
732
+ publish: (input, opts) => this.request("POST", "/briefs", input, opts),
733
+ get: (id, opts) => this.request("GET", `/briefs/${encodeURIComponent(id)}`, undefined, opts),
734
+ };
731
735
  household = {
732
736
  signal: (input, opts) => this.request("POST", "/household/signals", input, opts),
733
737
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@betterlu/agentlu",
3
- "version": "1.10.0",
3
+ "version": "1.12.0",
4
4
  "description": "Client for the agentlu service API (/v1). Or just use the openai SDK pointed at http://localhost:8912/v1.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",