@athenaintel/react 0.40.1 → 0.40.3

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.
@@ -3,11 +3,35 @@ import { getToolDisplayMeta } from "../agent-runtime/src/tool-metadata.js";
3
3
  function runActivityKey(parts) {
4
4
  const tail = tailPart(parts);
5
5
  if (!tail) return null;
6
- const type = typeof tail["type"] === "string" ? tail["type"] : "unknown";
6
+ const type = tailType(tail);
7
7
  if (type === "text" || type === "reasoning") return null;
8
- const argsText = typeof tail["argsText"] === "string" ? tail["argsText"].length : 0;
8
+ return tailActivityKey({ tail, type, partCount: parts.length });
9
+ }
10
+ const RUN_PROGRESS_TEXT_STEP = 64;
11
+ function runProgressKey(parts) {
12
+ const tail = tailPart(parts);
13
+ if (!tail) return String(parts.length);
14
+ const type = tailType(tail);
15
+ if (type !== "text" && type !== "reasoning") {
16
+ return tailActivityKey({ tail, type, partCount: parts.length });
17
+ }
18
+ const text = tail["text"];
19
+ const step = Math.floor((typeof text === "string" ? text.length : 0) / RUN_PROGRESS_TEXT_STEP);
20
+ return `${parts.length}:${type}:${step}`;
21
+ }
22
+ function tailType(tail) {
23
+ const type = tail["type"];
24
+ return typeof type === "string" ? type : "unknown";
25
+ }
26
+ function tailActivityKey({
27
+ tail,
28
+ type,
29
+ partCount
30
+ }) {
31
+ const argsText = tail["argsText"];
32
+ const argsLength = typeof argsText === "string" ? argsText.length : 0;
9
33
  const settled = hasNoResultYet(tail) ? 0 : 1;
10
- return `${parts.length}:${type}:${argsText}:${settled}`;
34
+ return `${partCount}:${type}:${argsLength}:${settled}`;
11
35
  }
