@butlerbot/sdk 0.0.47 → 0.0.48

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.
@@ -36,6 +36,15 @@ export type DialogueRequestParams = {
36
36
  * 500 characters; the server refuses a longer one. Left off when blank.
37
37
  */
38
38
  wake?: string;
39
+ /**
40
+ * Tools switched on for this one turn, by id, that the turn could reach but has off unless
41
+ * asked for: the Discord bot asks for `react` on a turn the summoning judge started, so
42
+ * Alfred may answer a message with a reaction rather than words. Activation, never a grant:
43
+ * the server switches on only what the turn's platform, the user's plan and the user's own
44
+ * settings already allow, and refuses an id it does not know with the nearest real ones.
45
+ * Passed per `send()`/`ask()`, since it is true of the one turn; left off when empty.
46
+ */
47
+ tools?: string[];
39
48
  /**
40
49
  * What the platform attaches beside this turn's message, never inside it: what it replies
41
50
  * to, who it mentions, where it was sent. See `MessageContextItem` for the shape and the
@@ -55,7 +64,7 @@ export type DialogueRequestParams = {
55
64
  *
56
65
  * A key the transport already sends (`RESERVED_TURN_FIELDS`: `message`, `chatId`,
57
66
  * `api_key`, `model`, `instructions`, `platform`, `address`, `personality`, `wake`,
58
- * `context`) is refused: `send()` throws, and `ask()` rejects, before anything is sent.
67
+ * `tools`, `context`) is refused: `send()` throws, and `ask()` rejects, before anything is sent.
59
68
  */
60
69
  extra?: Record<string, string>;
61
70
  };
@@ -61,6 +61,8 @@ export type TransportTurnRequest = {
61
61
  personality?: string;
62
62
  /** Why Alfred is speaking on this one turn: a line for its system prompt, at most 500 characters. */
63
63
  wake?: string;
64
+ /** Tools switched on for this one turn, by id. Sent only when non-empty; see `DialogueRequestParams.tools`. */
65
+ tools?: string[];
64
66
  /** What the platform attaches beside this turn's message. Sent only when non-empty. */
65
67
  context?: MessageContextItem[];
66
68
  /** Further turn parameters, forwarded to the server verbatim. See `DialogueRequestParams.extra`. */
@@ -81,6 +83,12 @@ export declare const RESERVED_TURN_FIELDS: readonly string[];
81
83
  export declare function turnExtra(extra: Record<string, string> | undefined): Record<string, string> | undefined;
82
84
  /** A turn's context as it travels, JSON-encoded, or nothing when there is none. */
83
85
  export declare function turnContext(context: MessageContextItem[] | undefined): string | undefined;
86
+ /**
87
+ * A turn's tools as they travel: the ids trimmed, emptied ones dropped, repeats folded, joined
88
+ * with commas; nothing when none is left. A comma in an id would read as two ids, so one is
89
+ * refused before anything is sent.
90
+ */
91
+ export declare function turnTools(tools: string[] | undefined): string | undefined;
84
92
  export type TransportHandlers = {
85
93
  /** One payload of the stream, already in the shape callers expect. */
86
94
  payload(payload: unknown): void;
@@ -11,6 +11,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
11
11
  exports.RESERVED_TURN_FIELDS = void 0;
12
12
  exports.turnExtra = turnExtra;
13
13
  exports.turnContext = turnContext;
14
+ exports.turnTools = turnTools;
14
15
  exports.noticePayload = noticePayload;
15
16
  exports.convoStartedPayload = convoStartedPayload;
16
17
  exports.completedPayload = completedPayload;
@@ -31,6 +32,7 @@ exports.RESERVED_TURN_FIELDS = [
31
32
  "address",
32
33
  "personality",
33
34
  "wake",
35
+ "tools",
34
36
  "context",
35
37
  ];
36
38
  /**
@@ -60,6 +62,28 @@ function turnExtra(extra) {
60
62
  function turnContext(context) {
61
63
  return context && context.length > 0 ? JSON.stringify(context) : undefined;
62
64
  }
65
+ /**
66
+ * A turn's tools as they travel: the ids trimmed, emptied ones dropped, repeats folded, joined
67
+ * with commas; nothing when none is left. A comma in an id would read as two ids, so one is
68
+ * refused before anything is sent.
69
+ */
70
+ function turnTools(tools) {
71
+ if (!tools || tools.length === 0)
72
+ return undefined;
73
+ const ids = [];
74
+ for (const raw of tools) {
75
+ if (typeof raw !== "string")
76
+ throw new Error(`A turn's \`tools\` are tool ids; one is ${typeof raw}.`);
77
+ const id = raw.trim();
78
+ if (!id)
79
+ continue;
80
+ if (id.includes(","))
81
+ throw new Error(`A turn's \`tools\` entry may not contain a comma: "${id}".`);
82
+ if (!ids.includes(id))
83
+ ids.push(id);
84
+ }
85
+ return ids.length > 0 ? ids.join(",") : undefined;
86
+ }
63
87
  // =============================================
64
88
  // PAYLOAD SHAPES
65
89
  // =============================================
@@ -179,7 +179,12 @@ class LinkConversationTransport {
179
179
  };
180
180
  learnChatId(progress.chatId);
181
181
  const context = (0, transport_1.turnContext)(request.context);
182
- const extra = (0, transport_1.turnExtra)(request.extra);
182
+ // The turn's tools ride in `extra`, which the Link service spreads into the same query
183
+ // the SSE transport builds: the server reads `tools` either way, and a caller's own
184
+ // `extra` can never carry that key, since the transport reserves it.
185
+ const tools = (0, transport_1.turnTools)(request.tools);
186
+ const own = (0, transport_1.turnExtra)(request.extra);
187
+ const extra = tools ? { ...(own ?? {}), tools } : own;
183
188
  let done;
184
189
  try {
185
190
  done = await this.link.exchange("conversation.chat", {
@@ -124,6 +124,9 @@ function asQuery(request) {
124
124
  const wake = request.wake?.trim();
125
125
  if (wake)
126
126
  query.wake = wake;
127
+ const tools = (0, transport_1.turnTools)(request.tools);
128
+ if (tools)
129
+ query.tools = tools;
127
130
  const context = (0, transport_1.turnContext)(request.context);
128
131
  if (context)
129
132
  query.context = context;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@butlerbot/sdk",
3
- "version": "0.0.47",
3
+ "version": "0.0.48",
4
4
  "description": "The official ButlerBot SDK",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",