diff --git a/.github/workflows/automerge-dependabot.yml b/.github/workflows/automerge-dependabot.yml.archived similarity index 100% rename from .github/workflows/automerge-dependabot.yml rename to .github/workflows/automerge-dependabot.yml.archived diff --git a/backend/windmill-api/openapi.yaml b/backend/windmill-api/openapi.yaml index 449f8553f3..2310b7e91a 100644 --- a/backend/windmill-api/openapi.yaml +++ b/backend/windmill-api/openapi.yaml @@ -2326,6 +2326,65 @@ paths: items: type: string + /resources/type/hub/list: + get: + summary: list hub resource types + operationId: listHubResourceTypes + tags: + - resource + responses: + "200": + description: resource type details + content: + application/json: + schema: + type: array + items: + type: object + properties: + id: + type: string + name: + type: string + schema: {} + required: + - id + - name + + /resources/type/hub/query: + get: + summary: query hub resource types by similarity + operationId: queryHubResourceTypes + tags: + - resource + parameters: + - name: text + description: query text + in: query + required: true + schema: + type: string + - name: limit + description: query limit + in: query + required: false + schema: + type: number + responses: + "200": + description: resource type details + content: + application/json: + schema: + type: array + items: + type: object + properties: + id: + type: string + required: + - id + /scripts/hub/list: get: summary: list all available hub scripts diff --git a/backend/windmill-api/src/apps.rs b/backend/windmill-api/src/apps.rs index 391349fc4a..f48e27462a 100644 --- a/backend/windmill-api/src/apps.rs +++ b/backend/windmill-api/src/apps.rs @@ -15,7 +15,9 @@ use crate::{ HTTP_CLIENT, }; use axum::{ + body::StreamBody, extract::{Extension, Json, Path, Query}, + response::IntoResponse, routing::{delete, get, post}, Router, }; @@ -35,7 +37,7 @@ use windmill_common::{ jobs::{get_payload_tag_from_prefixed_path, JobPayload, RawCode}, users::username_to_permissioned_as, utils::{ - http_get_from_hub, list_elems_from_hub, not_found_if_none, paginate, Pagination, StripPath, + http_get_from_hub, not_found_if_none, paginate, query_elems_from_hub, Pagination, StripPath, }, }; use windmill_queue::{push, PushIsolationLevel, QueueTransaction}; @@ -544,14 +546,19 @@ async fn create_app( Ok((StatusCode::CREATED, app.path)) } -async fn list_hub_apps(ApiAuthed { email, .. }: ApiAuthed) -> JsonResult { - let flows = list_elems_from_hub( +async fn list_hub_apps(ApiAuthed { email, .. }: ApiAuthed) -> impl IntoResponse { + let (status_code, headers, response) = query_elems_from_hub( &HTTP_CLIENT, "https://hub.windmill.dev/searchUiData?approved=true", &email, + None, ) .await?; - Ok(Json(flows)) + Ok::<_, Error>(( + status_code, + headers, + StreamBody::new(response.bytes_stream()), + )) } pub async fn get_hub_app_by_id( diff --git a/backend/windmill-api/src/flows.rs b/backend/windmill-api/src/flows.rs index 39178bb284..5c55f9f891 100644 --- a/backend/windmill-api/src/flows.rs +++ b/backend/windmill-api/src/flows.rs @@ -14,6 +14,8 @@ use crate::{ webhook_util::{WebhookMessage, WebhookShared}, HTTP_CLIENT, }; +use axum::body::StreamBody; +use axum::response::IntoResponse; use axum::{ extract::{Extension, Path, Query}, routing::{delete, get, post}, @@ -26,6 +28,7 @@ use sql_builder::prelude::*; use sql_builder::SqlBuilder; use sqlx::{FromRow, Postgres, Transaction}; use windmill_audit::{audit_log, ActionKind}; +use windmill_common::utils::query_elems_from_hub; use windmill_common::{ db::UserDB, error::{self, to_anyhow, Error, JsonResult, Result}, @@ -33,9 +36,7 @@ use windmill_common::{ jobs::JobPayload, schedule::Schedule, scripts::Schema, - utils::{ - http_get_from_hub, list_elems_from_hub, not_found_if_none, paginate, Pagination, StripPath, - }, + utils::{http_get_from_hub, not_found_if_none, paginate, Pagination, StripPath}, }; use windmill_queue::{push, schedule::push_scheduled_job, PushIsolationLevel, QueueTransaction}; @@ -156,14 +157,19 @@ async fn list_flows( Ok(Json(rows)) } -async fn list_hub_flows(ApiAuthed { email, .. }: ApiAuthed) -> JsonResult { - let flows = list_elems_from_hub( +async fn list_hub_flows(ApiAuthed { email, .. }: ApiAuthed) -> impl IntoResponse { + let (status_code, headers, response) = query_elems_from_hub( &HTTP_CLIENT, "https://hub.windmill.dev/searchFlowData?approved=true", &email, + None, ) .await?; - Ok(Json(flows)) + Ok::<_, Error>(( + status_code, + headers, + StreamBody::new(response.bytes_stream()), + )) } async fn list_paths( diff --git a/backend/windmill-api/src/lib.rs b/backend/windmill-api/src/lib.rs index be71de8a38..7bc1b39818 100644 --- a/backend/windmill-api/src/lib.rs +++ b/backend/windmill-api/src/lib.rs @@ -205,6 +205,7 @@ pub async fn run_server( .nest("/workers", workers::global_service()) .nest("/configs", configs::global_service()) .nest("/scripts", scripts::global_service()) + .nest("/resources", resources::global_service()) .nest("/groups", groups::global_service()) .nest("/flows", flows::global_service()) .nest("/apps", apps::global_service().layer(cors.clone())) diff --git a/backend/windmill-api/src/openai.rs b/backend/windmill-api/src/openai.rs index 9bfded69b1..dd3094d2e2 100644 --- a/backend/windmill-api/src/openai.rs +++ b/backend/windmill-api/src/openai.rs @@ -7,7 +7,6 @@ use crate::{ use axum::{ body::{Bytes, StreamBody}, extract::{Extension, Path}, - http::HeaderMap, response::IntoResponse, routing::post, Router, @@ -170,12 +169,8 @@ async fn proxy( )); } - let mut headers = HeaderMap::new(); - for (k, v) in response.headers().iter() { - headers.insert(k, v.clone()); - } - let status_code = response.status(); + let headers = response.headers().clone(); let stream = response.bytes_stream(); Ok((status_code, headers, StreamBody::new(stream))) diff --git a/backend/windmill-api/src/resources.rs b/backend/windmill-api/src/resources.rs index a5a5422d27..5999823468 100644 --- a/backend/windmill-api/src/resources.rs +++ b/backend/windmill-api/src/resources.rs @@ -10,9 +10,12 @@ use crate::{ db::{ApiAuthed, DB}, users::{maybe_refresh_folders, require_owner_of_path, Tokened}, webhook_util::{WebhookMessage, WebhookShared}, + HTTP_CLIENT, }; use axum::{ + body::StreamBody, extract::{Extension, Path, Query}, + response::IntoResponse, routing::{delete, get, post}, Json, Router, }; @@ -27,10 +30,18 @@ use windmill_common::{ db::UserDB, error::{Error, JsonResult, Result}, jobs::QueuedJob, - utils::{not_found_if_none, paginate, require_admin, Pagination, StripPath}, + utils::{ + not_found_if_none, paginate, query_elems_from_hub, require_admin, Pagination, StripPath, + }, variables, }; +pub fn global_service() -> Router { + Router::new() + .route("/type/hub/list", get(list_hub_resource_types)) + .route("/type/hub/query", get(query_hub_resource_types)) +} + pub fn workspaced_service() -> Router { Router::new() .route("/list", get(list_resources)) @@ -898,3 +909,46 @@ async fn update_resource_type( Ok(format!("resource_type {} updated", name)) } + +async fn list_hub_resource_types(ApiAuthed { email, .. }: ApiAuthed) -> impl IntoResponse { + let (status_code, headers, response) = query_elems_from_hub( + &HTTP_CLIENT, + "https://hub.windmill.dev/resource_types/list", + &email, + None, + ) + .await?; + Ok::<_, Error>(( + status_code, + headers, + StreamBody::new(response.bytes_stream()), + )) +} + +#[derive(Deserialize)] +struct HubResourceTypesQuery { + text: String, + limit: Option, +} +async fn query_hub_resource_types( + ApiAuthed { email, .. }: ApiAuthed, + Query(query): Query, +) -> impl IntoResponse { + let mut query_params = vec![("text", query.text)]; + if let Some(query_limit) = query.limit { + query_params.push(("limit", query_limit.to_string().clone())); + } + let (status_code, headers, response) = query_elems_from_hub( + &HTTP_CLIENT, + "https://hub.windmill.dev/resource_types/query", + &email, + Some(query_params), + ) + .await?; + + Ok::<_, Error>(( + status_code, + headers, + StreamBody::new(response.bytes_stream()), + )) +} diff --git a/backend/windmill-api/src/scripts.rs b/backend/windmill-api/src/scripts.rs index b1bab3405b..e0582e5cd2 100644 --- a/backend/windmill-api/src/scripts.rs +++ b/backend/windmill-api/src/scripts.rs @@ -14,7 +14,9 @@ use crate::{ HTTP_CLIENT, }; use axum::{ + body::StreamBody, extract::{Extension, Path, Query}, + response::IntoResponse, routing::{get, post}, Json, Router, }; @@ -41,8 +43,7 @@ use windmill_common::{ }, users::username_to_permissioned_as, utils::{ - list_elems_from_hub, not_found_if_none, paginate, query_elems_from_hub, require_admin, - Pagination, StripPath, + not_found_if_none, paginate, query_elems_from_hub, require_admin, Pagination, StripPath, }, }; use windmill_queue::{self, schedule::push_scheduled_job, PushIsolationLevel, QueueTransaction}; @@ -233,14 +234,19 @@ async fn list_scripts( Ok(Json(rows)) } -async fn list_hub_scripts(ApiAuthed { email, .. }: ApiAuthed) -> JsonResult { - let asks = list_elems_from_hub( +async fn list_hub_scripts(ApiAuthed { email, .. }: ApiAuthed) -> impl IntoResponse { + let (status_code, headers, response) = query_elems_from_hub( &HTTP_CLIENT, "https://hub.windmill.dev/searchData?approved=true", &email, + None, ) .await?; - Ok(Json(asks)) + Ok::<_, Error>(( + status_code, + headers, + StreamBody::new(response.bytes_stream()), + )) } #[derive(Deserialize)] @@ -252,17 +258,26 @@ struct HubScriptsQuery { async fn query_hub_scripts( ApiAuthed { email, .. }: ApiAuthed, Query(query): Query, -) -> JsonResult { - let asks = query_elems_from_hub( +) -> impl IntoResponse { + let mut query_params = vec![("text", query.text)]; + if let Some(query_kind) = query.kind { + query_params.push(("kind", query_kind.clone())); + } + if let Some(query_limit) = query.limit { + query_params.push(("limit", query_limit.to_string().clone())); + } + let (status_code, headers, response) = query_elems_from_hub( &HTTP_CLIENT, "https://hub.windmill.dev/scripts/query", &email, - &query.text, - &query.kind, - &query.limit, + Some(query_params), ) .await?; - Ok(Json(asks)) + Ok::<_, Error>(( + status_code, + headers, + StreamBody::new(response.bytes_stream()), + )) } fn hash_script(ns: &NewScript) -> i64 { diff --git a/backend/windmill-common/src/utils.rs b/backend/windmill-common/src/utils.rs index d25e24a541..36660ce337 100644 --- a/backend/windmill-common/src/utils.rs +++ b/backend/windmill-common/src/utils.rs @@ -7,6 +7,7 @@ */ use crate::error::{Error, Result}; +use hyper::{HeaderMap, StatusCode}; use rand::{distributions::Alphanumeric, thread_rng, Rng}; use serde::{Deserialize, Serialize}; use sha2::{Digest, Sha256}; @@ -73,43 +74,18 @@ pub fn not_found_if_none>(opt: Option, kind: &str, name: U) } } -#[cfg(feature = "reqwest")] -pub async fn list_elems_from_hub( - http_client: &reqwest::Client, - url: &str, - email: &str, -) -> Result { - let rows = http_get_from_hub(http_client, url, email, false, None) - .await? - .json::() - .await - .map_err(crate::error::to_anyhow)?; - Ok(rows) -} - #[cfg(feature = "reqwest")] pub async fn query_elems_from_hub( http_client: &reqwest::Client, url: &str, email: &str, - query_text: &str, - query_kind: &Option, - query_limit: &Option, -) -> Result { - let mut query_params = vec![("text", query_text)]; - if let Some(query_kind) = query_kind { - query_params.push(("kind", query_kind.as_str())); - } - let query_limit = query_limit.unwrap_or(0).to_string(); - if query_limit.parse::().unwrap() > 0 { - query_params.push(("limit", query_limit.as_str())); - } - let rows = http_get_from_hub(http_client, url, email, false, Some(query_params)) - .await? - .json::() - .await - .map_err(crate::error::to_anyhow)?; - Ok(rows) + query_params: Option>, +) -> Result<(StatusCode, HeaderMap, reqwest::Response)> { + let response = http_get_from_hub(http_client, url, email, false, query_params).await?; + + let status = response.status(); + + Ok((status, response.headers().clone(), response)) } #[cfg(feature = "reqwest")] @@ -118,7 +94,7 @@ pub async fn http_get_from_hub( url: &str, email: &str, plain: bool, - query_params: Option>, + query_params: Option>, ) -> Result { let mut request = http_client .get(url) diff --git a/frontend/src/lib/components/FlowBuilder.svelte b/frontend/src/lib/components/FlowBuilder.svelte index 308eb93c7e..89d200d27f 100644 --- a/frontend/src/lib/components/FlowBuilder.svelte +++ b/frontend/src/lib/components/FlowBuilder.svelte @@ -55,6 +55,7 @@ import { fade } from 'svelte/transition' import { loadFlowModuleState } from './flows/flowStateUtils' import FlowCopilotInputsModal from './copilot/FlowCopilotInputsModal.svelte' + import { snakeCase } from 'lodash' import FlowBuilderTutorials from './FlowBuilderTutorials.svelte' import FlowTutorials from './FlowTutorials.svelte' @@ -662,15 +663,16 @@ copilotFlowInputs = {} copilotFlowRequiredInputs = [] Object.entries(inputs).forEach(([key, expr]) => { + const snakeKey = snakeCase(key) if ( key in stepSchema.properties && expr.includes('flow_input.') && !expr.includes('flow_input.iter') && - (!$flowStore.schema || !(key in $flowStore.schema.properties)) // prevent overriding flow inputs + (!$flowStore.schema || !(snakeKey in $flowStore.schema.properties)) // prevent overriding flow inputs ) { - copilotFlowInputs[key] = stepSchema.properties[key] - if (stepSchema.required.includes(key)) { - copilotFlowRequiredInputs.push(key) + copilotFlowInputs[snakeKey] = stepSchema.properties[snakeKey] + if (stepSchema.required.includes(snakeKey)) { + copilotFlowRequiredInputs.push(snakeKey) } } }) @@ -682,7 +684,7 @@ Object.entries(inputs).forEach(([key, expr]) => { flowModule.value.input_transforms[key] = { type: 'javascript', - expr + expr: expr.replaceAll(/flow_input\.([A-Za-z0-9_]+)/g, (_, p1) => 'flow_input.' + p1) } }) } else { @@ -706,13 +708,14 @@ const schemaProperty = Object.entries(schema.properties).find( (x) => x[0] === key )?.[1] + const snakeKey = snakeCase(key) if ( schemaProperty && - (!$flowStore.schema || !(key in $flowStore.schema.properties)) // prevent overriding flow inputs + (!$flowStore.schema || !(snakeKey in $flowStore.schema.properties)) // prevent overriding flow inputs ) { - copilotFlowInputs[key] = schemaProperty - if (schema.required.includes(key)) { - copilotFlowRequiredInputs.push(key) + copilotFlowInputs[snakeKey] = schemaProperty + if (schema.required.includes(snakeKey)) { + copilotFlowRequiredInputs.push(snakeKey) } } } @@ -723,6 +726,7 @@ // programatically set step inputs for (const key of Object.keys(flowModule.value.input_transforms)) { + const snakeKey = snakeCase(key) flowModule.value.input_transforms[key] = { type: 'javascript', expr: @@ -731,8 +735,8 @@ ? 'flow_input.iter.value' : pastModule ? 'results.' + pastModule.id - : 'flow_input.' + key - : 'flow_input.' + key + : 'flow_input.' + snakeKey + : 'flow_input.' + snakeKey } } } diff --git a/frontend/src/lib/components/copilot/flow.ts b/frontend/src/lib/components/copilot/flow.ts index 1bab7561d8..a4b78ecdba 100644 --- a/frontend/src/lib/components/copilot/flow.ts +++ b/frontend/src/lib/components/copilot/flow.ts @@ -56,21 +56,21 @@ const additionalInfos: { bun: ` We have to export a "main" function like this: "export async function main(...)" and specify the parameter types but do not call it. If needed, the standard fetch method is available globally, do not import it. -You can take as parameters resources which are dictionaries containing credentials or configuration information. Name the resource parameters like this: "{resource_type}_resource". -The resource type name has to be exactly as specified. +You can take as parameters resources which are dictionaries containing credentials or configuration information. Name the resource parameters like this: "{resource_type}Resource". +The following resource types are available: {resourceTypes} -Only define the type for resources that are actually needed to achieve the function purpose. If the type name conflicts with the imported object, rename the imported object NOT THE TYPE. +Only define the type for resources that are actually needed to achieve the function purpose. The resource type name has to be exactly as specified. If the type name conflicts with the imported object, rename the imported object NOT THE TYPE. `, python3: ` We have to export a "main" function and specify the parameter types but do not call it. -You can take as parameters resources which are dictionaries containing credentials or configuration information. Name the resource parameters like this: "{resource_type}Resource". -The resource type name has to be exactly as specified (has to be IN LOWERCASE). +You can take as parameters resources which are dictionaries containing credentials or configuration information. Name the resource parameters like this: "{resource_type}_resource". +The following resource types are available: {resourceTypes} -Only define the type for resources that are actually needed to achieve the function purpose. If the type name conflicts with the imported object, rename the imported object NOT THE TYPE. +Only define the type for resources that are actually needed to achieve the function purpose. The resource type name has to be exactly as specified (has to be IN LOWERCASE). If the type name conflicts with the imported object, rename the imported object NOT THE TYPE. ` } @@ -79,11 +79,11 @@ const triggerPrompts: { python3: string } = { bun: `I'm building a workflow which is a sequence of script steps. Write the first script in {codeLang} which should check for {description} and return an array. -You can use "const {state_name}: {state_type} = await getState()" and "await setState(value: any)" from "windmill-client@1" to maintain state across runs. +To maintain state across runs, you can use "const {state_name}: {state_type} = await getState()" and "await setState(value: any)" which you have to import like this: import { getState, setState } from "windmill-client@1" {additionalInformation}`, python3: `I'm building a workflow which is a sequence of script steps. Write the first script in {codeLang} which should check for {description} and return an array. -You can use get_state() and set_state(value) from wmill to maintain state across runs. +To maintain state across runs, you can use get_state() and set_state(value) which you have to import like this: from wmill import get_state, set_state {additionalInformation}` } diff --git a/frontend/src/lib/components/copilot/lib.ts b/frontend/src/lib/components/copilot/lib.ts index 27531820c7..fea70bdc7e 100644 --- a/frontend/src/lib/components/copilot/lib.ts +++ b/frontend/src/lib/components/copilot/lib.ts @@ -74,18 +74,62 @@ interface FixScriptOpions extends BaseOptions { type CopilotOptions = ScriptGenerationOptions | EditScriptOptions | FixScriptOpions -export async function addResourceTypes(scriptOptions: CopilotOptions, prompt: string) { +async function getResourceTypes(scriptOptions: CopilotOptions) { if (!workspace) { throw new Error('Workspace not initialized') } - if (['deno', 'bun', 'nativets'].includes(scriptOptions.language)) { - const resourceTypes = await ResourceService.listResourceType({ workspace }) - const resourceTypesText = formatResourceTypes(resourceTypes, 'typescript') - prompt = prompt.replace('{resourceTypes}', resourceTypesText) - } else if (scriptOptions.language === 'python3') { - const resourceTypes = await ResourceService.listResourceType({ workspace }) - const resourceTypesText = formatResourceTypes(resourceTypes, 'python3') + const localResourceTypes = await ResourceService.listResourceType({ workspace }) + + const elems = + scriptOptions.type === 'gen' || scriptOptions.type === 'edit' ? [scriptOptions.description] : [] + + if (scriptOptions.type === 'edit' || scriptOptions.type === 'fix') { + const { code } = scriptOptions + + const mainSig = + scriptOptions.language === 'python3' + ? code.match(/def main\((.*?)\)/s) + : code.match(/function main\((.*?)\)/s) + + if (mainSig) { + elems.push(mainSig[1]) + } + + const matches = code.matchAll(/^(?:type|class) ([a-zA-Z0-9_]+)/gm) + + for (const match of matches) { + elems.push(match[1]) + } + } + + const hubResourceTypes = await ResourceService.listHubResourceTypes() + const queriedIds = ( + await ResourceService.queryHubResourceTypes({ + text: elems.join(';') + }) + ).map((rt) => rt.id) + const customResourceTypes = localResourceTypes.filter((rt) => rt.name.startsWith('c_')) + const resourceTypes = [ + ...hubResourceTypes + .filter((rt) => queriedIds.includes(String(rt.id))) + .map((rt) => ({ + ...rt, + schema: JSON.parse(rt.schema) + })), + ...customResourceTypes + ] + + return resourceTypes +} + +export async function addResourceTypes(scriptOptions: CopilotOptions, prompt: string) { + if (['deno', 'bun', 'nativets', 'python3'].includes(scriptOptions.language)) { + const resourceTypes = await getResourceTypes(scriptOptions) + const resourceTypesText = formatResourceTypes( + resourceTypes, + scriptOptions.language === 'python3' ? 'python3' : 'typescript' + ) prompt = prompt.replace('{resourceTypes}', resourceTypesText) } return prompt diff --git a/frontend/src/lib/components/copilot/prompts/edit.yaml b/frontend/src/lib/components/copilot/prompts/edit.yaml index f9bd3b4ae8..1b0e37bf13 100644 --- a/frontend/src/lib/components/copilot/prompts/edit.yaml +++ b/frontend/src/lib/components/copilot/prompts/edit.yaml @@ -16,12 +16,12 @@ prompts: ``` We have to export a "main" function and specify the parameter types but do not call it. - You can take as parameters resources which are dictionaries containing credentials or configuration information. Name the resource parameters like this: "{resource_type}_resource". - The resource type name has to be exactly as specified (has to be IN LOWERCASE). + You can take as parameters resources which are dictionaries containing credentials or configuration information. Name the resource parameters like this: "{resource_type}_resource". + The following resource types are available: {resourceTypes} - Only define the type for resources that are actually needed to achieve the function purpose. If the type name conflicts with the imported object, rename the imported object NOT THE TYPE. + Only define the type for resources that are actually needed to achieve the function purpose. The resource type name has to be exactly as specified (has to be IN LOWERCASE). If the type name conflicts with the imported object, rename the imported object NOT THE TYPE. My instructions: {description} deno: @@ -133,12 +133,12 @@ prompts: ``` We have to export a "main" function like this: "export async function main(...)" and specify the parameter types but do not call it. - You can take as parameters resources which are dictionaries containing credentials or configuration information. Name the resource parameters like this: "{resource_type}Resource". - The resource type name has to be exactly as specified. + You can take as parameters resources which are dictionaries containing credentials or configuration information. Name the resource parameters like this: "{resource_type}Resource". + The following resource types are available: {resourceTypes} - Only define the type for resources that are actually needed to achieve the function purpose. If the type name conflicts with the imported object, rename the imported object NOT THE TYPE. + Only define the type for resources that are actually needed to achieve the function purpose. The resource type name has to be exactly as specified. If the type name conflicts with the imported object, rename the imported object NOT THE TYPE. My instructions: {description} bun: @@ -151,11 +151,11 @@ prompts: We have to export a "main" function like this: "export async function main(...)" and specify the parameter types but do not call it. If needed, the standard fetch method is available globally, do not import it. You can take as parameters resources which are dictionaries containing credentials or configuration information. Name the resource parameters like this: "{resource_type}Resource". - The resource type name has to be exactly as specified. + The following resource types are available: {resourceTypes} - Only define the type for resources that are actually needed to achieve the function purpose. If the type name conflicts with the imported object, rename the imported object NOT THE TYPE. + Only define the type for resources that are actually needed to achieve the function purpose. The resource type name has to be exactly as specified. If the type name conflicts with the imported object, rename the imported object NOT THE TYPE. My instructions: {description} frontend: diff --git a/frontend/src/lib/components/copilot/prompts/editPrompt.ts b/frontend/src/lib/components/copilot/prompts/editPrompt.ts index 639083f045..29a879b001 100644 --- a/frontend/src/lib/components/copilot/prompts/editPrompt.ts +++ b/frontend/src/lib/components/copilot/prompts/editPrompt.ts @@ -2,7 +2,7 @@ export const EDIT_PROMPT = { "system": "You write code as instructed by the user. Only output code. Wrap the code in a code block. \nPut explanations directly in the code as comments.\n\nHere's how interactions have to look like:\nuser: {sample_question}\nassistant: ```language\n{code}\n```", "prompts": { "python3": { - "prompt": "Here's my python3 code: \n```python\n{code}\n```\n\nWe have to export a \"main\" function and specify the parameter types but do not call it.\nYou can take as parameters resources which are dictionaries containing credentials or configuration information. Name the resource parameters like this: \"{resource_type}_resource\". \nThe resource type name has to be exactly as specified (has to be IN LOWERCASE).\n\n{resourceTypes}\n\nOnly define the type for resources that are actually needed to achieve the function purpose. If the type name conflicts with the imported object, rename the imported object NOT THE TYPE.\n\nMy instructions: {description}" + "prompt": "Here's my python3 code: \n```python\n{code}\n```\n\nWe have to export a \"main\" function and specify the parameter types but do not call it.\nYou can take as parameters resources which are dictionaries containing credentials or configuration information. Name the resource parameters like this: \"{resource_type}_resource\".\nThe following resource types are available:\n\n{resourceTypes}\n\nOnly define the type for resources that are actually needed to achieve the function purpose. The resource type name has to be exactly as specified (has to be IN LOWERCASE). If the type name conflicts with the imported object, rename the imported object NOT THE TYPE.\n\nMy instructions: {description}" }, "deno": { "prompt": "Here's my TypeScript code in a deno running environment:\n```typescript\n{code}\n```\n\nWe have to export a \"main\" function like this: \"export async function main(...)\" and specify the parameter types but do not call it.\nIf needed, the standard fetch method is available globally, do not import it.\nYou can take as parameters resources which are dictionaries containing credentials or configuration information. Name the resource parameters like this: \"{resource_type}Resource\". \nThe resource type name has to be exactly as specified.\n\n{resourceTypes}\n\nOnly define the type for resources that are actually needed to achieve the function purpose. If the type name conflicts with the imported object, rename the imported object NOT THE TYPE.\n\nMy instructions: {description}" @@ -32,10 +32,10 @@ export const EDIT_PROMPT = { "prompt": "Here's my powershell code: \n```powershell\n{code}\n```\n\nArguments can be obtained by calling the param function on the first line like that: `param($ParamName1, $ParamName2 = \"default value\", [{type}]$ParamName3, ...)`\nI get the following error: {error}\n\nMy instructions: {description}" }, "nativets": { - "prompt": "Here's my TypeScript code: \n```typescript\n{code}\n```\n\nWe have to export a \"main\" function like this: \"export async function main(...)\" and specify the parameter types but do not call it.\nYou can take as parameters resources which are dictionaries containing credentials or configuration information. Name the resource parameters like this: \"{resource_type}Resource\". \nThe resource type name has to be exactly as specified.\n\n{resourceTypes}\n\nOnly define the type for resources that are actually needed to achieve the function purpose. If the type name conflicts with the imported object, rename the imported object NOT THE TYPE.\n\nMy instructions: {description}" + "prompt": "Here's my TypeScript code: \n```typescript\n{code}\n```\n\nWe have to export a \"main\" function like this: \"export async function main(...)\" and specify the parameter types but do not call it.\nYou can take as parameters resources which are dictionaries containing credentials or configuration information. Name the resource parameters like this: \"{resource_type}Resource\".\nThe following resource types are available:\n\n{resourceTypes}\n\nOnly define the type for resources that are actually needed to achieve the function purpose. The resource type name has to be exactly as specified. If the type name conflicts with the imported object, rename the imported object NOT THE TYPE.\n\nMy instructions: {description}" }, "bun": { - "prompt": "Here's my TypeScript code: \n```typescript\n{code}\n```\n\nWe have to export a \"main\" function like this: \"export async function main(...)\" and specify the parameter types but do not call it.\nIf needed, the standard fetch method is available globally, do not import it.\nYou can take as parameters resources which are dictionaries containing credentials or configuration information. Name the resource parameters like this: \"{resource_type}Resource\". \nThe resource type name has to be exactly as specified.\n\n{resourceTypes}\n\nOnly define the type for resources that are actually needed to achieve the function purpose. If the type name conflicts with the imported object, rename the imported object NOT THE TYPE.\n\nMy instructions: {description}" + "prompt": "Here's my TypeScript code: \n```typescript\n{code}\n```\n\nWe have to export a \"main\" function like this: \"export async function main(...)\" and specify the parameter types but do not call it.\nIf needed, the standard fetch method is available globally, do not import it.\nYou can take as parameters resources which are dictionaries containing credentials or configuration information. Name the resource parameters like this: \"{resource_type}Resource\". \nThe following resource types are available:\n\n{resourceTypes}\n\nOnly define the type for resources that are actually needed to achieve the function purpose. The resource type name has to be exactly as specified. If the type name conflicts with the imported object, rename the imported object NOT THE TYPE.\n\nMy instructions: {description}" }, "frontend": { "prompt": "Here's my client-side javascript code: \n```javascript\n{code}\n```\n\nYou can access the context object with the ctx global variable. \nThe app state is a store that can be used to store data. You can access and update the state object with the state global variable like this: state.foo = 'bar'\nYou can use the goto function to navigate to a specific URL: goto(path: string, newTab?: boolean)\nUse the setTab function to manually set the tab of a Tab component: setTab(id: string, index: string)\nUse the recompute function to recompute a component: recompute(id: string)\nUse the getAgGrid function to get the ag-grid instance of a table: getAgGrid(id: string)\nThe setValue function is meant to set or force the value of a component: setValue(id: string, value: any).\n\nMy instructions: {description}" diff --git a/frontend/src/lib/components/copilot/prompts/fix.yaml b/frontend/src/lib/components/copilot/prompts/fix.yaml index 6afd0b77f2..ee7a8de5c6 100644 --- a/frontend/src/lib/components/copilot/prompts/fix.yaml +++ b/frontend/src/lib/components/copilot/prompts/fix.yaml @@ -19,11 +19,11 @@ prompts: We have to export a "main" function and specify the parameter types but do not call it. You can take as parameters resources which are dictionaries containing credentials or configuration information. Name the resource parameters like this: "{resource_type}_resource". - The resource type name has to be exactly as specified (has to be IN LOWERCASE). + The following resource types are available: {resourceTypes} - Only define the type for resources that are actually needed to achieve the function purpose. If the type name conflicts with the imported object, rename the imported object NOT THE TYPE. + Only define the type for resources that are actually needed to achieve the function purpose. The resource type name has to be exactly as specified (has to be IN LOWERCASE). If the type name conflicts with the imported object, rename the imported object NOT THE TYPE. I get the following error: {error} Fix my code. @@ -36,12 +36,12 @@ prompts: We have to export a "main" function like this: "export async function main(...)" and specify the parameter types but do not call it. If needed, the standard fetch method is available globally, do not import it. - You can take as parameters resources which are dictionaries containing credentials or configuration information. Name the resource parameters like this: "{resource_type}Resource". - The resource type name has to be exactly as specified. + You can take as parameters resources which are dictionaries containing credentials or configuration information. Name the resource parameters like this: "{resource_type}Resource". + The following resource types are available: {resourceTypes} - Only define the type for resources that are actually needed to achieve the function purpose. If the type name conflicts with the imported object, rename the imported object NOT THE TYPE. + Only define the type for resources that are actually needed to achieve the function purpose. The resource type name has to be exactly as specified. If the type name conflicts with the imported object, rename the imported object NOT THE TYPE. I get the following error: {error} Fix my code. @@ -142,11 +142,11 @@ prompts: We have to export a "main" function like this: "export async function main(...)" and specify the parameter types but do not call it. You can take as parameters resources which are dictionaries containing credentials or configuration information. Name the resource parameters like this: "{resource_type}Resource". - The resource type name has to be exactly as specified. + The following resource types are available: {resourceTypes} - Only define the type for resources that are actually needed to achieve the function purpose. If the type name conflicts with the imported object, rename the imported object NOT THE TYPE. + Only define the type for resources that are actually needed to achieve the function purpose. The resource type name has to be exactly as specified. If the type name conflicts with the imported object, rename the imported object NOT THE TYPE. I get the following error: {error} Fix my code. @@ -159,12 +159,12 @@ prompts: We have to export a "main" function like this: "export async function main(...)" and specify the parameter types but do not call it. If needed, the standard fetch method is available globally, do not import it. - You can take as parameters resources which are dictionaries containing credentials or configuration information. Name the resource parameters like this: "{resource_type}Resource". - The resource type name has to be exactly as specified. + You can take as parameters resources which are dictionaries containing credentials or configuration information. Name the resource parameters like this: "{resource_type}Resource". + The following resource types are available: {resourceTypes} - Only define the type for resources that are actually needed to achieve the function purpose. If the type name conflicts with the imported object, rename the imported object NOT THE TYPE. + Only define the type for resources that are actually needed to achieve the function purpose. The resource type name has to be exactly as specified. If the type name conflicts with the imported object, rename the imported object NOT THE TYPE. I get the following error: {error} Fix my code. diff --git a/frontend/src/lib/components/copilot/prompts/fixPrompt.ts b/frontend/src/lib/components/copilot/prompts/fixPrompt.ts index 44cd016dbc..033c73c749 100644 --- a/frontend/src/lib/components/copilot/prompts/fixPrompt.ts +++ b/frontend/src/lib/components/copilot/prompts/fixPrompt.ts @@ -2,10 +2,10 @@ export const FIX_PROMPT = { "system": "You fix the code shared by the user. Only output code. Wrap the code in a code block. \nExplain the error and the fix after generating the code inside an tag.\nAlso put explanations directly in the code as comments.\n\nHere's how interactions have to look like:\nuser: {sample_question}\nassistant: ```language\n{code}\n```\n{explanation}", "prompts": { "python3": { - "prompt": "Here's my python3 code: \n```python\n{code}\n```\n\nWe have to export a \"main\" function and specify the parameter types but do not call it.\nYou can take as parameters resources which are dictionaries containing credentials or configuration information. Name the resource parameters like this: \"{resource_type}_resource\". \nThe resource type name has to be exactly as specified (has to be IN LOWERCASE).\n\n{resourceTypes}\n\nOnly define the type for resources that are actually needed to achieve the function purpose. If the type name conflicts with the imported object, rename the imported object NOT THE TYPE.\n\nI get the following error: {error}\nFix my code." + "prompt": "Here's my python3 code: \n```python\n{code}\n```\n\nWe have to export a \"main\" function and specify the parameter types but do not call it.\nYou can take as parameters resources which are dictionaries containing credentials or configuration information. Name the resource parameters like this: \"{resource_type}_resource\". \nThe following resource types are available:\n\n{resourceTypes}\n\nOnly define the type for resources that are actually needed to achieve the function purpose. The resource type name has to be exactly as specified (has to be IN LOWERCASE). If the type name conflicts with the imported object, rename the imported object NOT THE TYPE.\n\nI get the following error: {error}\nFix my code." }, "deno": { - "prompt": "Here's my TypeScript code in a deno running environment:\n```typescript\n{code}\n```\n\nWe have to export a \"main\" function like this: \"export async function main(...)\" and specify the parameter types but do not call it.\nIf needed, the standard fetch method is available globally, do not import it.\nYou can take as parameters resources which are dictionaries containing credentials or configuration information. Name the resource parameters like this: \"{resource_type}Resource\". \nThe resource type name has to be exactly as specified.\n\n{resourceTypes}\n\nOnly define the type for resources that are actually needed to achieve the function purpose. If the type name conflicts with the imported object, rename the imported object NOT THE TYPE.\n\nI get the following error: {error}\nFix my code." + "prompt": "Here's my TypeScript code in a deno running environment:\n```typescript\n{code}\n```\n\nWe have to export a \"main\" function like this: \"export async function main(...)\" and specify the parameter types but do not call it.\nIf needed, the standard fetch method is available globally, do not import it.\nYou can take as parameters resources which are dictionaries containing credentials or configuration information. Name the resource parameters like this: \"{resource_type}Resource\".\nThe following resource types are available:\n\n{resourceTypes}\n\nOnly define the type for resources that are actually needed to achieve the function purpose. The resource type name has to be exactly as specified. If the type name conflicts with the imported object, rename the imported object NOT THE TYPE.\n\nI get the following error: {error}\nFix my code." }, "go": { "prompt": "Here's my go code: \n```go\n{code}\n```\n\nWe have to export a \"main\" function. Import the packages you need. The return type of the function has to be ({return_type}, error). The file package has to be \"inner\"\n\nI get the following error: {error}\nFix my code." @@ -32,10 +32,10 @@ export const FIX_PROMPT = { "prompt": "Here's my powershell code: \n```powershell\n{code}\n```\n\nArguments can be obtained by calling the param function on the first line like that: `param($ParamName1, $ParamName2 = \"default value\", [{type}]$ParamName3, ...)`\n\nI get the following error: {error}\nFix my code." }, "nativets": { - "prompt": "Here's my TypeScript code: \n```typescript\n{code}\n```\n\nWe have to export a \"main\" function like this: \"export async function main(...)\" and specify the parameter types but do not call it.\nYou can take as parameters resources which are dictionaries containing credentials or configuration information. Name the resource parameters like this: \"{resource_type}Resource\". \nThe resource type name has to be exactly as specified.\n\n{resourceTypes}\n\nOnly define the type for resources that are actually needed to achieve the function purpose. If the type name conflicts with the imported object, rename the imported object NOT THE TYPE.\n\nI get the following error: {error}\nFix my code." + "prompt": "Here's my TypeScript code: \n```typescript\n{code}\n```\n\nWe have to export a \"main\" function like this: \"export async function main(...)\" and specify the parameter types but do not call it.\nYou can take as parameters resources which are dictionaries containing credentials or configuration information. Name the resource parameters like this: \"{resource_type}Resource\". \nThe following resource types are available:\n\n{resourceTypes}\n\nOnly define the type for resources that are actually needed to achieve the function purpose. The resource type name has to be exactly as specified. If the type name conflicts with the imported object, rename the imported object NOT THE TYPE.\n\nI get the following error: {error}\nFix my code." }, "bun": { - "prompt": "Here's my TypeScript code: \n```typescript\n{code}\n```\n\nWe have to export a \"main\" function like this: \"export async function main(...)\" and specify the parameter types but do not call it.\nIf needed, the standard fetch method is available globally, do not import it.\nYou can take as parameters resources which are dictionaries containing credentials or configuration information. Name the resource parameters like this: \"{resource_type}Resource\". \nThe resource type name has to be exactly as specified.\n\n{resourceTypes}\n\nOnly define the type for resources that are actually needed to achieve the function purpose. If the type name conflicts with the imported object, rename the imported object NOT THE TYPE.\n\nI get the following error: {error}\nFix my code." + "prompt": "Here's my TypeScript code: \n```typescript\n{code}\n```\n\nWe have to export a \"main\" function like this: \"export async function main(...)\" and specify the parameter types but do not call it.\nIf needed, the standard fetch method is available globally, do not import it.\nYou can take as parameters resources which are dictionaries containing credentials or configuration information. Name the resource parameters like this: \"{resource_type}Resource\".\nThe following resource types are available:\n\n{resourceTypes}\n\nOnly define the type for resources that are actually needed to achieve the function purpose. The resource type name has to be exactly as specified. If the type name conflicts with the imported object, rename the imported object NOT THE TYPE.\n\nI get the following error: {error}\nFix my code." } } }; \ No newline at end of file diff --git a/frontend/src/lib/components/copilot/prompts/gen.yaml b/frontend/src/lib/components/copilot/prompts/gen.yaml index 9b79e5b8f9..3adad28454 100644 --- a/frontend/src/lib/components/copilot/prompts/gen.yaml +++ b/frontend/src/lib/components/copilot/prompts/gen.yaml @@ -12,21 +12,21 @@ prompts: prompt: |- Write a function in python called "main". The function should {description}. Specify the parameter types. Do not call the main function. You can take as parameters resources which are dictionaries containing credentials or configuration information. Name the resource parameters like this: "{resource_type}_resource". - The resource type name has to be exactly as specified (has to be IN LOWERCASE). + The following resource types are available: {resourceTypes} - Only define the type for resources that are actually needed to achieve the function purpose. If the type name conflicts with the imported object, rename the imported object NOT THE TYPE. + Only define the type for resources that are actually needed to achieve the function purpose. The resource type name has to be exactly as specified (has to be IN LOWERCASE). If the type name conflicts with the imported object, rename the imported object NOT THE TYPE. deno: prompt: |- Write a function in TypeScript called "main". The function should {description}. Specify the parameter types. You are in a Deno environment. You can import deno libraries or you can also import npm libraries like that: "import ... from "npm:{package}";". Export the "main" function like this: "export async function main(...)". Do not call the main function. If needed, the standard fetch method is available globally, do not import it. You can take as parameters resources which are dictionaries containing credentials or configuration information. Name the resource parameters like this: "{resource_type}Resource". - The resource type name has to be exactly as specified. + The following resource types are available: {resourceTypes} - Only define the type for resources that are actually needed to achieve the function purpose. If the type name conflicts with the imported object, rename the imported object NOT THE TYPE. + Only define the type for resources that are actually needed to achieve the function purpose. The resource type name has to be exactly as specified. If the type name conflicts with the imported object, rename the imported object NOT THE TYPE. go: prompt: |- Write a function in go called "main". The function should {description}. Import the packages you need. The return type of the function has to be ({return_type}, error). The file package has to be "inner". @@ -55,21 +55,21 @@ prompts: prompt: |- Write a function in TypeScript called "main". The function should {description}. Specify the parameter types. You should use fetch and are not allowed to import any libraries. Export the "main" function like this: "export async function main(...)". Do not call the main function. You can take as parameters resources which are dictionaries containing credentials or configuration information. Name the resource parameters like this: "{resource_type}Resource". - The resource type name has to be exactly as specified. + The following resource types are available: {resourceTypes} - Only define the type for resources that are actually needed to achieve the function purpose. If the type name conflicts with the imported object, rename the imported object NOT THE TYPE. + Only define the type for resources that are actually needed to achieve the function purpose. The resource type name has to be exactly as specified. If the type name conflicts with the imported object, rename the imported object NOT THE TYPE. bun: prompt: |- Write a function in TypeScript called "main". The function should {description}. Specify the parameter types. You can import npm libraries. Export the "main" function like this: "export async function main(...)". Do not call the main function. If needed, the standard fetch method is available globally, do not import it. You can take as parameters resources which are dictionaries containing credentials or configuration information. Name the resource parameters like this: "{resource_type}Resource". - The resource type name has to be exactly as specified. + The following resource types are available: {resourceTypes} - Only define the type for resources that are actually needed to achieve the function purpose. If the type name conflicts with the imported object, rename the imported object NOT THE TYPE. + Only define the type for resources that are actually needed to achieve the function purpose. The resource type name has to be exactly as specified. If the type name conflicts with the imported object, rename the imported object NOT THE TYPE. frontend: prompt: |- Write client-side javascript code that should {description}. You have access to a few helpers: diff --git a/frontend/src/lib/components/copilot/prompts/genPrompt.ts b/frontend/src/lib/components/copilot/prompts/genPrompt.ts index cd088a7c20..e6738cb6ff 100644 --- a/frontend/src/lib/components/copilot/prompts/genPrompt.ts +++ b/frontend/src/lib/components/copilot/prompts/genPrompt.ts @@ -2,10 +2,10 @@ export const GEN_PROMPT = { "system": "You write code as instructed by the user. Only output code. Wrap the code in a code block. \nPut explanations directly in the code as comments.\n\nHere's how interactions have to look like:\nuser: {sample_question}\nassistant: ```language\n{code}\n```", "prompts": { "python3": { - "prompt": "Write a function in python called \"main\". The function should {description}. Specify the parameter types. Do not call the main function.\nYou can take as parameters resources which are dictionaries containing credentials or configuration information. Name the resource parameters like this: \"{resource_type}_resource\".\nThe resource type name has to be exactly as specified (has to be IN LOWERCASE).\n\n{resourceTypes}\n\nOnly define the type for resources that are actually needed to achieve the function purpose. If the type name conflicts with the imported object, rename the imported object NOT THE TYPE." + "prompt": "Write a function in python called \"main\". The function should {description}. Specify the parameter types. Do not call the main function.\nYou can take as parameters resources which are dictionaries containing credentials or configuration information. Name the resource parameters like this: \"{resource_type}_resource\".\nThe following resource types are available:\n\n{resourceTypes}\n\nOnly define the type for resources that are actually needed to achieve the function purpose. The resource type name has to be exactly as specified (has to be IN LOWERCASE). If the type name conflicts with the imported object, rename the imported object NOT THE TYPE." }, "deno": { - "prompt": "Write a function in TypeScript called \"main\". The function should {description}. Specify the parameter types. You are in a Deno environment. You can import deno libraries or you can also import npm libraries like that: \"import ... from \"npm:{package}\";\". Export the \"main\" function like this: \"export async function main(...)\". Do not call the main function.\nIf needed, the standard fetch method is available globally, do not import it.\nYou can take as parameters resources which are dictionaries containing credentials or configuration information. Name the resource parameters like this: \"{resource_type}Resource\".\nThe resource type name has to be exactly as specified.\n\n{resourceTypes}\n\nOnly define the type for resources that are actually needed to achieve the function purpose. If the type name conflicts with the imported object, rename the imported object NOT THE TYPE." + "prompt": "Write a function in TypeScript called \"main\". The function should {description}. Specify the parameter types. You are in a Deno environment. You can import deno libraries or you can also import npm libraries like that: \"import ... from \"npm:{package}\";\". Export the \"main\" function like this: \"export async function main(...)\". Do not call the main function.\nIf needed, the standard fetch method is available globally, do not import it.\nYou can take as parameters resources which are dictionaries containing credentials or configuration information. Name the resource parameters like this: \"{resource_type}Resource\".\nThe following resource types are available:\n\n{resourceTypes}\n\nOnly define the type for resources that are actually needed to achieve the function purpose. The resource type name has to be exactly as specified. If the type name conflicts with the imported object, rename the imported object NOT THE TYPE." }, "go": { "prompt": "Write a function in go called \"main\". The function should {description}. Import the packages you need. The return type of the function has to be ({return_type}, error). The file package has to be \"inner\"." @@ -32,10 +32,10 @@ export const GEN_PROMPT = { "prompt": "Write powershell code that should {description}. Arguments can be obtained by calling the param function on the first line like that: `param($ParamName1, $ParamName2 = \"default value\", [{type}]$ParamName3, ...)`" }, "nativets": { - "prompt": "Write a function in TypeScript called \"main\". The function should {description}. Specify the parameter types. You should use fetch and are not allowed to import any libraries. Export the \"main\" function like this: \"export async function main(...)\". Do not call the main function.\nYou can take as parameters resources which are dictionaries containing credentials or configuration information. Name the resource parameters like this: \"{resource_type}Resource\".\nThe resource type name has to be exactly as specified.\n\n{resourceTypes}\n\nOnly define the type for resources that are actually needed to achieve the function purpose. If the type name conflicts with the imported object, rename the imported object NOT THE TYPE." + "prompt": "Write a function in TypeScript called \"main\". The function should {description}. Specify the parameter types. You should use fetch and are not allowed to import any libraries. Export the \"main\" function like this: \"export async function main(...)\". Do not call the main function.\nYou can take as parameters resources which are dictionaries containing credentials or configuration information. Name the resource parameters like this: \"{resource_type}Resource\".\nThe following resource types are available:\n\n{resourceTypes}\n\nOnly define the type for resources that are actually needed to achieve the function purpose. The resource type name has to be exactly as specified. If the type name conflicts with the imported object, rename the imported object NOT THE TYPE." }, "bun": { - "prompt": "Write a function in TypeScript called \"main\". The function should {description}. Specify the parameter types. You can import npm libraries. Export the \"main\" function like this: \"export async function main(...)\". Do not call the main function.\nIf needed, the standard fetch method is available globally, do not import it.\nYou can take as parameters resources which are dictionaries containing credentials or configuration information. Name the resource parameters like this: \"{resource_type}Resource\".\nThe resource type name has to be exactly as specified.\n\n{resourceTypes}\n\nOnly define the type for resources that are actually needed to achieve the function purpose. If the type name conflicts with the imported object, rename the imported object NOT THE TYPE." + "prompt": "Write a function in TypeScript called \"main\". The function should {description}. Specify the parameter types. You can import npm libraries. Export the \"main\" function like this: \"export async function main(...)\". Do not call the main function.\nIf needed, the standard fetch method is available globally, do not import it.\nYou can take as parameters resources which are dictionaries containing credentials or configuration information. Name the resource parameters like this: \"{resource_type}Resource\".\nThe following resource types are available:\n\n{resourceTypes}\n\nOnly define the type for resources that are actually needed to achieve the function purpose. The resource type name has to be exactly as specified. If the type name conflicts with the imported object, rename the imported object NOT THE TYPE." }, "frontend": { "prompt": "Write client-side javascript code that should {description}. You have access to a few helpers:\nYou can access the context object with the ctx global variable. \nThe app state is a store that can be used to store data. You can access and update the state object with the state global variable like this: state.foo = 'bar'\nYou can use the goto function to navigate to a specific URL: goto(path: string, newTab?: boolean)\nUse the setTab function to manually set the tab of a Tab component: setTab(id: string, index: string)\nUse the recompute function to recompute a component: recompute(id: string)\nUse the getAgGrid function to get the ag-grid instance of a table: getAgGrid(id: string)\nThe setValue function is meant to set or force the value of a component: setValue(id: string, value: any)."