@astralform/js 4.6.1 → 4.7.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/dist/index.d.cts CHANGED
@@ -889,6 +889,7 @@ declare class AstralformClient {
889
889
  private send;
890
890
  get<T>(path: string): Promise<T>;
891
891
  post<T>(path: string, body: unknown): Promise<T>;
892
+ patch<T>(path: string, body: unknown): Promise<T>;
892
893
  private del;
893
894
  private handleError;
894
895
  getHealth(): Promise<{
@@ -899,6 +900,16 @@ declare class AstralformClient {
899
900
  getAgentStatus(): Promise<AgentStatus>;
900
901
  getConversations(limit?: number, offset?: number): Promise<Conversation[]>;
901
902
  getMessages(conversationId: string): Promise<Message[]>;
903
+ /**
904
+ * Replace the title the server generated from the conversation's first turn.
905
+ *
906
+ * The server does NOT bump `updated_at` for a rename — conversations list
907
+ * newest-updated first, and relabelling one is not activity — so the
908
+ * timestamp coming back is the original. Callers should merge the response
909
+ * rather than stamp their own, or they reintroduce the reordering the
910
+ * server deliberately avoids.
911
+ */
912
+ renameConversation(id: string, title: string): Promise<Conversation>;
902
913
  deleteConversation(id: string): Promise<void>;
903
914
  /**
904
915
  * List the AI personas (sub-agents) available INSIDE the client's active
@@ -1223,6 +1234,19 @@ declare class ChatSession {
1223
1234
  * already scanned.
1224
1235
  */
1225
1236
  loadMoreConversations(): Promise<Conversation[]>;
1237
+ /**
1238
+ * Rename a conversation, server first.
1239
+ *
1240
+ * Deliberately NOT optimistic, unlike the delete below. A failed delete is
1241
+ * self-correcting (the row is still there on the next page fetch), but a
1242
+ * failed rename that had already been written locally would leave the
1243
+ * sidebar showing a title the server never accepted — and nothing refetches
1244
+ * a conversation that is already in the loaded list.
1245
+ *
1246
+ * Mirrors the `title_generated` path: the entry in `conversations` is
1247
+ * mutated in place, which is what every consumer of the list reads.
1248
+ */
1249
+ renameConversation(id: string, title: string): Promise<void>;
1226
1250
  deleteConversation(id: string): Promise<void>;
1227
1251
  toggleClientTool(name: string): boolean;
1228
1252
  }
@@ -1349,6 +1373,11 @@ declare class StreamManager {
1349
1373
  skipHistoryReplay?: boolean;
1350
1374
  }): Promise<void>;
1351
1375
  createConversation(): Promise<string>;
1376
+ /**
1377
+ * Rename a conversation. Purely a relabel — no active-conversation or
1378
+ * background-job bookkeeping to do, unlike delete, so this is a passthrough.
1379
+ */
1380
+ renameConversation(id: string, title: string): Promise<void>;
1352
1381
  deleteConversation(id: string): Promise<void>;
1353
1382
  stop(): void;
1354
1383
  destroy(): void;
package/dist/index.d.ts CHANGED
@@ -889,6 +889,7 @@ declare class AstralformClient {
889
889
  private send;
890
890
  get<T>(path: string): Promise<T>;
891
891
  post<T>(path: string, body: unknown): Promise<T>;
892
+ patch<T>(path: string, body: unknown): Promise<T>;
892
893
  private del;
893
894
  private handleError;
894
895
  getHealth(): Promise<{
@@ -899,6 +900,16 @@ declare class AstralformClient {
899
900
  getAgentStatus(): Promise<AgentStatus>;
900
901
  getConversations(limit?: number, offset?: number): Promise<Conversation[]>;
901
902
  getMessages(conversationId: string): Promise<Message[]>;
903
+ /**
904
+ * Replace the title the server generated from the conversation's first turn.
905
+ *
906
+ * The server does NOT bump `updated_at` for a rename — conversations list
907
+ * newest-updated first, and relabelling one is not activity — so the
908
+ * timestamp coming back is the original. Callers should merge the response
909
+ * rather than stamp their own, or they reintroduce the reordering the
910
+ * server deliberately avoids.
911
+ */
912
+ renameConversation(id: string, title: string): Promise<Conversation>;
902
913
  deleteConversation(id: string): Promise<void>;
903
914
  /**
904
915
  * List the AI personas (sub-agents) available INSIDE the client's active
@@ -1223,6 +1234,19 @@ declare class ChatSession {
1223
1234
  * already scanned.
1224
1235
  */
1225
1236
  loadMoreConversations(): Promise<Conversation[]>;
1237
+ /**
1238
+ * Rename a conversation, server first.
1239
+ *
1240
+ * Deliberately NOT optimistic, unlike the delete below. A failed delete is
1241
+ * self-correcting (the row is still there on the next page fetch), but a
1242
+ * failed rename that had already been written locally would leave the
1243
+ * sidebar showing a title the server never accepted — and nothing refetches
1244
+ * a conversation that is already in the loaded list.
1245
+ *
1246
+ * Mirrors the `title_generated` path: the entry in `conversations` is
1247
+ * mutated in place, which is what every consumer of the list reads.
1248
+ */
1249
+ renameConversation(id: string, title: string): Promise<void>;
1226
1250
  deleteConversation(id: string): Promise<void>;
1227
1251
  toggleClientTool(name: string): boolean;
1228
1252
  }
@@ -1349,6 +1373,11 @@ declare class StreamManager {
1349
1373
  skipHistoryReplay?: boolean;
1350
1374
  }): Promise<void>;
1351
1375
  createConversation(): Promise<string>;
1376
+ /**
1377
+ * Rename a conversation. Purely a relabel — no active-conversation or
1378
+ * background-job bookkeeping to do, unlike delete, so this is a passthrough.
1379
+ */
1380
+ renameConversation(id: string, title: string): Promise<void>;
1352
1381
  deleteConversation(id: string): Promise<void>;
1353
1382
  stop(): void;
1354
1383
  destroy(): void;
package/dist/index.js CHANGED
@@ -460,6 +460,12 @@ var AstralformClient = class {
460
460
  return await response.json();
461
461
  });
462
462
  }
