@galaxy-stack/ai-coder-core 0.3.0-alpha.1 → 0.3.0-alpha.8

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.
Files changed (122) hide show
  1. package/CHANGELOG.d/2026-09-19-research-rejection-evidence.md +15 -0
  2. package/CHANGELOG.d/2026-09-21-evidence-missing-remediation.md +15 -0
  3. package/CHANGELOG.d/2026-09-21-observation-nudge-context.md +12 -0
  4. package/CHANGELOG.d/2026-09-22-model-retry-budget.md +18 -0
  5. package/CHANGELOG.d/2026-09-22-no-progress-recovery-turn.md +19 -0
  6. package/CHANGELOG.d/2026-09-23-agent-platform.md +5 -0
  7. package/CHANGELOG.d/2026-09-23-conservative-output-reserve.md +16 -0
  8. package/CHANGELOG.d/2026-09-24-approval-workspace-review.md +7 -0
  9. package/CHANGELOG.d/2026-09-24-incremental-ollama.md +5 -0
  10. package/CHANGELOG.md +71 -1
  11. package/README.md +78 -4
  12. package/dist/adapters/node/config/manual-provider-config.d.ts +19 -0
  13. package/dist/adapters/node/config/manual-provider-config.d.ts.map +1 -0
  14. package/dist/adapters/node/config/manual-provider-config.js +91 -0
  15. package/dist/adapters/node/config/manual-provider-config.js.map +1 -0
  16. package/dist/adapters/node/host/command-containment.d.ts +45 -0
  17. package/dist/adapters/node/host/command-containment.d.ts.map +1 -0
  18. package/dist/adapters/node/host/command-containment.js +580 -0
  19. package/dist/adapters/node/host/command-containment.js.map +1 -0
  20. package/dist/adapters/node/host/content-hash.d.ts +2 -0
  21. package/dist/adapters/node/host/content-hash.d.ts.map +1 -0
  22. package/dist/adapters/node/host/content-hash.js +5 -0
  23. package/dist/adapters/node/host/content-hash.js.map +1 -0
  24. package/dist/adapters/node/host/file-run-store.d.ts +29 -0
  25. package/dist/adapters/node/host/file-run-store.d.ts.map +1 -0
  26. package/dist/adapters/node/host/file-run-store.js +94 -0
  27. package/dist/adapters/node/host/file-run-store.js.map +1 -0
  28. package/dist/adapters/node/host/host-environment.d.ts +9 -0
  29. package/dist/adapters/node/host/host-environment.d.ts.map +1 -0
  30. package/dist/adapters/node/host/host-environment.js +29 -0
  31. package/dist/adapters/node/host/host-environment.js.map +1 -0
  32. package/dist/adapters/node/host/node-command-port.d.ts +21 -0
  33. package/dist/adapters/node/host/node-command-port.d.ts.map +1 -0
  34. package/dist/adapters/node/host/node-command-port.js +281 -0
  35. package/dist/adapters/node/host/node-command-port.js.map +1 -0
  36. package/dist/adapters/node/host/node-workspace-evidence-verifier.d.ts +22 -0
  37. package/dist/adapters/node/host/node-workspace-evidence-verifier.d.ts.map +1 -0
  38. package/dist/adapters/node/host/node-workspace-evidence-verifier.js +384 -0
  39. package/dist/adapters/node/host/node-workspace-evidence-verifier.js.map +1 -0
  40. package/dist/adapters/node/host/node-workspace-port.d.ts +87 -0
  41. package/dist/adapters/node/host/node-workspace-port.d.ts.map +1 -0
  42. package/dist/adapters/node/host/node-workspace-port.js +860 -0
  43. package/dist/adapters/node/host/node-workspace-port.js.map +1 -0
  44. package/dist/adapters/node/host/node-workspace-snapshot.d.ts +61 -0
  45. package/dist/adapters/node/host/node-workspace-snapshot.d.ts.map +1 -0
  46. package/dist/adapters/node/host/node-workspace-snapshot.js +281 -0
  47. package/dist/adapters/node/host/node-workspace-snapshot.js.map +1 -0
  48. package/dist/adapters/node/host/path-scope.d.ts +17 -0
  49. package/dist/adapters/node/host/path-scope.d.ts.map +1 -0
  50. package/dist/adapters/node/host/path-scope.js +89 -0
  51. package/dist/adapters/node/host/path-scope.js.map +1 -0
  52. package/dist/adapters/node/host/project-tools.d.ts +42 -0
  53. package/dist/adapters/node/host/project-tools.d.ts.map +1 -0
  54. package/dist/adapters/node/host/project-tools.js +362 -0
  55. package/dist/adapters/node/host/project-tools.js.map +1 -0
  56. package/dist/adapters/node/mcp/mcp-client.d.ts +206 -0
  57. package/dist/adapters/node/mcp/mcp-client.d.ts.map +1 -0
  58. package/dist/adapters/node/mcp/mcp-client.js +128 -0
  59. package/dist/adapters/node/mcp/mcp-client.js.map +1 -0
  60. package/dist/adapters/node/mcp/oauth-provider.d.ts +39 -0
  61. package/dist/adapters/node/mcp/oauth-provider.d.ts.map +1 -0
  62. package/dist/adapters/node/mcp/oauth-provider.js +168 -0
  63. package/dist/adapters/node/mcp/oauth-provider.js.map +1 -0
  64. package/dist/adapters/node/memory/sqlite-memory.d.ts +22 -0
  65. package/dist/adapters/node/memory/sqlite-memory.d.ts.map +1 -0
  66. package/dist/adapters/node/memory/sqlite-memory.js +83 -0
  67. package/dist/adapters/node/memory/sqlite-memory.js.map +1 -0
  68. package/dist/adapters/node/provider/ollama-chat-stream.d.ts +17 -0
  69. package/dist/adapters/node/provider/ollama-chat-stream.d.ts.map +1 -0
  70. package/dist/adapters/node/provider/ollama-chat-stream.js +176 -0
  71. package/dist/adapters/node/provider/ollama-chat-stream.js.map +1 -0
  72. package/dist/adapters/node/provider/ollama-coding-model.d.ts +89 -0
  73. package/dist/adapters/node/provider/ollama-coding-model.d.ts.map +1 -0
  74. package/dist/adapters/node/provider/ollama-coding-model.js +464 -0
  75. package/dist/adapters/node/provider/ollama-coding-model.js.map +1 -0
  76. package/dist/adapters/node/provider/ollama-research-port.d.ts +32 -0
  77. package/dist/adapters/node/provider/ollama-research-port.d.ts.map +1 -0
  78. package/dist/adapters/node/provider/ollama-research-port.js +346 -0
  79. package/dist/adapters/node/provider/ollama-research-port.js.map +1 -0
  80. package/dist/adapters/node/skills/directory-skills.d.ts +12 -0
  81. package/dist/adapters/node/skills/directory-skills.d.ts.map +1 -0
  82. package/dist/adapters/node/skills/directory-skills.js +90 -0
  83. package/dist/adapters/node/skills/directory-skills.js.map +1 -0
  84. package/dist/adapters/node/tools/tool-executor.d.ts +91 -0
  85. package/dist/adapters/node/tools/tool-executor.d.ts.map +1 -0
  86. package/dist/adapters/node/tools/tool-executor.js +948 -0
  87. package/dist/adapters/node/tools/tool-executor.js.map +1 -0
  88. package/dist/adapters/node/tools/workspace-review.d.ts +13 -0
  89. package/dist/adapters/node/tools/workspace-review.d.ts.map +1 -0
  90. package/dist/adapters/node/tools/workspace-review.js +81 -0
  91. package/dist/adapters/node/tools/workspace-review.js.map +1 -0
  92. package/dist/agent/index.d.ts +79 -0
  93. package/dist/agent/index.d.ts.map +1 -0
  94. package/dist/agent/index.js +97 -0
  95. package/dist/agent/index.js.map +1 -0
  96. package/dist/approval/approval-policy.d.ts.map +1 -1
  97. package/dist/approval/approval-policy.js +4 -1
  98. package/dist/approval/approval-policy.js.map +1 -1
  99. package/dist/context/checkpoint.d.ts +2 -0
  100. package/dist/context/checkpoint.d.ts.map +1 -1
  101. package/dist/context/checkpoint.js +5 -2
  102. package/dist/context/checkpoint.js.map +1 -1
  103. package/dist/context/context-manager.d.ts.map +1 -1
  104. package/dist/context/context-manager.js +21 -8
  105. package/dist/context/context-manager.js.map +1 -1
  106. package/dist/context/context-profile.d.ts +1 -1
  107. package/dist/context/context-profile.js +2 -2
  108. package/dist/prompt/prompt-assembler.d.ts +1 -0
  109. package/dist/prompt/prompt-assembler.d.ts.map +1 -1
  110. package/dist/prompt/prompt-assembler.js +16 -2
  111. package/dist/prompt/prompt-assembler.js.map +1 -1
  112. package/dist/runtime/run-controller.d.ts.map +1 -1
  113. package/dist/runtime/run-controller.js +131 -24
  114. package/dist/runtime/run-controller.js.map +1 -1
  115. package/dist/runtime/runtime-types.d.ts +20 -0
  116. package/dist/runtime/runtime-types.d.ts.map +1 -1
  117. package/dist/tools/tool-registry.js +1 -1
  118. package/dist/tools/tool-registry.js.map +1 -1
  119. package/docs/AGENT_PLATFORM.md +91 -0
  120. package/docs/GALAXY_AGENT_PLATFORM_PLAN.md +353 -0
  121. package/docs/GALAXY_AGENT_PLATFORM_TODO.md +176 -0
  122. package/package.json +19 -5
