Skip to content

Conversation

@BDHU
Copy link
Owner

@BDHU BDHU commented Jan 14, 2026

Key Changes

API Renaming

  • node → op: The @node decorator is now @op
  • replica → service: The @replica decorator is now @service
  • Related type renames: ActorHandle → ServiceClass, ReplicaHandle → ServiceHandle, NodeExecutionError → OpExecutionError
    Module Restructuring
  • New api/ module: Contains op.py, op_function.py, and service.py with clean, focused APIs
  • New backends/ module: Reorganized distributed/grpc into backends/grpc with improved structure
  • New resources/ module: Centralized device and mesh management
  • New runtime/ module: Added scheduler, task pool, and execution hooks for better runtime control
  • Removed agents/ module: Deprecated and removed
  • Removed core/ and distributed/ modules: Consolidated into new structure

New Features

  • Enhanced service decorator supporting both class and function usage
  • Comprehensive type stubs added (init.pyi) for better IDE support
  • New runtime scheduler with improved task management
  • Pool-based execution for better resource utilization

Documentation

  • Updated ARCHITECTURE.md to reflect new structure
  • Updated DESIGN.md with ObjectRef terminology
  • Updated README.md to describe dynamic execution model

Tests & Examples

  • All tests updated to use new API terminology
  • Examples refactored for new structure
  • Removed outdated agents example documentation

Breaking Changes: This is a significant refactoring with API renames. Users will need to update their code:

BDHU added 20 commits January 13, 2026 22:15
The agents module has been removed as part of the refactoring to rename core concepts.
- Rename @node decorator to @op
- Rename @replica decorator to @service
- Update imports and exports accordingly
- Rename ActorHandle to ServiceClass
- Rename ReplicaHandle to ServiceHandle
- Rename NodeExecutionError to OpExecutionError
Add __init__.pyi with comprehensive type annotations for the public API.
- Rename NodeExecutionError to OpExecutionError
- Add context.py for execution context
- Add op.py for operation handling
- Update various runtime files to use new naming
- Remove optimizer.py and task.py as they are no longer needed
- Rename replica.proto to service.proto and regenerate protobuf files
- Update gRPC backend code to use service terminology
- Update service provider code accordingly
- Update mesh.py and __init__.py to use new terminology
- Add require_mesh function for mesh requirement checking
- Change @node decorators to @op
- Change @replica decorators to @service
- Update comments and docstrings accordingly
- Update mesh creation to use new CpuDevice constructor
- Change @node imports and decorators to @op
- Change @replica imports and decorators to @service
- Update test class names and method calls accordingly
- Update conftest.py to import op instead of node
- Change @node imports and decorators to @op
- Change @replica imports and decorators to @service
- Update test class names and method calls accordingly
- Update conftest.py to import op instead of node
- Rename @node decorator to @op in documentation and examples
- Rename @replica decorator to @service in architecture docs and tests
- Update README.md to reflect dynamic execution model instead of JAX-style compilation
- Update DESIGN.md to use ObjectRef terminology instead of Context
- Update test comments and file headers to use new decorator names
- Remove outdated agents example documentation
@BDHU BDHU self-assigned this Jan 14, 2026
@BDHU BDHU added the enhancement New feature or request label Jan 14, 2026
@codspeed-hq
Copy link
Contributor

codspeed-hq bot commented Jan 14, 2026

Merging this PR will degrade performance by 30.78%

⚡ 2 improved benchmarks
❌ 2 regressed benchmarks
✅ 9 untouched benchmarks
🆕 2 new benchmarks
⏩ 32 skipped benchmarks1

⚠️ Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Benchmark BASE HEAD Efficiency
test_bench_replica_multiple_calls 13 µs 14.7 µs -11.67%
test_bench_basic_replica_execution 14.8 µs 21.3 µs -30.78%
test_bench_profiling_summary_generation 72.5 µs 40.4 µs +79.44%
test_bench_replica_with_different_multipliers 15.1 µs 13 µs +15.81%
🆕 test_bench_parallel_node_execution N/A 13 µs N/A
🆕 test_bench_mixed_parallel_sequential N/A 13.1 µs N/A

