@zauso-ai/capstan-agent 0.1.4 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,157 @@
1
+ import { routeToToolName } from "./mcp.js";
2
+ // ---------------------------------------------------------------------------
3
+ // Internal helpers
4
+ // ---------------------------------------------------------------------------
5
+ /** HTTP methods that carry a request body. */
6
+ const BODY_METHODS = new Set(["POST", "PUT", "PATCH", "DELETE"]);
7
+ /**
8
+ * Build a human-readable tool description from a route entry.
9
+ */
10
+ function buildDescription(route) {
11
+ if (route.description) {
12
+ return route.description;
13
+ }
14
+ return `${route.method.toUpperCase()} ${route.path}`;
15
+ }
16
+ /**
17
+ * Build the JSON Schema that describes the tool's input.
18
+ *
19
+ * If the route already carries an `inputSchema` we return it as-is
20
+ * (it is already JSON Schema). Otherwise we return a permissive
21
+ * empty-object schema.
22
+ */
23
+ function buildInputJsonSchema(route) {
24
+ if (route.inputSchema) {
25
+ return { ...route.inputSchema };
26
+ }
27
+ return { type: "object", properties: {} };
28
+ }
29
+ /**
30
+ * Construct the URL for a GET request, appending `input` as query parameters.
31
+ */
32
+ function buildGetUrl(base, path, input) {
33
+ const url = new URL(path, base);
34
+ for (const [key, value] of Object.entries(input)) {
35
+ if (value !== undefined && value !== null) {
36
+ url.searchParams.set(key, String(value));
37
+ }
38
+ }
39
+ return url.toString();
40
+ }
41
+ /**
42
+ * Determine whether a route should be included given the capability filter.
43
+ */
44
+ function matchesCapabilities(route, capabilities) {
45
+ if (!capabilities || capabilities.length === 0) {
46
+ return true;
47
+ }
48
+ // Routes without an explicit capability are included only when no filter
49
+ // is specified (handled above). When a filter IS specified, the route
50
+ // must declare a matching capability.
51
+ if (!route.capability) {
52
+ return false;
53
+ }
54
+ return capabilities.includes(route.capability);
55
+ }
56
+ /**
57
+ * Normalise the `input` argument that LangChain passes to `func`.
58
+ *
59
+ * LangChain may send either a JSON string or an object depending on the
60
+ * agent implementation, so we handle both.
61
+ */
62
+ function normaliseInput(input) {
63
+ if (typeof input === "string") {
64
+ if (input.trim() === "") {
65
+ return {};
66
+ }
67
+ try {
68
+ const parsed = JSON.parse(input);
69
+ if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) {
70
+ return parsed;
71
+ }
72
+ return {};
73
+ }
74
+ catch {
75
+ return {};
76
+ }
77
+ }
78
+ return input;
79
+ }
80
+ // ---------------------------------------------------------------------------
81
+ // Public API
82
+ // ---------------------------------------------------------------------------
83
+ /**
84
+ * Convert a {@link CapabilityRegistry} into an array of LangChain-compatible
85
+ * tool definitions.
86
+ *
87
+ * Each tool invokes the corresponding Capstan API endpoint over HTTP when
88
+ * called, so the Capstan server must be running at `options.baseUrl`.
89
+ *
90
+ * @param registry - The Capstan capability registry.
91
+ * @param options - Connection and filtering options.
92
+ * @returns An array of tool definitions ready to hand to a LangChain agent.
93
+ */
94
+ export function toLangChainTools(registry, options) {
95
+ const { baseUrl, authorization, capabilities } = options;
96
+ const routes = registry.getRoutes();
97
+ const tools = [];
98
+ for (const route of routes) {
99
+ if (!matchesCapabilities(route, capabilities)) {
100
+ continue;
101
+ }
102
+ const name = routeToToolName(route.method, route.path);
103
+ const description = buildDescription(route);
104
+ const schema = buildInputJsonSchema(route);
105
+ const method = route.method.toUpperCase();
106
+ const func = async (rawInput) => {
107
+ const input = normaliseInput(rawInput);
108
+ const headers = {};
109
+ if (authorization) {
110
+ headers["Authorization"] = authorization;
111
+ }
112
+ let response;
113
+ if (BODY_METHODS.has(method)) {
114
+ headers["Content-Type"] = "application/json";
115
+ response = await fetch(new URL(route.path, baseUrl).toString(), {
116
+ method,
117
+ headers,
118
+ body: JSON.stringify(input),
119
+ });
120
+ }
121
+ else {
122
+ // GET / HEAD — pass input as query parameters.
123
+ response = await fetch(buildGetUrl(baseUrl, route.path, input), {
124
+ method,
125
+ headers,
126
+ });
127
+ }
128
+ const text = await response.text();
129
+ return text;
130
+ };
131
+ tools.push({ name, description, schema, func });
132
+ }
133
+ return tools;
134
+ }
135
+ /**
136
+ * Generate LangChain-compatible tool specifications (metadata only, no
137
+ * executable function).
138
+ *
139
+ * Useful for sending tool definitions over the wire or for inspection
140
+ * without needing a live server connection.
141
+ *
142
+ * @param registry - The Capstan capability registry.
143
+ * @returns An array of tool spec objects.
144
+ */
145
+ export function toLangChainToolSpecs(registry) {
146
+ const routes = registry.getRoutes();
147
+ const specs = [];
148
+ for (const route of routes) {
149
+ specs.push({
150
+ name: routeToToolName(route.method, route.path),
151
+ description: buildDescription(route),
152
+ parameters: buildInputJsonSchema(route),
153
+ });
154
+ }
155
+ return specs;
156
+ }
157
+ //# sourceMappingURL=langchain.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"langchain.js","sourceRoot":"","sources":["../src/langchain.ts"],"names":[],"mappings":"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"}
package/dist/llm.d.ts ADDED
@@ -0,0 +1,41 @@
1
+ export interface LLMMessage {
2
+ role: "system" | "user" | "assistant";
3
+ content: string;
4
+ }
5
+ export interface LLMResponse {
6
+ content: string;
7
+ model: string;
8
+ usage?: {
9
+ promptTokens: number;
10
+ completionTokens: number;
11
+ totalTokens: number;
12
+ } | undefined;
13
+ finishReason?: string | undefined;
14
+ }
15
+ export interface LLMStreamChunk {
16
+ content: string;
17
+ done: boolean;
18
+ }
19
+ export interface LLMOptions {
20
+ model?: string;
21
+ temperature?: number;
22
+ maxTokens?: number;
23
+ systemPrompt?: string;
24
+ responseFormat?: Record<string, unknown>;
25
+ }
26
+ export interface LLMProvider {
27
+ name: string;
28
+ chat(messages: LLMMessage[], options?: LLMOptions): Promise<LLMResponse>;
29
+ stream?(messages: LLMMessage[], options?: LLMOptions): AsyncIterable<LLMStreamChunk>;
30
+ }
31
+ export declare function openaiProvider(config: {
32
+ apiKey: string;
33
+ baseUrl?: string;
34
+ model?: string;
35
+ }): LLMProvider;
36
+ export declare function anthropicProvider(config: {
37
+ apiKey: string;
38
+ model?: string;
39
+ baseUrl?: string;
40
+ }): LLMProvider;
41
+ //# sourceMappingURL=llm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llm.d.ts","sourceRoot":"","sources":["../src/llm.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,WAAW,CAAC;IACtC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE;QACN,YAAY,EAAE,MAAM,CAAC;QACrB,gBAAgB,EAAE,MAAM,CAAC;QACzB,WAAW,EAAE,MAAM,CAAC;KACrB,GAAG,SAAS,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACnC;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC1C;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,QAAQ,EAAE,UAAU,EAAE,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IACzE,MAAM,CAAC,CACL,QAAQ,EAAE,UAAU,EAAE,EACtB,OAAO,CAAC,EAAE,UAAU,GACnB,aAAa,CAAC,cAAc,CAAC,CAAC;CAClC;AAMD,wBAAgB,cAAc,CAAC,MAAM,EAAE;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,WAAW,CA8Gd;AAMD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,GAAG,WAAW,CAyDd"}
package/dist/llm.js ADDED
@@ -0,0 +1,166 @@
1
+ // ---------------------------------------------------------------------------
2
+ // LLM provider adapter interface and built-in implementations
3
+ // ---------------------------------------------------------------------------
4
+ // ---------------------------------------------------------------------------
5
+ // OpenAI-compatible provider
6
+ // ---------------------------------------------------------------------------
7
+ export function openaiProvider(config) {
8
+ const baseUrl = config.baseUrl ?? "https://api.openai.com/v1";
9
+ const defaultModel = config.model ?? "gpt-4o";
10
+ return {
11
+ name: "openai",
12
+ async chat(messages, options) {
13
+ const body = {
14
+ model: options?.model ?? defaultModel,
15
+ messages: options?.systemPrompt
16
+ ? [{ role: "system", content: options.systemPrompt }, ...messages]
17
+ : messages,
18
+ };
19
+ if (options?.temperature !== undefined)
20
+ body["temperature"] = options.temperature;
21
+ if (options?.maxTokens !== undefined)
22
+ body["max_tokens"] = options.maxTokens;
23
+ if (options?.responseFormat)
24
+ body["response_format"] = {
25
+ type: "json_schema",
26
+ json_schema: {
27
+ schema: options.responseFormat,
28
+ name: "response",
29
+ strict: true,
30
+ },
31
+ };
32
+ const res = await fetch(`${baseUrl}/chat/completions`, {
33
+ method: "POST",
34
+ headers: {
35
+ Authorization: `Bearer ${config.apiKey}`,
36
+ "Content-Type": "application/json",
37
+ },
38
+ body: JSON.stringify(body),
39
+ });
40
+ if (!res.ok)
41
+ throw new Error(`LLM error ${res.status}: ${await res.text()}`);
42
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
43
+ const data = (await res.json());
44
+ return {
45
+ content: data.choices?.[0]?.message?.content ?? "",
46
+ model: data.model ?? defaultModel,
47
+ usage: data.usage
48
+ ? {
49
+ promptTokens: data.usage.prompt_tokens,
50
+ completionTokens: data.usage.completion_tokens,
51
+ totalTokens: data.usage.total_tokens,
52
+ }
53
+ : undefined,
54
+ finishReason: data.choices?.[0]?.finish_reason,
55
+ };
56
+ },
57
+ async *stream(messages, options) {
58
+ const body = {
59
+ model: options?.model ?? defaultModel,
60
+ messages: options?.systemPrompt
61
+ ? [{ role: "system", content: options.systemPrompt }, ...messages]
62
+ : messages,
63
+ stream: true,
64
+ };
65
+ if (options?.temperature !== undefined)
66
+ body["temperature"] = options.temperature;
67
+ if (options?.maxTokens !== undefined)
68
+ body["max_tokens"] = options.maxTokens;
69
+ const res = await fetch(`${baseUrl}/chat/completions`, {
70
+ method: "POST",
71
+ headers: {
72
+ Authorization: `Bearer ${config.apiKey}`,
73
+ "Content-Type": "application/json",
74
+ },
75
+ body: JSON.stringify(body),
76
+ });
77
+ if (!res.ok)
78
+ throw new Error(`LLM error ${res.status}`);
79
+ if (!res.body)
80
+ throw new Error("No body");
81
+ const reader = res.body.getReader();
82
+ const decoder = new TextDecoder();
83
+ let buf = "";
84
+ while (true) {
85
+ const { done, value } = await reader.read();
86
+ if (done)
87
+ break;
88
+ buf += decoder.decode(value, { stream: true });
89
+ const lines = buf.split("\n");
90
+ buf = lines.pop() ?? "";
91
+ for (const line of lines) {
92
+ if (!line.startsWith("data: "))
93
+ continue;
94
+ const d = line.slice(6).trim();
95
+ if (d === "[DONE]") {
96
+ yield { content: "", done: true };
97
+ return;
98
+ }
99
+ try {
100
+ const p = JSON.parse(d);
101
+ const c = p.choices?.[0]?.delta?.content ?? "";
102
+ if (c)
103
+ yield { content: c, done: false };
104
+ }
105
+ catch {
106
+ // skip malformed chunks
107
+ }
108
+ }
109
+ }
110
+ yield { content: "", done: true };
111
+ },
112
+ };
113
+ }
114
+ // ---------------------------------------------------------------------------
115
+ // Anthropic provider
116
+ // ---------------------------------------------------------------------------
117
+ export function anthropicProvider(config) {
118
+ const baseUrl = config.baseUrl ?? "https://api.anthropic.com/v1";
119
+ const defaultModel = config.model ?? "claude-sonnet-4-20250514";
120
+ return {
121
+ name: "anthropic",
122
+ async chat(messages, options) {
123
+ const sys = options?.systemPrompt ??
124
+ messages.find((m) => m.role === "system")?.content;
125
+ const msgs = messages.filter((m) => m.role !== "system");
126
+ const body = {
127
+ model: options?.model ?? defaultModel,
128
+ messages: msgs,
129
+ max_tokens: options?.maxTokens ?? 4096,
130
+ };
131
+ if (sys)
132
+ body["system"] = sys;
133
+ if (options?.temperature !== undefined)
134
+ body["temperature"] = options.temperature;
135
+ const res = await fetch(`${baseUrl}/messages`, {
136
+ method: "POST",
137
+ headers: {
138
+ "x-api-key": config.apiKey,
139
+ "anthropic-version": "2023-06-01",
140
+ "Content-Type": "application/json",
141
+ },
142
+ body: JSON.stringify(body),
143
+ });
144
+ if (!res.ok)
145
+ throw new Error(`Anthropic error ${res.status}: ${await res.text()}`);
146
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
147
+ const data = (await res.json());
148
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
149
+ const text = data.content?.find((b) => b.type === "text")?.text ?? "";
150
+ return {
151
+ content: text,
152
+ model: data.model ?? defaultModel,
153
+ usage: data.usage
154
+ ? {
155
+ promptTokens: data.usage.input_tokens,
156
+ completionTokens: data.usage.output_tokens,
157
+ totalTokens: (data.usage.input_tokens ?? 0) +
158
+ (data.usage.output_tokens ?? 0),
159
+ }
160
+ : undefined,
161
+ finishReason: data.stop_reason,
162
+ };
163
+ },
164
+ };
165
+ }
166
+ //# sourceMappingURL=llm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llm.js","sourceRoot":"","sources":["../src/llm.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * MCP Client — connect to external MCP servers and consume their tools.
3
+ *
4
+ * Uses the official `@modelcontextprotocol/sdk` Client and
5
+ * StreamableHTTPClientTransport for spec-compliant communication.
6
+ * Falls back to a raw JSON-RPC 2.0 implementation when the SDK
7
+ * transport encounters issues (e.g. the remote server does not
8
+ * support Streamable HTTP).
9
+ */
10
+ /** Options for connecting to a remote MCP server. */
11
+ export interface McpClientOptions {
12
+ /** MCP server URL (Streamable HTTP endpoint). */
13
+ url: string;
14
+ /** Optional authorization header value (e.g. "Bearer <token>"). */
15
+ authorization?: string;
16
+ /** Client name for identification during the MCP handshake. */
17
+ clientName?: string;
18
+ }
19
+ /** A tool exposed by a remote MCP server. */
20
+ export interface McpTool {
21
+ name: string;
22
+ description?: string | undefined;
23
+ inputSchema?: Record<string, unknown> | undefined;
24
+ }
25
+ /** A connected MCP client that can list and invoke remote tools. */
26
+ export interface McpClient {
27
+ /** List available tools on the remote server. */
28
+ listTools(): Promise<McpTool[]>;
29
+ /** Call a tool by name with optional arguments. */
30
+ callTool(name: string, args?: Record<string, unknown>): Promise<unknown>;
31
+ /** Close the connection. */
32
+ close(): Promise<void>;
33
+ }
34
+ /**
35
+ * Create an MCP client connected to a remote server.
36
+ *
37
+ * Attempts to connect using the official SDK `Client` +
38
+ * `StreamableHTTPClientTransport` first. Falls back to a raw JSON-RPC 2.0
39
+ * implementation if the SDK transport fails (e.g. unsupported server).
40
+ *
41
+ * @param options - Connection options (URL, auth, client name).
42
+ * @returns A connected `McpClient` ready to list and call tools.
43
+ */
44
+ export declare function createMcpClient(options: McpClientOptions): Promise<McpClient>;
45
+ //# sourceMappingURL=mcp-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-client.d.ts","sourceRoot":"","sources":["../src/mcp-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAUH,qDAAqD;AACrD,MAAM,WAAW,gBAAgB;IAC/B,iDAAiD;IACjD,GAAG,EAAE,MAAM,CAAC;IACZ,mEAAmE;IACnE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,+DAA+D;IAC/D,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,6CAA6C;AAC7C,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;CACnD;AAED,oEAAoE;AACpE,MAAM,WAAW,SAAS;IACxB,iDAAiD;IACjD,SAAS,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAChC,mDAAmD;IACnD,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACzE,4BAA4B;IAC5B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAyUD;;;;;;;;;GASG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,SAAS,CAAC,CAuCpB"}