raysurfer 1.4.2 → 1.4.4

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/dist/index.js CHANGED
@@ -1,219 +1,71 @@
1
1
  import { createRequire } from "node:module";
2
- var __create = Object.create;
3
- var __getProtoOf = Object.getPrototypeOf;
4
2
  var __defProp = Object.defineProperty;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __hasOwnProp = Object.prototype.hasOwnProperty;
7
- var __toESM = (mod, isNodeMode, target) => {
8
- target = mod != null ? __create(__getProtoOf(mod)) : {};
9
- const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
10
- for (let key of __getOwnPropNames(mod))
11
- if (!__hasOwnProp.call(to, key))
12
- __defProp(to, key, {
13
- get: () => mod[key],
14
- enumerable: true
15
- });
16
- return to;
3
+ var __returnValue = (v) => v;
4
+ function __exportSetter(name, newValue) {
5
+ this[name] = __returnValue.bind(null, newValue);
6
+ }
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, {
10
+ get: all[name],
11
+ enumerable: true,
12
+ configurable: true,
13
+ set: __exportSetter.bind(all, name)
14
+ });
17
15
  };
16
+ var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
18
17
  var __require = /* @__PURE__ */ createRequire(import.meta.url);
19
18
 
20
- // src/types.ts
21
- var ExecutionState;
22
- ((ExecutionState2) => {
23
- ExecutionState2["COMPLETED"] = "completed";
24
- ExecutionState2["ERRORED"] = "errored";
25
- ExecutionState2["TIMED_OUT"] = "timed_out";
26
- ExecutionState2["CANCELLED"] = "cancelled";
27
- })(ExecutionState ||= {});
28
- var AgentVerdict;
29
- ((AgentVerdict2) => {
30
- AgentVerdict2["THUMBS_UP"] = "thumbs_up";
31
- AgentVerdict2["THUMBS_DOWN"] = "thumbs_down";
32
- AgentVerdict2["PENDING"] = "pending";
33
- })(AgentVerdict ||= {});
34
-
35
- // src/accessible.ts
36
- function toJsonLike(value) {
37
- if (value === null || typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
38
- return value;
39
- }
40
- if (value === undefined) {
41
- return null;
42
- }
43
- if (Array.isArray(value)) {
44
- return value.map((item) => toJsonLike(item));
45
- }
46
- if (typeof value === "object") {
47
- const result = {};
48
- for (const [key, nested] of Object.entries(value)) {
49
- result[key] = toJsonLike(nested);
19
+ // src/errors.ts
20
+ var RaySurferError, APIError, AuthenticationError, CacheUnavailableError, RateLimitError, ValidationError;
21
+ var init_errors = __esm(() => {
22
+ RaySurferError = class RaySurferError extends Error {
23
+ constructor(message) {
24
+ super(message);
25
+ this.name = "RaySurferError";
50
26
  }
51
- return result;
52
- }
53
- return String(value);
54
- }
55
- function queueUsageTracking(fn, args, result, durationMs, errorMessage) {
56
- const client = fn._raysurferClient;
57
- if (!client)
58
- return;
59
- const codeBlockId = fn._raysurferSchema.codeBlockId ?? `function_registry:${fn._raysurferSchema.name}`;
60
- const outputData = errorMessage === undefined ? result : { error: errorMessage };
61
- client.storeExecution({
62
- codeBlockId,
63
- triggeringTask: `agent_accessible:${fn._raysurferSchema.name}`,
64
- inputData: {
65
- args: toJsonLike(args)
66
- },
67
- outputData: toJsonLike(outputData),
68
- executionState: errorMessage ? "errored" /* ERRORED */ : "completed" /* COMPLETED */,
69
- durationMs,
70
- errorMessage
71
- }).catch(() => {});
72
- }
73
- function inferParameters(fn) {
74
- const src = fn.toString();
75
- const match = /^[^(]*\(([^)]*)\)/.exec(src);
76
- const paramStr = match?.[1];
77
- if (!paramStr?.trim())
78
- return {};
79
- const params = {};
80
- const parts = paramStr.split(",");
81
- for (const part of parts) {
82
- const cleaned = part.trim().replace(/\/\*.*?\*\//g, "").replace(/=.*$/, "").replace(/:.*$/, "").trim();
83
- if (cleaned && cleaned !== "..." && !cleaned.startsWith("...")) {
84
- params[cleaned] = "string";
27
+ };
28
+ APIError = class APIError extends RaySurferError {
29
+ statusCode;
30
+ constructor(message, statusCode) {
31
+ super(message);
32
+ this.name = "APIError";
33
+ this.statusCode = statusCode;
85
34
  }
86
- }
87
- return params;
88
- }
89
- function agentAccessible(fn, options) {
90
- const resolvedName = options?.name ?? fn.name ?? "anonymous";
91
- const resolvedDescription = options?.description ?? "";
92
- const resolvedSchema = options?.inputSchema ?? options?.parameters ?? inferParameters(fn);
93
- let marked;
94
- const wrapped = (...args) => {
95
- const started = Date.now();
96
- try {
97
- const result = fn(...args);
98
- if (result instanceof Promise) {
99
- const trackedPromise = result.then((resolved) => {
100
- queueUsageTracking(marked, args, resolved, Date.now() - started);
101
- return resolved;
102
- }).catch((error) => {
103
- const message = error instanceof Error ? error.message : String(error);
104
- queueUsageTracking(marked, args, null, Date.now() - started, message);
105
- throw error;
106
- });
107
- return trackedPromise;
108
- }
109
- queueUsageTracking(marked, args, result, Date.now() - started);
110
- return result;
111
- } catch (error) {
112
- const message = error instanceof Error ? error.message : String(error);
113
- queueUsageTracking(marked, args, null, Date.now() - started, message);
114
- throw error;
35
+ };
36
+ AuthenticationError = class AuthenticationError extends RaySurferError {
37
+ constructor(message = "Invalid API key") {
38
+ super(message);
39
+ this.name = "AuthenticationError";
115
40
  }
116
41
  };
117
- marked = wrapped;
118
- marked._raysurferAccessible = true;
119
- marked._raysurferSchema = {
120
- name: resolvedName,
121
- description: resolvedDescription,
122
- inputSchema: resolvedSchema,
123
- parameters: resolvedSchema,
124
- source: fn.toString()
42
+ CacheUnavailableError = class CacheUnavailableError extends RaySurferError {
43
+ statusCode;
44
+ constructor(message = "Cache backend is unreachable", statusCode = 503) {
45
+ super(message);
46
+ this.name = "CacheUnavailableError";
47
+ this.statusCode = statusCode;
48
+ }
125
49
  };
126
- return marked;
127
- }
128
- function toAnthropicTool(fn) {
129
- const schema = fn._raysurferSchema;
130
- return {
131
- name: schema.name,
132
- description: schema.description,
133
- input_schema: schema.inputSchema
50
+ RateLimitError = class RateLimitError extends RaySurferError {
51
+ retryAfter;
52
+ constructor(message = "Rate limit exceeded", retryAfter) {
53
+ super(message);
54
+ this.name = "RateLimitError";
55
+ this.retryAfter = retryAfter;
56
+ }
134
57
  };
135
- }
136
- async function publishFunctionRegistry(client, functions) {
137
- const snippetNames = [];
138
- for (const fn of functions) {
139
- if (!fn._raysurferAccessible)
140
- continue;
141
- const schema = fn._raysurferSchema;
142
- const resp = await client.uploadNewCodeSnip({
143
- task: `Call ${schema.name}: ${schema.description}`,
144
- fileWritten: { path: `${schema.name}.ts`, content: schema.source },
145
- succeeded: true,
146
- useRaysurferAiVoting: false,
147
- tags: ["function_registry", "agent_accessible"]
148
- });
149
- if (resp.snippetName) {
150
- snippetNames.push(resp.snippetName);
151
- schema.codeBlockId = resp.snippetName;
58
+ ValidationError = class ValidationError extends RaySurferError {
59
+ field;
60
+ constructor(message = "Validation failed", field) {
61
+ super(message);
62
+ this.name = "ValidationError";
63
+ this.field = field;
152
64
  }
153
- setTrackingClient(fn, client);
154
- }
155
- return snippetNames;
156
- }
157
- function setTrackingClient(fn, client) {
158
- fn._raysurferClient = client;
159
- }
160
- // src/errors.ts
161
- class RaySurferError extends Error {
162
- constructor(message) {
163
- super(message);
164
- this.name = "RaySurferError";
165
- }
166
- }
167
-
168
- class APIError extends RaySurferError {
169
- statusCode;
170
- constructor(message, statusCode) {
171
- super(message);
172
- this.name = "APIError";
173
- this.statusCode = statusCode;
174
- }
175
- }
176
-
177
- class AuthenticationError extends RaySurferError {
178
- constructor(message = "Invalid API key") {
179
- super(message);
180
- this.name = "AuthenticationError";
181
- }
182
- }
183
-
184
- class CacheUnavailableError extends RaySurferError {
185
- statusCode;
186
- constructor(message = "Cache backend is unreachable", statusCode = 503) {
187
- super(message);
188
- this.name = "CacheUnavailableError";
189
- this.statusCode = statusCode;
190
- }
191
- }
192
-
193
- class RateLimitError extends RaySurferError {
194
- retryAfter;
195
- constructor(message = "Rate limit exceeded", retryAfter) {
196
- super(message);
197
- this.name = "RateLimitError";
198
- this.retryAfter = retryAfter;
199
- }
200
- }
201
-
202
- class ValidationError extends RaySurferError {
203
- field;
204
- constructor(message = "Validation failed", field) {
205
- super(message);
206
- this.name = "ValidationError";
207
- this.field = field;
208
- }
209
- }
65
+ };
66
+ });
210
67
 
211
68
  // src/client.ts
212
- var VERSION = "1.4.0";
213
- var DEFAULT_BASE_URL = "https://api.raysurfer.com";
214
- var MAX_RETRIES = 3;
215
- var RETRY_BASE_DELAY = 500;
216
- var RETRYABLE_STATUS_CODES = new Set([429, 500, 502, 503, 504]);
217
69
  function normalizeDependencies(rawDeps) {
218
70
  if (!rawDeps)
219
71
  return {};
@@ -385,6 +237,9 @@ class RaySurfer {
385
237
  if (typeof taskOrOptions === "object") {
386
238
  opts = taskOrOptions;
387
239
  } else {
240
+ if (!fileWritten || succeeded === undefined) {
241
+ throw new Error("fileWritten and succeeded are required when using positional arguments");
242
+ }
388
243
  opts = {
389
244
  task: taskOrOptions,
390
245
  fileWritten,
@@ -400,6 +255,9 @@ class RaySurfer {
400
255
  voteCount
401
256
  };
402
257
  }
258
+ if (opts.repoPath || opts.githubUrl) {
259
+ return this.uploadRepo(opts);
260
+ }
403
261
  if (opts.fileWritten && opts.filesWritten) {
404
262
  throw new Error("Provide either fileWritten or filesWritten, not both.");
405
263
  }
@@ -411,7 +269,7 @@ class RaySurfer {
411
269
  normalizedFiles.push(...opts.filesWritten);
412
270
  }
413
271
  if (normalizedFiles.length === 0) {
414
- throw new Error("Missing required file input: provide fileWritten or filesWritten.");
272
+ throw new Error("Missing required file input: provide fileWritten, filesWritten, repoPath, or githubUrl.");
415
273
  }
416
274
  if (normalizedFiles.length > 1) {
417
275
  const responses = [];
@@ -449,7 +307,8 @@ class RaySurfer {
449
307
  public: opts.public || undefined,
450
308
  vote_source: opts.voteSource,
451
309
  vote_count: opts.voteCount,
452
- per_function_reputation: opts.perFunctionReputation || undefined
310
+ per_function_reputation: opts.perFunctionReputation || undefined,
311
+ content_type: opts.contentType
453
312
  };
454
313
  const result = await this.request("POST", "/api/store/execution-result", data, this.workspaceHeaders(opts.workspaceId));
455
314
  return {
@@ -459,6 +318,63 @@ class RaySurfer {
459
318
  snippetName: result.snippet_name ?? null
460
319
  };
461
320
  }
321
+ async uploadRepo(opts) {
322
+ const files = [];
323
+ if (opts.repoPath) {
324
+ const fs = await import("node:fs");
325
+ const path = await import("node:path");
326
+ const skipDirs = new Set([
327
+ ".git",
328
+ "__pycache__",
329
+ "node_modules",
330
+ ".venv",
331
+ "venv",
332
+ ".tox",
333
+ "dist",
334
+ "build"
335
+ ]);
336
+ const walkDir = (dir, base) => {
337
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
338
+ if (skipDirs.has(entry.name))
339
+ continue;
340
+ const fullPath = path.join(dir, entry.name);
341
+ const relPath = path.join(base, entry.name);
342
+ if (entry.isDirectory()) {
343
+ walkDir(fullPath, relPath);
344
+ } else if (entry.isFile()) {
345
+ try {
346
+ const content = fs.readFileSync(fullPath, "utf-8");
347
+ files.push({ path: relPath, content });
348
+ } catch {}
349
+ }
350
+ }
351
+ };
352
+ walkDir(opts.repoPath, "");
353
+ }
354
+ const requestData = {
355
+ task: opts.task,
356
+ files
357
+ };
358
+ if (opts.githubUrl) {
359
+ requestData.github_url = opts.githubUrl;
360
+ }
361
+ if (opts.dependencies) {
362
+ requestData.dependencies = opts.dependencies;
363
+ }
364
+ if (opts.tags) {
365
+ requestData.tags = opts.tags;
366
+ }
367
+ if (opts.contentType) {
368
+ requestData.content_type = opts.contentType;
369
+ }
370
+ const result = await this.request("POST", "/api/store/repo", requestData, this.workspaceHeaders(opts.workspaceId));
371
+ return {
372
+ success: result.success,
373
+ codeBlocksStored: result.success ? 1 : 0,
374
+ message: result.message,
375
+ snippetName: result.repo_id ?? null
376
+ };
377
+ }
462
378
  uploadNewCodeSnip = this.upload.bind(this);
463
379
  uploadNewCodeSnips = this.upload.bind(this);
464
380
  async delete(snippetId, options) {
@@ -474,6 +390,9 @@ class RaySurfer {
474
390
  if (!Array.isArray(promptsOrOptions)) {
475
391
  opts = promptsOrOptions;
476
392
  } else {
393
+ if (!filesWritten) {
394
+ throw new Error("filesWritten is required when using positional arguments");
395
+ }
477
396
  opts = {
478
397
  prompts: promptsOrOptions,
479
398
  filesWritten,
@@ -526,6 +445,15 @@ class RaySurfer {
526
445
  if (params.perFunctionReputation) {
527
446
  data.per_function_reputation = true;
528
447
  }
448
+ if (params.resultType && params.resultType !== "any") {
449
+ data.result_type = params.resultType;
450
+ }
451
+ if (params.contentType) {
452
+ data.content_type = params.contentType;
453
+ }
454
+ if (params.autoSummarize) {
455
+ data.auto_summarize = true;
456
+ }
529
457
  const result = await this.request("POST", "/api/retrieve/search", data, this.workspaceHeaders(params.workspaceId));
530
458
  return {
531
459
  matches: result.matches.map((m) => {
@@ -563,7 +491,13 @@ class RaySurfer {
563
491
  dependencies: normalizeDependencies(m.dependencies),
564
492
  agentId: m.agent_id ?? null,
565
493
  comments: m.comments ?? [],
566
- functions
494
+ functions,
495
+ type: m.type ?? "file",
496
+ downloadUrl: m.download_url ?? null,
497
+ fileTree: m.file_tree ?? null,
498
+ fileCount: m.file_count ?? null,
499
+ framework: m.framework ?? null,
500
+ readmePreview: m.readme_preview ?? null
567
501
  };
568
502
  }),
569
503
  totalFound: result.total_found,
@@ -716,7 +650,7 @@ class RaySurfer {
716
650
 
717
651
  ## IMPORTANT: Pre-validated Code Files Available
718
652
  `,
719
- "The following validated code has been retrieved from the cache. " + `Use these files directly instead of regenerating code.
653
+ `The following validated code has been retrieved from the cache. Use these files directly instead of regenerating code.
720
654
  `
721
655
  ];
722
656
  for (const f of files) {
@@ -851,6 +785,35 @@ class RaySurfer {
851
785
  hasMore: response.has_more
852
786
  };
853
787
  }
788
+ async log(params) {
789
+ const response = await this.request("POST", "/api/logs/ingest", {
790
+ log_hash: params.logHash,
791
+ value: params.value,
792
+ source: params.source ?? "",
793
+ scope: params.scope ?? "",
794
+ run_id: params.runId ?? "",
795
+ metadata: params.metadata ?? {}
796
+ });
797
+ return response.log_hash;
798
+ }
799
+ async getLog(logHash, limit = 50) {
800
+ const response = await this.request("GET", `/api/logs/hash/${logHash}`, { limit });
801
+ return {
802
+ logHash: response.log_hash,
803
+ source: response.source,
804
+ totalEvents: response.total_events,
805
+ recentEvents: response.recent_events.map((e) => ({
806
+ id: e.id,
807
+ logHash: e.log_hash,
808
+ source: e.source,
809
+ value: e.value,
810
+ preview: e.preview,
811
+ runId: e.run_id,
812
+ metadata: e.metadata,
813
+ loggedAt: e.logged_at
814
+ }))
815
+ };
816
+ }
854
817
  async voteCodeSnip(params) {
855
818
  const data = {
856
819
  task: params.task,
@@ -1067,6 +1030,35 @@ class RaySurfer {
1067
1030
  codegen
1068
1031
  });
1069
1032
  }
1033
+ async chat(query, options) {
1034
+ const response = await this.request("POST", "/api/agent-chat", {
1035
+ user_query: query,
1036
+ user_id: options.user,
1037
+ org_id: options.org,
1038
+ model: options.model ?? "sonnet",
1039
+ max_turns: options.maxTurns ?? 8
1040
+ });
1041
+ return {
1042
+ success: response.success,
1043
+ output: response.output,
1044
+ error: response.error,
1045
+ sessionId: response.session_id,
1046
+ durationMs: response.duration_ms,
1047
+ changedFiles: response.changed_files ?? [],
1048
+ workspaceFiles: response.org_workspace_files ?? []
1049
+ };
1050
+ }
1051
+ async heartbeat(options) {
1052
+ return this.request("POST", "/api/agents/heartbeat", {
1053
+ agent_id: options.agentId,
1054
+ agent_name: options.agentName,
1055
+ status: options.status ?? "running",
1056
+ current_task: options.currentTask,
1057
+ cpu_percent: options.cpuPercent,
1058
+ memory_percent: options.memoryPercent,
1059
+ metadata: options.metadata
1060
+ });
1061
+ }
1070
1062
  async publishFunctionRegistry(functions) {
1071
1063
  const snippetNames = [];
1072
1064
  for (const fn of functions) {
@@ -1115,52 +1107,732 @@ class RaySurfer {
1115
1107
  };
1116
1108
  }
1117
1109
  }
1118
- var client_default = RaySurfer;
1119
-
1120
- // src/agent.ts
1121
- var DEFAULT_CODEGEN_MODEL = "claude-opus-4-6";
1122
- var DEFAULT_EXECUTION_TIMEOUT_MS = 300000;
1123
- var CODEGEN_DOCS_URL = "https://docs.raysurfer.com/sdk/typescript#programmatic-tool-calling";
1124
- function missingCodegenKeyError(value) {
1125
- return new Error(`Invalid codegenApiKey value: ${String(value)}. Expected format: non-empty provider API key string. ` + "Current tier/state: tier=unknown, codegen_api_key_missing=true (not configured on app and not provided at call-time). " + `Fix: pass codegenApiKey in app config or run(...). Docs: ${CODEGEN_DOCS_URL}`);
1126
- }
1127
- function invalidCodegenPromptError(value) {
1128
- return new Error(`Invalid codegenPrompt value: ${String(value)}. Expected format: non-empty prompt string. ` + "Current tier/state: tier=unknown, codegen_prompt_invalid=true. " + `Fix: pass codegenPrompt or provide a non-empty task. Docs: ${CODEGEN_DOCS_URL}`);
1129
- }
1110
+ var VERSION = "1.4.3", DEFAULT_BASE_URL = "https://api.raysurfer.com", MAX_RETRIES = 3, RETRY_BASE_DELAY = 500, RETRYABLE_STATUS_CODES, client_default;
1111
+ var init_client = __esm(() => {
1112
+ init_errors();
1113
+ RETRYABLE_STATUS_CODES = new Set([429, 500, 502, 503, 504]);
1114
+ client_default = RaySurfer;
1115
+ });
1130
1116
 
1131
- class CodegenApp {
1132
- _raysurfer;
1133
- _defaultCodegenApiKey;
1134
- _defaultCodegenModel;
1135
- _defaultExecutionTimeoutMs;
1136
- constructor(options = {}) {
1137
- const {
1138
- raysurfer,
1139
- codegenApiKey,
1140
- codegenModel,
1141
- executionTimeoutMs,
1142
- ...clientOptions
1143
- } = options;
1144
- this._raysurfer = raysurfer ?? new client_default(clientOptions);
1145
- this._defaultCodegenApiKey = codegenApiKey;
1146
- this._defaultCodegenModel = codegenModel ?? DEFAULT_CODEGEN_MODEL;
1147
- this._defaultExecutionTimeoutMs = executionTimeoutMs ?? DEFAULT_EXECUTION_TIMEOUT_MS;
1117
+ // src/sdk-client.ts
1118
+ var exports_sdk_client = {};
1119
+ __export(exports_sdk_client, {
1120
+ query: () => query,
1121
+ default: () => sdk_client_default,
1122
+ RaysurferOpencodeClient: () => ClaudeSDKClient,
1123
+ RaysurferClient: () => ClaudeSDKClient,
1124
+ ClaudeSDKClient: () => ClaudeSDKClient
1125
+ });
1126
+ import { existsSync, mkdirSync, readFileSync as readFileSync2, writeFileSync } from "node:fs";
1127
+ import { join } from "node:path";
1128
+ function resolveRunParseSampleRate(configured) {
1129
+ if (configured !== undefined) {
1130
+ if (!Number.isFinite(configured) || configured < 0 || configured > 1) {
1131
+ throw new Error(`runParseSampleRate must be between 0.0 and 1.0 inclusive; got ${configured}.`);
1132
+ }
1133
+ return configured;
1148
1134
  }
1149
- get raysurfer() {
1150
- return this._raysurfer;
1135
+ const envValue = process.env[RUN_PARSE_SAMPLE_RATE_ENV_VAR];
1136
+ if (!envValue || envValue.trim() === "") {
1137
+ return DEFAULT_RUN_PARSE_SAMPLE_RATE;
1151
1138
  }
1152
- tool(name, description, parameters, callback) {
1153
- this._raysurfer.tool(name, description, parameters, callback);
1154
- return this;
1139
+ const parsed = Number(envValue);
1140
+ if (!Number.isFinite(parsed) || parsed < 0 || parsed > 1) {
1141
+ console.warn(`[raysurfer] ${RUN_PARSE_SAMPLE_RATE_ENV_VAR}=${JSON.stringify(envValue)} is invalid. ` + `Expected a number between 0.0 and 1.0 inclusive. Falling back to ${DEFAULT_RUN_PARSE_SAMPLE_RATE}.`);
1142
+ return DEFAULT_RUN_PARSE_SAMPLE_RATE;
1155
1143
  }
1156
- async run(task, options = {}) {
1157
- const codegenApiKey = this.resolveCodegenApiKey(options.codegenApiKey);
1158
- const codegenPrompt = this.resolveCodegenPrompt(task, options.codegenPrompt);
1159
- const codegenModel = options.codegenModel ?? this._defaultCodegenModel;
1160
- const timeout = options.executionTimeoutMs ?? this._defaultExecutionTimeoutMs;
1161
- return this._raysurfer.executeWithSandboxCodegen(task, {
1162
- provider: "anthropic",
1163
- apiKey: codegenApiKey,
1144
+ return parsed;
1145
+ }
1146
+ function shouldParseRunForAiVoting(sampleRate) {
1147
+ if (sampleRate >= 1)
1148
+ return true;
1149
+ if (sampleRate <= 0)
1150
+ return false;
1151
+ return Math.random() < sampleRate;
1152
+ }
1153
+ function augmentSystemPrompt(systemPrompt, addition) {
1154
+ if (!addition)
1155
+ return systemPrompt;
1156
+ if (typeof systemPrompt === "string")
1157
+ return systemPrompt + addition;
1158
+ if (systemPrompt?.type === "preset") {
1159
+ return { ...systemPrompt, append: (systemPrompt.append ?? "") + addition };
1160
+ }
1161
+ return addition;
1162
+ }
1163
+ function splitOptions(options) {
1164
+ const {
1165
+ workspaceId,
1166
+ publicSnips,
1167
+ debug,
1168
+ runParseSampleRate,
1169
+ workingDirectory,
1170
+ agentId,
1171
+ ...sdkOptions
1172
+ } = options;
1173
+ return {
1174
+ sdkOptions,
1175
+ extras: {
1176
+ workspaceId,
1177
+ publicSnips,
1178
+ debug,
1179
+ runParseSampleRate,
1180
+ workingDirectory,
1181
+ agentId
1182
+ }
1183
+ };
1184
+ }
1185
+ function applyDefaultAgentCompatibilityOptions(options) {
1186
+ const merged = { ...options };
1187
+ const hasToolsPreset = merged.tools !== undefined && merged.tools !== null;
1188
+ const hasAllowedTools = Array.isArray(merged.allowedTools) && merged.allowedTools.length > 0;
1189
+ if (!hasToolsPreset && !hasAllowedTools) {
1190
+ merged.tools = DEFAULT_AGENT_COMPAT_TOOLS_PRESET;
1191
+ }
1192
+ if (merged.sandbox && typeof merged.sandbox === "object") {
1193
+ merged.sandbox = {
1194
+ ...DEFAULT_SANDBOX_SETTINGS,
1195
+ ...merged.sandbox
1196
+ };
1197
+ } else {
1198
+ merged.sandbox = { ...DEFAULT_SANDBOX_SETTINGS };
1199
+ }
1200
+ return merged;
1201
+ }
1202
+ function query(params) {
1203
+ return new RaysurferQuery(params);
1204
+ }
1205
+
1206
+ class ClaudeSDKClient {
1207
+ options;
1208
+ constructor(options = {}) {
1209
+ this.options = options;
1210
+ }
1211
+ query(prompt) {
1212
+ return query({ prompt, options: this.options });
1213
+ }
1214
+ }
1215
+ var DEFAULT_RAYSURFER_URL = "https://api.raysurfer.com", CACHE_DIR = ".raysurfer_code", DEFAULT_RUN_PARSE_SAMPLE_RATE = 1, RUN_PARSE_SAMPLE_RATE_ENV_VAR = "RAYSURFER_RUN_PARSE_SAMPLE_RATE", DEFAULT_AGENT_COMPAT_TOOLS_PRESET, DEFAULT_SANDBOX_SETTINGS, FILE_MODIFY_TOOLS, TRACKABLE_EXTENSIONS, BASH_OUTPUT_PATTERNS, createDebugLogger = (enabled) => ({
1216
+ log: (...args) => enabled && console.log("[raysurfer]", ...args),
1217
+ time: (label) => enabled && console.time(`[raysurfer] ${label}`),
1218
+ timeEnd: (label) => enabled && console.timeEnd(`[raysurfer] ${label}`),
1219
+ table: (data) => enabled && console.table(data),
1220
+ group: (label) => enabled && console.group(`[raysurfer] ${label}`),
1221
+ groupEnd: () => enabled && console.groupEnd()
1222
+ }), RaysurferQuery, sdk_client_default;
1223
+ var init_sdk_client = __esm(() => {
1224
+ init_client();
1225
+ DEFAULT_AGENT_COMPAT_TOOLS_PRESET = {
1226
+ type: "preset",
1227
+ preset: "claude_code"
1228
+ };
1229
+ DEFAULT_SANDBOX_SETTINGS = {
1230
+ enabled: true,
1231
+ autoAllowBashIfSandboxed: true
1232
+ };
1233
+ FILE_MODIFY_TOOLS = ["Write", "Edit", "MultiEdit", "NotebookEdit"];
1234
+ TRACKABLE_EXTENSIONS = new Set([
1235
+ ".py",
1236
+ ".js",
1237
+ ".ts",
1238
+ ".rb",
1239
+ ".go",
1240
+ ".rs",
1241
+ ".java",
1242
+ ".cpp",
1243
+ ".c",
1244
+ ".h",
1245
+ ".pdf",
1246
+ ".docx",
1247
+ ".xlsx",
1248
+ ".csv",
1249
+ ".json",
1250
+ ".yaml",
1251
+ ".yml",
1252
+ ".xml",
1253
+ ".html",
1254
+ ".css",
1255
+ ".md",
1256
+ ".txt",
1257
+ ".sh",
1258
+ ".sql"
1259
+ ]);
1260
+ BASH_OUTPUT_PATTERNS = [
1261
+ />>\s*([^\s;&|]+)/g,
1262
+ />\s*([^\s;&|]+)/g,
1263
+ /-o\s+([^\s;&|]+)/g,
1264
+ /--output[=\s]+([^\s;&|]+)/g,
1265
+ /savefig\(['"]([^'"]+)['"]\)/g,
1266
+ /to_csv\(['"]([^'"]+)['"]\)/g,
1267
+ /to_excel\(['"]([^'"]+)['"]\)/g,
1268
+ /write\(['"]([^'"]+)['"]\)/g
1269
+ ];
1270
+ RaysurferQuery = class RaysurferQuery {
1271
+ _inner = null;
1272
+ _initPromise = null;
1273
+ _raysurfer = null;
1274
+ _cachedFiles = [];
1275
+ _modifiedFilePaths = new Set;
1276
+ _bashGeneratedFiles = new Set;
1277
+ _executionLogs = [];
1278
+ _taskSucceeded = false;
1279
+ _generatedCodeBlocks = [];
1280
+ _cacheUploadDone = false;
1281
+ _messageCount = 0;
1282
+ _startTime = 0;
1283
+ _promptText;
1284
+ _params;
1285
+ _debug;
1286
+ _cacheEnabled;
1287
+ _workDir;
1288
+ _apiKey;
1289
+ _baseUrl;
1290
+ _extras;
1291
+ _sdkOptions;
1292
+ _runParseSampleRate;
1293
+ _parseRunForAiVoting;
1294
+ constructor(params) {
1295
+ this._params = params;
1296
+ const options = params.options ?? {};
1297
+ const { sdkOptions, extras } = splitOptions(options);
1298
+ this._sdkOptions = applyDefaultAgentCompatibilityOptions(sdkOptions);
1299
+ this._extras = extras;
1300
+ this._promptText = typeof params.prompt === "string" ? params.prompt : null;
1301
+ const debugEnabled = extras.debug || process.env.RAYSURFER_DEBUG === "true";
1302
+ this._debug = createDebugLogger(debugEnabled);
1303
+ this._apiKey = process.env.RAYSURFER_API_KEY;
1304
+ this._baseUrl = process.env.RAYSURFER_BASE_URL || DEFAULT_RAYSURFER_URL;
1305
+ this._cacheEnabled = !!this._apiKey;
1306
+ this._runParseSampleRate = resolveRunParseSampleRate(extras.runParseSampleRate);
1307
+ this._parseRunForAiVoting = shouldParseRunForAiVoting(this._runParseSampleRate);
1308
+ if (extras.workingDirectory && !sdkOptions.cwd) {
1309
+ console.warn("[raysurfer] workingDirectory is deprecated, use cwd instead");
1310
+ this._sdkOptions.cwd = extras.workingDirectory;
1311
+ }
1312
+ this._workDir = this._sdkOptions.cwd || process.cwd();
1313
+ }
1314
+ async _initialize() {
1315
+ this._debug.group("Raysurfer Query Started");
1316
+ this._debug.log("Prompt:", this._promptText ?? "<stream>");
1317
+ this._debug.log("Cache enabled:", this._cacheEnabled);
1318
+ this._debug.log("Base URL:", this._baseUrl);
1319
+ this._debug.log("Run parse sample rate:", this._runParseSampleRate);
1320
+ this._debug.log("Parse this run for AI voting:", this._parseRunForAiVoting);
1321
+ if (!this._cacheEnabled) {
1322
+ console.warn("[raysurfer] RAYSURFER_API_KEY not set - caching disabled");
1323
+ }
1324
+ let addToLlmPrompt = "";
1325
+ if (this._cacheEnabled && this._promptText) {
1326
+ this._raysurfer = new RaySurfer({
1327
+ apiKey: this._apiKey,
1328
+ baseUrl: this._baseUrl,
1329
+ workspaceId: this._extras.workspaceId,
1330
+ snipsDesired: this._extras.workspaceId ? "client" : undefined,
1331
+ publicSnips: this._extras.publicSnips,
1332
+ agentId: this._extras.agentId
1333
+ });
1334
+ try {
1335
+ this._debug.time("Cache lookup");
1336
+ const cacheDir = join(this._workDir, CACHE_DIR);
1337
+ const response = await this._raysurfer.getCodeFiles({
1338
+ task: this._promptText,
1339
+ topK: 5,
1340
+ minVerdictScore: 0.3,
1341
+ preferComplete: true,
1342
+ perFunctionReputation: true,
1343
+ cacheDir
1344
+ });
1345
+ this._debug.timeEnd("Cache lookup");
1346
+ this._cachedFiles = response.files;
1347
+ addToLlmPrompt = response.addToLlmPrompt;
1348
+ this._debug.log(`Found ${this._cachedFiles.length} cached files:`);
1349
+ console.log("[raysurfer] Cache hit:", this._cachedFiles.length, "snippets retrieved");
1350
+ if (this._cachedFiles.length > 0) {
1351
+ this._debug.table(this._cachedFiles.map((f) => ({
1352
+ filename: f.filename,
1353
+ score: `${Math.round(f.score * 100)}%`,
1354
+ thumbs: `${f.thumbsUp}/${f.thumbsDown}`,
1355
+ sourceLength: `${f.source.length} chars`
1356
+ })));
1357
+ try {
1358
+ mkdirSync(cacheDir, { recursive: true });
1359
+ for (const file of this._cachedFiles) {
1360
+ const filePath = join(cacheDir, file.filename);
1361
+ writeFileSync(filePath, file.source, "utf-8");
1362
+ this._debug.log(` → Wrote cached file: ${filePath}`);
1363
+ this._modifiedFilePaths.add(filePath);
1364
+ }
1365
+ } catch (writeErr) {
1366
+ this._debug.log("Failed to write cached files:", writeErr instanceof Error ? writeErr : String(writeErr));
1367
+ }
1368
+ }
1369
+ } catch (error) {
1370
+ const errMsg = error instanceof Error ? error.message : String(error);
1371
+ this._debug.log("Cache lookup failed:", errMsg);
1372
+ console.warn("[raysurfer] Cache unavailable:", errMsg);
1373
+ }
1374
+ }
1375
+ const augmented = augmentSystemPrompt(this._sdkOptions.systemPrompt, addToLlmPrompt);
1376
+ const augmentedOptions = {
1377
+ ...this._sdkOptions,
1378
+ systemPrompt: augmented
1379
+ };
1380
+ this._debug.log("Augmented prompt addition:", addToLlmPrompt.length, "chars");
1381
+ let sdkQueryFn;
1382
+ try {
1383
+ const sdk = await import("@anthropic-ai/claude-agent-sdk");
1384
+ sdkQueryFn = sdk.query;
1385
+ } catch {
1386
+ throw new Error("Could not import @anthropic-ai/claude-agent-sdk. Install it with: npm install @anthropic-ai/claude-agent-sdk");
1387
+ }
1388
+ this._debug.time("Claude API call");
1389
+ this._debug.log("Calling Claude Agent SDK...");
1390
+ this._startTime = Date.now();
1391
+ this._inner = sdkQueryFn({
1392
+ prompt: this._params.prompt,
1393
+ options: augmentedOptions
1394
+ });
1395
+ }
1396
+ async _ensureInit() {
1397
+ if (!this._inner) {
1398
+ if (!this._initPromise) {
1399
+ this._initPromise = this._initialize();
1400
+ }
1401
+ await this._initPromise;
1402
+ }
1403
+ return this._inner;
1404
+ }
1405
+ _extractBashOutputFiles(command) {
1406
+ for (const pattern of BASH_OUTPUT_PATTERNS) {
1407
+ pattern.lastIndex = 0;
1408
+ let match = pattern.exec(command);
1409
+ while (match !== null) {
1410
+ const filePath = match[1];
1411
+ if (filePath && filePath.length > 0) {
1412
+ const ext = filePath.substring(filePath.lastIndexOf(".")).toLowerCase();
1413
+ if (TRACKABLE_EXTENSIONS.has(ext)) {
1414
+ this._bashGeneratedFiles.add(filePath);
1415
+ this._debug.log(` → Bash output file detected: ${filePath}`);
1416
+ }
1417
+ }
1418
+ match = pattern.exec(command);
1419
+ }
1420
+ }
1421
+ }
1422
+ _trackMessage(message) {
1423
+ this._messageCount++;
1424
+ const msg = message;
1425
+ const elapsed = Date.now() - this._startTime;
1426
+ this._debug.log(`
1427
+ ═══════════════════════════════════════════════════`);
1428
+ this._debug.log(`Message #${this._messageCount} [${elapsed}ms] type=${msg.type} subtype=${msg.subtype ?? "none"}`);
1429
+ this._debug.log(`═══════════════════════════════════════════════════`);
1430
+ this._debug.log(JSON.stringify(msg, null, 2));
1431
+ if (msg.type === "assistant" && msg.message?.content) {
1432
+ const blocks = msg.message.content;
1433
+ for (const block of blocks) {
1434
+ if (block.type === "tool_use" && block.name && FILE_MODIFY_TOOLS.includes(block.name)) {
1435
+ const filePath = block.input?.file_path ?? block.input?.notebook_path;
1436
+ if (filePath) {
1437
+ this._debug.log(` → ${block.name} tool detected:`, filePath);
1438
+ this._modifiedFilePaths.add(filePath);
1439
+ }
1440
+ }
1441
+ if (block.type === "tool_use" && block.name === "Bash") {
1442
+ const command = block.input?.command;
1443
+ if (command) {
1444
+ this._extractBashOutputFiles(command);
1445
+ }
1446
+ }
1447
+ if (block.type === "tool_result" && block.content) {
1448
+ if (this._parseRunForAiVoting) {
1449
+ this._executionLogs.push(block.content.slice(0, 5000));
1450
+ }
1451
+ }
1452
+ if (block.type === "text" && block.text) {
1453
+ const codeMatches = block.text.match(/```(?:typescript|javascript|ts|js)?\n?([\s\S]*?)\n?```/g);
1454
+ if (codeMatches) {
1455
+ for (const match of codeMatches) {
1456
+ const code = match.replace(/```(?:typescript|javascript|ts|js)?\n?/, "").replace(/\n?```$/, "");
1457
+ if (code.trim().length > 50) {
1458
+ this._generatedCodeBlocks.push(code.trim());
1459
+ this._debug.log(` → Extracted code block (${code.length} chars)`);
1460
+ }
1461
+ }
1462
+ }
1463
+ }
1464
+ }
1465
+ }
1466
+ if (msg.type === "result" && msg.subtype === "success") {
1467
+ this._taskSucceeded = true;
1468
+ this._debug.timeEnd("Claude API call");
1469
+ this._debug.log("Task succeeded!");
1470
+ this._debug.log(" Duration:", msg.duration_ms, "ms");
1471
+ this._debug.log(" Total cost:", msg.total_cost_usd, "USD");
1472
+ this._debug.log(" Turns:", msg.num_turns);
1473
+ }
1474
+ if (msg.type === "result" && msg.subtype !== "success") {
1475
+ this._debug.timeEnd("Claude API call");
1476
+ this._debug.log("Task failed:", msg.subtype);
1477
+ }
1478
+ }
1479
+ async _uploadCache() {
1480
+ if (this._cacheUploadDone)
1481
+ return;
1482
+ this._cacheUploadDone = true;
1483
+ this._debug.log("Total messages streamed:", this._messageCount);
1484
+ this._debug.log("Modified files tracked:", this._modifiedFilePaths.size);
1485
+ this._debug.log("Code blocks extracted:", this._generatedCodeBlocks.length);
1486
+ const filesToCache = [];
1487
+ for (const filePath of this._modifiedFilePaths) {
1488
+ if (filePath.includes(CACHE_DIR)) {
1489
+ this._debug.log(" → Skipping cached file:", filePath);
1490
+ continue;
1491
+ }
1492
+ try {
1493
+ if (existsSync(filePath)) {
1494
+ const content = readFileSync2(filePath, "utf-8");
1495
+ if (content.includes("\x00")) {
1496
+ this._debug.log(" → Skipping binary file:", filePath);
1497
+ continue;
1498
+ }
1499
+ filesToCache.push({ path: filePath, content });
1500
+ this._debug.log(" → Will cache file:", filePath, `(${content.length} chars)`);
1501
+ } else {
1502
+ this._debug.log(" → File not found:", filePath);
1503
+ }
1504
+ } catch (err) {
1505
+ this._debug.log(" → Failed to read file:", filePath, err instanceof Error ? err : String(err));
1506
+ }
1507
+ }
1508
+ for (const filePath of this._bashGeneratedFiles) {
1509
+ if (this._modifiedFilePaths.has(filePath))
1510
+ continue;
1511
+ try {
1512
+ if (existsSync(filePath)) {
1513
+ const content = readFileSync2(filePath, "utf-8");
1514
+ if (!content.includes("\x00")) {
1515
+ filesToCache.push({ path: filePath, content });
1516
+ this._debug.log(" → Will cache Bash-generated file:", filePath, `(${content.length} chars)`);
1517
+ }
1518
+ }
1519
+ } catch {
1520
+ this._debug.log(" → Failed to read Bash-generated file:", filePath);
1521
+ }
1522
+ }
1523
+ if (this._generatedCodeBlocks.length > 0) {
1524
+ const largestBlock = this._generatedCodeBlocks.reduce((a, b) => a.length > b.length ? a : b);
1525
+ filesToCache.push({
1526
+ path: "generated-code.ts",
1527
+ content: largestBlock
1528
+ });
1529
+ this._debug.log(" → Will cache generated code block:", `(${largestBlock.length} chars)`);
1530
+ }
1531
+ this._debug.log("Total items to cache:", filesToCache.length);
1532
+ if (this._cacheEnabled && this._raysurfer && this._taskSucceeded && this._promptText) {
1533
+ const cachedBlocksForVoting = this._parseRunForAiVoting ? this._cachedFiles.map((f) => ({
1534
+ codeBlockId: f.codeBlockId,
1535
+ filename: f.filename,
1536
+ description: f.description
1537
+ })) : [];
1538
+ if (filesToCache.length > 0 || cachedBlocksForVoting.length > 0) {
1539
+ try {
1540
+ this._debug.time("Cache upload + voting");
1541
+ if (!this._parseRunForAiVoting) {
1542
+ this._debug.log("Skipping AI voting parse for this run due sampling");
1543
+ }
1544
+ const joinedLogs = this._parseRunForAiVoting && this._executionLogs.length > 0 ? this._executionLogs.join(`
1545
+ ---
1546
+ `) : undefined;
1547
+ this._debug.log("Uploading", filesToCache.length, "files, voting for", cachedBlocksForVoting.length, "cached blocks,", this._executionLogs.length, "log entries...");
1548
+ for (const [i, file] of filesToCache.entries()) {
1549
+ await this._raysurfer.uploadNewCodeSnip({
1550
+ task: this._promptText,
1551
+ fileWritten: file,
1552
+ succeeded: true,
1553
+ cachedCodeBlocks: i === 0 && cachedBlocksForVoting.length > 0 ? cachedBlocksForVoting : undefined,
1554
+ useRaysurferAiVoting: this._parseRunForAiVoting,
1555
+ executionLogs: joinedLogs,
1556
+ perFunctionReputation: true
1557
+ });
1558
+ }
1559
+ if (filesToCache.length === 0 && cachedBlocksForVoting.length > 0) {
1560
+ for (const cb of cachedBlocksForVoting) {
1561
+ await this._raysurfer.voteCodeSnip({
1562
+ task: this._promptText,
1563
+ codeBlockId: cb.codeBlockId,
1564
+ codeBlockName: cb.filename,
1565
+ codeBlockDescription: cb.description,
1566
+ succeeded: true
1567
+ });
1568
+ }
1569
+ }
1570
+ this._debug.timeEnd("Cache upload + voting");
1571
+ this._debug.log("Cache upload successful, voting queued on backend");
1572
+ console.log("[raysurfer] Cache upload successful:", filesToCache.length, "files stored");
1573
+ } catch (error) {
1574
+ const errMsg = error instanceof Error ? error.message : String(error);
1575
+ this._debug.log("Cache upload failed:", errMsg);
1576
+ console.warn("[raysurfer] Cache upload failed:", errMsg);
1577
+ }
1578
+ }
1579
+ }
1580
+ this._debug.groupEnd();
1581
+ }
1582
+ async next(...args) {
1583
+ const inner = await this._ensureInit();
1584
+ const result = await inner.next(...args);
1585
+ if (!result.done) {
1586
+ this._trackMessage(result.value);
1587
+ } else {
1588
+ await this._uploadCache();
1589
+ }
1590
+ return result;
1591
+ }
1592
+ async return(value) {
1593
+ if (this._inner) {
1594
+ await this._uploadCache();
1595
+ return this._inner.return(value);
1596
+ }
1597
+ return { done: true, value: undefined };
1598
+ }
1599
+ async throw(e) {
1600
+ if (this._inner)
1601
+ return this._inner.throw(e);
1602
+ throw e;
1603
+ }
1604
+ [Symbol.asyncIterator]() {
1605
+ return this;
1606
+ }
1607
+ async[Symbol.asyncDispose]() {
1608
+ this.close();
1609
+ }
1610
+ async interrupt() {
1611
+ return (await this._ensureInit()).interrupt();
1612
+ }
1613
+ async setPermissionMode(mode) {
1614
+ return (await this._ensureInit()).setPermissionMode(mode);
1615
+ }
1616
+ async setModel(model) {
1617
+ return (await this._ensureInit()).setModel(model);
1618
+ }
1619
+ async setMaxThinkingTokens(maxThinkingTokens) {
1620
+ return (await this._ensureInit()).setMaxThinkingTokens(maxThinkingTokens);
1621
+ }
1622
+ async supportedCommands() {
1623
+ return (await this._ensureInit()).supportedCommands();
1624
+ }
1625
+ async supportedModels() {
1626
+ return (await this._ensureInit()).supportedModels();
1627
+ }
1628
+ async mcpServerStatus() {
1629
+ return (await this._ensureInit()).mcpServerStatus();
1630
+ }
1631
+ async accountInfo() {
1632
+ return (await this._ensureInit()).accountInfo();
1633
+ }
1634
+ async rewindFiles(userMessageId, options) {
1635
+ return (await this._ensureInit()).rewindFiles(userMessageId, options);
1636
+ }
1637
+ async setMcpServers(servers) {
1638
+ return (await this._ensureInit()).setMcpServers(servers);
1639
+ }
1640
+ async streamInput(stream) {
1641
+ return (await this._ensureInit()).streamInput(stream);
1642
+ }
1643
+ close() {
1644
+ if (this._inner)
1645
+ this._inner.close();
1646
+ }
1647
+ };
1648
+ sdk_client_default = query;
1649
+ });
1650
+
1651
+ // src/types.ts
1652
+ var ExecutionState;
1653
+ ((ExecutionState2) => {
1654
+ ExecutionState2["COMPLETED"] = "completed";
1655
+ ExecutionState2["ERRORED"] = "errored";
1656
+ ExecutionState2["TIMED_OUT"] = "timed_out";
1657
+ ExecutionState2["CANCELLED"] = "cancelled";
1658
+ })(ExecutionState ||= {});
1659
+ var AgentVerdict;
1660
+ ((AgentVerdict2) => {
1661
+ AgentVerdict2["THUMBS_UP"] = "thumbs_up";
1662
+ AgentVerdict2["THUMBS_DOWN"] = "thumbs_down";
1663
+ AgentVerdict2["PENDING"] = "pending";
1664
+ })(AgentVerdict ||= {});
1665
+
1666
+ // src/accessible.ts
1667
+ function toJsonLike(value) {
1668
+ if (value === null || typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
1669
+ return value;
1670
+ }
1671
+ if (value === undefined) {
1672
+ return null;
1673
+ }
1674
+ if (Array.isArray(value)) {
1675
+ return value.map((item) => toJsonLike(item));
1676
+ }
1677
+ if (typeof value === "object") {
1678
+ const result = {};
1679
+ for (const [key, nested] of Object.entries(value)) {
1680
+ result[key] = toJsonLike(nested);
1681
+ }
1682
+ return result;
1683
+ }
1684
+ return String(value);
1685
+ }
1686
+ function queueUsageTracking(fn, args, result, durationMs, errorMessage) {
1687
+ const client = fn._raysurferClient;
1688
+ if (!client)
1689
+ return;
1690
+ const codeBlockId = fn._raysurferSchema.codeBlockId ?? `function_registry:${fn._raysurferSchema.name}`;
1691
+ const outputData = errorMessage === undefined ? result : { error: errorMessage };
1692
+ client.storeExecution({
1693
+ codeBlockId,
1694
+ triggeringTask: `agent_accessible:${fn._raysurferSchema.name}`,
1695
+ inputData: {
1696
+ args: toJsonLike(args)
1697
+ },
1698
+ outputData: toJsonLike(outputData),
1699
+ executionState: errorMessage ? "errored" /* ERRORED */ : "completed" /* COMPLETED */,
1700
+ durationMs,
1701
+ errorMessage
1702
+ }).catch(() => {});
1703
+ }
1704
+ function inferParameters(fn) {
1705
+ const src = fn.toString();
1706
+ const match = /^[^(]*\(([^)]*)\)/.exec(src);
1707
+ const paramStr = match?.[1];
1708
+ if (!paramStr?.trim())
1709
+ return {};
1710
+ const params = {};
1711
+ const parts = paramStr.split(",");
1712
+ for (const part of parts) {
1713
+ const cleaned = part.trim().replace(/\/\*.*?\*\//g, "").replace(/=.*$/, "").replace(/:.*$/, "").trim();
1714
+ if (cleaned && cleaned !== "..." && !cleaned.startsWith("...")) {
1715
+ params[cleaned] = "string";
1716
+ }
1717
+ }
1718
+ return params;
1719
+ }
1720
+ function agentAccessible(fn, options) {
1721
+ const resolvedName = options?.name ?? fn.name ?? "anonymous";
1722
+ const resolvedDescription = options?.description ?? "";
1723
+ const resolvedSchema = options?.inputSchema ?? options?.parameters ?? inferParameters(fn);
1724
+ let marked;
1725
+ const wrapped = (...args) => {
1726
+ const started = Date.now();
1727
+ try {
1728
+ const result = fn(...args);
1729
+ if (result instanceof Promise) {
1730
+ const trackedPromise = result.then((resolved) => {
1731
+ queueUsageTracking(marked, args, resolved, Date.now() - started);
1732
+ return resolved;
1733
+ }).catch((error) => {
1734
+ const message = error instanceof Error ? error.message : String(error);
1735
+ queueUsageTracking(marked, args, null, Date.now() - started, message);
1736
+ throw error;
1737
+ });
1738
+ return trackedPromise;
1739
+ }
1740
+ queueUsageTracking(marked, args, result, Date.now() - started);
1741
+ return result;
1742
+ } catch (error) {
1743
+ const message = error instanceof Error ? error.message : String(error);
1744
+ queueUsageTracking(marked, args, null, Date.now() - started, message);
1745
+ throw error;
1746
+ }
1747
+ };
1748
+ marked = wrapped;
1749
+ marked._raysurferAccessible = true;
1750
+ marked._raysurferSchema = {
1751
+ name: resolvedName,
1752
+ description: resolvedDescription,
1753
+ inputSchema: resolvedSchema,
1754
+ parameters: resolvedSchema,
1755
+ source: fn.toString()
1756
+ };
1757
+ return marked;
1758
+ }
1759
+ function toAnthropicTool(fn) {
1760
+ const schema = fn._raysurferSchema;
1761
+ return {
1762
+ name: schema.name,
1763
+ description: schema.description,
1764
+ input_schema: schema.inputSchema
1765
+ };
1766
+ }
1767
+ async function publishFunctionRegistry(client, functions) {
1768
+ const snippetNames = [];
1769
+ for (const fn of functions) {
1770
+ if (!fn._raysurferAccessible)
1771
+ continue;
1772
+ const schema = fn._raysurferSchema;
1773
+ const resp = await client.uploadNewCodeSnip({
1774
+ task: `Call ${schema.name}: ${schema.description}`,
1775
+ fileWritten: { path: `${schema.name}.ts`, content: schema.source },
1776
+ succeeded: true,
1777
+ useRaysurferAiVoting: false,
1778
+ tags: ["function_registry", "agent_accessible"]
1779
+ });
1780
+ if (resp.snippetName) {
1781
+ snippetNames.push(resp.snippetName);
1782
+ schema.codeBlockId = resp.snippetName;
1783
+ }
1784
+ setTrackingClient(fn, client);
1785
+ }
1786
+ return snippetNames;
1787
+ }
1788
+ function setTrackingClient(fn, client) {
1789
+ fn._raysurferClient = client;
1790
+ }
1791
+ // src/agent.ts
1792
+ init_client();
1793
+ var DEFAULT_CODEGEN_MODEL = "claude-opus-4-6";
1794
+ var DEFAULT_EXECUTION_TIMEOUT_MS = 300000;
1795
+ var CODEGEN_DOCS_URL = "https://docs.raysurfer.com/sdk/typescript#programmatic-tool-calling";
1796
+ function missingCodegenKeyError(value) {
1797
+ return new Error(`Invalid codegenApiKey value: ${String(value)}. Expected format: non-empty provider API key string. ` + "Current tier/state: tier=unknown, codegen_api_key_missing=true (not configured on app and not provided at call-time). " + `Fix: pass codegenApiKey in app config or run(...). Docs: ${CODEGEN_DOCS_URL}`);
1798
+ }
1799
+ function invalidCodegenPromptError(value) {
1800
+ return new Error(`Invalid codegenPrompt value: ${String(value)}. Expected format: non-empty prompt string. ` + "Current tier/state: tier=unknown, codegen_prompt_invalid=true. " + `Fix: pass codegenPrompt or provide a non-empty task. Docs: ${CODEGEN_DOCS_URL}`);
1801
+ }
1802
+
1803
+ class CodegenApp {
1804
+ _raysurfer;
1805
+ _defaultCodegenApiKey;
1806
+ _defaultCodegenModel;
1807
+ _defaultExecutionTimeoutMs;
1808
+ constructor(options = {}) {
1809
+ const {
1810
+ raysurfer,
1811
+ codegenApiKey,
1812
+ codegenModel,
1813
+ executionTimeoutMs,
1814
+ ...clientOptions
1815
+ } = options;
1816
+ this._raysurfer = raysurfer ?? new client_default(clientOptions);
1817
+ this._defaultCodegenApiKey = codegenApiKey;
1818
+ this._defaultCodegenModel = codegenModel ?? DEFAULT_CODEGEN_MODEL;
1819
+ this._defaultExecutionTimeoutMs = executionTimeoutMs ?? DEFAULT_EXECUTION_TIMEOUT_MS;
1820
+ }
1821
+ get raysurfer() {
1822
+ return this._raysurfer;
1823
+ }
1824
+ tool(name, description, parameters, callback) {
1825
+ this._raysurfer.tool(name, description, parameters, callback);
1826
+ return this;
1827
+ }
1828
+ async run(task, options = {}) {
1829
+ const codegenApiKey = this.resolveCodegenApiKey(options.codegenApiKey);
1830
+ const codegenPrompt = this.resolveCodegenPrompt(task, options.codegenPrompt);
1831
+ const codegenModel = options.codegenModel ?? this._defaultCodegenModel;
1832
+ const timeout = options.executionTimeoutMs ?? this._defaultExecutionTimeoutMs;
1833
+ return this._raysurfer.executeWithSandboxCodegen(task, {
1834
+ provider: "anthropic",
1835
+ apiKey: codegenApiKey,
1164
1836
  prompt: codegenPrompt,
1165
1837
  model: codegenModel
1166
1838
  }, { timeout });
@@ -1190,6 +1862,10 @@ class CodegenApp {
1190
1862
  throw invalidCodegenPromptError(value);
1191
1863
  }
1192
1864
  }
1865
+
1866
+ // src/index.ts
1867
+ init_client();
1868
+
1193
1869
  // src/config.ts
1194
1870
  import { readFileSync } from "node:fs";
1195
1871
  function coerceStringList(value) {
@@ -1339,6 +2015,10 @@ function loadConfig(path, modules) {
1339
2015
  }
1340
2016
  return functions;
1341
2017
  }
2018
+
2019
+ // src/index.ts
2020
+ init_errors();
2021
+
1342
2022
  // src/logging.ts
1343
2023
  var CAP = 1000;
1344
2024
  var telemetry = new Map;
@@ -1685,535 +2365,83 @@ class ProgrammaticToolCallingSession {
1685
2365
  }
1686
2366
  }
1687
2367
  }
1688
- // src/sdk-client.ts
1689
- import { existsSync, mkdirSync, readFileSync as readFileSync2, writeFileSync } from "node:fs";
1690
- import { join } from "node:path";
1691
- var DEFAULT_RAYSURFER_URL = "https://api.raysurfer.com";
1692
- var CACHE_DIR = ".raysurfer_code";
1693
- var DEFAULT_RUN_PARSE_SAMPLE_RATE = 1;
1694
- var RUN_PARSE_SAMPLE_RATE_ENV_VAR = "RAYSURFER_RUN_PARSE_SAMPLE_RATE";
1695
- var DEFAULT_AGENT_COMPAT_TOOLS_PRESET = {
1696
- type: "preset",
1697
- preset: "claude_code"
1698
- };
1699
- var DEFAULT_SANDBOX_SETTINGS = {
1700
- enabled: true,
1701
- autoAllowBashIfSandboxed: true
1702
- };
1703
- function resolveRunParseSampleRate(configured) {
1704
- if (configured !== undefined) {
1705
- if (!Number.isFinite(configured) || configured < 0 || configured > 1) {
1706
- throw new Error(`runParseSampleRate must be between 0.0 and 1.0 inclusive; got ${configured}.`);
1707
- }
1708
- return configured;
1709
- }
1710
- const envValue = process.env[RUN_PARSE_SAMPLE_RATE_ENV_VAR];
1711
- if (!envValue || envValue.trim() === "") {
1712
- return DEFAULT_RUN_PARSE_SAMPLE_RATE;
1713
- }
1714
- const parsed = Number(envValue);
1715
- if (!Number.isFinite(parsed) || parsed < 0 || parsed > 1) {
1716
- console.warn(`[raysurfer] ${RUN_PARSE_SAMPLE_RATE_ENV_VAR}=${JSON.stringify(envValue)} is invalid. ` + `Expected a number between 0.0 and 1.0 inclusive. Falling back to ${DEFAULT_RUN_PARSE_SAMPLE_RATE}.`);
1717
- return DEFAULT_RUN_PARSE_SAMPLE_RATE;
1718
- }
1719
- return parsed;
1720
- }
1721
- function shouldParseRunForAiVoting(sampleRate) {
1722
- if (sampleRate >= 1)
1723
- return true;
1724
- if (sampleRate <= 0)
1725
- return false;
1726
- return Math.random() < sampleRate;
1727
- }
1728
- var FILE_MODIFY_TOOLS = ["Write", "Edit", "MultiEdit", "NotebookEdit"];
1729
- var TRACKABLE_EXTENSIONS = new Set([
1730
- ".py",
1731
- ".js",
1732
- ".ts",
1733
- ".rb",
1734
- ".go",
1735
- ".rs",
1736
- ".java",
1737
- ".cpp",
1738
- ".c",
1739
- ".h",
1740
- ".pdf",
1741
- ".docx",
1742
- ".xlsx",
1743
- ".csv",
1744
- ".json",
1745
- ".yaml",
1746
- ".yml",
1747
- ".xml",
1748
- ".html",
1749
- ".css",
1750
- ".md",
1751
- ".txt",
1752
- ".sh",
1753
- ".sql"
1754
- ]);
1755
- var BASH_OUTPUT_PATTERNS = [
1756
- />>\s*([^\s;&|]+)/g,
1757
- />\s*([^\s;&|]+)/g,
1758
- /-o\s+([^\s;&|]+)/g,
1759
- /--output[=\s]+([^\s;&|]+)/g,
1760
- /savefig\(['"]([^'"]+)['"]\)/g,
1761
- /to_csv\(['"]([^'"]+)['"]\)/g,
1762
- /to_excel\(['"]([^'"]+)['"]\)/g,
1763
- /write\(['"]([^'"]+)['"]\)/g
1764
- ];
1765
- var createDebugLogger = (enabled) => ({
1766
- log: (...args) => enabled && console.log("[raysurfer]", ...args),
1767
- time: (label) => enabled && console.time(`[raysurfer] ${label}`),
1768
- timeEnd: (label) => enabled && console.timeEnd(`[raysurfer] ${label}`),
1769
- table: (data) => enabled && console.table(data),
1770
- group: (label) => enabled && console.group(`[raysurfer] ${label}`),
1771
- groupEnd: () => enabled && console.groupEnd()
1772
- });
1773
- function augmentSystemPrompt(systemPrompt, addition) {
1774
- if (!addition)
1775
- return systemPrompt;
1776
- if (typeof systemPrompt === "string")
1777
- return systemPrompt + addition;
1778
- if (systemPrompt?.type === "preset") {
1779
- return { ...systemPrompt, append: (systemPrompt.append ?? "") + addition };
1780
- }
1781
- return addition;
1782
- }
1783
- function splitOptions(options) {
1784
- const {
1785
- workspaceId,
1786
- publicSnips,
1787
- debug,
1788
- runParseSampleRate,
1789
- workingDirectory,
1790
- agentId,
1791
- ...sdkOptions
1792
- } = options;
1793
- return {
1794
- sdkOptions,
1795
- extras: {
1796
- workspaceId,
1797
- publicSnips,
1798
- debug,
1799
- runParseSampleRate,
1800
- workingDirectory,
1801
- agentId
1802
- }
1803
- };
1804
- }
1805
- function applyDefaultAgentCompatibilityOptions(options) {
1806
- const merged = { ...options };
1807
- const hasToolsPreset = merged.tools !== undefined && merged.tools !== null;
1808
- const hasAllowedTools = Array.isArray(merged.allowedTools) && merged.allowedTools.length > 0;
1809
- if (!hasToolsPreset && !hasAllowedTools) {
1810
- merged.tools = DEFAULT_AGENT_COMPAT_TOOLS_PRESET;
1811
- }
1812
- if (merged.sandbox && typeof merged.sandbox === "object") {
1813
- merged.sandbox = {
1814
- ...DEFAULT_SANDBOX_SETTINGS,
1815
- ...merged.sandbox
1816
- };
1817
- } else {
1818
- merged.sandbox = { ...DEFAULT_SANDBOX_SETTINGS };
1819
- }
1820
- return merged;
1821
- }
2368
+ // src/runner.ts
2369
+ init_client();
1822
2370
 
1823
- class RaysurferQuery {
1824
- _inner = null;
1825
- _initPromise = null;
1826
- _raysurfer = null;
1827
- _cachedFiles = [];
1828
- _modifiedFilePaths = new Set;
1829
- _bashGeneratedFiles = new Set;
1830
- _executionLogs = [];
1831
- _taskSucceeded = false;
1832
- _generatedCodeBlocks = [];
1833
- _cacheUploadDone = false;
1834
- _messageCount = 0;
1835
- _startTime = 0;
1836
- _promptText;
1837
- _params;
1838
- _debug;
1839
- _cacheEnabled;
1840
- _workDir;
2371
+ class Agent {
1841
2372
  _apiKey;
1842
2373
  _baseUrl;
1843
- _extras;
1844
- _sdkOptions;
1845
- _runParseSampleRate;
1846
- _parseRunForAiVoting;
1847
- constructor(params) {
1848
- this._params = params;
1849
- const options = params.options ?? {};
1850
- const { sdkOptions, extras } = splitOptions(options);
1851
- this._sdkOptions = applyDefaultAgentCompatibilityOptions(sdkOptions);
1852
- this._extras = extras;
1853
- this._promptText = typeof params.prompt === "string" ? params.prompt : null;
1854
- const debugEnabled = extras.debug || process.env.RAYSURFER_DEBUG === "true";
1855
- this._debug = createDebugLogger(debugEnabled);
1856
- this._apiKey = process.env.RAYSURFER_API_KEY;
1857
- this._baseUrl = process.env.RAYSURFER_BASE_URL || DEFAULT_RAYSURFER_URL;
1858
- this._cacheEnabled = !!this._apiKey;
1859
- this._runParseSampleRate = resolveRunParseSampleRate(extras.runParseSampleRate);
1860
- this._parseRunForAiVoting = shouldParseRunForAiVoting(this._runParseSampleRate);
1861
- if (extras.workingDirectory && !sdkOptions.cwd) {
1862
- console.warn("[raysurfer] workingDirectory is deprecated, use cwd instead");
1863
- this._sdkOptions.cwd = extras.workingDirectory;
1864
- }
1865
- this._workDir = this._sdkOptions.cwd || process.cwd();
1866
- }
1867
- async _initialize() {
1868
- this._debug.group("Raysurfer Query Started");
1869
- this._debug.log("Prompt:", this._promptText ?? "<stream>");
1870
- this._debug.log("Cache enabled:", this._cacheEnabled);
1871
- this._debug.log("Base URL:", this._baseUrl);
1872
- this._debug.log("Run parse sample rate:", this._runParseSampleRate);
1873
- this._debug.log("Parse this run for AI voting:", this._parseRunForAiVoting);
1874
- if (!this._cacheEnabled) {
1875
- console.warn("[raysurfer] RAYSURFER_API_KEY not set - caching disabled");
1876
- }
1877
- let addToLlmPrompt = "";
1878
- if (this._cacheEnabled && this._promptText) {
1879
- this._raysurfer = new RaySurfer({
2374
+ _agentId;
2375
+ _allowedTools;
2376
+ _systemPrompt;
2377
+ _model;
2378
+ _raysurfer;
2379
+ constructor(options = {}) {
2380
+ this._apiKey = options.apiKey;
2381
+ this._baseUrl = options.baseUrl;
2382
+ this._agentId = options.agentId;
2383
+ this._allowedTools = options.allowedTools ?? ["Read", "Write", "Bash"];
2384
+ this._systemPrompt = options.systemPrompt ?? "You are a helpful assistant.";
2385
+ this._model = options.model;
2386
+ }
2387
+ ensureClient(orgId) {
2388
+ if (!this._raysurfer || orgId) {
2389
+ this._raysurfer = new client_default({
1880
2390
  apiKey: this._apiKey,
1881
2391
  baseUrl: this._baseUrl,
1882
- workspaceId: this._extras.workspaceId,
1883
- snipsDesired: this._extras.workspaceId ? "client" : undefined,
1884
- publicSnips: this._extras.publicSnips,
1885
- agentId: this._extras.agentId
2392
+ organizationId: orgId,
2393
+ snipsDesired: orgId ? "company" : undefined,
2394
+ agentId: this._agentId
1886
2395
  });
1887
- try {
1888
- this._debug.time("Cache lookup");
1889
- const cacheDir = join(this._workDir, CACHE_DIR);
1890
- const response = await this._raysurfer.getCodeFiles({
1891
- task: this._promptText,
1892
- topK: 5,
1893
- minVerdictScore: 0.3,
1894
- preferComplete: true,
1895
- perFunctionReputation: true,
1896
- cacheDir
1897
- });
1898
- this._debug.timeEnd("Cache lookup");
1899
- this._cachedFiles = response.files;
1900
- addToLlmPrompt = response.addToLlmPrompt;
1901
- this._debug.log(`Found ${this._cachedFiles.length} cached files:`);
1902
- console.log("[raysurfer] Cache hit:", this._cachedFiles.length, "snippets retrieved");
1903
- if (this._cachedFiles.length > 0) {
1904
- this._debug.table(this._cachedFiles.map((f) => ({
1905
- filename: f.filename,
1906
- score: `${Math.round(f.score * 100)}%`,
1907
- thumbs: `${f.thumbsUp}/${f.thumbsDown}`,
1908
- sourceLength: `${f.source.length} chars`
1909
- })));
1910
- try {
1911
- mkdirSync(cacheDir, { recursive: true });
1912
- for (const file of this._cachedFiles) {
1913
- const filePath = join(cacheDir, file.filename);
1914
- writeFileSync(filePath, file.source, "utf-8");
1915
- this._debug.log(` → Wrote cached file: ${filePath}`);
1916
- this._modifiedFilePaths.add(filePath);
1917
- }
1918
- } catch (writeErr) {
1919
- this._debug.log("Failed to write cached files:", writeErr instanceof Error ? writeErr : String(writeErr));
1920
- }
1921
- }
1922
- } catch (error) {
1923
- const errMsg = error instanceof Error ? error.message : String(error);
1924
- this._debug.log("Cache lookup failed:", errMsg);
1925
- console.warn("[raysurfer] Cache unavailable:", errMsg);
1926
- }
1927
- }
1928
- const augmented = augmentSystemPrompt(this._sdkOptions.systemPrompt, addToLlmPrompt);
1929
- const augmentedOptions = {
1930
- ...this._sdkOptions,
1931
- systemPrompt: augmented
1932
- };
1933
- this._debug.log("Augmented prompt addition:", addToLlmPrompt.length, "chars");
1934
- let sdkQueryFn;
1935
- try {
1936
- const sdk = await import("@anthropic-ai/claude-agent-sdk");
1937
- sdkQueryFn = sdk.query;
1938
- } catch {
1939
- throw new Error("Could not import @anthropic-ai/claude-agent-sdk. Install it with: npm install @anthropic-ai/claude-agent-sdk");
1940
- }
1941
- this._debug.time("Claude API call");
1942
- this._debug.log("Calling Claude Agent SDK...");
1943
- this._startTime = Date.now();
1944
- this._inner = sdkQueryFn({
1945
- prompt: this._params.prompt,
1946
- options: augmentedOptions
1947
- });
1948
- }
1949
- async _ensureInit() {
1950
- if (!this._inner) {
1951
- if (!this._initPromise) {
1952
- this._initPromise = this._initialize();
1953
- }
1954
- await this._initPromise;
1955
- }
1956
- return this._inner;
1957
- }
1958
- _extractBashOutputFiles(command) {
1959
- for (const pattern of BASH_OUTPUT_PATTERNS) {
1960
- pattern.lastIndex = 0;
1961
- let match = pattern.exec(command);
1962
- while (match !== null) {
1963
- const filePath = match[1];
1964
- if (filePath && filePath.length > 0) {
1965
- const ext = filePath.substring(filePath.lastIndexOf(".")).toLowerCase();
1966
- if (TRACKABLE_EXTENSIONS.has(ext)) {
1967
- this._bashGeneratedFiles.add(filePath);
1968
- this._debug.log(` → Bash output file detected: ${filePath}`);
1969
- }
1970
- }
1971
- match = pattern.exec(command);
1972
- }
1973
- }
1974
- }
1975
- _trackMessage(message) {
1976
- this._messageCount++;
1977
- const msg = message;
1978
- const elapsed = Date.now() - this._startTime;
1979
- this._debug.log(`
1980
- ═══════════════════════════════════════════════════`);
1981
- this._debug.log(`Message #${this._messageCount} [${elapsed}ms] type=${msg.type} subtype=${msg.subtype ?? "none"}`);
1982
- this._debug.log(`═══════════════════════════════════════════════════`);
1983
- this._debug.log(JSON.stringify(msg, null, 2));
1984
- if (msg.type === "assistant" && msg.message?.content) {
1985
- const blocks = msg.message.content;
1986
- for (const block of blocks) {
1987
- if (block.type === "tool_use" && block.name && FILE_MODIFY_TOOLS.includes(block.name)) {
1988
- const filePath = block.input?.file_path ?? block.input?.notebook_path;
1989
- if (filePath) {
1990
- this._debug.log(` → ${block.name} tool detected:`, filePath);
1991
- this._modifiedFilePaths.add(filePath);
1992
- }
1993
- }
1994
- if (block.type === "tool_use" && block.name === "Bash") {
1995
- const command = block.input?.command;
1996
- if (command) {
1997
- this._extractBashOutputFiles(command);
1998
- }
1999
- }
2000
- if (block.type === "tool_result" && block.content) {
2001
- if (this._parseRunForAiVoting) {
2002
- this._executionLogs.push(block.content.slice(0, 5000));
2003
- }
2004
- }
2005
- if (block.type === "text" && block.text) {
2006
- const codeMatches = block.text.match(/```(?:typescript|javascript|ts|js)?\n?([\s\S]*?)\n?```/g);
2007
- if (codeMatches) {
2008
- for (const match of codeMatches) {
2009
- const code = match.replace(/```(?:typescript|javascript|ts|js)?\n?/, "").replace(/\n?```$/, "");
2010
- if (code.trim().length > 50) {
2011
- this._generatedCodeBlocks.push(code.trim());
2012
- this._debug.log(` → Extracted code block (${code.length} chars)`);
2013
- }
2014
- }
2015
- }
2016
- }
2017
- }
2018
- }
2019
- if (msg.type === "result" && msg.subtype === "success") {
2020
- this._taskSucceeded = true;
2021
- this._debug.timeEnd("Claude API call");
2022
- this._debug.log("Task succeeded!");
2023
- this._debug.log(" Duration:", msg.duration_ms, "ms");
2024
- this._debug.log(" Total cost:", msg.total_cost_usd, "USD");
2025
- this._debug.log(" Turns:", msg.num_turns);
2026
- }
2027
- if (msg.type === "result" && msg.subtype !== "success") {
2028
- this._debug.timeEnd("Claude API call");
2029
- this._debug.log("Task failed:", msg.subtype);
2030
2396
  }
2397
+ return this._raysurfer;
2031
2398
  }
2032
- async _uploadCache() {
2033
- if (this._cacheUploadDone)
2034
- return;
2035
- this._cacheUploadDone = true;
2036
- this._debug.log("Total messages streamed:", this._messageCount);
2037
- this._debug.log("Modified files tracked:", this._modifiedFilePaths.size);
2038
- this._debug.log("Code blocks extracted:", this._generatedCodeBlocks.length);
2039
- const filesToCache = [];
2040
- for (const filePath of this._modifiedFilePaths) {
2041
- if (filePath.includes(CACHE_DIR)) {
2042
- this._debug.log(" → Skipping cached file:", filePath);
2043
- continue;
2044
- }
2045
- try {
2046
- if (existsSync(filePath)) {
2047
- const content = readFileSync2(filePath, "utf-8");
2048
- if (content.includes("\x00")) {
2049
- this._debug.log(" → Skipping binary file:", filePath);
2050
- continue;
2051
- }
2052
- filesToCache.push({ path: filePath, content });
2053
- this._debug.log(" → Will cache file:", filePath, `(${content.length} chars)`);
2054
- } else {
2055
- this._debug.log(" → File not found:", filePath);
2056
- }
2057
- } catch (err) {
2058
- this._debug.log(" → Failed to read file:", filePath, err instanceof Error ? err : String(err));
2059
- }
2399
+ async run(messages, options = {}) {
2400
+ const rs = this.ensureClient(options.orgId);
2401
+ const lastUserMsg = [...messages].reverse().find((m) => m.role === "user");
2402
+ if (!lastUserMsg) {
2403
+ throw new Error("Messages must contain at least one user message.");
2060
2404
  }
2061
- for (const filePath of this._bashGeneratedFiles) {
2062
- if (this._modifiedFilePaths.has(filePath))
2063
- continue;
2064
- try {
2065
- if (existsSync(filePath)) {
2066
- const content = readFileSync2(filePath, "utf-8");
2067
- if (!content.includes("\x00")) {
2068
- filesToCache.push({ path: filePath, content });
2069
- this._debug.log(" → Will cache Bash-generated file:", filePath, `(${content.length} chars)`);
2070
- }
2405
+ const query2 = lastUserMsg.content;
2406
+ const runId = crypto.randomUUID();
2407
+ const searchResult = await rs.search({ task: query2 });
2408
+ const codeUsed = searchResult.matches?.map((m) => ({
2409
+ code_block_id: m.codeBlock.id,
2410
+ filename: m.codeBlock.name,
2411
+ description: m.codeBlock.description
2412
+ })) ?? [];
2413
+ let succeeded = false;
2414
+ const responseMessages = [];
2415
+ try {
2416
+ const { query: sdkQuery } = await Promise.resolve().then(() => (init_sdk_client(), exports_sdk_client));
2417
+ for await (const msg of sdkQuery({
2418
+ prompt: query2,
2419
+ options: {
2420
+ allowedTools: this._allowedTools,
2421
+ systemPrompt: this._systemPrompt,
2422
+ model: this._model
2071
2423
  }
2072
- } catch {
2073
- this._debug.log(" → Failed to read Bash-generated file:", filePath);
2074
- }
2075
- }
2076
- if (this._generatedCodeBlocks.length > 0) {
2077
- const largestBlock = this._generatedCodeBlocks.reduce((a, b) => a.length > b.length ? a : b);
2078
- filesToCache.push({
2079
- path: "generated-code.ts",
2080
- content: largestBlock
2081
- });
2082
- this._debug.log(" → Will cache generated code block:", `(${largestBlock.length} chars)`);
2083
- }
2084
- this._debug.log("Total items to cache:", filesToCache.length);
2085
- if (this._cacheEnabled && this._raysurfer && this._taskSucceeded && this._promptText) {
2086
- const cachedBlocksForVoting = this._parseRunForAiVoting ? this._cachedFiles.map((f) => ({
2087
- codeBlockId: f.codeBlockId,
2088
- filename: f.filename,
2089
- description: f.description
2090
- })) : [];
2091
- if (filesToCache.length > 0 || cachedBlocksForVoting.length > 0) {
2092
- try {
2093
- this._debug.time("Cache upload + voting");
2094
- if (!this._parseRunForAiVoting) {
2095
- this._debug.log("Skipping AI voting parse for this run due sampling");
2096
- }
2097
- const joinedLogs = this._parseRunForAiVoting && this._executionLogs.length > 0 ? this._executionLogs.join(`
2098
- ---
2099
- `) : undefined;
2100
- this._debug.log("Uploading", filesToCache.length, "files, voting for", cachedBlocksForVoting.length, "cached blocks,", this._executionLogs.length, "log entries...");
2101
- for (const [i, file] of filesToCache.entries()) {
2102
- await this._raysurfer.uploadNewCodeSnip({
2103
- task: this._promptText,
2104
- fileWritten: file,
2105
- succeeded: true,
2106
- cachedCodeBlocks: i === 0 && cachedBlocksForVoting.length > 0 ? cachedBlocksForVoting : undefined,
2107
- useRaysurferAiVoting: this._parseRunForAiVoting,
2108
- executionLogs: joinedLogs,
2109
- perFunctionReputation: true
2110
- });
2111
- }
2112
- if (filesToCache.length === 0 && cachedBlocksForVoting.length > 0) {
2113
- for (const cb of cachedBlocksForVoting) {
2114
- await this._raysurfer.voteCodeSnip({
2115
- task: this._promptText,
2116
- codeBlockId: cb.codeBlockId,
2117
- codeBlockName: cb.filename,
2118
- codeBlockDescription: cb.description,
2119
- succeeded: true
2120
- });
2121
- }
2122
- }
2123
- this._debug.timeEnd("Cache upload + voting");
2124
- this._debug.log("Cache upload successful, voting queued on backend");
2125
- console.log("[raysurfer] Cache upload successful:", filesToCache.length, "files stored");
2126
- } catch (error) {
2127
- const errMsg = error instanceof Error ? error.message : String(error);
2128
- this._debug.log("Cache upload failed:", errMsg);
2129
- console.warn("[raysurfer] Cache upload failed:", errMsg);
2424
+ })) {
2425
+ responseMessages.push(msg);
2426
+ if (typeof msg === "object" && msg !== null && "type" in msg && msg.type === "result" && "subtype" in msg && msg.subtype === "success") {
2427
+ succeeded = true;
2130
2428
  }
2131
2429
  }
2430
+ } catch {
2431
+ succeeded = false;
2132
2432
  }
2133
- this._debug.groupEnd();
2134
- }
2135
- async next(...args) {
2136
- const inner = await this._ensureInit();
2137
- const result = await inner.next(...args);
2138
- if (!result.done) {
2139
- this._trackMessage(result.value);
2140
- } else {
2141
- await this._uploadCache();
2142
- }
2143
- return result;
2144
- }
2145
- async return(value) {
2146
- if (this._inner) {
2147
- await this._uploadCache();
2148
- return this._inner.return(value);
2149
- }
2150
- return { done: true, value: undefined };
2151
- }
2152
- async throw(e) {
2153
- if (this._inner)
2154
- return this._inner.throw(e);
2155
- throw e;
2156
- }
2157
- [Symbol.asyncIterator]() {
2158
- return this;
2159
- }
2160
- async[Symbol.asyncDispose]() {
2161
- this.close();
2162
- }
2163
- async interrupt() {
2164
- return (await this._ensureInit()).interrupt();
2165
- }
2166
- async setPermissionMode(mode) {
2167
- return (await this._ensureInit()).setPermissionMode(mode);
2168
- }
2169
- async setModel(model) {
2170
- return (await this._ensureInit()).setModel(model);
2171
- }
2172
- async setMaxThinkingTokens(maxThinkingTokens) {
2173
- return (await this._ensureInit()).setMaxThinkingTokens(maxThinkingTokens);
2174
- }
2175
- async supportedCommands() {
2176
- return (await this._ensureInit()).supportedCommands();
2177
- }
2178
- async supportedModels() {
2179
- return (await this._ensureInit()).supportedModels();
2180
- }
2181
- async mcpServerStatus() {
2182
- return (await this._ensureInit()).mcpServerStatus();
2183
- }
2184
- async accountInfo() {
2185
- return (await this._ensureInit()).accountInfo();
2186
- }
2187
- async rewindFiles(userMessageId, options) {
2188
- return (await this._ensureInit()).rewindFiles(userMessageId, options);
2189
- }
2190
- async setMcpServers(servers) {
2191
- return (await this._ensureInit()).setMcpServers(servers);
2192
- }
2193
- async streamInput(stream) {
2194
- return (await this._ensureInit()).streamInput(stream);
2195
- }
2196
- close() {
2197
- if (this._inner)
2198
- this._inner.close();
2199
- }
2200
- }
2201
- function query(params) {
2202
- return new RaysurferQuery(params);
2203
- }
2204
-
2205
- class ClaudeSDKClient {
2206
- options;
2207
- constructor(options = {}) {
2208
- this.options = options;
2209
- }
2210
- query(prompt) {
2211
- return query({ prompt, options: this.options });
2433
+ return {
2434
+ runId,
2435
+ query: query2,
2436
+ succeeded,
2437
+ messages: responseMessages,
2438
+ codeUsed
2439
+ };
2212
2440
  }
2213
2441
  }
2214
- var sdk_client_default = query;
2215
2442
 
2216
2443
  // src/index.ts
2444
+ init_sdk_client();
2217
2445
  import {
2218
2446
  AbortError,
2219
2447
  createSdkMcpServer,
@@ -2252,6 +2480,7 @@ export {
2252
2480
  CacheUnavailableError,
2253
2481
  AuthenticationError,
2254
2482
  AgentVerdict,
2483
+ Agent,
2255
2484
  AbortError,
2256
2485
  APIError
2257
2486
  };