@galaxy-stack/ai-coder-core 0.1.0 → 0.3.0-alpha.10
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.
- package/CHANGELOG.d/2026-09-19-advisory-guard-policy.md +25 -0
- package/CHANGELOG.d/2026-09-19-research-citation-parsing.md +16 -0
- package/CHANGELOG.d/2026-09-19-research-rejection-evidence.md +15 -0
- package/CHANGELOG.d/2026-09-19-test-journal-reporter.md +8 -0
- package/CHANGELOG.d/2026-09-21-evidence-missing-remediation.md +15 -0
- package/CHANGELOG.d/2026-09-21-observation-nudge-context.md +12 -0
- package/CHANGELOG.d/2026-09-22-model-retry-budget.md +18 -0
- package/CHANGELOG.d/2026-09-22-no-progress-recovery-turn.md +19 -0
- package/CHANGELOG.d/2026-09-23-agent-platform.md +5 -0
- package/CHANGELOG.d/2026-09-23-conservative-output-reserve.md +16 -0
- package/CHANGELOG.d/2026-09-24-approval-workspace-review.md +7 -0
- package/CHANGELOG.d/2026-09-24-incremental-ollama.md +5 -0
- package/CHANGELOG.d/2026-09-25-tail-anchored-bounding.md +5 -0
- package/CHANGELOG.d/2026-09-26-default-model-deepseek.md +8 -0
- package/CHANGELOG.d/README.md +16 -0
- package/CHANGELOG.md +166 -0
- package/README.md +119 -8
- package/dist/adapters/node/config/manual-provider-config.d.ts +19 -0
- package/dist/adapters/node/config/manual-provider-config.d.ts.map +1 -0
- package/dist/adapters/node/config/manual-provider-config.js +91 -0
- package/dist/adapters/node/config/manual-provider-config.js.map +1 -0
- package/dist/adapters/node/host/command-containment.d.ts +45 -0
- package/dist/adapters/node/host/command-containment.d.ts.map +1 -0
- package/dist/adapters/node/host/command-containment.js +580 -0
- package/dist/adapters/node/host/command-containment.js.map +1 -0
- package/dist/adapters/node/host/content-hash.d.ts +2 -0
- package/dist/adapters/node/host/content-hash.d.ts.map +1 -0
- package/dist/adapters/node/host/content-hash.js +5 -0
- package/dist/adapters/node/host/content-hash.js.map +1 -0
- package/dist/adapters/node/host/file-run-store.d.ts +29 -0
- package/dist/adapters/node/host/file-run-store.d.ts.map +1 -0
- package/dist/adapters/node/host/file-run-store.js +94 -0
- package/dist/adapters/node/host/file-run-store.js.map +1 -0
- package/dist/adapters/node/host/host-environment.d.ts +9 -0
- package/dist/adapters/node/host/host-environment.d.ts.map +1 -0
- package/dist/adapters/node/host/host-environment.js +29 -0
- package/dist/adapters/node/host/host-environment.js.map +1 -0
- package/dist/adapters/node/host/node-command-port.d.ts +21 -0
- package/dist/adapters/node/host/node-command-port.d.ts.map +1 -0
- package/dist/adapters/node/host/node-command-port.js +281 -0
- package/dist/adapters/node/host/node-command-port.js.map +1 -0
- package/dist/adapters/node/host/node-workspace-evidence-verifier.d.ts +22 -0
- package/dist/adapters/node/host/node-workspace-evidence-verifier.d.ts.map +1 -0
- package/dist/adapters/node/host/node-workspace-evidence-verifier.js +384 -0
- package/dist/adapters/node/host/node-workspace-evidence-verifier.js.map +1 -0
- package/dist/adapters/node/host/node-workspace-port.d.ts +87 -0
- package/dist/adapters/node/host/node-workspace-port.d.ts.map +1 -0
- package/dist/adapters/node/host/node-workspace-port.js +860 -0
- package/dist/adapters/node/host/node-workspace-port.js.map +1 -0
- package/dist/adapters/node/host/node-workspace-snapshot.d.ts +61 -0
- package/dist/adapters/node/host/node-workspace-snapshot.d.ts.map +1 -0
- package/dist/adapters/node/host/node-workspace-snapshot.js +282 -0
- package/dist/adapters/node/host/node-workspace-snapshot.js.map +1 -0
- package/dist/adapters/node/host/path-scope.d.ts +17 -0
- package/dist/adapters/node/host/path-scope.d.ts.map +1 -0
- package/dist/adapters/node/host/path-scope.js +89 -0
- package/dist/adapters/node/host/path-scope.js.map +1 -0
- package/dist/adapters/node/host/project-tools.d.ts +42 -0
- package/dist/adapters/node/host/project-tools.d.ts.map +1 -0
- package/dist/adapters/node/host/project-tools.js +362 -0
- package/dist/adapters/node/host/project-tools.js.map +1 -0
- package/dist/adapters/node/mcp/mcp-client.d.ts +206 -0
- package/dist/adapters/node/mcp/mcp-client.d.ts.map +1 -0
- package/dist/adapters/node/mcp/mcp-client.js +128 -0
- package/dist/adapters/node/mcp/mcp-client.js.map +1 -0
- package/dist/adapters/node/mcp/oauth-provider.d.ts +39 -0
- package/dist/adapters/node/mcp/oauth-provider.d.ts.map +1 -0
- package/dist/adapters/node/mcp/oauth-provider.js +168 -0
- package/dist/adapters/node/mcp/oauth-provider.js.map +1 -0
- package/dist/adapters/node/memory/sqlite-memory.d.ts +22 -0
- package/dist/adapters/node/memory/sqlite-memory.d.ts.map +1 -0
- package/dist/adapters/node/memory/sqlite-memory.js +83 -0
- package/dist/adapters/node/memory/sqlite-memory.js.map +1 -0
- package/dist/adapters/node/provider/ollama-chat-stream.d.ts +17 -0
- package/dist/adapters/node/provider/ollama-chat-stream.d.ts.map +1 -0
- package/dist/adapters/node/provider/ollama-chat-stream.js +176 -0
- package/dist/adapters/node/provider/ollama-chat-stream.js.map +1 -0
- package/dist/adapters/node/provider/ollama-coding-model.d.ts +89 -0
- package/dist/adapters/node/provider/ollama-coding-model.d.ts.map +1 -0
- package/dist/adapters/node/provider/ollama-coding-model.js +464 -0
- package/dist/adapters/node/provider/ollama-coding-model.js.map +1 -0
- package/dist/adapters/node/provider/ollama-research-port.d.ts +32 -0
- package/dist/adapters/node/provider/ollama-research-port.d.ts.map +1 -0
- package/dist/adapters/node/provider/ollama-research-port.js +346 -0
- package/dist/adapters/node/provider/ollama-research-port.js.map +1 -0
- package/dist/adapters/node/skills/directory-skills.d.ts +12 -0
- package/dist/adapters/node/skills/directory-skills.d.ts.map +1 -0
- package/dist/adapters/node/skills/directory-skills.js +90 -0
- package/dist/adapters/node/skills/directory-skills.js.map +1 -0
- package/dist/adapters/node/tools/tool-executor.d.ts +91 -0
- package/dist/adapters/node/tools/tool-executor.d.ts.map +1 -0
- package/dist/adapters/node/tools/tool-executor.js +948 -0
- package/dist/adapters/node/tools/tool-executor.js.map +1 -0
- package/dist/adapters/node/tools/workspace-review.d.ts +13 -0
- package/dist/adapters/node/tools/workspace-review.d.ts.map +1 -0
- package/dist/adapters/node/tools/workspace-review.js +81 -0
- package/dist/adapters/node/tools/workspace-review.js.map +1 -0
- package/dist/agent/index.d.ts +79 -0
- package/dist/agent/index.d.ts.map +1 -0
- package/dist/agent/index.js +97 -0
- package/dist/agent/index.js.map +1 -0
- package/dist/approval/approval-policy.d.ts.map +1 -1
- package/dist/approval/approval-policy.js +4 -1
- package/dist/approval/approval-policy.js.map +1 -1
- package/dist/context/checkpoint.d.ts +5 -0
- package/dist/context/checkpoint.d.ts.map +1 -1
- package/dist/context/checkpoint.js +36 -4
- package/dist/context/checkpoint.js.map +1 -1
- package/dist/context/context-manager.d.ts.map +1 -1
- package/dist/context/context-manager.js +21 -8
- package/dist/context/context-manager.js.map +1 -1
- package/dist/context/context-profile.d.ts +1 -1
- package/dist/context/context-profile.js +2 -2
- package/dist/context/tool-output.d.ts.map +1 -1
- package/dist/context/tool-output.js +23 -4
- package/dist/context/tool-output.js.map +1 -1
- package/dist/prompt/prompt-assembler.d.ts +2 -1
- package/dist/prompt/prompt-assembler.d.ts.map +1 -1
- package/dist/prompt/prompt-assembler.js +40 -3
- package/dist/prompt/prompt-assembler.js.map +1 -1
- package/dist/runtime/completion-gate.d.ts +1 -1
- package/dist/runtime/completion-gate.d.ts.map +1 -1
- package/dist/runtime/completion-gate.js +12 -0
- package/dist/runtime/completion-gate.js.map +1 -1
- package/dist/runtime/index.d.ts +1 -0
- package/dist/runtime/index.d.ts.map +1 -1
- package/dist/runtime/index.js +1 -0
- package/dist/runtime/index.js.map +1 -1
- package/dist/runtime/research-citations.d.ts +15 -0
- package/dist/runtime/research-citations.d.ts.map +1 -0
- package/dist/runtime/research-citations.js +49 -0
- package/dist/runtime/research-citations.js.map +1 -0
- package/dist/runtime/run-controller.d.ts +6 -0
- package/dist/runtime/run-controller.d.ts.map +1 -1
- package/dist/runtime/run-controller.js +276 -65
- package/dist/runtime/run-controller.js.map +1 -1
- package/dist/runtime/runtime-types.d.ts +30 -0
- package/dist/runtime/runtime-types.d.ts.map +1 -1
- package/dist/tools/settings-types.js +1 -1
- package/dist/tools/settings-types.js.map +1 -1
- package/dist/tools/tool-registry.js +1 -1
- package/dist/tools/tool-registry.js.map +1 -1
- package/docs/AGENT_PLATFORM.md +91 -0
- package/docs/ARCHITECTURE.md +13 -2
- package/docs/GALAXY_AGENT_PLATFORM_PLAN.md +176 -0
- package/docs/GALAXY_AGENT_PLATFORM_TODO.md +181 -0
- package/docs/HOST_CONFORMANCE.md +38 -0
- package/docs/PROMPT_CONTRACT.md +9 -0
- package/package.json +25 -9
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { AjvJsonSchemaValidator } from "@modelcontextprotocol/sdk/validation/ajv";
|
|
2
|
+
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
3
|
+
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
|
|
4
|
+
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
|
|
5
|
+
import { UnauthorizedError } from "@modelcontextprotocol/sdk/client/auth.js";
|
|
6
|
+
import { createHash } from "node:crypto";
|
|
7
|
+
import { FileOAuthProvider } from "./oauth-provider.js";
|
|
8
|
+
/** Server annotations are display hints, never authorization or verified runtime effects. */
|
|
9
|
+
export class McpAgentClient {
|
|
10
|
+
client;
|
|
11
|
+
name;
|
|
12
|
+
timeout;
|
|
13
|
+
constructor(client, name, timeout) {
|
|
14
|
+
this.client = client;
|
|
15
|
+
this.name = name;
|
|
16
|
+
this.timeout = timeout;
|
|
17
|
+
}
|
|
18
|
+
static async connect(config, signal, options) {
|
|
19
|
+
if (!/^[a-zA-Z0-9_-]{1,48}$/.test(config.name))
|
|
20
|
+
throw new Error("Invalid MCP server name.");
|
|
21
|
+
const timeout = Math.max(100, Math.min(120000, config.timeoutMs ?? 30000));
|
|
22
|
+
let provider;
|
|
23
|
+
if (config.transport === "http") {
|
|
24
|
+
const url = new URL(config.url);
|
|
25
|
+
if (url.username || url.password || !["http:", "https:"].includes(url.protocol))
|
|
26
|
+
throw new Error("MCP requires an HTTP(S) URL without embedded credentials.");
|
|
27
|
+
if (config.auth === "oauth")
|
|
28
|
+
provider = options?.oauthProviderFactory?.(config.url) ?? new FileOAuthProvider(config.url, options?.stateDir);
|
|
29
|
+
}
|
|
30
|
+
const initial = await this.open(config, timeout, signal, provider);
|
|
31
|
+
if (initial)
|
|
32
|
+
return initial;
|
|
33
|
+
if (config.transport !== "http" || !provider)
|
|
34
|
+
throw new Error(`MCP server ${config.name} requires authentication. Configure "auth": "oauth" and run blackhole mcp login.`);
|
|
35
|
+
return this.login(config, timeout, signal, provider);
|
|
36
|
+
}
|
|
37
|
+
static async open(config, timeout, signal, provider) {
|
|
38
|
+
const client = new Client({ name: "galaxy-agent", version: "0.1.0" });
|
|
39
|
+
const transport = config.transport === "stdio"
|
|
40
|
+
? new StdioClientTransport({ command: config.command, args: config.args ?? [], ...(config.env ? { env: config.env } : {}), ...(config.cwd ? { cwd: config.cwd } : {}), stderr: "pipe" })
|
|
41
|
+
: new StreamableHTTPClientTransport(new URL(config.url), { requestInit: { headers: config.headers ?? {} }, ...(provider ? { authProvider: provider } : {}) });
|
|
42
|
+
try {
|
|
43
|
+
// SDK transport optional sessionId typing predates exactOptionalPropertyTypes.
|
|
44
|
+
if (transport instanceof StdioClientTransport)
|
|
45
|
+
transport.stderr?.on("data", () => { });
|
|
46
|
+
await client.connect(transport, { timeout, ...(signal ? { signal } : {}) });
|
|
47
|
+
// Drain stderr to prevent a verbose local server blocking on a full pipe.
|
|
48
|
+
if (transport instanceof StdioClientTransport)
|
|
49
|
+
transport.stderr?.on("data", () => { });
|
|
50
|
+
return new McpAgentClient(client, config.name, timeout);
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
await transport.close().catch(() => { });
|
|
54
|
+
if (provider && error instanceof UnauthorizedError)
|
|
55
|
+
return undefined;
|
|
56
|
+
throw error;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
/** OAuth authorization-code completion: browser login, token exchange, reconnect. */
|
|
60
|
+
static async login(config, timeout, signal, provider) {
|
|
61
|
+
if (signal?.aborted)
|
|
62
|
+
throw new Error("OAuth login canceled.");
|
|
63
|
+
if (!provider.waitForAuthorizationCode)
|
|
64
|
+
throw new Error("OAuth provider does not support interactive login.");
|
|
65
|
+
const code = await Promise.race([provider.waitForAuthorizationCode(), this.abortPromise(signal)]);
|
|
66
|
+
const { auth } = await import("@modelcontextprotocol/sdk/client/auth.js");
|
|
67
|
+
const result = await auth(provider, { serverUrl: config.url, authorizationCode: code });
|
|
68
|
+
if (result !== "AUTHORIZED")
|
|
69
|
+
throw new Error("OAuth login did not complete.");
|
|
70
|
+
const client = await this.open(config, timeout, signal, provider);
|
|
71
|
+
if (!client)
|
|
72
|
+
throw new Error("OAuth login succeeded but the MCP server still refuses the connection.");
|
|
73
|
+
return client;
|
|
74
|
+
}
|
|
75
|
+
static abortPromise(signal) {
|
|
76
|
+
return new Promise((_, reject) => { if (signal?.aborted)
|
|
77
|
+
reject(new Error("OAuth login canceled."));
|
|
78
|
+
else
|
|
79
|
+
signal?.addEventListener("abort", () => reject(new Error("OAuth login canceled.")), { once: true }); });
|
|
80
|
+
}
|
|
81
|
+
async tools(signal) {
|
|
82
|
+
const tools = [];
|
|
83
|
+
const validator = new AjvJsonSchemaValidator();
|
|
84
|
+
let cursor;
|
|
85
|
+
const seen = new Set();
|
|
86
|
+
for (let page = 0; page < 32; page++) {
|
|
87
|
+
const result = await this.client.listTools(cursor ? { cursor } : {}, { timeout: this.timeout, ...(signal ? { signal } : {}) });
|
|
88
|
+
for (const tool of result.tools) {
|
|
89
|
+
if (tools.length >= 1000 || seen.has(tool.name))
|
|
90
|
+
throw new Error("MCP tool catalog is oversized or contains duplicate names.");
|
|
91
|
+
seen.add(tool.name);
|
|
92
|
+
if (JSON.stringify(tool.inputSchema).length > 65536)
|
|
93
|
+
throw new Error("MCP tool schema exceeds 64 KiB.");
|
|
94
|
+
const hash = createHash("sha256").update(`${this.name}\0${tool.name}`).digest("hex").slice(0, 12);
|
|
95
|
+
const name = `mcp_${this.name.slice(0, 16)}_${tool.name.replace(/[^a-zA-Z0-9_]/g, "_").slice(0, 24)}_${hash}`;
|
|
96
|
+
const validate = validator.getValidator(tool.inputSchema);
|
|
97
|
+
tools.push({
|
|
98
|
+
validateArguments: args => { const result = validate(args); return { valid: result.valid, errors: result.valid ? [] : [result.errorMessage] }; },
|
|
99
|
+
// A server's readOnlyHint opts its tool out of the host permission
|
|
100
|
+
// prompt (user-approved policy). Everything else still asks, and
|
|
101
|
+
// every result stays untrusted data with bounded output.
|
|
102
|
+
id: `mcp.${this.name}.${tool.name}`,
|
|
103
|
+
risk: tool.annotations?.readOnlyHint === true ? "read" : "external",
|
|
104
|
+
trust: "external",
|
|
105
|
+
definition: { type: "function", function: { name, description: (tool.description ?? tool.name).slice(0, 4096), parameters: tool.inputSchema } },
|
|
106
|
+
execute: async (args, context) => {
|
|
107
|
+
const result = await this.client.callTool({ name: tool.name, arguments: { ...args } }, undefined, { signal: context.signal, timeout: Math.max(1, Math.min(this.timeout, context.deadline - Date.now())) });
|
|
108
|
+
if (result.isError)
|
|
109
|
+
throw new Error(`MCP ${this.name}/${tool.name}: ${JSON.stringify(result.content).slice(0, 2048)}`);
|
|
110
|
+
return { server: this.name, tool: tool.name, trust: "external", result };
|
|
111
|
+
},
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
if (!result.nextCursor)
|
|
115
|
+
return tools;
|
|
116
|
+
if (result.nextCursor === cursor)
|
|
117
|
+
throw new Error("MCP pagination cursor did not advance.");
|
|
118
|
+
cursor = result.nextCursor;
|
|
119
|
+
}
|
|
120
|
+
throw new Error("MCP pagination limit reached.");
|
|
121
|
+
}
|
|
122
|
+
listResources(cursor) { return this.client.listResources(cursor ? { cursor } : {}, { timeout: this.timeout }); }
|
|
123
|
+
readResource(uri, signal) { return this.client.readResource({ uri }, { timeout: this.timeout, ...(signal ? { signal } : {}) }); }
|
|
124
|
+
listPrompts(cursor) { return this.client.listPrompts(cursor ? { cursor } : {}, { timeout: this.timeout }); }
|
|
125
|
+
getPrompt(name, args, signal) { return this.client.getPrompt({ name, arguments: args }, { timeout: this.timeout, ...(signal ? { signal } : {}) }); }
|
|
126
|
+
async close() { await this.client.close(); }
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=mcp-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-client.js","sourceRoot":"","sources":["../../../../src/adapters/node/mcp/mcp-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { OAuthClientProvider, OAuthDiscoveryState } from "@modelcontextprotocol/sdk/client/auth.js";
|
|
2
|
+
import type { OAuthClientInformation, OAuthClientInformationFull, OAuthClientInformationMixed, OAuthClientMetadata, OAuthTokens } from "@modelcontextprotocol/sdk/shared/auth.js";
|
|
3
|
+
/**
|
|
4
|
+
* OAuth client provider for remote MCP servers needing login: RFC 9728
|
|
5
|
+
* discovery, dynamic client registration, PKCE authorization code and refresh
|
|
6
|
+
* tokens. Credentials persist in one host-state JSON file with 0600
|
|
7
|
+
* permissions, keyed by server host. The localhost callback server starts in
|
|
8
|
+
* the constructor; every async provider method awaits that bind, and the SDK
|
|
9
|
+
* only reads the synchronous redirect getters after such a call, so the
|
|
10
|
+
* redirect URL is deterministic. Call close() to release the port.
|
|
11
|
+
*/
|
|
12
|
+
export declare class FileOAuthProvider implements OAuthClientProvider {
|
|
13
|
+
private readonly path;
|
|
14
|
+
private readonly key;
|
|
15
|
+
private readonly pending;
|
|
16
|
+
private listener;
|
|
17
|
+
private readonly ready;
|
|
18
|
+
constructor(serverUrl: string, stateDir?: string);
|
|
19
|
+
private handleCallback;
|
|
20
|
+
/** Releases the localhost callback port once the session or login ends. */
|
|
21
|
+
close(): Promise<void>;
|
|
22
|
+
get redirectUrl(): string;
|
|
23
|
+
get clientMetadata(): OAuthClientMetadata;
|
|
24
|
+
clientInformation(): Promise<OAuthClientInformationMixed | undefined>;
|
|
25
|
+
saveClientInformation(clientInformation: OAuthClientInformationFull | OAuthClientInformation): Promise<void>;
|
|
26
|
+
tokens(): Promise<OAuthTokens | undefined>;
|
|
27
|
+
saveTokens(tokens: OAuthTokens): Promise<void>;
|
|
28
|
+
redirectToAuthorization(authorizationUrl: URL): Promise<void>;
|
|
29
|
+
saveCodeVerifier(codeVerifier: string): Promise<void>;
|
|
30
|
+
codeVerifier(): Promise<string>;
|
|
31
|
+
saveDiscoveryState(state: OAuthDiscoveryState): Promise<void>;
|
|
32
|
+
discoveryState(): Promise<OAuthDiscoveryState | undefined>;
|
|
33
|
+
invalidateCredentials(scope: "all" | "client" | "tokens" | "verifier" | "discovery"): Promise<void>;
|
|
34
|
+
/** Authorization code captured by the localhost callback; rejects after auth errors. */
|
|
35
|
+
waitForAuthorizationCode(): Promise<string>;
|
|
36
|
+
static tokenFile(stateDir?: string): string;
|
|
37
|
+
static clear(stateDir: string | undefined, serverUrl: string): Promise<void>;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=oauth-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth-provider.d.ts","sourceRoot":"","sources":["../../../../src/adapters/node/mcp/oauth-provider.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,0CAA0C,CAAC;AACzG,OAAO,KAAK,EAAE,sBAAsB,EAAE,0BAA0B,EAAE,2BAA2B,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,0CAA0C,CAAC;AAgDlL;;;;;;;;GAQG;AACH,qBAAa,iBAAkB,YAAW,mBAAmB;IAC3D,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqC;IAC7D,OAAO,CAAC,QAAQ,CAAoE;IACpF,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAgB;gBAC1B,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM;IAgBhD,OAAO,CAAC,cAAc;IAUtB,2EAA2E;IACrE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAM5B,IAAI,WAAW,IAAI,MAAM,CAAgD;IACzE,IAAI,cAAc,IAAI,mBAAmB,CASxC;IACK,iBAAiB,IAAI,OAAO,CAAC,2BAA2B,GAAG,SAAS,CAAC;IACrE,qBAAqB,CAAC,iBAAiB,EAAE,0BAA0B,GAAG,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC;IAG5G,MAAM,IAAI,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC;IAC1C,UAAU,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAC9C,uBAAuB,CAAC,gBAAgB,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;IAK7D,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IACrD,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC;IAM/B,kBAAkB,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IAC7D,cAAc,IAAI,OAAO,CAAC,mBAAmB,GAAG,SAAS,CAAC;IAC1D,qBAAqB,CAAC,KAAK,EAAE,KAAK,GAAG,QAAQ,GAAG,QAAQ,GAAG,UAAU,GAAG,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAUzG,wFAAwF;IACxF,wBAAwB,IAAI,OAAO,CAAC,MAAM,CAAC;IAC3C,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM;WAC9B,KAAK,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAOnF"}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { chmod, mkdir, readFile, rename, unlink, writeFile } from "node:fs/promises";
|
|
2
|
+
import { createServer } from "node:http";
|
|
3
|
+
import { execFile } from "node:child_process";
|
|
4
|
+
import { homedir, tmpdir } from "node:os";
|
|
5
|
+
import { randomUUID } from "node:crypto";
|
|
6
|
+
import { isAbsolute, join } from "node:path";
|
|
7
|
+
function defer() {
|
|
8
|
+
let resolve;
|
|
9
|
+
let reject;
|
|
10
|
+
const promise = new Promise((res, rej) => { resolve = res; reject = rej; });
|
|
11
|
+
return { promise, resolve, reject };
|
|
12
|
+
}
|
|
13
|
+
const EMPTY_STORE = { clients: {}, tokens: {}, verifiers: {}, discovery: {} };
|
|
14
|
+
function sanitizeKey(value) { return value.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 96); }
|
|
15
|
+
async function readStore(path) {
|
|
16
|
+
try {
|
|
17
|
+
const parsed = JSON.parse(await readFile(path, "utf8"));
|
|
18
|
+
if (parsed?.version !== 1)
|
|
19
|
+
return { version: 1, ...EMPTY_STORE };
|
|
20
|
+
return { version: 1, clients: parsed.clients ?? {}, tokens: parsed.tokens ?? {}, verifiers: parsed.verifiers ?? {}, discovery: parsed.discovery ?? {} };
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return { version: 1, ...EMPTY_STORE };
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
async function writeStore(path, store) {
|
|
27
|
+
await mkdir(join(path, ".."), { recursive: true, mode: 0o700 });
|
|
28
|
+
const temp = join(tmpdir(), `galaxy-oauth-${randomUUID()}.json`);
|
|
29
|
+
await writeFile(temp, JSON.stringify(store, null, 2), { encoding: "utf8", mode: 0o600 });
|
|
30
|
+
await chmod(temp, 0o600);
|
|
31
|
+
await rename(temp, path);
|
|
32
|
+
await chmod(path, 0o600).catch(() => { });
|
|
33
|
+
}
|
|
34
|
+
function openBrowser(url) {
|
|
35
|
+
const command = process.platform === "darwin" ? "open" : process.platform === "win32" ? "cmd" : "xdg-open";
|
|
36
|
+
const args = process.platform === "win32" ? ["/c", "start", "", url] : [url];
|
|
37
|
+
execFile(command, args, { timeout: 5000 }, error => { if (error)
|
|
38
|
+
process.stderr.write(`Galaxy MCP: mở URL này để đăng nhập:\n${url}\n`); });
|
|
39
|
+
}
|
|
40
|
+
function keyFor(serverUrl) { return sanitizeKey(new URL(serverUrl).host); }
|
|
41
|
+
/**
|
|
42
|
+
* OAuth client provider for remote MCP servers needing login: RFC 9728
|
|
43
|
+
* discovery, dynamic client registration, PKCE authorization code and refresh
|
|
44
|
+
* tokens. Credentials persist in one host-state JSON file with 0600
|
|
45
|
+
* permissions, keyed by server host. The localhost callback server starts in
|
|
46
|
+
* the constructor; every async provider method awaits that bind, and the SDK
|
|
47
|
+
* only reads the synchronous redirect getters after such a call, so the
|
|
48
|
+
* redirect URL is deterministic. Call close() to release the port.
|
|
49
|
+
*/
|
|
50
|
+
export class FileOAuthProvider {
|
|
51
|
+
path;
|
|
52
|
+
key;
|
|
53
|
+
pending = defer();
|
|
54
|
+
listener;
|
|
55
|
+
ready;
|
|
56
|
+
constructor(serverUrl, stateDir) {
|
|
57
|
+
this.key = keyFor(serverUrl);
|
|
58
|
+
const base = stateDir && isAbsolute(stateDir) ? stateDir : join(homedir(), ".galaxy", "agent");
|
|
59
|
+
this.path = join(base, "mcp-auth.json");
|
|
60
|
+
this.ready = new Promise(resolve => {
|
|
61
|
+
const server = createServer((request, response) => this.handleCallback(request, response));
|
|
62
|
+
server.on("error", error => { this.pending.reject(new Error(`OAuth callback failed: ${error.message}`)); resolve(); });
|
|
63
|
+
server.listen(0, "127.0.0.1", () => {
|
|
64
|
+
const address = server.address();
|
|
65
|
+
if (!address || typeof address === "string") {
|
|
66
|
+
this.pending.reject(new Error("OAuth callback port unavailable."));
|
|
67
|
+
resolve();
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
this.listener = { server, url: new URL(`http://127.0.0.1:${address.port}/callback`) };
|
|
71
|
+
resolve();
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
this.ready.catch(() => { });
|
|
75
|
+
}
|
|
76
|
+
handleCallback(request, response) {
|
|
77
|
+
const url = new URL(request.url ?? "/", "http://127.0.0.1");
|
|
78
|
+
const finish = (status, body) => { response.writeHead(status, { "content-type": "text/plain" }); response.end(body); };
|
|
79
|
+
const oauthError = url.searchParams.get("error");
|
|
80
|
+
const oauthCode = url.searchParams.get("code");
|
|
81
|
+
if (oauthError) {
|
|
82
|
+
finish(400, `Authorization failed: ${oauthError}`);
|
|
83
|
+
this.pending.reject(new Error(`OAuth: ${oauthError}`));
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
if (!oauthCode) {
|
|
87
|
+
finish(400, "Missing authorization code.");
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
finish(200, "Galaxy MCP authorization complete. You can close this tab.");
|
|
91
|
+
this.pending.resolve(oauthCode);
|
|
92
|
+
}
|
|
93
|
+
/** Releases the localhost callback port once the session or login ends. */
|
|
94
|
+
async close() {
|
|
95
|
+
await this.ready.catch(() => { });
|
|
96
|
+
if (!this.listener)
|
|
97
|
+
return;
|
|
98
|
+
const { server } = this.listener;
|
|
99
|
+
this.listener = undefined;
|
|
100
|
+
await new Promise(resolve => server.close(() => resolve()));
|
|
101
|
+
}
|
|
102
|
+
get redirectUrl() { return this.listener?.url.toString() ?? ""; }
|
|
103
|
+
get clientMetadata() {
|
|
104
|
+
return {
|
|
105
|
+
client_name: "Galaxy Code",
|
|
106
|
+
client_uri: "https://github.com/galaxy-blackhole/galaxy-code",
|
|
107
|
+
grant_types: ["authorization_code", "refresh_token"],
|
|
108
|
+
response_types: ["code"],
|
|
109
|
+
token_endpoint_auth_method: "none",
|
|
110
|
+
redirect_uris: [this.redirectUrl],
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
async clientInformation() { await this.ready; return (await readStore(this.path)).clients[this.key]; }
|
|
114
|
+
async saveClientInformation(clientInformation) {
|
|
115
|
+
await this.ready;
|
|
116
|
+
const store = await readStore(this.path);
|
|
117
|
+
store.clients[this.key] = clientInformation;
|
|
118
|
+
await writeStore(this.path, store);
|
|
119
|
+
}
|
|
120
|
+
async tokens() { await this.ready; return (await readStore(this.path)).tokens[this.key]; }
|
|
121
|
+
async saveTokens(tokens) { await this.ready; const store = await readStore(this.path); store.tokens[this.key] = tokens; await writeStore(this.path, store); }
|
|
122
|
+
async redirectToAuthorization(authorizationUrl) {
|
|
123
|
+
await this.ready;
|
|
124
|
+
process.stderr.write(`Galaxy MCP: đang chờ đăng nhập trình duyệt cho ${authorizationUrl.host}…\n`);
|
|
125
|
+
openBrowser(authorizationUrl.toString());
|
|
126
|
+
}
|
|
127
|
+
async saveCodeVerifier(codeVerifier) { await this.ready; const store = await readStore(this.path); store.verifiers[this.key] = codeVerifier; await writeStore(this.path, store); }
|
|
128
|
+
async codeVerifier() {
|
|
129
|
+
await this.ready;
|
|
130
|
+
const verifier = (await readStore(this.path)).verifiers[this.key];
|
|
131
|
+
if (!verifier)
|
|
132
|
+
throw new Error("OAuth code verifier missing; restart the login flow.");
|
|
133
|
+
return verifier;
|
|
134
|
+
}
|
|
135
|
+
async saveDiscoveryState(state) { await this.ready; const store = await readStore(this.path); store.discovery[this.key] = state; await writeStore(this.path, store); }
|
|
136
|
+
async discoveryState() { await this.ready; return (await readStore(this.path)).discovery[this.key]; }
|
|
137
|
+
async invalidateCredentials(scope) {
|
|
138
|
+
await this.ready;
|
|
139
|
+
if (scope === "all") {
|
|
140
|
+
await unlink(this.path).catch(() => { });
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
const store = await readStore(this.path);
|
|
144
|
+
if (scope === "client")
|
|
145
|
+
delete store.clients[this.key];
|
|
146
|
+
if (scope === "tokens")
|
|
147
|
+
delete store.tokens[this.key];
|
|
148
|
+
if (scope === "verifier")
|
|
149
|
+
delete store.verifiers[this.key];
|
|
150
|
+
if (scope === "discovery")
|
|
151
|
+
delete store.discovery[this.key];
|
|
152
|
+
await writeStore(this.path, store);
|
|
153
|
+
}
|
|
154
|
+
/** Authorization code captured by the localhost callback; rejects after auth errors. */
|
|
155
|
+
waitForAuthorizationCode() { return this.ready.then(() => this.pending.promise); }
|
|
156
|
+
static tokenFile(stateDir) { return join(stateDir && isAbsolute(stateDir) ? stateDir : join(homedir(), ".galaxy", "agent"), "mcp-auth.json"); }
|
|
157
|
+
static async clear(stateDir, serverUrl) {
|
|
158
|
+
const path = join(stateDir && isAbsolute(stateDir) ? stateDir : join(homedir(), ".galaxy", "agent"), "mcp-auth.json");
|
|
159
|
+
const key = keyFor(serverUrl);
|
|
160
|
+
const store = await readStore(path);
|
|
161
|
+
delete store.tokens[key];
|
|
162
|
+
delete store.clients[key];
|
|
163
|
+
delete store.verifiers[key];
|
|
164
|
+
delete store.discovery[key];
|
|
165
|
+
await writeStore(path, store);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
//# sourceMappingURL=oauth-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth-provider.js","sourceRoot":"","sources":["../../../../src/adapters/node/mcp/oauth-provider.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { AgentMemoryPort, MemoryRecord } from "../../../agent/index.js";
|
|
2
|
+
/** Optional Node >=22.13 adapter. No database or native imports occur from the core root. */
|
|
3
|
+
export declare class SqliteAgentMemory implements AgentMemoryPort {
|
|
4
|
+
private readonly scope;
|
|
5
|
+
private readonly db;
|
|
6
|
+
constructor(path: string, scope: string);
|
|
7
|
+
search(query: string, options?: {
|
|
8
|
+
limit?: number;
|
|
9
|
+
includeCandidates?: boolean;
|
|
10
|
+
}): Promise<readonly MemoryRecord[]>;
|
|
11
|
+
remember(input: {
|
|
12
|
+
key: string;
|
|
13
|
+
content: string;
|
|
14
|
+
source: string;
|
|
15
|
+
trust?: "candidate" | "confirmed";
|
|
16
|
+
expectedRevision?: number;
|
|
17
|
+
}): Promise<MemoryRecord>;
|
|
18
|
+
history(key: string): Promise<readonly MemoryRecord[]>;
|
|
19
|
+
forget(key: string): Promise<number>;
|
|
20
|
+
close(): void;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=sqlite-memory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite-memory.d.ts","sourceRoot":"","sources":["../../../../src/adapters/node/memory/sqlite-memory.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAK7E,6FAA6F;AAC7F,qBAAa,iBAAkB,YAAW,eAAe;IAE7B,OAAO,CAAC,QAAQ,CAAC,KAAK;IADhD,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAe;gBACtB,IAAI,EAAE,MAAM,EAAmB,KAAK,EAAE,MAAM;IAgBlD,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,iBAAiB,CAAC,EAAE,OAAO,CAAA;KAAO,GAAG,OAAO,CAAC,SAAS,YAAY,EAAE,CAAC;IAQtH,QAAQ,CAAC,KAAK,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,WAAW,GAAG,WAAW,CAAC;QAAC,gBAAgB,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,YAAY,CAAC;IAmBtJ,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,YAAY,EAAE,CAAC;IAGtD,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAM1C,KAAK,IAAI,IAAI;CACd"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { DatabaseSync } from "node:sqlite";
|
|
2
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
3
|
+
import { mkdirSync, chmodSync } from "node:fs";
|
|
4
|
+
import { dirname } from "node:path";
|
|
5
|
+
function record(row) {
|
|
6
|
+
return { id: String(row.id), key: String(row.memory_key), scope: String(row.scope), revision: Number(row.revision), content: String(row.content), source: String(row.source), contentHash: String(row.content_hash), status: row.status, trust: row.trust, updatedAt: String(row.updated_at) };
|
|
7
|
+
}
|
|
8
|
+
/** Optional Node >=22.13 adapter. No database or native imports occur from the core root. */
|
|
9
|
+
export class SqliteAgentMemory {
|
|
10
|
+
scope;
|
|
11
|
+
db;
|
|
12
|
+
constructor(path, scope) {
|
|
13
|
+
this.scope = scope;
|
|
14
|
+
if (!scope || scope.length > 1024)
|
|
15
|
+
throw new Error("A bounded host-owned memory scope is required.");
|
|
16
|
+
if (path !== ":memory:")
|
|
17
|
+
mkdirSync(dirname(path), { recursive: true, mode: 0o700 });
|
|
18
|
+
this.db = new DatabaseSync(path);
|
|
19
|
+
if (path !== ":memory:")
|
|
20
|
+
chmodSync(path, 0o600);
|
|
21
|
+
this.db.exec(`PRAGMA busy_timeout=5000; PRAGMA journal_mode=WAL; PRAGMA secure_delete=ON;
|
|
22
|
+
CREATE TABLE IF NOT EXISTS agent_memory_schema(version INTEGER PRIMARY KEY);
|
|
23
|
+
INSERT OR IGNORE INTO agent_memory_schema VALUES(1);
|
|
24
|
+
CREATE TABLE IF NOT EXISTS memories(id TEXT PRIMARY KEY, scope TEXT NOT NULL, memory_key TEXT NOT NULL, revision INTEGER NOT NULL,
|
|
25
|
+
content TEXT NOT NULL, source TEXT NOT NULL, content_hash TEXT NOT NULL, status TEXT NOT NULL, trust TEXT NOT NULL, updated_at TEXT NOT NULL,
|
|
26
|
+
UNIQUE(scope,memory_key,revision));
|
|
27
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS memory_search USING fts5(id UNINDEXED, content, tokenize='unicode61');
|
|
28
|
+
CREATE TRIGGER IF NOT EXISTS memory_insert AFTER INSERT ON memories BEGIN INSERT INTO memory_search VALUES(new.id,new.content); END;
|
|
29
|
+
CREATE TRIGGER IF NOT EXISTS memory_delete AFTER DELETE ON memories BEGIN DELETE FROM memory_search WHERE id=old.id; END;
|
|
30
|
+
CREATE INDEX IF NOT EXISTS memory_scope ON memories(scope,status,memory_key);`);
|
|
31
|
+
}
|
|
32
|
+
async search(query, options = {}) {
|
|
33
|
+
const limit = Math.max(1, Math.min(50, Math.floor(options.limit ?? 8)));
|
|
34
|
+
const tokens = query.match(/[\p{L}\p{N}_]+/gu)?.slice(0, 24) ?? [];
|
|
35
|
+
const trust = options.includeCandidates ? "" : " AND m.trust='confirmed'";
|
|
36
|
+
if (!tokens.length)
|
|
37
|
+
return this.db.prepare(`SELECT m.* FROM memories m WHERE m.scope=? AND m.status='active'${trust} ORDER BY updated_at DESC LIMIT ?`).all(this.scope, limit).map(record);
|
|
38
|
+
const match = tokens.map(t => `"${t}"`).join(" OR ");
|
|
39
|
+
return this.db.prepare(`SELECT m.* FROM memory_search f JOIN memories m ON m.id=f.id WHERE memory_search MATCH ? AND m.scope=? AND m.status='active'${trust} ORDER BY bm25(memory_search),m.updated_at DESC LIMIT ?`).all(match, this.scope, limit).map(record);
|
|
40
|
+
}
|
|
41
|
+
async remember(input) {
|
|
42
|
+
if (!input.key.trim() || input.key.length > 256 || !input.content.trim() || input.content.length > 16000 || !input.source.trim() || input.source.length > 2048)
|
|
43
|
+
throw new Error("Invalid memory key, content, or provenance.");
|
|
44
|
+
const trust = input.trust ?? "candidate";
|
|
45
|
+
if (!["candidate", "confirmed"].includes(trust))
|
|
46
|
+
throw new Error("Invalid memory trust.");
|
|
47
|
+
const hash = createHash("sha256").update(input.content).digest("hex");
|
|
48
|
+
this.db.exec("BEGIN IMMEDIATE");
|
|
49
|
+
try {
|
|
50
|
+
const previous = this.db.prepare("SELECT * FROM memories WHERE scope=? AND memory_key=? AND status='active'").get(this.scope, input.key);
|
|
51
|
+
if (input.expectedRevision !== undefined && input.expectedRevision !== Number(previous?.revision ?? 0))
|
|
52
|
+
throw new Error("Memory revision conflict.");
|
|
53
|
+
if (previous?.content_hash === hash && previous.source === input.source && previous.trust === trust) {
|
|
54
|
+
this.db.exec("COMMIT");
|
|
55
|
+
return record(previous);
|
|
56
|
+
}
|
|
57
|
+
// A generated candidate cannot silently supersede an explicitly confirmed note.
|
|
58
|
+
if (previous?.trust === "confirmed" && trust === "candidate")
|
|
59
|
+
throw new Error("A candidate cannot replace a confirmed memory; choose a new key.");
|
|
60
|
+
this.db.prepare("UPDATE memories SET status='superseded' WHERE scope=? AND memory_key=?").run(this.scope, input.key);
|
|
61
|
+
const id = randomUUID();
|
|
62
|
+
this.db.prepare("INSERT INTO memories VALUES(?,?,?,?,?,?,?,?,?,?)").run(id, this.scope, input.key, Number(previous?.revision ?? 0) + 1, input.content, input.source, hash, "active", trust, new Date().toISOString());
|
|
63
|
+
const next = record(this.db.prepare("SELECT * FROM memories WHERE id=?").get(id));
|
|
64
|
+
this.db.exec("COMMIT");
|
|
65
|
+
return next;
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
this.db.exec("ROLLBACK");
|
|
69
|
+
throw error;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
async history(key) {
|
|
73
|
+
return this.db.prepare("SELECT * FROM memories WHERE scope=? AND memory_key=? ORDER BY revision").all(this.scope, key).map(record);
|
|
74
|
+
}
|
|
75
|
+
async forget(key) {
|
|
76
|
+
const result = this.db.prepare("DELETE FROM memories WHERE scope=? AND memory_key=?").run(this.scope, key);
|
|
77
|
+
// This removes searchable/history data; user backups may still contain earlier copies.
|
|
78
|
+
this.db.exec("PRAGMA wal_checkpoint(TRUNCATE)");
|
|
79
|
+
return Number(result.changes);
|
|
80
|
+
}
|
|
81
|
+
close() { this.db.close(); }
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=sqlite-memory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite-memory.js","sourceRoot":"","sources":["../../../../src/adapters/node/memory/sqlite-memory.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type CodingRoundEvent, type ModelIdentity } from "../../../ports/index.js";
|
|
2
|
+
export declare const OLLAMA_GLM_5_3_FLASH_IDENTITY: ModelIdentity;
|
|
3
|
+
export interface NormalizeOllamaChatOptions {
|
|
4
|
+
readonly identity?: ModelIdentity;
|
|
5
|
+
readonly requestedMaxOutputTokens?: number;
|
|
6
|
+
readonly roundId: string;
|
|
7
|
+
}
|
|
8
|
+
/** Stateful normalizer shared by live NDJSON and deterministic replay. */
|
|
9
|
+
export declare function createOllamaChatNormalizer(options: NormalizeOllamaChatOptions): {
|
|
10
|
+
initial: readonly CodingRoundEvent[];
|
|
11
|
+
push: (rawChunk: unknown) => readonly CodingRoundEvent[];
|
|
12
|
+
readonly failed: boolean;
|
|
13
|
+
finish(): readonly CodingRoundEvent[];
|
|
14
|
+
};
|
|
15
|
+
/** Pure replay helper; live adapters push each chunk without buffering the response. */
|
|
16
|
+
export declare function normalizeOllamaChatChunks(chunks: readonly unknown[], options: NormalizeOllamaChatOptions): readonly CodingRoundEvent[];
|
|
17
|
+
//# sourceMappingURL=ollama-chat-stream.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ollama-chat-stream.d.ts","sourceRoot":"","sources":["../../../../src/adapters/node/provider/ollama-chat-stream.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,gBAAgB,EACrB,KAAK,aAAa,EACnB,MAAM,yBAAyB,CAAC;AAIjC,eAAO,MAAM,6BAA6B,EAAE,aAK1C,CAAC;AAEH,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,QAAQ,CAAC,EAAE,aAAa,CAAC;IAClC,QAAQ,CAAC,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAC3C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AA4BD,0EAA0E;AAC1E,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,0BAA0B;;qBAWpD,OAAO,KAAG,SAAS,gBAAgB,EAAE;;cAqHjD,SAAS,gBAAgB,EAAE;EAMxC;AAED,wFAAwF;AACxF,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,SAAS,OAAO,EAAE,EAAE,OAAO,EAAE,0BAA0B,GAAG,SAAS,gBAAgB,EAAE,CAStI"}
|