@beignet/core
Version:
Core framework primitives for Beignet
282 lines • 10.9 kB
JavaScript
import { createProviderInstrumentation, } from "../providers/index.js";
import { runWithResolvedTracingContext } from "../tracing/execution.js";
/** Bind application context and principal types once for capability definitions. */
export function createAgentCapabilities() {
return {
defineAgentCapability(name, options) {
return {
kind: "agentCapability",
name,
description: options.description,
input: options.input,
output: options.output,
handle: options.handle,
};
},
defineAgentCapabilityRegistry,
};
}
/** Error thrown when a capability registry is ambiguous. */
export class AgentCapabilityRegistryError extends Error {
constructor(message) {
super(message);
this.name = "AgentCapabilityRegistryError";
}
}
/** Build a capability registry and reject duplicate external names. */
function defineAgentCapabilityRegistry(definitions) {
const byName = new Map();
for (const capability of definitions) {
if (byName.has(capability.name)) {
throw new AgentCapabilityRegistryError(`Duplicate agent capability definition "${capability.name}" in registry.`);
}
byName.set(capability.name, capability);
}
return {
definitions: [...definitions],
get(name) {
return byName.get(name);
},
};
}
/** Error raised by capability lookup, validation, or execution. */
export class AgentCapabilityError extends Error {
code;
capabilityName;
issues;
cause;
constructor(args) {
super(args.message);
this.name = "AgentCapabilityError";
this.code = args.code;
this.capabilityName = args.capabilityName;
this.issues = args.issues;
this.cause = args.cause;
}
}
function formatPath(path) {
if (!path?.length)
return "";
return path
.map((segment) => typeof segment === "object" && segment !== null && "key" in segment
? String(segment.key)
: String(segment))
.join(".");
}
function formatIssues(issues) {
return issues
.map((issue) => {
const path = formatPath(issue.path);
return path ? `${path}: ${issue.message}` : issue.message;
})
.join("; ");
}
async function parseCapabilitySchema(schema, input, args) {
const result = await schema["~standard"].validate(input);
if (result.issues?.length) {
throw new AgentCapabilityError({
code: args.code,
capabilityName: args.capabilityName,
message: `Agent capability "${args.capabilityName}" ${args.code === "invalid_input" ? "input" : "output"} validation failed: ${formatIssues(result.issues)}`,
issues: result.issues,
});
}
if ("value" in result) {
return result.value;
}
throw new AgentCapabilityError({
code: args.code,
capabilityName: args.capabilityName,
message: `Agent capability "${args.capabilityName}" schema returned no value.`,
});
}
function instrumentationTarget(ctx) {
if (!ctx || typeof ctx !== "object")
return undefined;
if ("ports" in ctx) {
return ctx.ports;
}
return ctx;
}
async function notifyHooks(hooks, event) {
await Promise.all(hooks.map(async (hook) => {
try {
await hook(event);
}
catch {
// Observers must not alter application behavior.
}
}));
}
/** Create a validated, traced executor for a capability registry. */
export function createAgentCapabilityExecutor(options) {
const hooks = options.hooks ?? [];
const instrumentationConfig = {
providerName: "agent-capabilities",
watcher: "agentCapabilities",
};
async function executeDynamic(invocation) {
const startedAt = Date.now();
let stage = "lookup";
let ctx;
let capability;
let input;
let hasValidatedInput = false;
let instrumentation = createProviderInstrumentation(options.instrumentation, instrumentationConfig);
try {
capability = options.registry.get(invocation.name);
const observedName = capability?.name ?? "unknown";
instrumentation.custom({
name: "agentCapability.started",
label: `Agent capability ${observedName}`,
summary: "Capability execution started",
details: { capabilityName: observedName, phase: "start" },
});
await notifyHooks(hooks, {
name: invocation.name,
phase: "start",
stage,
principal: invocation.principal,
});
if (!capability) {
throw new AgentCapabilityError({
code: "unknown_capability",
capabilityName: invocation.name,
message: `Unknown agent capability "${invocation.name}".`,
});
}
const registeredCapability = capability;
const runtimeCapability = registeredCapability;
return await runWithResolvedTracingContext({
tracing: options.tracing,
ctx: async () => {
stage = "input";
input = await parseCapabilitySchema(runtimeCapability.input, invocation.input, {
capabilityName: runtimeCapability.name,
code: "invalid_input",
});
hasValidatedInput = true;
if (invocation.authorize) {
stage = "authorization";
await invocation.authorize({
capability: registeredCapability,
name: registeredCapability.name,
principal: invocation.principal,
input,
});
}
stage = "context";
ctx = await options.createContext({
capability: registeredCapability,
name: registeredCapability.name,
principal: invocation.principal,
input,
});
return ctx;
},
operation: {
name: `beignet.agent_capability ${registeredCapability.name}`,
type: "agentCapability",
kind: "internal",
attributes: {
"beignet.agent_capability.name": registeredCapability.name,
},
metricAttributes: {
"beignet.agent_capability.name": registeredCapability.name,
},
},
async run(resolvedCtx) {
ctx = resolvedCtx;
if (options.instrumentation === undefined) {
instrumentation = createProviderInstrumentation(instrumentationTarget(ctx), instrumentationConfig);
instrumentation.custom({
name: "agentCapability.started",
label: `Agent capability ${registeredCapability.name}`,
summary: "Capability execution started",
details: {
capabilityName: registeredCapability.name,
phase: "start",
},
});
}
stage = "handler";
const rawOutput = await runtimeCapability.handle({
capability: runtimeCapability,
ctx,
principal: invocation.principal,
input,
});
stage = "output";
const output = await parseCapabilitySchema(runtimeCapability.output, rawOutput, {
capabilityName: registeredCapability.name,
code: "invalid_output",
});
const durationMs = Date.now() - startedAt;
instrumentation.custom({
name: "agentCapability.completed",
label: `Agent capability ${registeredCapability.name}`,
summary: "Capability execution completed",
details: {
capabilityName: registeredCapability.name,
phase: "end",
durationMs,
},
});
await notifyHooks(hooks, {
name: registeredCapability.name,
phase: "end",
stage,
capability: registeredCapability,
ctx,
principal: invocation.principal,
input,
output,
durationMs,
});
return output;
},
});
}
catch (error) {
const wrapped = error instanceof AgentCapabilityError
? error
: new AgentCapabilityError({
code: "execution_failed",
capabilityName: capability?.name ?? invocation.name,
message: `Agent capability "${capability?.name ?? invocation.name}" execution failed.`,
cause: error,
});
const durationMs = Date.now() - startedAt;
const observedName = capability?.name ?? "unknown";
instrumentation.custom({
name: "agentCapability.failed",
label: `Agent capability ${observedName}`,
summary: "Capability execution failed",
details: {
capabilityName: observedName,
phase: "error",
stage,
durationMs,
code: wrapped.code,
},
});
await notifyHooks(hooks, {
name: invocation.name,
phase: "error",
stage,
...(capability ? { capability } : {}),
ctx,
principal: invocation.principal,
durationMs,
error: wrapped,
...(hasValidatedInput ? { input } : {}),
});
throw wrapped;
}
}
return {
execute: executeDynamic,
executeDynamic,
};
}
//# sourceMappingURL=index.js.map