Comparing dynamic (d204bf5) with main (9abf039)

Open in CodSpeed

Footnotes

  1. 32 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@BDHU BDHU merged commit a77f853 into main Jan 14, 2026
5 of 6 checks passed
@BDHU BDHU deleted the dynamic branch January 14, 2026 18:16
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @BDHU, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces a fundamental architectural shift in the thinkagain framework, moving away from a static, JAX-inspired graph compilation approach to a more flexible and intuitive dynamic execution model. The core intent is to streamline the developer experience by providing a cleaner, more Pythonic API that simplifies the creation of distributed AI pipelines. This refactoring enhances runtime capabilities through an advanced scheduler and a more direct way to manage stateful services, ultimately making the framework more modular and easier to use for complex asynchronous workflows.

Highlights

  • API Renaming: The @node decorator has been renamed to @op for functions, and @replica has been renamed to @service for stateful classes. Related types like NodeExecutionError are now OpExecutionError.
  • Dynamic Execution Model: The framework transitions from a JAX-style static graph compilation (@jit) to a dynamic execution model. Computation graphs are now built implicitly at runtime through .go() calls, which immediately return ObjectRef futures for non-blocking task submission and automatic dependency tracking.
  • Module Restructuring: The codebase has been significantly reorganized with new top-level modules: api/ for public interfaces, backends/ for execution backends, resources/ for device and mesh management, and runtime/ for the new scheduler and execution logic. The old agents/, core/, and distributed/ modules have been removed or refactored into the new structure.
  • Enhanced Services: The @service decorator now supports both class and function usage, and services directly manage mutable state, eliminating the need for explicit decompose/compose patterns. Services are managed by ServicePools for load balancing and deployment.
  • New Runtime Scheduler: A new DAGScheduler is introduced to manage tasks, resolve dependencies, and execute independent operations concurrently, providing automatic parallelism. ObjectRefs serve as futures for results from these scheduled operations.
  • Comprehensive Type Stubs: New __init__.pyi files have been added to provide comprehensive type stubs for the updated API, improving IDE support and static analysis.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d204bf5050

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +203 to +205
def _unique_dependencies(self, op: Op) -> set[ObjectRef]:
"""Return unique ObjectRef dependencies for an op."""
return set(op.get_dependencies())

Choose a reason for hiding this comment

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

P1 Badge Avoid hashing ObjectRef dependencies

When an op depends on another op, op.get_dependencies() returns ObjectRef instances. _unique_dependencies builds a set from that list, but ObjectRef is a mutable dataclass without __hash__, so this raises TypeError: unhashable type: 'ObjectRef' as soon as any dependency exists. That means any .go() call that passes an ObjectRef argument will fail during submission. Consider deduping by op_id (or another hashable key) instead of putting ObjectRef objects directly in a set.

Useful? React with 👍 / 👎.

Comment on lines +331 to +333
return {
"pending": max(len(self._tasks) - len(self._running), 0),
"running": len(self._running),

Choose a reason for hiding this comment

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

P2 Badge Fix stats pending count to use tracked ops

The stats property references self._tasks, but the scheduler tracks ops in self._ops and never defines _tasks. Accessing scheduler.stats will therefore raise AttributeError, breaking any monitoring or tests that call it. This looks like a leftover rename and should be updated to use the correct collection.

Useful? React with 👍 / 👎.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request represents a significant and well-executed refactoring of the thinkagain framework. The transition from a JAX-style static graph compilation to a dynamic execution model using @op, @service, and .go() calls introduces a much cleaner API and improved runtime capabilities. The module restructuring into api, backends, resources, and runtime is logical and enhances maintainability. All documentation, examples, and tests have been thoroughly updated to reflect the new terminology and architectural changes. The introduction of ObjectRef and DAGScheduler as core components for dynamic dependency tracking and parallel execution is a strong improvement. Overall, this is a comprehensive and well-implemented refactoring that significantly enhances the framework's design and usability.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants