Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions src/agent/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2038,9 +2038,10 @@ const executeJavascriptTool = defineTool("execute_javascript", {
result:
`Result saved to ${relativePath} (${(fullResultBytes / 1024).toFixed(1)} KB).\n` +
`Preview (first 500 chars):\n${preview}\n\n` +
`Use read_output("${relativePath}") to read the full result.\n` +
`Use read_output("${relativePath}", startLine, endLine) for specific sections.\n` +
`You can also read this file from handler code via host:fs-read.`,
`IMPORTANT: Read the full output by writing a handler that reads "${relativePath}" via host:fs-read.\n` +
`Process the data in handler code — do NOT summarize or propose changes based only on the preview.\n` +
`Only use read_output("${relativePath}") directly if you need a quick look at a specific section;\n` +
`read_output("${relativePath}", startLine, endLine) supports line ranges.`,
...(consoleOutput?.length ? { consoleOutput } : {}),
_resourceStats: resourceStats,
_stats: stats ?? undefined,
Expand Down Expand Up @@ -2898,7 +2899,7 @@ const HELP_TOPICS: Record<string, string> = {
"- YOU orchestrate: pass handler A's result as handler B's event",
"",
"HANDLER CODE STYLE:",
"- Every handler must define function handler(event) or async function handler(event)",
"- Every handler must define function handler(...) or async function handler(...)",
"- The function name is mandatory; parameter names are flexible, and zero parameters are allowed",
"- Module-level state persists across execute_javascript calls",
"",
Expand Down
14 changes: 12 additions & 2 deletions src/code-validator/guest/runtime/src/validator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1003,7 +1003,12 @@ fn check_handler_function(source: &str) -> bool {
}

/// Diagnose handler declarations that look close but are not the required shape.
/// If a valid `function handler` already exists at the top level, skip the
/// misnamed-function check so nested helpers (e.g. `function process(...)`) are
/// not flagged as errors.
fn check_handler_signature_issue(source: &str) -> Option<(String, Option<u32>)> {
let has_valid_handler = check_handler_function(source);

for (line_index, line) in source.lines().enumerate() {
let trimmed = line.trim();
let line_number = Some((line_index + 1) as u32);
Expand Down Expand Up @@ -1052,7 +1057,9 @@ fn check_handler_signature_issue(source: &str) -> Option<(String, Option<u32>)>
let name = &rest[..name_end];
if name == "handler" {
continue;
} else if matches!(name, "Handler" | "handle" | "main" | "run" | "process") {
} else if !has_valid_handler
&& matches!(name, "Handler" | "handle" | "main" | "run" | "process")
{
return Some((
alloc::format!(
"Handler function must be named exactly 'handler'. Found function '{}'. Fix: rename it to function handler(event) {{ ... return result; }}.",
Expand Down Expand Up @@ -1101,8 +1108,11 @@ fn check_handler_has_return(source: &str) -> bool {
}
}
b'f' => {
// Skip nested function and function* declarations
// Skip nested function declarations, generators, and
// anonymous function expressions (function(...) { ... })
if (rest[i..].starts_with("function ")
|| rest[i..].starts_with("function(")
|| rest[i..].starts_with("function*(")
|| rest[i..].starts_with("function*"))
&& let Some(after_nested) = skip_nested_block(rest, i)
{
Expand Down
Loading