kestrel.markets
Version:
A typed, token-efficient language + runtime for agentic trading: agents author bounded plans, the runtime fires them at the tick. CLI + typed library + MCP server.
208 lines (205 loc) • 6.6 kB
JavaScript
import {
ARTIFACT_REF_SHAPE,
ArgShapeError,
OPERATION_ID_SHAPE,
VALIDATE_DOCUMENT_SHAPE,
agentDescribe,
agentOpNames,
asAuthoredResponse,
asBlotters,
asBoundResponse,
asEventCursor,
asRequiredString,
asSessionRef,
createSdk,
localTransport,
remoteTransport
} from "./bin-a4jbxqxk.js";
import"./bin-cv13fq8c.js";
import"./bin-kxzrsgjw.js";
import {
DEFAULT_API
} from "./bin-qewrvqtv.js";
import {
EXIT
} from "./bin-t9ggwnv5.js";
import"./bin-xx1qrxe3.js";
import"./bin-t58k60v9.js";
import"./bin-p5jfg5b0.js";
import"./bin-29be75ss.js";
import"./bin-n77kea5n.js";
import"./bin-mn7wcxhv.js";
import"./bin-8pchjxn2.js";
import"./bin-am3351y2.js";
import"./bin-73jr945c.js";
import"./bin-df1tn094.js";
import"./bin-3ft0k1jq.js";
import"./bin-2ywrx58g.js";
import"./bin-wckvcay0.js";
// src/cli/commands/agent.ts
var AGENT_PROTOCOL_VERSION = "kestrel.agent/v1";
var AGENT_OPS = agentOpNames;
class AgentRefusal extends Error {
name = "AgentRefusal";
code;
constructor(code, message) {
super(message);
this.code = code;
}
}
function codeOf(e) {
if (e !== null && typeof e === "object" && "code" in e) {
const code = e.code;
if (typeof code === "string" && code.length > 0)
return code;
}
return "error";
}
function problemOf(e) {
if (e !== null && typeof e === "object" && "problem" in e) {
const p = e.problem;
if (p !== null && typeof p === "object")
return p;
}
return;
}
function buildSdk(api, fetchImpl) {
if (api === undefined)
return createSdk(localTransport());
const baseUrl = api === "" || api === "default" ? DEFAULT_API : api;
return createSdk(remoteTransport({ baseUrl, fetch: fetchImpl }));
}
async function drainProcessStdin() {
if (typeof Bun !== "undefined")
return await Bun.stdin.text();
const chunks = [];
for await (const chunk of process.stdin)
chunks.push(chunk);
return Buffer.concat(chunks).toString("utf8");
}
function requireSession(s) {
if (s === undefined) {
throw new AgentRefusal("no-session", "no active Session — issue `openSession` before a session verb");
}
return s;
}
async function agentCommand(globals, io) {
const readIn = io?.stdin ?? drainProcessStdin;
const writeOut = io?.stdout ?? ((s) => void process.stdout.write(s));
const writeErr = io?.stderr ?? ((s) => void process.stderr.write(s));
const fetchImpl = io?.fetch ?? globalThis.fetch;
const sdk = buildSdk(globals.api, fetchImpl);
const emit = (kind, value) => {
writeOut(JSON.stringify({ v: AGENT_PROTOCOL_VERSION, kind, value }) + `
`);
};
const refuse = (code, message, problem) => {
writeErr(JSON.stringify({
v: AGENT_PROTOCOL_VERSION,
kind: "refusal",
code,
message,
...problem !== undefined ? { problem } : {}
}) + `
`);
};
const raw = await readIn();
const requestLines = raw.split(`
`).filter((l) => l.trim().length > 0);
if (requestLines.length === 0) {
const interactiveTty = io?.stdin === undefined && Boolean(process.stdin.isTTY);
if (!interactiveTty) {
refuse("empty-request-stream", "agent mode read zero request lines from stdin — expected one JSONL verb envelope (`{ op, ... }`) per line");
return EXIT.USAGE;
}
}
let session;
for (const rawLine of requestLines) {
let req;
try {
const parsed = JSON.parse(rawLine);
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
throw new AgentRefusal("bad-request", "a request line must be a JSON object");
}
req = parsed;
} catch (e) {
const code = e instanceof AgentRefusal ? e.code : "bad-request";
refuse(code, `unparseable request line: ${rawLine}`);
return EXIT.USAGE;
}
const op = req["op"];
try {
switch (op) {
case "describe":
emit("describe", agentDescribe(AGENT_PROTOCOL_VERSION));
break;
case "catalog":
emit("catalog", await sdk.catalog());
break;
case "validate":
emit("validate", await sdk.validate(asRequiredString(req["document"], "document", VALIDATE_DOCUMENT_SHAPE)));
break;
case "openSession": {
const document = req["document"] !== undefined ? String(req["document"]) : undefined;
const gated = await sdk.openSession(asSessionRef(req["subject"]), document);
if (gated.gated) {
emit("openSession", { gated: true, payment: gated.payment });
} else {
session = gated.value;
emit("openSession", { gated: false, sessionId: gated.value.sessionId });
}
break;
}
case "start":
emit("start", await requireSession(session).start());
break;
case "advance":
emit("advance", await requireSession(session).advance(asAuthoredResponse(req["response"])));
break;
case "revise":
emit("revise", await requireSession(session).revise(asAuthoredResponse(req["response"])));
break;
case "submit":
emit("submit", await requireSession(session).submit(asBoundResponse(req["response"])));
break;
case "resume":
emit("resume", await requireSession(session).resume(asEventCursor(req["after"])));
break;
case "finalize":
emit("finalize", await requireSession(session).finalize());
break;
case "grade":
emit("grade", await sdk.grade({ blotters: asBlotters(req["blotters"]) }));
break;
case "artifact":
emit("artifact", await sdk.artifact(asRequiredString(req["ref"], "ref", ARTIFACT_REF_SHAPE)));
break;
case "resumeOperation": {
const after = asEventCursor(req["after"]);
const ref = {
operationId: asRequiredString(req["operationId"], "operationId", OPERATION_ID_SHAPE),
...after !== undefined ? { after } : {}
};
emit("resumeOperation", await sdk.resumeOperation(ref));
break;
}
default:
refuse("unknown-op", `unknown agent op ${JSON.stringify(op)} — valid ops: ${AGENT_OPS.join(", ")} (see \`kestrel agent --help\`)`);
return EXIT.USAGE;
}
} catch (e) {
if (e instanceof ArgShapeError) {
refuse(e.code, e.message);
return EXIT.USAGE;
}
refuse(codeOf(e), e instanceof Error ? e.message : String(e), problemOf(e));
return EXIT.GENERIC;
}
}
return EXIT.OK;
}
export {
agentCommand,
AGENT_PROTOCOL_VERSION,
AGENT_OPS
};