@mondaydotcomorg/atp-client
Version:
Client SDK for Agent Tool Protocol
140 lines • 4.29 kB
JavaScript
export class ClientSession {
baseUrl;
customHeaders;
clientId;
clientToken;
initPromise;
hooks;
constructor(baseUrl, headers, hooks) {
this.baseUrl = baseUrl;
this.customHeaders = headers || {};
this.hooks = hooks;
}
/**
* Initializes the client session with the server.
* This MUST be called before any other operations.
* The server generates and returns a unique client ID and token.
* @param clientInfo - Optional client information
* @param tools - Optional client tool definitions to register with the server
* @param services - Optional client service capabilities (LLM, approval, embedding)
*/
async init(clientInfo, tools, services) {
if (this.initPromise) {
await this.initPromise;
return {
clientId: this.clientId,
token: this.clientToken,
expiresAt: 0,
tokenRotateAt: 0,
};
}
this.initPromise = (async () => {
const url = `${this.baseUrl}/api/init`;
const body = JSON.stringify({
clientInfo,
tools: tools || [],
services,
});
const headers = await this.prepareHeaders('POST', url, body);
const response = await fetch(url, {
method: 'POST',
headers,
body,
});
if (!response.ok) {
throw new Error(`Client initialization failed: ${response.status} ${response.statusText}`);
}
const data = (await response.json());
this.clientId = data.clientId;
this.clientToken = data.token;
})();
await this.initPromise;
return {
clientId: this.clientId,
token: this.clientToken,
expiresAt: 0,
tokenRotateAt: 0,
};
}
/**
* Gets the unique client ID.
*/
getClientId() {
if (!this.clientId) {
throw new Error('Client not initialized. Call init() first.');
}
return this.clientId;
}
/**
* Ensures the client is initialized before making requests.
*/
async ensureInitialized() {
if (!this.clientId) {
throw new Error('Client not initialized. Call init() first.');
}
}
/**
* Creates HTTP headers for requests.
*/
getHeaders() {
const headers = {
'Content-Type': 'application/json',
...this.customHeaders,
};
if (this.clientId) {
headers['X-Client-ID'] = this.clientId;
}
if (this.clientToken) {
headers['Authorization'] = `Bearer ${this.clientToken}`;
}
return headers;
}
getBaseUrl() {
return this.baseUrl;
}
/**
* Updates the client token from response headers (token refresh).
*/
updateToken(response) {
const newToken = response.headers.get('X-ATP-Token');
if (newToken) {
this.clientToken = newToken;
}
}
/**
* Prepares headers for a request, calling preRequest hook if configured
*/
async prepareHeaders(method, url, body) {
let headers = {
'Content-Type': 'application/json',
...this.customHeaders,
};
if (this.clientId) {
headers['X-Client-ID'] = this.clientId;
}
if (this.clientToken) {
headers['Authorization'] = `Bearer ${this.clientToken}`;
}
if (this.hooks?.preRequest) {
try {
const result = await this.hooks.preRequest({
url,
method,
currentHeaders: headers,
body,
});
if (result.abort) {
throw new Error(result.abortReason || 'Request aborted by preRequest hook');
}
if (result.headers) {
headers = result.headers;
}
}
catch (error) {
throw error;
}
}
return headers;
}
}
//# sourceMappingURL=session.js.map