@betterlu/agentlu 1.8.0 → 1.9.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 +22 -1
- package/dist/generated.d.ts +23 -17
- package/dist/index.d.ts +21 -2
- package/dist/index.js +39 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -54,7 +54,7 @@ const { data } = await alu.llm.json<{ items: string[] }>(
|
|
|
54
54
|
);
|
|
55
55
|
for await (const event of alu.llm.stream("Count to three")) console.log(event.type);
|
|
56
56
|
|
|
57
|
-
// Agent tier (default agent `api`; pin fast/
|
|
57
|
+
// Agent tier (default agent `api`; pin fast/thorough/… or "<app>/<name>").
|
|
58
58
|
const run = await alu.agent.run({ agent: "fast", input: "what changed in node 24?" });
|
|
59
59
|
const done = await alu.agent.background({ input: "research this deeply" }, { timeoutMs: 600_000 });
|
|
60
60
|
```
|
|
@@ -89,6 +89,27 @@ try {
|
|
|
89
89
|
| `incomplete` | the run finished without a complete answer |
|
|
90
90
|
| `internal` | anything else, including a cancelled run and the `systemone_unconfigured` config boundary (never retried, so it surfaces instead of degrading) |
|
|
91
91
|
|
|
92
|
+
## Waiting for agentlu on boot
|
|
93
|
+
|
|
94
|
+
Apps that PM2 starts alongside agentlu (reboot, `pm2 restart agentlu`) should
|
|
95
|
+
wait for it before registering, in the background, so they don't warn on the
|
|
96
|
+
first `ECONNREFUSED`. `waitForReady` polls `/health` with backoff while it is
|
|
97
|
+
unreachable and resolves `true`, or `false` at the deadline. It never throws.
|
|
98
|
+
|
|
99
|
+
```ts
|
|
100
|
+
void (async () => {
|
|
101
|
+
const up = await alu.waitForReady({
|
|
102
|
+
timeoutMs: 90_000,
|
|
103
|
+
onWait: ({ attempt }) => attempt === 1 && log.info("waiting for agentlu"),
|
|
104
|
+
});
|
|
105
|
+
try {
|
|
106
|
+
await useCases.ensure();
|
|
107
|
+
} catch (err) {
|
|
108
|
+
log.warn("agentlu register failed", { err, waited: up });
|
|
109
|
+
}
|
|
110
|
+
})();
|
|
111
|
+
```
|
|
112
|
+
|
|
92
113
|
## Bulk uploads and background runs
|
|
93
114
|
|
|
94
115
|
```ts
|
package/dist/generated.d.ts
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
export interface WireCreateResponse {
|
|
12
12
|
/** Execution backend. */
|
|
13
13
|
"backend"?: "pi";
|
|
14
|
-
/** Model id, or an agent name (stock OpenAI clients can only set `model`). Harness-qualified ids run other runtimes: `google/<id>` selects an Antigravity model
|
|
14
|
+
/** Model id, or an agent name (stock OpenAI clients can only set `model`). Harness-qualified ids run other runtimes: `google/<id>` selects an Antigravity model on the Google agent. See GET /v1/models and GET /v1/models?harness=google. */
|
|
15
15
|
"model"?: string;
|
|
16
16
|
"input"?: string | Array<{
|
|
17
17
|
"role": "user" | "assistant" | "system" | "developer";
|
|
@@ -70,8 +70,8 @@ export interface WireCreateResponse {
|
|
|
70
70
|
"tool_choice"?: "auto" | "none" | "required";
|
|
71
71
|
"metadata"?: Record<string, string>;
|
|
72
72
|
"include"?: Array<"reasoning" | "rounds" | "subagents" | "artifacts">;
|
|
73
|
-
/** 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.
|
|
74
|
-
"agent"?: "auto" | "fast" | "thorough" | "assistant" | "
|
|
73
|
+
/** 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`. */
|
|
74
|
+
"agent"?: "auto" | "fast" | "thorough" | "assistant" | "code" | "google" | "image" | "api" | "digest" | "cradle" | "roleplay" | "custom" | "direct" | string | "mealu" | "nestlu" | "kitchen" | "waterlu" | "money" | "swarm" | "stage" | "storylu" | "google-research" | "google-image" | "android" | "research";
|
|
75
75
|
/** 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. */
|
|
76
76
|
"reasoning"?: {
|
|
77
77
|
"effort"?: "off" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max";
|
|
@@ -84,7 +84,6 @@ export interface WireCreateResponse {
|
|
|
84
84
|
"person"?: string | null;
|
|
85
85
|
/** person = attribute the thread to the human matching `person` (shows in their sidebar). Requires the client flag `allow_person_threads`; without it a stored/threaded request is rejected with HTTP 403 `person_threads_not_allowed`. A sessionless `store: false` run creates no thread, so there is nothing to attribute and the flag is not consulted. */
|
|
86
86
|
"owner"?: "client" | "person";
|
|
87
|
-
"project"?: string;
|
|
88
87
|
/** Opaque caller-side identity (one of your users or devices). Stored on the response and, for stored runs, its thread; filter with `?end_user=`. */
|
|
89
88
|
"end_user"?: string;
|
|
90
89
|
}
|
|
@@ -150,7 +149,7 @@ export interface WireRegisterClientRequest {
|
|
|
150
149
|
/** 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. */
|
|
151
150
|
"defaults"?: {
|
|
152
151
|
"backend"?: "pi";
|
|
153
|
-
"agent"?: "auto" | "fast" | "thorough" | "assistant" | "
|
|
152
|
+
"agent"?: "auto" | "fast" | "thorough" | "assistant" | "code" | "google" | "image" | "api" | "digest" | "cradle" | "roleplay" | "custom" | "direct" | string | "mealu" | "nestlu" | "kitchen" | "waterlu" | "money" | "swarm" | "stage" | "storylu" | "google-research" | "google-image" | "android" | "research";
|
|
154
153
|
"model"?: string;
|
|
155
154
|
"instructions"?: string;
|
|
156
155
|
"temperature"?: number;
|
|
@@ -200,8 +199,8 @@ export interface WireRegisterClientRequest {
|
|
|
200
199
|
/** 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. */
|
|
201
200
|
export interface WireClientDefaults {
|
|
202
201
|
"backend"?: "pi";
|
|
203
|
-
/** 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.
|
|
204
|
-
"agent"?: "auto" | "fast" | "thorough" | "assistant" | "
|
|
202
|
+
/** 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`. */
|
|
203
|
+
"agent"?: "auto" | "fast" | "thorough" | "assistant" | "code" | "google" | "image" | "api" | "digest" | "cradle" | "roleplay" | "custom" | "direct" | string | "mealu" | "nestlu" | "kitchen" | "waterlu" | "money" | "swarm" | "stage" | "storylu" | "google-research" | "google-image" | "android" | "research";
|
|
205
204
|
/** ModelConfig id (GET /v1/models). Stock clients may also use an agent name here; prefer explicit `agent` for machine calls. */
|
|
206
205
|
"model"?: string;
|
|
207
206
|
/** System prompt for every run of this client. */
|
|
@@ -264,7 +263,7 @@ export interface WireAppAgentDeclaration {
|
|
|
264
263
|
}
|
|
265
264
|
export interface WireCreateThreadRequest {
|
|
266
265
|
"title"?: string;
|
|
267
|
-
"agent"?: "auto" | "fast" | "thorough" | "assistant" | "
|
|
266
|
+
"agent"?: "auto" | "fast" | "thorough" | "assistant" | "code" | "google" | "image" | "api" | "digest" | "cradle" | "roleplay" | "custom" | "research" | string;
|
|
268
267
|
"model"?: string;
|
|
269
268
|
"person"?: string | null;
|
|
270
269
|
"owner"?: "client" | "person";
|
|
@@ -300,7 +299,7 @@ export interface WireResponse {
|
|
|
300
299
|
"created_at": number;
|
|
301
300
|
"status": "queued" | "in_progress" | "completed" | "failed" | "incomplete" | "cancelled";
|
|
302
301
|
"backend": "pi";
|
|
303
|
-
"agent": "auto" | "fast" | "thorough" | "assistant" | "
|
|
302
|
+
"agent": "auto" | "fast" | "thorough" | "assistant" | "code" | "google" | "image" | "api" | "digest" | "cradle" | "roleplay" | "custom";
|
|
304
303
|
"model": string;
|
|
305
304
|
"conversation"?: {
|
|
306
305
|
"id": string;
|
|
@@ -411,7 +410,7 @@ export interface WireResponse {
|
|
|
411
410
|
};
|
|
412
411
|
"android"?: {
|
|
413
412
|
"sessionId"?: string;
|
|
414
|
-
"username"?:
|
|
413
|
+
"username"?: string;
|
|
415
414
|
"ownerId"?: string;
|
|
416
415
|
"status": "active" | "needs_human" | "human_control" | "idle" | "closed" | "interrupted" | "reserved";
|
|
417
416
|
"action"?: string;
|
|
@@ -487,7 +486,7 @@ export interface WireThread {
|
|
|
487
486
|
"created_at": number;
|
|
488
487
|
"updated_at": number;
|
|
489
488
|
"title": string;
|
|
490
|
-
"agent": "auto" | "fast" | "thorough" | "assistant" | "
|
|
489
|
+
"agent": "auto" | "fast" | "thorough" | "assistant" | "code" | "google" | "image" | "api" | "digest" | "cradle" | "roleplay" | "custom";
|
|
491
490
|
"model": string | null;
|
|
492
491
|
/** "api" for threads created through /v1; "chat" when a human started it. */
|
|
493
492
|
"origin": string;
|
|
@@ -526,7 +525,7 @@ export interface WireClient {
|
|
|
526
525
|
"allow_person_threads"?: boolean;
|
|
527
526
|
"defaults"?: {
|
|
528
527
|
"backend"?: "pi";
|
|
529
|
-
"agent"?: "auto" | "fast" | "thorough" | "assistant" | "
|
|
528
|
+
"agent"?: "auto" | "fast" | "thorough" | "assistant" | "code" | "google" | "image" | "api" | "digest" | "cradle" | "roleplay" | "custom" | "direct" | string | "mealu" | "nestlu" | "kitchen" | "waterlu" | "money" | "swarm" | "stage" | "storylu" | "google-research" | "google-image" | "android" | "research";
|
|
530
529
|
"model"?: string;
|
|
531
530
|
"instructions"?: string;
|
|
532
531
|
"temperature"?: number;
|
|
@@ -592,7 +591,8 @@ export interface WireError {
|
|
|
592
591
|
};
|
|
593
592
|
}
|
|
594
593
|
export interface WireAgentInfo {
|
|
595
|
-
|
|
594
|
+
/** A builtin agent id, or `household/<slug>` for an agent built in the household studio. */
|
|
595
|
+
"id": string;
|
|
596
596
|
"object": "agent";
|
|
597
597
|
"profile": string;
|
|
598
598
|
"description": string;
|
|
@@ -604,6 +604,8 @@ export interface WireAgentInfo {
|
|
|
604
604
|
"long_running": boolean;
|
|
605
605
|
/** Runtime that serves this agent. */
|
|
606
606
|
"harness": "pi" | "google";
|
|
607
|
+
/** Household agents only: the capability ids the agent was built with. */
|
|
608
|
+
"capabilities"?: string[];
|
|
607
609
|
}
|
|
608
610
|
export interface WireModelInfo {
|
|
609
611
|
"id": string;
|
|
@@ -616,6 +618,8 @@ export interface WireModelInfo {
|
|
|
616
618
|
"default": boolean;
|
|
617
619
|
/** Runtime that serves this model. */
|
|
618
620
|
"harness": "pi" | "google" | "systemone";
|
|
621
|
+
/** Reasoning levels the model accepts (google models: the values the ACP thought_level option advertises). */
|
|
622
|
+
"efforts"?: Array<"off" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max">;
|
|
619
623
|
/** Present on decision models: how to call them. */
|
|
620
624
|
"decision"?: {
|
|
621
625
|
"endpoint": "/v1/decisions";
|
|
@@ -646,7 +650,7 @@ export interface WireResponseList {
|
|
|
646
650
|
"created_at": number;
|
|
647
651
|
"status": "queued" | "in_progress" | "completed" | "failed" | "incomplete" | "cancelled";
|
|
648
652
|
"backend": "pi";
|
|
649
|
-
"agent": "auto" | "fast" | "thorough" | "assistant" | "
|
|
653
|
+
"agent": "auto" | "fast" | "thorough" | "assistant" | "code" | "google" | "image" | "api" | "digest" | "cradle" | "roleplay" | "custom";
|
|
650
654
|
"model": string;
|
|
651
655
|
"conversation"?: {
|
|
652
656
|
"id": string;
|
|
@@ -752,7 +756,7 @@ export interface WireResponseList {
|
|
|
752
756
|
};
|
|
753
757
|
"android"?: {
|
|
754
758
|
"sessionId"?: string;
|
|
755
|
-
"username"?:
|
|
759
|
+
"username"?: string;
|
|
756
760
|
"ownerId"?: string;
|
|
757
761
|
"status": "active" | "needs_human" | "human_control" | "idle" | "closed" | "interrupted" | "reserved";
|
|
758
762
|
"action"?: string;
|
|
@@ -778,7 +782,7 @@ export interface WireThreadList {
|
|
|
778
782
|
"created_at": number;
|
|
779
783
|
"updated_at": number;
|
|
780
784
|
"title": string;
|
|
781
|
-
"agent": "auto" | "fast" | "thorough" | "assistant" | "
|
|
785
|
+
"agent": "auto" | "fast" | "thorough" | "assistant" | "code" | "google" | "image" | "api" | "digest" | "cradle" | "roleplay" | "custom";
|
|
782
786
|
"model": string | null;
|
|
783
787
|
"origin": string;
|
|
784
788
|
"end_user"?: string | null;
|
|
@@ -832,7 +836,7 @@ export interface WireFileList {
|
|
|
832
836
|
export interface WireAgentList {
|
|
833
837
|
"object": "list";
|
|
834
838
|
"data": Array<{
|
|
835
|
-
"id":
|
|
839
|
+
"id": string;
|
|
836
840
|
"object": "agent";
|
|
837
841
|
"profile": string;
|
|
838
842
|
"description": string;
|
|
@@ -841,6 +845,7 @@ export interface WireAgentList {
|
|
|
841
845
|
"supports_images": boolean;
|
|
842
846
|
"long_running": boolean;
|
|
843
847
|
"harness": "pi" | "google";
|
|
848
|
+
"capabilities"?: string[];
|
|
844
849
|
}>;
|
|
845
850
|
/** Opaque keyset cursor; null on the last page. */
|
|
846
851
|
"next_cursor": string | null;
|
|
@@ -856,6 +861,7 @@ export interface WireModelList {
|
|
|
856
861
|
"available": boolean;
|
|
857
862
|
"default": boolean;
|
|
858
863
|
"harness": "pi" | "google" | "systemone";
|
|
864
|
+
"efforts"?: Array<"off" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max">;
|
|
859
865
|
"decision"?: {
|
|
860
866
|
"endpoint": "/v1/decisions";
|
|
861
867
|
"question_types": Array<"noul" | "choice" | "score">;
|
package/dist/index.d.ts
CHANGED
|
@@ -85,7 +85,7 @@ export interface AndroidOperation {
|
|
|
85
85
|
}
|
|
86
86
|
export interface AndroidActivity {
|
|
87
87
|
sessionId: string;
|
|
88
|
-
username:
|
|
88
|
+
username: string;
|
|
89
89
|
ownerId?: string;
|
|
90
90
|
status: AndroidStatus;
|
|
91
91
|
action?: string;
|
|
@@ -313,6 +313,17 @@ export type UseCaseCatalog<T extends Record<string, UseCaseDeclaration>> = {
|
|
|
313
313
|
/** Idempotent get-or-create for every use-case. Safe to call on boot. */
|
|
314
314
|
ensure: () => Promise<void>;
|
|
315
315
|
};
|
|
316
|
+
export interface WaitForReadyOptions {
|
|
317
|
+
/** Give up after this long. Default 90 s. */
|
|
318
|
+
timeoutMs?: number;
|
|
319
|
+
/** Called before each backoff while the service is unreachable (log at info). */
|
|
320
|
+
onWait?: (info: {
|
|
321
|
+
attempt: number;
|
|
322
|
+
elapsedMs: number;
|
|
323
|
+
error: AgentLuError;
|
|
324
|
+
}) => void;
|
|
325
|
+
signal?: AbortSignal;
|
|
326
|
+
}
|
|
316
327
|
export interface RunOptions {
|
|
317
328
|
backend?: Backend;
|
|
318
329
|
agent?: string;
|
|
@@ -590,7 +601,7 @@ export declare class AgentLu {
|
|
|
590
601
|
/**
|
|
591
602
|
* Agent tier: a profile, tool families, threads and background runs. The
|
|
592
603
|
* default agent is `api` (no persona - `instructions` are the system prompt);
|
|
593
|
-
* pin `fast`/`
|
|
604
|
+
* pin `fast`/`thorough`/... or an app-owned `<app>/<name>` id when needed.
|
|
594
605
|
*/
|
|
595
606
|
readonly agent: AgentTierApi;
|
|
596
607
|
/** Build a direct-tier run body from a short-form `llm.*` request. */
|
|
@@ -666,6 +677,14 @@ export declare class AgentLu {
|
|
|
666
677
|
models(): Promise<unknown>;
|
|
667
678
|
tools(): Promise<unknown>;
|
|
668
679
|
health(): Promise<unknown>;
|
|
680
|
+
/**
|
|
681
|
+
* Wait until the service answers `/health`, retrying while it is unreachable
|
|
682
|
+
* (offline, 502/503/504, timeout) with jittered backoff. Resolves `true` once
|
|
683
|
+
* it answers and `false` at the deadline or on abort; never throws. Call it
|
|
684
|
+
* on boot before `ensure()`/`register()` so an app started alongside agentlu
|
|
685
|
+
* waits quietly instead of warning on the first ECONNREFUSED.
|
|
686
|
+
*/
|
|
687
|
+
waitForReady(opts?: WaitForReadyOptions): Promise<boolean>;
|
|
669
688
|
private request;
|
|
670
689
|
private raw;
|
|
671
690
|
private rawOnce;
|
package/dist/index.js
CHANGED
|
@@ -431,7 +431,7 @@ export class AgentLu {
|
|
|
431
431
|
/**
|
|
432
432
|
* Agent tier: a profile, tool families, threads and background runs. The
|
|
433
433
|
* default agent is `api` (no persona - `instructions` are the system prompt);
|
|
434
|
-
* pin `fast`/`
|
|
434
|
+
* pin `fast`/`thorough`/... or an app-owned `<app>/<name>` id when needed.
|
|
435
435
|
*/
|
|
436
436
|
agent = {
|
|
437
437
|
run: (opts) => this.run(withAgentTierDefault(opts)),
|
|
@@ -768,6 +768,44 @@ export class AgentLu {
|
|
|
768
768
|
async health() {
|
|
769
769
|
return this.request("GET", "/health", undefined, { auth: false });
|
|
770
770
|
}
|
|
771
|
+
/**
|
|
772
|
+
* Wait until the service answers `/health`, retrying while it is unreachable
|
|
773
|
+
* (offline, 502/503/504, timeout) with jittered backoff. Resolves `true` once
|
|
774
|
+
* it answers and `false` at the deadline or on abort; never throws. Call it
|
|
775
|
+
* on boot before `ensure()`/`register()` so an app started alongside agentlu
|
|
776
|
+
* waits quietly instead of warning on the first ECONNREFUSED.
|
|
777
|
+
*/
|
|
778
|
+
async waitForReady(opts = {}) {
|
|
779
|
+
const timeoutMs = opts.timeoutMs ?? 90_000;
|
|
780
|
+
const start = Date.now();
|
|
781
|
+
for (let attempt = 1;; attempt++) {
|
|
782
|
+
if (opts.signal?.aborted)
|
|
783
|
+
return false;
|
|
784
|
+
try {
|
|
785
|
+
await this.request("GET", "/health", undefined, {
|
|
786
|
+
auth: false,
|
|
787
|
+
maxAttempts: 1,
|
|
788
|
+
timeoutMs: 5_000,
|
|
789
|
+
signal: opts.signal,
|
|
790
|
+
});
|
|
791
|
+
return true;
|
|
792
|
+
}
|
|
793
|
+
catch (e) {
|
|
794
|
+
if (opts.signal?.aborted)
|
|
795
|
+
return false;
|
|
796
|
+
const err = e instanceof AgentLuError ? e : null;
|
|
797
|
+
// Any other answer (401, 404, ...) means the server is up.
|
|
798
|
+
if (!err || (err.kind !== "unavailable" && err.kind !== "timeout"))
|
|
799
|
+
return true;
|
|
800
|
+
const elapsedMs = Date.now() - start;
|
|
801
|
+
if (elapsedMs >= timeoutMs)
|
|
802
|
+
return false;
|
|
803
|
+
opts.onWait?.({ attempt, elapsedMs, error: err });
|
|
804
|
+
const delay = Math.min(5_000, 500 * 2 ** (attempt - 1)) * (0.75 + Math.random() * 0.5);
|
|
805
|
+
await sleep(Math.min(delay, timeoutMs - elapsedMs));
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
}
|
|
771
809
|
async request(method, path, body, opts) {
|
|
772
810
|
const res = await this.raw(method, path, body, opts);
|
|
773
811
|
if (res.status === 204)
|
package/package.json
CHANGED