@@ -0,0 +1,346 @@
1
+ import { createHash } from "node:crypto";
2
+ import { isIP } from "node:net";
3
+ import { portFailure, portSuccess, } from "../../../ports/index.js";
4
+ export const OLLAMA_RESEARCH_LIMITS = Object.freeze({
5
+ defaultFetchBytes: 12_000,
6
+ defaultSearchResults: 3,
7
+ maxFetchBytes: 65_536,
8
+ maxQueryBytes: 2_048,
9
+ maxResponseBytes: 1_048_576,
10
+ maxSearchResults: 10,
11
+ maxSnippetBytes: 2_048,
12
+ maxTitleBytes: 512,
13
+ maxUrlBytes: 4_096,
14
+ timeoutMs: 30_000,
15
+ });
16
+ class ResearchFailure extends Error {
17
+ code;
18
+ retryable;
19
+ status;
20
+ constructor(code, message, retryable = false, status) {
21
+ super(message);
22
+ this.code = code;
23
+ this.retryable = retryable;
24
+ this.status = status;
25
+ }
26
+ }
27
+ function isObject(value) {
28
+ return typeof value === "object" && value !== null && !Array.isArray(value);
29
+ }
30
+ function valueType(value) {
31
+ return value === null ? "null" : Array.isArray(value) ? "array" : typeof value;
32
+ }
33
+ function schemaDiagnostic(payload, fields) {
34
+ let serialized;
35
+ try {
36
+ serialized = JSON.stringify(payload) ?? String(payload);
37
+ }
38
+ catch {
39
+ serialized = "<unserializable>";
40
+ }
41
+ const digest = createHash("sha256").update(serialized, "utf8").digest("hex");
42
+ const fieldTypes = fields.map((field) => (`${field}=${isObject(payload) && field in payload ? valueType(payload[field]) : "missing"}`));
43
+ return `payloadSha256=${digest}; root=${valueType(payload)}; ${fieldTypes.join("; ")}`;
44
+ }
45
+ function failure(error) {
46
+ const known = error instanceof ResearchFailure ? error : null;
47
+ return portFailure({
48
+ code: known?.code ?? "PROVIDER_ERROR",
49
+ message: known?.message ?? "Ollama research transport failed. Provider error details are withheld to protect credentials.",
50
+ retryable: known?.retryable ?? true,
51
+ ...(known?.status === undefined ? {} : { details: { status: known.status } }),
52
+ });
53
+ }
54
+ function byteLength(value) {
55
+ return Buffer.byteLength(value, "utf8");
56
+ }
57
+ function boundedText(value, maxBytes) {
58
+ const bytes = Buffer.from(value, "utf8");
59
+ if (bytes.byteLength <= maxBytes)
60
+ return { text: value, truncated: false };
61
+ let end = maxBytes;
62
+ // A UTF-8 cut may land in a continuation byte. Exclude the whole final code point.
63
+ while (end > 0 && (bytes[end] & 0xc0) === 0x80)
64
+ end -= 1;
65
+ return { text: bytes.subarray(0, end).toString("utf8"), truncated: true };
66
+ }
67
+ function isPublicIpv4(address) {
68
+ const [first = 0, second = 0, third = 0] = address.split(".").map(Number);
69
+ return !(first === 0 || first === 10 || first === 127 || first >= 224
70
+ || (first === 100 && second >= 64 && second <= 127)
71
+ || (first === 169 && second === 254)
72
+ || (first === 172 && second >= 16 && second <= 31)
73
+ || (first === 192 && second === 168)
74
+ || (first === 192 && second === 0 && (third === 0 || third === 2))
75
+ || (first === 198 && (second === 18 || second === 19))
76
+ || (first === 198 && second === 51 && third === 100)
77
+ || (first === 203 && second === 0 && third === 113));
78
+ }
79
+ function isPublicIpv6(address) {
80
+ // WHATWG URL canonicalizes embedded IPv4 to hexadecimal groups before this call.
81
+ const sections = address.split("::");
82
+ const head = (sections[0] ?? "").split(":").filter(Boolean).map((part) => Number.parseInt(part, 16));
83
+ const tail = (sections[1] ?? "").split(":").filter(Boolean).map((part) => Number.parseInt(part, 16));
84
+ const groups = sections.length === 1 ? head : [...head, ...Array(8 - head.length - tail.length).fill(0), ...tail];
85
+ const bytes = groups.flatMap((group) => [group >> 8, group & 0xff]);
86
+ if (bytes.slice(0, 10).every((byte) => byte === 0) && bytes[10] === 0xff && bytes[11] === 0xff) {
87
+ return isPublicIpv4(bytes.slice(12).join("."));
88
+ }
89
+ // Accept ordinary global unicast; exclude local, multicast, translation/tunnel,
90
+ // unspecified and documentation/special-use ranges conservatively.
91
+ if ((bytes[0] & 0xe0) !== 0x20)
92
+ return false;
93
+ if (groups[0] === 0x2002)
94
+ return false; // 6to4 can encode non-public IPv4.
95
+ if (groups[0] === 0x2001 && (groups[1] < 0x0200 || groups[1] === 0x0db8))
96
+ return false;
97
+ if (groups[0] === 0x3fff && groups[1] < 0x1000)
98
+ return false;
99
+ return true;
100
+ }
101
+ function publicUrl(value) {
102
+ if (byteLength(value) > OLLAMA_RESEARCH_LIMITS.maxUrlBytes || /[\u0000-\u0020\u007f\\]/u.test(value))
103
+ return null;
104
+ let parsed;
105
+ try {
106
+ parsed = new URL(value);
107
+ }
108
+ catch {
109
+ return null;
110
+ }
111
+ if (!["http:", "https:"].includes(parsed.protocol) || parsed.username || parsed.password)
112
+ return null;
113
+ const hostname = parsed.hostname.replace(/^\[|\]$/g, "").replace(/\.$/, "").toLowerCase();
114
+ const version = isIP(hostname);
115
+ if (version === 4)
116
+ return isPublicIpv4(hostname) ? parsed : null;
117
+ if (version === 6)
118
+ return isPublicIpv6(hostname) ? parsed : null;
119
+ if (!hostname.includes(".") || !hostname.split(".").every((part) => /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/u.test(part)))
120
+ return null;
121
+ if (["localhost", "local", "internal", "home", "lan", "test", "invalid", "example", "arpa"]
122
+ .some((suffix) => hostname === suffix || hostname.endsWith(`.${suffix}`)))
123
+ return null;
124
+ return parsed;
125
+ }
126
+ function assertActive(context) {
127
+ if (context.signal.aborted)
128
+ throw new ResearchFailure("CANCELED", "Ollama research request was canceled.");
129
+ if (!Number.isFinite(context.deadline) || Date.now() >= context.deadline) {
130
+ throw new ResearchFailure("DEADLINE_EXCEEDED", "Ollama research deadline elapsed.", true);
131
+ }
132
+ }
133
+ async function abortable(promise, signal) {
134
+ return new Promise((resolve, reject) => {
135
+ const abort = () => reject(signal.reason);
136
+ if (signal.aborted) {
137
+ // The supplied promise may already be in flight; retain its rejection handler.
138
+ void promise.catch(() => { });
139
+ reject(signal.reason);
140
+ return;
141
+ }
142
+ signal.addEventListener("abort", abort, { once: true });
143
+ promise.then(resolve, reject).finally(() => signal.removeEventListener("abort", abort));
144
+ });
145
+ }
146
+ /** Cloud research only: no local URL is fetched, and external content never becomes trusted instructions. */
147
+ export class OllamaResearchPort {
148
+ apiKey;
149
+ fetchImpl;
150
+ timeoutMs;
151
+ constructor(options = {}) {
152
+ this.apiKey = options.apiKey?.trim() ?? "";
153
+ this.fetchImpl = options.fetch ?? globalThis.fetch;
154
+ this.timeoutMs = options.timeoutMs ?? OLLAMA_RESEARCH_LIMITS.timeoutMs;
155
+ if (!Number.isSafeInteger(this.timeoutMs) || this.timeoutMs < 1 || this.timeoutMs > 2_147_483_647) {
156
+ throw new Error("Ollama research timeoutMs must be a positive 32-bit integer.");
157
+ }
158
+ }
159
+ hasCredential(value) {
160
+ return this.apiKey.length > 0 && (value.includes(this.apiKey)
161
+ || value.toLowerCase().includes(encodeURIComponent(this.apiKey).toLowerCase())
162
+ || (() => { try {
163
+ return decodeURIComponent(value).includes(this.apiKey);
164
+ }
165
+ catch {
166
+ return false;
167
+ } })());
168
+ }
169
+ redact(value) {
170
+ let sanitized = value;
171
+ if (this.apiKey) {
172
+ sanitized = sanitized.replaceAll(this.apiKey, "[REDACTED]");
173
+ const encodedKey = encodeURIComponent(this.apiKey).replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
174
+ sanitized = sanitized.replace(new RegExp(encodedKey, "gi"), "[REDACTED]");
175
+ }
176
+ return sanitized.replace(/Bearer\s+[^\s"'<>]+/giu, "Bearer [REDACTED]");
177
+ }
178
+ async request(route, body, context) {
179
+ assertActive(context);
180
+ if (!this.apiKey)
181
+ throw new ResearchFailure("PRECONDITION_FAILED", "Ollama web research requires an Ollama API key.");
182
+ if (/[\u0000-\u0020\u007f]/u.test(this.apiKey))
183
+ throw new ResearchFailure("INVALID_INPUT", "Ollama research API key contains invalid characters.");
184
+ const controller = new AbortController();
185
+ const cancel = () => controller.abort(new ResearchFailure("CANCELED", "Ollama research request was canceled."));
186
+ context.signal.addEventListener("abort", cancel, { once: true });
187
+ const timer = setTimeout(() => {
188
+ controller.abort(new ResearchFailure("DEADLINE_EXCEEDED", "Ollama research request timed out.", true));
189
+ }, Math.min(this.timeoutMs, context.deadline - Date.now()));
190
+ let reader;
191
+ let response;
192
+ try {
193
+ const responsePromise = this.fetchImpl(`https://ollama.com/api/${route}`, {
194
+ method: "POST",
195
+ headers: { "Content-Type": "application/json", Authorization: `Bearer ${this.apiKey}` },
196
+ body: JSON.stringify(body),
197
+ redirect: "manual",
198
+ signal: controller.signal,
199
+ });
200
+ // Also closes a late response from an injected transport that ignores abort.
201
+ void responsePromise.then((late) => {
202
+ if (controller.signal.aborted)
203
+ void late.body?.cancel().catch(() => { });
204
+ }, () => { });
205
+ response = await abortable(responsePromise, controller.signal);
206
+ if (response.redirected || (response.status >= 300 && response.status < 400)) {
207
+ throw new ResearchFailure("PERMISSION_DENIED", "Ollama research redirects are disabled to protect the API key.");
208
+ }
209
+ if (!response.ok) {
210
+ const status = response.status;
211
+ if (status === 401 || status === 403)
212
+ throw new ResearchFailure("PERMISSION_DENIED", "Ollama web research authentication or account permission was rejected.", false, status);
213
+ if (status === 408 || status === 504)
214
+ throw new ResearchFailure("DEADLINE_EXCEEDED", "Ollama web research provider timed out.", true, status);
215
+ if (status === 429)
216
+ throw new ResearchFailure("UNAVAILABLE", "Ollama web research rate limit reached; retry later.", true, status);
217
+ if (status >= 500)
218
+ throw new ResearchFailure("UNAVAILABLE", "Ollama web research service is temporarily unavailable.", true, status);
219
+ throw new ResearchFailure("PROVIDER_ERROR", "Ollama web research request was rejected by the provider.", false, status);
220
+ }
221
+ const declaredLength = Number(response.headers.get("content-length") ?? "0");
222
+ if (declaredLength > OLLAMA_RESEARCH_LIMITS.maxResponseBytes) {
223
+ throw new ResearchFailure("LIMIT_EXCEEDED", "Ollama web research response exceeds the byte limit.");
224
+ }
225
+ if (!response.body)
226
+ throw new ResearchFailure("PROVIDER_ERROR", "Ollama web research returned an empty response body.");
227
+ reader = response.body.getReader();
228
+ const chunks = [];
229
+ let size = 0;
230
+ while (true) {
231
+ const item = await abortable(reader.read(), controller.signal);
232
+ if (item.done)
233
+ break;
234
+ size += item.value.byteLength;
235
+ if (size > OLLAMA_RESEARCH_LIMITS.maxResponseBytes) {
236
+ throw new ResearchFailure("LIMIT_EXCEEDED", "Ollama web research response exceeds the byte limit.");
237
+ }
238
+ chunks.push(item.value);
239
+ }
240
+ assertActive(context);
241
+ if (controller.signal.aborted)
242
+ throw controller.signal.reason;
243
+ try {
244
+ return JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(Buffer.concat(chunks, size)));
245
+ }
246
+ catch {
247
+ throw new ResearchFailure("PROVIDER_ERROR", "Ollama web research response is not valid UTF-8 JSON.");
248
+ }
249
+ }
250
+ finally {
251
+ clearTimeout(timer);
252
+ context.signal.removeEventListener("abort", cancel);
253
+ if (reader) {
254
+ // Never await cancel: a malicious/stalled stream may never settle it.
255
+ void reader.cancel().catch(() => { });
256
+ reader.releaseLock();
257
+ }
258
+ else {
259
+ void response?.body?.cancel().catch(() => { });
260
+ }
261
+ }
262
+ }
263
+ async search(input, context) {
264
+ try {
265
+ assertActive(context);
266
+ if (input.cursor !== undefined)
267
+ throw new ResearchFailure("UNSUPPORTED", "Ollama web search does not support cursors. Refine the query instead of retrying a page.");
268
+ const query = typeof input.query === "string" ? input.query.trim() : "";
269
+ if (!query || byteLength(query) > OLLAMA_RESEARCH_LIMITS.maxQueryBytes || /[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f]/u.test(query)) {
270
+ throw new ResearchFailure("INVALID_INPUT", "Search query must contain 1–2048 UTF-8 bytes of readable text.");
271
+ }
272
+ if (this.hasCredential(query))
273
+ throw new ResearchFailure("INVALID_INPUT", "Search query must not contain the research API key.");
274
+ const limit = input.limit ?? OLLAMA_RESEARCH_LIMITS.defaultSearchResults;
275
+ if (!Number.isSafeInteger(limit) || limit < 1 || limit > OLLAMA_RESEARCH_LIMITS.maxSearchResults) {
276
+ throw new ResearchFailure("INVALID_INPUT", "Ollama web search limit must be an integer between 1 and 10.");
277
+ }
278
+ const payload = await this.request("web_search", { query, max_results: limit }, context);
279
+ if (!isObject(payload) || !Array.isArray(payload.results)) {
280
+ throw new ResearchFailure("PROVIDER_ERROR", `Ollama web search response is missing its results array (${schemaDiagnostic(payload, ["results"])}).`);
281
+ }
282
+ const results = [];
283
+ let truncated = payload.results.length > limit;
284
+ for (const candidate of payload.results) {
285
+ if (!isObject(candidate) || typeof candidate.title !== "string" || typeof candidate.content !== "string" || typeof candidate.url !== "string") {
286
+ throw new ResearchFailure("PROVIDER_ERROR", `Ollama web search returned an invalid result schema (${schemaDiagnostic(candidate, ["title", "content", "url"])}).`);
287
+ }
288
+ const parsed = publicUrl(candidate.url);
289
+ if (!parsed || this.hasCredential(candidate.url) || this.hasCredential(parsed.href)) {
290
+ truncated = true;
291
+ continue;
292
+ }
293
+ if (results.length >= limit)
294
+ continue;
295
+ const title = boundedText(this.redact(candidate.title).trim() || parsed.hostname, OLLAMA_RESEARCH_LIMITS.maxTitleBytes);
296
+ const snippet = boundedText(this.redact(candidate.content), OLLAMA_RESEARCH_LIMITS.maxSnippetBytes);
297
+ truncated ||= title.truncated || snippet.truncated;
298
+ results.push(Object.freeze({ provider: "ollama", title: title.text, url: parsed.href, snippet: snippet.text }));
299
+ }
300
+ return portSuccess(Object.freeze({
301
+ pagination: Object.freeze({ hasMore: truncated }),
302
+ results: Object.freeze(results),
303
+ trust: "untrusted_data",
304
+ }));
305
+ }
306
+ catch (error) {
307
+ return failure(error);
308
+ }
309
+ }
310
+ async extract(input, context) {
311
+ try {
312
+ assertActive(context);
313
+ if (input.cursor !== undefined)
314
+ throw new ResearchFailure("UNSUPPORTED", "Ollama web fetch does not support cursors. Use a more specific source URL instead of retrying a page.");
315
+ if (input.extractDepth !== undefined && !["basic", "advanced"].includes(input.extractDepth))
316
+ throw new ResearchFailure("INVALID_INPUT", "Unsupported research extraction depth.");
317
+ const parsed = typeof input.url === "string" ? publicUrl(input.url) : null;
318
+ if (!parsed || this.hasCredential(input.url) || this.hasCredential(parsed.href)) {
319
+ throw new ResearchFailure("INVALID_INPUT", "Web fetch requires a public HTTP(S) URL without credentials or private/local addresses.");
320
+ }
321
+ const maxBytes = input.maxBytes ?? OLLAMA_RESEARCH_LIMITS.defaultFetchBytes;
322
+ if (!Number.isSafeInteger(maxBytes) || maxBytes < 1 || maxBytes > OLLAMA_RESEARCH_LIMITS.maxFetchBytes) {
323
+ throw new ResearchFailure("INVALID_INPUT", "Ollama web fetch maxBytes must be an integer between 1 and 65536.");
324
+ }
325
+ const payload = await this.request("web_fetch", { url: parsed.href }, context);
326
+ if (!isObject(payload) || typeof payload.title !== "string" || typeof payload.content !== "string" || !Array.isArray(payload.links) || !payload.links.every((link) => typeof link === "string")) {
327
+ throw new ResearchFailure("PROVIDER_ERROR", `Ollama web fetch returned an invalid page schema (${schemaDiagnostic(payload, ["title", "content", "links"])}).`);
328
+ }
329
+ if (!payload.content.trim())
330
+ throw new ResearchFailure("NOT_FOUND", "Ollama web fetch returned no readable page content.");
331
+ const bounded = boundedText(this.redact(payload.content), maxBytes);
332
+ return portSuccess(Object.freeze({
333
+ content: bounded.text,
334
+ contentSha256: createHash("sha256").update(bounded.text, "utf8").digest("hex"),
335
+ pagination: Object.freeze({ hasMore: bounded.truncated }),
336
+ provider: "ollama",
337
+ trust: "untrusted_data",
338
+ url: parsed.href,
339
+ }));
340
+ }
341
+ catch (error) {
342
+ return failure(error);
343
+ }
344
+ }
345
+ }
346
+ //# sourceMappingURL=ollama-research-port.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ollama-research-port.js","sourceRoot":"","sources":["../../../../src/adapters/node/provider/ollama-research-port.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { AgentSkillsPort, SkillDescriptor } from "../../../agent/index.js";
2
+ export declare class DirectorySkills implements AgentSkillsPort {
3
+ private readonly roots;
4
+ private readonly entries;
5
+ constructor(roots: Readonly<Record<string, string>>);
6
+ list(): Promise<readonly SkillDescriptor[]>;
7
+ load(id: string): Promise<SkillDescriptor & {
8
+ readonly content: string;
9
+ }>;
10
+ readResource(id: string, path: string): Promise<string>;
11
+ }
12
+ //# sourceMappingURL=directory-skills.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"directory-skills.d.ts","sourceRoot":"","sources":["../../../../src/adapters/node/skills/directory-skills.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAsBhF,qBAAa,eAAgB,YAAW,eAAe;IAEzC,OAAO,CAAC,QAAQ,CAAC,KAAK;IADlC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqD;gBAChD,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9D,IAAI,IAAI,OAAO,CAAC,SAAS,eAAe,EAAE,CAAC;IAmB3C,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG;QAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAOzE,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAQ9D"}
@@ -0,0 +1,90 @@
1
+ import { open, readdir, realpath } from "node:fs/promises";
2
+ import { isAbsolute, join, relative, resolve, sep } from "node:path";
3
+ import { createHash } from "node:crypto";
4
+ import { parse } from "yaml";
5
+ const MAX_BYTES = 65536;
6
+ function inside(root, path) { const rel = relative(root, path); return rel !== ".." && !rel.startsWith(`..${sep}`) && !isAbsolute(rel); }
7
+ async function boundedFile(path) {
8
+ const handle = await open(path, "r");
9
+ try {
10
+ const stat = await handle.stat();
11
+ if (!stat.isFile() || stat.size > MAX_BYTES)
12
+ throw new Error("Skill resource must be a regular file up to 64 KiB.");
13
+ const buffer = Buffer.alloc(MAX_BYTES + 1);
14
+ const { bytesRead } = await handle.read(buffer, 0, buffer.length, 0);
15
+ if (bytesRead > MAX_BYTES)
16
+ throw new Error("Skill resource exceeded its size limit.");
17
+ return buffer.subarray(0, bytesRead).toString("utf8");
18
+ }
19
+ finally {
20
+ await handle.close();
21
+ }
22
+ }
23
+ function describe(id, source, content) {
24
+ const front = /^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/u.exec(content);
25
+ if (!front)
26
+ throw new Error(`Skill ${id} requires YAML frontmatter.`);
27
+ const metadata = parse(front[1], { maxAliasCount: 20 });
28
+ if (!metadata || typeof metadata !== "object" || !("name" in metadata) || !("description" in metadata) || typeof metadata.name !== "string" || typeof metadata.description !== "string" || !metadata.name.trim() || !metadata.description.trim() || metadata.description.length > 2048)
29
+ throw new Error(`Invalid skill metadata: ${id}`);
30
+ return { id, name: metadata.name, description: metadata.description, source, contentHash: createHash("sha256").update(content).digest("hex") };
31
+ }
32
+ export class DirectorySkills {
33
+ roots;
34
+ entries = new Map();
35
+ constructor(roots) {
36
+ this.roots = roots;
37
+ }
38
+ async list() {
39
+ const result = [];
40
+ this.entries.clear();
41
+ for (const [namespace, path] of Object.entries(this.roots)) {
42
+ let root;
43
+ try {
44
+ root = await realpath(path);
45
+ }
46
+ catch (e) {
47
+ if (e.code === "ENOENT")
48
+ continue;
49
+ throw e;
50
+ }
51
+ for (const entry of (await readdir(root, { withFileTypes: true })).sort((a, b) => a.name.localeCompare(b.name))) {
52
+ if (!entry.isDirectory())
53
+ continue;
54
+ if (result.length >= 256)
55
+ throw new Error("Skill catalog exceeds 256 entries; narrow the configured roots.");
56
+ const skillRoot = await realpath(join(root, entry.name));
57
+ const source = await realpath(join(skillRoot, "SKILL.md")).catch(e => { if (e.code === "ENOENT")
58
+ return null; throw e; });
59
+ if (!source)
60
+ continue;
61
+ if (!inside(root, skillRoot) || !inside(skillRoot, source))
62
+ throw new Error("Skill path escapes its catalog.");
63
+ const descriptor = describe(`${namespace}/${entry.name}`, source, await boundedFile(source));
64
+ this.entries.set(descriptor.id, { root: skillRoot, hash: descriptor.contentHash });
65
+ result.push(descriptor);
66
+ }
67
+ }
68
+ return result;
69
+ }
70
+ async load(id) {
71
+ const content = await this.readResource(id, "SKILL.md");
72
+ const entry = this.entries.get(id);
73
+ const descriptor = describe(id, join(entry.root, "SKILL.md"), content);
74
+ if (entry.hash !== descriptor.contentHash)
75
+ throw new Error("Skill changed after discovery; refresh the catalog.");
76
+ return { ...descriptor, content };
77
+ }
78
+ async readResource(id, path) {
79
+ const entry = this.entries.get(id);
80
+ if (!entry)
81
+ throw new Error("Unknown skill. Discover skills before loading.");
82
+ if (isAbsolute(path))
83
+ throw new Error("Skill resources must use relative paths.");
84
+ const target = await realpath(resolve(entry.root, path));
85
+ if (!inside(entry.root, target))
86
+ throw new Error("Skill resource escapes its directory.");
87
+ return boundedFile(target);
88
+ }
89
+ }
90
+ //# sourceMappingURL=directory-skills.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"directory-skills.js","sourceRoot":"","sources":["../../../../src/adapters/node/skills/directory-skills.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,91 @@
1
+ import { type AiCoderApprovalProfile, type AiCoderRuntimeToolEffects, type AiCoderRuntimeToolExecutor, type AiCoderRuntimeToolResult, type ApprovalPort, type CodingToolCall, type CommandRunnerPort, type ModelCapabilities, type ResearchPort, type RunExecutionContext, type ToolExecutionContext, type WorkspacePort } from "../../../index.js";
2
+ import { type NodeWorkspaceSnapshotOptions } from "../host/node-workspace-snapshot.js";
3
+ export declare class ContractToolError extends Error {
4
+ readonly code: string;
5
+ readonly retryable: boolean;
6
+ readonly suggestedAction?: string | undefined;
7
+ constructor(code: string, message: string, retryable?: boolean, suggestedAction?: string | undefined);
8
+ }
9
+ export interface ContractToolPort {
10
+ execute(id: string, args: Readonly<Record<string, unknown>>, context: RunExecutionContext): Promise<DispatchResult>;
11
+ }
12
+ export declare const LAB_AVAILABLE_TOOL_IDS: readonly ["catalog.search", "task.checkpoint", "workspace.list", "workspace.glob", "workspace.grep", "workspace.read", "workspace.edit", "workspace.write", "command.run", "project.detect", "project.validate", "git.exec"];
13
+ export declare const LAB_GRANTED_PERMISSIONS: readonly ["core.storage", "fs.workspace", "process.execute"];
14
+ export declare const LAB_RESEARCH_TOOL_IDS: readonly ["research.search", "research.fetch"];
15
+ export declare const LAB_OPTIONAL_CONTRACT_TOOL_IDS: readonly ["research.fetch", "research.search", "command.session", "preview.manage", "perception.analyze", "artifact.create", "artifact.list", "artifact.read", "user.ask"];
16
+ export declare const LAB_FULL_CONTRACT_TOOL_IDS: readonly ["catalog.search", "task.checkpoint", "workspace.list", "workspace.glob", "workspace.grep", "workspace.read", "workspace.edit", "workspace.write", "command.run", "project.detect", "project.validate", "git.exec", "research.fetch", "research.search", "command.session", "preview.manage", "perception.analyze", "artifact.create", "artifact.list", "artifact.read", "user.ask"];
17
+ export declare const LAB_FULL_CONTRACT_PERMISSIONS: readonly ["core.storage", "fs.workspace", "process.execute", "core.artifacts", "network.outbound", "preview.local", "user.interaction"];
18
+ type JsonObject = Readonly<Record<string, unknown>>;
19
+ export interface LabTaskCheckpointState {
20
+ readonly decisions: readonly string[];
21
+ readonly goal: string;
22
+ readonly nextStep: string;
23
+ readonly progress: string;
24
+ readonly updatedAt: string;
25
+ }
26
+ export interface LabTaskCheckpointStore {
27
+ get(runId: string): LabTaskCheckpointState | undefined;
28
+ set(runId: string, checkpoint: LabTaskCheckpointState): unknown;
29
+ }
30
+ type DispatchResult = Readonly<{
31
+ effects?: AiCoderRuntimeToolEffects;
32
+ output: JsonObject;
33
+ summary: string;
34
+ trust: AiCoderRuntimeToolResult["trust"];
35
+ }>;
36
+ export interface NodeToolExecutorOptions {
37
+ readonly approval?: ApprovalPort;
38
+ readonly approvalProfile?: AiCoderApprovalProfile;
39
+ readonly approvalTimeoutMs?: number;
40
+ readonly capabilities: ModelCapabilities;
41
+ readonly command: CommandRunnerPort;
42
+ /** Enables deterministic contract doubles; this is not a production integration profile. */
43
+ readonly enableContractTools?: boolean;
44
+ readonly contractTools?: ContractToolPort;
45
+ readonly enableGit?: boolean;
46
+ /** Real public research adapter, available only when explicitly supplied by the host. */
47
+ readonly research?: ResearchPort;
48
+ /** Host-owned durable state used by task.checkpoint across executor recreation. */
49
+ readonly taskCheckpointStore?: LabTaskCheckpointStore;
50
+ /** Must match the host's outer workspace snapshot policy. */
51
+ readonly workspaceSnapshot?: NodeWorkspaceSnapshotOptions;
52
+ /** Alias for hosts that prefer an explicit named lab profile. */
53
+ readonly toolProfile?: "default" | "full_contract";
54
+ readonly workspace: WorkspacePort;
55
+ }
56
+ export declare class NodeToolExecutor implements AiCoderRuntimeToolExecutor {
57
+ private readonly options;
58
+ private readonly approvalPolicy;
59
+ private readonly contractTools;
60
+ private readonly contractToolsEnabled;
61
+ private readonly grantedPermissions;
62
+ private readonly idempotencyCache;
63
+ private readonly researchFetchCache;
64
+ private readonly researchSearchCache;
65
+ private readonly taskCheckpointStore;
66
+ private registry;
67
+ private mutationBaseline;
68
+ constructor(options: NodeToolExecutorOptions);
69
+ getToolSet(context: RunExecutionContext): Promise<Readonly<{
70
+ canonicalToolIds: Readonly<Record<string, string>>;
71
+ definitions: readonly Readonly<{
72
+ function: Readonly<{
73
+ description: string;
74
+ name: string;
75
+ parameters: Readonly<Record<string, unknown>>;
76
+ }>;
77
+ type: "function";
78
+ }>[];
79
+ effectCapabilities: Readonly<Record<string, readonly ("research" | "write" | "plan" | "approval" | "criterion_satisfy" | "criterion_waive" | "diff_review" | "inspect" | "state_version" | "validate")[]>>;
80
+ snapshotHash: string;
81
+ }>>;
82
+ restoreToolSet(input: Readonly<{
83
+ names: readonly string[];
84
+ snapshotHash: string;
85
+ }>, context: RunExecutionContext): Promise<void>;
86
+ execute(call: CodingToolCall, context: ToolExecutionContext): Promise<AiCoderRuntimeToolResult>;
87
+ private ensureRegistry;
88
+ private dispatch;
89
+ }
90
+ export {};
91
+ //# sourceMappingURL=tool-executor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-executor.d.ts","sourceRoot":"","sources":["../../../../src/adapters/node/tools/tool-executor.ts"],"names":[],"mappings":"AAAA,OAAO,EAOL,KAAK,sBAAsB,EAE3B,KAAK,yBAAyB,EAC9B,KAAK,0BAA0B,EAC/B,KAAK,wBAAwB,EAE7B,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EAItB,KAAK,YAAY,EACjB,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,aAAa,EACnB,MAAM,mBAAmB,CAAC;AAI3B,OAAO,EAML,KAAK,4BAA4B,EAClC,MAAM,oCAAoC,CAAC;AAE5C,qBAAa,iBAAkB,SAAQ,KAAK;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM;IAAmB,QAAQ,CAAC,SAAS;IAAU,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM;gBAA5F,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAW,SAAS,UAAQ,EAAW,eAAe,CAAC,EAAE,MAAM,YAAA;CAClH;AACD,MAAM,WAAW,gBAAgB;IAC/B,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EAAE,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;CACrH;AAED,eAAO,MAAM,sBAAsB,8NAaxB,CAAC;AAEZ,eAAO,MAAM,uBAAuB,8DAIzB,CAAC;AAEZ,eAAO,MAAM,qBAAqB,gDAAgE,CAAC;AAEnG,eAAO,MAAM,8BAA8B,4KAUhC,CAAC;AAEZ,eAAO,MAAM,0BAA0B,+XAG5B,CAAC;AAEZ,eAAO,MAAM,6BAA6B,yIAM/B,CAAC;AAEZ,KAAK,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAuBpD,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,sBAAsB;IACrC,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,sBAAsB,GAAG,SAAS,CAAC;IACvD,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,sBAAsB,GAAG,OAAO,CAAC;CACjE;AAED,KAAK,cAAc,GAAG,QAAQ,CAAC;IAC7B,OAAO,CAAC,EAAE,yBAAyB,CAAC;IACpC,MAAM,EAAE,UAAU,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,wBAAwB,CAAC,OAAO,CAAC,CAAC;CAC1C,CAAC,CAAC;AAyFH,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,QAAQ,CAAC,EAAE,YAAY,CAAC;IACjC,QAAQ,CAAC,eAAe,CAAC,EAAE,sBAAsB,CAAC;IAClD,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,YAAY,EAAE,iBAAiB,CAAC;IACzC,QAAQ,CAAC,OAAO,EAAE,iBAAiB,CAAC;IACpC,4FAA4F;IAC5F,QAAQ,CAAC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IACvC,QAAQ,CAAC,aAAa,CAAC,EAAE,gBAAgB,CAAC;IAC1C,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAC7B,yFAAyF;IACzF,QAAQ,CAAC,QAAQ,CAAC,EAAE,YAAY,CAAC;IACjC,mFAAmF;IACnF,QAAQ,CAAC,mBAAmB,CAAC,EAAE,sBAAsB,CAAC;IACtD,6DAA6D;IAC7D,QAAQ,CAAC,iBAAiB,CAAC,EAAE,4BAA4B,CAAC;IAC1D,iEAAiE;IACjE,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,GAAG,eAAe,CAAC;IACnD,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAC;CACnC;AA0ID,qBAAa,gBAAiB,YAAW,0BAA0B;IAiCrD,OAAO,CAAC,QAAQ,CAAC,OAAO;IAhCpC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAiD;IAChF,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA0B;IACxD,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAU;IAC/C,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAsB;IACzD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAA+C;IAChF,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAqC;IACxE,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAqC;IACzE,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAyB;IAC7D,OAAO,CAAC,QAAQ,CAAoC;YAEtC,gBAAgB;gBAsBD,OAAO,EAAE,uBAAuB;IAgBvD,UAAU,CAAC,OAAO,EAAE,mBAAmB;;;;;;;;;;;;;IAWvC,cAAc,CAClB,KAAK,EAAE,QAAQ,CAAC;QAAE,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC,EACnE,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,IAAI,CAAC;IAaV,OAAO,CAAC,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,wBAAwB,CAAC;IA8ErG,OAAO,CAAC,cAAc;YAkBR,QAAQ;CA4kBvB"}