@astralform/js 8.3.0 → 8.5.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
@@ -320,6 +320,7 @@ const conversations = await client.getConversations();
320
320
  const messages = await client.getMessages("conversation-id");
321
321
  const agents = await client.getAgents();
322
322
  const skills = await client.getSkills();
323
+ const commands = await client.listSkillCommands();
323
324
 
324
325
  // Job-based streaming
325
326
  const job = await client.createJob({ message: "Hello" });
package/dist/index.cjs CHANGED
@@ -404,7 +404,31 @@ function toMessage(m) {
404
404
  content: m.content,
405
405
  parentId: m.parent_id,
406
406
  status: "complete",
407
- createdAt: m.created_at
407
+ createdAt: m.created_at,
408
+ // Server-joined result typing. `?? undefined` rather than `?? null` so an
409
+ // absent field and an explicit null both read as "the server said nothing",
410
+ // which is the one distinction a renderer actually makes here.
411
+ toolCalls: m.tool_calls?.map(toToolCallRequest) ?? void 0,
412
+ sources: m.sources?.map(toToolSource) ?? void 0,
413
+ durationMs: m.duration_ms ?? void 0,
414
+ isError: m.is_error ?? void 0,
415
+ deniedBy: m.denied_by ?? void 0,
416
+ denialKind: m.denial_kind ?? void 0
417
+ };
418
+ }
419
+ function toToolSource(s) {
420
+ return { title: s.title, url: s.url, snippet: s.snippet };
421
+ }
422
+ function toToolCallRequest(t) {
423
+ return {
424
+ callId: t.call_id,
425
+ toolName: t.tool_name,
426
+ displayName: t.display_name,
427
+ description: t.description,
428
+ arguments: t.arguments ?? {},
429
+ isClientTool: t.is_client_tool ?? false,
430
+ toolCategory: t.tool_category,
431
+ iconUrl: t.icon_url
408
432
  };
409
433
  }
410
434
  var AstralformClient = class {
@@ -855,6 +879,37 @@ var AstralformClient = class {
855
879
  const raw = await this.get("/v1/skills");
856
880
  return raw.map((s) => camelizeKeys(s));
857
881
  }
882
+ /**
883
+ * List the slash commands the active agent offers — the system commands
884
+ * followed by its enabled skills. Backs the composer's "/" menu.
885
+ *
886
+ * @param surface Who will execute them. Omit for the server's default,
887
+ * `"web"`: what `POST /v1/jobs` runs itself. `"telegram"` returns the
888
+ * bot's commands under Telegram-valid names; `"all"` returns every
889
+ * command, including those the other surfaces filter out — `surfaces` is
890
+ * set on every row either way, and is what tells them apart here.
891
+ *
892
+ * The default surface is not sent as a query parameter. The server already
893
+ * defaults to `web`, so omitting it keeps the request byte-identical to
894
+ * what clients that call the raw path send today — same reasoning as
895
+ * {@link getConversationEvents}'s `toolOutputs`.
896
+ */
897
+ async listSkillCommands(surface) {
898
+ const query = surface && surface !== "web" ? `?surface=${surface}` : "";
899
+ const raw = await this.get(
900
+ `/v1/skills/commands${query}`
901
+ );
902
+ return raw.map((c) => {
903
+ const command = camelizeKeys(c);
904
+ return {
905
+ ...command,
906
+ displayName: command.displayName ?? "",
907
+ description: command.description ?? "",
908
+ argsHint: command.argsHint ?? "",
909
+ surfaces: command.surfaces ?? []
910
+ };
911
+ });
912
+ }
858
913
  async getConversationEvents(conversationId, jobId, options) {
859
914
  const params = new URLSearchParams();
860
915
  if (jobId) params.set("job_id", jobId);