diff --git a/cli/src/guidance/skills.ts b/cli/src/guidance/skills.ts index 6298c39dfb..1f75778bb4 100644 --- a/cli/src/guidance/skills.ts +++ b/cli/src/guidance/skills.ts @@ -262,6 +262,8 @@ const result: S3Object = await wmill.writeS3File( Import: import * as wmill from 'windmill-client' +workerHasInternalServer(): boolean + /** * Initialize the Windmill client with authentication token and base URL * @param token - Authentication token (defaults to WM_TOKEN env variable) @@ -925,6 +927,8 @@ const result: S3Object = await wmill.writeS3File( Import: import * as wmill from 'windmill-client' +workerHasInternalServer(): boolean + /** * Initialize the Windmill client with authentication token and base URL * @param token - Authentication token (defaults to WM_TOKEN env variable) @@ -1651,6 +1655,8 @@ const result: S3Object = await wmill.writeS3File( Import: import * as wmill from 'windmill-client' +workerHasInternalServer(): boolean + /** * Initialize the Windmill client with authentication token and base URL * @param token - Authentication token (defaults to WM_TOKEN env variable) @@ -2591,6 +2597,8 @@ export async function preprocessor(event: Event) { Import: import * as wmill from 'windmill-client' +workerHasInternalServer(): boolean + /** * Initialize the Windmill client with authentication token and base URL * @param token - Authentication token (defaults to WM_TOKEN env variable) @@ -3433,6 +3441,8 @@ result: S3Object = wmill.write_s3_file( Import: import wmill +def worker_has_internal_server() -> bool + def get_mocked_api() -> Optional[dict] # Get the HTTP client instance. @@ -3497,7 +3507,10 @@ def run_script_by_path(path: str, args: dict = None, timeout: dt.timedelta | int # Run script by hash synchronously and return its result. def run_script_by_hash(hash_: str, args: dict = None, timeout: dt.timedelta | int | float | None = None, verbose: bool = False, cleanup: bool = True, assert_result_is_not_none: bool = False) -> Any -# Run a script on the current worker without creating a job +# Run a script on the current worker without creating a job. +# +# On agent workers (no internal server), falls back to running a normal +# preview job and waiting for the result. def run_inline_script_preview(content: str, language: str, args: dict = None) -> Any # Wait for a job to complete and return its result. diff --git a/python-client/wmill/wmill/client.py b/python-client/wmill/wmill/client.py index be8d9b1150..d70372f626 100644 --- a/python-client/wmill/wmill/client.py +++ b/python-client/wmill/wmill/client.py @@ -66,6 +66,11 @@ class Windmill: f"workspace required as an argument or as WM_WORKSPACE environment variable" ) + def worker_has_internal_server(self) -> bool: + return bool( + re.match(r"^https?://(localhost|127\.0\.0\.1)(:|/|$)", self.base_url or "") + ) + def get_mocked_api(self) -> Optional[dict]: mocked_path = os.environ.get("WM_MOCKED_API_FILE") if not mocked_path: @@ -326,8 +331,15 @@ class Windmill: language: str, args: dict = None, ) -> Any: - """Run a script on the current worker without creating a job""" - endpoint = f"/w/{self.workspace}/jobs/run_inline/preview" + """Run a script on the current worker without creating a job. + + On agent workers (no internal server), falls back to running a normal + preview job and waiting for the result. + """ + if self.worker_has_internal_server(): + endpoint = f"/w/{self.workspace}/jobs/run_inline/preview" + else: + endpoint = f"/w/{self.workspace}/jobs/run_wait_result/preview" body = { "content": content, "language": language, diff --git a/system_prompts/auto-generated/prompts.ts b/system_prompts/auto-generated/prompts.ts index d5d4f752ad..bdfda1c7aa 100644 --- a/system_prompts/auto-generated/prompts.ts +++ b/system_prompts/auto-generated/prompts.ts @@ -153,6 +153,8 @@ export const SDK_TYPESCRIPT = `# TypeScript SDK (windmill-client) Import: import * as wmill from 'windmill-client' +workerHasInternalServer(): boolean + /** * Initialize the Windmill client with authentication token and base URL * @param token - Authentication token (defaults to WM_TOKEN env variable) @@ -690,6 +692,8 @@ export const SDK_PYTHON = `# Python SDK (wmill) Import: import wmill +def worker_has_internal_server() -> bool + def get_mocked_api() -> Optional[dict] # Get the HTTP client instance. @@ -754,7 +758,10 @@ def run_script_by_path(path: str, args: dict = None, timeout: dt.timedelta | int # Run script by hash synchronously and return its result. def run_script_by_hash(hash_: str, args: dict = None, timeout: dt.timedelta | int | float | None = None, verbose: bool = False, cleanup: bool = True, assert_result_is_not_none: bool = False) -> Any -# Run a script on the current worker without creating a job +# Run a script on the current worker without creating a job. +# +# On agent workers (no internal server), falls back to running a normal +# preview job and waiting for the result. def run_inline_script_preview(content: str, language: str, args: dict = None) -> Any # Wait for a job to complete and return its result. diff --git a/system_prompts/auto-generated/script.md b/system_prompts/auto-generated/script.md index bd9eaf1764..463cd7965b 100644 --- a/system_prompts/auto-generated/script.md +++ b/system_prompts/auto-generated/script.md @@ -1213,6 +1213,8 @@ SELECT * FROM users WHERE name = ? AND age > ?; Import: import * as wmill from 'windmill-client' +workerHasInternalServer(): boolean + /** * Initialize the Windmill client with authentication token and base URL * @param token - Authentication token (defaults to WM_TOKEN env variable) @@ -1750,6 +1752,8 @@ ducklake(name: string = "main"): SqlTemplateFunction Import: import wmill +def worker_has_internal_server() -> bool + def get_mocked_api() -> Optional[dict] # Get the HTTP client instance. @@ -1814,7 +1818,10 @@ def run_script_by_path(path: str, args: dict = None, timeout: dt.timedelta | int # Run script by hash synchronously and return its result. def run_script_by_hash(hash_: str, args: dict = None, timeout: dt.timedelta | int | float | None = None, verbose: bool = False, cleanup: bool = True, assert_result_is_not_none: bool = False) -> Any -# Run a script on the current worker without creating a job +# Run a script on the current worker without creating a job. +# +# On agent workers (no internal server), falls back to running a normal +# preview job and waiting for the result. def run_inline_script_preview(content: str, language: str, args: dict = None) -> Any # Wait for a job to complete and return its result. diff --git a/system_prompts/auto-generated/sdks/python.md b/system_prompts/auto-generated/sdks/python.md index 241d438f58..e0b1bd3dfd 100644 --- a/system_prompts/auto-generated/sdks/python.md +++ b/system_prompts/auto-generated/sdks/python.md @@ -2,6 +2,8 @@ Import: import wmill +def worker_has_internal_server() -> bool + def get_mocked_api() -> Optional[dict] # Get the HTTP client instance. @@ -66,7 +68,10 @@ def run_script_by_path(path: str, args: dict = None, timeout: dt.timedelta | int # Run script by hash synchronously and return its result. def run_script_by_hash(hash_: str, args: dict = None, timeout: dt.timedelta | int | float | None = None, verbose: bool = False, cleanup: bool = True, assert_result_is_not_none: bool = False) -> Any -# Run a script on the current worker without creating a job +# Run a script on the current worker without creating a job. +# +# On agent workers (no internal server), falls back to running a normal +# preview job and waiting for the result. def run_inline_script_preview(content: str, language: str, args: dict = None) -> Any # Wait for a job to complete and return its result. diff --git a/system_prompts/auto-generated/sdks/typescript.md b/system_prompts/auto-generated/sdks/typescript.md index 8d96473313..42c8a8e0ba 100644 --- a/system_prompts/auto-generated/sdks/typescript.md +++ b/system_prompts/auto-generated/sdks/typescript.md @@ -2,6 +2,8 @@ Import: import * as wmill from 'windmill-client' +workerHasInternalServer(): boolean + /** * Initialize the Windmill client with authentication token and base URL * @param token - Authentication token (defaults to WM_TOKEN env variable) diff --git a/system_prompts/auto-generated/skills/write-script-bun/SKILL.md b/system_prompts/auto-generated/skills/write-script-bun/SKILL.md index dd54dbfcd1..0e802b6fba 100644 --- a/system_prompts/auto-generated/skills/write-script-bun/SKILL.md +++ b/system_prompts/auto-generated/skills/write-script-bun/SKILL.md @@ -131,6 +131,8 @@ const result: S3Object = await wmill.writeS3File( Import: import * as wmill from 'windmill-client' +workerHasInternalServer(): boolean + /** * Initialize the Windmill client with authentication token and base URL * @param token - Authentication token (defaults to WM_TOKEN env variable) diff --git a/system_prompts/auto-generated/skills/write-script-bunnative/SKILL.md b/system_prompts/auto-generated/skills/write-script-bunnative/SKILL.md index 8db8b807c2..3e411d4d81 100644 --- a/system_prompts/auto-generated/skills/write-script-bunnative/SKILL.md +++ b/system_prompts/auto-generated/skills/write-script-bunnative/SKILL.md @@ -129,6 +129,8 @@ const result: S3Object = await wmill.writeS3File( Import: import * as wmill from 'windmill-client' +workerHasInternalServer(): boolean + /** * Initialize the Windmill client with authentication token and base URL * @param token - Authentication token (defaults to WM_TOKEN env variable) diff --git a/system_prompts/auto-generated/skills/write-script-deno/SKILL.md b/system_prompts/auto-generated/skills/write-script-deno/SKILL.md index 89e4f67c50..a250d5d60a 100644 --- a/system_prompts/auto-generated/skills/write-script-deno/SKILL.md +++ b/system_prompts/auto-generated/skills/write-script-deno/SKILL.md @@ -135,6 +135,8 @@ const result: S3Object = await wmill.writeS3File( Import: import * as wmill from 'windmill-client' +workerHasInternalServer(): boolean + /** * Initialize the Windmill client with authentication token and base URL * @param token - Authentication token (defaults to WM_TOKEN env variable) diff --git a/system_prompts/auto-generated/skills/write-script-nativets/SKILL.md b/system_prompts/auto-generated/skills/write-script-nativets/SKILL.md index a2df7c864e..df981a2f90 100644 --- a/system_prompts/auto-generated/skills/write-script-nativets/SKILL.md +++ b/system_prompts/auto-generated/skills/write-script-nativets/SKILL.md @@ -96,6 +96,8 @@ export async function preprocessor(event: Event) { Import: import * as wmill from 'windmill-client' +workerHasInternalServer(): boolean + /** * Initialize the Windmill client with authentication token and base URL * @param token - Authentication token (defaults to WM_TOKEN env variable) diff --git a/system_prompts/auto-generated/skills/write-script-python3/SKILL.md b/system_prompts/auto-generated/skills/write-script-python3/SKILL.md index 06000d0a07..04c87ca9eb 100644 --- a/system_prompts/auto-generated/skills/write-script-python3/SKILL.md +++ b/system_prompts/auto-generated/skills/write-script-python3/SKILL.md @@ -137,6 +137,8 @@ result: S3Object = wmill.write_s3_file( Import: import wmill +def worker_has_internal_server() -> bool + def get_mocked_api() -> Optional[dict] # Get the HTTP client instance. @@ -201,7 +203,10 @@ def run_script_by_path(path: str, args: dict = None, timeout: dt.timedelta | int # Run script by hash synchronously and return its result. def run_script_by_hash(hash_: str, args: dict = None, timeout: dt.timedelta | int | float | None = None, verbose: bool = False, cleanup: bool = True, assert_result_is_not_none: bool = False) -> Any -# Run a script on the current worker without creating a job +# Run a script on the current worker without creating a job. +# +# On agent workers (no internal server), falls back to running a normal +# preview job and waiting for the result. def run_inline_script_preview(content: str, language: str, args: dict = None) -> Any # Wait for a job to complete and return its result. diff --git a/typescript-client/client.ts b/typescript-client/client.ts index 1aded4a720..41b66e6d96 100644 --- a/typescript-client/client.ts +++ b/typescript-client/client.ts @@ -43,6 +43,10 @@ export const SHARED_FOLDER = "/shared"; let mockedApi: MockedApi | undefined = undefined; +export function workerHasInternalServer(): boolean { + return /^https?:\/\/(localhost|127\.0\.0\.1)(:|\/|$)/.test(OpenAPI.BASE ?? ""); +} + /** * Initialize the Windmill client with authentication token and base URL * @param token - Authentication token (defaults to WM_TOKEN env variable) diff --git a/typescript-client/sqlUtils.ts b/typescript-client/sqlUtils.ts index eef46c50bc..26af4aff92 100644 --- a/typescript-client/sqlUtils.ts +++ b/typescript-client/sqlUtils.ts @@ -1,4 +1,4 @@ -import { getWorkspace } from "./client"; +import { getWorkspace, workerHasInternalServer } from "./client"; import { JobService } from "./services.gen"; type ResultCollection = @@ -223,10 +223,18 @@ function buildSqlTemplateFunction(provider: SqlProvider): SqlTemplateFunction { if (resultCollection) content = `-- result_collection=${resultCollection}\n${content}`; try { - let result = await JobService.runScriptPreviewInline({ - workspace: getWorkspace(), - requestBody: { args, content, language: provider.language }, - }); + let result; + if (workerHasInternalServer()) { + result = await JobService.runScriptPreviewInline({ + workspace: getWorkspace(), + requestBody: { args, content, language: provider.language }, + }); + } else { + result = await JobService.runScriptPreviewAndWaitResult({ + workspace: getWorkspace(), + requestBody: { args, content, language: provider.language }, + }); + } return result as SqlResult; } catch (e: any) { let err = e;