mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-24 08:01:38 +00:00
Merge branch 'main' into dieri/triggers-queue-mode
This commit is contained in:
@@ -1,5 +1,25 @@
|
||||
# Changelog
|
||||
|
||||
## [1.574.1](https://github.com/windmill-labs/windmill/compare/v1.574.0...v1.574.1) (2025-11-08)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* make get_logs work even for partial flow jobs ([d6421c2](https://github.com/windmill-labs/windmill/commit/d6421c2ea79993ef7815c50cf035d3b3425e271e))
|
||||
|
||||
## [1.574.0](https://github.com/windmill-labs/windmill/compare/v1.573.5...v1.574.0) (2025-11-07)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* env var in flow ([#6852](https://github.com/windmill-labs/windmill/issues/6852)) ([c59183f](https://github.com/windmill-labs/windmill/commit/c59183f5c39f853d9679c00dd5aa755ef171d735))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **cli:** add automatic handler of .node files for codebase bundler ([62ffe9f](https://github.com/windmill-labs/windmill/commit/62ffe9ffce6d070c81794e8483ab83b431aee9ea))
|
||||
* teams selector svelte5 ([#7087](https://github.com/windmill-labs/windmill/issues/7087)) ([6045f0c](https://github.com/windmill-labs/windmill/commit/6045f0c40654a88e93be688bcdfab874cfc0b267))
|
||||
|
||||
## [1.573.5](https://github.com/windmill-labs/windmill/compare/v1.573.4...v1.573.5) (2025-11-07)
|
||||
|
||||
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
true
|
||||
null
|
||||
]
|
||||
},
|
||||
"hash": "5a219a2532517869578c4504ff3153c43903f929ae5d62fbba12610f89c36d55"
|
||||
|
||||
+4
-4
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "SELECT j.created_by AS \"created_by!\", CONCAT(coalesce(job_logs.logs, '')) as logs, job_logs.log_offset, job_logs.log_file_index\n FROM v2_job j\n LEFT JOIN job_logs ON job_logs.job_id = j.id\n WHERE j.id = $1 AND j.workspace_id = $2 AND ($3::text[] IS NULL OR j.tag = ANY($3))",
|
||||
"query": "SELECT j.created_by AS \"created_by\", coalesce(job_logs.logs, '') as logs, COALESCE(job_logs.log_offset, 0) as log_offset, job_logs.log_file_index\n FROM v2_job j\n LEFT JOIN job_logs ON job_logs.job_id = j.id\n WHERE j.id = $1 AND j.workspace_id = $2 AND ($3::text[] IS NULL OR j.tag = ANY($3))",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "created_by!",
|
||||
"name": "created_by",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
@@ -34,9 +34,9 @@
|
||||
"nullable": [
|
||||
false,
|
||||
null,
|
||||
false,
|
||||
null,
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "35061719d01929a7146c80de4b637abdad3198d3340ec7c04ed671baff0a4d0b"
|
||||
"hash": "5e7cadffbee74b11e224b60322b102b9899b4a97b8e557692c0085a9b472b8a7"
|
||||
}
|
||||
Generated
+31
-31
@@ -9071,9 +9071,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "openssl"
|
||||
version = "0.10.74"
|
||||
version = "0.10.75"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24ad14dd45412269e1a30f52ad8f0664f0f4f4a89ee8fe28c3b3527021ebb654"
|
||||
checksum = "08838db121398ad17ab8531ce9de97b244589089e290a384c900cb9ff7434328"
|
||||
dependencies = [
|
||||
"bitflags 2.9.4",
|
||||
"cfg-if",
|
||||
@@ -9112,9 +9112,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.110"
|
||||
version = "0.9.111"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0a9f0075ba3c21b09f8e8b2026584b1d18d49388648f2fbbf3c97ea8deced8e2"
|
||||
checksum = "82cab2d520aa75e3c58898289429321eb788c3106963d0dc886ec7a5f4adc321"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
@@ -15137,7 +15137,7 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "windmill"
|
||||
version = "1.573.5"
|
||||
version = "1.574.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"aws-sdk-config",
|
||||
@@ -15197,7 +15197,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-api"
|
||||
version = "1.573.5"
|
||||
version = "1.574.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"argon2",
|
||||
@@ -15317,7 +15317,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-api-client"
|
||||
version = "1.573.5"
|
||||
version = "1.574.1"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"chrono",
|
||||
@@ -15332,7 +15332,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-audit"
|
||||
version = "1.573.5"
|
||||
version = "1.574.1"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"lazy_static",
|
||||
@@ -15346,7 +15346,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-autoscaling"
|
||||
version = "1.573.5"
|
||||
version = "1.574.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"axum",
|
||||
@@ -15365,7 +15365,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-common"
|
||||
version = "1.573.5"
|
||||
version = "1.574.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-recursion",
|
||||
@@ -15450,7 +15450,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-git-sync"
|
||||
version = "1.573.5"
|
||||
version = "1.574.1"
|
||||
dependencies = [
|
||||
"regex",
|
||||
"serde",
|
||||
@@ -15465,7 +15465,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-indexer"
|
||||
version = "1.573.5"
|
||||
version = "1.574.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
@@ -15489,7 +15489,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-macros"
|
||||
version = "1.573.5"
|
||||
version = "1.574.1"
|
||||
dependencies = [
|
||||
"itertools 0.14.0",
|
||||
"lazy_static",
|
||||
@@ -15501,7 +15501,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser"
|
||||
version = "1.573.5"
|
||||
version = "1.574.1"
|
||||
dependencies = [
|
||||
"convert_case 0.6.0",
|
||||
"serde",
|
||||
@@ -15510,7 +15510,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-bash"
|
||||
version = "1.573.5"
|
||||
version = "1.574.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"lazy_static",
|
||||
@@ -15522,7 +15522,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-csharp"
|
||||
version = "1.573.5"
|
||||
version = "1.574.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"serde_json",
|
||||
@@ -15534,7 +15534,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-go"
|
||||
version = "1.573.5"
|
||||
version = "1.574.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"gosyn",
|
||||
@@ -15546,7 +15546,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-graphql"
|
||||
version = "1.573.5"
|
||||
version = "1.574.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"lazy_static",
|
||||
@@ -15558,7 +15558,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-java"
|
||||
version = "1.573.5"
|
||||
version = "1.574.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"serde_json",
|
||||
@@ -15570,7 +15570,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-nu"
|
||||
version = "1.573.5"
|
||||
version = "1.574.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"nu-parser",
|
||||
@@ -15581,7 +15581,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-php"
|
||||
version = "1.573.5"
|
||||
version = "1.574.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"itertools 0.14.0",
|
||||
@@ -15592,7 +15592,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-py"
|
||||
version = "1.573.5"
|
||||
version = "1.574.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"itertools 0.14.0",
|
||||
@@ -15604,7 +15604,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-py-imports"
|
||||
version = "1.573.5"
|
||||
version = "1.574.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-recursion",
|
||||
@@ -15627,7 +15627,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-ruby"
|
||||
version = "1.573.5"
|
||||
version = "1.574.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"lazy_static",
|
||||
@@ -15641,7 +15641,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-rust"
|
||||
version = "1.573.5"
|
||||
version = "1.574.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"convert_case 0.6.0",
|
||||
@@ -15658,7 +15658,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-sql"
|
||||
version = "1.573.5"
|
||||
version = "1.574.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"lazy_static",
|
||||
@@ -15672,7 +15672,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-ts"
|
||||
version = "1.573.5"
|
||||
version = "1.574.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"lazy_static",
|
||||
@@ -15690,7 +15690,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-yaml"
|
||||
version = "1.573.5"
|
||||
version = "1.574.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"serde",
|
||||
@@ -15701,7 +15701,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-queue"
|
||||
version = "1.573.5"
|
||||
version = "1.574.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-recursion",
|
||||
@@ -15735,7 +15735,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-sql-datatype-parser-wasm"
|
||||
version = "1.573.5"
|
||||
version = "1.574.1"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-test",
|
||||
@@ -15745,7 +15745,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-worker"
|
||||
version = "1.573.5"
|
||||
version = "1.574.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-once-cell",
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "windmill"
|
||||
version = "1.573.5"
|
||||
version = "1.574.1"
|
||||
authors.workspace = true
|
||||
edition.workspace = true
|
||||
|
||||
@@ -33,7 +33,7 @@ members = [
|
||||
exclude = ["./windmill-duckdb-ffi-internal"]
|
||||
|
||||
[workspace.package]
|
||||
version = "1.573.5"
|
||||
version = "1.574.1"
|
||||
authors = ["Ruben Fiszel <ruben@windmill.dev>"]
|
||||
edition = "2021"
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
openapi: "3.0.3"
|
||||
|
||||
info:
|
||||
version: 1.573.5
|
||||
version: 1.574.1
|
||||
title: Windmill API
|
||||
|
||||
contact:
|
||||
|
||||
@@ -1468,7 +1468,7 @@ async fn get_job_logs(
|
||||
.flatten();
|
||||
|
||||
let record = sqlx::query!(
|
||||
"SELECT j.created_by AS \"created_by!\", CONCAT(coalesce(job_logs.logs, '')) as logs, job_logs.log_offset, job_logs.log_file_index
|
||||
"SELECT j.created_by AS \"created_by\", coalesce(job_logs.logs, '') as logs, COALESCE(job_logs.log_offset, 0) as log_offset, job_logs.log_file_index
|
||||
FROM v2_job j
|
||||
LEFT JOIN job_logs ON job_logs.job_id = j.id
|
||||
WHERE j.id = $1 AND j.workspace_id = $2 AND ($3::text[] IS NULL OR j.tag = ANY($3))",
|
||||
@@ -1497,11 +1497,21 @@ async fn get_job_logs(
|
||||
.await?;
|
||||
|
||||
#[cfg(all(feature = "enterprise", feature = "parquet"))]
|
||||
if let Some(r) = get_logs_from_store(record.log_offset, &logs, &record.log_file_index).await
|
||||
if let Some(r) = get_logs_from_store(
|
||||
record.log_offset.unwrap_or(0),
|
||||
&logs,
|
||||
&record.log_file_index,
|
||||
)
|
||||
.await
|
||||
{
|
||||
return r.map(content_plain);
|
||||
}
|
||||
if let Some(r) = get_logs_from_disk(record.log_offset, &logs, &record.log_file_index).await
|
||||
if let Some(r) = get_logs_from_disk(
|
||||
record.log_offset.unwrap_or(0),
|
||||
&logs,
|
||||
&record.log_file_index,
|
||||
)
|
||||
.await
|
||||
{
|
||||
return r.map(content_plain);
|
||||
}
|
||||
@@ -4285,7 +4295,11 @@ pub async fn run_script_by_path_inner(
|
||||
timeout,
|
||||
None,
|
||||
// If the job has a parent job, set priority to 2 as it may be ran synchronously and block a current worker until being executed. Flow steps have a priority of 1 so this is higher.
|
||||
if run_query.parent_job.is_some() || run_query.root_job.is_some() { Some(2) } else { None },
|
||||
if run_query.parent_job.is_some() || run_query.root_job.is_some() {
|
||||
Some(2)
|
||||
} else {
|
||||
None
|
||||
},
|
||||
push_authed.as_ref(),
|
||||
false,
|
||||
None,
|
||||
|
||||
@@ -192,7 +192,7 @@ fn try_exact_property_access(
|
||||
let suffix = &expr[access_pattern_pos..];
|
||||
let maybe_key_name = if suffix.starts_with(DOT_PATTERN) {
|
||||
let key_name_pos = DOT_PATTERN.len();
|
||||
Some(&expr[key_name_pos..])
|
||||
Some(&suffix[key_name_pos..])
|
||||
} else if suffix.starts_with(START_BRACKET_PATTERN) {
|
||||
let key_name_pos = START_BRACKET_PATTERN.len();
|
||||
let suffix = &suffix[key_name_pos..];
|
||||
@@ -220,36 +220,40 @@ fn try_exact_property_access(
|
||||
}
|
||||
|
||||
async fn handle_full_regex(
|
||||
captures: regex::Captures<'_>,
|
||||
expr: &str,
|
||||
authed_client: &AuthedClient,
|
||||
by_id: &IdContext,
|
||||
) -> anyhow::Result<Box<RawValue>> {
|
||||
let obj_name = captures.get(1).unwrap().as_str();
|
||||
let obj_key = captures.get(2).unwrap().as_str();
|
||||
let idx_o = captures.get(3).map(|y| y.as_str());
|
||||
let rest = captures.get(4).map(|y| y.as_str());
|
||||
let query = if let Some(idx) = idx_o {
|
||||
match rest {
|
||||
Some(rest) => Some(format!("{}{}", idx, rest)),
|
||||
None => Some(idx.to_string()),
|
||||
}
|
||||
} else {
|
||||
rest.map(|x| x.trim_start_matches('.').to_string())
|
||||
};
|
||||
) -> Option<anyhow::Result<Box<RawValue>>> {
|
||||
if let Some(captures) = RE_FULL.captures(&expr) {
|
||||
let obj_name = captures.get(1).unwrap().as_str();
|
||||
let obj_key = captures.get(2).unwrap().as_str();
|
||||
let idx_o = captures.get(3).map(|y| y.as_str());
|
||||
let rest = captures.get(4).map(|y| y.as_str());
|
||||
let query = if let Some(idx) = idx_o {
|
||||
match rest {
|
||||
Some(rest) => Some(format!("{}{}", idx, rest)),
|
||||
None => Some(idx.to_string()),
|
||||
}
|
||||
} else {
|
||||
rest.map(|x| x.trim_start_matches('.').to_string())
|
||||
};
|
||||
|
||||
let result = if obj_name == "results" {
|
||||
authed_client
|
||||
.get_result_by_id(&by_id.flow_job.to_string(), obj_key, query)
|
||||
.await
|
||||
} else if obj_name == "flow_env" {
|
||||
authed_client
|
||||
.get_flow_env_by_flow_job_id(&by_id.flow_job.to_string(), obj_key, query)
|
||||
.await
|
||||
} else {
|
||||
unreachable!();
|
||||
};
|
||||
let result = if obj_name == "results" {
|
||||
authed_client
|
||||
.get_result_by_id(&by_id.flow_job.to_string(), obj_key, query)
|
||||
.await
|
||||
} else if obj_name == "flow_env" {
|
||||
authed_client
|
||||
.get_flow_env_by_flow_job_id(&by_id.flow_job.to_string(), obj_key, query)
|
||||
.await
|
||||
} else {
|
||||
unreachable!();
|
||||
};
|
||||
|
||||
return result;
|
||||
return Some(result);
|
||||
}
|
||||
|
||||
return None;
|
||||
}
|
||||
|
||||
pub async fn eval_timeout(
|
||||
@@ -299,8 +303,8 @@ pub async fn eval_timeout(
|
||||
}
|
||||
|
||||
if let (Some(by_id), Some(authed_client)) = (by_id, authed_client) {
|
||||
if let Some(captures) = RE_FULL.captures(&expr) {
|
||||
return handle_full_regex(captures, authed_client, by_id).await;
|
||||
if let Some(result) = handle_full_regex(&expr, authed_client, by_id).await {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -444,9 +448,10 @@ fn replace_with_await(expr: String, fn_name: &str) -> String {
|
||||
s
|
||||
}
|
||||
lazy_static! {
|
||||
static ref RE: Regex =
|
||||
Regex::new(r#"(?m)(?P<r>(?:results|flow_env)(?:\?)?(?:(?:\.[a-zA-Z_0-9]+)|(?:\[\".*?\"\])))"#)
|
||||
.unwrap();
|
||||
static ref RE: Regex = Regex::new(
|
||||
r#"(?m)(?P<r>(?:results|flow_env)(?:\?)?(?:(?:\.[a-zA-Z_0-9]+)|(?:\[\".*?\"\])))"#
|
||||
)
|
||||
.unwrap();
|
||||
static ref RE_FULL: Regex = Regex::new(
|
||||
r"(?m)^(results|flow_env)(?:\?)?\.([a-zA-Z_0-9]+)(?:\[(\d+)\])?((?:\.[a-zA-Z_0-9]+)+)?$"
|
||||
)
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@ import { sleep } from "https://deno.land/x/sleep@v1.2.1/mod.ts";
|
||||
import * as windmill from "https://deno.land/x/windmill@v1.174.0/mod.ts";
|
||||
import * as api from "https://deno.land/x/windmill@v1.174.0/windmill-api/index.ts";
|
||||
|
||||
export const VERSION = "v1.573.5";
|
||||
export const VERSION = "v1.574.1";
|
||||
|
||||
export async function login(email: string, password: string): Promise<string> {
|
||||
return await windmill.UserService.login({
|
||||
|
||||
@@ -180,6 +180,14 @@ export async function handleScriptMetadata(
|
||||
}
|
||||
}
|
||||
|
||||
export interface OutputFile {
|
||||
path: string
|
||||
contents: Uint8Array
|
||||
hash: string
|
||||
/** "contents" as text (changes automatically with "contents") */
|
||||
readonly text: string
|
||||
}
|
||||
|
||||
export async function handleFile(
|
||||
path: string,
|
||||
workspace: Workspace,
|
||||
@@ -210,7 +218,9 @@ export async function handleFile(
|
||||
|
||||
let bundleContent: string | Tarball | undefined = undefined;
|
||||
|
||||
let forceTar = false;
|
||||
if (codebase) {
|
||||
let outputFiles: OutputFile[] = [];
|
||||
if (codebase.customBundler) {
|
||||
log.info(`Using custom bundler ${codebase.customBundler} for ${path}`);
|
||||
bundleContent = execSync(
|
||||
@@ -232,35 +242,42 @@ export async function handleFile(
|
||||
external: codebase.external,
|
||||
inject: codebase.inject,
|
||||
define: codebase.define,
|
||||
loader: codebase.loader ?? { ".node": "file" },
|
||||
outdir: '/',
|
||||
platform: "node",
|
||||
packages: "bundle",
|
||||
target: format == "cjs" ? "node20.15.1" : "esnext",
|
||||
});
|
||||
const endTime = performance.now();
|
||||
bundleContent = out.outputFiles[0].text;
|
||||
outputFiles = out.outputFiles;
|
||||
log.info(
|
||||
`Finished bundling ${path}: ${(bundleContent.length / 1024).toFixed(
|
||||
0
|
||||
)}kB (${(endTime - startTime).toFixed(0)}ms)`
|
||||
);
|
||||
}
|
||||
if (Array.isArray(codebase.assets) && codebase.assets.length > 0) {
|
||||
if (outputFiles.length > 1) {
|
||||
const archiveNpm = await import("npm:@ayonli/jsext/archive");
|
||||
log.info(
|
||||
`Using the following asset configuration for ${path}: ${JSON.stringify(
|
||||
codebase.assets
|
||||
)}`
|
||||
`Found multiple output files for ${path}, creating a tarball... ${outputFiles.map((file) => file.path).join(", ")}`
|
||||
);
|
||||
forceTar = true;
|
||||
const startTime = performance.now();
|
||||
const tarball = new archiveNpm.Tarball();
|
||||
const mainPath = path.split(SEP).pop()?.split(".")[0] + ".js";
|
||||
const content = outputFiles.find((file) => file.path == "/" + mainPath)?.text ?? '';
|
||||
log.info(`Main content: ${content.length}chars`);
|
||||
tarball.append(
|
||||
new File([bundleContent], "main.js", { type: "text/plain" })
|
||||
new File([content], "main.js", { type: "text/plain" })
|
||||
);
|
||||
for (const asset of codebase.assets) {
|
||||
const data = fs.readFileSync(asset.from);
|
||||
const blob = new Blob([data], { type: "text/plain" });
|
||||
const file = new File([blob], asset.to);
|
||||
tarball.append(file);
|
||||
for (const file of outputFiles) {
|
||||
if (file.path == "/" + mainPath) {
|
||||
continue;
|
||||
}
|
||||
log.info(`Adding file: ${file.path.substring(1)}`);
|
||||
const fil = new File([file.contents], file.path.substring(1));
|
||||
tarball.append(fil);
|
||||
}
|
||||
const endTime = performance.now();
|
||||
log.info(
|
||||
@@ -269,6 +286,33 @@ export async function handleFile(
|
||||
).toFixed(0)}kB (${(endTime - startTime).toFixed(0)}ms)`
|
||||
);
|
||||
bundleContent = tarball;
|
||||
} else {
|
||||
if (Array.isArray(codebase.assets) && codebase.assets.length > 0) {
|
||||
const archiveNpm = await import("npm:@ayonli/jsext/archive");
|
||||
log.info(
|
||||
`Using the following asset configuration for ${path}: ${JSON.stringify(
|
||||
codebase.assets
|
||||
)}`
|
||||
);
|
||||
const startTime = performance.now();
|
||||
const tarball = new archiveNpm.Tarball();
|
||||
tarball.append(
|
||||
new File([bundleContent], "main.js", { type: "text/plain" })
|
||||
);
|
||||
for (const asset of codebase.assets) {
|
||||
const data = fs.readFileSync(asset.from);
|
||||
const blob = new Blob([data], { type: "text/plain" });
|
||||
const file = new File([blob], asset.to);
|
||||
tarball.append(file);
|
||||
}
|
||||
const endTime = performance.now();
|
||||
log.info(
|
||||
`Finished creating tarball for ${path}: ${(
|
||||
tarball.size / 1024
|
||||
).toFixed(0)}kB (${(endTime - startTime).toFixed(0)}ms)`
|
||||
);
|
||||
bundleContent = tarball;
|
||||
}
|
||||
}
|
||||
}
|
||||
let typed = opts?.skipScriptsMetadata
|
||||
@@ -325,7 +369,7 @@ export async function handleFile(
|
||||
}
|
||||
|
||||
if (typed && codebase) {
|
||||
typed.codebase = await codebase.getDigest();
|
||||
typed.codebase = await codebase.getDigest(forceTar);
|
||||
}
|
||||
|
||||
const requestBodyCommon: NewScript = {
|
||||
@@ -352,7 +396,7 @@ export async function handleFile(
|
||||
concurrency_key: typed?.concurrency_key,
|
||||
debounce_key: typed?.debounce_key,
|
||||
debounce_delay_s: typed?.debounce_delay_s,
|
||||
codebase: await codebase?.getDigest(),
|
||||
codebase: await codebase?.getDigest(forceTar),
|
||||
timeout: typed?.timeout,
|
||||
on_behalf_of_email: typed?.on_behalf_of_email,
|
||||
};
|
||||
|
||||
@@ -99,6 +99,7 @@ export interface Codebase {
|
||||
external?: string[];
|
||||
define?: { [key: string]: string };
|
||||
inject?: string[];
|
||||
loader?: any,
|
||||
format?: "cjs" | "esm";
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -68,7 +68,7 @@ export {
|
||||
// }
|
||||
// });
|
||||
|
||||
export const VERSION = "1.573.5";
|
||||
export const VERSION = "1.574.1";
|
||||
|
||||
export const WM_FORK_PREFIX = "wm-fork";
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import { Codebase, SyncOptions } from "../core/conf.ts";
|
||||
import { log } from "../../deps.ts";
|
||||
import { digestDir } from "./utils.ts";
|
||||
|
||||
export type SyncCodebase = Codebase & { getDigest: () => Promise<string> };
|
||||
export type SyncCodebase = Codebase & { getDigest: (forceTar?: boolean) => Promise<string> };
|
||||
export function listSyncCodebases(
|
||||
options: SyncOptions
|
||||
): SyncCodebase[] {
|
||||
@@ -13,16 +13,21 @@ export function listSyncCodebases(
|
||||
}
|
||||
for (const codebase of options?.codebases ?? []) {
|
||||
let _digest: string | undefined = undefined;
|
||||
const getDigest: () => Promise<string> = async () => {
|
||||
if (_digest == undefined) {
|
||||
let alreadyPrinted = false;
|
||||
const getDigest: (forceTar?: boolean) => Promise<string> = async (forceTar?: boolean) => {
|
||||
if (_digest == undefined || forceTar) {
|
||||
_digest = await digestDir(
|
||||
codebase.relative_path,
|
||||
JSON.stringify(codebase)
|
||||
);
|
||||
if (Array.isArray(codebase.assets) && codebase.assets.length > 0) {
|
||||
if (forceTar || (Array.isArray(codebase.assets) && codebase.assets.length > 0)) {
|
||||
_digest += ".tar";
|
||||
}
|
||||
log.info(`Codebase ${codebase.relative_path}, digest: ${_digest}`);
|
||||
if (!alreadyPrinted) {
|
||||
alreadyPrinted = true;
|
||||
log.info(`Codebase ${codebase.relative_path}, digest: ${_digest}`);
|
||||
}
|
||||
return _digest;
|
||||
}
|
||||
return _digest;
|
||||
};
|
||||
|
||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "windmill-components",
|
||||
"version": "1.573.5",
|
||||
"version": "1.574.1",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "windmill-components",
|
||||
"version": "1.573.5",
|
||||
"version": "1.574.1",
|
||||
"hasInstallScript": true,
|
||||
"license": "AGPL-3.0",
|
||||
"dependencies": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "windmill-components",
|
||||
"version": "1.573.5",
|
||||
"version": "1.574.1",
|
||||
"scripts": {
|
||||
"dev": "vite dev",
|
||||
"build": "vite build",
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
channels?: ChannelItem[]
|
||||
teamId?: string
|
||||
onError?: (error: Error) => void
|
||||
onselectedchannelchange?: (channel: ChannelItem | undefined) => void
|
||||
onSelectedChannelChange?: (channel: ChannelItem | undefined) => void
|
||||
}
|
||||
|
||||
let {
|
||||
@@ -30,7 +30,7 @@
|
||||
channels = undefined,
|
||||
teamId,
|
||||
onError,
|
||||
onselectedchannelchange
|
||||
onSelectedChannelChange
|
||||
}: Props = $props()
|
||||
|
||||
let isFetching = $state(false)
|
||||
@@ -69,7 +69,7 @@
|
||||
$effect(() => {
|
||||
if (selectedChannel?.channel_id !== previousChannelId) {
|
||||
previousChannelId = selectedChannel?.channel_id
|
||||
onselectedchannelchange?.(selectedChannel)
|
||||
onSelectedChannelChange?.(selectedChannel)
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -502,7 +502,7 @@
|
||||
channel_name: handlerExtraArgs['channel_name']
|
||||
}
|
||||
: undefined}
|
||||
onselectedchannelchange={(channel) => {
|
||||
onSelectedChannelChange={(channel) => {
|
||||
handlerExtraArgs['channel'] = channel?.channel_id
|
||||
handlerExtraArgs['channel_name'] = channel?.channel_name
|
||||
}}
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
import { aiChatManager } from './copilot/chat/AIChatManager.svelte'
|
||||
import { stateSnapshot } from '$lib/svelte5Utils.svelte'
|
||||
import FlowChatInterface from './flows/conversations/FlowChatInterface.svelte'
|
||||
import { randomUUID } from './flows/conversations/FlowChatManager.svelte'
|
||||
|
||||
interface Props {
|
||||
previewMode: 'upTo' | 'whole'
|
||||
@@ -469,7 +470,7 @@
|
||||
return jobId ?? ''
|
||||
}}
|
||||
createConversation={async () => {
|
||||
const newConversationId = crypto.randomUUID()
|
||||
const newConversationId = randomUUID()
|
||||
return newConversationId
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -586,7 +586,7 @@
|
||||
minWidth="140px"
|
||||
showRefreshButton={false}
|
||||
selectedTeam={currentTeam}
|
||||
onselectedteamchange={(team) => handleTeamChange(team, i)}
|
||||
onSelectedTeamChange={(team) => handleTeamChange(team, i)}
|
||||
/>
|
||||
|
||||
{#if $values['critical_error_channels'][i]?.teams_channel?.team_id}
|
||||
@@ -595,7 +595,7 @@
|
||||
placeholder="Search channels"
|
||||
teamId={$values['critical_error_channels'][i]?.teams_channel?.team_id}
|
||||
selectedChannel={currentChannel}
|
||||
onselectedchannelchange={(channel) => handleChannelChange(channel, i)}
|
||||
onSelectedChannelChange={(channel) => handleChannelChange(channel, i)}
|
||||
onError={(e) =>
|
||||
sendUserToast('Failed to load channels: ' + e.message, true)}
|
||||
/>
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
teams?: TeamItem[] | undefined
|
||||
minWidth?: string
|
||||
onError?: (error: Error) => void
|
||||
onselectedteamchange?: (team: TeamItem | undefined) => void
|
||||
onSelectedTeamChange?: (team: TeamItem | undefined) => void
|
||||
}
|
||||
|
||||
let {
|
||||
@@ -29,7 +29,7 @@
|
||||
teams = undefined,
|
||||
minWidth = '160px',
|
||||
onError,
|
||||
onselectedteamchange
|
||||
onSelectedTeamChange
|
||||
}: Props = $props()
|
||||
|
||||
let isFetching = $state(false)
|
||||
@@ -68,7 +68,7 @@
|
||||
$effect(() => {
|
||||
if (selectedTeam?.team_id !== previousTeamId) {
|
||||
previousTeamId = selectedTeam?.team_id
|
||||
onselectedteamchange?.(selectedTeam)
|
||||
onSelectedTeamChange?.(selectedTeam)
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -55,7 +55,11 @@
|
||||
})
|
||||
|
||||
let selectedItems: string[] = $state([...new Set(outputs?.result.peak())].map(convertToValue))
|
||||
$effect(() => setResultsFromSelectedItems(selectedItems))
|
||||
$effect(() => {
|
||||
selectedItems
|
||||
// console.log('selectedItems', selectedItems)
|
||||
untrack(() => setResultsFromSelectedItems(selectedItems))
|
||||
})
|
||||
|
||||
let customItems: string[] = $state([])
|
||||
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
import { AI_AGENT_SCHEMA } from '../flowInfers'
|
||||
import { nextId } from '../flowModuleNextId'
|
||||
import ConfirmationModal from '$lib/components/common/confirmationModal/ConfirmationModal.svelte'
|
||||
import { randomUUID } from '../conversations/FlowChatManager.svelte'
|
||||
|
||||
interface Props {
|
||||
noEditor: boolean
|
||||
@@ -491,7 +492,7 @@
|
||||
<FlowChatInterface
|
||||
onRunFlow={runFlowWithMessage}
|
||||
createConversation={async () => {
|
||||
const newConversationId = crypto.randomUUID()
|
||||
const newConversationId = randomUUID()
|
||||
return newConversationId
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -18,6 +18,15 @@ export interface FlowChatManagerOptions {
|
||||
path?: string
|
||||
}
|
||||
|
||||
export function randomUUID() {
|
||||
// Pure JS (RFC4122 v4) UUID implementation (no external dependencies)
|
||||
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
|
||||
const r = (Math.random() * 16) | 0
|
||||
const v = c === 'x' ? r : (r & 0x3) | 0x8
|
||||
return v.toString(16)
|
||||
})
|
||||
}
|
||||
|
||||
class FlowChatManager {
|
||||
// State
|
||||
messages = $state<ChatMessage[]>([])
|
||||
@@ -320,7 +329,7 @@ class FlowChatManager {
|
||||
delete this.#conversationsCache[currentConversationId]
|
||||
|
||||
const userMessage: ChatMessage = {
|
||||
id: crypto.randomUUID(),
|
||||
id: randomUUID(),
|
||||
content: this.inputMessage.trim(),
|
||||
created_at: new Date().toISOString(),
|
||||
message_type: 'user',
|
||||
@@ -371,17 +380,20 @@ class FlowChatManager {
|
||||
let isCompleted = false
|
||||
|
||||
try {
|
||||
const jobId = await JobService.runFlowByPath({
|
||||
workspace: this.#workspace!,
|
||||
path: this.#path!,
|
||||
requestBody: { user_message: messageContent },
|
||||
memoryId: currentConversationId
|
||||
})
|
||||
// Encode the payload as base64
|
||||
const payload = { user_message: messageContent }
|
||||
const payloadBase64 = btoa(JSON.stringify(payload))
|
||||
|
||||
// Build the EventSource URL
|
||||
const streamUrl = `/api/w/${this.#workspace}/jobs/run_and_stream/f/${this.#path}`
|
||||
const streamUrl = `/api/w/${this.#workspace}/jobs_u/getupdate_sse/${jobId}`
|
||||
const url = new URL(streamUrl, window.location.origin)
|
||||
url.searchParams.set('payload', payloadBase64)
|
||||
url.searchParams.set('memory_id', currentConversationId)
|
||||
url.searchParams.set('poll_delay_ms', '50')
|
||||
|
||||
url.searchParams.set('fast', 'true')
|
||||
url.searchParams.set('only_result', 'true')
|
||||
// Create EventSource connection
|
||||
const eventSource = new EventSource(url.toString())
|
||||
this.currentEventSource = eventSource
|
||||
@@ -392,7 +404,6 @@ class FlowChatManager {
|
||||
eventSource.onmessage = async (event) => {
|
||||
try {
|
||||
const data = JSON.parse(event.data)
|
||||
|
||||
if (data.type === 'update') {
|
||||
if (data.flow_stream_job_id) {
|
||||
this.currentJobId = data.flow_stream_job_id
|
||||
@@ -420,7 +431,7 @@ class FlowChatManager {
|
||||
this.messages = [
|
||||
...this.messages,
|
||||
{
|
||||
id: 'temp-' + crypto.randomUUID(),
|
||||
id: 'temp-' + randomUUID(),
|
||||
content: newContent,
|
||||
created_at: new Date().toISOString(),
|
||||
message_type: 'tool',
|
||||
@@ -442,7 +453,7 @@ class FlowChatManager {
|
||||
assistantMessageId.length === 0 &&
|
||||
accumulatedContent.length > 0
|
||||
) {
|
||||
assistantMessageId = 'temp-' + crypto.randomUUID()
|
||||
assistantMessageId = 'temp-' + randomUUID()
|
||||
this.messages = [
|
||||
...this.messages,
|
||||
{
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
export let error: boolean = false
|
||||
export let allowCopy = false
|
||||
export let previousId: string | undefined = undefined
|
||||
export let flow_env: Record<string, string> | undefined = undefined
|
||||
export let flow_env: Record<string, any> | undefined = undefined
|
||||
|
||||
let variables: Record<string, string> = {}
|
||||
let resources: Record<string, any> = {}
|
||||
|
||||
@@ -65,6 +65,7 @@
|
||||
initFlowGraphAssetsCtx
|
||||
} from '$lib/components/flows/FlowAssetsHandler.svelte'
|
||||
import { page } from '$app/state'
|
||||
import { randomUUID } from '$lib/components/flows/conversations/FlowChatManager.svelte'
|
||||
|
||||
let flow: Flow | undefined = $state()
|
||||
let can_write = false
|
||||
@@ -401,7 +402,7 @@
|
||||
let path = $derived(page.params.path ?? '')
|
||||
|
||||
async function handleNewConversation({ clearMessages = true }: { clearMessages?: boolean }) {
|
||||
const newConversationId = crypto.randomUUID()
|
||||
const newConversationId = randomUUID()
|
||||
|
||||
// Add the new conversation to the sidebar (returns id of draft or new conversation)
|
||||
if (flowConversationsSidebar) {
|
||||
|
||||
+2
-2
@@ -4,8 +4,8 @@ verify_ssl = true
|
||||
name = "pypi"
|
||||
|
||||
[packages]
|
||||
wmill = ">=1.573.5"
|
||||
wmill_pg = ">=1.573.5"
|
||||
wmill = ">=1.574.1"
|
||||
wmill_pg = ">=1.574.1"
|
||||
sendgrid = "*"
|
||||
mysql-connector-python = "*"
|
||||
pymongo = "*"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
openapi: "3.0.3"
|
||||
|
||||
info:
|
||||
version: 1.573.5
|
||||
version: 1.574.1
|
||||
title: OpenFlow Spec
|
||||
contact:
|
||||
name: Ruben Fiszel
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
RootModule = 'WindmillClient.psm1'
|
||||
|
||||
# Version number of this module.
|
||||
ModuleVersion = '1.573.5'
|
||||
ModuleVersion = '1.574.1'
|
||||
|
||||
# Supported PSEditions
|
||||
# CompatiblePSEditions = @()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[tool.poetry]
|
||||
name = "wmill"
|
||||
version = "1.573.5"
|
||||
version = "1.574.1"
|
||||
description = "A client library for accessing Windmill server wrapping the Windmill client API"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://windmill.dev"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[tool.poetry]
|
||||
name = "wmill-pg"
|
||||
version = "1.573.5"
|
||||
version = "1.574.1"
|
||||
description = "An extension client for the wmill client library focused on pg"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://windmill.dev"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@windmill/windmill",
|
||||
"version": "1.573.5",
|
||||
"version": "1.574.1",
|
||||
"exports": "./src/index.ts",
|
||||
"publish": {
|
||||
"exclude": ["!src", "./s3Types.ts", "./client.ts"]
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "windmill-client",
|
||||
"description": "Windmill SDK client for browsers and Node.js",
|
||||
"version": "1.573.5",
|
||||
"version": "1.574.1",
|
||||
"author": "Ruben Fiszel",
|
||||
"license": "Apache 2.0",
|
||||
"devDependencies": {
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
1.573.5
|
||||
1.574.1
|
||||
|
||||
Reference in New Issue
Block a user