acp-sdk
Version:
Agent Communication Protocol SDK
223 lines (220 loc) • 6.12 kB
JavaScript
;
var uuid = require('uuid');
var errors_cjs$1 = require('../models/errors.cjs');
var models_cjs = require('../models/models.cjs');
var schemas_cjs = require('../models/schemas.cjs');
var errors_cjs = require('./errors.cjs');
var sse_cjs = require('./sse.cjs');
var utils_cjs = require('./utils.cjs');
var instrumentation_cjs = require('../instrumentation.cjs');
class Client {
#baseUrl;
#fetch;
#sessionId;
constructor(init) {
this.#fetch = init?.fetch ?? globalThis.fetch.bind(globalThis);
this.#baseUrl = normalizeBaseUrl(init?.baseUrl ?? "");
this.#sessionId = init?.sessionId;
}
get sessionId() {
return this.#sessionId;
}
async withSession(cb, sessionId = uuid.v4()) {
return await instrumentation_cjs.getTracer().startActiveSpan(
"session",
{ attributes: { "acp.session": sessionId } },
async (span) => {
try {
const client = new Client({
fetch: this.#fetch,
baseUrl: this.#baseUrl,
sessionId
});
return await cb(client);
} finally {
span.end();
}
}
);
}
async #fetcher(url, options) {
let response;
try {
response = await this.#fetch(this.#baseUrl + url, options);
await this.#handleErrorResponse(response);
return await response.json();
} catch (err) {
if (err instanceof errors_cjs.BaseError || err instanceof Error && err.name === "AbortError") {
throw err;
}
throw new errors_cjs.FetchError(err.message ?? "fetch failed", response, {
cause: err
});
}
}
async #fetchEventSource(url, options) {
let eventSource;
try {
eventSource = await sse_cjs.createEventSource({
url: this.#baseUrl + url,
fetch: this.#fetch,
options
});
} catch (err) {
throw new errors_cjs.FetchError(
err.message ?? "fetch failed",
void 0,
{
cause: err
}
);
}
await this.#handleErrorResponse(eventSource.response);
return eventSource;
}
async #handleErrorResponse(response) {
if (response.ok) return;
const text = await response.text();
let data;
try {
data = JSON.parse(text);
} catch {
throw new errors_cjs.HTTPError(response, text);
}
const result = errors_cjs$1.ErrorModel.safeParse(data);
if (result.success) {
throw new errors_cjs.ACPError(result.data);
}
throw new errors_cjs.HTTPError(response, data);
}
async *#processEventSource(eventSource) {
for await (const message of eventSource.consume()) {
const event = models_cjs.Event.parse(JSON.parse(message.data));
if (event.type === "error") {
throw new errors_cjs.ACPError(event.error);
}
yield event;
}
}
async ping() {
const data = await this.#fetcher("/ping", { method: "GET" });
schemas_cjs.PingResponse.parse(data);
}
async agents() {
const data = await this.#fetcher("/agents", { method: "GET" });
return schemas_cjs.AgentsListResponse.parse(data).agents;
}
async agent(name) {
const data = await this.#fetcher(`/agents/${name}`, { method: "GET" });
return schemas_cjs.AgentsReadResponse.parse(data);
}
async runSync(agentName, input) {
const data = await this.#fetcher(
"/runs",
jsonPost({
agent_name: agentName,
input: utils_cjs.inputToMessages(input),
mode: "sync",
session_id: this.#sessionId
})
);
return schemas_cjs.RunCreateResponse.parse(data);
}
async runAsync(agentName, input) {
const data = await this.#fetcher(
"/runs",
jsonPost({
agent_name: agentName,
input: utils_cjs.inputToMessages(input),
mode: "async",
session_id: this.#sessionId
})
);
return schemas_cjs.RunCreateResponse.parse(data);
}
async *runStream(agentName, input, signal) {
const eventSource = await this.#fetchEventSource(
"/runs",
jsonPost(
{
agent_name: agentName,
input: utils_cjs.inputToMessages(input),
mode: "stream",
session_id: this.#sessionId
},
{ signal }
)
);
for await (const event of this.#processEventSource(eventSource)) {
yield event;
}
}
async runStatus(runId) {
const data = await this.#fetcher(`/runs/${runId}`, { method: "GET" });
return schemas_cjs.RunReadResponse.parse(data);
}
async runEvents(runId) {
const data = await this.#fetcher(`/runs/${runId}/events`, {
method: "GET"
});
return schemas_cjs.RunEventsListResponse.parse(data).events;
}
async runCancel(runId) {
const data = await this.#fetcher(`/runs/${runId}/cancel`, {
method: "POST"
});
return schemas_cjs.RunReadResponse.parse(data);
}
async runResumeSync(runId, awaitResume) {
const data = await this.#fetcher(
`/runs/${runId}`,
jsonPost({
await_resume: awaitResume,
mode: "sync"
})
);
return schemas_cjs.RunResumeResponse.parse(data);
}
async runResumeAsync(runId, awaitResume) {
const data = await this.#fetcher(
`/runs/${runId}`,
jsonPost({
await_resume: awaitResume,
mode: "async"
})
);
return schemas_cjs.RunResumeResponse.parse(data);
}
async *runResumeStream(runId, awaitResume, signal) {
const eventSource = await this.#fetchEventSource(
`/runs/${runId}`,
jsonPost(
{
await_resume: awaitResume,
mode: "stream"
},
{ signal }
)
);
for await (const event of this.#processEventSource(eventSource)) {
yield event;
}
}
}
const normalizeBaseUrl = (url) => {
if (url.endsWith("/")) {
return url.slice(0, -1);
}
return url;
};
const jsonPost = (json, init) => {
return {
...init,
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(json)
};
};
exports.Client = Client;
//# sourceMappingURL=client.cjs.map
//# sourceMappingURL=client.cjs.map