open-agents-ai 0.185.21 → 0.185.23
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 +143 -86
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -35253,97 +35253,98 @@ function generateFrontendHTML() {
|
|
|
35253
35253
|
<head>
|
|
35254
35254
|
<meta charset="UTF-8">
|
|
35255
35255
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
35256
|
-
<title>
|
|
35256
|
+
<title>OA \u2014 Voice</title>
|
|
35257
35257
|
<style>
|
|
35258
35258
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
35259
35259
|
body {
|
|
35260
|
-
background: #
|
|
35261
|
-
color: #
|
|
35262
|
-
font-family: 'SF Mono', 'Cascadia Code', 'Fira Code',
|
|
35260
|
+
background: #1a1a1e;
|
|
35261
|
+
color: #b0b0b0;
|
|
35262
|
+
font-family: 'SF Mono', 'Cascadia Code', 'Fira Code', monospace;
|
|
35263
35263
|
display: flex;
|
|
35264
35264
|
flex-direction: column;
|
|
35265
|
-
align-items: center;
|
|
35266
|
-
justify-content: center;
|
|
35267
35265
|
min-height: 100vh;
|
|
35268
|
-
overflow: hidden;
|
|
35269
35266
|
}
|
|
35267
|
+
#header {
|
|
35268
|
+
background: #1e1e22;
|
|
35269
|
+
padding: 8px 16px;
|
|
35270
|
+
display: flex;
|
|
35271
|
+
align-items: center;
|
|
35272
|
+
gap: 12px;
|
|
35273
|
+
border-bottom: 1px solid #2a2a30;
|
|
35274
|
+
}
|
|
35275
|
+
#header .accent { color: #b2920a; font-weight: bold; font-size: 0.8rem; }
|
|
35276
|
+
#header .status { font-size: 0.7rem; color: #555; }
|
|
35277
|
+
#header .status.live { color: #b2920a; }
|
|
35270
35278
|
#waveform {
|
|
35271
|
-
|
|
35272
|
-
height: 80px;
|
|
35279
|
+
height: 48px;
|
|
35273
35280
|
display: flex;
|
|
35274
35281
|
align-items: center;
|
|
35275
35282
|
justify-content: center;
|
|
35276
|
-
font-size:
|
|
35283
|
+
font-size: 1.6rem;
|
|
35277
35284
|
line-height: 1;
|
|
35278
|
-
letter-spacing: 0.
|
|
35285
|
+
letter-spacing: 0.04em;
|
|
35279
35286
|
white-space: nowrap;
|
|
35280
35287
|
overflow: hidden;
|
|
35281
|
-
margin-bottom: 1.5rem;
|
|
35282
35288
|
user-select: none;
|
|
35289
|
+
background: #1e1e22;
|
|
35290
|
+
border-bottom: 1px solid #2a2a30;
|
|
35291
|
+
}
|
|
35292
|
+
#conversation {
|
|
35293
|
+
flex: 1;
|
|
35294
|
+
overflow-y: auto;
|
|
35295
|
+
padding: 12px 16px;
|
|
35296
|
+
}
|
|
35297
|
+
.msg {
|
|
35298
|
+
padding: 6px 0;
|
|
35299
|
+
font-size: 0.82rem;
|
|
35300
|
+
line-height: 1.4;
|
|
35301
|
+
}
|
|
35302
|
+
.msg.user { color: #888; }
|
|
35303
|
+
.msg.user::before { content: '\u25B8 '; color: #555; }
|
|
35304
|
+
.msg.agent { color: #b2920a; }
|
|
35305
|
+
.msg.agent::before { content: '\u25B9 '; color: #b2920a; }
|
|
35306
|
+
#footer {
|
|
35307
|
+
background: #1e1e22;
|
|
35308
|
+
padding: 8px 16px;
|
|
35309
|
+
display: flex;
|
|
35310
|
+
align-items: center;
|
|
35311
|
+
gap: 10px;
|
|
35312
|
+
border-top: 1px solid #2a2a30;
|
|
35283
35313
|
}
|
|
35284
|
-
#title {
|
|
35285
|
-
font-size: 0.75rem;
|
|
35286
|
-
color: #7c3aed;
|
|
35287
|
-
letter-spacing: 0.3em;
|
|
35288
|
-
text-transform: uppercase;
|
|
35289
|
-
margin-bottom: 1.5rem;
|
|
35290
|
-
}
|
|
35291
|
-
#status {
|
|
35292
|
-
font-size: 0.85rem;
|
|
35293
|
-
color: #6b6b8a;
|
|
35294
|
-
margin-bottom: 1rem;
|
|
35295
|
-
}
|
|
35296
|
-
#status .connected { color: #a78bfa; }
|
|
35297
|
-
#status .disconnected { color: #f87171; }
|
|
35298
|
-
#transcripts {
|
|
35299
|
-
width: 90%; max-width: 600px; max-height: 40vh;
|
|
35300
|
-
overflow-y: auto; padding: 1rem;
|
|
35301
|
-
background: rgba(139,92,246,0.04);
|
|
35302
|
-
border-radius: 4px;
|
|
35303
|
-
border: 1px solid rgba(139,92,246,0.12);
|
|
35304
|
-
}
|
|
35305
|
-
.transcript {
|
|
35306
|
-
padding: 0.35rem 0;
|
|
35307
|
-
border-bottom: 1px solid rgba(139,92,246,0.08);
|
|
35308
|
-
font-size: 0.8rem;
|
|
35309
|
-
color: #a5a0c8;
|
|
35310
|
-
}
|
|
35311
|
-
.transcript .speaker { font-weight: bold; margin-right: 0.5rem; }
|
|
35312
|
-
.transcript .speaker.user { color: #c084fc; }
|
|
35313
|
-
.transcript .speaker.agent { color: #8b5cf6; }
|
|
35314
|
-
#controls { margin-top: 1.5rem; }
|
|
35315
35314
|
button {
|
|
35316
|
-
background:
|
|
35317
|
-
border: 1px solid
|
|
35318
|
-
color: #
|
|
35319
|
-
padding:
|
|
35320
|
-
border-radius:
|
|
35315
|
+
background: #2a2a30;
|
|
35316
|
+
border: 1px solid #3a3a42;
|
|
35317
|
+
color: #b2920a;
|
|
35318
|
+
padding: 6px 16px;
|
|
35319
|
+
border-radius: 3px;
|
|
35321
35320
|
font-family: inherit;
|
|
35322
|
-
font-size: 0.
|
|
35321
|
+
font-size: 0.75rem;
|
|
35323
35322
|
cursor: pointer;
|
|
35324
|
-
transition:
|
|
35325
|
-
letter-spacing: 0.05em;
|
|
35323
|
+
transition: background 0.15s;
|
|
35326
35324
|
}
|
|
35327
|
-
button:hover { background:
|
|
35328
|
-
button.active { background:
|
|
35325
|
+
button:hover { background: #3a3a42; }
|
|
35326
|
+
button.active { background: #3a2a10; border-color: #b2920a; }
|
|
35327
|
+
#footer .hint { font-size: 0.65rem; color: #444; }
|
|
35329
35328
|
</style>
|
|
35330
35329
|
</head>
|
|
35331
35330
|
<body>
|
|
35332
|
-
<div id="
|
|
35333
|
-
<
|
|
35334
|
-
<
|
|
35335
|
-
<span class="disconnected">connecting...</span>
|
|
35331
|
+
<div id="header">
|
|
35332
|
+
<span class="accent">OA</span>
|
|
35333
|
+
<span id="status" class="status">connecting</span>
|
|
35336
35334
|
</div>
|
|
35337
|
-
<div id="
|
|
35338
|
-
<div id="
|
|
35339
|
-
|
|
35335
|
+
<div id="waveform"></div>
|
|
35336
|
+
<div id="conversation"></div>
|
|
35337
|
+
<div id="footer">
|
|
35338
|
+
<button id="micBtn" onclick="toggleMic()">mic</button>
|
|
35339
|
+
<span class="hint" id="hint">tap to start</span>
|
|
35340
35340
|
</div>
|
|
35341
35341
|
|
|
35342
35342
|
<script>
|
|
35343
35343
|
const waveEl = document.getElementById('waveform');
|
|
35344
35344
|
const statusEl = document.getElementById('status');
|
|
35345
|
-
const
|
|
35345
|
+
const convoEl = document.getElementById('conversation');
|
|
35346
35346
|
const micBtn = document.getElementById('micBtn');
|
|
35347
|
+
const hintEl = document.getElementById('hint');
|
|
35347
35348
|
|
|
35348
35349
|
// ---------------------------------------------------------------------------
|
|
35349
35350
|
// Braille waveform \u2014 ported from TUI braille-spinner.ts
|
|
@@ -35354,10 +35355,10 @@ const DENSITY = [
|
|
|
35354
35355
|
];
|
|
35355
35356
|
const WAVE = [...DENSITY, ...DENSITY.slice(1, -1).reverse()]; // 16 entries
|
|
35356
35357
|
|
|
35357
|
-
// Color themes:
|
|
35358
|
-
const THEME_IDLE = ['#
|
|
35359
|
-
const THEME_SPEAKING = ['#
|
|
35360
|
-
const THEME_LISTENING = ['#
|
|
35358
|
+
// Color themes: TUI-aligned dark grey + yellow accent
|
|
35359
|
+
const THEME_IDLE = ['#1e1e22','#2a2a30','#333338','#3e3e44','#4a4a52','#555560','#666670','#777780','#888890'];
|
|
35360
|
+
const THEME_SPEAKING = ['#1e1e22','#2a2510','#3a3518','#4a4520','#5a5528','#6a6530','#8a7a20','#a89010','#b2920a'];
|
|
35361
|
+
const THEME_LISTENING = ['#1e1e22','#2a2818','#3a3820','#4a4828','#5a5830','#6a6838','#8a8830','#a8a020','#b2920a'];
|
|
35361
35362
|
|
|
35362
35363
|
function buildColorRamp(ramp) {
|
|
35363
35364
|
return [...ramp, ...ramp.slice(1, -1).reverse()]; // 16 entries
|
|
@@ -35459,7 +35460,8 @@ function connect() {
|
|
|
35459
35460
|
ws.onopen = () => {
|
|
35460
35461
|
connecting = false;
|
|
35461
35462
|
if (disconnectGrace) { clearTimeout(disconnectGrace); disconnectGrace = null; }
|
|
35462
|
-
statusEl.
|
|
35463
|
+
statusEl.textContent = 'connected';
|
|
35464
|
+
statusEl.className = 'status live';
|
|
35463
35465
|
reconnectDelay = 1000;
|
|
35464
35466
|
};
|
|
35465
35467
|
|
|
@@ -35471,7 +35473,8 @@ function connect() {
|
|
|
35471
35473
|
if (!disconnectGrace) {
|
|
35472
35474
|
disconnectGrace = setTimeout(() => {
|
|
35473
35475
|
disconnectGrace = null;
|
|
35474
|
-
statusEl.
|
|
35476
|
+
statusEl.textContent = 'reconnecting';
|
|
35477
|
+
statusEl.className = 'status';
|
|
35475
35478
|
}, 2000);
|
|
35476
35479
|
}
|
|
35477
35480
|
reconnectTimer = setTimeout(connect, reconnectDelay);
|
|
@@ -35503,11 +35506,10 @@ function connect() {
|
|
|
35503
35506
|
|
|
35504
35507
|
function addTranscript(speaker, text) {
|
|
35505
35508
|
const div = document.createElement('div');
|
|
35506
|
-
div.className = '
|
|
35507
|
-
div.
|
|
35508
|
-
|
|
35509
|
-
|
|
35510
|
-
transcriptsEl.scrollTop = transcriptsEl.scrollHeight;
|
|
35509
|
+
div.className = 'msg ' + speaker;
|
|
35510
|
+
div.textContent = text;
|
|
35511
|
+
convoEl.appendChild(div);
|
|
35512
|
+
convoEl.scrollTop = convoEl.scrollHeight;
|
|
35511
35513
|
}
|
|
35512
35514
|
|
|
35513
35515
|
function escapeHtml(s) {
|
|
@@ -35565,11 +35567,12 @@ async function toggleMic() {
|
|
|
35565
35567
|
scriptProcessor.connect(micCtx.destination);
|
|
35566
35568
|
micActive = true;
|
|
35567
35569
|
waveState = 'listening';
|
|
35568
|
-
micBtn.textContent = 'stop
|
|
35570
|
+
micBtn.textContent = 'stop';
|
|
35569
35571
|
micBtn.classList.add('active');
|
|
35572
|
+
hintEl.textContent = 'listening...';
|
|
35570
35573
|
ws.send(JSON.stringify({ type: 'mic_start', username: 'web-user' }));
|
|
35571
35574
|
} catch (err) {
|
|
35572
|
-
|
|
35575
|
+
hintEl.textContent = 'mic error: ' + err.message;
|
|
35573
35576
|
}
|
|
35574
35577
|
}
|
|
35575
35578
|
|
|
@@ -35579,8 +35582,9 @@ function stopMic() {
|
|
|
35579
35582
|
waveState = 'idle';
|
|
35580
35583
|
if (scriptProcessor) { scriptProcessor.disconnect(); scriptProcessor = null; }
|
|
35581
35584
|
if (micStream) { micStream.getTracks().forEach(t => t.stop()); micStream = null; }
|
|
35582
|
-
micBtn.textContent = '
|
|
35585
|
+
micBtn.textContent = 'mic';
|
|
35583
35586
|
micBtn.classList.remove('active');
|
|
35587
|
+
hintEl.textContent = 'tap to start';
|
|
35584
35588
|
if (ws && ws.readyState === 1) {
|
|
35585
35589
|
ws.send(JSON.stringify({ type: 'mic_stop' }));
|
|
35586
35590
|
}
|
|
@@ -38525,6 +38529,7 @@ var init_call_agent = __esm({
|
|
|
38525
38529
|
tier;
|
|
38526
38530
|
clientId;
|
|
38527
38531
|
runner = null;
|
|
38532
|
+
backend = null;
|
|
38528
38533
|
config;
|
|
38529
38534
|
repoRoot;
|
|
38530
38535
|
opts;
|
|
@@ -38543,6 +38548,7 @@ var init_call_agent = __esm({
|
|
|
38543
38548
|
/** Initialize the runner with appropriate tools for the access tier */
|
|
38544
38549
|
async init() {
|
|
38545
38550
|
const backend = new OllamaAgenticBackend(this.config.backendUrl, this.config.model, this.config.apiKey);
|
|
38551
|
+
this.backend = backend;
|
|
38546
38552
|
const feed = getActivityFeed();
|
|
38547
38553
|
const systemPrompt = this.buildSystemPrompt();
|
|
38548
38554
|
const runnerOpts = {
|
|
@@ -38652,21 +38658,46 @@ var init_call_agent = __esm({
|
|
|
38652
38658
|
const historyContext = this.conversationHistory.slice(-10).map((h) => `${h.role === "user" ? "User" : "You"}: ${h.text}`).join("\n");
|
|
38653
38659
|
const feed = getActivityFeed();
|
|
38654
38660
|
const activitySummary = feed.getSummary(this.tier === "admin" ? 20 : 10, this.tier === "admin");
|
|
38655
|
-
const wantsAction = /\b(read|open|show|run|execute|check|look at|find|search|grep|edit|write|fix|test|build|deploy|install)\b/i.test(text) && !/\b(how are you|what's up|hello|hi|hey|can you hear|stop|quit|bye)\b/i.test(text);
|
|
38656
|
-
|
|
38657
|
-
|
|
38658
|
-
|
|
38659
|
-
|
|
38661
|
+
const wantsAction = /\b(read|open|show|run|execute|check|look at|find|search|grep|edit|write|fix|test|build|deploy|install|create|delete|remove|update|change|modify|commit|push|pull)\b/i.test(text) && !/\b(how are you|what's up|hello|hi|hey|can you hear|stop|quit|bye|thanks|thank you|ok|okay|sure|yeah|yes|no)\b/i.test(text);
|
|
38662
|
+
if (!wantsAction) {
|
|
38663
|
+
try {
|
|
38664
|
+
const chatMessages = [
|
|
38665
|
+
{ role: "system", content: this.buildSystemPrompt() },
|
|
38666
|
+
...this.conversationHistory.slice(-6).map((h) => ({
|
|
38667
|
+
role: h.role === "user" ? "user" : "assistant",
|
|
38668
|
+
content: h.text
|
|
38669
|
+
})),
|
|
38670
|
+
{ role: "user", content: text }
|
|
38671
|
+
];
|
|
38672
|
+
const chatResult = await this.backend.chatCompletion({
|
|
38673
|
+
messages: chatMessages,
|
|
38674
|
+
tools: [],
|
|
38675
|
+
temperature: 0.4,
|
|
38676
|
+
maxTokens: 256,
|
|
38677
|
+
timeoutMs: 15e3
|
|
38678
|
+
});
|
|
38679
|
+
const reply = chatResult.choices[0]?.message?.content ?? "I heard you.";
|
|
38680
|
+
this.conversationHistory.push({ role: "assistant", text: reply });
|
|
38681
|
+
this.emit("response", reply);
|
|
38682
|
+
} catch {
|
|
38683
|
+
this.emit("response", "Sorry, I couldn't process that.");
|
|
38684
|
+
}
|
|
38685
|
+
} else {
|
|
38686
|
+
const taskPrompt = [
|
|
38687
|
+
`User said: "${text}"`,
|
|
38688
|
+
"",
|
|
38689
|
+
historyContext ? `Conversation so far:
|
|
38660
38690
|
${historyContext}
|
|
38661
38691
|
` : "",
|
|
38662
|
-
|
|
38692
|
+
`Background activity:
|
|
38663
38693
|
${activitySummary}
|
|
38664
38694
|
`,
|
|
38665
|
-
|
|
38666
|
-
|
|
38667
|
-
|
|
38668
|
-
|
|
38669
|
-
|
|
38695
|
+
"The user is requesting an action. Use tools as needed, then call task_complete with a brief spoken summary of what you did (1-2 sentences)."
|
|
38696
|
+
].join("\n");
|
|
38697
|
+
const result = await this.runner.run(taskPrompt, `Working directory: ${this.repoRoot}`);
|
|
38698
|
+
if (result.summary) {
|
|
38699
|
+
this.conversationHistory.push({ role: "assistant", text: result.summary });
|
|
38700
|
+
}
|
|
38670
38701
|
}
|
|
38671
38702
|
} catch (err) {
|
|
38672
38703
|
this.emit("error", err instanceof Error ? err : new Error(String(err)));
|
|
@@ -51558,6 +51589,9 @@ async function handleUpdate(subcommand, ctx) {
|
|
|
51558
51589
|
installOverlay.dismiss();
|
|
51559
51590
|
await new Promise((r) => setTimeout(r, 200));
|
|
51560
51591
|
ctx.contextSave?.();
|
|
51592
|
+
if (ctx.hasActiveTask?.())
|
|
51593
|
+
ctx.abortActiveTask?.();
|
|
51594
|
+
ctx.killEphemeral?.();
|
|
51561
51595
|
process.exit(120);
|
|
51562
51596
|
}
|
|
51563
51597
|
async function switchModel(query, ctx, local = false) {
|
|
@@ -66171,6 +66205,24 @@ async function startInteractive(config, repoPath) {
|
|
|
66171
66205
|
await new Promise((r) => setTimeout(r, 50));
|
|
66172
66206
|
process.stdin.pause();
|
|
66173
66207
|
}
|
|
66208
|
+
try {
|
|
66209
|
+
const oaDir = join70(repoRoot, ".oa");
|
|
66210
|
+
const nexusPidFile = join70(oaDir, "nexus", "daemon.pid");
|
|
66211
|
+
if (existsSync53(nexusPidFile)) {
|
|
66212
|
+
const pid = parseInt(readFileSync42(nexusPidFile, "utf8").trim(), 10);
|
|
66213
|
+
if (pid > 0) {
|
|
66214
|
+
try {
|
|
66215
|
+
process.kill(pid, 0);
|
|
66216
|
+
} catch {
|
|
66217
|
+
try {
|
|
66218
|
+
__require("node:fs").unlinkSync(nexusPidFile);
|
|
66219
|
+
} catch {
|
|
66220
|
+
}
|
|
66221
|
+
}
|
|
66222
|
+
}
|
|
66223
|
+
}
|
|
66224
|
+
} catch {
|
|
66225
|
+
}
|
|
66174
66226
|
initOaDirectory(repoRoot);
|
|
66175
66227
|
const savedSettings = resolveSettings(repoRoot);
|
|
66176
66228
|
let restoredSessionContext = null;
|
|
@@ -67363,6 +67415,11 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
67363
67415
|
if (carousel.isRunning)
|
|
67364
67416
|
carousel.stop();
|
|
67365
67417
|
},
|
|
67418
|
+
killEphemeral() {
|
|
67419
|
+
if (_shellToolRef)
|
|
67420
|
+
_shellToolRef.killAll();
|
|
67421
|
+
killAllFullSubAgents();
|
|
67422
|
+
},
|
|
67366
67423
|
async voiceToggle() {
|
|
67367
67424
|
const msg = await voiceEngine.toggle();
|
|
67368
67425
|
if (telegramBridge) {
|
package/package.json
CHANGED