open-agents-ai 0.187.441 → 0.187.443

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/dist/index.js CHANGED
@@ -549,7 +549,7 @@ function agentMessageToChatMessage(msg) {
549
549
  function buildEmptyUsage() {
550
550
  return { prompt_tokens: 0, completion_tokens: 0, total_tokens: 0 };
551
551
  }
552
- var VllmBackend, VllmClient;
552
+ var VllmBackend;
553
553
  var init_VllmBackend = __esm({
554
554
  "packages/backend-vllm/dist/VllmBackend.js"() {
555
555
  "use strict";
@@ -691,47 +691,6 @@ var init_VllmBackend = __esm({
691
691
  }
692
692
  }
693
693
  };
694
- VllmClient = class {
695
- backend;
696
- constructor(config) {
697
- this.backend = new VllmBackend({
698
- baseUrl: config.baseUrl,
699
- model: config.model,
700
- apiKey: config.apiKey,
701
- timeoutMs: config.timeout
702
- });
703
- }
704
- async complete(request) {
705
- const agentMessages = request.messages.map((m2) => ({
706
- id: globalThis.crypto.randomUUID(),
707
- sessionId: globalThis.crypto.randomUUID(),
708
- role: m2.role,
709
- content: m2.content,
710
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
711
- }));
712
- const result = await this.backend.complete({
713
- messages: agentMessages,
714
- tools: request.tools,
715
- maxTokens: request.maxTokens,
716
- temperature: request.temperature
717
- });
718
- return {
719
- id: globalThis.crypto.randomUUID(),
720
- content: result.content ?? "",
721
- toolCalls: result.toolCalls.length > 0 ? result.toolCalls.map((tc) => ({
722
- id: tc.id,
723
- name: tc.name,
724
- arguments: JSON.stringify(tc.arguments)
725
- })) : void 0,
726
- usage: {
727
- promptTokens: result.usage.prompt_tokens,
728
- completionTokens: result.usage.completion_tokens,
729
- totalTokens: result.usage.total_tokens
730
- },
731
- finishReason: result.truncated ? "length" : "stop"
732
- };
733
- }
734
- };
735
694
  }
736
695
  });
737
696
 
