@mondaydotcomorg/atp-client
Version:
Client SDK for Agent Tool Protocol
200 lines (163 loc) • 5.58 kB
text/typescript
import type { SearchOptions, SearchResult, ExploreResult } from '@mondaydotcomorg/atp-protocol';
import type { RuntimeAPIName } from '@mondaydotcomorg/atp-runtime';
import type { ISession } from './session.js';
import type { InProcessSession } from './in-process-session.js';
export class APIOperations {
private session: ISession;
private inProcessSession?: InProcessSession;
private apiDefinitions?: string;
constructor(session: ISession, inProcessSession?: InProcessSession) {
this.session = session;
this.inProcessSession = inProcessSession;
}
/**
* Connects to the server and retrieves API definitions.
*/
async connect(options?: { apiGroups?: string[] }): Promise<{
serverVersion: string;
capabilities: unknown;
apiGroups: string[];
}> {
await this.session.ensureInitialized();
if (this.inProcessSession) {
const data = await this.inProcessSession.getDefinitions(options);
this.apiDefinitions = data.typescript;
return {
serverVersion: data.version,
capabilities: {},
apiGroups: data.apiGroups,
};
}
const params = new URLSearchParams();
if (options?.apiGroups) {
params.set('apiGroups', options.apiGroups.join(','));
}
const url = `${this.session.getBaseUrl()}/api/definitions?${params}`;
const headers = await this.session.prepareHeaders('GET', url);
const response = await fetch(url, { headers });
if (!response.ok) {
throw new Error(`Connection failed: ${response.status} ${response.statusText}`);
}
const data = (await response.json()) as {
typescript: string;
version: string;
apiGroups: string[];
};
this.apiDefinitions = data.typescript;
return {
serverVersion: data.version,
capabilities: {},
apiGroups: data.apiGroups,
};
}
/**
* Gets the TypeScript type definitions for available APIs.
*/
getTypeDefinitions(): string {
if (!this.apiDefinitions) {
throw new Error('Not connected. Call connect() first.');
}
return this.apiDefinitions;
}
/**
* Searches for available API functions.
*/
async searchAPI(query: string, options?: SearchOptions): Promise<SearchResult[]> {
await this.session.ensureInitialized();
if (this.inProcessSession) {
const data = await this.inProcessSession.search(
query,
options as unknown as Record<string, unknown>
);
return data.results as SearchResult[];
}
const url = `${this.session.getBaseUrl()}/api/search`;
const body = JSON.stringify({ query, ...options });
const headers = await this.session.prepareHeaders('POST', url, body);
const response = await fetch(url, {
method: 'POST',
headers,
body,
});
if (!response.ok) {
throw new Error(`Search failed: ${response.status} ${response.statusText}`);
}
const data = (await response.json()) as { results: SearchResult[] };
return data.results;
}
/**
* Explores the API filesystem at the given path.
*/
async exploreAPI(path: string): Promise<ExploreResult> {
await this.session.ensureInitialized();
if (this.inProcessSession) {
return (await this.inProcessSession.explore(path)) as ExploreResult;
}
const url = `${this.session.getBaseUrl()}/api/explore`;
const body = JSON.stringify({ path });
const headers = await this.session.prepareHeaders('POST', url, body);
const response = await fetch(url, {
method: 'POST',
headers,
body,
});
if (!response.ok) {
throw new Error(`Explore failed: ${response.status} ${response.statusText}`);
}
return (await response.json()) as ExploreResult;
}
/**
* Gets information about the server.
*/
async getServerInfo(): Promise<{
version: string;
capabilities: Record<string, boolean>;
}> {
await this.session.ensureInitialized();
if (this.inProcessSession) {
return await this.inProcessSession.getServerInfo();
}
const url = `${this.session.getBaseUrl()}/api/info`;
const headers = await this.session.prepareHeaders('GET', url);
const response = await fetch(url, { headers });
if (!response.ok) {
throw new Error(`Failed to get server info: ${response.status}`);
}
return (await response.json()) as {
version: string;
capabilities: Record<string, boolean>;
};
}
/**
* Gets ATP runtime API definitions as TypeScript declarations.
* Returns the full TypeScript definitions for atp.llm.*, atp.cache.*, etc.
* These are the APIs available during code execution.
*
* Behavior:
* - No options: Returns APIs based on client capabilities (default filtering)
* - apis: ['llm', 'cache']: Returns only specified APIs (intersection with client capabilities)
* - apis: []: Returns all APIs regardless of client capabilities
*
* @param options - Optional filtering options
* @param options.apis - Specific APIs to include (e.g., ['llm', 'cache', 'approval'])
*/
async getRuntimeDefinitions(options?: { apis?: RuntimeAPIName[] }): Promise<string> {
await this.session.ensureInitialized();
if (this.inProcessSession) {
return await this.inProcessSession.getRuntimeDefinitions(
options?.apis ? { apis: options.apis } : undefined
);
}
const params = new URLSearchParams();
if (options?.apis && options.apis.length > 0) {
params.set('apis', options.apis.join(','));
}
const url = `${this.session.getBaseUrl()}/api/runtime${params.toString() ? `?${params}` : ''}`;
const headers = await this.session.prepareHeaders('GET', url);
const response = await fetch(url, { headers });
if (!response.ok) {
throw new Error(`Failed to get runtime definitions: ${response.status}`);
}
return await response.text();
}
}