open-agents-ai 0.185.75 → 0.185.77
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 +268 -4
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -65537,7 +65537,10 @@ body {
|
|
|
65537
65537
|
<div id="tabs" style="display:flex;gap:0;background:#1e1e22;border-bottom:1px solid #2a2a30;padding:0 16px;flex-shrink:0">
|
|
65538
65538
|
<button class="tab active" onclick="switchTab('chat')" id="tab-chat" style="background:none;border:none;border-bottom:2px solid #b2920a;color:#b2920a;padding:6px 16px;font-family:inherit;font-size:0.7rem;cursor:pointer">chat</button>
|
|
65539
65539
|
<button class="tab" onclick="switchTab('agent')" id="tab-agent" style="background:none;border:none;border-bottom:2px solid transparent;color:#555;padding:6px 16px;font-family:inherit;font-size:0.7rem;cursor:pointer">agent</button>
|
|
65540
|
-
<button class="tab" onclick="switchTab('jobs')" id="tab-jobs" style="background:none;border:none;border-bottom:2px solid transparent;color:#555;padding:6px 16px;font-family:inherit;font-size:0.7rem;cursor:pointer">
|
|
65540
|
+
<button class="tab" onclick="switchTab('jobs')" id="tab-jobs" style="background:none;border:none;border-bottom:2px solid transparent;color:#555;padding:6px 16px;font-family:inherit;font-size:0.7rem;cursor:pointer">dashboard</button>
|
|
65541
|
+
<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>
|
|
65542
|
+
<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>
|
|
65543
|
+
<span id="token-counter" style="margin-left:auto;font-size:0.6rem;color:#555">0 tokens</span>
|
|
65541
65544
|
</div>
|
|
65542
65545
|
<div id="conversation"></div>
|
|
65543
65546
|
<div id="agent-panel" style="display:none;flex:1;overflow-y:auto;padding:12px 16px">
|
|
@@ -65551,10 +65554,33 @@ body {
|
|
|
65551
65554
|
</div>
|
|
65552
65555
|
<div id="jobs-panel" style="display:none;flex:1;overflow-y:auto;padding:12px 16px">
|
|
65553
65556
|
<div id="dashboard-health" style="display:flex;gap:12px;margin-bottom:16px;flex-wrap:wrap"></div>
|
|
65557
|
+
<div id="dashboard-daemons" style="margin-bottom:16px"></div>
|
|
65554
65558
|
<div id="dashboard-usage" style="margin-bottom:16px"></div>
|
|
65555
65559
|
<h3 style="color:#b2920a;font-size:0.7rem;margin-bottom:8px">Job History</h3>
|
|
65556
65560
|
<div id="jobs-list" style="font-size:0.78rem"></div>
|
|
65557
65561
|
</div>
|
|
65562
|
+
<div id="config-panel" style="display:none;flex:1;overflow-y:auto;padding:12px 16px">
|
|
65563
|
+
<h3 style="color:#b2920a;font-size:0.7rem;margin-bottom:12px">Server Configuration</h3>
|
|
65564
|
+
<div id="config-content" style="font-size:0.78rem"></div>
|
|
65565
|
+
<h3 style="color:#b2920a;font-size:0.7rem;margin:16px 0 8px">Model</h3>
|
|
65566
|
+
<div style="display:flex;gap:8px;align-items:center">
|
|
65567
|
+
<select id="config-model-select" style="background:#2a2a30;border:1px solid #3a3a42;color:#b0b0b0;padding:4px 8px;border-radius:3px;font-family:inherit;font-size:0.7rem;flex:1"></select>
|
|
65568
|
+
<button onclick="switchModel()" style="background:#2a2a30;border:1px solid #3a3a42;color:#b2920a;padding:4px 12px;border-radius:3px;font-family:inherit;font-size:0.7rem;cursor:pointer">switch</button>
|
|
65569
|
+
</div>
|
|
65570
|
+
<h3 style="color:#b2920a;font-size:0.7rem;margin:16px 0 8px">Endpoint</h3>
|
|
65571
|
+
<div id="config-endpoint" style="font-size:0.78rem;color:#888"></div>
|
|
65572
|
+
<h3 style="color:#b2920a;font-size:0.7rem;margin:16px 0 8px">Profiles</h3>
|
|
65573
|
+
<div id="config-profiles" style="font-size:0.78rem"></div>
|
|
65574
|
+
<h3 style="color:#b2920a;font-size:0.7rem;margin:16px 0 8px">Export Conversation</h3>
|
|
65575
|
+
<div style="display:flex;gap:8px">
|
|
65576
|
+
<button onclick="exportChat('md')" style="background:#2a2a30;border:1px solid #3a3a42;color:#b2920a;padding:4px 12px;border-radius:3px;font-family:inherit;font-size:0.7rem;cursor:pointer">markdown</button>
|
|
65577
|
+
<button onclick="exportChat('json')" style="background:#2a2a30;border:1px solid #3a3a42;color:#b2920a;padding:4px 12px;border-radius:3px;font-family:inherit;font-size:0.7rem;cursor:pointer">JSON</button>
|
|
65578
|
+
</div>
|
|
65579
|
+
</div>
|
|
65580
|
+
<div id="activity-panel" style="display:none;flex:1;overflow-y:auto;padding:12px 16px">
|
|
65581
|
+
<h3 style="color:#b2920a;font-size:0.7rem;margin-bottom:12px">Recent Activity (Audit Log)</h3>
|
|
65582
|
+
<div id="activity-feed" style="font-size:0.72rem"></div>
|
|
65583
|
+
</div>
|
|
65558
65584
|
|
|
65559
65585
|
<div id="footer">
|
|
65560
65586
|
<span id="system-prompt-toggle" onclick="toggleSystemPrompt()">sys</span>
|
|
@@ -65733,6 +65759,7 @@ async function sendMessage() {
|
|
|
65733
65759
|
}
|
|
65734
65760
|
|
|
65735
65761
|
messages.push({ role: 'assistant', content: fullContent });
|
|
65762
|
+
updateTokenCounter(fullContent.split(/\\s+/).length * 1.3 | 0); // rough token estimate
|
|
65736
65763
|
// Re-render with copy button
|
|
65737
65764
|
msgDiv.innerHTML = renderMarkdown(fullContent);
|
|
65738
65765
|
const actions = document.createElement('div');
|
|
@@ -65780,16 +65807,135 @@ function closeKeyModal() {
|
|
|
65780
65807
|
}
|
|
65781
65808
|
|
|
65782
65809
|
// Tab switching
|
|
65810
|
+
const allPanels = ['conversation','agent-panel','jobs-panel','config-panel','activity-panel'];
|
|
65783
65811
|
function switchTab(tab) {
|
|
65784
|
-
|
|
65785
|
-
document.getElementById(
|
|
65786
|
-
document.getElementById(
|
|
65812
|
+
const panelMap = {chat:'conversation',agent:'agent-panel',jobs:'jobs-panel',config:'config-panel',activity:'activity-panel'};
|
|
65813
|
+
allPanels.forEach(id => { const el = document.getElementById(id); if(el) el.style.display = 'none'; });
|
|
65814
|
+
const panel = document.getElementById(panelMap[tab]);
|
|
65815
|
+
if (panel) panel.style.display = tab === 'chat' ? 'flex' : 'block';
|
|
65787
65816
|
document.getElementById('footer').style.display = tab === 'chat' ? 'flex' : 'none';
|
|
65788
65817
|
document.querySelectorAll('.tab').forEach(t => { t.style.borderBottomColor = 'transparent'; t.style.color = '#555'; });
|
|
65789
65818
|
const active = document.getElementById('tab-' + tab);
|
|
65790
65819
|
if (active) { active.style.borderBottomColor = '#b2920a'; active.style.color = '#b2920a'; }
|
|
65791
65820
|
if (tab === 'jobs') loadJobs();
|
|
65792
65821
|
if (tab === 'agent') loadProfiles();
|
|
65822
|
+
if (tab === 'config') loadConfig();
|
|
65823
|
+
if (tab === 'activity') loadActivity();
|
|
65824
|
+
}
|
|
65825
|
+
|
|
65826
|
+
// Token counter
|
|
65827
|
+
let totalTokens = 0;
|
|
65828
|
+
function updateTokenCounter(n) { totalTokens += n; document.getElementById('token-counter').textContent = totalTokens.toLocaleString() + ' tokens'; }
|
|
65829
|
+
|
|
65830
|
+
// Config panel
|
|
65831
|
+
async function loadConfig() {
|
|
65832
|
+
try {
|
|
65833
|
+
const [cfg, ep, models] = await Promise.all([
|
|
65834
|
+
fetch('/v1/config', { headers: headers() }).then(r => r.json()),
|
|
65835
|
+
fetch('/v1/config/endpoint', { headers: headers() }).then(r => r.json()),
|
|
65836
|
+
fetch('/v1/models', { headers: headers() }).then(r => r.json()),
|
|
65837
|
+
]);
|
|
65838
|
+
const c = cfg.config || {};
|
|
65839
|
+
document.getElementById('config-content').innerHTML =
|
|
65840
|
+
'<table style="width:100%">' +
|
|
65841
|
+
Object.entries(c).map(([k,v]) =>
|
|
65842
|
+
'<tr style="border-bottom:1px solid #2a2a30"><td style="padding:4px;color:#888">' + k + '</td>' +
|
|
65843
|
+
'<td style="padding:4px;color:#b0b0b0">' + (v === '[redacted]' ? '<span style="color:#555">[redacted]</span>' : String(v)) + '</td></tr>'
|
|
65844
|
+
).join('') + '</table>';
|
|
65845
|
+
document.getElementById('config-endpoint').textContent = ep.url + ' (' + (ep.backendType || 'unknown') + ')';
|
|
65846
|
+
// Populate model switcher
|
|
65847
|
+
const sel = document.getElementById('config-model-select');
|
|
65848
|
+
sel.innerHTML = '';
|
|
65849
|
+
for (const m of (models.data || [])) {
|
|
65850
|
+
const opt = document.createElement('option');
|
|
65851
|
+
opt.value = m.id.replace(/^local\\//, '');
|
|
65852
|
+
opt.textContent = m.id.replace(/^local\\//, '');
|
|
65853
|
+
if (opt.value === c.model) opt.selected = true;
|
|
65854
|
+
sel.appendChild(opt);
|
|
65855
|
+
}
|
|
65856
|
+
} catch {}
|
|
65857
|
+
// Profiles
|
|
65858
|
+
try {
|
|
65859
|
+
const r = await fetch('/v1/profiles', { headers: headers() });
|
|
65860
|
+
const d = await r.json();
|
|
65861
|
+
document.getElementById('config-profiles').innerHTML = (d.profiles || []).map(p =>
|
|
65862
|
+
'<div style="background:#1e1e22;border:1px solid #2a2a30;border-radius:3px;padding:6px 10px;margin:4px 0">' +
|
|
65863
|
+
'<span style="color:#b2920a">' + p.name + '</span>' +
|
|
65864
|
+
(p.encrypted ? ' <span style="color:#555;font-size:0.6rem">(encrypted)</span>' : '') +
|
|
65865
|
+
' <span style="color:#555;font-size:0.6rem">' + (p.source || '') + '</span></div>'
|
|
65866
|
+
).join('') || '<span style="color:#555">No profiles</span>';
|
|
65867
|
+
} catch {}
|
|
65868
|
+
}
|
|
65869
|
+
|
|
65870
|
+
async function switchModel() {
|
|
65871
|
+
const model = document.getElementById('config-model-select').value;
|
|
65872
|
+
if (!model) return;
|
|
65873
|
+
try {
|
|
65874
|
+
await fetch('/v1/config/model', {
|
|
65875
|
+
method: 'PUT', headers: headers(),
|
|
65876
|
+
body: JSON.stringify({ model }),
|
|
65877
|
+
});
|
|
65878
|
+
loadConfig();
|
|
65879
|
+
modelSelect.value = model; // sync chat model picker
|
|
65880
|
+
} catch {}
|
|
65881
|
+
}
|
|
65882
|
+
|
|
65883
|
+
// Export conversation
|
|
65884
|
+
function exportChat(fmt) {
|
|
65885
|
+
let content;
|
|
65886
|
+
if (fmt === 'json') {
|
|
65887
|
+
content = JSON.stringify(messages, null, 2);
|
|
65888
|
+
} else {
|
|
65889
|
+
content = messages.map(m => (m.role === 'user' ? '**You:** ' : '**Agent:** ') + m.content).join('\\n\\n');
|
|
65890
|
+
}
|
|
65891
|
+
const blob = new Blob([content], { type: fmt === 'json' ? 'application/json' : 'text/markdown' });
|
|
65892
|
+
const a = document.createElement('a');
|
|
65893
|
+
a.href = URL.createObjectURL(blob);
|
|
65894
|
+
a.download = 'conversation.' + (fmt === 'json' ? 'json' : 'md');
|
|
65895
|
+
a.click();
|
|
65896
|
+
}
|
|
65897
|
+
|
|
65898
|
+
// Activity feed (audit log)
|
|
65899
|
+
async function loadActivity() {
|
|
65900
|
+
try {
|
|
65901
|
+
const r = await fetch('/v1/audit?limit=50', { headers: headers() });
|
|
65902
|
+
const d = await r.json();
|
|
65903
|
+
const feed = document.getElementById('activity-feed');
|
|
65904
|
+
if (!d.records?.length) { feed.innerHTML = '<span style="color:#555">No activity yet</span>'; return; }
|
|
65905
|
+
feed.innerHTML = d.records.map(r => {
|
|
65906
|
+
const time = r.ts?.split('T')[1]?.slice(0,8) || '';
|
|
65907
|
+
const color = r.status >= 400 ? '#ff4444' : r.status >= 300 ? '#b2920a' : '#4ec94e';
|
|
65908
|
+
return '<div style="padding:3px 0;border-bottom:1px solid #1e1e22">' +
|
|
65909
|
+
'<span style="color:#555">' + time + '</span> ' +
|
|
65910
|
+
'<span style="color:' + color + '">' + r.status + '</span> ' +
|
|
65911
|
+
'<span style="color:#888">' + r.method + '</span> ' +
|
|
65912
|
+
'<span style="color:#b0b0b0">' + r.path + '</span> ' +
|
|
65913
|
+
'<span style="color:#555">' + r.latencyMs + 'ms</span> ' +
|
|
65914
|
+
'<span style="color:#555;font-size:0.6rem">' + (r.user || '') + '</span></div>';
|
|
65915
|
+
}).join('');
|
|
65916
|
+
} catch {}
|
|
65917
|
+
}
|
|
65918
|
+
|
|
65919
|
+
// Daemon monitor (on dashboard tab)
|
|
65920
|
+
async function loadDaemons() {
|
|
65921
|
+
// The daemon registry is server-side (TUI). We can't query it via REST yet.
|
|
65922
|
+
// Show running jobs as a proxy for active processes.
|
|
65923
|
+
try {
|
|
65924
|
+
const r = await fetch('/v1/runs?status=running', { headers: headers() });
|
|
65925
|
+
const d = await r.json();
|
|
65926
|
+
const el = document.getElementById('dashboard-daemons');
|
|
65927
|
+
if (!d.runs?.length) {
|
|
65928
|
+
el.innerHTML = '<div style="background:#1e1e22;border:1px solid #2a2a30;border-radius:3px;padding:8px 12px;color:#555;font-size:0.7rem">No active processes</div>';
|
|
65929
|
+
return;
|
|
65930
|
+
}
|
|
65931
|
+
el.innerHTML = '<h3 style="color:#b2920a;font-size:0.7rem;margin-bottom:8px">Active Processes</h3>' +
|
|
65932
|
+
d.runs.map(j =>
|
|
65933
|
+
'<div style="background:#1e1e22;border-left:2px solid #b2920a;padding:6px 10px;margin:4px 0;font-size:0.72rem">' +
|
|
65934
|
+
'<span style="color:#b2920a">' + (j.id||'').slice(0,12) + '</span> ' +
|
|
65935
|
+
'<span style="color:#4ec94e">running</span> ' +
|
|
65936
|
+
'<span style="color:#888">' + (j.task||'').slice(0,50) + '</span></div>'
|
|
65937
|
+
).join('');
|
|
65938
|
+
} catch {}
|
|
65793
65939
|
}
|
|
65794
65940
|
|
|
65795
65941
|
// Agent task
|
|
@@ -65910,6 +66056,7 @@ async function loadDashboard() {
|
|
|
65910
66056
|
|
|
65911
66057
|
async function loadJobs() {
|
|
65912
66058
|
loadDashboard();
|
|
66059
|
+
loadDaemons();
|
|
65913
66060
|
const list = document.getElementById('jobs-list');
|
|
65914
66061
|
try {
|
|
65915
66062
|
const r = await fetch('/v1/runs', { headers: headers() });
|
|
@@ -65977,6 +66124,98 @@ var init_logger = __esm({
|
|
|
65977
66124
|
}
|
|
65978
66125
|
});
|
|
65979
66126
|
|
|
66127
|
+
// packages/cli/dist/api/openapi.js
|
|
66128
|
+
function getOpenApiSpec() {
|
|
66129
|
+
return {
|
|
66130
|
+
openapi: "3.0.3",
|
|
66131
|
+
info: {
|
|
66132
|
+
title: "Open Agents REST API",
|
|
66133
|
+
description: "AI coding agent powered by open-weight models. Enterprise REST API for agentic task execution, OpenAI-compatible inference, and system management.",
|
|
66134
|
+
version: "0.185.75",
|
|
66135
|
+
license: { name: "CC-BY-NC-4.0", url: "https://creativecommons.org/licenses/by-nc/4.0/" }
|
|
66136
|
+
},
|
|
66137
|
+
servers: [{ url: "http://localhost:11435", description: "Local development" }],
|
|
66138
|
+
security: [{ BearerAuth: [] }],
|
|
66139
|
+
components: {
|
|
66140
|
+
securitySchemes: {
|
|
66141
|
+
BearerAuth: { type: "http", scheme: "bearer", description: "API key with scope (read/run/admin)" }
|
|
66142
|
+
}
|
|
66143
|
+
},
|
|
66144
|
+
paths: {
|
|
66145
|
+
"/health": { get: { summary: "Liveness probe", tags: ["Health"], security: [], responses: { 200: { description: "Server is alive" } } } },
|
|
66146
|
+
"/health/ready": { get: { summary: "Readiness probe (checks backend)", tags: ["Health"], security: [], responses: { 200: { description: "Backend reachable" }, 503: { description: "Backend unreachable" } } } },
|
|
66147
|
+
"/health/startup": { get: { summary: "Startup complete", tags: ["Health"], security: [], responses: { 200: { description: "Started" } } } },
|
|
66148
|
+
"/version": { get: { summary: "Version info", tags: ["Health"], security: [], responses: { 200: { description: "Version, node, platform" } } } },
|
|
66149
|
+
"/metrics": { get: { summary: "Prometheus metrics", tags: ["Health"], security: [], responses: { 200: { description: "Prometheus text format" } } } },
|
|
66150
|
+
"/v1/models": { get: { summary: "List available models", tags: ["Inference"], security: [{ BearerAuth: [] }], responses: { 200: { description: "OpenAI-format model list" } } } },
|
|
66151
|
+
"/v1/chat/completions": { post: { summary: "Chat completion (OpenAI-compatible)", tags: ["Inference"], security: [{ BearerAuth: [] }], requestBody: { required: true, content: { "application/json": { schema: { type: "object", required: ["model", "messages"], properties: { model: { type: "string" }, messages: { type: "array" }, stream: { type: "boolean" }, max_tokens: { type: "integer" }, temperature: { type: "number" } } } } } }, responses: { 200: { description: "Chat response" } } } },
|
|
66152
|
+
"/v1/embeddings": { post: { summary: "Generate embeddings", tags: ["Inference"], responses: { 200: { description: "Embedding vectors" } } } },
|
|
66153
|
+
"/v1/run": { post: { summary: "Submit agentic task", tags: ["Agentic"], requestBody: { required: true, content: { "application/json": { schema: { type: "object", required: ["task"], properties: { task: { type: "string" }, model: { type: "string" }, stream: { type: "boolean" }, profile: { type: "string" }, working_directory: { type: "string" }, isolate: { type: "boolean" } } } } } }, responses: { 202: { description: "Task accepted" } } } },
|
|
66154
|
+
"/v1/runs": { get: { summary: "List all runs", tags: ["Agentic"], parameters: [{ name: "limit", in: "query", schema: { type: "integer" } }, { name: "offset", in: "query", schema: { type: "integer" } }, { name: "status", in: "query", schema: { type: "string" } }], responses: { 200: { description: "Run list with pagination" } } } },
|
|
66155
|
+
"/v1/runs/{id}": { get: { summary: "Get run status", tags: ["Agentic"], parameters: [{ name: "id", in: "path", required: true, schema: { type: "string" } }], responses: { 200: { description: "Run details" }, 404: { description: "Not found" } } }, delete: { summary: "Abort run", tags: ["Agentic"], responses: { 200: { description: "Aborted" } } } },
|
|
66156
|
+
"/v1/config": { get: { summary: "Get configuration", tags: ["Config"], responses: { 200: { description: "Current config" } } }, patch: { summary: "Update configuration", tags: ["Config"], responses: { 200: { description: "Updated" } } } },
|
|
66157
|
+
"/v1/config/model": { get: { summary: "Current model", tags: ["Config"], responses: { 200: { description: "Model name" } } }, put: { summary: "Switch model", tags: ["Config"], responses: { 200: { description: "Switched" } } } },
|
|
66158
|
+
"/v1/config/endpoint": { get: { summary: "Current endpoint", tags: ["Config"], responses: { 200: { description: "Endpoint URL" } } }, put: { summary: "Switch endpoint", tags: ["Config"], responses: { 200: { description: "Switched" } } } },
|
|
66159
|
+
"/v1/usage": { get: { summary: "Token usage and rate limits", tags: ["Metering"], responses: { 200: { description: "Usage stats" } } } },
|
|
66160
|
+
"/v1/audit": { get: { summary: "Query audit log", tags: ["Audit"], parameters: [{ name: "since", in: "query", schema: { type: "string" } }, { name: "user", in: "query", schema: { type: "string" } }, { name: "limit", in: "query", schema: { type: "integer" } }], responses: { 200: { description: "Audit records" } } } },
|
|
66161
|
+
"/v1/commands": { get: { summary: "List slash commands", tags: ["Commands"], responses: { 200: { description: "Command list" } } } },
|
|
66162
|
+
"/v1/commands/{cmd}": { post: { summary: "Execute slash command", tags: ["Commands"], responses: { 200: { description: "Command output" } } } },
|
|
66163
|
+
"/v1/profiles": { get: { summary: "List tool profiles", tags: ["Profiles"], responses: { 200: { description: "Profile list" } } }, post: { summary: "Create profile", tags: ["Profiles"], responses: { 201: { description: "Created" } } } },
|
|
66164
|
+
"/v1/profiles/{name}": { get: { summary: "Get profile", tags: ["Profiles"], responses: { 200: { description: "Profile details" } } }, delete: { summary: "Delete profile", tags: ["Profiles"], responses: { 200: { description: "Deleted" } } } }
|
|
66165
|
+
}
|
|
66166
|
+
};
|
|
66167
|
+
}
|
|
66168
|
+
function getSwaggerUI() {
|
|
66169
|
+
return `<!DOCTYPE html><html><head><title>OA API Docs</title>
|
|
66170
|
+
<style>body{font-family:'SF Mono',monospace;background:#1a1a1e;color:#b0b0b0;margin:0;padding:20px}
|
|
66171
|
+
h1{color:#b2920a;font-size:1.2rem}h2{color:#b2920a;font-size:0.9rem;margin-top:20px}
|
|
66172
|
+
.endpoint{background:#1e1e22;border:1px solid #2a2a30;border-radius:3px;padding:10px;margin:8px 0}
|
|
66173
|
+
.method{font-weight:bold;padding:2px 8px;border-radius:2px;font-size:0.75rem}
|
|
66174
|
+
.get{color:#4ec94e}.post{color:#b2920a}.put{color:#4e94c9}.patch{color:#c9944e}.delete{color:#c94e4e}
|
|
66175
|
+
.path{color:#b0b0b0;margin-left:8px}.summary{color:#888;font-size:0.75rem;margin-left:12px}
|
|
66176
|
+
.tag{margin-top:16px;border-bottom:1px solid #2a2a30;padding-bottom:4px}
|
|
66177
|
+
a{color:#b2920a}
|
|
66178
|
+
</style></head><body>
|
|
66179
|
+
<h1>Open Agents API</h1>
|
|
66180
|
+
<p>Interactive docs. For full spec: <a href="/openapi.json">/openapi.json</a></p>
|
|
66181
|
+
<div id="docs"></div>
|
|
66182
|
+
<script>
|
|
66183
|
+
fetch('/openapi.json').then(r=>r.json()).then(spec=>{
|
|
66184
|
+
const docs=document.getElementById('docs');
|
|
66185
|
+
const tags={};
|
|
66186
|
+
for(const[path,methods]of Object.entries(spec.paths)){
|
|
66187
|
+
for(const[method,op]of Object.entries(methods)){
|
|
66188
|
+
const tag=(op.tags||['Other'])[0];
|
|
66189
|
+
if(!tags[tag])tags[tag]=[];
|
|
66190
|
+
tags[tag].push({method,path,summary:op.summary||''});
|
|
66191
|
+
}
|
|
66192
|
+
}
|
|
66193
|
+
for(const[tag,endpoints]of Object.entries(tags)){
|
|
66194
|
+
docs.innerHTML+='<div class="tag"><h2>'+tag+'</h2></div>';
|
|
66195
|
+
for(const ep of endpoints){
|
|
66196
|
+
docs.innerHTML+='<div class="endpoint"><span class="method '+ep.method+'">'+ep.method.toUpperCase()+'</span><span class="path">'+ep.path+'</span><span class="summary">'+ep.summary+'</span></div>';
|
|
66197
|
+
}
|
|
66198
|
+
}
|
|
66199
|
+
});
|
|
66200
|
+
</script></body></html>`;
|
|
66201
|
+
}
|
|
66202
|
+
var init_openapi = __esm({
|
|
66203
|
+
"packages/cli/dist/api/openapi.js"() {
|
|
66204
|
+
"use strict";
|
|
66205
|
+
}
|
|
66206
|
+
});
|
|
66207
|
+
|
|
66208
|
+
// packages/cli/dist/api/auth-oidc.js
|
|
66209
|
+
var OIDC_ISSUER, OIDC_AUDIENCE, OIDC_SCOPE_CLAIM;
|
|
66210
|
+
var init_auth_oidc = __esm({
|
|
66211
|
+
"packages/cli/dist/api/auth-oidc.js"() {
|
|
66212
|
+
"use strict";
|
|
66213
|
+
OIDC_ISSUER = process.env["OA_OIDC_ISSUER"] || "";
|
|
66214
|
+
OIDC_AUDIENCE = process.env["OA_OIDC_AUDIENCE"] || "";
|
|
66215
|
+
OIDC_SCOPE_CLAIM = process.env["OA_OIDC_SCOPE_CLAIM"] || "scope";
|
|
66216
|
+
}
|
|
66217
|
+
});
|
|
66218
|
+
|
|
65980
66219
|
// packages/cli/dist/api/profiles.js
|
|
65981
66220
|
import { existsSync as existsSync53, readFileSync as readFileSync42, writeFileSync as writeFileSync25, mkdirSync as mkdirSync27, readdirSync as readdirSync20, unlinkSync as unlinkSync12 } from "node:fs";
|
|
65982
66221
|
import { join as join70 } from "node:path";
|
|
@@ -66912,6 +67151,20 @@ async function handleV1Run(req, res) {
|
|
|
66912
67151
|
jsonResponse(res, 400, { error: "Missing required field: task" });
|
|
66913
67152
|
return;
|
|
66914
67153
|
}
|
|
67154
|
+
if (task.length > 5e4) {
|
|
67155
|
+
jsonResponse(res, 400, { error: "Task too long", message: "Max 50,000 characters", length: task.length });
|
|
67156
|
+
return;
|
|
67157
|
+
}
|
|
67158
|
+
const sandbox = requestBody["sandbox"] || process.env["OA_DEFAULT_SANDBOX"] || "none";
|
|
67159
|
+
if (sandbox === "container") {
|
|
67160
|
+
try {
|
|
67161
|
+
const { execSync: es } = __require("node:child_process");
|
|
67162
|
+
es("docker --version", { stdio: "pipe", timeout: 5e3 });
|
|
67163
|
+
} catch {
|
|
67164
|
+
jsonResponse(res, 400, { error: "Container sandbox unavailable", message: "Docker not found. Install Docker or use sandbox:'none'." });
|
|
67165
|
+
return;
|
|
67166
|
+
}
|
|
67167
|
+
}
|
|
66915
67168
|
const id = `job-${randomBytes16(3).toString("hex")}`;
|
|
66916
67169
|
const dir = jobsDir();
|
|
66917
67170
|
const workingDir = requestBody["working_directory"] || req.headers["x-working-directory"];
|
|
@@ -67278,6 +67531,15 @@ async function handleRequest(req, res, ollamaUrl, verbose) {
|
|
|
67278
67531
|
handleMetrics(res);
|
|
67279
67532
|
return;
|
|
67280
67533
|
}
|
|
67534
|
+
if (pathname === "/openapi.json" && method === "GET") {
|
|
67535
|
+
jsonResponse(res, 200, getOpenApiSpec());
|
|
67536
|
+
return;
|
|
67537
|
+
}
|
|
67538
|
+
if (pathname === "/docs" && method === "GET") {
|
|
67539
|
+
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
67540
|
+
res.end(getSwaggerUI());
|
|
67541
|
+
return;
|
|
67542
|
+
}
|
|
67281
67543
|
if (pathname === "/" && method === "GET" && req.headers.accept?.includes("text/html")) {
|
|
67282
67544
|
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
67283
67545
|
res.end(getWebUI());
|
|
@@ -67707,6 +67969,8 @@ var init_serve = __esm({
|
|
|
67707
67969
|
init_audit_log();
|
|
67708
67970
|
init_web_ui();
|
|
67709
67971
|
init_logger();
|
|
67972
|
+
init_openapi();
|
|
67973
|
+
init_auth_oidc();
|
|
67710
67974
|
init_oa_directory();
|
|
67711
67975
|
init_render();
|
|
67712
67976
|
init_profiles();
|
package/package.json
CHANGED