12
36
  function runActivityVerb(parts) {
13
37
  const tail = tailPart(parts);
@@ -60,11 +84,13 @@ export {
60
84
  RUN_ACTIVITY_COUNTER_SECONDS,
61
85
  RUN_ACTIVITY_DEFAULT_VERB,
62
86
  RUN_ACTIVITY_STALL_SECONDS,
87
+ RUN_PROGRESS_TEXT_STEP,
63
88
  isRunActivityStalled,
64
89
  isToolCallInFlight,
65
90
  runActivityKey,
66
91
  runActivityLabel,
67
92
  runActivityVerb,
68
- runElapsedLabel
93
+ runElapsedLabel,
94
+ runProgressKey
69
95
  };
70
96
  //# sourceMappingURL=run-activity.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"run-activity.js","sources":["../../src/chat/run-activity.ts"],"sourcesContent":["import { getToolDisplayMeta } from '@athenaintel/agent-runtime';\nimport { isStreamingToolPlaceholder } from './super-grouping/activity-timeline';\n\n/**\n * Run-liveness key for a streaming assistant message.\n *\n * A tool card's spinner says \"this call is running\"; nothing says the RUN is\n * still alive once parts exist — a stalled stream and a busy one look\n * identical. The activity key summarizes the message tail: it is `null` when\n * no liveness row should show (no parts yet, or a text/reasoning tail that\n * already animates on its own), and otherwise changes whenever anything\n * streams into the tail part — so an elapsed timer keyed on it measures\n * \"time since the stream last moved\", not just \"time since the call began\".\n */\nexport function runActivityKey(parts: ReadonlyArray<unknown>): string | null {\n const tail = tailPart(parts);\n if (!tail) return null;\n const type = typeof tail['type'] === 'string' ? (tail['type'] as string) : 'unknown';\n if (type === 'text' || type === 'reasoning') return null;\n const argsText = typeof tail['argsText'] === 'string' ? (tail['argsText'] as string).length : 0;\n // A streaming placeholder is not a result: the key moves when the real one replaces it.\n const settled = hasNoResultYet(tail) ? 0 : 1;\n return `${parts.length}:${type}:${argsText}:${settled}`;\n}\n\n/**\n * The present-tense verb for what the run is doing right now — the registry's\n * activity label for a tool call still awaiting its result (\"Searching the\n * web\") — or `null` when the tail is not a tool call in flight.\n */\nexport function runActivityVerb(parts: ReadonlyArray<unknown>): string | null {\n const tail = tailPart(parts);\n if (!tail || !isTailToolCallRunning(tail)) return null;\n const toolName = tail['toolName'];\n if (typeof toolName !== 'string' || toolName.length === 0) return null;\n return getToolDisplayMeta(toolName).activeLabel;\n}\n\n/**\n * Whether the run is waiting on a tool that is still running: the tail part\n * is a tool call with no result yet, or only the streaming placeholder a\n * long tool (Python execution, a task subagent) publishes while it works. A\n * command, a build or a test suite streams nothing for minutes while it\n * works, so a quiet stream then is work, not a stall.\n */\nexport function isToolCallInFlight(parts: ReadonlyArray<unknown>): boolean {\n const tail = tailPart(parts);\n return tail !== null && isTailToolCallRunning(tail);\n}\n\nfunction isTailToolCallRunning(tail: Record<string, unknown>): boolean {\n return tail['type'] === 'tool-call' && hasNoResultYet(tail);\n}\n\n/** No result yet: none at all, or only the streaming placeholder (`isStreamingToolPlaceholder`). */\nfunction hasNoResultYet(tail: Record<string, unknown>): boolean {\n return tail['result'] === undefined || isStreamingToolPlaceholder({ artifact: tail['artifact'] });\n}\n\nfunction tailPart(parts: ReadonlyArray<unknown>): Record<string, unknown> | null {\n const last = parts[parts.length - 1];\n if (last === undefined || last === null || typeof last !== 'object') return null;\n return last as Record<string, unknown>;\n}\n\n/**\n * Seconds without any streamed change before the row flips to a stall tone —\n * while the run waits on the model, never while a tool call is in flight\n * ({@link isRunActivityStalled}).\n */\nexport const RUN_ACTIVITY_STALL_SECONDS = 30;\n\n/**\n * Whether the run looks stalled: nothing has streamed for\n * {@link RUN_ACTIVITY_STALL_SECONDS} while it waits on the model. Never while a\n * tool call is in flight: the call's own row says it is running.\n */\nexport function isRunActivityStalled({\n seconds,\n toolCallInFlight,\n}: {\n seconds: number;\n toolCallInFlight: boolean;\n}): boolean {\n return !toolCallInFlight && seconds >= RUN_ACTIVITY_STALL_SECONDS;\n}\n\n/** Seconds before the row starts showing its elapsed counter. */\nexport const RUN_ACTIVITY_COUNTER_SECONDS = 3;\n\n/** The default verb when nothing more specific is known. */\nexport const RUN_ACTIVITY_DEFAULT_VERB = 'Thinking';\n\n/**\n * The counter alone for a card whose header already names the verb: `null`\n * until it is due, then \"11s\" / \"1m 05s\". The stall tone is the caller's\n * (a color and an announcement), not more words on the header row.\n */\nexport function runElapsedLabel(seconds: number): string | null {\n if (seconds < RUN_ACTIVITY_COUNTER_SECONDS) return null;\n if (seconds < 60) return `${seconds}s`;\n const minutes = Math.floor(seconds / 60);\n const remainder = seconds % 60;\n return `${minutes}m ${String(remainder).padStart(2, '0')}s`;\n}\n\n/**\n * The status line for `seconds` since the stream last moved: the verb with an\n * ellipsis and the elapsed counter once it is due (`runElapsedLabel`), or the\n * stall wording when the run looks `stalled` ({@link isRunActivityStalled}).\n */\nexport function runActivityLabel({\n seconds,\n verb = RUN_ACTIVITY_DEFAULT_VERB,\n stalled,\n}: {\n seconds: number;\n verb?: string;\n stalled: boolean;\n}): string {\n if (stalled) return `Still working — nothing new for ${seconds}s`;\n const elapsed = runElapsedLabel(seconds);\n return elapsed === null ? `${verb}…` : `${verb}… · ${elapsed}`;\n}\n"],"names":[],"mappings":";;AAcO,SAAS,eAAe,OAA8C;AAC3E,QAAM,OAAO,SAAS,KAAK;AAC3B,MAAI,CAAC,KAAM,QAAO;AAClB,QAAM,OAAO,OAAO,KAAK,MAAM,MAAM,WAAY,KAAK,MAAM,IAAe;AAC3E,MAAI,SAAS,UAAU,SAAS,YAAa,QAAO;AACpD,QAAM,WAAW,OAAO,KAAK,UAAU,MAAM,WAAY,KAAK,UAAU,EAAa,SAAS;AAE9F,QAAM,UAAU,eAAe,IAAI,IAAI,IAAI;AAC3C,SAAO,GAAG,MAAM,MAAM,IAAI,IAAI,IAAI,QAAQ,IAAI,OAAO;AACvD;AAOO,SAAS,gBAAgB,OAA8C;AAC5E,QAAM,OAAO,SAAS,KAAK;AAC3B,MAAI,CAAC,QAAQ,CAAC,sBAAsB,IAAI,EAAG,QAAO;AAClD,QAAM,WAAW,KAAK,UAAU;AAChC,MAAI,OAAO,aAAa,YAAY,SAAS,WAAW,EAAG,QAAO;AAClE,SAAO,mBAAmB,QAAQ,EAAE;AACtC;AASO,SAAS,mBAAmB,OAAwC;AACzE,QAAM,OAAO,SAAS,KAAK;AAC3B,SAAO,SAAS,QAAQ,sBAAsB,IAAI;AACpD;AAEA,SAAS,sBAAsB,MAAwC;AACrE,SAAO,KAAK,MAAM,MAAM,eAAe,eAAe,IAAI;AAC5D;AAGA,SAAS,eAAe,MAAwC;AAC9D,SAAO,KAAK,QAAQ,MAAM,UAAa,2BAA2B,EAAE,UAAU,KAAK,UAAU,GAAG;AAClG;AAEA,SAAS,SAAS,OAA+D;AAC/E,QAAM,OAAO,MAAM,MAAM,SAAS,CAAC;AACnC,MAAI,SAAS,UAAa,SAAS,QAAQ,OAAO,SAAS,SAAU,QAAO;AAC5E,SAAO;AACT;AAOO,MAAM,6BAA6B;AAOnC,SAAS,qBAAqB;AAAA,EACnC;AAAA,EACA;AACF,GAGY;AACV,SAAO,CAAC,oBAAoB,WAAW;AACzC;AAGO,MAAM,+BAA+B;AAGrC,MAAM,4BAA4B;AAOlC,SAAS,gBAAgB,SAAgC;AAC9D,MAAI,UAAU,6BAA8B,QAAO;AACnD,MAAI,UAAU,GAAI,QAAO,GAAG,OAAO;AACnC,QAAM,UAAU,KAAK,MAAM,UAAU,EAAE;AACvC,QAAM,YAAY,UAAU;AAC5B,SAAO,GAAG,OAAO,KAAK,OAAO,SAAS,EAAE,SAAS,GAAG,GAAG,CAAC;AAC1D;AAOO,SAAS,iBAAiB;AAAA,EAC/B;AAAA,EACA,OAAO;AAAA,EACP;AACF,GAIW;AACT,MAAI,QAAS,QAAO,mCAAmC,OAAO;AAC9D,QAAM,UAAU,gBAAgB,OAAO;AACvC,SAAO,YAAY,OAAO,GAAG,IAAI,MAAM,GAAG,IAAI,OAAO,OAAO;AAC9D;"}
1
+ {"version":3,"file":"run-activity.js","sources":["../../src/chat/run-activity.ts"],"sourcesContent":["import { getToolDisplayMeta } from '@athenaintel/agent-runtime';\nimport { isStreamingToolPlaceholder } from './super-grouping/activity-timeline';\n\n/**\n * Run-liveness key for a streaming assistant message.\n *\n * A tool card's spinner says \"this call is running\"; nothing says the RUN is\n * still alive once parts exist — a stalled stream and a busy one look\n * identical. The activity key summarizes the message tail: it is `null` when\n * no liveness row should show (no parts yet, or a text/reasoning tail that\n * already animates on its own), and otherwise changes whenever anything\n * streams into the tail part. The stall clock itself keys on\n * {@link runProgressKey}, which also moves while a text or reasoning tail grows.\n */\nexport function runActivityKey(parts: ReadonlyArray<unknown>): string | null {\n const tail = tailPart(parts);\n if (!tail) return null;\n const type = tailType(tail);\n if (type === 'text' || type === 'reasoning') return null;\n return tailActivityKey({ tail, type, partCount: parts.length });\n}\n\n/**\n * Characters of streamed text or reasoning per step of {@link runProgressKey}.\n * The model writes a step within a second at any ordinary streaming rate, so\n * the stall clock restarts about as often as words arrive, while the small\n * meta that reads the key re-renders once per step, never once per token. Only\n * a stream slower than one step per stall window (about two characters a\n * second) could read as quiet while it writes.\n */\nexport const RUN_PROGRESS_TEXT_STEP = 64;\n\n/**\n * The stall clock's key for a streaming assistant message: it changes\n * whenever anything streams, so a timer keyed on it counts the seconds\n * nothing has streamed, which is what the stall tone says\n * ({@link isRunActivityStalled}). A part added, a tool call's arguments\n * growing, a result landing, or the tail's text or reasoning growing by\n * another {@link RUN_PROGRESS_TEXT_STEP} characters each move it. A primitive,\n * so a selector returning it re-renders nothing while the stream is still.\n * A tail that is not text or reasoning keys as {@link runActivityKey} does.\n */\nexport function runProgressKey(parts: ReadonlyArray<unknown>): string {\n const tail = tailPart(parts);\n if (!tail) return String(parts.length);\n const type = tailType(tail);\n if (type !== 'text' && type !== 'reasoning') {\n return tailActivityKey({ tail, type, partCount: parts.length });\n }\n const text = tail['text'];\n const step = Math.floor((typeof text === 'string' ? text.length : 0) / RUN_PROGRESS_TEXT_STEP);\n return `${parts.length}:${type}:${step}`;\n}\n\nfunction tailType(tail: Record<string, unknown>): string {\n const type = tail['type'];\n return typeof type === 'string' ? type : 'unknown';\n}\n\n/** What a tool-call (or any other non-text) tail has streamed: its arguments so far, and whether its result is in. */\nfunction tailActivityKey({\n tail,\n type,\n partCount,\n}: {\n tail: Record<string, unknown>;\n type: string;\n partCount: number;\n}): string {\n const argsText = tail['argsText'];\n const argsLength = typeof argsText === 'string' ? argsText.length : 0;\n // A streaming placeholder is not a result: the key moves when the real one replaces it.\n const settled = hasNoResultYet(tail) ? 0 : 1;\n return `${partCount}:${type}:${argsLength}:${settled}`;\n}\n\n/**\n * The present-tense verb for what the run is doing right now — the registry's\n * activity label for a tool call still awaiting its result (\"Searching the\n * web\") — or `null` when the tail is not a tool call in flight.\n */\nexport function runActivityVerb(parts: ReadonlyArray<unknown>): string | null {\n const tail = tailPart(parts);\n if (!tail || !isTailToolCallRunning(tail)) return null;\n const toolName = tail['toolName'];\n if (typeof toolName !== 'string' || toolName.length === 0) return null;\n return getToolDisplayMeta(toolName).activeLabel;\n}\n\n/**\n * Whether the run is waiting on a tool that is still running: the tail part\n * is a tool call with no result yet, or only the streaming placeholder a\n * long tool (Python execution, a task subagent) publishes while it works. A\n * command, a build or a test suite streams nothing for minutes while it\n * works, so a quiet stream then is work, not a stall.\n */\nexport function isToolCallInFlight(parts: ReadonlyArray<unknown>): boolean {\n const tail = tailPart(parts);\n return tail !== null && isTailToolCallRunning(tail);\n}\n\nfunction isTailToolCallRunning(tail: Record<string, unknown>): boolean {\n return tail['type'] === 'tool-call' && hasNoResultYet(tail);\n}\n\n/** No result yet: none at all, or only the streaming placeholder (`isStreamingToolPlaceholder`). */\nfunction hasNoResultYet(tail: Record<string, unknown>): boolean {\n return tail['result'] === undefined || isStreamingToolPlaceholder({ artifact: tail['artifact'] });\n}\n\nfunction tailPart(parts: ReadonlyArray<unknown>): Record<string, unknown> | null {\n const last = parts[parts.length - 1];\n if (last === undefined || last === null || typeof last !== 'object') return null;\n return last as Record<string, unknown>;\n}\n\n/**\n * Seconds without any streamed change before the row flips to a stall tone —\n * while the run waits on the model, never while a tool call is in flight\n * ({@link isRunActivityStalled}).\n */\nexport const RUN_ACTIVITY_STALL_SECONDS = 30;\n\n/**\n * Whether the run looks stalled: nothing has streamed for\n * {@link RUN_ACTIVITY_STALL_SECONDS} while it waits on the model. Never while a\n * tool call is in flight: the call's own row says it is running.\n */\nexport function isRunActivityStalled({\n seconds,\n toolCallInFlight,\n}: {\n seconds: number;\n toolCallInFlight: boolean;\n}): boolean {\n return !toolCallInFlight && seconds >= RUN_ACTIVITY_STALL_SECONDS;\n}\n\n/** Seconds before the row starts showing its elapsed counter. */\nexport const RUN_ACTIVITY_COUNTER_SECONDS = 3;\n\n/** The default verb when nothing more specific is known. */\nexport const RUN_ACTIVITY_DEFAULT_VERB = 'Thinking';\n\n/**\n * The counter alone for a card whose header already names the verb: `null`\n * until it is due, then \"11s\" / \"1m 05s\". The stall tone is the caller's\n * (a color and an announcement), not more words on the header row.\n */\nexport function runElapsedLabel(seconds: number): string | null {\n if (seconds < RUN_ACTIVITY_COUNTER_SECONDS) return null;\n if (seconds < 60) return `${seconds}s`;\n const minutes = Math.floor(seconds / 60);\n const remainder = seconds % 60;\n return `${minutes}m ${String(remainder).padStart(2, '0')}s`;\n}\n\n/**\n * The status line for `seconds` since the stream last moved: the verb with an\n * ellipsis and the elapsed counter once it is due (`runElapsedLabel`), or the\n * stall wording when the run looks `stalled` ({@link isRunActivityStalled}).\n */\nexport function runActivityLabel({\n seconds,\n verb = RUN_ACTIVITY_DEFAULT_VERB,\n stalled,\n}: {\n seconds: number;\n verb?: string;\n stalled: boolean;\n}): string {\n if (stalled) return `Still working — nothing new for ${seconds}s`;\n const elapsed = runElapsedLabel(seconds);\n return elapsed === null ? `${verb}…` : `${verb}… · ${elapsed}`;\n}\n"],"names":[],"mappings":";;AAcO,SAAS,eAAe,OAA8C;AAC3E,QAAM,OAAO,SAAS,KAAK;AAC3B,MAAI,CAAC,KAAM,QAAO;AAClB,QAAM,OAAO,SAAS,IAAI;AAC1B,MAAI,SAAS,UAAU,SAAS,YAAa,QAAO;AACpD,SAAO,gBAAgB,EAAE,MAAM,MAAM,WAAW,MAAM,QAAQ;AAChE;AAUO,MAAM,yBAAyB;AAY/B,SAAS,eAAe,OAAuC;AACpE,QAAM,OAAO,SAAS,KAAK;AAC3B,MAAI,CAAC,KAAM,QAAO,OAAO,MAAM,MAAM;AACrC,QAAM,OAAO,SAAS,IAAI;AAC1B,MAAI,SAAS,UAAU,SAAS,aAAa;AAC3C,WAAO,gBAAgB,EAAE,MAAM,MAAM,WAAW,MAAM,QAAQ;AAAA,EAChE;AACA,QAAM,OAAO,KAAK,MAAM;AACxB,QAAM,OAAO,KAAK,OAAO,OAAO,SAAS,WAAW,KAAK,SAAS,KAAK,sBAAsB;AAC7F,SAAO,GAAG,MAAM,MAAM,IAAI,IAAI,IAAI,IAAI;AACxC;AAEA,SAAS,SAAS,MAAuC;AACvD,QAAM,OAAO,KAAK,MAAM;AACxB,SAAO,OAAO,SAAS,WAAW,OAAO;AAC3C;AAGA,SAAS,gBAAgB;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AACF,GAIW;AACT,QAAM,WAAW,KAAK,UAAU;AAChC,QAAM,aAAa,OAAO,aAAa,WAAW,SAAS,SAAS;AAEpE,QAAM,UAAU,eAAe,IAAI,IAAI,IAAI;AAC3C,SAAO,GAAG,SAAS,IAAI,IAAI,IAAI,UAAU,IAAI,OAAO;AACtD;AAOO,SAAS,gBAAgB,OAA8C;AAC5E,QAAM,OAAO,SAAS,KAAK;AAC3B,MAAI,CAAC,QAAQ,CAAC,sBAAsB,IAAI,EAAG,QAAO;AAClD,QAAM,WAAW,KAAK,UAAU;AAChC,MAAI,OAAO,aAAa,YAAY,SAAS,WAAW,EAAG,QAAO;AAClE,SAAO,mBAAmB,QAAQ,EAAE;AACtC;AASO,SAAS,mBAAmB,OAAwC;AACzE,QAAM,OAAO,SAAS,KAAK;AAC3B,SAAO,SAAS,QAAQ,sBAAsB,IAAI;AACpD;AAEA,SAAS,sBAAsB,MAAwC;AACrE,SAAO,KAAK,MAAM,MAAM,eAAe,eAAe,IAAI;AAC5D;AAGA,SAAS,eAAe,MAAwC;AAC9D,SAAO,KAAK,QAAQ,MAAM,UAAa,2BAA2B,EAAE,UAAU,KAAK,UAAU,GAAG;AAClG;AAEA,SAAS,SAAS,OAA+D;AAC/E,QAAM,OAAO,MAAM,MAAM,SAAS,CAAC;AACnC,MAAI,SAAS,UAAa,SAAS,QAAQ,OAAO,SAAS,SAAU,QAAO;AAC5E,SAAO;AACT;AAOO,MAAM,6BAA6B;AAOnC,SAAS,qBAAqB;AAAA,EACnC;AAAA,EACA;AACF,GAGY;AACV,SAAO,CAAC,oBAAoB,WAAW;AACzC;AAGO,MAAM,+BAA+B;AAGrC,MAAM,4BAA4B;AAOlC,SAAS,gBAAgB,SAAgC;AAC9D,MAAI,UAAU,6BAA8B,QAAO;AACnD,MAAI,UAAU,GAAI,QAAO,GAAG,OAAO;AACnC,QAAM,UAAU,KAAK,MAAM,UAAU,EAAE;AACvC,QAAM,YAAY,UAAU;AAC5B,SAAO,GAAG,OAAO,KAAK,OAAO,SAAS,EAAE,SAAS,GAAG,GAAG,CAAC;AAC1D;AAOO,SAAS,iBAAiB;AAAA,EAC/B;AAAA,EACA,OAAO;AAAA,EACP;AACF,GAIW;AACT,MAAI,QAAS,QAAO,mCAAmC,OAAO;AAC9D,QAAM,UAAU,gBAAgB,OAAO;AACvC,SAAO,YAAY,OAAO,GAAG,IAAI,MAAM,GAAG,IAAI,OAAO,OAAO;AAC9D;"}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
3
- const version = "0.40.1";
3
+ const version = "0.40.3";
4
4
  const packageJson = {
5
5
  version
6
6
  };
@@ -1,4 +1,4 @@
1
- const version = "0.40.1";
1
+ const version = "0.40.3";
2
2
  const packageJson = {
3
3
  version
4
4
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@athenaintel/react",
3
- "version": "0.40.1",
3
+ "version": "0.40.3",
4
4
  "description": "Athena React SDK — Build AI-powered chat applications with the Athena platform",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",