Skip to content

Commit 3b42287

Browse files
Merge pull request #571 from future-agi/feature/api-docs-sim-2
Feature/api docs sim - Persona, Prompt Simulaton, Call Executions, test Executions and Run tests
2 parents 0ddc265 + decd848 commit 3b42287

50 files changed

Lines changed: 3474 additions & 146 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/components/FastNav.astro

Lines changed: 30 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -118,29 +118,6 @@
118118
oldToc.innerHTML = newToc.innerHTML;
119119
}
120120

121-
// Swap API right panel (for API pages with two-column layout)
122-
var newRight = doc.getElementById('api-right-panel');
123-
var oldRight = document.getElementById('api-right-panel');
124-
if (newRight && oldRight) {
125-
oldRight.innerHTML = newRight.innerHTML;
126-
}
127-
// Also move any new .apg-right-panel into the aside
128-
var newApgRight = document.querySelector('article .apg-right-panel');
129-
if (newApgRight && oldRight) {
130-
oldRight.innerHTML = '';
131-
oldRight.appendChild(newApgRight);
132-
newApgRight.style.display = 'block';
133-
}
134-
135-
// Re-run inline scripts from the new content (ApiPlayground JS)
136-
var newScripts = doc.querySelectorAll('article script, .apg-right-panel script');
137-
newScripts.forEach(function(oldScript) {
138-
var newScript = document.createElement('script');
139-
newScript.textContent = oldScript.textContent;
140-
document.body.appendChild(newScript);
141-
document.body.removeChild(newScript);
142-
});
143-
144121
// Update document title
145122
var newTitle = doc.querySelector('title');
146123
if (newTitle) document.title = newTitle.textContent;
@@ -152,6 +129,31 @@
152129
oldSidebar.innerHTML = newSidebar.innerHTML;
153130
}
154131

132+
// Re-execute inline scripts in swapped article
133+
// (innerHTML doesn't execute <script> tags — clone them so the browser runs them)
134+
// This populates ApiPlayground code displays, sets up event listeners, etc.
135+
if (oldArticle) {
136+
oldArticle.querySelectorAll('script').forEach(function(dead) {
137+
var live = document.createElement('script');
138+
Array.from(dead.attributes).forEach(function(a) {
139+
live.setAttribute(a.name, a.value);
140+
});
141+
live.textContent = dead.textContent;
142+
dead.parentNode.replaceChild(live, dead);
143+
});
144+
}
145+
146+
// Move ApiPlayground's .apg-right-panel into the aside (AFTER scripts have populated it)
147+
var rightPanel = document.getElementById('api-right-panel');
148+
if (rightPanel) {
149+
rightPanel.innerHTML = '';
150+
var newPanel = document.querySelector('.apg-right-panel');
151+
if (newPanel) {
152+
rightPanel.appendChild(newPanel);
153+
newPanel.style.display = 'block';
154+
}
155+
}
156+
155157
// Scroll content to top
156158
var main = document.querySelector('main');
157159
if (main) main.scrollTop = 0;
@@ -195,8 +197,11 @@
195197
}
196198
});
197199

198-
// Cache current page
199-
pageCache[window.location.pathname] = document.documentElement.outerHTML;
200+
// Cache current page from server (not live DOM which has JS mutations)
201+
fetch(window.location.pathname)
202+
.then(function(r) { return r.text(); })
203+
.then(function(html) { pageCache[window.location.pathname] = html; })
204+
.catch(function() {});
200205

201206
// Prefetch visible sidebar links into cache
202207
function prefetchVisible() {
@@ -221,7 +226,6 @@
221226

222227
// Re-init on Astro view transitions (fallback)
223228
document.addEventListener('astro:page-load', function() {
224-
pageCache[window.location.pathname] = document.documentElement.outerHTML;
225229
initFastNav();
226230
setTimeout(prefetchVisible, 500);
227231
});

src/components/Sidebar.astro

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -402,38 +402,38 @@ function inferApiMethod(title: string): { method: string; css: string } | null {
402402
}
403403
}
404404

