@hasna/conversations 0.1.22 → 0.1.24

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/bin/index.js CHANGED
@@ -3282,6 +3282,14 @@ function resolveIdentity(explicit) {
3282
3282
  return envValue;
3283
3283
  return getAutoName();
3284
3284
  }
3285
+ function updateCachedAutoName(newName) {
3286
+ cachedAutoName = newName;
3287
+ try {
3288
+ mkdirSync3(dirname2(AGENT_ID_FILE), { recursive: true });
3289
+ writeFileSync(AGENT_ID_FILE, newName + `
3290
+ `, "utf-8");
3291
+ } catch {}
3292
+ }
3285
3293
  var AGENT_ID_FILE, cachedAutoName = null;
3286
3294
  var init_identity = __esm(() => {
3287
3295
  init_names();
@@ -3314,6 +3322,7 @@ function heartbeat(agent, status, metadata) {
3314
3322
  const db2 = getDb();
3315
3323
  const metadataJson = metadata ? JSON.stringify(metadata) : null;
3316
3324
  const resolvedStatus = status || "online";
3325
+ const normalizedAgent = agent.trim().toLowerCase();
3317
3326
  db2.prepare(`
3318
3327
  INSERT INTO agent_presence (agent, status, last_seen_at, metadata)
3319
3328
  VALUES (?, ?, strftime('%Y-%m-%dT%H:%M:%f', 'now'), ?)
@@ -3321,11 +3330,12 @@ function heartbeat(agent, status, metadata) {
3321
3330
  status = excluded.status,
3322
3331
  last_seen_at = excluded.last_seen_at,
3323
3332
  metadata = excluded.metadata
3324
- `).run(agent, resolvedStatus, metadataJson);
3333
+ `).run(normalizedAgent, resolvedStatus, metadataJson);
3325
3334
  }
3326
3335
  function getPresence(agent) {
3327
3336
  const db2 = getDb();
3328
- const row = db2.prepare("SELECT * FROM agent_presence WHERE agent = ?").get(agent);
3337
+ const normalizedAgent = agent.trim().toLowerCase();
3338
+ const row = db2.prepare("SELECT * FROM agent_presence WHERE LOWER(agent) = ?").get(normalizedAgent);
3329
3339
  return row ? parsePresence(row) : null;
3330
3340
  }
3331
3341
  function listAgents(opts) {
@@ -3341,18 +3351,21 @@ function listAgents(opts) {
3341
3351
  }
3342
3352
  function removePresence(agent) {
3343
3353
  const db2 = getDb();
3344
- const result = db2.prepare("DELETE FROM agent_presence WHERE agent = ?").run(agent);
3354
+ const normalizedAgent = agent.trim().toLowerCase();
3355
+ const result = db2.prepare("DELETE FROM agent_presence WHERE LOWER(agent) = ?").run(normalizedAgent);
3345
3356
  return result.changes > 0;
3346
3357
  }
3347
3358
  function renameAgent(oldName, newName) {
3348
3359
  const db2 = getDb();
3349
- const existing = db2.prepare("SELECT agent FROM agent_presence WHERE agent = ?").get(oldName);
3360
+ const normalizedOld = oldName.trim().toLowerCase();
3361
+ const normalizedNew = newName.trim().toLowerCase();
3362
+ const existing = db2.prepare("SELECT agent FROM agent_presence WHERE LOWER(agent) = ?").get(normalizedOld);
3350
3363
  if (!existing)
3351
3364
  return false;
3352
- const conflict = db2.prepare("SELECT agent FROM agent_presence WHERE agent = ?").get(newName);
3365
+ const conflict = db2.prepare("SELECT agent FROM agent_presence WHERE LOWER(agent) = ?").get(normalizedNew);
3353
3366
  if (conflict)
3354
- throw new Error(`Agent "${newName}" already exists`);
3355
- db2.prepare("UPDATE agent_presence SET agent = ? WHERE agent = ?").run(newName, oldName);
3367
+ throw new Error(`Agent "${normalizedNew}" already exists`);
3368
+ db2.prepare("UPDATE agent_presence SET agent = ? WHERE LOWER(agent) = ?").run(normalizedNew, normalizedOld);
3356
3369
  return true;
3357
3370
  }
3358
3371
  var ONLINE_THRESHOLD_SECONDS = 60;
@@ -3504,7 +3517,7 @@ var init_poll = __esm(() => {
3504
3517
  var require_package = __commonJS((exports, module) => {
3505
3518
  module.exports = {
3506
3519
  name: "@hasna/conversations",
3507
- version: "0.1.22",
3520
+ version: "0.1.24",
3508
3521
  description: "Real-time CLI messaging for AI agents",
3509
3522
  type: "module",
3510
3523
  bin: {
@@ -30872,7 +30885,7 @@ var require_formats = __commonJS((exports) => {
30872
30885
  }
30873
30886
  var TIME = /^(\d\d):(\d\d):(\d\d(?:\.\d+)?)(z|([+-])(\d\d)(?::?(\d\d))?)?$/i;
30874
30887
  function getTime(strictTimeZone) {
30875
- return function time(str) {
30888
+ return function time3(str) {
30876
30889
  const matches = TIME.exec(str);
30877
30890
  if (!matches)
30878
30891
  return false;
@@ -31136,6 +31149,62 @@ class ExperimentalServerTasks {
31136
31149
  requestStream(request, resultSchema, options) {
31137
31150
  return this._server.requestStream(request, resultSchema, options);
31138
31151
  }
31152
+ createMessageStream(params, options) {
31153
+ const clientCapabilities = this._server.getClientCapabilities();
31154
+ if ((params.tools || params.toolChoice) && !clientCapabilities?.sampling?.tools) {
31155
+ throw new Error("Client does not support sampling tools capability.");
31156
+ }
31157
+ if (params.messages.length > 0) {
31158
+ const lastMessage = params.messages[params.messages.length - 1];
31159
+ const lastContent = Array.isArray(lastMessage.content) ? lastMessage.content : [lastMessage.content];
31160
+ const hasToolResults = lastContent.some((c) => c.type === "tool_result");
31161
+ const previousMessage = params.messages.length > 1 ? params.messages[params.messages.length - 2] : undefined;
31162
+ const previousContent = previousMessage ? Array.isArray(previousMessage.content) ? previousMessage.content : [previousMessage.content] : [];
31163
+ const hasPreviousToolUse = previousContent.some((c) => c.type === "tool_use");
31164
+ if (hasToolResults) {
31165
+ if (lastContent.some((c) => c.type !== "tool_result")) {
31166
+ throw new Error("The last message must contain only tool_result content if any is present");
31167
+ }
31168
+ if (!hasPreviousToolUse) {
31169
+ throw new Error("tool_result blocks are not matching any tool_use from the previous message");
31170
+ }
31171
+ }
31172
+ if (hasPreviousToolUse) {
31173
+ const toolUseIds = new Set(previousContent.filter((c) => c.type === "tool_use").map((c) => c.id));
31174
+ const toolResultIds = new Set(lastContent.filter((c) => c.type === "tool_result").map((c) => c.toolUseId));
31175
+ if (toolUseIds.size !== toolResultIds.size || ![...toolUseIds].every((id) => toolResultIds.has(id))) {
31176
+ throw new Error("ids of tool_result blocks and tool_use blocks from previous message do not match");
31177
+ }
31178
+ }
31179
+ }
31180
+ return this.requestStream({
31181
+ method: "sampling/createMessage",
31182
+ params
31183
+ }, CreateMessageResultSchema, options);
31184
+ }
31185
+ elicitInputStream(params, options) {
31186
+ const clientCapabilities = this._server.getClientCapabilities();
31187
+ const mode = params.mode ?? "form";
31188
+ switch (mode) {
31189
+ case "url": {
31190
+ if (!clientCapabilities?.elicitation?.url) {
31191
+ throw new Error("Client does not support url elicitation.");
31192
+ }
31193
+ break;
31194
+ }
31195
+ case "form": {
31196
+ if (!clientCapabilities?.elicitation?.form) {
31197
+ throw new Error("Client does not support form elicitation.");
31198
+ }
31199
+ break;
31200
+ }
31201
+ }
31202
+ const normalizedParams = mode === "form" && params.mode === undefined ? { ...params, mode: "form" } : params;
31203
+ return this.requestStream({
31204
+ method: "elicitation/create",
31205
+ params: normalizedParams
31206
+ }, ElicitResultSchema, options);
31207
+ }
31139
31208
  async getTask(taskId, options) {
31140
31209
  return this._server.getTask({ taskId }, options);
31141
31210
  }
@@ -31149,6 +31218,9 @@ class ExperimentalServerTasks {
31149
31218
  return this._server.cancelTask({ taskId }, options);
31150
31219
  }
31151
31220
  }
31221
+ var init_server = __esm(() => {
31222
+ init_types2();
31223
+ });
31152
31224
 
31153
31225
  // node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/helpers.js
31154
31226
  function assertToolsCallTaskCapability(requests, method, entityName) {
@@ -31187,11 +31259,12 @@ function assertClientRequestTaskCapability(requests, method, entityName) {
31187
31259
 
31188
31260
  // node_modules/@modelcontextprotocol/sdk/dist/esm/server/index.js
31189
31261
  var Server;
31190
- var init_server = __esm(() => {
31262
+ var init_server2 = __esm(() => {
31191
31263
  init_protocol();
31192
31264
  init_types2();
31193
31265
  init_ajv_provider();
31194
31266
  init_zod_compat();
31267
+ init_server();
31195
31268
  Server = class Server extends Protocol {
31196
31269
  constructor(_serverInfo, options) {
31197
31270
  super(options);
@@ -32333,7 +32406,7 @@ function createCompletionResult(suggestions) {
32333
32406
  }
32334
32407
  var EMPTY_OBJECT_JSON_SCHEMA, EMPTY_COMPLETION_RESULT;
32335
32408
  var init_mcp = __esm(() => {
32336
- init_server();
32409
+ init_server2();
32337
32410
  init_zod_compat();
32338
32411
  init_zod_json_schema_compat();
32339
32412
  init_types2();
@@ -33185,6 +33258,9 @@ var init_mcp2 = __esm(() => {
33185
33258
  isError: true
33186
33259
  };
33187
33260
  }
33261
+ if (!fromParam) {
33262
+ updateCachedAutoName(newName);
33263
+ }
33188
33264
  return {
33189
33265
  content: [{ type: "text", text: JSON.stringify({ old_name: oldName, new_name: newName, renamed: true }) }]
33190
33266
  };
package/bin/mcp.js CHANGED
@@ -6302,7 +6302,7 @@ var require_formats = __commonJS((exports) => {
6302
6302
  }
6303
6303
  var TIME = /^(\d\d):(\d\d):(\d\d(?:\.\d+)?)(z|([+-])(\d\d)(?::?(\d\d))?)?$/i;
6304
6304
  function getTime(strictTimeZone) {
6305
- return function time(str) {
6305
+ return function time3(str) {
6306
6306
  const matches = TIME.exec(str);
6307
6307
  if (!matches)
6308
6308
  return false;
@@ -27263,6 +27263,62 @@ class ExperimentalServerTasks {
27263
27263
  requestStream(request, resultSchema, options) {
27264
27264
  return this._server.requestStream(request, resultSchema, options);
27265
27265
  }
27266
+ createMessageStream(params, options) {
27267
+ const clientCapabilities = this._server.getClientCapabilities();
27268
+ if ((params.tools || params.toolChoice) && !clientCapabilities?.sampling?.tools) {
27269
+ throw new Error("Client does not support sampling tools capability.");
27270
+ }
27271
+ if (params.messages.length > 0) {
27272
+ const lastMessage = params.messages[params.messages.length - 1];
27273
+ const lastContent = Array.isArray(lastMessage.content) ? lastMessage.content : [lastMessage.content];
27274
+ const hasToolResults = lastContent.some((c) => c.type === "tool_result");
27275
+ const previousMessage = params.messages.length > 1 ? params.messages[params.messages.length - 2] : undefined;
27276
+ const previousContent = previousMessage ? Array.isArray(previousMessage.content) ? previousMessage.content : [previousMessage.content] : [];
27277
+ const hasPreviousToolUse = previousContent.some((c) => c.type === "tool_use");
27278
+ if (hasToolResults) {
27279
+ if (lastContent.some((c) => c.type !== "tool_result")) {
27280
+ throw new Error("The last message must contain only tool_result content if any is present");
27281
+ }
27282
+ if (!hasPreviousToolUse) {
27283
+ throw new Error("tool_result blocks are not matching any tool_use from the previous message");
27284
+ }
27285
+ }
27286
+ if (hasPreviousToolUse) {
27287
+ const toolUseIds = new Set(previousContent.filter((c) => c.type === "tool_use").map((c) => c.id));
27288
+ const toolResultIds = new Set(lastContent.filter((c) => c.type === "tool_result").map((c) => c.toolUseId));
27289
+ if (toolUseIds.size !== toolResultIds.size || ![...toolUseIds].every((id) => toolResultIds.has(id))) {
27290
+ throw new Error("ids of tool_result blocks and tool_use blocks from previous message do not match");
27291
+ }
27292
+ }
27293
+ }
27294
+ return this.requestStream({
27295
+ method: "sampling/createMessage",
27296
+ params
27297
+ }, CreateMessageResultSchema, options);
27298
+ }
27299
+ elicitInputStream(params, options) {
27300
+ const clientCapabilities = this._server.getClientCapabilities();
27301
+ const mode = params.mode ?? "form";
27302
+ switch (mode) {
27303
+ case "url": {
27304
+ if (!clientCapabilities?.elicitation?.url) {
27305
+ throw new Error("Client does not support url elicitation.");
27306
+ }
27307
+ break;
27308
+ }
27309
+ case "form": {
27310
+ if (!clientCapabilities?.elicitation?.form) {
27311
+ throw new Error("Client does not support form elicitation.");
27312
+ }
27313
+ break;
27314
+ }
27315
+ }
27316
+ const normalizedParams = mode === "form" && params.mode === undefined ? { ...params, mode: "form" } : params;
27317
+ return this.requestStream({
27318
+ method: "elicitation/create",
27319
+ params: normalizedParams
27320
+ }, ElicitResultSchema, options);
27321
+ }
27266
27322
  async getTask(taskId, options) {
27267
27323
  return this._server.getTask({ taskId }, options);
27268
27324
  }
@@ -29710,6 +29766,14 @@ function resolveIdentity(explicit) {
29710
29766
  return envValue;
29711
29767
  return getAutoName();
29712
29768
  }
29769
+ function updateCachedAutoName(newName) {
29770
+ cachedAutoName = newName;
29771
+ try {
29772
+ mkdirSync3(dirname2(AGENT_ID_FILE), { recursive: true });
29773
+ writeFileSync(AGENT_ID_FILE, newName + `
29774
+ `, "utf-8");
29775
+ } catch {}
29776
+ }
29713
29777
 
29714
29778
  // src/lib/presence.ts
29715
29779
  init_db();
@@ -29739,6 +29803,7 @@ function heartbeat(agent, status, metadata) {
29739
29803
  const db2 = getDb();
29740
29804
  const metadataJson = metadata ? JSON.stringify(metadata) : null;
29741
29805
  const resolvedStatus = status || "online";
29806
+ const normalizedAgent = agent.trim().toLowerCase();
29742
29807
  db2.prepare(`
29743
29808
  INSERT INTO agent_presence (agent, status, last_seen_at, metadata)
29744
29809
  VALUES (?, ?, strftime('%Y-%m-%dT%H:%M:%f', 'now'), ?)
@@ -29746,7 +29811,7 @@ function heartbeat(agent, status, metadata) {
29746
29811
  status = excluded.status,
29747
29812
  last_seen_at = excluded.last_seen_at,
29748
29813
  metadata = excluded.metadata
29749
- `).run(agent, resolvedStatus, metadataJson);
29814
+ `).run(normalizedAgent, resolvedStatus, metadataJson);
29750
29815
  }
29751
29816
  function listAgents(opts) {
29752
29817
  const db2 = getDb();
@@ -29761,24 +29826,27 @@ function listAgents(opts) {
29761
29826
  }
29762
29827
  function removePresence(agent) {
29763
29828
  const db2 = getDb();
29764
- const result = db2.prepare("DELETE FROM agent_presence WHERE agent = ?").run(agent);
29829
+ const normalizedAgent = agent.trim().toLowerCase();
29830
+ const result = db2.prepare("DELETE FROM agent_presence WHERE LOWER(agent) = ?").run(normalizedAgent);
29765
29831
  return result.changes > 0;
29766
29832
  }
29767
29833
  function renameAgent(oldName, newName) {
29768
29834
  const db2 = getDb();
29769
- const existing = db2.prepare("SELECT agent FROM agent_presence WHERE agent = ?").get(oldName);
29835
+ const normalizedOld = oldName.trim().toLowerCase();
29836
+ const normalizedNew = newName.trim().toLowerCase();
29837
+ const existing = db2.prepare("SELECT agent FROM agent_presence WHERE LOWER(agent) = ?").get(normalizedOld);
29770
29838
  if (!existing)
29771
29839
  return false;
29772
- const conflict = db2.prepare("SELECT agent FROM agent_presence WHERE agent = ?").get(newName);
29840
+ const conflict = db2.prepare("SELECT agent FROM agent_presence WHERE LOWER(agent) = ?").get(normalizedNew);
29773
29841
  if (conflict)
29774
- throw new Error(`Agent "${newName}" already exists`);
29775
- db2.prepare("UPDATE agent_presence SET agent = ? WHERE agent = ?").run(newName, oldName);
29842
+ throw new Error(`Agent "${normalizedNew}" already exists`);
29843
+ db2.prepare("UPDATE agent_presence SET agent = ? WHERE LOWER(agent) = ?").run(normalizedNew, normalizedOld);
29776
29844
  return true;
29777
29845
  }
29778
29846
  // package.json
29779
29847
  var package_default = {
29780
29848
  name: "@hasna/conversations",
29781
- version: "0.1.22",
29849
+ version: "0.1.24",
29782
29850
  description: "Real-time CLI messaging for AI agents",
29783
29851
  type: "module",
29784
29852
  bin: {
@@ -30571,6 +30639,9 @@ server.registerTool("rename_agent", {
30571
30639
  isError: true
30572
30640
  };
30573
30641
  }
30642
+ if (!fromParam) {
30643
+ updateCachedAutoName(newName);
30644
+ }
30574
30645
  return {
30575
30646
  content: [{ type: "text", text: JSON.stringify({ old_name: oldName, new_name: newName, renamed: true }) }]
30576
30647
  };
package/dist/index.js CHANGED
@@ -3426,6 +3426,7 @@ function heartbeat(agent, status, metadata) {
3426
3426
  const db2 = getDb();
3427
3427
  const metadataJson = metadata ? JSON.stringify(metadata) : null;
3428
3428
  const resolvedStatus = status || "online";
3429
+ const normalizedAgent = agent.trim().toLowerCase();
3429
3430
  db2.prepare(`
3430
3431
  INSERT INTO agent_presence (agent, status, last_seen_at, metadata)
3431
3432
  VALUES (?, ?, strftime('%Y-%m-%dT%H:%M:%f', 'now'), ?)
@@ -3433,11 +3434,12 @@ function heartbeat(agent, status, metadata) {
3433
3434
  status = excluded.status,
3434
3435
  last_seen_at = excluded.last_seen_at,
3435
3436
  metadata = excluded.metadata
3436
- `).run(agent, resolvedStatus, metadataJson);
3437
+ `).run(normalizedAgent, resolvedStatus, metadataJson);
3437
3438
  }
3438
3439
  function getPresence(agent) {
3439
3440
  const db2 = getDb();
3440
- const row = db2.prepare("SELECT * FROM agent_presence WHERE agent = ?").get(agent);
3441
+ const normalizedAgent = agent.trim().toLowerCase();
3442
+ const row = db2.prepare("SELECT * FROM agent_presence WHERE LOWER(agent) = ?").get(normalizedAgent);
3441
3443
  return row ? parsePresence(row) : null;
3442
3444
  }
3443
3445
  function listAgents(opts) {
@@ -3453,18 +3455,21 @@ function listAgents(opts) {
3453
3455
  }
3454
3456
  function removePresence(agent) {
3455
3457
  const db2 = getDb();
3456
- const result = db2.prepare("DELETE FROM agent_presence WHERE agent = ?").run(agent);
3458
+ const normalizedAgent = agent.trim().toLowerCase();
3459
+ const result = db2.prepare("DELETE FROM agent_presence WHERE LOWER(agent) = ?").run(normalizedAgent);
3457
3460
  return result.changes > 0;
3458
3461
  }
3459
3462
  function renameAgent(oldName, newName) {
3460
3463
  const db2 = getDb();
3461
- const existing = db2.prepare("SELECT agent FROM agent_presence WHERE agent = ?").get(oldName);
3464
+ const normalizedOld = oldName.trim().toLowerCase();
3465
+ const normalizedNew = newName.trim().toLowerCase();
3466
+ const existing = db2.prepare("SELECT agent FROM agent_presence WHERE LOWER(agent) = ?").get(normalizedOld);
3462
3467
  if (!existing)
3463
3468
  return false;
3464
- const conflict = db2.prepare("SELECT agent FROM agent_presence WHERE agent = ?").get(newName);
3469
+ const conflict = db2.prepare("SELECT agent FROM agent_presence WHERE LOWER(agent) = ?").get(normalizedNew);
3465
3470
  if (conflict)
3466
- throw new Error(`Agent "${newName}" already exists`);
3467
- db2.prepare("UPDATE agent_presence SET agent = ? WHERE agent = ?").run(newName, oldName);
3471
+ throw new Error(`Agent "${normalizedNew}" already exists`);
3472
+ db2.prepare("UPDATE agent_presence SET agent = ? WHERE LOWER(agent) = ?").run(normalizedNew, normalizedOld);
3468
3473
  return true;
3469
3474
  }
3470
3475
  export {
@@ -14,6 +14,10 @@ export declare function resolveIdentity(explicit?: string): string;
14
14
  * Throws if no identity is set via flag or env.
15
15
  */
16
16
  export declare function requireIdentity(explicit?: string): string;
17
+ /**
18
+ * Update the cached auto name after a successful rename.
19
+ */
20
+ export declare function updateCachedAutoName(newName: string): void;
17
21
  /**
18
22
  * Reset the cached auto name (for testing).
19
23
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/conversations",
3
- "version": "0.1.22",
3
+ "version": "0.1.24",
4
4
  "description": "Real-time CLI messaging for AI agents",
5
5
  "type": "module",
6
6
  "bin": {