@tiflis-io/tiflis-code-workstation 0.3.13 → 0.3.14

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/main.js +30 -23
  2. package/package.json +1 -1
package/dist/main.js CHANGED
@@ -110,8 +110,8 @@ var EnvSchema = z.object({
110
110
  // ─────────────────────────────────────────────────────────────
111
111
  // Headless Agents Configuration
112
112
  // ─────────────────────────────────────────────────────────────
113
- /** Timeout for agent command execution in seconds (default: 15 minutes) */
114
- AGENT_EXECUTION_TIMEOUT: z.coerce.number().default(900),
113
+ /** Timeout for agent command execution in seconds (default: 2 hours) */
114
+ AGENT_EXECUTION_TIMEOUT: z.coerce.number().default(7200),
115
115
  CLAUDE_SESSION_LOCK_WAIT_MS: z.coerce.number().default(1500),
116
116
  // ─────────────────────────────────────────────────────────────
117
117
  // Agent Visibility Configuration
@@ -343,8 +343,8 @@ var AGENT_COMMANDS = {
343
343
  }
344
344
  };
345
345
  var AGENT_EXECUTION_CONFIG = {
346
- /** Default execution timeout (seconds) - 15 minutes for complex tasks */
347
- DEFAULT_TIMEOUT_SECONDS: 900,
346
+ /** Default execution timeout (seconds) - 2 hours for complex tasks */
347
+ DEFAULT_TIMEOUT_SECONDS: 7200,
348
348
  /** Timeout for waiting on process termination during graceful shutdown (ms) */
349
349
  GRACEFUL_SHUTDOWN_TIMEOUT_MS: 2e3,
350
350
  /** Maximum buffer size for JSON line parsing (bytes) */
@@ -5173,7 +5173,8 @@ var MessageRepository = class {
5173
5173
  const result = db2.select({ maxSeq: max(messages.sequence) }).from(messages).where(eq3(messages.sessionId, params.sessionId)).get();
5174
5174
  const nextSequence = (result?.maxSeq ?? 0) + 1;
5175
5175
  const newMessage = {
5176
- id: nanoid2(16),
5176
+ id: params.messageId ?? nanoid2(16),
5177
+ // Use provided ID or generate new one
5177
5178
  sessionId: params.sessionId,
5178
5179
  sequence: nextSequence,
5179
5180
  role: params.role,
@@ -5846,8 +5847,9 @@ var ChatHistoryService = class _ChatHistoryService {
5846
5847
  * Saves a supervisor message to the database.
5847
5848
  * Messages are shared across all devices connected to this workstation.
5848
5849
  * @param contentBlocks - Optional structured content blocks (for assistant messages)
5850
+ * @param messageId - Optional ID to use (e.g., streaming_message_id for deduplication)
5849
5851
  */
5850
- saveSupervisorMessage(role, content, contentBlocks) {
5852
+ saveSupervisorMessage(role, content, contentBlocks, messageId) {
5851
5853
  this.ensureSupervisorSession();
5852
5854
  const sessionId = _ChatHistoryService.SUPERVISOR_SESSION_ID;
5853
5855
  const params = {
@@ -5856,7 +5858,9 @@ var ChatHistoryService = class _ChatHistoryService {
5856
5858
  contentType: "text",
5857
5859
  content,
5858
5860
  contentBlocks: contentBlocks ? JSON.stringify(contentBlocks) : void 0,
5859
- isComplete: true
5861
+ isComplete: true,
5862
+ messageId
5863
+ // Pass through to repository for consistent IDs
5860
5864
  };
5861
5865
  const saved = this.messageRepo.create(params);
5862
5866
  this.logger.debug(
@@ -5945,14 +5949,16 @@ var ChatHistoryService = class _ChatHistoryService {
5945
5949
  * @param content - Text content (summary for assistant messages)
5946
5950
  * @param contentBlocks - Structured content blocks for rich UI
5947
5951
  */
5948
- saveAgentMessage(sessionId, role, content, contentBlocks) {
5952
+ saveAgentMessage(sessionId, role, content, contentBlocks, messageId) {
5949
5953
  const params = {
5950
5954
  sessionId,
5951
5955
  role,
5952
5956
  contentType: "text",
5953
5957
  content,
5954
5958
  contentBlocks: contentBlocks ? JSON.stringify(contentBlocks) : void 0,
5955
- isComplete: true
5959
+ isComplete: true,
5960
+ messageId
5961
+ // Pass through to repository
5956
5962
  };
5957
5963
  const saved = this.messageRepo.create(params);
5958
5964
  this.logger.debug(
@@ -10608,7 +10614,7 @@ async function bootstrap() {
10608
10614
  const isExecuting = supervisorAgent.isProcessing();
10609
10615
  let currentStreamingBlocks;
10610
10616
  let streamingMessageId;
10611
- if (isExecuting && !beforeSequence) {
10617
+ if (isExecuting) {
10612
10618
  const blocks = supervisorMessageAccumulator.get();
10613
10619
  if (blocks.length > 0) {
10614
10620
  currentStreamingBlocks = blocks;
@@ -10664,7 +10670,7 @@ async function bootstrap() {
10664
10670
  const isExecuting = agentSessionManager.isExecuting(sessionId);
10665
10671
  let currentStreamingBlocks;
10666
10672
  let streamingMessageId;
10667
- if (isExecuting && !beforeSequence) {
10673
+ if (isExecuting) {
10668
10674
  const blocks = agentMessageAccumulator.get(sessionId);
10669
10675
  if (blocks && blocks.length > 0) {
10670
10676
  currentStreamingBlocks = blocks;
@@ -10920,11 +10926,11 @@ async function bootstrap() {
10920
10926
  );
10921
10927
  }
10922
10928
  }
10929
+ const accumulatedBlocks = agentMessageAccumulator.get(sessionId) ?? [];
10930
+ const streamingMessageId = getOrCreateAgentStreamingMessageId(sessionId);
10923
10931
  let fullTextContent = "";
10924
10932
  if (isComplete) {
10925
- const allBlocks = agentMessageAccumulator.get(sessionId) ?? [];
10926
- agentMessageAccumulator.delete(sessionId);
10927
- if (allBlocks.length === 0) {
10933
+ if (accumulatedBlocks.length === 0) {
10928
10934
  logger.warn(
10929
10935
  {
10930
10936
  sessionId,
@@ -10934,8 +10940,8 @@ async function bootstrap() {
10934
10940
  "Completion received but no blocks were accumulated - blocks may be lost"
10935
10941
  );
10936
10942
  }
10937
- if (allBlocks.length > 0) {
10938
- const blockTypeCounts = allBlocks.reduce(
10943
+ if (accumulatedBlocks.length > 0) {
10944
+ const blockTypeCounts = accumulatedBlocks.reduce(
10939
10945
  (acc, b) => {
10940
10946
  acc[b.block_type] = (acc[b.block_type] ?? 0) + 1;
10941
10947
  return acc;
@@ -10945,26 +10951,25 @@ async function bootstrap() {
10945
10951
  logger.info(
10946
10952
  {
10947
10953
  sessionId,
10948
- totalBlocks: allBlocks.length,
10954
+ totalBlocks: accumulatedBlocks.length,
10949
10955
  blockTypes: blockTypeCounts
10950
10956
  },
10951
10957
  "Saving agent message with accumulated blocks"
10952
10958
  );
10953
- fullTextContent = allBlocks.filter((b) => b.block_type === "text").map((b) => b.content).join("\n");
10954
- const hasError = allBlocks.some((b) => b.block_type === "error");
10959
+ fullTextContent = accumulatedBlocks.filter((b) => b.block_type === "text").map((b) => b.content).join("\n");
10960
+ const hasError = accumulatedBlocks.some((b) => b.block_type === "error");
10955
10961
  const role = hasError ? "system" : "assistant";
10956
10962
  chatHistoryService.saveAgentMessage(
10957
10963
  sessionId,
10958
10964
  role,
10959
10965
  fullTextContent,
10960
- allBlocks
10966
+ accumulatedBlocks,
10967
+ streamingMessageId
10961
10968
  );
10962
10969
  }
10963
10970
  }
10964
- const accumulatedBlocks = agentMessageAccumulator.get(sessionId) ?? [];
10965
10971
  const mergedBlocks = mergeToolBlocks(accumulatedBlocks);
10966
10972
  const fullAccumulatedText = mergedBlocks.filter((b) => b.block_type === "text").map((b) => b.content).join("\n");
10967
- const streamingMessageId = getOrCreateAgentStreamingMessageId(sessionId);
10968
10973
  const outputEvent = {
10969
10974
  type: "session.output",
10970
10975
  session_id: sessionId,
@@ -10985,6 +10990,7 @@ async function bootstrap() {
10985
10990
  );
10986
10991
  if (isComplete) {
10987
10992
  clearAgentStreamingMessageId(sessionId);
10993
+ agentMessageAccumulator.delete(sessionId);
10988
10994
  }
10989
10995
  if (isComplete && fullTextContent.length > 0) {
10990
10996
  const pendingVoiceCommand = pendingAgentVoiceCommands.get(sessionId);
@@ -11105,7 +11111,8 @@ async function bootstrap() {
11105
11111
  chatHistoryService.saveSupervisorMessage(
11106
11112
  "assistant",
11107
11113
  finalOutput,
11108
- mergedBlocks
11114
+ mergedBlocks,
11115
+ streamingMessageId ?? void 0
11109
11116
  );
11110
11117
  const pendingVoiceCommand = pendingSupervisorVoiceCommands.get(deviceId);
11111
11118
  if (pendingVoiceCommand && ttsService) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tiflis-io/tiflis-code-workstation",
3
- "version": "0.3.13",
3
+ "version": "0.3.14",
4
4
  "description": "Workstation server for tiflis-code - manages agent sessions and terminal access",
5
5
  "author": "Roman Barinov <rbarinov@gmail.com>",
6
6
  "license": "FSL-1.1-NC",