405-
var SCROLL_KEY = 'sidebar-scroll';
406-
407-
function saveScroll() {
405+
function scrollToActiveItem() {
408406
var nav = document.querySelector('#sidebar nav');
409-
if (nav) sessionStorage.setItem(SCROLL_KEY, nav.scrollTop);
410-
}
411-
412-
function restoreScroll() {
413-
var saved = sessionStorage.getItem(SCROLL_KEY);
414-
if (saved !== null) {
415-
var nav = document.querySelector('#sidebar nav');
416-
if (nav) nav.scrollTop = parseInt(saved, 10);
407+
if (!nav) return;
408+
// Find the active link — it has font-medium + bg-hover styling applied server-side
409+
var active = nav.querySelector('a.font-medium');
410+
if (!active) return;
411+
// Calculate position relative to the nav scroll container
412+
var navRect = nav.getBoundingClientRect();
413+
var activeRect = active.getBoundingClientRect();
414+
// Only scroll if the active item is outside the visible area
415+
if (activeRect.top < navRect.top || activeRect.bottom > navRect.bottom) {
416+
var offset = active.offsetTop - nav.offsetTop - navRect.height / 3;
417+
nav.scrollTop = Math.max(0, offset);
417418
}
418419
}
419420

420421
setupSidebar();
421-
restoreScroll();
422+
scrollToActiveItem();
422423

423424
// Register global listeners only once (script re-executes on view transitions)
424425
if (!window.__sidebarListenersReady) {
425426
window.__sidebarListenersReady = true;
426427

427-
document.addEventListener('astro:before-swap', saveScroll);
428-
429428
document.addEventListener('astro:page-load', function() {
430429
setupSidebar();
431-
restoreScroll();
430+
scrollToActiveItem();
432431
});
433432

434433
// Re-init after FastNav swaps sidebar innerHTML
435434
window.addEventListener('fastnav', function() {
436435
setupSidebar();
436+
scrollToActiveItem();
437437
});
438438
}
439439

src/components/docs/ApiCollapsible.astro

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -28,29 +28,31 @@ const cid = `apic-${Math.random().toString(36).slice(2, 8)}`;
2828
</div>
2929
</div>
3030

31-
<script is:inline define:vars={{ cid, title }}>
32-
(function(){
33-
var el = document.getElementById(cid);
34-
if (!el || el._apicBound) return;
35-
el._apicBound = true;
31+
<script is:inline>
32+
function initApiCollapsibles() {
33+
document.querySelectorAll('.api-collapsible').forEach(function(el) {
34+
if (el._apicBound) return;
35+
el._apicBound = true;
3636

37-
var trigger = el.querySelector('[data-apic-trigger]');
38-
var content = el.querySelector('[data-apic-content]');
39-
var icon = el.querySelector('[data-apic-icon]');
40-
var label = el.querySelector('[data-apic-label]');
41-
var isOpen = false;
37+
var trigger = el.querySelector('[data-apic-trigger]');
38+
var icon = el.querySelector('[data-apic-icon]');
39+
var label = el.querySelector('[data-apic-label]');
40+
var isOpen = false;
41+
var showTitle = label ? label.textContent : 'Show properties';
42+
var hideTitle = showTitle.replace(/^Show\b/, 'Hide');
4243

43-
var openTitle = title.replace(/^Show\b/, 'Hide');
44-
45-
if (trigger) {
46-
trigger.addEventListener('click', function() {
47-
isOpen = !isOpen;
48-
el.classList.toggle('api-collapsible-open', isOpen);
49-
if (icon) icon.textContent = isOpen ? '\u00d7' : '+';
50-
if (label) label.textContent = isOpen ? openTitle : title;
51-
});
52-
}
53-
})();
44+
if (trigger) {
45+
trigger.addEventListener('click', function() {
46+
isOpen = !isOpen;
47+
el.classList.toggle('api-collapsible-open', isOpen);
48+
if (icon) icon.textContent = isOpen ? '\u00d7' : '+';
49+
if (label) label.textContent = isOpen ? hideTitle : showTitle;
50+
});
51+
}
52+
});
53+
}
54+
initApiCollapsibles();
55+
document.addEventListener('astro:page-load', initApiCollapsibles);
5456
</script>
5557

5658
<style is:global>

src/lib/api-navigation.ts

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,36 @@ export const apiNavigation: ApiNavGroup[] = [
6969
}
7070
]
7171
},
72+
{
73+
"title": "Personas",
74+
"items": [
75+
{
76+
"title": "List personas",
77+
"href": "/docs/api/personas/listpersonas",
78+
"method": "GET"
79+
},
80+
{
81+
"title": "Create persona",
82+
"href": "/docs/api/personas/createpersona",
83+
"method": "POST"
84+
},
85+
{
86+
"title": "Update persona",
87+
"href": "/docs/api/personas/updatepersona",
88+
"method": "PATCH"
89+
},
90+
{
91+
"title": "Delete persona",
92+
"href": "/docs/api/personas/deletepersona",
93+
"method": "DELETE"
94+
},
95+
{
96+
"title": "Duplicate persona",
97+
"href": "/docs/api/personas/duplicatepersona",
98+
"method": "POST"
99+
}
100+
]
101+
},
72102
{
73103
"title": "Agent Definitions",
74104
"items": [
@@ -132,15 +162,165 @@ export const apiNavigation: ApiNavGroup[] = [
132162
{
133163
"title": "Run Tests",
134164
"items": [
165+
{
166+
"title": "List test runs",
167+
"href": "/docs/api/run-tests/listruntests",
168+
"method": "GET"
169+
},
135170
{
136171
"title": "Create a New Test Run",
137172
"href": "/docs/api/run-tests/createruntest",
138173
"method": "POST"
139174
},
175+
{
176+
"title": "Get test run details",
177+
"href": "/docs/api/run-tests/getruntestdetails",
178+
"method": "GET"
179+
},
180+
{
181+
"title": "Delete a test run",
182+
"href": "/docs/api/run-tests/deleteruntest",
183+
"method": "DELETE"
184+
},
140185
{
141186
"title": "Execute a test run",
142187
"href": "/docs/api/run-tests/executeruntest",
143188
"method": "POST"
189+
},
190+
{
191+
"title": "Update test run components",
192+
"href": "/docs/api/run-tests/updatetestcomponents",
193+
"method": "PATCH"
194+
},
195+
{
196+
"title": "Get test executions",
197+
"href": "/docs/api/run-tests/gettestexecutions",
198+
"method": "GET"
199+
},
200+
{
201+
"title": "Get scenarios for a test run",
202+
"href": "/docs/api/run-tests/gettestscenarios",
203+
"method": "GET"
204+
},
205+
{
206+
"title": "Get call executions for a test run",
207+
"href": "/docs/api/run-tests/getcallexecutions",
208+
"method": "GET"
209+
},
210+
{
211+
"title": "Get evaluation summary",
212+
"href": "/docs/api/run-tests/getevalsummary",
213+
"method": "GET"
214+
},
215+
{
216+
"title": "Compare evaluation summaries",
217+
"href": "/docs/api/run-tests/compareevalsummaries",
218+
"method": "GET"
219+
},
220+
{
221+
"title": "Add evaluation configurations",
222+
"href": "/docs/api/run-tests/addevalconfigs",
223+
"method": "POST"
224+
},
225+
{
226+
"title": "Update evaluation configuration",
227+
"href": "/docs/api/run-tests/updateevalconfig",
228+
"method": "PATCH"
229+
},
230+
{
231+
"title": "Delete evaluation configuration",
232+
"href": "/docs/api/run-tests/deleteevalconfig",
233+
"method": "DELETE"
234+
},
235+
{
236+
"title": "Run new evaluations on test executions",
237+
"href": "/docs/api/run-tests/runnewevalsontestexecution",
238+
"method": "POST"
239+
},
240+
{
241+
"title": "Rerun test executions",
242+
"href": "/docs/api/run-tests/reruntestexecutions",
243+
"method": "POST"
244+
},
245+
{
246+
"title": "Delete test executions",
247+
"href": "/docs/api/run-tests/deletetestexecutions",
248+
"method": "POST"
249+
}
250+
]
251+
},
252+
{
253+
"title": "Test Executions",
254+
"items": [
255+
{
256+
"title": "Get test execution details",
257+
"href": "/docs/api/test-executions/gettestexecutiondetails",
258+
"method": "GET"
259+
},
260+
{
261+
"title": "Get execution KPIs",
262+
"href": "/docs/api/test-executions/getkpis",
263+
"method": "GET"
264+
},
265+
{
266+
"title": "Get performance summary",
267+
"href": "/docs/api/test-executions/getperformancesummary",
268+
"method": "GET"
269+
},
270+
{
271+
"title": "Get eval explanation summary",
272+
"href": "/docs/api/test-executions/getevalexplanationsummary",
273+
"method": "GET"
274+
},
275+
{
276+
"title": "Cancel test execution",
277+
"href": "/docs/api/test-executions/cancelexecution",
278+
"method": "POST"
279+
},
280+
{
281+
"title": "Rerun call executions",
282+
"href": "/docs/api/test-executions/reruncalls",
283+
"method": "POST"
284+
}
285+
]
286+
},
287+
{
288+
"title": "Call Executions",
289+
"items": [
290+
{
291+
"title": "Get call execution details",
292+
"href": "/docs/api/call-executions/getcallexecutiondetails",
293+
"method": "GET"
294+
},
295+
{
296+
"title": "Compare execution sessions",
297+
"href": "/docs/api/call-executions/getsessioncomparison",
298+
"method": "GET"
299+
}
300+
]
301+
},
302+
{
303+
"title": "Prompt Simulations",
304+
"items": [
305+
{
306+
"title": "List prompt simulation scenarios",
307+
"href": "/docs/api/prompt-simulations/listscenarios",
308+
"method": "GET"
309+
},
310+
{
311+
"title": "List simulations for prompt template",
312+
"href": "/docs/api/prompt-simulations/listsimulations",
313+
"method": "GET"
314+
},
315+
{
316+
"title": "Get prompt simulation details",
317+
"href": "/docs/api/prompt-simulations/getsimulationdetails",
318+
"method": "GET"
319+
},
320+
{
321+
"title": "Execute prompt simulation",
322+
"href": "/docs/api/prompt-simulations/executesimulation",
323+
"method": "POST"
144324
}
145325
]
146326
},

0 commit comments

Comments
 (0)