@butlerbot/sdk 0.0.18 → 0.0.20

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/dist/config.js CHANGED
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.CONFIG = void 0;
4
4
  exports.CONFIG = {
5
- server: "https://core.butlerbot.net",
5
+ server: "https://core.butler.now",
6
6
  healthcheckPath: "/api/healthcheck",
7
7
  paths: {
8
8
  conversation: {
package/dist/link/link.js CHANGED
@@ -379,9 +379,20 @@ class Link {
379
379
  }
380
380
  const controller = new AbortController();
381
381
  this.calls.set(callId, controller);
382
+ // Only a final status is kept in the conversation, so every call has to end on
383
+ // one. The tool may send its own, with a better label than we could invent; if
384
+ // it does not, we send one for it below rather than leave the call unfinished.
385
+ let reported = "running";
386
+ const report = (label, state) => {
387
+ if (reported !== "running")
388
+ return;
389
+ reported = state;
390
+ this.send("tool.status", { label, state }, frame.id);
391
+ };
382
392
  const status = {
383
- update: (label) => this.send("tool.status", { label, state: "running" }, frame.id),
384
- fail: (label) => this.send("tool.status", { label, state: "failed" }, frame.id),
393
+ update: (label) => report(label, "running"),
394
+ complete: (label) => report(label, "completed"),
395
+ fail: (label) => report(label, "failed"),
385
396
  };
386
397
  void tool.invoke(args, meta, status, controller.signal).then(result => {
387
398
  this.calls.delete(callId);
@@ -389,6 +400,15 @@ class Link {
389
400
  // given up on the call, so there is nothing to report to.
390
401
  if (!this.socket)
391
402
  return;
403
+ if (!result.ok && reported === "completed") {
404
+ // The tool said it succeeded and then failed anyway. The outcome is the
405
+ // part worth keeping, so let the failure replace what it claimed.
406
+ reported = "running";
407
+ }
408
+ if (result.ok)
409
+ report(`Finished ${tool.id}.`, "completed");
410
+ else
411
+ report(result.error, "failed");
392
412
  this.send("tool.result", result.ok
393
413
  ? { ok: true, output: result.output }
394
414
  : { ok: false, error: result.error }, frame.id);
@@ -1,9 +1,19 @@
1
1
  import { LinkToolDescriptor } from "./protocol";
2
2
  import { InferSchemaOutput, JSONSchema, ToolSchema } from "./schema";
3
- /** Reports progress while a tool runs. Shown live in Alfred's tool status feed. */
3
+ /**
4
+ * Reports progress while a tool runs. Shown live in Alfred's tool status feed.
5
+ *
6
+ * `update` is progress; `complete` and `fail` are final. Only a final status is kept
7
+ * in the conversation once the turn ends — a status left at `update` is shown live
8
+ * and then forgotten — so a tool that wants to leave a trace should finish with
9
+ * `complete`. If it does not, the link sends a final status for it when `run`
10
+ * returns, so the call is recorded either way.
11
+ */
4
12
  export type ToolStatusReporter = {
5
- /** Replaces the current status label. */
13
+ /** Replaces the current status label. The call is still running. */
6
14
  update(label: string): void;
15
+ /** Marks the tool as finished, with the label the conversation keeps. */
16
+ complete(label: string): void;
7
17
  /** Marks the tool as failed in the UI. The thrown error still decides the result. */
8
18
  fail(label: string): void;
9
19
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@butlerbot/sdk",
3
- "version": "0.0.18",
3
+ "version": "0.0.20",
4
4
  "description": "The official ButlerBot SDK",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -35,7 +35,7 @@
35
35
  "bugs": {
36
36
  "url": "https://github.com/butlerbots/alfred5_sdk/issues"
37
37
  },
38
- "homepage": "https://butlerbot.net",
38
+ "homepage": "https://butler.now",
39
39
  "engines": {
40
40
  "node": ">=18.0.0"
41
41
  },
package/readme.md CHANGED
@@ -1,10 +1,10 @@
1
1
  # ButlerBot SDK
2
2
 
3
- ButlerBot SDK is a JavaScript library that provides a simple way to interact with the [ButlerBot](https://butlerbot.net/) API.
3
+ ButlerBot SDK is a JavaScript library that provides a simple way to interact with the [ButlerBot](https://butler.now/) API.
4
4
 
5
5
  ## Quickstart
6
6
 
7
- Grab an API key at [ButlerBot](https://butlerbot.net/) and install the package:
7
+ Grab an API key at [ButlerBot](https://butler.now/) and install the package:
8
8
 
9
9
  ```bash
10
10
  npm i @butlerbot/sdk
@@ -61,8 +61,9 @@ link.addTool(new Tool({
61
61
  description: "Brew a coffee for the user",
62
62
  schema: z.object({ cups: z.number().int().min(1).max(4) }),
63
63
  run: async ({ args, status }) => {
64
- status.update("Grinding beans");
65
- return `Brewed ${args.cups} cup(s).`; // args is typed from the schema
64
+ status.update("Grinding beans"); // progress, shown while it runs
65
+ status.complete("Brewed the coffee"); // the label the conversation keeps
66
+ return `Brewed ${args.cups} cup(s).`; // args is typed from the schema
66
67
  },
67
68
  }));
68
69