@@ -509330,11 +509289,9 @@ var init_agent_loop = __esm({
509330
509289
  handlers = [];
509331
509290
  constructor(config) {
509332
509291
  this.config = config;
509333
- this.client = new VllmClient({
509292
+ this.client = new VllmBackend({
509334
509293
  baseUrl: config.backendUrl,
509335
- model: config.model,
509336
- maxTokens: config.maxTokens,
509337
- temperature: config.temperature
509294
+ model: config.model
509338
509295
  });
509339
509296
  this.memory = new MessageHistory();
509340
509297
  this.executor = new ToolExecutor({
@@ -509376,19 +509333,14 @@ var init_agent_loop = __esm({
509376
509333
  results.push(userMsg);
509377
509334
  for (let i2 = 0; i2 < this.config.maxIterations; i2++) {
509378
509335
  this.setState("thinking");
509379
- const messages2 = this.memory.getMessages().map((m2) => ({
509380
- role: m2.role,
509381
- content: m2.content
509382
- }));
509383
509336
  const response = await this.client.complete({
509384
- messages: messages2,
509337
+ messages: this.memory.getMessages(),
509385
509338
  tools: this.executor.getToolDefinitions()
509386
509339
  });
509387
509340
  if (response.toolCalls && response.toolCalls.length > 0) {
509388
509341
  this.setState("executing_tool");
509389
509342
  for (const toolCall of response.toolCalls) {
509390
- const args = JSON.parse(toolCall.arguments);
509391
- const result = await this.executor.execute(toolCall.name, args);
509343
+ const result = await this.executor.execute(toolCall.name, toolCall.arguments);
509392
509344
  const toolMsg = {
509393
509345
  id: crypto.randomUUID(),
509394
509346
  sessionId: userMsg.sessionId,
@@ -509414,7 +509366,7 @@ var init_agent_loop = __esm({
509414
509366
  id: crypto.randomUUID(),
509415
509367
  sessionId: userMsg.sessionId,
509416
509368
  role: "assistant",
509417
- content: response.content,
509369
+ content: response.content ?? "",
509418
509370
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
509419
509371
  };
509420
509372
  this.memory.add(assistantMsg);
@@ -531184,7 +531136,9 @@ var oa_directory_exports = {};
531184
531136
  __export(oa_directory_exports, {
531185
531137
  OA_DIR: () => OA_DIR,
531186
531138
  buildContextRestorePrompt: () => buildContextRestorePrompt,
531139
+ buildHandoffPrompt: () => buildHandoffPrompt,
531187
531140
  cleanPromptForDiary: () => cleanPromptForDiary,
531141
+ clearTaskHandoff: () => clearTaskHandoff,
531188
531142
  deleteSession: () => deleteSession,
531189
531143
  deleteUsageRecord: () => deleteUsageRecord,
531190
531144
  discoverContextFiles: () => discoverContextFiles,
@@ -531202,6 +531156,7 @@ __export(oa_directory_exports, {
531202
531156
  loadUsageHistory: () => loadUsageHistory,
531203
531157
  readIndexData: () => readIndexData,
531204
531158
  readIndexMeta: () => readIndexMeta,
531159
+ readTaskHandoff: () => readTaskHandoff,
531205
531160
  recordUsage: () => recordUsage,
531206
531161
  renderSessionDiary: () => renderSessionDiary,
531207
531162
  resolveSettings: () => resolveSettings,
@@ -531212,7 +531167,8 @@ __export(oa_directory_exports, {
531212
531167
  saveSessionContext: () => saveSessionContext,
531213
531168
  saveSessionHistory: () => saveSessionHistory,
531214
531169
  writeIndexData: () => writeIndexData,
531215
- writeIndexMeta: () => writeIndexMeta
531170
+ writeIndexMeta: () => writeIndexMeta,
531171
+ writeTaskHandoff: () => writeTaskHandoff
531216
531172
  });
531217
531173
  import { existsSync as existsSync59, mkdirSync as mkdirSync34, readFileSync as readFileSync46, writeFileSync as writeFileSync31, readdirSync as readdirSync15, statSync as statSync17, unlinkSync as unlinkSync14, openSync as openSync2, closeSync as closeSync2, renameSync as renameSync3 } from "node:fs";
531218
531174
  import { join as join77, relative as relative6, basename as basename13, dirname as dirname22 } from "node:path";
@@ -531496,6 +531452,91 @@ function loadPendingTask(repoRoot) {
531496
531452
  return null;
531497
531453
  }
531498
531454
  }
531455
+ function writeTaskHandoff(repoRoot, handoff) {
531456
+ const contextDir = join77(repoRoot, OA_DIR, "context");
531457
+ mkdirSync34(contextDir, { recursive: true });
531458
+ const filePath = join77(contextDir, HANDOFF_FILE);
531459
+ const tempPath = filePath + ".tmp";
531460
+ writeFileSync31(tempPath, JSON.stringify(handoff, null, 2) + "\n", "utf-8");
531461
+ try {
531462
+ renameSync3(tempPath, filePath);
531463
+ } catch {
531464
+ writeFileSync31(filePath, JSON.stringify(handoff, null, 2) + "\n", "utf-8");
531465
+ try {
531466
+ unlinkSync14(tempPath);
531467
+ } catch {
531468
+ }
531469
+ }
531470
+ }
531471
+ function readTaskHandoff(repoRoot) {
531472
+ const filePath = join77(repoRoot, OA_DIR, "context", HANDOFF_FILE);
531473
+ try {
531474
+ if (!existsSync59(filePath)) return null;
531475
+ const data = JSON.parse(readFileSync46(filePath, "utf-8"));
531476
+ const handoffTime = new Date(data.handoffAt).getTime();
531477
+ const now = Date.now();
531478
+ const ageMs = now - handoffTime;
531479
+ const maxAgeMs = 24 * 60 * 60 * 1e3;
531480
+ if (ageMs > maxAgeMs) {
531481
+ return null;
531482
+ }
531483
+ return data;
531484
+ } catch {
531485
+ return null;
531486
+ }
531487
+ }
531488
+ function clearTaskHandoff(repoRoot) {
531489
+ const filePath = join77(repoRoot, OA_DIR, "context", HANDOFF_FILE);
531490
+ try {
531491
+ if (existsSync59(filePath)) {
531492
+ unlinkSync14(filePath);
531493
+ }
531494
+ } catch {
531495
+ }
531496
+ }
531497
+ function buildHandoffPrompt(repoRoot) {
531498
+ const handoff = readTaskHandoff(repoRoot);
531499
+ if (!handoff || !handoff.eligible) return null;
531500
+ const lines = ["<task-handoff>", ""];
531501
+ lines.push(`## Previous Task: ${handoff.base.task.slice(0, 100)}...`);
531502
+ lines.push("");
531503
+ if (handoff.accomplishments.length > 0) {
531504
+ lines.push("### Accomplished:");
531505
+ for (const a2 of handoff.accomplishments.slice(0, 5)) {
531506
+ lines.push(`- ${a2}`);
531507
+ }
531508
+ lines.push("");
531509
+ }
531510
+ if (handoff.files.length > 0) {
531511
+ lines.push("### Files Modified:");
531512
+ for (const f2 of handoff.files.slice(0, 5)) {
531513
+ const op = f2.operation;
531514
+ const anchors = f2.anchors?.length ? ` (${f2.anchors.slice(0, 3).join(", ")})` : "";
531515
+ lines.push(`- [${op}] ${f2.path}${anchors}`);
531516
+ }
531517
+ lines.push("");
531518
+ }
531519
+ if (handoff.findings.length > 0) {
531520
+ lines.push("### Critical Findings:");
531521
+ for (const f2 of handoff.findings.slice(0, 5)) {
531522
+ lines.push(`- ${f2}`);
531523
+ }
531524
+ lines.push("");
531525
+ }
531526
+ if (handoff.memories.length > 0) {
531527
+ lines.push("### Memories Used:");
531528
+ for (const m2 of handoff.memories.slice(0, 3)) {
531529
+ lines.push(`- [${m2.topic}/${m2.key}]: ${m2.relevance}`);
531530
+ }
531531
+ lines.push("");
531532
+ }
531533
+ lines.push("### Validation:");
531534
+ lines.push(`- Tests: ${handoff.validation.testsRan ? handoff.validation.testsPassed ? "✓ passed" : "✗ failed" : "not run"}`);
531535
+ lines.push(`- Build: ${handoff.validation.buildSucceeded ? "✓ succeeded" : "✗ failed"}`);
531536
+ lines.push("");
531537
+ lines.push("</task-handoff>");
531538
+ return lines.join("\n");
531539
+ }
531499
531540
  function computeDedupeHash(task, savedAt) {
531500
531541
  return createHash8("sha256").update(`${task}|${savedAt}`).digest("hex").slice(0, 16);
531501
531542
  }
@@ -531782,6 +531823,17 @@ function loadSessionContext(repoRoot) {
531782
531823
  }
531783
531824
  function buildContextRestorePrompt(repoRoot) {
531784
531825
  const ctx3 = loadSessionContext(repoRoot);
531826
+ const handoffPrompt = buildHandoffPrompt(repoRoot);
531827
+ if (handoffPrompt) {
531828
+ const baseCtx = ctx3 && ctx3.entries.length > 0 ? `
531829
+
531830
+ <session-recap>
531831
+ Recent tasks: ${ctx3.entries.slice(-3).map(
531832
+ (e2) => `[${e2.completed ? "done" : "partial"}] ${normalizeSessionText(e2.summary || e2.task, 80)}`
531833
+ ).join(", ")}
531834
+ </session-recap>` : "";
531835
+ return handoffPrompt + baseCtx;
531836
+ }
531785
531837
  if (!ctx3 || ctx3.entries.length === 0) return null;
531786
531838
  const recent = ctx3.entries.slice(-5);
531787
531839
  const chronology = recent.map((e2) => {
@@ -532098,7 +532150,7 @@ function deleteUsageRecord(kind, value2, repoRoot) {
532098
532150
  remove(join77(repoRoot, OA_DIR, USAGE_HISTORY_FILE));
532099
532151
  }
532100
532152
  }
532101
- var OA_DIR, SUBDIRS, CONTEXT_FILES, PENDING_TASK_FILE, CONTEXT_SAVE_FILE, MAX_CONTEXT_ENTRIES, SAME_TASK_REPLACE_WINDOW_MS, LOCK_TIMEOUT_MS, LOCK_RETRY_MS, LOCK_RETRY_MAX, SESSIONS_DIR, SESSIONS_INDEX, SKIP_DIRS2, HOME_SKIP_DIRS, USAGE_HISTORY_FILE, MAX_HISTORY_RECORDS;
532153
+ var OA_DIR, SUBDIRS, CONTEXT_FILES, PENDING_TASK_FILE, HANDOFF_FILE, CONTEXT_SAVE_FILE, MAX_CONTEXT_ENTRIES, SAME_TASK_REPLACE_WINDOW_MS, LOCK_TIMEOUT_MS, LOCK_RETRY_MS, LOCK_RETRY_MAX, SESSIONS_DIR, SESSIONS_INDEX, SKIP_DIRS2, HOME_SKIP_DIRS, USAGE_HISTORY_FILE, MAX_HISTORY_RECORDS;
532102
532154
  var init_oa_directory = __esm({
532103
532155
  "packages/cli/src/tui/oa-directory.ts"() {
532104
532156
  "use strict";
@@ -532115,6 +532167,7 @@ var init_oa_directory = __esm({
532115
532167
  "AGENTS.md"
532116
532168
  ];
532117
532169
  PENDING_TASK_FILE = "pending-task.json";
532170
+ HANDOFF_FILE = "task-handoff.json";
532118
532171
  CONTEXT_SAVE_FILE = "session-context.json";
532119
532172
  MAX_CONTEXT_ENTRIES = 20;
532120
532173
  SAME_TASK_REPLACE_WINDOW_MS = 12 * 60 * 60 * 1e3;
@@ -544638,7 +544691,26 @@ async function stepEndpoints(config, ollamaUrl, rl, availableRows, repoRoot) {
544638
544691
  return true;
544639
544692
  }
544640
544693
  if (item.key === "add_custom") {
544641
- _helpers.render();
544694
+ _helpers.getInput("Enter custom endpoint URL:", "").then((url) => {
544695
+ if (url && url.trim()) {
544696
+ const trimmedUrl = url.trim();
544697
+ try {
544698
+ new URL(trimmedUrl);
544699
+ config.endpoints.push({
544700
+ kind: "custom",
544701
+ label: trimmedUrl.replace(/^https?:\/\//, "").split("/")[0] || "Custom",
544702
+ url: trimmedUrl,
544703
+ enabled: true,
544704
+ models: []
544705
+ });
544706
+ _helpers.done();
544707
+ } catch {
544708
+ _helpers.done();
544709
+ }
544710
+ } else {
544711
+ _helpers.done();
544712
+ }
544713
+ });
544642
544714
  return true;
544643
544715
  }
544644
544716
  return false;
@@ -585177,6 +585249,42 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
585177
585249
  });
585178
585250
  } catch {
585179
585251
  }
585252
+ try {
585253
+ const handoff = {
585254
+ base: {
585255
+ savedAt: (/* @__PURE__ */ new Date()).toISOString(),
585256
+ task: cleanPromptForDiary(task).slice(0, 500),
585257
+ summary: result.summary.slice(0, 500),
585258
+ assistantResponse: cleanForStorage(lastAssistantText || result.summary).slice(0, 1200),
585259
+ filesModified: Array.from(filesTouched).slice(0, 30),
585260
+ toolCalls: result.toolCalls,
585261
+ completed: result.completed,
585262
+ model: config.model,
585263
+ source: "task_complete"
585264
+ },
585265
+ accomplishments: [],
585266
+ // Populated by agent if it provides structured output
585267
+ files: Array.from(filesTouched).slice(0, 20).map((f2) => ({
585268
+ path: f2,
585269
+ operation: "modified"
585270
+ })),
585271
+ memories: [],
585272
+ // Populated from memory recalls during task
585273
+ findings: [],
585274
+ // Populated by agent
585275
+ validation: {
585276
+ testsRan: false,
585277
+ // Would need to track during task
585278
+ testsPassed: false,
585279
+ buildSucceeded: true
585280
+ // Assume success if task completed
585281
+ },
585282
+ eligible: result.completed,
585283
+ handoffAt: (/* @__PURE__ */ new Date()).toISOString()
585284
+ };
585285
+ writeTaskHandoff(repoRoot, handoff);
585286
+ } catch {
585287
+ }
585180
585288
  try {
585181
585289
  const sessionId2 = `session-${Date.now().toString(36)}`;
585182
585290
  const contentLines = statusBar?._contentLines ?? [];
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.187.441",
3
+ "version": "0.187.443",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "open-agents-ai",
9
- "version": "0.187.441",
9
+ "version": "0.187.443",
10
10
  "hasInstallScript": true,
11
11
  "license": "CC-BY-NC-4.0",
12
12
  "dependencies": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.187.441",
3
+ "version": "0.187.443",
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",