open-agents-ai 0.186.2 → 0.186.4

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 +60 -87
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -65555,6 +65555,7 @@ body {
65555
65555
  <div id="header">
65556
65556
  <span class="accent">OA</span>
65557
65557
  <span class="status" id="status">connecting...</span>
65558
+ <span id="update-btn" style="display:none;background:#3a2a10;border:1px solid #b2920a;color:#b2920a;padding:2px 8px;border-radius:3px;font-family:inherit;font-size:0.6rem;cursor:pointer" onclick="doUpdate()">update</span>
65558
65559
  <select id="model-select"><option>loading...</option></select>
65559
65560
  <button class="key-btn" onclick="toggleWorkspace()" title="Toggle workspace sidebar">files</button>
65560
65561
  <button class="key-btn" id="sandbox-toggle" onclick="toggleSandbox()" title="Toggle Docker sandbox" style="opacity:0.5">sandbox: off</button>
@@ -65572,19 +65573,18 @@ body {
65572
65573
  <button class="tab" onclick="switchTab('config')" id="tab-config" style="background:none;border:none;border-bottom:2px solid transparent;color:#555;padding:6px 16px;font-family:inherit;font-size:0.7rem;cursor:pointer">config</button>
65573
65574
  <button class="tab" onclick="switchTab('activity')" id="tab-activity" style="background:none;border:none;border-bottom:2px solid transparent;color:#555;padding:6px 16px;font-family:inherit;font-size:0.7rem;cursor:pointer">activity</button>
65574
65575
  <span id="sys-metrics" style="margin-left:auto;font-size:0.6rem;color:#555"></span>
65575
- <span id="update-btn" style="display:none;background:#3a2a10;border:1px solid #b2920a;color:#b2920a;padding:2px 8px;border-radius:3px;font-family:inherit;font-size:0.6rem;cursor:pointer" onclick="doUpdate()">update</span>
65576
65576
  <span id="token-counter" style="font-size:0.6rem;color:#555">0 tokens</span>
65577
65577
  </div>
65578
- <div style="display:flex;flex:1;overflow:hidden">
65579
- <div id="workspace-sidebar" style="display:none;width:250px;background:#1e1e22;border-right:1px solid #2a2a30;overflow-y:auto;padding:8px;flex-shrink:0;font-size:0.7rem">
65580
- <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:8px">
65581
- <span style="color:#b2920a;font-size:0.7rem;font-weight:bold">Workspace</span>
65582
- <button onclick="toggleWorkspace()" style="background:none;border:none;color:#555;cursor:pointer;font-size:0.8rem">x</button>
65578
+ <div id="chat-container" style="display:flex;flex:1;overflow:hidden">
65579
+ <div id="workspace-sidebar" style="display:none;width:250px;background:#1e1e22;border-right:1px solid #2a2a30;overflow-y:auto;padding:8px;flex-shrink:0;font-size:0.7rem">
65580
+ <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:8px">
65581
+ <span style="color:#b2920a;font-size:0.7rem;font-weight:bold">Workspace</span>
65582
+ <button onclick="toggleWorkspace()" style="background:none;border:none;color:#555;cursor:pointer;font-size:0.8rem">x</button>
65583
+ </div>
65584
+ <div id="workspace-cwd" style="color:#555;font-size:0.6rem;margin-bottom:8px;word-break:break-all"></div>
65585
+ <div id="workspace-tree" style="color:#b0b0b0"></div>
65583
65586
  </div>
65584
- <div id="workspace-cwd" style="color:#555;font-size:0.6rem;margin-bottom:8px;word-break:break-all"></div>
65585
- <div id="workspace-tree" style="color:#b0b0b0"></div>
65586
- </div>
65587
- <div id="conversation" style="flex:1;overflow-y:auto;padding:12px 16px;display:flex;flex-direction:column;gap:4px"></div>
65587
+ <div id="conversation" style="flex:1;overflow-y:auto;padding:12px 16px;display:flex;flex-direction:column;gap:4px"></div>
65588
65588
  </div>
65589
65589
  <div id="agent-panel" style="display:none;flex:1;overflow-y:auto;padding:12px 16px">
65590
65590
  <textarea id="agent-task" placeholder="Describe the task for the agent..." style="width:100%;min-height:80px;background:#2a2a30;border:1px solid #3a3a42;border-radius:3px;padding:8px 12px;color:#b0b0b0;font-family:inherit;font-size:0.82rem;resize:vertical;outline:none;margin-bottom:8px"></textarea>
@@ -65853,21 +65853,35 @@ async function sendMessage() {
65853
65853
  messages.push({ role: 'assistant', content: fullContent });
65854
65854
  updateTokenCounter(fullContent.split(/\\s+/).length * 1.3 | 0);
65855
65855
 
65856
- // Final render: content + collapsible tools
65856
+ // Final render: content + collapsible tools + metadata
65857
65857
  contentDiv.innerHTML = renderMarkdown(fullContent);
65858
65858
 
65859
- // Collapse tool calls into a dropdown after streaming completes
65859
+ // Metadata bar: turns, tokens, duration (always shown, compact)
65860
+ if (metaInfo) {
65861
+ const metaBar = document.createElement('div');
65862
+ metaBar.style.cssText = 'margin:6px 0 2px;padding:4px 8px;background:#1e1e22;border-radius:3px;font-size:0.6rem;color:#555;display:flex;gap:12px;flex-wrap:wrap';
65863
+ const parts = [];
65864
+ if (metaInfo.turns) parts.push(metaInfo.turns + ' turn' + (metaInfo.turns > 1 ? 's' : ''));
65865
+ if (metaInfo.toolCalls) parts.push(metaInfo.toolCalls + ' tool call' + (metaInfo.toolCalls > 1 ? 's' : ''));
65866
+ if (metaInfo.tokens) parts.push(metaInfo.tokens + ' tokens');
65867
+ if (metaInfo.duration) parts.push((metaInfo.duration / 1000).toFixed(1) + 's');
65868
+ metaBar.innerHTML = parts.map(p => '<span>' + p + '</span>').join('');
65869
+ msgDiv.appendChild(metaBar);
65870
+ }
65871
+
65872
+ // Collapse tool calls into a dropdown
65860
65873
  if (chatTools.length > 0) {
65861
65874
  const details = document.createElement('details');
65862
- details.style.cssText = 'margin:4px 0;font-size:0.65rem;color:#555';
65875
+ details.style.cssText = 'margin:2px 0;font-size:0.65rem;color:#555';
65863
65876
  const summary = document.createElement('summary');
65864
- summary.style.cssText = 'cursor:pointer;color:#b2920a;font-size:0.65rem';
65865
- summary.textContent = chatTools.length + ' tool call' + (chatTools.length > 1 ? 's' : '') + (metaInfo?.tokens ? ' | ' + metaInfo.tokens + ' tokens' : '') + (metaInfo?.duration ? ' | ' + (metaInfo.duration/1000).toFixed(1) + 's' : '');
65877
+ summary.style.cssText = 'cursor:pointer;color:#888;font-size:0.6rem';
65878
+ summary.textContent = 'show ' + chatTools.length + ' tool call' + (chatTools.length > 1 ? 's' : '');
65866
65879
  details.appendChild(summary);
65867
- // Move live tool elements into the details
65868
65880
  while (toolsContainer.firstChild) details.appendChild(toolsContainer.firstChild);
65869
65881
  toolsContainer.appendChild(details);
65870
65882
  }
65883
+
65884
+ // Action buttons
65871
65885
  const actions = document.createElement('div');
65872
65886
  actions.className = 'msg-actions';
65873
65887
  const copyBtn = document.createElement('button');
@@ -65913,9 +65927,9 @@ function closeKeyModal() {
65913
65927
  }
65914
65928
 
65915
65929
  // Tab switching
65916
- const allPanels = ['conversation','agent-panel','jobs-panel','config-panel','activity-panel'];
65930
+ const allPanels = ['chat-container','agent-panel','jobs-panel','config-panel','activity-panel'];
65917
65931
  function switchTab(tab) {
65918
- const panelMap = {chat:'conversation',agent:'agent-panel',jobs:'jobs-panel',config:'config-panel',activity:'activity-panel'};
65932
+ const panelMap = {chat:'chat-container',agent:'agent-panel',jobs:'jobs-panel',config:'config-panel',activity:'activity-panel'};
65919
65933
  allPanels.forEach(id => { const el = document.getElementById(id); if(el) el.style.display = 'none'; });
65920
65934
  const panel = document.getElementById(panelMap[tab]);
65921
65935
  if (panel) panel.style.display = tab === 'chat' ? 'flex' : 'block';
@@ -68102,89 +68116,46 @@ Respond conversationally. Call task_complete with your final response.`;
68102
68116
  "X-Session-ID": session.id
68103
68117
  });
68104
68118
  let fullContent = "";
68105
- let lastOutput = "";
68106
- let toolCalls = [];
68107
- let rawBuffer = "";
68119
+ let rawOutput = "";
68108
68120
  child.stdout?.on("data", (chunk) => {
68109
- rawBuffer += chunk.toString();
68110
- const lines = rawBuffer.split("\n");
68111
- rawBuffer = lines.pop() || "";
68112
- for (const line of lines) {
68113
- if (!line.trim())
68114
- continue;
68115
- try {
68116
- const evt = JSON.parse(line);
68117
- if (evt.type === "tool_call" || evt.tool) {
68118
- const toolInfo = { tool: evt.tool || evt.name || "unknown", args: evt.args };
68119
- toolCalls.push(toolInfo);
68120
- res.write("data: " + JSON.stringify({ type: "tool_call", ...toolInfo }) + "\n\n");
68121
- } else if (evt.type === "tool_result") {
68122
- const lastTool = toolCalls[toolCalls.length - 1];
68123
- if (lastTool)
68124
- lastTool.result = (evt.output || evt.result || "").slice(0, 500);
68125
- res.write("data: " + JSON.stringify({ type: "tool_result", output: (evt.output || evt.result || "").slice(0, 200) }) + "\n\n");
68126
- } else if (evt.type === "assistant_text" || evt.type === "text") {
68127
- const delta = evt.content || evt.text || "";
68128
- fullContent += delta;
68129
- res.write("data: " + JSON.stringify({
68130
- id: `chatcmpl-${session.id.slice(0, 8)}`,
68131
- object: "chat.completion.chunk",
68132
- choices: [{ index: 0, delta: { content: delta }, finish_reason: null }]
68133
- }) + "\n\n");
68134
- } else if (evt.status === "completed" || evt.type === "task_complete") {
68135
- const summary = evt.summary || evt.content || "";
68136
- const contentMatch = summary.match(/Tokens:\s*[\d,]+\s+(.*)/s);
68137
- const cleanContent = contentMatch ? contentMatch[1].trim() : summary;
68138
- if (cleanContent && cleanContent.length > 5) {
68139
- fullContent = cleanContent;
68140
- res.write("data: " + JSON.stringify({
68141
- id: `chatcmpl-${session.id.slice(0, 8)}`,
68142
- object: "chat.completion.chunk",
68143
- choices: [{ index: 0, delta: { content: cleanContent }, finish_reason: null }]
68144
- }) + "\n\n");
68145
- }
68146
- res.write("data: " + JSON.stringify({
68147
- type: "complete",
68148
- turns: evt.turns || summary.match(/(\d+) turns/)?.[1],
68149
- toolCalls: toolCalls.length,
68150
- tokens: evt.tokens || summary.match(/Tokens:\s*([\d,]+)/)?.[1],
68151
- duration: evt.durationMs || evt.duration
68152
- }) + "\n\n");
68153
- }
68154
- } catch {
68155
- }
68156
- }
68121
+ rawOutput += chunk.toString();
68157
68122
  });
68158
68123
  child.stderr?.on("data", () => {
68159
68124
  });
68160
- child.on("close", () => {
68161
- if (!fullContent) {
68162
- const allOutput = rawBuffer.trim();
68125
+ await new Promise((resolve36) => {
68126
+ child.on("close", () => {
68163
68127
  try {
68164
- const result = JSON.parse(allOutput);
68128
+ const result = JSON.parse(rawOutput.trim());
68165
68129
  let content = result.assistant_text || "";
68166
68130
  if (!content) {
68167
68131
  const summary = result.summary || "";
68168
- const summaryMatch = summary.match(/Tokens:\s*[\d,]+\s+([\s\S]*)/);
68169
- content = summaryMatch ? summaryMatch[1].trim() : summary;
68132
+ const match = summary.match(/Tokens:\s*[\d,]+\s+([\s\S]*)/);
68133
+ content = match ? match[1].trim() : summary;
68170
68134
  }
68171
68135
  fullContent = content;
68172
- res.write("data: " + JSON.stringify({
68173
- id: `chatcmpl-${session.id.slice(0, 8)}`,
68174
- object: "chat.completion.chunk",
68175
- choices: [{ index: 0, delta: { content }, finish_reason: null }]
68176
- }) + "\n\n");
68136
+ if (content) {
68137
+ res.write("data: " + JSON.stringify({
68138
+ id: `chatcmpl-${session.id.slice(0, 8)}`,
68139
+ object: "chat.completion.chunk",
68140
+ choices: [{ index: 0, delta: { content }, finish_reason: null }]
68141
+ }) + "\n\n");
68142
+ }
68143
+ if (result.tool_calls?.length) {
68144
+ for (const tc of result.tool_calls) {
68145
+ res.write("data: " + JSON.stringify({ type: "tool_call", tool: tc.tool, args: tc.args }) + "\n\n");
68146
+ }
68147
+ }
68177
68148
  const meta = result.summary || "";
68178
68149
  res.write("data: " + JSON.stringify({
68179
68150
  type: "complete",
68180
68151
  turns: meta.match(/(\d+) turns/)?.[1],
68181
68152
  tokens: meta.match(/Tokens:\s*([\d,]+)/)?.[1],
68182
- toolCalls: parseInt(meta.match(/(\d+) tool calls/)?.[1] || "0", 10),
68153
+ toolCalls: result.tool_calls?.length || 0,
68183
68154
  duration: result.durationMs
68184
68155
  }) + "\n\n");
68185
68156
  } catch {
68186
- if (allOutput) {
68187
- fullContent = allOutput.slice(0, 500);
68157
+ if (rawOutput.trim()) {
68158
+ fullContent = rawOutput.trim().slice(0, 500);
68188
68159
  res.write("data: " + JSON.stringify({
68189
68160
  id: `chatcmpl-${session.id.slice(0, 8)}`,
68190
68161
  object: "chat.completion.chunk",
@@ -68192,11 +68163,13 @@ Respond conversationally. Call task_complete with your final response.`;
68192
68163
  }) + "\n\n");
68193
68164
  }
68194
68165
  }
68195
- }
68196
- addAssistantMessage(session, fullContent);
68197
- res.write("data: [DONE]\n\n");
68198
- res.end();
68166
+ addAssistantMessage(session, fullContent);
68167
+ res.write("data: [DONE]\n\n");
68168
+ res.end();
68169
+ resolve36();
68170
+ });
68199
68171
  });
68172
+ return;
68200
68173
  } else {
68201
68174
  let output = "";
68202
68175
  child.stdout?.on("data", (chunk) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.186.2",
3
+ "version": "0.186.4",
4
4
  "description": "AI coding agent powered by open-source models (Ollama/vLLM) — interactive TUI with agentic tool-calling loop",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",