@aiaiai-pt/martha-cli 0.44.0 → 0.45.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.
Files changed (2) hide show
  1. package/dist/index.js +44 -15
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -11119,7 +11119,7 @@ init_config();
11119
11119
  init_errors();
11120
11120
 
11121
11121
  // src/version.ts
11122
- var CLI_VERSION = "0.44.0";
11122
+ var CLI_VERSION = "0.45.0";
11123
11123
 
11124
11124
  // src/commands/sessions.ts
11125
11125
  function relativeTime(iso) {
@@ -17735,6 +17735,7 @@ function sleepUnref(ms) {
17735
17735
  });
17736
17736
  }
17737
17737
  var DEFAULT_LEASE_S = 300;
17738
+ var ACK_INTERVAL_MS = 5000;
17738
17739
  function heartbeatIntervalMs(leaseTimeoutS) {
17739
17740
  const lease = typeof leaseTimeoutS === "number" && leaseTimeoutS > 0 ? leaseTimeoutS : DEFAULT_LEASE_S;
17740
17741
  return Math.min(lease / 3, 60) * 1000;
@@ -17820,10 +17821,26 @@ function startupEchoLine(who, opts) {
17820
17821
  const modePart = opts.mode ? `, mode ${opts.mode}` : "";
17821
17822
  return `[runner] attached as ${identity2}${modePart}, scope ${scope}, cwd ${opts.cwd}, ${exec}${opts.once ? " — once" : ""}`;
17822
17823
  }
17824
+ function shouldFlushAck(pendingAckId, lastAckedId, lastAckAt, now, force, intervalMs) {
17825
+ if (!pendingAckId || pendingAckId === lastAckedId)
17826
+ return false;
17827
+ if (force)
17828
+ return true;
17829
+ return now - lastAckAt >= intervalMs;
17830
+ }
17831
+ async function postChannelAck(ctx, cursor, connectToken) {
17832
+ const headers = connectToken ? { Authorization: `Bearer ${connectToken}` } : undefined;
17833
+ try {
17834
+ await ctx.api.post("/api/channel/ingress", { type: "channel.ack", data: { cursor } }, headers ? { headers } : undefined);
17835
+ } catch {}
17836
+ }
17823
17837
  async function runChannelLoop(ctx, state, abort) {
17824
17838
  let lastEventId;
17825
17839
  let backoffMs = 1000;
17826
17840
  const maxBackoff = 30000;
17841
+ let pendingAckId;
17842
+ let lastAckedId;
17843
+ let lastAckAt = 0;
17827
17844
  while (!abort.signal.aborted) {
17828
17845
  let connectToken;
17829
17846
  try {
@@ -17884,28 +17901,40 @@ async function runChannelLoop(ctx, state, abort) {
17884
17901
  backoffMs = 1000;
17885
17902
  process.stderr.write(source_default.dim(`[runner] channel connected${lastEventId ? ` (resumed since ${lastEventId})` : ""}
17886
17903
  `));
17904
+ const maybeFlushAck = async (force) => {
17905
+ const now = Date.now();
17906
+ if (!shouldFlushAck(pendingAckId, lastAckedId, lastAckAt, now, force, ACK_INTERVAL_MS))
17907
+ return;
17908
+ const cursor = pendingAckId;
17909
+ lastAckAt = now;
17910
+ await postChannelAck(ctx, cursor, connectToken);
17911
+ lastAckedId = cursor;
17912
+ };
17887
17913
  try {
17888
17914
  for await (const evt of parseGenericSSE(res.body)) {
17889
17915
  if (abort.signal.aborted)
17890
17916
  break;
17891
17917
  if (evt.id)
17892
17918
  lastEventId = evt.id;
17893
- if (evt.event !== "tool.invoke")
17894
- continue;
17895
- let frame = null;
17896
- try {
17897
- frame = evt.data ? JSON.parse(evt.data) : null;
17898
- } catch {
17899
- continue;
17900
- }
17901
- if (!frame)
17902
- continue;
17903
- try {
17904
- await runToolInvokeFrame(ctx, frame, state, connectToken);
17905
- } catch (e) {
17906
- process.stderr.write(source_default.red(`[runner] tool.invoke execution failed: ${String(e)}
17919
+ if (evt.event === "tool.invoke") {
17920
+ let frame = null;
17921
+ try {
17922
+ frame = evt.data ? JSON.parse(evt.data) : null;
17923
+ } catch {
17924
+ frame = null;
17925
+ }
17926
+ if (frame) {
17927
+ try {
17928
+ await runToolInvokeFrame(ctx, frame, state, connectToken);
17929
+ } catch (e) {
17930
+ process.stderr.write(source_default.red(`[runner] tool.invoke execution failed: ${String(e)}
17907
17931
  `));
17932
+ }
17933
+ }
17908
17934
  }
17935
+ if (evt.id)
17936
+ pendingAckId = evt.id;
17937
+ await maybeFlushAck(evt.event === "channel.control");
17909
17938
  }
17910
17939
  } catch (err) {
17911
17940
  if (abort.signal.aborted)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aiaiai-pt/martha-cli",
3
- "version": "0.44.0",
3
+ "version": "0.45.0",
4
4
  "description": "Terminal-first client for the Martha AI platform",
5
5
  "homepage": "https://docs.martha.nomadriver.co",
6
6
  "repository": {