463
+ async patch(path, body) {
464
+ return this.withDeadline(async (signal) => {
465
+ const response = await this.send("PATCH", path, body, signal);
466
+ return await response.json();
467
+ });
468
+ }
463
469
  async del(path) {
464
470
  await this.request("DELETE", path);
465
471
  }
@@ -530,6 +536,25 @@ var AstralformClient = class {
530
536
  createdAt: m.created_at
531
537
  }));
532
538
  }
539
+ /**
540
+ * Replace the title the server generated from the conversation's first turn.
541
+ *
542
+ * The server does NOT bump `updated_at` for a rename — conversations list
543
+ * newest-updated first, and relabelling one is not activity — so the
544
+ * timestamp coming back is the original. Callers should merge the response
545
+ * rather than stamp their own, or they reintroduce the reordering the
546
+ * server deliberately avoids.
547
+ */
548
+ async renameConversation(id, title) {
549
+ const c = await this.patch(`/v1/conversations/${encodeURIComponent(id)}`, { title });
550
+ return {
551
+ id: c.id,
552
+ title: c.title,
553
+ messageCount: c.message_count,
554
+ createdAt: c.created_at,
555
+ updatedAt: c.updated_at
556
+ };
557
+ }
533
558
  async deleteConversation(id) {
534
559
  await this.del(`/v1/conversations/${encodeURIComponent(id)}`);
535
560
  }
@@ -1879,6 +1904,26 @@ var ChatSession = class {
1879
1904
  this.isLoadingConversations = false;
1880
1905
  }
1881
1906
  }
1907
+ /**
1908
+ * Rename a conversation, server first.
1909
+ *
1910
+ * Deliberately NOT optimistic, unlike the delete below. A failed delete is
1911
+ * self-correcting (the row is still there on the next page fetch), but a
1912
+ * failed rename that had already been written locally would leave the
1913
+ * sidebar showing a title the server never accepted — and nothing refetches
1914
+ * a conversation that is already in the loaded list.
1915
+ *
1916
+ * Mirrors the `title_generated` path: the entry in `conversations` is
1917
+ * mutated in place, which is what every consumer of the list reads.
1918
+ */
1919
+ async renameConversation(id, title) {
1920
+ const updated = await this.client.renameConversation(id, title);
1921
+ const conv = this.conversations.find((c) => c.id === id);
1922
+ if (conv) {
1923
+ conv.title = updated.title;
1924
+ }
1925
+ await this.storage.updateConversationTitle(id, updated.title);
1926
+ }
1882
1927
  async deleteConversation(id) {
1883
1928
  try {
1884
1929
  await this.client.deleteConversation(id);
@@ -2169,12 +2214,19 @@ var StreamManager = class {
2169
2214
  }
2170
2215
  await this.restore(conversationId);
2171
2216
  }
2172
- // ── Create / delete conversation ──────────────────────────────
2217
+ // ── Create / rename / delete conversation ─────────────────────
2173
2218
  async createConversation() {
2174
2219
  const id = await this.session.createNewConversation();
2175
2220
  this.setActiveConversation(id);
2176
2221
  return id;
2177
2222
  }
2223
+ /**
2224
+ * Rename a conversation. Purely a relabel — no active-conversation or
2225
+ * background-job bookkeeping to do, unlike delete, so this is a passthrough.
2226
+ */
2227
+ async renameConversation(id, title) {
2228
+ await this.session.renameConversation(id, title);
2229
+ }
2178
2230
  async deleteConversation(id) {
2179
2231
  await this.session.deleteConversation(id);
2180
2232
  this._backgroundJobs.delete(id);