Add Beryl Agent and harness source

This commit is contained in:
2026-09-08 20:10:03 +08:00
parent 06d72d001c
commit 47cfbcd66a
70 changed files with 12558 additions and 0 deletions
@@ -0,0 +1 @@
{"name":"@agent-studio/shared","version":"0.1.0","type":"module","exports":"./src/index.ts","scripts":{"lint":"eslint src tests","typecheck":"tsc -p tsconfig.json --noEmit","test":"vitest run","build":"tsc -p tsconfig.json"},"dependencies":{"zod":"^4.1.5"}}
@@ -0,0 +1,14 @@
import { z } from 'zod';
export const eventTypes = ['session.started','session.ended','user.message','assistant.delta','assistant.completed','skill.requested','skill.loaded','tool.requested','tool.completed','tool.failed','approval.required','approval.resolved','attachment.uploaded','attachment.rejected','model.configured','model.validation_failed','run.started','run.cancelled','run.completed','run.failed'] as const;
const baseEvent = z.object({eventId:z.string(),sessionId:z.string(),runId:z.string().optional(),timestamp:z.string().datetime(),sequence:z.number().int().positive()});
export const HarnessEventSchema = z.discriminatedUnion('type', eventTypes.map(type=>baseEvent.extend({type:z.literal(type),payload:z.record(z.string(),z.unknown())})) as unknown as [ReturnType<typeof baseEvent.extend>,ReturnType<typeof baseEvent.extend>,...ReturnType<typeof baseEvent.extend>[]]);
export type HarnessEventType = typeof eventTypes[number];
export type HarnessEvent = {eventId:string;sessionId:string;runId?:string;timestamp:string;sequence:number;type:HarnessEventType;payload:Record<string,unknown>};
export const ModelConnectionInputSchema = z.object({providerId:z.string().min(1).max(80),api:z.enum(['openai-responses','openai-completions','anthropic-messages']),baseUrl:z.url().optional(),apiKey:z.string().min(1).max(4096).optional(),modelId:z.string().min(1).max(200),displayName:z.string().max(200).optional(),supportsImages:z.boolean(),supportsVideo:z.boolean().default(false),contextWindow:z.number().int().positive().max(10_000_000).optional(),maxTokens:z.number().int().positive().max(1_000_000).optional()}).strict();
export type ModelConnectionInput = z.infer<typeof ModelConnectionInputSchema>;
export const MessageInputSchema = z.object({text:z.string().max(100_000).default(''),attachmentIds:z.array(z.string()).max(4).default([])}).strict().refine(v=>v.text.trim()||v.attachmentIds.length,{message:'Text or attachment is required'});
export const ApiErrorSchema = z.object({error:z.object({code:z.string(),message:z.string(),requestId:z.string(),details:z.record(z.string(),z.unknown()).default({})})});
export type ImageAttachment={attachmentId:string;sessionId:string;name:string;mediaType:'image/jpeg'|'image/png'|'image/webp';byteSize:number;width:number;height:number;status:'ready'};
export type SkillCatalogItem={name:string;description:string;source:string;filePath:string;diagnostics:Array<{level:'warning'|'error';message:string}>};
@@ -0,0 +1,39 @@
import { describe, expect, it } from "vitest";
import {
ApiErrorSchema,
HarnessEventSchema,
MessageInputSchema,
ModelConnectionInputSchema,
} from "../src/index.js";
describe("shared schemas", () => {
it("validates a harness event", () =>
expect(
HarnessEventSchema.parse({
eventId: "e",
sessionId: "s",
timestamp: new Date().toISOString(),
sequence: 1,
type: "run.started",
payload: {},
}).type,
).toBe("run.started"));
it("requires message content", () =>
expect(() =>
MessageInputSchema.parse({ text: " ", attachmentIds: [] }),
).toThrow());
it("strictly validates model config", () =>
expect(() =>
ModelConnectionInputSchema.parse({
providerId: "p",
api: "bad",
modelId: "m",
supportsImages: false,
}),
).toThrow());
it("validates unified errors", () =>
expect(
ApiErrorSchema.parse({
error: { code: "X", message: "x", requestId: "r", details: {} },
}).error.code,
).toBe("X"));
});
@@ -0,0 +1 @@
{"extends":"../../tsconfig.base.json","compilerOptions":{"outDir":"dist","rootDir":"."},"include":["src","tests"]}