Skip to content

Conversation

@kiranandcode
Copy link
Contributor

@kiranandcode kiranandcode commented Jan 28, 2026

Implements an internal synthesis API. This API is implemented as a Encodable[Callable] instance, which implements decode by calling a series of operations, parse, compile, exec from an evaluation module:

@defop
def parse(source: str, filename: str) -> ast.AST:
    """
    Parse source text into an AST.

    source: The Python source code to parse.
    filename: The filename recorded in the resulting AST for tracebacks and tooling.

    Returns the parsed AST.
    """
    raise TypeError("An eval provider must be installed in order to parse code.")


@defop
def compile(module: ast.AST, filename: str) -> CodeType:
    """
    Compile an AST into a Python code object.

    module: The AST to compile (typically produced by parse()).
    filename: The filename recorded in the resulting code object (CodeType.co_filename), used in tracebacks and by inspect.getsource().

    Returns the compiled code object.
    """
    raise TypeError("An eval provider must be installed in order to compile code.")


@defop
def exec(
    bytecode: CodeType,
    env: MutableMapping[str, Any],
) -> None:
    """
    Execute a compiled code object.

    bytecode: A code object to execute (typically produced by compile()).
    env: The namespace mapping used during execution.
    """
    raise TypeError("An eval provider must be installed in order to execute code.")

For testing, this also adds a UnsafeEvalProvider which provides naive implementations of these by shelling out to the builtin python implementations of each without further checking.

@kiranandcode
Copy link
Contributor Author

Questions: Should these evaluation functions take in the type of the expected result? If we plan to implement providers that do type checking etc. then maybe we should? I think these should go in compile?

Copy link
Contributor

@eb8680 eb8680 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left a bunch of comments below, but one common theme is whether this API is compatible with a metacircular evaluator #503

@eb8680
Copy link
Contributor

eb8680 commented Jan 28, 2026

Questions: Should these evaluation functions take in the type of the expected result? If we plan to implement providers that do type checking etc. then maybe we should? I think these should go in compile?

The expected result type needs to be communicated to the LLM API as well, so I think this data and validation logic probably need to live in the result of type_to_encodable_type(return_annotation) somehow.

Copy link
Contributor

@eb8680 eb8680 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good!

@kiranandcode
Copy link
Contributor Author

awesome, will merge once tests pass!

@kiranandcode kiranandcode merged commit 7679e47 into master Jan 31, 2026
6 checks passed
@kiranandcode kiranandcode deleted the kg-encodable-default branch January 31, 2026 01:54
eb8680 added a commit that referenced this pull request Jan 31, 2026
* Fresh diff

* remove instructionhandler

* updated internal interface to make all tests pass

* fixed caching tests

* updated llm.ipynb

* removed unnecessarily defensive validation

* updated tool call decoding to use concrete type of tool result instead of annotations

* updated completions to fix basic type errors

* updated call assistant to handle decoding tool calls

* dropped stale comments

* moved model and param model back to internals of `completions`

* added default encodable instance for Callable

* fixed type errors

* update to use more structured type for synthesis

* updated callable encoding tests

* s/TypeError/NotImplementedError

* simplified smart constructor

* bare callables not allowed

* droped synthesis and removed encoding_instructions

* fixed imports

* fixed imports and tests

* added restricted python again

* added test for custom policies for restricted python

* more specific arguments to RestrictedEvalProvider and made exec more customisable

* reverted flags for customizing rglobals, using same rglobals for local and globals for exec, fixing bug

* fixed failing tests (env was not being mutated)

* updated restricted python to be a llm dependency

---------

Co-authored-by: Eli <eli@basis.ai>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Introduce the internal synthesis API Support additional contexts for ProgramSynthesis

2 participants