Repository navigation
Add plumbing for TS/PY snippets in Sandboxes - #1778
Conversation
Pure builders for the commands that run a snippet with input as globals and a top-level return as the result, plus the parser for the result sentinel. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
There was a problem hiding this comment.
🟡 Changes recommended
Result framing, cyclic validation, and TypeScript transformation have correctness gaps.
4 open findings
What changed in this PR
Adds internal sandbox plumbing to execute TypeScript and Python snippets with JSON inputs and parsed results.
Changes:
- Builds inline or file-backed runner commands.
- Validates JSON inputs and global names.
- Adds execution and parsing tests for both languages.
| File | Description |
|---|---|
runnerScripts.ts |
Implements snippet runners, validation, and result parsing. |
runnerScripts.test.ts |
Tests execution, payload handling, validation, and parsing. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
…cles and sparse arrays - TypeScript wrapper emits the result frame on clean exit, so output scheduled after the snippet returned no longer breaks parsing - parseRunnerOutput takes the exit code and ignores the sentinel on failure - TypeScript is transformed (enums etc.), not only stripped - input validation rejects circular references and empty array slots Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…26 removed Enums and other syntax that needs transforming are no longer supported. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
## Summary
<!-- Succinctly describe your change, providing context, what you've
changed, and why. -->
Adds `step.sandbox.python()`, a managed-lifecycle Sandbox that runs
Python code and can take `input`.
### Direct step usage
Use Python from TS, with the sandbox's lifecycle managed for you.
`input`s become variables accessible by the code.
```ts
const stats = await step.sandbox.python("stats", `
import statistics
return {"mean": statistics.mean(values)}
`, {
input: { values: [1, 2, 3, 4] },
});
```
### Reusable functions
Create a reusable function usable during any run.
Output can also be typed and validated using any
`StandardSchema`-compliant schema library.
```ts
import { step } from "inngest";
import { z } from "zod";
export const stats = async (id: string, values: number[]) => {
return step.sandbox.python(id, `
import statistics
return {"mean": statistics.mean(values), "stdev": statistics.stdev(values)}
`, {
input: { values },
schema: { output: z.object({ mean: z.number(), stdev: z.number() }),
});
};
```
```ts
// later in a run
const { mean } = await stats("get-stats", [1, 2, 3, 4]);
```
### Trace
<img width="1084" height="224" alt="image"
src="https://github.com/user-attachments/assets/da75f15a-b33e-479b-8fae-0d9f5cf029dc"
/>
<img width="1082" height="327" alt="image"
src="https://github.com/user-attachments/assets/d7a43855-f6d4-4e8d-bc2e-8ac0f904ac43"
/>
## Checklist
<!-- Tick these items off as you progress. -->
<!-- If an item isn't applicable, ideally please strikeout the item by
wrapping it in "~~"" and suffix it with "N/A My reason for skipping
this." -->
<!-- e.g. "- [ ] ~~Added tests~~ N/A Only touches docs" -->
- [ ] ~Added a [docs PR](https://github.com/inngest/website) that
references this PR~ N/A Later bump
- [x] Added unit/integration tests
- [x] Added changesets if applicable
## Related
<!-- A space for any related links, issues, or PRs. -->
<!-- Linear issues are autolinked. -->
<!-- e.g. - INN-123 -->
<!-- GitHub issues/PRs can be linked using shorthand. -->
<!-- e.g. "- inngest/inngest#123" -->
<!-- Feel free to remove this section if there are no applicable related
links.-->
- Based on #1778
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
## Summary
<!-- Succinctly describe your change, providing context, what you've
changed, and why. -->
Adds `step.sandbox.typescript()`, a managed-lifecycle Sandbox that runs
TypeScript code and can take `input`.
### Direct step usage
Run TS, with the sandbox's lifecycle managed for you.
`input`s become variables accessible by the code.
```ts
const stats = await step.sandbox.typescript("sum", `
return numbers.reduce((a: number, b: number) => a + b, 0)
`, {
input: { numbers: [1, 2, 3] },
});
```
### Reusable functions
Create a reusable function usable during any run.
Output can also be typed and validated using any
`StandardSchema`-compliant schema library.
```ts
import { step } from "inngest";
import { z } from "zod";
export const stats = async (id: string, values: number[]) => {
return step.sandbox.typescript(id, `
...
`, {
input: { values },
schema: { output: z.object({ words: z.number() }),
});
};
```
```ts
// later in a run
const { words } = await stats("get-stats", event.data.body);
```
### Trace
<img width="1082" height="227" alt="image"
src="https://github.com/user-attachments/assets/3d1c8ad2-7f82-4756-b088-24844543b5fd"
/>
<img width="1086" height="323" alt="image"
src="https://github.com/user-attachments/assets/0524e5ab-c794-47a5-9f5d-a05fd6cfc58f"
/>
## Checklist
<!-- Tick these items off as you progress. -->
<!-- If an item isn't applicable, ideally please strikeout the item by
wrapping it in "~~"" and suffix it with "N/A My reason for skipping
this." -->
<!-- e.g. "- [ ] ~~Added tests~~ N/A Only touches docs" -->
- [ ] ~Added a [docs PR](https://github.com/inngest/website) that
references this PR~ N/A Later bump
- [x] Added unit/integration tests
- [x] Added changesets if applicable
## Related
<!-- A space for any related links, issues, or PRs. -->
<!-- Linear issues are autolinked. -->
<!-- e.g. - INN-123 -->
<!-- GitHub issues/PRs can be linked using shorthand. -->
<!-- e.g. "- inngest/inngest#123" -->
<!-- Feel free to remove this section if there are no applicable related
links.-->
- Based on #1778 and #1783
---------
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>


Summary
Add the plumbing for TypeScript and Python snippets to unlock higher-level APIs for running code. These allow submitted code to be within an existing process with some controlled globals etc which allow us to influence the environment enough to produce some nice future sugar.
This is the foundation that will allow for functionality such as:
Checklist
Added a docs PR that references this PRN/A internal