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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cspell.config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ ignorePaths:
words:
# Project/Brand names
- HMAC
- retryable
- codemie
- passwordless
- SAMEORIGIN
Expand Down
14 changes: 8 additions & 6 deletions docs/admin/configuration/codemie/api-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -1050,12 +1050,13 @@ Automatically compress long conversation histories when token usage exceeds a th

### Workflow Configuration

| Parameter | Type | Default | Description |
| ------------------------------ | ------- | ------- | ------------------------------------------------------------------------------------- |
| `WORKFLOW_MAX_CONCURRENCY` | integer | `5` | Max simultaneous workflow executions to control resource usage |
| `WORKFLOW_DEFAULT_CONCURRENCY` | integer | `2` | Default concurrency when not specified by workflow |
| `WORKFLOW_GENERATION_ENABLED` | boolean | `false` | Enable AI-assisted workflow generation feature |
| `WORKFLOW_GENERATOR_LLM_MODEL` | string | `""` | LLM model used for workflow generation; falls back to global default model when empty |
| Parameter | Type | Default | Description |
| ------------------------------ | ------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `WORKFLOW_MAX_CONCURRENCY` | integer | `5` | Max simultaneous workflow executions to control resource usage |
| `WORKFLOW_DEFAULT_CONCURRENCY` | integer | `2` | Default concurrency when not specified by workflow |
| `WORKFLOW_GENERATION_ENABLED` | boolean | `false` | Enable AI-assisted workflow generation feature |
| `WORKFLOW_GENERATOR_LLM_MODEL` | string | `""` | LLM model used for workflow generation; falls back to global default model when empty |
| `WORKFLOW_RUN_FILES_MAX_COUNT` | integer | `20` | Max number of files a workflow run can start with; a request with more files is rejected with `400`. The execution request accepts at most 20 files, so a higher value has no effect |

### Sub-workflows

Expand Down Expand Up @@ -1161,6 +1162,7 @@ Configure secure Python code execution in isolated Kubernetes pods for running u
| `CODE_EXECUTOR_VERBOSE` | boolean | `false` | Enable verbose logging for executor debugging |
| `CODE_EXECUTOR_KEEP_TEMPLATE` | boolean | `true` | Persist pod template after execution for performance optimization |
| `CODE_EXECUTOR_SKIP_ENVIRONMENT_SETUP` | boolean | `false` | Skip environment initialization in sandbox (faster startup but may break dependencies) |
| `FEATURE_WORKSPACE_SCRIPT_BRIDGE` | boolean | unset | Overrides `enabled` of the `features:workspaceScriptBridge` customer configuration component at load time, where the component exists in the loaded `customer-config.yaml`. When `true`, workspace scripts can call CodeMie tools through `codemie_runtime_sdk` (`sandbox-jobs` mode only). Changing it requires a restart. See [Code Executor Configuration](./code-executor-configuration.md#workspace-script-tool-call-bridge). |

:::warning Security Considerations
**Sandbox Isolation:** `CODE_EXECUTOR_EXECUTION_MODE=sandbox` runs user-supplied code in a dedicated Kubernetes pod, isolated from the CodeMie API. This is the execution model for running untrusted code safely in production.
Expand Down
128 changes: 128 additions & 0 deletions docs/admin/configuration/codemie/code-executor-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,134 @@ extraEnv:
value: "<namespace>"
```

## Workspace Script Tool-Call Bridge

A script run by the execute workspace script tool can call CodeMie tools while it runs. The script imports `codemie_runtime_sdk` and calls a tool by name. The CodeMie API runs the tool and returns its result to the script, so a script can, for example, read a Jira issue or a Confluence page as part of its work.

:::info Current limitations

- The bridge works in `sandbox-jobs` mode only. In `sandbox-shared` mode, and whenever the bridge is disabled, scripts cannot make tool calls.
- Only tools that are opted in can be called from a script. Integration tools such as Jira, Confluence, GitHub, and GitLab are included. Platform, file system, workspace, IDE, and MCP tools are not.
- A request is limited to 256 KiB, and so is a result. A larger one fails with the `payload_too_large` error code.
:::

### Enabling the Bridge

The bridge is controlled by the `features:workspaceScriptBridge` [customer configuration](./customer-feature-configuration.md) component. It is disabled by default.

| Setting | Default | Description |
| ------------------ | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `enabled` | `false` | Enables the bridge for workspace script runs. |
| `timeoutSeconds` | `120` | Time limit in seconds for a script run with the bridge, counted from the start of the script. Values above `480` are lowered to `480`. A missing, non-numeric, or non-positive value falls back to `120`. |
| `maxParallelCalls` | `5` | Most tool calls of one run that are served at the same time. `1` serves them one after another. Values above the process-wide limit (`10` by default) are lowered to it. A missing or invalid value falls back to `5`. |

```yaml
components:
- id: "features:workspaceScriptBridge"
settings:
enabled: true
timeoutSeconds: 120
maxParallelCalls: 5
name: "Workspace Script Bridge"
description: "Allow scripts run in the workspace sandbox to call tools during their run"
```

Ways to change the settings:

- **Administration page.** All three settings can be edited at runtime in **Settings → Administration → Customer Configuration**, under **Workspace script bridge** (switch **Enable workspace script bridge**, fields **Script run limit (seconds)** and **Parallel tool calls per run**). See [Dynamic Customer Configuration](./dynamic-customer-configuration.md).
- **`customer-config.yaml`.** The YAML value is the deployment default when nothing is saved on the page. A customer ConfigMap that replaces the default file needs its own copy of the component for the YAML value and for `FEATURE_WORKSPACE_SCRIPT_BRIDGE` to apply; a value saved on the administration page works without it.
- **`FEATURE_WORKSPACE_SCRIPT_BRIDGE`.** Set to `true` or `false` to override `enabled` from the YAML at load time. The override applies only where the component exists in the loaded file, and changing it requires a restart of CodeMie API.

A saved change applies to script runs that start afterwards. The backend reads the setting on every run, and other CodeMie API instances pick up the change within `CUSTOMER_CONFIG_CACHE_TTL_SECONDS` (default: `60` seconds).

### Run Time Limit and Capacity

While the bridge is enabled, the deadline of the sandbox Job for every workspace script run is:

```text
max(CODE_EXECUTOR_EXECUTION_TIMEOUT, timeoutSeconds) + 60 seconds
```

With the defaults (`30` and `120`), a run can last up to 180 seconds. With `timeoutSeconds` at its maximum of `480`, a run can last up to 540 seconds. A `timeoutSeconds` value below `CODE_EXECUTOR_EXECUTION_TIMEOUT` does not shorten a run. Without the bridge, the deadline is `CODE_EXECUTOR_EXECUTION_TIMEOUT` plus 60 seconds.

Gateways between the browser and CodeMie API must keep the run's stream open for the whole run, so they must allow at least as long as the run limit (540 seconds at the maximum).

:::warning Capacity
A run holds one executor slot until it finishes. The number of slots is set by `CODE_EXECUTOR_MAX_POD_POOL_SIZE` (default: `5`), and a request made when all slots are taken fails with a capacity error. Long runs with a high `timeoutSeconds` can exhaust the slots sooner, so the limit should stay as low as the scripts allow.
:::

### Calling Tools from a Script

Use a tool from the tool list of the run. The name and arguments are the ones the tool defines.

```python
import codemie_runtime_sdk as sdk

envelope = sdk.call_tool("<tool name>", {"<argument>": "<value>"})
print(envelope["result"])
```

`call_tool(name, args=None, *, timeout=None)` returns the envelope of the call: `result` holds the tool's output, and `http` (with `status` and `reason`) is present for tools that make HTTP requests. `timeout` is in seconds and defaults to `100`.

To run several calls together, use `call_tools`. It takes a list of dictionaries with `name` and optionally `args`, and returns a list in the same order. A call that fails is returned as a `ToolCallError` item instead of being raised, so one failure does not hide the other results. A batch holds at most 32 calls.

```python
import codemie_runtime_sdk as sdk

results = sdk.call_tools(
[
{"name": "<tool name>", "args": {"<argument>": "<value>"}},
{"name": "<tool name>", "args": {"<argument>": "<other value>"}},
]
)
for result in results:
if isinstance(result, sdk.ToolCallError):
print(result.code, result.message)
else:
print(result["result"])
```

A failed call raises `ToolCallError` (or, in a batch, is returned as one). Its attributes are:

- `code`: the reason, listed below.
- `message`: a short description of the failure.
- `retryable`: `True` when repeating the call can succeed.
- `may_have_run`: `True` when the tool may already have run. A call that changes data, such as a create, update, or send, must not be repeated when this is `True` until its result has been checked.

| Code | Meaning | Retryable |
| ----------------------------------------- | ------------------------------------------------------------------------------------------------- | --------- |
| `tool_failed` | The tool ran and raised an error. | Yes |
| `tool_blocked` | The tool is not allowed in this run. | No |
| `tool_unavailable` | The tool is not in the run's tool list, is not opted in for scripts, or has no argument schema. | No |
| `bad_arguments` | The arguments do not match the tool's schema, or the call contains an unknown field. | No |
| `payload_too_large` | The request or the result is larger than 256 KiB. | No |
| `timeout` | No answer arrived within `timeout` seconds. | Yes |
| `unavailable` | The backend stopped answering during the run, or the bridge is not available to this run. | Depends |
| `deadline_exceeded` | The run has too little time left to start the call, so the call was not started. | No |
| `internal_error` | The backend failed in an unexpected way. | Yes |
| `error` | A generic failure. | Yes |
| `bad_request`, `unknown_op`, `no_context` | The SDK call or the run's setup is wrong. These point to a deployment problem, not to the script. | No |

Check `retryable` and `may_have_run` rather than the code alone, because `unavailable` covers both cases.

While a run is active, requests and responses are exchanged as files in a `.codemie_bridge` folder inside the script working directory. The folder is removed when the script finishes and is excluded from exported and changed files.

```mermaid
sequenceDiagram
participant S as Workspace script
participant P as Sandbox Job pod
participant B as CodeMie API

S->>P: Write request file
B->>P: Poll for requests
B->>P: Write response file
S->>P: Read response file
Note over S,B: Repeats while the script runs
S->>P: Script finishes
B->>P: Stop polling and remove the folder
B->>P: Download exports and changed files
```

## Applying CodeMie API Settings

```bash
Expand Down
Loading
Loading