mirror of
https://github.com/rowboatlabs/rowboat.git
synced 2026-04-25 08:26:22 +02:00
add list runs endpoint
This commit is contained in:
parent
1822deadc1
commit
338cc3d2f9
2 changed files with 91 additions and 2 deletions
|
|
@ -22,6 +22,7 @@ export const CreateRunOptions = Run.pick({
|
|||
export interface IRunsRepo {
|
||||
create(options: z.infer<typeof CreateRunOptions>): Promise<z.infer<typeof Run>>;
|
||||
fetch(id: string): Promise<z.infer<typeof Run>>;
|
||||
list(cursor?: string): Promise<z.infer<typeof ListRunsResponse>>;
|
||||
appendEvents(runId: string, events: z.infer<typeof RunEvent>[]): Promise<void>;
|
||||
}
|
||||
|
||||
|
|
@ -76,4 +77,68 @@ export class FSRunsRepo implements IRunsRepo {
|
|||
log: events,
|
||||
};
|
||||
}
|
||||
|
||||
async list(cursor?: string): Promise<z.infer<typeof ListRunsResponse>> {
|
||||
const runsDir = path.join(WorkDir, 'runs');
|
||||
const PAGE_SIZE = 20;
|
||||
|
||||
let files: string[] = [];
|
||||
try {
|
||||
const entries = await fsp.readdir(runsDir, { withFileTypes: true });
|
||||
files = entries
|
||||
.filter(e => e.isFile() && e.name.endsWith('.jsonl'))
|
||||
.map(e => e.name);
|
||||
} catch (err: any) {
|
||||
if (err && err.code === 'ENOENT') {
|
||||
return { runs: [] };
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
|
||||
files.sort((a, b) => b.localeCompare(a));
|
||||
|
||||
const cursorFile = cursor;
|
||||
let startIndex = 0;
|
||||
if (cursorFile) {
|
||||
const exact = files.indexOf(cursorFile);
|
||||
if (exact >= 0) {
|
||||
startIndex = exact + 1;
|
||||
} else {
|
||||
const firstOlder = files.findIndex(name => name.localeCompare(cursorFile) < 0);
|
||||
startIndex = firstOlder === -1 ? files.length : firstOlder;
|
||||
}
|
||||
}
|
||||
|
||||
const selected = files.slice(startIndex, startIndex + PAGE_SIZE);
|
||||
const runs: z.infer<typeof ListRunsResponse>['runs'] = [];
|
||||
|
||||
for (const name of selected) {
|
||||
const runId = name.slice(0, -'.jsonl'.length);
|
||||
try {
|
||||
const contents = await fsp.readFile(path.join(runsDir, name), 'utf8');
|
||||
const firstLine = contents.split('\n').find(line => line.trim() !== '');
|
||||
if (!firstLine) {
|
||||
continue;
|
||||
}
|
||||
const start = StartEvent.parse(JSON.parse(firstLine));
|
||||
runs.push({
|
||||
id: runId,
|
||||
createdAt: start.ts!,
|
||||
agentId: start.agentName,
|
||||
});
|
||||
} catch {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
const hasMore = startIndex + PAGE_SIZE < files.length;
|
||||
const nextCursor = hasMore && selected.length > 0
|
||||
? selected[selected.length - 1]
|
||||
: undefined;
|
||||
|
||||
return {
|
||||
runs,
|
||||
...(nextCursor ? { nextCursor } : {}),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -12,9 +12,8 @@ import { ModelConfig, Provider } from "./models/models.js";
|
|||
import { IAgentsRepo } from "./agents/repo.js";
|
||||
import { Agent } from "./agents/agents.js";
|
||||
import { AskHumanResponsePayload, authorizePermission, createMessage, createRun, replyToHumanInputRequest, Run, stop, ToolPermissionAuthorizePayload } from './runs/runs.js';
|
||||
import { IRunsRepo, ListRunsResponse, CreateRunOptions } from './runs/repo.js';
|
||||
import { IRunsRepo, CreateRunOptions, ListRunsResponse } from './runs/repo.js';
|
||||
import { IBus } from './application/lib/bus.js';
|
||||
import { RunEvent } from './entities/run-events.js';
|
||||
|
||||
let id = 0;
|
||||
|
||||
|
|
@ -462,6 +461,31 @@ const routes = new Hono()
|
|||
return c.json(run);
|
||||
}
|
||||
)
|
||||
.get(
|
||||
'/runs',
|
||||
describeRoute({
|
||||
summary: 'List runs',
|
||||
description: 'List all runs',
|
||||
responses: {
|
||||
200: {
|
||||
description: 'Runs list',
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: resolver(ListRunsResponse),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
validator('query', z.object({
|
||||
cursor: z.string().optional(),
|
||||
})),
|
||||
async (c) => {
|
||||
const repo = container.resolve<IRunsRepo>('runsRepo');
|
||||
const runs = await repo.list(c.req.valid('query').cursor);
|
||||
return c.json(runs);
|
||||
}
|
||||
)
|
||||
.post(
|
||||
'/runs/:runId/messages/new',
|
||||
describeRoute({
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue